Цены позиций в корзине. Конспект вебинара
Часть 1 / Часть 2 / Часть 3
Вебинар:
¶Цены позиций в корзине
Система хранит три «запчасти» цены для каждой позиции в корзине:
- цена, которая прописана в базе (каталоге) —
BASE_PRICE
; - величина «смещения» (см. ниже) —
DISCOUNT_PRICE
; - цена в корзине, которую видит клиент в публичной части и по которой он покупает —
PRICE
;
¶Главное правило суммы цен (или закон сохранения базовой цены)
Всегда, для каждой позиции в корзине, в том числе при установке ручной цены для позиции, должно выполняться правило:
BASE_PRICE = PRICE + DISCOUNT_PRICE
Если это правило нарушается, выписка чека происходит с ошибкой.
Пример типичной ситуации: не печатается чек, с ошибкой «несоответствие цены».
Действия: первое, что нужно глянуть — в базе поднять заказ и посмотреть, для каждой ли позиции в заказе выполняется правило суммирования цен (базовая цена точно равна сумме цены и скидки).
¶Смещения цен
Основная нагрузка по «смещениям» цены:
- наценке на товар;
- скидке на товар;
- округлению цен;
- комбинации выше упомянутых трансформаций
...ложится на DISCOUNT_PRICE
. При ручных ценах вычисление этой цены должно выполняться нами.
¶Ручные цены
Ручные цены — разные для разных клиентов — устанавливаются одним из двух способов, каждый из которых приводит к тому, что вместе с величиной цены устанавливается флаг CUSTOM_PRICE=Y
.
use Bitrix\Sale\BasketBase;
use Bitrix\Sale\Fuser;
use Bitrix\Sale\Registry;
/**
* @var $basketClass BasketBase
*/
// Получаем объект, заведующий реестрами
$registry = Registry::getInstance(Registry::REGISTRY_TYPE_ORDER);
// Получаем класс работы с корзинами
$basketClass = $registry->getBasketClassName();
// Читаем корзину для текущего покупателя
$basket = $basketClass::loadItemsForFUser(Fuser::getId(), SITE_ID);
// Создаём новую позицию в корзине
$basketItem = $basket->createItem('catalog', $productId);
// Ставим кастомную цену
// ... вариант 1:
$basketItem->setPrice(1175, true);
// ... вариант 2:
$basketItem->setFields([
'PRICE' => 1175,
'CUSTOM_PRICE' => 'Y'
]);
Напоминаю: если для позиции в корзине установлен флаг кастомной цены — CUSTOM_PRICE=Y
— система не будет пересчитывать DISCOUNT_PRICE
. Это ложится на наши плечи.
¶Неприятный нюанс с правилами корзины
Результаты действующих правил корзины фиксируются в базе данных только в момент фактического оформления заказа (есть правила корзины, мы видим их в админке, но в базе данных для корзины не оформленного заказа результата их выполнения не зафиксировано). До момента оформления заказа применённые правила корзины доступны через скомпилированный объект заказа, но в базе данных не отображены никак.
Планируется пофиксить в будущем.
Обсуждение статьи 1