Разработка функционала "собери набор" на 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка функционала "собери набор" на 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1181
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    813
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка функционала "собери набор" на 1С-Битрикс

«Собери набор» — более лёгкая вариация конструктора: пользователь не настраивает совместимость компонентов, а просто выбирает N товаров из фиксированного пула, получая скидку за комплектность. Типичные кейсы: «Выбери 3 из 10 косметических средств», «Скомплектуй пицца + напиток + десерт», «Подарочная коробка: выбери 5 конфет из 30 вкусов». Задача кажется проще конструктора ПК, но в реализации есть нетривиальные моменты.

Структура функционала

Функционал «собери набор» состоит из трёх компонентов:

  1. Страница набора — описание акции, правила (сколько выбрать, фиксированная или переменная цена)
  2. Интерфейс выбора — сетка доступных товаров с чекбоксами/кнопками добавления
  3. Корзина набора — mini-корзина на странице, показывающая текущий выбор и прогресс

Хранение данных набора

Набор описывается элементом инфоблока (или записью кастомной таблицы):

// Свойства инфоблока "Наборы"
'MIN_ITEMS'     => 3,      // минимум позиций для активации скидки
'MAX_ITEMS'     => 5,      // максимум позиций в наборе
'SET_PRICE'     => 1990,   // фиксированная цена набора (если задана)
'DISCOUNT_PCT'  => 15,     // скидка на сумму выбранных товаров (альтернатива)
'PRODUCTS'      => [12, 15, 18, 22, ...], // ID допустимых товаров (множественное св-во)
'ACTIVE_FROM'   => '2025-03-01', // срок акции
'ACTIVE_TO'     => '2025-04-01',

При большом пуле товаров (50+) список допустимых позиций задаётся не перечислением ID, а фильтром по разделу или тегу:

'ALLOWED_SECTIONS' => [5, 7, 12], // ID разделов, из которых можно выбирать
'ALLOWED_TAGS'     => ['promo-may', 'gift-set'],

Интерфейс выбора: ключевые UX-паттерны

Счётчик прогресса — показывает «Выбрано 2 из 3». Без него пользователь теряется. Реализация:

const maxItems = 3;
let selected = [];

function toggleProduct(productId, btn) {
    if (selected.includes(productId)) {
        selected = selected.filter(id => id !== productId);
        btn.classList.remove('selected');
    } else if (selected.length < maxItems) {
        selected.push(productId);
        btn.classList.add('selected');
    }
    updateProgress();
}

function updateProgress() {
    document.querySelector('.progress-text').textContent = `Выбрано ${selected.length} из ${maxItems}`;
    document.querySelector('.add-to-cart-btn').disabled = selected.length < minItems;
}

Блокировка лишних выборов — когда выбрано максимальное количество, остальные товары становятся неактивными (disabled), но с возможностью снять выбор с уже добавленных. Визуально: карточка серая, кнопка неактивна.

Превью набора — справа (на десктопе) или снизу (на мобильном) фиксированная панель со списком выбранных товаров, финальной ценой и кнопкой «В корзину».

Расчёт цены

Два режима ценообразования:

Фиксированная цена набора. Пользователь выбрал любые 3 товара — платит 999 рублей, независимо от цен отдельных позиций. В корзине добавляется специальная позиция «Набор» с ценой 999 р., без детализации по товарам.

Скидка на выбранные позиции. Сумма цен выбранных товаров умножается на коэффициент (например, ×0,85 при скидке 15%). В корзине каждый товар добавляется по сниженной цене.

Для второго варианта в Битрикс можно использовать правила корзины (b_sale_discount), но проще установить цену программно при добавлении в корзину через поле PRICE позиции и CUSTOM_PRICE => 'Y'.

Добавление в корзину

// Контроллер AJAX-запроса добавления набора в корзину
public function addSetToCartAction(int $setId, array $productIds): array {
    // 1. Валидация: все productIds допустимы для данного набора
    $setData = $this->loadSetData($setId);
    if (!$this->validateProducts($productIds, $setData)) {
        return ['success' => false, 'error' => 'Недопустимые товары'];
    }

    // 2. Проверка количества
    if (count($productIds) < $setData['MIN_ITEMS'] || count($productIds) > $setData['MAX_ITEMS']) {
        return ['success' => false, 'error' => 'Неверное количество позиций'];
    }

    // 3. Рассчитать цены
    $prices = $this->calcPrices($productIds, $setData);

    // 4. Добавить в корзину
    $setCode = 'bundle_' . $setId . '_' . uniqid();
    $basket  = \Bitrix\Sale\Basket::loadItemsForFUser(\CSaleBasket::GetBasketUserID(), SITE_ID);

    foreach ($productIds as $i => $pid) {
        $item = $basket->createItem('catalog', $pid);
        $item->setFields([
            'QUANTITY'     => 1,
            'CUSTOM_PRICE' => 'Y',
            'PRICE'        => $prices[$i],
            'BASE_PRICE'   => $prices[$i],
        ]);
        // Записываем SET_CODE в props для группировки в корзине
        $propCol = $item->getPropertyCollection();
        $propCol->setProperty(['CODE' => 'SET_CODE', 'VALUE' => $setCode]);
    }
    $basket->save();

    return ['success' => true, 'basket_count' => count($basket)];
}

Отображение в корзине и заказе

В корзине товары из одного набора должны отображаться как группа. Шаблон компонента bitrix:sale.basket.basket кастомизируется: товары группируются по SET_CODE, отображаются со скидкой и с возможностью редактировать набор (ссылка обратно на страницу конструктора).

В заказе (таблица b_sale_order_props) сохраняется SET_CODE как реквизит позиции — для корректной обработки возвратов и аналитики.

Ограничения по остаткам

Если товар из набора закончился на складе, его нельзя выбирать. Проверка остатков — через CCatalogProduct::GetByID() или через \Bitrix\Catalog\ProductTable:

$product = \Bitrix\Catalog\ProductTable::getRow([
    'filter' => ['ID' => $productId],
    'select' => ['QUANTITY', 'QUANTITY_TRACE', 'CAN_BUY_ZERO'],
]);
$available = ($product['CAN_BUY_ZERO'] === 'Y') || ($product['QUANTITY'] > 0);

Остатки кешируются на 5–10 минут — слишком частые запросы к базе при большом пуле товаров нагружают систему.

Аналитика

Набор — это конверсионный инструмент, его эффективность нужно измерять. Что отслеживать:

  • Сколько пользователей начали выбор (просмотр страницы набора)
  • Сколько завершили выбор и добавили в корзину
  • Сколько дошли до оплаты
  • Средний состав набора (какие товары выбираются чаще)

События передаются в Яндекс.Метрику или Google Analytics через dataLayer.push() при каждом шаге.

Сроки

Вариант Что входит Срок
Простой набор (фикс. цена) UI выбора + корзина + страница набора 1–2 недели
Со скидкой на позиции + ограничения + расчёт скидок, остатки, аналитика 2–4 недели
Несколько активных наборов + управление в админке, сроки акций 3–5 недель

Функционал «собери набор» работает лучше всего как ограниченная акция: срок действия создаёт urgency, а возможность выбора — ощущение персонализации. Это сочетание конвертирует лучше, чем статичный готовый набор по такой же цене.