Удалить товары из корзины, если есть определенные товары.

Просмотров: 3503

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

Корзина битрикс

Для начала создадим новое свойство для товаров каталога, в моем случае называется "Покупается отдельно" с кодом "ATT_B_ONLY". Обязательно, проставляем ему галку Значение добавляется в корзину

Корзина битрикс

Выводим оповещение о удалении в корзине

Переходим в шаблон корзины (sale.basket.basket) и создаем тут файл result_modifier.php, в который добавляем следующий код:

foreach ($arResult['GRID']['ROWS'] as $basketItem) {
    foreach ($basketItem['PROPS'] as $basketItemProp) {
        if ($basketItemProp['CODE'] == 'ATT_B_ONLY') {
             $arResult['BASKET_ITEM_ONLY'][] = $basketItem['NAME'];
        }
    }
}
  • Пребрали массив с товарами корзины.
  • Внутри перебора, довыбрали свойства товаров.
  • Если обнаружен товар со свойством "ATT_B_ONLY" добавили его название в ключ массива $arResult['BASKET_ITEM_ONLY'].
Ссылку на подробную информацию можно вывести на этой же странице, что бы не перенаправлять пользователя на новую. Достаточно воспользоваться заметкой
Показ страницы сайта в боковом слайдере

В template.php, добавляем оповещение с перечислением товаров из $arResult['BASKET_ITEM_ONLY']


В вашей корзине есть товары:
<strong>
<? echo implode(', ', $arResult['BASKET_ITEM_ONLY']) ?>
</strong>
Если продолжите оформление, другие товары будут удалены из корзины.<br>
<span id="show_coopon_about_panel">
Подробнее о купонах
</span>

Удаляем определенные товары из оформления заказа

Теперь, нам нужно удалить товары, у которых нет свойства с кодом "ATT_B_ONLY", из оформления заказа.

В шаблоне оформления заказа (sale.order.ajax) открываем или создаем (если еще нет) файл result_modifier.php и добавляем в него

foreach ($arResult['BASKET_ITEMS'] as $basketItem) {
    foreach ($basketItem['PROPS'] as $basketItemProp) {
        if ($basketItemProp['CODE'] !== 'ATT_B_ONLY') {
            CSaleBasket::Delete($basketItem['ID']);
        }
    }
}

Здесь, ровно тоже самое: проходимся по товарам заказа, внутри по свойствам товара и если нет свойства с кодом "ATT_B_ONLY" удаляем товар (запись корзины) методом CSaleBasket::Delete

Можно дополнить условие, обработав товары методом CSaleBasket::Update - переложив не соответсвующие товары в отложенные корзины. Таким образом, пользователю не придется снова искать их в каталоге, сможет просто найти не попавшие в выборку товары в отложенных.

Михаил Базаров 12.08.2022
Улучшение

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

Задача. Если в корзину добавлены товары со свойством "'Это генератор купона" (ETO_GENERATOR_KUPONA), надо удалить все другие товары из корзины.
Код
foreach ($arResult['BASKET_ITEMS'] as $basketItem) {
    $res = CIBlockElement::GetList(
        array(),
        array('ID' => $basketItem['PRODUCT_ID']),
        false,
        false,
        array('PROPERTY_ETO_GENERATOR_KUPONA')
    );
    while ($ob = $res->GetNext()) {
        if ($ob['PROPERTY_ETO_GENERATOR_KUPONA_VALUE']) {
            $arCuponsGoods[] = $basketItem['ID'];
        } else {
            $arNotCuponsGoods[] = $basketItem['ID'];
        }
    }
}

if (count($arCuponsGoods) > 0) {
    foreach ($arNotCuponsGoods as $value) {
        if (!in_array($value, $arCuponsGoods)) {
            $arrForDelItems[] = $value;
        }
    }
}

if(count($arrForDelItems) > 0) {
    foreach ($arrForDelItems as $del) {
        CSaleBasket::Delete($del);
    }
}

Пояснение:
- Создаем два массива, с товарами которые купоны и товарми которые не купоны ($arCuponsGoods и $arNotCuponsGoods)
- Если $arCuponsGoods не пустой, то создаем новый массив ($arrForDelItems) со списком кандидатов на удаление.
- Если $arrForDelItems не пустой, запускаем foreach с удалением записи корзины  CSaleBasket::Delete($del);.

Как генерировать скидочные купоны по информации заказа, можно посмотреть тут https://camouf.ru/blog-note/13295/
Наталья 22.02.2023
Добрый день, благодарю за рабочий код, все четко! Но есть момент.
На странице оформления заказа result_modifier и удаление товаров не отрабатывает при первой загрузке страницы. Если страницу перезагрузить, тогда отработает.

Пробовала и предложенный вариант удаления данных:
if(count($arrForDelItems) > 0) {
   foreach ($arrForDelItems as $del) {
       CSaleBasket::Delete($del);
   }
}

и новый на D7, когда мы получаем корзину, удаляем данные, сохраняем
$basket = Sale\Basket::loadItemsForFUser(Sale\Fuser::getId(), SITE_ID);
$orderBasket = $basket->getBasketItems();
..
if(count($arrForDelItems) > 0) {
foreach($orderBasket as $basketItem) {
     $id=$basketItem->getField('ID');
     if(in_array($id,$arrForDelItems)) {      
       $basketItem->delete();  
     }
 }
}
$basket->save();
$basket->refreshData();

результат одинаковый.
В чем может быть ошибка и куда смотреть? Спасибо
Михаил Базаров 22.02.2023
Затруднительно сказать. result_modifier вызывается перед выполнением шаблона, должен на первом же хите сработать.
Как-то, даже предположить не могу что именно у вас не так.