Перейти к содержимому

Правила работы с корзиной - условия, порядок, отладка

Разбираемся, как устроены правила корзины, в каком порядке они применяются и почему скидка не появляется в заказе.

Решение

Смотрим активные правила и их порядок:

use Bitrix\Main\Loader;
use Bitrix\Sale\Internals\DiscountTable;
Loader::includeModule('sale');
$rows = DiscountTable::getList([
'select' => ['ID', 'NAME', 'SORT', 'ACTIVE', 'LAST_DISCOUNT', 'PRIORITY'],
'order' => ['SORT' => 'ASC'],
])->fetchAll();
foreach ($rows as $row) {
printf("%-4s %-30s сорт=%-4s последнее=%s\n",
$row['ID'], mb_substr($row['NAME'], 0, 30), $row['SORT'], $row['LAST_DISCOUNT']);
}

Правила применяются по порядку сортировки, а не по величине скидки. Флаг «последнее правило» обрывает цепочку: всё, что стоит ниже, к заказу уже не применяется.

Разбираем правило на условие и действие:

// условие: что должно быть в корзине - сумма, товары, группа покупателя
// действие: что сделать - процент, фиксированная сумма, подарок, доставка
$discount = DiscountTable::getById($id)->fetch();
print_r(unserialize($discount['CONDITIONS'] ?? ''));
print_r(unserialize($discount['ACTIONS'] ?? ''));

Условия объединяются логикой «и» по умолчанию. Одно невыполненное условие отменяет правило целиком, и именно это чаще всего означает «скидка не применяется».

Считаем скидку кодом, минуя интерфейс:

use Bitrix\Sale\Discount;
$order = \Bitrix\Sale\Order::load($orderId);
$order->getDiscount()->calculate();
$result = $order->getDiscount()->getApplyResult(true);
print_r($result['DISCOUNT_LIST']); // какие правила реально сработали
// в списке видны номера правил и суммы, на которые они уменьшили заказ

Список применённых правил отвечает на вопрос точнее любых предположений. Пустой список при активном правиле означает, что условия не выполнились на этом конкретном заказе.

Показываем скидку в каталоге:

// в самом правиле включается показ в каталоге, иначе оно действует только в корзине
'PRESET_ID' => null,
'RENEWAL' => 'N',
'SHOW_IN_CATALOG' => 'Y',
// порядок правил задаётся сортировкой: первое подошедшее может остановить остальные

Скидка, работающая только в корзине, на витрине не видна, и покупатель узнаёт о ней в последний момент. Показ в каталоге - настройка правила, а не параметр компонента списка товаров.

Комбинации товаров описываются условиями на состав корзины покупателя. Правило «второй товар со скидкой» проверяет количество позиций и применяет действие к части из них, и собирается это целиком в конструкторе условий, без единой строки кода.

Порядок разбора несработавшего правила всегда один: сначала активность и период действия, потом условия по одному, и только затем взаимодействие с соседними правилами. Начинать с последнего пункта - обычная ошибка: чаще всего дело в простом невыполненном условии.

Купон - это не отдельный механизм скидок, а всего лишь условие применения правила. Правило с купоном работает точно так же, как обычное, но включается только после ввода кода покупателем, и в каталоге до этого момента не показывается.

Типичные проблемы

Скидка не применяется к заказу.

Не выполняется хотя бы одно условие правила. Условия объединяются логикой «и», и одного несовпадения достаточно.

Применилось не то правило, что ожидали.

Порядок задан сортировкой, а не размером скидки. Правило с флагом «последнее» обрывает всю цепочку ниже.

Скидка есть в корзине, но не видна в каталоге.

У правила выключен показ в каталоге. Это настройка самого правила, а не компонента витрины.

Скидки складываются, хотя не должны.

Ни у одного правила не стоит признак последнего. Без него применяются все подходящие правила подряд.

Правило работает не у всех покупателей.

В условиях указана группа пользователей. Гость и авторизованный посетитель попадают в разные группы.

Частые вопросы

Чем правило корзины отличается от цены со скидкой?

Цена со скидкой - это отдельный тип цены у товара, правило считается на корзине по условиям. Первое видно всегда, второе зависит от состава заказа.

Можно ли задать своё условие кодом?

Да, своим классом условия, зарегистрированным в модуле продаж. Он появляется в конструкторе наравне со штатными.

Как проверить правило, не оформляя заказ?

Расчётом скидок на загруженном заказе из кода: результат показывает список сработавших правил. Это быстрее, чем повторять сценарий покупателя.

Почему скидка меняется после смены доставки?

Условия могут учитывать доставку и оплату. Пересчёт идёт на каждое изменение заказа, и набор подходящих правил меняется вместе с ним.

Смежное

Первоисточник