Программное добавление скидки магазина в Битрикс по свойству инфоблока
Зачем программно создавать скидку магазина
Скидки интернет-магазина в «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 дней гарантии