Как правильно настроить правила работы с корзиной в Битрикс?

Существует правило «корзины»: <br/> <i>При покупке товара А, покупатель получает товар Б в подарок</i> — данное правило можно настроить с помощью стандартных методов. <br/> <br/> Однако, если условия выглядят так: <br/> <i>При покупке 2 товаров А, покупатель получает 2 товара Б в подарок</i>, то решить эту задачу стандартными методами уже не получится, хотя она кажется очевидной. <br/> <br/> Кажется, что эта задача довольно распространена, но я не нашел кейсов с её решением. <br/> Может быть, кто-то сталкивался с подобной проблемой и знает, как её можно решить? Буду признателен за помощь.
  • 13 сентября 2024 г. 8:45
Ответы на вопрос 2
Для настройки правила, при котором покупатель получает в подарок два товара Б при покупке двух товаров А, в Битрикс можно использовать различные подходы. Вот несколько вариантов решения этой задачи:

### Вариант 1: Использование маркетинговых акций

1. **Создание скидки**: Зайдите в раздел "Маркетинг" -> "Скидки" и создайте новую акцию.
2. **Условия**: 
   - Установите условия, что скидка применяется при покупке двух товаров А.
3. **Бонусное предложение**:
   - В настройках акции добавьте условие на получение товара Б в подарок (например, через виртуальный товар, который будет автоматически добавлен в корзину).

### Вариант 2: Использование правил корзины

1. **Разработка пользовательского правила**: Если стандартные инструменты не подходят, можно воспользоваться пользовательскими правилами.
   - Для этого потребуется использование API Битрикс или написание добавления в компонент корзины.
2. **Логика**:
   - Проверьте количество добавленных товаров А в корзину.
   - Если количество >= 2, добавьте в корзину два товара Б.
   - Важно обеспечить, чтобы данное правило запускалось при каждом изменении корзины (например, при добавлении товаров).

### Вариант 3: Использование модулей и сценариев

1. **Скрипты**: Можно написать PHP-скрипт, который будет проверять содержимое корзины и выполнять необходимые действия.
   - Этот скрипт может вызываться при обновлении корзины или на этапе оформления заказа.
2. **События**: Также возможно использовать события Битрикс (например, на событие `OnSaleOrderBeforeAdd`) для проверки корзины.

### Вариант 4: Обратитесь к разработчикам

1. Если ваша задача слишком сложна для стандартных возможностей и не хочется углубляться в программирование, вы можете рассмотреть возможность найма разработчика, который сможет реализовать нужное вам общее правило.
2. Разработчик сможет использовать API Битрикс для создания такого механизма и настройки его под ваши требования.

### Заключение

Выбор решения зависит от ваших технических навыков, доступных ресурсов и предпочтений. Если вы хотите использовать стандартные инструменты Битрикс, стоит рассмотреть акционные настройки; если они не подходят, подойдите к созданию пользовательского решения.
Нашел такой вариант, но не понимаю как получить данные у основго товара (который не подарок, товар А), по количеству 

// local/php_interface/init.php

// Кастомные скидочные правила
$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandlerCompatible(
    "sale",
    "OnCondSaleActionsControlBuildList",
    ["ProjectName\\EventHelpers\\SaleActionCustomPrice", "GetControlDescr"]
);


<?php

// local/php_interface/lib/eventhelpers/SaleActionCustomPrice.php

namespace ProjectName\EventHelpers;

use \Bitrix\Main\Loader;

class SaleActionCustomPrice  extends \CSaleActionCtrlAction
{
    /**
     * Получение имени класса
     * @return string
     */
    public static function GetClassName()
    {
        return __CLASS__;
    }

    /**
     * Получение ID условия
     * @return array|string
     */
    public static function GetControlID()
    {
        return "DiscountPriceType";
    }

    /**
     * Добавление пункта в список условий с указанием отдельной группы
     * @param $arParams
     * @return array
     * @throws \Bitrix\Main\ArgumentException
     * @throws \Bitrix\Main\LoaderException
     * @throws \Bitrix\Main\ObjectPropertyException
     * @throws \Bitrix\Main\SystemException
     */
    public static function GetControlShow($arParams)
    {
        $arControls = static::GetAtomsEx();
        $arResult = array(
            'controlgroup' => true,
            'group' =>  false,
            'label' => 'Кастомные правила',
            'showIn' => static::GetShowIn($arParams['SHOW_IN_GROUPS']),
            'children' =>  [array(
                'controlId' => static::GetControlID(),
                'group' => false,
                'label' => "Если тип цены не",
                'showIn' => static::GetShowIn($arParams['SHOW_IN_GROUPS']),
                'control' => array(
                    "Если тип цены не",
                    $arControls["PT"]
                )
            )]
        );

        return $arResult;
    }

    /**
     * Формирование данных для визуального представления условия
     * @param bool $strControlID
     * @param bool $boolEx
     * @return array
     * @throws \Bitrix\Main\ArgumentException
     * @throws \Bitrix\Main\LoaderException
     * @throws \Bitrix\Main\ObjectPropertyException
     * @throws \Bitrix\Main\SystemException
     */
    public static function GetAtomsEx($strControlID = false, $boolEx = false)
    {
        $boolEx = (true === $boolEx ? true : false);
        $priceList = [];
        if (Loader::includeModule('main')) {
            // Получение типов цен
            $arGroupPrice = \Bitrix\Catalog\GroupTable::getList([
                'select' => ['ID', 'NAME'],
                'cache' => [
                    'ttl' => 60,
                    'cache_joins' => true,
                ]
            ]);

            while ($el = $arGroupPrice->fetch()) {
                $priceList[$el['ID']] = $el['NAME'] . " [" . $el['ID'] . "]";
            }
        }

        $arAtomList = [
            "PT" => [
                "JS" => [
                    "id" => "PT",
                    "name" => "extra",
                    "type" => "select",
                    "values" => $priceList,
                    "defaultText" => "...",
                    "defaultValue" => "",
                    "first_option" => "..."
                ],
                "ATOM" => [
                    "ID" => "PT",
                    "FIELD_TYPE" => "string",
                    "FIELD_LENGTH" => 255,
                    "MULTIPLE" => "N",
                    "VALIDATE" => "list"
                ]
            ],
        ];
        if (!$boolEx) {
            foreach ($arAtomList as &$arOneAtom)
            {
                $arOneAtom = $arOneAtom["JS"];
            }
            if (isset($arOneAtom))
            {
                unset($arOneAtom);
            }
        }

        return $arAtomList;
    }

    /**
     * Функция должна вернуть колбэк того, что должно быть выполнено при наступлении условий
     * @param $arOneCondition
     * @param $arParams
     * @param $arControl
     * @param bool $arSubs
     * @return string
     */
    public static function Generate($arOneCondition, $arParams, $arControl, $arSubs = false)
    {
        return __CLASS__ . '::applyProductDiscount($row, "' . $arOneCondition["PT"] . '")';
    }

    /**
     * Логика кастомного условия
     * @param $row
     * @param $priceType
     * @return bool
     */
    public static function applyProductDiscount($row, $priceType)
    {
        return $priceType != $row['PRICE_TYPE_ID'];
    }
}
Похожие вопросы