В WooCommerce есть много различных способов организации системы скидок на товары в корзине, одним из них будет функция описанная ниже.
Суть функции и её логика:
- Задаём параметры скидки для категории товаров. Если категорий не много, то можно задать вручную
- Проходим в цикле по элементам корзины WooCommerce что бы заполнить массив данных. В этом случае функция учитывает только первую категорию к которой относится товар.
- Массив данных содержит общее количество товаров, сумму, и товары(здесь они не используются)
- Добавление скидки в зависимости от наличия условия.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
/** * Добавление скидок на товар в корзине * @param WC_Cart $cart */ function coderun_discount_category(WC_Cart $cart) { //Параметры скидки $params_discount = [ '3573' => [//ид категории на которую нужно предоставить скидку 'name' => 'аккумуляторы', //название категории 'min' => 1, //минимальное количество 'max' => 3, //Максимальное количество 'dicount' => 0.20, //скидка 20% ], '3450' => [ 'name' => 'водонагреватели', 'min' => 1, 'max' => 3, 'dicount' => 0.30, ] ]; $items = $cart->get_cart_contents(); //элементы корзины $product_category = []; foreach ($items as $item) { $category = $item['data']->get_category_ids(); $product_id = $item['product_id']; $quantity = $item['quantity']; if (isset($category[0])) { $product_category[$category[0]]['quantity'] += $quantity;//Считаем количество товаров принадлежащих одной категории $product_category[$category[0]]['products'][] = $product_id; $product_category[$category[0]]['summ'] += $item['line_subtotal']; //сумма } } //Установка скидки foreach ($product_category as $cat_id => $data) { if (isset($params_discount[$cat_id])) { if ($data['quantity'] >= $params_discount[$cat_id]['min'] && $data['quantity'] <= $params_discount[$cat_id]['max']) { $discount = $data['summ'] * $params_discount[$cat_id]['dicount'];//Значение скидки для установки в Woo $name = $params_discount[$cat_id]['name'];//Имя категории $dscount_value = $params_discount[$cat_id]['dicount'] * 100;//Человеко-читаемое значение скидки $cart->add_fee("Скидка на {$name} {$dscount_value} %", -$discount); } } } } add_action("woocommerce_cart_calculate_fees", "coderun_discount_category"); |
Функция немного «сыровата», но в любом случае её можно довести до нужно логического решения.
Так же следует обратить внимание, что WooCommerce при вызове $cart->add_fee($name,$discount) требует что бы $name было уникальным в рамках корзины. Т.е если у вас название скидки имеет одно и то же имя для всех категорий — то будет добавлена только одна скидка.
Что бы код работал — нужно его добавить в файл function.php вашего шаблона сайта.
Визуально работа данной функции выглядит таким образом:

Здравствуйте! Ваш код работает, но показывает скидку только для одной категории, а я добавил как в вашем примере 2 разные категории. Я так понимаю вы именно это имели ввиду «Так же следует обратить внимание, что WooCommerce при вызове $cart->add_fee($name,$discount) требует что бы $name было уникальным в рамках корзины. Т.е если у вас название скидки имеет одно и то же имя для всех категорий – то будет добавлена только одна скидка.» Я уже несколько раз перечитал эту фразу но совершенно не могу понять как мне задать уникальное имя? В вашем примере имя скидки формируется из «$cart->add_fee(«Скидка на {$name}», где name подставляется из того что я задал для каждой категории в самом начале сниппета. У меня так же как в примере — Категория 1 и Категория 2, name у них разный, но в итоге в корзине я вижу только «Скидка на Категория 2». Я не программист но стараюсь понять. Подскажите пожалуйста что все таки надо сделать что бы в корзине отображались скидки на все категории а не на одну. Спасибо!