Как программно добавить автоматическую скидку в документ «Чек ККМ» в 1С:Управление торговлей 11?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При программной работе с документами в 1С часто возникает задача не просто создать и заполнить документ, но и корректно применить все связанные с ним механизмы, такие как автоматические скидки и наценки. Особенно актуально это для конфигурации «Управление торговлей 11», где подсистема маркетинга и ценообразования является довольно сложной.

Проанализируем ситуацию: мы программно создаем документ ЧекККМ, заполняем его табличную часть «Товары». Если просто попытаться записать значение в колонку СуммаАвтоматическойСкидки, это не даст нужного результата. Система не пересчитает итоги, и скидка не будет корректно отражена, так как для этого должен быть запущен специальный механизм расчета. Давайте разберем, как правильно инициировать этот расчет и применить действующие скидки.

Решение 1: Использование метода объекта `ЗаполнитьСкидкиНаценки()`

Это самый простой, надежный и рекомендуемый способ. Разработчики конфигурации предусмотрели специальный метод, который инкапсулирует (скрывает) в себе всю сложную логику вызова подсистемы скидок. Вам не нужно вникать во внутреннее устройство механизма, достаточно просто вызвать один метод для уже заполненного документа.

Разберем по шагам, как это работает:

  1. Создаем новый объект документа ЧекККМ с помощью метода Документы.ЧекККМ.СоздатьДокумент().
  2. Заполняем необходимые реквизиты в шапке документа: Организация, КассаККМ, Партнер и другие.
  3. В цикле или поочередно добавляем строки в табличную часть Товары. Для каждой строки указываем Номенклатура, Характеристика (если используется), Количество и Цена. Важный момент: на этом этапе не нужно пытаться самостоятельно рассчитывать сумму или скидку. Просто заполняем основные данные.
  4. После того как все товары добавлены в табличную часть, вызываем метод самого объекта документа: ЧекККМОбъект.ЗаполнитьСкидкиНаценки().

Этот вызов запустит весь механизм: система проанализирует состав документа, дату, партнера, номенклатуру и применит все действующие на данный момент автоматические скидки. Поля, связанные со скидками (ПроцентАвтоматическойСкидки, СуммаАвтоматическойСкидки), а также итоговая Сумма в строках будут рассчитаны и заполнены автоматически.

Посмотрим на пример кода:


&НаСервере
Процедура СоздатьЧекСоСкидкой()

    // 1. Создаем объект документа
    ЧекККМОбъект = Документы.ЧекККМ.СоздатьДокумент();

    // 2. Заполняем реквизиты шапки
    ЧекККМОбъект.Дата = ТекущаяДата();
    ЧекККМОбъект.Организация = Константы.ОсновнаяОрганизация.Получить();
    ЧекККМОбъект.КассаККМ = Справочники.КассыККМ.НайтиПоНаименованию("Основная касса");
    ЧекККМОбъект.Статус = Перечисления.СтатусыЧековККМ.Пробит;

    // 3. Добавляем товары в табличную часть
    НоваяСтрока = ЧекККМОбъект.Товары.Добавить();
    НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Товар для скидки");
    НоваяСтрока.Количество = 2;
    НоваяСтрока.Цена = 1500;
    НоваяСтрока.СтавкаНДС = Перечисления.СтавкиНДС.НДС20;
    // Сумма рассчитается автоматически при изменении количества или цены
    // РассчитатьСуммуНДСВТабличнойЧасти(НоваяСтрока, ЧекККМОбъект); // Вспомогательная процедура
    
    // ... можно добавить другие товары ...

    // 4. Вызываем расчет скидок
    // Это ключевой шаг!
    ЧекККМОбъект.ЗаполнитьСкидкиНаценки();
    
    // После этого вызова строки в ЧекККМОбъект.Товары
    // будут содержать рассчитанные суммы скидок.

    // 5. Записываем и проводим документ
    Попытка
        ЧекККМОбъект.Записать(РежимЗаписиДокумента.Проведение);
    Исключение
        Сообщить(ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

Этот подход является предпочтительным, так как он использует встроенный API конфигурации. Это делает ваш код более устойчивым к будущим обновлениям 1С, ведь если разработчики изменят логику расчета скидок, они, скорее всего, обновят и метод ЗаполнитьСкидкиНаценки(), и ваш код продолжит работать корректно.

Решение 2: Прямой вызов процедур из общих модулей

Этот способ является более "низкоуровневым" и сложным. Он может понадобиться в специфических случаях, например, когда нужно рассчитать скидку для одной конкретной строки, не затрагивая весь документ, или когда требуется получить данные о скидках до фактического создания объекта документа.

В этом случае нам придется напрямую обращаться к процедурам и функциям общих модулей, отвечающих за маркетинг. Ключевую роль здесь играют модули МенеджерСкидокНаценок и МаркетингСервер.

Основная логика заключается в следующем:

  1. Собрать данные для расчета: сам объект документа (или просто структуру с данными), его табличную часть, дату, на которую нужно рассчитать скидки.
  2. Вызвать функцию МаркетингСервер.ПолучитьУсловияПредоставленияСкидокНаценок(). Эта функция вернет структуру с действующими скидками и условиями их применения.
  3. Передать объект документа и полученные условия в процедуру МенеджерСкидокНаценок.РассчитатьСкидкиНаценкиДокумента(). Эта процедура выполнит сам расчет и изменит данные в переданном ей объекте документа.

Посмотрим на примерный код, который иллюстрирует этот подход:


&НаСервере
Процедура СоздатьЧекНизкоуровнево()

    // Предполагаем, что ЧекККМОбъект уже создан
    // и его табличная часть "Товары" заполнена
    ЧекККМОбъект = Документы.ЧекККМ.СоздатьДокумент();
    // ... заполнение шапки и товаров, как в первом примере ...

    // Для нового, еще не записанного документа, ссылка будет пустой.
    // Механизм скидок может работать с уникальным идентификатором
    // или временной ссылкой.
    МассивОбъектовНазначения = Новый Массив;
    МассивОбъектовНазначения.Добавить(ЧекККМОбъект);

    // 1. Получаем условия предоставления скидок
    УсловияПредоставления = МаркетингСервер.ПолучитьУсловияПредоставленияСкидокНаценок(
        МассивОбъектовНазначения,
        ЧекККМОбъект.Дата,
        ЧекККМОбъект,
        ЧекККМОбъект.Товары);
    
    // 2. Вызываем процедуру расчета скидок
    МенеджерСкидокНаценок.РассчитатьСкидкиНаценкиДокумента(
        ЧекККМОбъект, 
        УсловияПредоставления);
        
    // После выполнения этой процедуры данные в объекте ЧекККМОбъект
    // будут изменены - скидки будут рассчитаны и применены.

    // Далее можно записывать документ
    ЧекККМОбъект.Записать(РежимЗаписиДокумента.Проведение);

КонецПроцедуры

Важно понимать: этот метод требует более глубокого знания архитектуры подсистемы маркетинга в УТ 11. Нужно правильно подготовить все параметры, понимать, какие данные ожидают процедуры на входе. Этот способ дает больше гибкости, но сопряжен с риском, что при обновлении конфигурации внутренние процедуры могут измениться, и ваш код перестанет работать. Используйте его только тогда, когда стандартный метод ЗаполнитьСкидкиНаценки() не решает вашу задачу.

Итоги и рекомендации

Мы рассмотрели два основных способа программного применения скидок в документе «Чек ККМ».

Таким образом, для решения стандартной задачи программного создания чека с автоматическим расчетом скидок всегда начинайте с первого, более простого и безопасного метода.

← На главную