Розроблення кастомізованої вітрини для дилерів 1С-Bitrix
Дилер працює не як роздрібний покупець. Йому потрібен свій прайс-лист з персональними цінами, можливість оформляти замовлення від імені кінцевого клієнта, бачити остатки по складах і вивантажувати дані у свою облікову систему. Стандартна вітрина інтернет-магазину Bitrix не покриває жодного з цих сценаріїв без серйозної доробки. Задача — побудувати B2B-розділ, який працює паралельно з роздрібним магазином на тому ж інфоблоці товарів.
Архітектура: мультисайтовість або розділ
Два підходи до розділення роздрібу й дилерів:
Мультисайт — окремий сайт у Bitrix (s2) з власним доменом (dealer.myshop.by). Дилерський сайт використовує той же інфоблок каталогу, але свій тип цін та шаблон. Перевага: повна ізоляція дизайну, налаштувань кошика й оформлення замовлення. Недолік: дублювання шаблонів компонентів.
Розділ на основному сайті — /dealer/ з перевіркою належності користувача до групи «Дилери». Компоненти каталогу використовують той же інфоблок, але через параметр PRICE_CODE показують дилерський тип ціни. Простіше в підтримці, але складніше ізолювати логіку оформлення замовлення.
Для більшості проектів мультисайт — правильний вибір. Він дає чисте розділення бізнес-логіки без умовних конструкцій у шаблонах.
Персональні ціни та типи цін
Bitrix підтримує до 8 типів цін у стандартній ліцензії та невеликі кількість — у «Бізнес» та вище. Для дилерської вітрини створюється окремий тип ціни (наприклад, DEALER_PRICE), прив'язаний до групи користувачів «Дилери».
Персоналізація за дилером реалізується через додаткові типи цін — по одному на кожного крупного дилера — або через знижки каталогу, прив'язані до групи користувача. Перший варіант масштабується до 20–30 дилерів, далі управління стає неможливим. Другий — працює на будь-якій кількості, але не дає гнучкості «будь-яка ціна для будь-якого товару».
Для індивідуальних прайсів з тисячами позицій використовуйте користувацьке властивість замовлення з ціною, розрахованою на льоту з базової дилерської ціни й персонального коефіцієнта. Коефіцієнт зберігається у UF-полі користувача (UF_DEALER_DISCOUNT), ціна перераховується в обробнику OnGetOptimalPrice.
Остатки по складах
Роздрібний покупець бачить «У наявності / Немає в наявності». Дилеру потрібні точні цифри по складах.
Модуль catalog.store зберігає остатки у таблиці b_catalog_store_product (поля PRODUCT_ID, STORE_ID, AMOUNT). Склади — у b_catalog_store. Компонент catalog.store.amount виводить остатки, але його стандартний шаблон не підходить для B2B — немає групування за регіонами, немає фільтрації по складах, доступних конкретному дилеру.
Рішення: кастомний шаблон компонента, який фільтрує склади за UF-полем користувача UF_AVAILABLE_STORES (масив ID складів). Дилер з Мінська бачить склади «Мінськ-1» та «Мінськ-2», дилер з Гомеля — «Гомель-центральний».
Замовлення від імені клієнта
Дилер оформляє замовлення й указує кінцевого отримувача. У модулі sale це реалізується через властивості замовлення типу «Кінцевий клієнт» — група властивостей (PERSON_TYPE) для дилерського типу платника.
Створіть тип платника «Дилер» з полями: реквізити дилера (заповняються автоматично з профілю) + блок «Кінцевий отримувач» (ФІО, адреса, телефон). В обробнику OnSaleOrderBeforeSaved перевіряйте, що дилер не може оформити замовлення за роздрібним типом платника.
Вивантаження даних
Дилери запитують прайс-лист у Excel/CSV для завантаження у свою 1С. Реалізується через кастомну сторінку /dealer/export/, яка генерує файл на основі \Bitrix\Catalog\PriceTable::getList() з фільтром за дилерським типом ціни. Формат Excel — через бібліотеку PhpSpreadsheet (встановлюється через Composer).
Для автоматичної вивантаження дайте дилеру API-ендпоінт з авторизацією за токеном. Ендпоінт повертає JSON з товарами, цінами й остатками — дилер забирає його за cron.
Терміни
| Компонент | Термін |
|---|---|
| Мультисайт + базовий каталог з дилерськими цінами | 3–4 дні |
| Персональні коефіцієнти + остатки по складах | 3–4 дні |
| Замовлення від імені клієнта + вивантаження | 2–3 дні |
| Тестування та налагодження прав доступу | 1–2 дні |
| Усього | 1–2 тижні |







