Как реализовать несколько бонусных программ для одной дисконтной карты в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет Торговля и дистрибуция
← На главную

В практической деятельности торговых предприятий часто возникает потребность в запуске сложных программ лояльности. Типичный сценарий: по одной и той же карте клиента необходимо параллельно вести учет основных бонусов (начисляются за регулярные покупки, активируются через 14 дней, позволяют оплатить до 50% чека) и акционных бонусов (дарятся к праздникам, имеют жесткий срок сгорания, позволяют оплатить не более 20% чека). При этом общая скидка по обеим программам в одном чеке не должна превышать установленный лимит в 50%.

Однако в стандартной архитектуре конфигураций «1С:Управление нашей фирмой», «1С:Розница» и «1С:Управление торговлей» заложено классическое ограничение: одна дисконтная карта может быть привязана только к одной бонусной программе. Регистр накопления бонусных баллов хранит общую сумму, не разделяя ее на «субсчета» с разными правилами списания. В этой статье мы подробно разберем, как обойти это ограничение программными и организационными методами.

Решение 1. Создание HTTP-сервиса в 1С для внешних касс (Архитектурный подход)

Если в магазинах используются внешние кассовые программы (например, Frontol, Set Retail) или кассы, способные отправлять веб-запросы, наилучшим решением будет вынос логики расчета бонусов на сторону back-end базы 1С через HTTP-сервис. Именно этот вариант выбрал автор обсуждаемой темы.

Выясним логику работы этой схемы: база 1С выступает в роли единого процессингового центра лояльности. Касса не хранит балансы локально, а запрашивает их у 1С в режиме реального времени при сканировании карты.

Проанализируем пример кода для HTTP-сервиса в 1С, который принимает запрос от кассы, рассчитывает остатки по категориям бонусов и возвращает результат в формате JSON:


// Функция-обработчик GET-запроса HTTP-сервиса лояльности
Функция ПолучитьБалансБонусов(Запрос)
    
    ПараметрыЗапроса = Запрос.ПараметрыЗапроса;
    КодКарты = ПараметрыЗапроса.Получить("CardCode");
    
    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    
    // Формируем запрос к регистру с учетом нового измерения "ВидБонусов"
    ТекстЗапроса = 
    "ВЫБРАТЬ
    |	БонусныеБаллыОстатки.ВидБонусов КАК ВидБонусов,
    |	СУММА(БонусныеБаллыОстатки.НачисленоОстаток) КАК Остаток
    |ИЗ
    |	РегистрНакопления.БонусныеБаллы.Остатки(, ДисконтнаяКарта.Код = &КодКарты) КАК БонусныеБаллыОстатки
    |СГРУППИРОВАТЬ ПО
    |	БонусныеБаллыОстатки.ВидБонусов";
    
    ЗапросБД = Новый Запрос(ТекстЗапроса);
    ЗапросБД.УстановитьПараметр("КодКарты", КодКарты);
    РезультатТаблица = ЗапросБД.Выполнить().Выгрузить();
    
    // Заполняем структуру ответа для кассового ПО
    ДанныеБонусов = Новый Структура;
    ДанныеБонусов.Вставить("CardCode", КодКарты);
    ДанныеБонусов.Вставить("MainBalance", 0);
    ДанныеБонусов.Вставить("PromoBalance", 0);
    
    Для Каждого Строка Из РезультатТаблица Цикл
        Если Строка.ВидБонусов = ПредопределенноеЗначение("Перечисление.ВидыБонусныхБаллов.Основной") Тогда
            ДанныеБонусов.MainBalance = Строка.Остаток;
        ИначеЕсли Строка.ВидБонусов = ПредопределенноеЗначение("Перечисление.ВидыБонусныхБаллов.Акционный") Тогда
            ДанныеБонусов.PromoBalance = Строка.Остаток;
        КонецЕсли;
    КонецЦикла;
    
    // Запись структуры в JSON
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, ДанныеБонусов);
    
    Ответ.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть());
    Возврат Ответ;
    
