Yandex Metrika
sanches.free 18 просмотров

Программное добавление скидки магазина в Битрикс по свойству инфоблока

Зачем программно создавать скидку магазина

Скидки интернет-магазина в «1С-Битрикс» хранятся как отдельные правила с деревом условий и действий. Через административный интерфейс это удобно для разовых акций, но при развёртывании шаблонного каталога или миграции быстрее один раз зашить создание правила в скрипт. Ниже — пример на D7: правило со скидкой в процентах на позиции корзины, если у товара в справочнике инфоблока выбраны определённые варианты свойства.

Идея примера

Берётся каталог-инфоблок с известным ID. Для списочного свойства с символьным кодом promo_badges перечисляются значения, у которых внешний идентификатор (XML_ID) входит в заранее заданный набор. Для каждого такого варианта строится условие вида CondIBProp:{IBLOCK_ID}:{PROPERTY_ID} с логикой равенства ID перечисления. Действие — скидка 7 % на корзину с объединением дочерних условий через OR внутри группы корзины.

  • Модули iblock и sale должны быть установлены и подключены.
  • ID инфоблока и код свойства подставьте под свою схему каталога.
  • Привязка к группам пользователей ниже дублирует типовой сценарий «все группы»; при необходимости сузьте список.

Готовый фрагмент PHP

Имена переменных и константы примера отличаются от исходного сниппета, чтобы не копировать его дословно; логика остаётся той же.

\Bitrix\Main\Loader::includeModule('iblock');
\Bitrix\Main\Loader::includeModule('sale');

$catalogIblockId = 18;
$discountTitle = 'Акция по меткам каталога';
$siteCode = 's1';
$promoPropertyCode = 'promo_badges';
$xmlIdWhitelist = array('warehouse_clearance', 'hot_deal_window', 'weekend_offer', 'loyalty_mark');

$allGroupIds = array();
$groups = \Bitrix\Main\GroupTable::getList(array('select' => array('ID')));
while ($row = $groups->fetch()) {
    $allGroupIds[] = (int)$row['ID'];
}

$basketConditions = array();
$propRows = \Bitrix\Iblock\PropertyTable::getList(array(
    'filter' => array('IBLOCK_ID' => $catalogIblockId, '=CODE' => $promoPropertyCode),
    'select' => array('ID', 'CODE'),
));
while ($prop = $propRows->fetch()) {
    $enums = \Bitrix\Iblock\PropertyEnumerationTable::getList(array(
        'filter' => array('PROPERTY_ID' => $prop['ID']),
    ));
    while ($item = $enums->fetch()) {
        if (!in_array($item['XML_ID'], $xmlIdWhitelist, true)) {
            continue;
        }
        $basketConditions[] = array(
            'CLASS_ID' => 'CondIBProp:' . $catalogIblockId . ':' . $prop['ID'],
            'DATA' => array(
                'logic' => 'Equal',
                'value' => $item['ID'],
            ),
        );
    }
}

$payload = array(
    'LID' => $siteCode,
    'NAME' => $discountTitle,
    'ACTIVE_FROM' => '',
    'ACTIVE_TO' => '',
    'ACTIVE' => 'Y',
    'SORT' => 100,
    'PRIORITY' => 1,
    'LAST_DISCOUNT' => 'Y',
    'XML_ID' => '',
    'ACTIONS_LIST' => array(
        'CLASS_ID' => 'CondGroup',
        'DATA' => array('All' => 'AND'),
        'CHILDREN' => array(
            array(
                'CLASS_ID' => 'ActSaleBsktGrp',
                'DATA' => array(
                    'Type' => 'Discount',
                    'Value' => 7.0,
                    'Unit' => 'Perc',
                    'Max' => 0,
                    'All' => 'OR',
                    'True' => 'True',
                ),
                'CHILDREN' => $basketConditions,
            ),
        ),
    ),
);

$addResult = \Bitrix\Sale\Internals\DiscountTable::add($payload);
if ($addResult->isSuccess()) {
    $newDiscountId = (int)$addResult->getId();
    foreach ($allGroupIds as $groupId) {
        \Bitrix\Sale\Internals\DiscountGroupTable::add(array(
            'ACTIVE' => 'Y',
            'GROUP_ID' => $groupId,
            'DISCOUNT_ID' => $newDiscountId,
        ));
    }
}

Что проверить после запуска

  • В разделе Маркетинг → Товарный маркетинг → Скидки появилось новое правило с заданным названием.
  • Если список условий остался пустым, проверьте код свойства, тип «список» и совпадение XML_ID вариантов.
  • Записи в DiscountGroupTable определяют видимость скидки для групп; для узкого сегмента замените выборку групп на явный массив ID.

Не хотите копаться сами?

Починю за 1-3 дня. Без предоплаты — оплата по результату.

15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии