Налаштування комплектів товарів (бандлів) на 1С-Bitrix
Магазин хоче продавати ноутбук разом з мишкою та сумкою як один товар зі знижкою 10%. На перший погляд — просто новий елемент каталогу. Насправді це ламає облік залишків, обмін з 1С та розрахунок маржинальності, якщо реалізувати бандл «в лоб» як звичайний товар.
Два підходи до реалізації бандлів
Підхід 1: Бандл як окремий товар. Створюється елемент інфоблоку, залишки ведуться окремо. Простий, але проблемний: при продажу бандла залишки вхідних товарів не зменшуються. Покупець може купити мишку окремо та у складі бандла, що призведе до overselling.
Підхід 2: Бандл як віртуальний товар з дочірніми позиціями. Бандл у каталозі — це агрегат. Його «залишок» — мінімальна кількість серед вхідних компонентів. При продажу зменшуються залишки реальних дочірніх товарів. Це правильний підхід.
Bitrix підтримує другий підхід через тип продукту TYPE_SET = 4 в b_catalog_product. Поле TYPE в b_catalog_product приймає значення: 1 — простий товар, 2 — товар з торговими пропозиціями, 4 — комплект (SET).
Структура зберігання комплекту
Зв'язок «комплект → компонент» зберігається в таблиці b_catalog_product_set:
-
SET_ID— ID комплекту (ID елемента інфоблоку зTYPE = 4) -
ITEM_ID— ID товара-компонента -
QUANTITY— кількість у комплекті -
SORT— порядок відображення -
IS_REQUIRED— обов'язковий або опціональний (0/1)
Створення комплекту через API:
// Створюємо товар типу SET
$elementId = $iblock->Add([
'NAME' => 'Ноутбук + мишка + сумка',
'IBLOCK_ID' => CATALOG_IBLOCK_ID,
'ACTIVE' => 'Y',
]);
// Встановлюємо тип SET
\Bitrix\Catalog\ProductTable::update($elementId, ['TYPE' => \Bitrix\Catalog\ProductTable::TYPE_SET]);
// Додаємо компоненти
\Bitrix\Catalog\ProductSetTable::add([
'SET_ID' => $elementId,
'ITEM_ID' => $laptopId,
'QUANTITY' => 1,
'SORT' => 10,
'IS_REQUIRED' => 1,
]);
\Bitrix\Catalog\ProductSetTable::add([
'SET_ID' => $elementId,
'ITEM_ID' => $mouseId,
'QUANTITY' => 1,
'SORT' => 20,
'IS_REQUIRED' => 1,
]);
Розрахунок залишків та ціни бандла
Доступна кількість бандла — мінімум серед компонентів:
$components = \Bitrix\Catalog\ProductSetTable::getList([
'filter' => ['SET_ID' => $bundleId],
'select' => ['ITEM_ID', 'QUANTITY'],
])->fetchAll();
$available = PHP_INT_MAX;
foreach ($components as $c) {
$stock = \Bitrix\Catalog\ProductTable::getByPrimary(
$c['ITEM_ID'], ['select' => ['QUANTITY']]
)->fetch();
$available = min($available, floor((float)$stock['QUANTITY'] / $c['QUANTITY']));
}
Ціна бандла може бути задана окремо (знижка на комплект) або розраховуватися як сума цін компонентів. У Bitrix ціна бандла зберігається в b_catalog_price так само, як у звичайного товара. Якщо потрібна автоматична знижка N% на комплект — використовується правило кошика через b_sale_discount, не ручна ціна.
Списання залишків при продажу
При додаванні бандла в кошик через стандартний компонент bitrix:sale.basket.basket Bitrix автоматично розкриває комплект: в b_sale_basket створюються рядки для кожного компонента з прапорцем SET_PARENT_ID, який посилається на рядок бандла. При проведенні замовлення залишки списуються з кожного компонента окремо.
Проблема виникає при прямому додаванні через \Bitrix\Sale\Basket::create() — якщо не передати параметри TYPE = TYPE_SET та дочірні позиції, розкриття не відбудеться. Завжди використовуйте \Bitrix\Catalog\Product\Bundle::add() замість прямої роботи з кошиком.
Що налаштовуємо
- Створення товарів типу
TYPE_SETта заповненняb_catalog_product_set - Розрахунок доступної кількості за мінімумом серед компонентів
- Правило кошика для знижки на комплект через
b_sale_discount - Коректне додавання в кошик через
Bundle::add() - Інтерфейс управління комплектами в адміністративній частині
- Перевірку синхронізації з 1С: тип SET повинен коректно передаватися під час обміну







