В розничной и оптовой торговле популярны маркетинговые акции формата «каждая вторая пара обуви/очков за полцены». При этом покупатель может выбрать абсолютно разные товары из определенной группы (сегмента), стоимость которых отличается. Главная сложность автоматизации такой задачи в «1С:Управление торговлей» версии 11.3 и 11.4 заключается в том, что система должна не просто посчитать количество, а корректно определить, к каким именно позициям применить скидку (как правило, к наиболее дешевым), чтобы защитить маржинальность бизнеса и не запутать покупателя.
В этой статье мы подробно разберем, почему стандартные инструменты УТ 11 ограничивают выполнение этой задачи, и пошагово рассмотрим наиболее надежное техническое решение с использованием внешней обработки расчета скидок.
Если мы попытаемся настроить акцию стандартным типом скидки «Скидка количеством» в УТ 11.3, мы столкнемся с рядом системных ограничений:
Для реализации честного и прозрачного алгоритма «каждый второй товар из сегмента со скидкой 50%» мы рекомендуем использовать механизм подключения внешних обработок расчета скидок.
В системе 1С:Предприятие реализован гибкий механизм расширения возможностей расчета скидок с помощью внешних обработок (файлы с расширением .epf). Мы можем взять за основу демонстрационный шаблон, поставляемый фирмой 1С, и внедрить в него собственную логику распределения скидки.
Рассмотрим алгоритм создания и подключения такой обработки по шагам.
В составе демонстрационной базы «1С:Управление торговлей» (или в каталоге шаблонов установки конфигурации) присутствует учебный файл внешней обработки СкидкаНаценкаПроцентЗаСпособДоставки.epf. Этот файл служит отличным каркасом, так как в нем уже прописаны все необходимые экспортные процедуры для интеграции с подсистемой скидок-наценок УТ 11.
Скопируем этот файл, переименуем его (например, в СкидкаКаждыйВторойТоварСегмента.epf) и откроем в конфигураторе 1С.
Нам необходимо изменить код в основной экспортной процедуре расчета. Логика нашего алгоритма должна выполнять следующие действия:
Проанализируем пример кода, который решает эту задачу в модуле внешней обработки:
Процедура РассчитатьСкидкиИНаценки(ПараметрыРасчета, ТаблицаСкидокНаценок) Экспорт
// 1. Получаем таблицу товаров документа из параметров расчета
ТаблицаТоваров = ПараметрыРасчета.ТаблицаТоваров;
// Подготовим массив для поштучного учета товаров из сегмента
МассивТоваровСегмента = Новый Массив;
Для Каждого СтрокаТовара Из ТаблицаТоваров Цикл
// Проверяем принадлежность номенклатуры к нашему целевому сегменту
Если ПринадлежитСегменту(СтрокаТовара.Номенклатура, ПараметрыРасчета.ПолучательСкидки) Тогда
// Раскладываем количество поштучно
Для Счетчик = 1 По СтрокаТовара.Количество Цикл
СтруктураШтуки = Новый Структура;
СтруктураШтуки.Вставить("СтрокаДокумента", СтрокаТовара);
СтруктураШтуки.Вставить("Цена", СтрокаТовара.Цена);
СтруктураШтуки.Вставить("СкидкаСумма", 0);
МассивТоваровСегмента.Добавить(СтруктураШтуки);
EndЦикла;
КонецЕсли;
КонецЦикла;
// 2. Сортируем полученный массив по цене по убыванию
// Для этого можно использовать вспомогательную таблицу значений
ТЗ_Сортировки = Новый ТаблицаЗначений;
ТЗ_Сортировки.Колонки.Добавить("ИндексМассива", Новый ОписаниеТипов("Число"));
ТЗ_Сортировки.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число"));
Для Индекс = 0 По МассивТоваровСегмента.Количество() - 1 Цикл
НоваяСтрока = ТЗ_Сортировки.Добавить();
НоваяСтрока.ИндексМассива = Индекс;
НоваяСтрока.Цена = МассивТоваровСегмента[Индекс].Цена;
КонецЦикла;
ТЗ_Сортировки.Сортировать("Цена Убыв");
// 3. Распределяем скидку 50% на каждую вторую позицию (четную по счету)
ПорядковыйНомер = 1;
Для Каждого СтрокаСорт Из ТЗ_Сортировки Цикл
// Каждый второй товар (2-й, 4-й, 6-й и т.д. по убыванию цены)
Если ПорядковыйНомер % 2 = 0 Тогда
ТекущийТовар = МассивТоваровСегмента[СтрокаСорт.ИндексМассива];
// Скидка 50% от цены за единицу
ТекущийТовар.СкидкаСумма = ТекущийТовар.Цена * 0.5;
КонецЕсли;
ПорядковыйНомер = ПорядковыйНомер + 1;
КонецЦикла;
// 4. Переносим рассчитанные скидки обратно в таблицу результатов
Для Каждого Элемент Из МассивТоваровСегмента Цикл
Если Элемент.СкидкаСумма > 0 Тогда
СтрокаСкидки = ТаблицаСкидокНаценок.Добавить();
СтрокаСкидки.КлючСвязи = Элемент.СтрокаДокумента.КлючСвязи;
СтрокаСкидки.Сумма = Элемент.СкидкаСумма;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ПринадлежитСегменту в коде выше должна проверять, входит ли товар в выбранный сегмент номенклатуры. Для этого можно использовать стандартные механизмы работы с сегментами в УТ 11, например, обращение к регистру сведений НоменклатураСегмента.
После того как логика написана и сохранена в файле .epf, выполним интеграцию с пользовательским интерфейсом:
Теперь при расчете скидок в чеке ККМ или Заказе клиента система будет обращаться к нашему алгоритму. Программа автоматически отсортирует все добавленные очки по цене, определит более дешевые и предоставит на них скидку 50% в строгом соответствии с требованиями бизнеса.