КонецФункции

При оплате чека касса отправляет встречный POST-запрос на списание нужного количества баллов каждого типа. В 1С создается документ списания, фиксирующий движения по регистру в разрезе видов бонусов.

Решение 2. Доработка типовой конфигурации через расширение

Если расчеты производятся непосредственно в Рабочем месте кассира (РМК) самой программы 1С, нам потребуется разработать расширение конфигурации, чтобы сохранить типовую базу на поддержке. Разберем этот процесс по шагам:

  1. Модификация метаданных: Через расширение добавляем новое измерение ВидБонусов (тип: ПеречислениеСсылка или СправочникСсылка) в регистр накопления БонусныеБаллы (в разных конфигурациях название может незначительно отличаться, например, БонусыНачисленные).
  2. Доработка механизмов начисления: Переопределяем модули проведения документов начисления бонусов. При автоматическом начислении за покупку указываем вид «Основной». При ручном начислении по акциям или через маркетинговые кампании записываем вид «Акционный».
  3. Переписка логики расчета скидок в РМК: Корректируем общий модуль расчета скидок при оформлении чека ККМ. Программа должна запросить остатки по регистру в разрезе нового измерения и применить следующий алгоритм лимитов:

Рассмотрим алгоритм распределения списания баллов в модуле расчета чека:


// Процедура рассчитывает максимально допустимые суммы списания баллов
Функция РассчитатьЛимитыСписания(СуммаЧека, ОстатокОсновных, ОстатокАкционных) Экспорт
    
    Лимиты = Новый Структура("СписатьОсновных, СписатьАкционных", 0, 0);
    
    // Шаг 1. Ограничение по акционным бонусам (максимум 20% от чека)
    МаксАкционных = Округлить(СуммаЧека * 0.20, 2);
    Лимиты.СписатьАкционных = Мин(ОстатокАкционных, МаксАкционных);
    
    // Шаг 2. Ограничение по основным бонусам (максимум 50% от чека)
    МаксОсновных = Округлить(СуммаЧека * 0.50, 2);
    
    // Шаг 3. Контроль суммарного лимита оплаты бонусами (не более 50% от чека)
    // Сначала расходуем более "приоритетные" акционные баллы, у которых ограничен срок жизни
    ДоступныйЛимитОсновных = МаксОсновных - Лимиты.СписатьАкционных;
    Лимиты.СписатьОсновных = Мин(ОстатокОсновных, ДоступныйЛимитОсновных);
    
    Возврат Лимиты;
    
КонецФункции

Этот код гарантирует, что система автоматически распределит списание средств клиента, отдавая приоритет сгорающим акционным баллам, но при этом строго удержит итоговую скидку в пределах установленного порога в 50%.

Решение 3. Обходной путь без программирования (штатными средствами 1С)

Если у вас нет ресурсов на программирование и доработку конфигурации, мы можем предложить альтернативный вариант настройки маркетинговых правил в стандартном функционале 1С. Вместо создания виртуального «акционного кошелька» бонусов маркетологи используют связку автоматических скидок и сегментации покупателей:

В такой схеме покупатель автоматически получит прямую скидку 20% по акции прямо в чеке, а оставшиеся до разрешенного лимита 30% стоимости покупки сможет доплатить своими стандартными бонусами со своего единственного накопительного счета. Эта схема полностью закрывает бизнес-требование, не требуя ни одной строчки программного кода.

Решение 4. Использование специализированных CRM-модулей и внешнего процессинга

Для крупных розничных сетей ведение сложной лояльности непосредственно в транзакционной базе 1С не рекомендуется из-за резкого роста нагрузки на СУБД в моменты пикового наплыва покупателей. В таких случаях целесообразно рассмотреть два альтернативных пути:

Мы проанализировали ключевые способы реализации параллельных бонусных программ для одной дисконтной карты в среде 1С. Выбор конкретного метода зависит от технических ресурсов вашей компании, используемого кассового оборудования и критичности сохранения типовой конфигурации 1С без изменений.

← На главную