В практической деятельности торговых предприятий часто возникает потребность в запуске сложных программ лояльности. Типичный сценарий: по одной и той же карте клиента необходимо параллельно вести учет основных бонусов (начисляются за регулярные покупки, активируются через 14 дней, позволяют оплатить до 50% чека) и акционных бонусов (дарятся к праздникам, имеют жесткий срок сгорания, позволяют оплатить не более 20% чека). При этом общая скидка по обеим программам в одном чеке не должна превышать установленный лимит в 50%.
Однако в стандартной архитектуре конфигураций «1С:Управление нашей фирмой», «1С:Розница» и «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С создается документ списания, фиксирующий движения по регистру в разрезе видов бонусов.
Если расчеты производятся непосредственно в Рабочем месте кассира (РМК) самой программы 1С, нам потребуется разработать расширение конфигурации, чтобы сохранить типовую базу на поддержке. Разберем этот процесс по шагам:
ВидБонусов (тип: ПеречислениеСсылка или СправочникСсылка) в регистр накопления БонусныеБаллы (в разных конфигурациях название может незначительно отличаться, например, БонусыНачисленные).Рассмотрим алгоритм распределения списания баллов в модуле расчета чека:
// Процедура рассчитывает максимально допустимые суммы списания баллов
Функция РассчитатьЛимитыСписания(СуммаЧека, ОстатокОсновных, ОстатокАкционных) Экспорт
Лимиты = Новый Структура("СписатьОсновных, СписатьАкционных", 0, 0);
// Шаг 1. Ограничение по акционным бонусам (максимум 20% от чека)
МаксАкционных = Округлить(СуммаЧека * 0.20, 2);
Лимиты.СписатьАкционных = Мин(ОстатокАкционных, МаксАкционных);
// Шаг 2. Ограничение по основным бонусам (максимум 50% от чека)
МаксОсновных = Округлить(СуммаЧека * 0.50, 2);
// Шаг 3. Контроль суммарного лимита оплаты бонусами (не более 50% от чека)
// Сначала расходуем более "приоритетные" акционные баллы, у которых ограничен срок жизни
ДоступныйЛимитОсновных = МаксОсновных - Лимиты.СписатьАкционных;
Лимиты.СписатьОсновных = Мин(ОстатокОсновных, ДоступныйЛимитОсновных);
Возврат Лимиты;
КонецФункции
Этот код гарантирует, что система автоматически распределит списание средств клиента, отдавая приоритет сгорающим акционным баллам, но при этом строго удержит итоговую скидку в пределах установленного порога в 50%.
Если у вас нет ресурсов на программирование и доработку конфигурации, мы можем предложить альтернативный вариант настройки маркетинговых правил в стандартном функционале 1С. Вместо создания виртуального «акционного кошелька» бонусов маркетологи используют связку автоматических скидок и сегментации покупателей:
МаксимальныйРазмерСкидки равным 50%.В такой схеме покупатель автоматически получит прямую скидку 20% по акции прямо в чеке, а оставшиеся до разрешенного лимита 30% стоимости покупки сможет доплатить своими стандартными бонусами со своего единственного накопительного счета. Эта схема полностью закрывает бизнес-требование, не требуя ни одной строчки программного кода.
Для крупных розничных сетей ведение сложной лояльности непосредственно в транзакционной базе 1С не рекомендуется из-за резкого роста нагрузки на СУБД в моменты пикового наплыва покупателей. В таких случаях целесообразно рассмотреть два альтернативных пути:
Мы проанализировали ключевые способы реализации параллельных бонусных программ для одной дисконтной карты в среде 1С. Выбор конкретного метода зависит от технических ресурсов вашей компании, используемого кассового оборудования и критичности сохранения типовой конфигурации 1С без изменений.