При интеграции конфигурации «1С:Управление торговлей 11» с внешними фронт-офисными системами и кассовым программным обеспечением часто возникает задача выгрузки списка дисконтных карт. Для корректной работы кассового узла необходимы не только коды и штрихкоды карт, но и размер предоставляемой скидки, а также накопленная сумма продаж по клиенту.
Попытка соединить справочник КартыЛояльности и справочник СкидкиНаценки прямым левым соединением в одном запросе часто приводит к пустой выборке или нулевым результатам. Выясним причину этой архитектурной особенности и разберем по шагам, как правильно составить запросы для получения всех необходимых данных.
Для правильной сборки структуры запроса важно понимать, как хранятся данные системы лояльности в конфигурациях УТ 11 (11.2, 11.3, 11.4 и новее):
КартыЛояльности. Владельцем карты лояльности выступает справочник ВидыКартЛояльности.ДействиеСкидокНаценок. Источником в этом регистре выступает конкретный вид карты лояльности (Справочник.ВидыКартЛояльности).ВыручкаИСебестоимостьПродаж. Обороты суммируются не по конкретной пластиковой карте, а по контрагенту/партнеру (через аналитику учета по партнерам АналитикаУчетаПоПартнерам.Партнер).БонусныеБаллы.Рассмотрим первый этап: выборку всех активных карт лояльности и привязанных к их видам действующих скидок. Для этого обратимся к срезу последних регистра сведений ДействиеСкидокНаценок и соединим его со справочником КартыЛояльности по полю Владелец.
Проанализируем пример кода на 1С:
ЗапросСкидки = Новый Запрос;
ЗапросСкидки.Текст =
"ВЫБРАТЬ
| ДействиеСкидокНаценокСрезПоследних.СкидкаНаценка КАК СкидкаНаценка,
| ДействиеСкидокНаценокСрезПоследних.СкидкаНаценка.ЗначениеСкидкиНаценки КАК СкидкаЗначение,
| КартыЛояльности.Ссылка КАК КартаЛояльности,
| ДействиеСкидокНаценокСрезПоследних.СкидкаНаценка.УсловияПредоставления.(
| УсловиеПредоставления
| ) КАК УсловияПредоставленияСкидок
|ИЗ
| РегистрСведений.ДействиеСкидокНаценок.СрезПоследних(, ) КАК ДействиеСкидокНаценокСрезПоследних
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.КартыЛояльности КАК КартыЛояльности
| ПО ДействиеСкидокНаценокСрезПоследних.Источник = КартыЛояльности.Владелец
|ГДЕ
| ДействиеСкидокНаценокСрезПоследних.Статус = &СтатусСкидки
| И ТИПЗНАЧЕНИЯ(ДействиеСкидокНаценокСрезПоследних.Источник) = ТИП(Справочник.ВидыКартЛояльности)
| И КартыЛояльности.Статус = &СтатусКартыЛояльности
|
|УПОРЯДОЧИТЬ ПО
| КартыЛояльности.Наименование,
| СкидкаЗначение УБЫВ";
ЗапросСкидки.УстановитьПараметр("СтатусСкидки", Перечисления.СтатусыДействияСкидок.Действует);
ЗапросСкидки.УстановитьПараметр("СтатусКартыЛояльности", Перечисления.СтатусыКартЛояльности.Действует);
ТЗСкидкипоКартам = ЗапросСкидки.Выполнить().Выгрузить();
В данном запросе мы отбираем только те скидки и карты, которые находятся в статусе Действует, и отсекаем пустые или неактивные типы источников.
Теперь разберем второй этап — расчет суммарных накоплений по клиентам (партнерам), за которыми закреплены выбранные карты. Поскольку скидка может быть накопительной, необходимо рассчитать общую сумму продаж с учетом проведенных возвратов.
Посмотрим на пример запроса для расчета сумм накоплений по регистру ВыручкаИСебестоимостьПродаж:
ЗапросВыручка = Новый Запрос;
ЗапросВыручка.Текст =
"ВЫБРАТЬ
| КартыЛояльности.Ссылка КАК КартаЛояльности,
| СУММА(ЕСТЬNULL(ВыручкаИСебестоимостьПродаж.СуммаВВалютеВзаиморасчетов, 0)) КАК СуммаНакоплений
|ИЗ
| Справочник.КартыЛояльности КАК КартыЛояльности
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ВыручкаИСебестоимостьПродаж КАК ВыручкаИСебестоимостьПродаж
| ПО КартыЛояльности.Партнер = ВыручкаИСебестоимостьПродаж.АналитикаУчетаПоПартнерам.Партнер
|ГДЕ
| КартыЛояльности.Ссылка В (&МассивКартДляВыручки)
|
|СГРУППИРОВАТЬ ПО
| КартыЛояльности.Ссылка
|
|УПОРЯДОЧИТЬ ПО
| КартыЛояльности.Ссылка";
ЗапросВыручка.УстановитьПараметр("МассивКартДляВыручки", МассивКартДляВыручки);
ТЗНакопления = ЗапросВыручка.Выполнить().Выгрузить();
В параметре МассивКартДляВыручки передается массив ссылок на карты лояльности, полученный и очищенный от дублей после выполнения первого запроса.
После получения двух таблиц значений (первая со скидками и картами, вторая со статистикой продаж) сопоставляем их по полю КартаЛояльности в программном коде 1С.
Если для карт используется накопительная система с несколькими порогами (например, 5% при накоплении от 10 000 руб., 10% — от 50 000 руб.), при обработке таблиц необходимо сопоставить значение СуммаНакоплений с условиями предоставления скидки из справочника УсловияПредоставленияСкидокНаценок и выбрать финальный процент для выгрузки во фронт-офис.
В случаях, когда скидки жестко привязаны к реквизиту вида карты и не используют сложную динамику порогов, можно воспользоваться упрощенным запросом получения скидок вида карт лояльности:
ЗапросУпрощенный = Новый Запрос;
ЗапросУпрощенный.Текст =
"ВЫБРАТЬ
| ВидыКартЛояльностиСкидкиНаценки.Ссылка КАК ВидКарты,
| СкидкиНаценки.ЗначениеСкидкиНаценки КАК РазмерСкидки
|ИЗ
| Справочник.СкидкиНаценки КАК СкидкиНаценки
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВидыКартЛояльности КАК ВидыКартЛояльностиСкидкиНаценки
| ПО СкидкиНаценки.ВидКартыЛояльности = ВидыКартЛояльностиСкидкиНаценки.Ссылка
|ГДЕ
| НЕ ВидыКартЛояльностиСкидкиНаценки.ПометкаУдаления";
Результат = ЗапросУпрощенный.Выполнить().Выгрузить();
Обратите внимание: данный упрощенный подход работает только тогда, когда в базе заполнен реквизит ВидКартыЛояльности непосредственно у элемента справочника СкидкиНаценки. В современной архитектуре УТ 11 рекомендуется использовать срез последних регистра ДействиеСкидокНаценок, так как он корректно учитывает период действия скидки и расписание ее работы.