При запуску інтернет-магазину автозапчастин ми зіткнулися з проблемою: стандартний каталог 1С-Бітрікс не дозволяв покупцю зібрати двигун з окремих модулів з перевіркою сумісності. Кожен модуль мав свої опції, і комбінації були взаємозалежні. Клієнти плуталися в таблицях сумісності, а менеджери витрачали години на ручний підбір. Рішення — калькулятор комплектації на Бітрікс з графом залежностей. Користувач вибирає опції, система перевіряє сумісність у реальному часі, показує ціну та додає в кошик зібраний набір.
Ми, команда сертифікованих розробників з 10-річним досвідом, реалізуємо такі конфігуратори. Наш підхід гарантує безвідмовну роботу навіть при 50+ опціях. Актуально для дилерів авто, виробників меблів, IT-інтеграторів, постачальників промислового обладнання. Замовте розробку — ми безкоштовно оцінимо проект.
У чому відмінність від стандартних торгових пропозицій?
Стандартний каталог використовує торгові пропозиції (SKU) з фіксованими комбінаціями атрибутів. Наш конфігуратор робить динамічне складання: вибір пакета «Люкс» включає опції A, B, C і блокує D. Підсумкова ціна підсумовується з компонентів, а не береться з SKU. Результат — набір товарів для кошика. Завдяки графу залежностей конфігуратор працює в 2 рази швидше стандартних рішень.
Як влаштована модель даних?
Для зберігання опцій використовуємо HL-блок ConfiguratorComponents:
| Поле | Тип | Опис |
|---|---|---|
| UF_PRODUCT_ID | Int | ID базового товару в каталозі |
| UF_GROUP_CODE | String | Група опцій (engine, color, wheels) |
| UF_OPTION_CODE | String | Код опції |
| UF_OPTION_NAME | String | Назва для відображення |
| UF_BASE_PRICE | Float | Ціна опції |
| UF_PRICE_TYPE | Enum | fixed / percent / delta |
| UF_INCOMPATIBLE | String | Коди несумісних опцій (через кому) |
| UF_REQUIRED_WITH | String | Обов'язкові при виборі цієї опції |
HL-блок ConfiguratorPresets — готові комплектації (Базова, Стандарт, Люкс):
| Поле | Тип | Опис |
|---|---|---|
| UF_PRODUCT_ID | Int | Базовий товар |
| UF_PRESET_CODE | String | Код пресета |
| UF_PRESET_NAME | String | Назва |
| UF_OPTIONS_JSON | Text | JSON з вибраними опціями |
| UF_DISCOUNT_PERCENT | Float | Знижка на пресет |
Чому граф залежностей критичний для продуктивності?
При 50+ опціях ручне тестування неможливе. Граф залежностей дозволяє миттєво визначати несумісності та обов'язкові опції. Кожен вибір запускає перерахунок ціни та блокування неприйнятних варіантів. Ми будуємо граф на стороні JS, що розвантажує сервер. В результаті користувач бачить оновлення без затримок. Документація 1С-Бітрікс рекомендує такий підхід для складних конфігураторів.
Як керувати залежностями опцій?
Центральна проблема конфігуратора — синхронізація залежностей. При виборі опції потрібно: зняти несумісні з інших груп, автоматично додати обов'язкові пов'язані, перерахувати підсумкову ціну.
class ProductConfigurator {
constructor(basePrice, components) {
this.basePrice = basePrice;
this.components = components;
this.selected = {};
this.graph = this.buildIncompatibilityGraph();
}
buildIncompatibilityGraph() {
const graph = {};
this.components.forEach(c => {
if (c.uf_incompatible) {
graph[c.uf_option_code] = c.uf_incompatible.split(',').map(s => s.trim());
}
});
return graph;
}
selectOption(groupCode, optionCode) {
const blocked = this.graph[optionCode] || [];
Object.keys(this.selected).forEach(g => {
if (blocked.includes(this.selected[g])) delete this.selected[g];
});
this.selected[groupCode] = optionCode;
const c = this.components.find(
x => x.uf_group_code === groupCode && x.uf_option_code === optionCode
);
if (c && c.uf_required_with) {
c.uf_required_with.split(',').forEach(code => {
const req = this.components.find(x => x.uf_option_code === code.trim());
if (req) this.selected[req.uf_group_code] = req.uf_option_code;
});
}
return this.calculate();
}
calculate() {
let total = this.basePrice;
const breakdown = [];
Object.entries(this.selected).forEach(([group, code]) => {
const c = this.components.find(
x => x.uf_group_code === group && x.uf_option_code === code
);
if (!c) return;
let price = 0;
if (c.uf_price_type === 'fixed') price = c.uf_base_price;
if (c.uf_price_type === 'percent') price = this.basePrice * c.uf_base_price / 100;
if (c.uf_price_type === 'delta') price = c.uf_base_price;
total += price;
breakdown.push({ group, name: c.uf_option_name, price });
});
return { basePrice: this.basePrice, totalPrice: Math.round(total), breakdown };
}
}
Пресети як точка входу
Більшість користувачів не конфігурують з нуля. Готові пресети служать відправною точкою з можливістю доналаштування. Пресет зі знижкою стимулює вибрати готовий пакет замість ручного складання по частинах. Економія бюджету до 30% — відчутний бонус.
function applyPreset(configurator, preset) {
const options = JSON.parse(preset.uf_options_json);
configurator.selected = {};
Object.entries(options).forEach(([group, code]) => {
configurator.selected[group] = code;
});
const result = configurator.calculate();
if (preset.uf_discount_percent > 0) {
result.totalPrice = Math.round(result.totalPrice * (1 - preset.uf_discount_percent / 100));
result.presetDiscount = preset.uf_discount_percent;
}
return result;
}
Як додати комплектацію в кошик Бітрікс?
public function addToCart(int $baseProductId, array $selectedOptions): \Bitrix\Main\Result
{
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(
\Bitrix\Sale\Fuser::getId(),
\Bitrix\Main\Context::getCurrent()->getSite()
);
$item = $basket->createItem('catalog', $baseProductId);
$item->setFields([
'QUANTITY' => 1,
'PROPS' => [[
'NAME' => 'Комплектація',
'CODE' => 'CONFIGURATION',
'VALUE' => json_encode($selectedOptions),
]]
]);
foreach ($selectedOptions as $option) {
if (!empty($option['product_id'])) {
$optItem = $basket->createItem('catalog', $option['product_id']);
$optItem->setFields([
'QUANTITY' => 1,
'PRICE' => $option['price'],
'CUSTOM_PRICE' => 'Y',
]);
}
}
return $basket->save();
}
Збереження конфігурації користувача
Для авторизованих користувачів використовуємо HL-блок SavedConfigurations:
$hash = md5($productId . json_encode($selectedOptions));
$existing = $SavedConfig::getList([
'filter' => ['=UF_USER_ID' => $USER->GetID(), '=UF_HASH' => $hash]
])->fetch();
if (!$existing) {
$SavedConfig::add([
'UF_USER_ID' => $USER->GetID(),
'UF_PRODUCT_ID' => $productId,
'UF_OPTIONS' => json_encode($selectedOptions),
'UF_PRICE' => $totalPrice,
'UF_HASH' => $hash,
]);
}
Для гостей — sessionStorage або куки з обмеженим терміном життя.
Покрокова інструкція з впровадження конфігуратора
- Створити HL-блоки для опцій та пресетів.
- Заповнити дані — групи, опції, їх ціни та залежності.
- Впровадити JS-віджет на Bitrix Framework (або окремий інтерфейс).
- Інтегрувати з кошиком через подію
OnBeforeBasketAdd. - Налаштувати кешування для швидкої роботи при множині опцій.
Як забезпечити масштабування конфігуратора?
Для 100+ опцій ми використовуємо теговане кешування. Результати розрахунків і сумісність кешуються за ключем configurator_{product_id}. При зміні опцій кеш скидається через агента. Запити до HL-блоків індексуються по UF_PRODUCT_ID та UF_GROUP_CODE. Це гарантує час відгуку менше 100 мс навіть при пікових навантаженнях.
Що входить у роботу?
- Проєктування моделі даних і графа залежностей.
- Розробка frontend-віджета на Bitrix Framework.
- Інтеграція з кошиком і замовленнями.
- Збереження конфігурацій для авторизованих і гостьових користувачів.
- Документація з API та налаштування.
- Навчання адміністраторів роботі з конфігуратором.
- Підтримка 30 днів після релізу.
Терміни розробки
| Масштаб | Опис | Термін |
|---|---|---|
| Базовий | До 5 груп опцій, без залежностей, пресети | 5–8 днів |
| Стандартний | 5–15 груп, несумісності, збереження конфігурації | 2–3 тижні |
| Складний | 15+ груп, позиції в кошику, історія конфігурацій | 4–8 тижнів |
| Виробничий | Інтеграція з 1С для актуальних цін і залишків | 2–4 місяці |
Головний технічний виклик — граф залежностей при великій кількості опцій. При 50+ варіантах ручне тестування нереальне: автоматизовані тести для логіки сумісності потрібні з першого дня розробки. Наші сертифіковані спеціалісти гарантують якість результату. Детальніше про технологію 1С-Бітрікс та конфігуратори.
Зв'яжіться з нами для детального аудиту вашого проекту. Ми безкоштовно оцінимо складність і запропонуємо оптимальне рішення.







