Розробка конструктора наборів товарів 1С-Bitrix
Покупець хоче зібрати подарункову кошик з 5 позицій на вибір. Або скомплектувати комп'ютер із сумісних комплектуючих. Або вибрати шини + диски + TPMS як одне замовлення. Жоден зі стандартних компонентів Bitrix — ні bitrix:catalog.element, ні торгові пропозиції — не вирішує це завдання. Потрібен конструктор наборів.
Чим конструктор відрізняється від торгових пропозицій
Торгові пропозиції (SKU) в Bitrix — це варіації одного товару: розмір, колір. Конструктор наборів — це комбінація різних товарів з різних категорій, зібрана в одне замовлення з загальною ціною. Іноді з фіксованою кількістю позицій на кожну «ячейку», іноді з довільним вибором.
Приклади:
- Подарункова набір: вибери 3 із 20 варіантів косметичних засобів
- Конструктор ПК: вибери процесор + материнську плату + RAM (з перевіркою сумісності)
- Комбо-набір: бургер + напиток + гарнір (один товар з кожної групи)
Структура даних
Набір — це окрема сутність. Варіант реалізації — інфоблок «Набори» з прив'язкою до товарів каталогу.
Інфоблок наборів (IBLOCK_SETS):
-
SET_NAME— назва набору -
SET_DESCRIPTION— опис -
SLOTS— JSON з описанням ячейок набору (множественна властивість типу «Рядок» або окрема таблиця) -
DISCOUNT_TYPE— тип скидки набору (percent/fixed) -
DISCOUNT_VALUE— розмір скидки
Структура слота (ячейки) в JSON:
{
"slot_id": 1,
"name": "Основна блюдо",
"required": true,
"min_qty": 1,
"max_qty": 1,
"product_filter": {
"IBLOCK_ID": 5,
"SECTION_ID": [12, 13]
}
}
Для складних проектів (конструктор ПК) краще зберігати слоти в окремій таблиці:
CREATE TABLE b_set_slots (
ID SERIAL PRIMARY KEY,
SET_ID INT NOT NULL REFERENCES b_iblock_element(ID),
SLOT_NAME VARCHAR(255),
REQUIRED BOOLEAN DEFAULT TRUE,
MIN_QTY INT DEFAULT 1,
MAX_QTY INT DEFAULT 1,
SORT INT DEFAULT 100
);
CREATE TABLE b_set_slot_products (
SLOT_ID INT NOT NULL REFERENCES b_set_slots(ID),
PRODUCT_ID INT NOT NULL REFERENCES b_iblock_element(ID),
PRIMARY KEY (SLOT_ID, PRODUCT_ID)
);
Логіка вибору й розрахунок ціни
Користувацький інтерфейс конструктора — послідовні кроки або єдина сторінка з вертикальними групами. На кожному кроці — список товарів для даного слота.
Розрахунок итогової ціни відбувається на клієнті (швидко, без сервера) й підтверджується на сервері (при додаванні в кошик):
function calcSetTotal(selectedProducts) {
let total = selectedProducts.reduce((sum, p) => sum + p.price * p.qty, 0);
// застосуємо скидку набору
if (setDiscount.type === 'percent') {
total = total * (1 - setDiscount.value / 100);
} else {
total = total - setDiscount.value;
}
return Math.max(0, total);
}
Додавання набору в кошик
Стандартний API кошика Bitrix не вміє додавати «пов'язані» позиції, що складають набір. Потрібна користувацька логіка:
use Bitrix\Sale\Basket;
use Bitrix\Sale\BasketItem;
$basket = Basket::loadItemsForFUser(CSaleBasket::GetBasketUserID(), SITE_ID);
$setBasketCode = 'set_' . uniqid(); // унікальний ідентифікатор набору
foreach ($selectedProducts as $product) {
$item = $basket->createItem('catalog', $product['PRODUCT_ID']);
$item->setFields([
'QUANTITY' => $product['QTY'],
'PRODUCT_PRICE_ID' => $product['PRICE_ID'],
'CUSTOM_PRICE' => 'Y',
'PRICE' => $product['PRICE'],
// користувацьке поле для групування позицій набору
'PROPS' => [['NAME' => 'SET_CODE', 'VALUE' => $setBasketCode]],
]);
}
$basket->save();
У кошику позиції набору відображаються згруповано за SET_CODE. Для цього шаблон кошика (bitrix:sale.basket.basket) потрібно кастомізувати — додати групування за властивістю набору.
Перевірка сумісності
Для конструкторів технічних виробів (ПК, автозапчастини, меблі під розмір) потрібна перевірка сумісності між вибраними позиціями. Матриця сумісності зберігається в кастомній таблиці:
CREATE TABLE b_compatibility_rules (
ID SERIAL PRIMARY KEY,
PRODUCT_A_ID INT NOT NULL,
PRODUCT_B_ID INT NOT NULL,
COMPATIBLE BOOLEAN DEFAULT TRUE,
REASON TEXT
);
При кожному виборі товару AJAX-запит до PHP-контролера перевіряє сумісність з уже вибраними позиціями й повертає список несумісних варіантів для блокування в UI:
public function checkCompatibilityAction(int $productId, array $selectedIds): array {
$incompatible = [];
foreach ($selectedIds as $id) {
$rule = CompatibilityTable::getRow([
'filter' => [
['PRODUCT_A_ID' => $productId, 'PRODUCT_B_ID' => $id],
['COMPATIBLE' => false],
]
]);
if ($rule) {
$incompatible[] = ['product_id' => $id, 'reason' => $rule['REASON']];
}
}
return $incompatible;
}
Збережені конфігурації
Користувач може захотіти зберегти зібраний набір і повернутися до нього. Збереження конфігурації в користувацькому аккаунті:
CREATE TABLE b_user_set_configs (
ID SERIAL PRIMARY KEY,
USER_ID INT NOT NULL,
SET_ID INT NOT NULL,
CONFIG_NAME VARCHAR(255),
PRODUCTS JSONB NOT NULL,
DATE_CREATE TIMESTAMP DEFAULT NOW()
);
Користувач видить свої конфігурації в особистому кабінеті й може додати будь-яку з них у кошик одним кліком.
Графіки виконання
| Тип конструктора | Що входить | Строк |
|---|---|---|
| Подарункова набір (простий вибір) | UI + кошик + скидка набору | 2–3 тижні |
| Комбо з групами (фаст-фуд стиль) | + групи слотів, обов'язкові позиції | 3–5 тижнів |
| Конструктор з сумісністю | + матриця сумісності, перевірки | 5–8 тижнів |
| + Збережені конфігурації | + ЛК, історія, шеринг конфігурації | +2–3 тижні |
Конструктор наборів збільшує середній чек: користувач, який збирає комплект, витрачає більше, ніж той, хто купує один товар. Інструмент працює тим краще, чим проще й зрозуміліше інтерфейс вибору.







