В некоторый конфигурациях 1С есть такие особые виды внешних обработок, как «Расчет скидки/наценки» и «Проверка условия предоставления скидки/наценки», они слабо документированы (я не нашёл нормального мануала), по этому сам разбирался. Если кто даст ссылку на мануал, буду благодарен.
Первое и главное, где взять шаблон, чтобы не изобретать велосипед? Оказывается в демо-конфигурации 1С:Управление торговлей 11.4 уже есть две таких обработки:
- условие предоставления скидки за ассортимент — проверка условия;
- скидка/наценка процент за способ доставки — расчёт скидки.
Регистрация обработки происходит стандартным образом, однако все основные данные заполняются по умолчанию в функций ПараметрыРегистрацииВнешнейОбработкиСкидкиНаценки() или ПараметрыРегистрацииВнешнейОбработкиУсловияПредоставленияСкидокНаценок() общего модуля СкидкиНаценкиСервер. В данные процедуры передаются только Наименование и Информация. Зря не дали возможность передавать версию обработки, ну да ладно, всегда можно самому добавить данный функционал.
Соответственно один вид обработки отвечает непосредственно за расчёт скидок/наценок, а второй за условие применения тех или иных скидок/наценок. Соответственно одновременно и условия и методику расчёта описать в одной обработке нельзя. Причём, если вы реализуете произвольный алгоритм расчёта скидок, то наложить отбор на номенклатуру или сформировать условие для скидки уже нельзя. Взялись сами считать, вот и считаем.
Рассмотрим механизм расчёта скидок, проверку условия изучим позже.
Расчёт начинается в процедуре Рассчитать() общего модуля СкидкиНаценкиСервер, там в зависимости от вида документа, запускается своя процедура расчёта. В этих процедурах формируется первый параметр ПараметрыРасчета, в котором много всего, что может пригодиться для работы, например, товары в виде таблицы значений и объект, т. е. документ или форма для которого вызван расчёт скидок.
Вторым шагом формируется параметр ДеревоСкидок, как результат запроса к справочнику СкидкиНаценки. Полученные параметры передаются процедуре РассчитатьСкидкиРекурсивно(), которая рассчитывает скидку для каждой строки дерева скидок.
Непосредственный расчёт происходит в процедуре РассчитатьСкидку() с параметрами СтрокаДерева и ПараметрыРасчета, где по типу параметра СтрокаДерева.СпособПредоставления определяется алгоритм расчёта скидок, именно тут запускается процедура расчёта скидок, расположенная в модуле объекта внешней обработки. Расчёт запускается в безопасном режиме!
Есть ещё один важный параметр, на основании которого рассчитываются скидки, а именно наши настройки из внешней обработки, их нужно как-то передать в алгоритм расчёта. Мы должны их оформить в структуру и определённым образом организовать выгрузку во временное хранилище (см. пример, функцию СохранитьНастройкиВнешнейОбработки() в модуле формы), потом эти настройки «как есть» будут сохранены в реквизите ПараметрыВнешнейОбработки элемента справочника СкидкиНаценки, а во время запуска нашей процедуры будут переданы в качестве параметра Настройки.
В итоге в процедуру Рассчитать модуля объекта внешней обработки передаются следующие параметры:
- СкидкаНаценка — соответствующие данные элемента справочника СкидкиНаценки;
- Настройки — полученные из хранилища значение наши настройки в виде структуры;
- Товары — выборка из переменной ПараметрыРасчета.Товары с отбором по условию, в случае, если скидка применяется не ко всем товарам (т.к. отбор по товарам не осуществляется, то это все товары).
- ПараметрыРасчета — большая структура со всеми данными для расчёта скидки.
Теперь как считать? Результатом расчёта должна быть таблица значений с колонками, описанными в процедуре ПустаяТаблицаСкидокСРасшифровкой() общего модуля СкидкиНаценкиСервер. Данные в таблицу значений вносятся специальными процедурами:
- ПрименитьЗначениеСкидкиКТовару() — это применение скидки к конкретному товару;
- РаспределитьЗначениеСкидкиНаТовары() — распределение скидки между всеми товарами пропорционально их стоимости.
Для примера предлагаю внешнюю обработку, реализующую начисление скидки от некоторого количества товара определённой номенклатуры. Т.е., допустим, за 1 штуку ничего не даём, за 2 - 20%, за 3 и далее- 40% за штуку. Пример настроек приведён выше на скриншоте, а сама обработка сделана на основе демонстрационных обработок из 1С:УТ 11.4.
Все исследования проводил на конфигурации Управление торговлей, редакция 11 (11.4.11.55) и потом проверял на 1С:Комплексная автоматизация 2 (2.4.11.46).
UPD: 18.08.2021 добавлена настройка для применения скидок ко всем товарам в документе.