При работе с типовыми конфигурациями, такими как 1С:Управление торговлей или 1С:ERP, многие разработчики сталкиваются с тем, что штатные механизмы расчета скидок (например, функции модуля СкидкиНаценкиЗаполнениеСервер) требуют наличия контекста формы. Это связано с тем, что при интерактивной работе пользователя данные о скидках проходят через временное хранилище (АдресВоВременномХранилище), которое инициализируется при открытии формы документа.
Если вы создаете документ программно, используя конструкцию Документы.ЗаказКлиента.СоздатьДокумент(), у объекта нет связанной формы, а значит, и нужного временного хранилища. Попытка принудительной передачи ФормаДокумента или попытка заполнения параметров хранилища вручную часто приводит к ошибкам, так как эти механизмы ожидают событий жизненного цикла формы.
Наиболее надежный и рекомендуемый способ программного изменения скидок без использования форм — прямое воздействие на табличную часть объекта. Вместо попыток «обмануть» серверные методы, давайте воспользуемся логикой прямого расчета.
Для того чтобы применить общую сумму скидки ко всем строкам заказа, выполним следующие действия:
СуммаРучнойСкидки или ПроцентРучнойСкидки табличной части Товары.Пример программного распределения скидки:
// Предположим, что ЗаказОбъект уже создан и заполнен
ОбщаяСуммаЗаказа = ЗаказОбъект.Товары.Итог("Сумма");
СуммаРучнойСкидкиНаВесьЗаказ = 1000; // Целевая сумма скидки
Для Каждого СтрокаТовара Из ЗаказОбъект.Товары Цикл
Доля = СтрокаТовара.Сумма / ОбщаяСуммаЗаказа;
СуммаСкидкиСтроки = СуммаРучнойСкидкиНаВесьЗаказ * Доля;
// Записываем сумму в колонку табличной части
СтрокаТовара.СуммаРучнойСкидки = СуммаСкидкиСтроки;
КонецЦикла;
// После изменения данных обязательно вызываем пересчет итогов
// Если в конфигурации предусмотрена процедура пересчета, вызываем её
ЗаказОбъект.ЗаполнитьИтоги();
Если специфика вашей задачи требует соблюдения логики ограничений скидок (например, проверка прав пользователя или максимального процента скидки), то прямого изменения данных недостаточно. В этом случае нам придется подготовить структуру данных, которую ожидают типовые методы.
Разберем, что нам необходимо для инициализации процесса:
ПараметрыСкидки, которая определяет режим использования автоматических и ручных скидок.СкидкиНаценкиЗаполнениеСервер для регистрации данных в сессии, если это возможно без вызова ПолучитьФорму.Важное замечание: Метод СкидкиНаценкиЗаполнениеСервер.АдресДанныхДляРасчетаРучныхСкидокВоВременномХранилище критически зависит от идентификатора формы. Если вы используете этот подход, убедитесь, что вы передаете актуальный УникальныйИдентификатор создаваемого объекта, а не объекта формы. Однако, учитывая высокую сложность поддержки такого кода при обновлениях конфигурации, мы рекомендуем использовать его только при крайней необходимости.
При внедрении любого из этих подходов, следуйте правилам хорошего тона при разработке на 1С:
СкидкиНаценки.Рассмотренные методы позволят вам гибко управлять скидками в заказах клиентов, не прибегая к сложным и нестабильным конструкциям с открытием форм в фоновых процессах или при программном создании документов.