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