В практике разработчика 1С часто возникает задача поддержания актуальности данных в цепочке документов. Одной из самых критичных связок является пара Реализация товаров и услуг (РТУ) и Счет-фактура выданный (СФ). Если пользователь меняет сумму, количество или контрагента в реализации, эти изменения должны автоматически отразиться в счете-фактуре, чтобы избежать расхождений в налоговой отчетности по НДС. Рассмотрим, как это реализовать на платформе 1С:Предприятие 8.2 и 8.3 (для обычных форм), проанализируем риски и разберем нестандартные ситуации, связанные с отраслевыми решениями.
В типовых конфигурациях (таких как «Управление торговлей 10.3» или «Бухгалтерия предприятия 2.0») за синхронизацию реквизитов отвечает специализированная процедура в общем модуле УчетНДС. Проанализируем, как это работает «под капотом». Обычно в модуле объекта РТУ в процедуре ПриЗаписи вызывается проверка соответствия данных.
Если вы обнаружили, что при изменении реализации счет-фактура не обновляется, первым делом следует проверить наличие следующего кода в модуле объекта реализации:
Процедура ПриЗаписи(Отказ)
// Стандартный вызов синхронизации счета-фактуры
УчетНДС.ПроверитьСоответствиеРеквизитовСчетФактуры(ЭтотОбъект);
КонецПроцедуры
Данная процедура анализирует структуру подчиненных документов, находит связанный СчетФактураВыданный и, если данные в нем отличаются от данных документа-основания (РТУ), обновляет его и записывает в режиме проведения. Если этот код закомментирован, значит, на это были веские причины, которые мы разберем далее.
Если типовой механизм вам не подходит или конфигурация сильно изменена, можно реализовать логику обновления вручную в процедуре ОбработкаПроведения или ПриЗаписи. Рассмотрим пример кода, который находит подчиненный документ и перепроводит его:
// В модуле объекта РТУ
СФ = УчетНДС.НайтиПодчиненныйДокумент(Ссылка, "СчетФактураВыданный");
Если ЗначениеЗаполнено(СФ) Тогда
ОбъектСФ = СФ.ПолучитьОбъект();
// Проверяем, нужно ли перезаписывать (опционально для производительности)
// Если ОбъектСФ.СуммаДокумента <> ЭтотОбъект.СуммаДокумента Тогда
Попытка
ОбъектСФ.Записать(РежимЗаписиДокумента.Проведение);
Исключение
Сообщить("Не удалось перепровести счет-фактуру: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Важный нюанс: Вызов Записать(РежимЗаписиДокумента.Проведение) для подчиненного документа внутри транзакции проведения основного документа может привести к взаимным блокировкам (Deadlocks). Проанализируем ситуацию: РТУ блокирует таблицу остатков, затем пытается провести СФ, который также хочет заблокировать налоговые регистры. Если в этот момент другой процесс делает то же самое в другом порядке, система зависнет. Поэтому безопаснее выполнять такие действия в событии ПриЗаписи или через механизм отложенных движений.
Разберем ситуацию, когда разработчик до вас намеренно отключил автоматическую синхронизацию. Это часто встречается в крупных информационных системах или отраслевых решениях (например, со спецификой алкогольной продукции, где используются префиксы лад). Основные причины:
ДокументОбъект.Записать(), а путем прямого формирования движений в регистрах.Рассмотрим фрагмент такой обработки, который был представлен в обсуждении. Проанализируем, почему он конфликтует со стандартной логикой:
// Фрагмент кода обработки, записывающей движения напрямую
НаборЗаписей = РегистрыНакопления.ТоварыОрганизацийБухгалтерскийУчет.СоздатьНаборЗаписей();
НаборЗаписей.Отбор["Регистратор"].Установить(Документ);
// ... заполнение таблицы движений ...
НаборЗаписей.Записать();
Когда используется такой подход, стандартные события модуля объекта (ПриЗаписи, ОбработкаПроведения) не вызываются. Следовательно, ваш код синхронизации просто не сработает. Если в вашей компании принято использовать подобные «быстрые» обработки, логику обновления счета-фактуры придется внедрять непосредственно в саму обработку.
Чтобы совместить возможность автоматического обновления СФ для обычных пользователей и оставить «тихий» режим для групповых обработок или обменов данными, проанализируем следующий метод. Добавим в модуль объекта РТУ экспортную переменную-флаг.
Шаг 1. В разделе описания переменных модуля объекта РТУ добавим:
Перем мНеОбновлятьСчетФактуру Экспорт;
Шаг 2. Обернем вызов синхронизации в проверку этого флага:
Процедура ПриЗаписи(Отказ)
Если мНеОбновлятьСчетФактуру <> Истина Тогда
УчетНДС.ПроверитьСоответствиеРеквизитовСчетФактуры(ЭтотОбъект);
КонецЕсли;
КонецПроцедуры
Шаг 3. В групповой обработке, где важно быстродействие, будем устанавливать этот флаг:
ДокОбъект = СсылкаНаРТУ.ПолучитьОбъект();
ДокОбъект.мНеОбновлятьСчетФактуру = Истина;
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
Такой подход позволяет сохранить гибкость системы: обычный менеджер при ручном редактировании документа получит автоматически обновленный счет-фактуру, а администратор при выполнении технических работ не вызовет лавинообразного перепроведения подчиненных документов.
При реализации автоматического перепроведения счета-фактуры важно соблюдать баланс между удобством пользователя и производительностью системы. Помните, что в типовых решениях 1С уже заложены механизмы УчетНДС.ПроверитьСоответствиеРеквизитовСчетФактуры, и прежде чем писать свой велосипед, выясните, почему стандартный код был отключен. Если система интегрирована с внешними обработками или обменами, всегда используйте программные флаги или свойство ОбменДанными.Загрузка, чтобы контролировать выполнение тяжелых операций по обновлению связанных документов.