Какой правильный способ добавить товар в корзину пользователю, основываясь на определенном условии?

Как лучше реализовать функционал, в соответствии с которым при общем весе товаров в корзине менее 3кг нужно добавить товар, а если вес кратен 3кг (3кг, 6кг, 9кг и т.д.), то количество товара должно увеличиваться? Какую стратегию будет эффективнее использовать: подписку на события корзины (OnBeforeBasketAdd или OnBeforeBasketUpdate), или определить собственные правила взаимодействия с корзиной? Можно ли при этом добавить условие кратности, учитывая что в настоящее время предусмотрены операции равенства, больше, меньше и т.д.?
  • 10 июня 2024 г. 13:11
Ответы на вопрос 2
Для добавления товара в корзину пользователя на основе определенного условия, в данном случае веса товаров, можно воспользоваться событием OnBeforeBasketAdd или OnBeforeBasketUpdate. 

Вам нужно определить свою логику в обработчике события, где будет происходить проверка веса товаров в корзине. Если общий вес товаров в корзине меньше 3кг, то вы добавляете один товар. Если же вес кратен 3кг, то увеличиваете количество товара в корзине.

Кроме того, чтобы добавить условие кратности, например, увеличивать количество товара только при весе товаров кратном 3кг, вы можете использовать модульность (операция %) для определения кратности и добавления соответствующего товара. 

Итак, лучшим способом будет определить собственные правила взаимодействия с корзиной и использовать события OnBeforeBasketAdd или OnBeforeBasketUpdate для их обработки.
Вешайте обработчик на следующие события модуля sale: 
OnBasketUpdate
OnBasketDelete
OnBasketAdd

Т.е. на каждое изменение состава корзины.
Так как сам обработчик тоже будет менять состав, не забудьте добавить флаг, чтобы не уйти в рекурсию. Что-то вроде:
if (self::$Bypass) return;
        self::$Bypass = true;

        // здесь ваш код

        self::$Bypass = false;


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

Корзину бы я получал на месте, не оглядываясь на входящие параметры:
\Bitrix\Main\Loader::includeModule('sale');
        $basket = \Bitrix\Sale\Basket::loadItemsForFUser(
                \Bitrix\Sale\Fuser::getId(),
                \Bitrix\Main\Context::getCurrent()->getSite()
            );


Входящие параметры сделайте так:
public static function basketOperator ($_=0,$__=0,$___=0)
Похожие вопросы