При переходе на новые версии 1С:Комплексная автоматизация (2.5.5 и выше) или 1С:ERP 2.5 многие разработчики сталкиваются с серьезными трудностями при попытке изменить логику работы взаиморасчетов. Старые подходы, работавшие в версии 2.4, здесь практически неприменимы из-за внедрения архитектуры «Онлайн-взаиморасчетов». Рассмотрим подробно, как реализовать задачу по выделению НДС в регистрах накопления РасчетыСКлиентамиПоСрокам и РасчетыСпоставщикамиПоСрокам, не нарушив при этом стабильность системы.
Прежде чем приступать к написанию кода, проанализируем ситуацию. В версии 2.5 механизмы формирования движений по взаиморасчетам кардинально изменились. Если раньше движения формировались непосредственно в модулях документов, то теперь за это отвечает специализированный Менеджер расчета взаиморасчетов. Основная сложность заключается в том, что данные в регистры «...по срокам» попадают после сложного процесса распределения оплат по накладным (обычно по методу FIFO или по плановым датам погашения).
Выясним причину, почему прямая правка типовых запросов — это плохая идея. Алгоритмы распределения используют временные таблицы и динамическое формирование текстов запросов в общих модулях. Попытка внедрить туда расчет НДС «в лоб» может привести к катастрофическому падению производительности или ошибкам в фоновых заданиях очереди расчета.
Рассмотрим наиболее безопасный с точки зрения обновлений и стабильности метод — создание отдельного регистра. Это позволит нам хранить нужные данные, не вмешиваясь в структуру типовых объектов, что особенно важно для конфигураций на поддержке.
Доп_РасчетыСКлиентамиПоСрокамНДС).АналитикаУчетаПоПартнерам, ОбъектРасчетов, Валюта, РасчетныйДокумент, ДатаПлановогоПогашения.СуммаНДС.ПриЗаписи типового регистра РасчетыСКлиентамиПоСрокам.Разберем логику работы подписки. В момент, когда типовая система закончила распределение и записывает набор записей в регистр по срокам, мы перехватываем этот набор, анализируем Регистратор, вычисляем ставку НДС из первичного документа и записываем пропорциональную сумму в наш новый регистр.
Если создание нового регистра кажется избыточным, можно воспользоваться методом «ленивых вычислений». Этот способ подойдет, если данные по НДС не нужны в режиме реального времени в каждую секунду проведения документа.
Рассмотрим по шагам реализацию этого подхода:
Шаг 1. Добавление реквизитов. Через расширение добавим в типовые регистры РасчетыСКлиентамиПоСрокам и РасчетыСпоставщикамиПоСрокам два поля:
НдсРассчитан (Тип: Булево, установим свойство "Индексировать").СуммаНДС (Тип: ОпределяемыйТип.ДенежнаяСуммаЛюбогоЗнака).Шаг 2. Создание обработчика. Напишем процедуру, которая будет выбирать записи, где НдсРассчитан = Ложь. Для каждой записи нам нужно будет обратиться к Регистратору или ОбъектуРасчетов, чтобы понять, какая сумма НДС должна соответствовать данной задолженности.
Пример кода для такой обработки (упрощенно):
Процедура РассчитатьНДСВРегистреПоСрокам() Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Таблица.Регистратор КАК Регистратор,
| Таблица.НомерСтроки КАК НомерСтроки
|ИЗ
| РегистрНакопления.РасчетыСКлиентамиПоСрокам КАК Таблица
|ГДЕ
| Таблица.НдсРассчитан = ЛОЖЬ";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Здесь логика получения ставки НДС из документа-регистратора
// или из объекта расчетов (Заказа/Договора)
СтавкаНДС = ПолучитьСтавкуНДСИзДокумента(Выборка.Регистратор);
НаборЗаписей = РегистрыНакопления.РасчетыСКлиентамиПоСрокам.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(Выборка.Регистратор);
НаборЗаписей.Прочитать();
Для Каждого Запись Из НаборЗаписей Цикл
Если НЕ Запись.НдсРассчитан Тогда
Запись.СуммаНДС = Запись.Сумма * СтавкаНДС / (100 + СтавкаНДС);
Запись.НдсРассчитан = Истина;
КонецЕсли;
КонецЦикла;
НаборЗаписей.Записать();
КонецЦикла;
КонецПроцедуры
Шаг 3. Автоматизация. Настроим регламентное задание, которое будет запускать этот расчет с периодичностью раз в час или раз в сутки (в зависимости от требований бизнеса). Это позволит избежать «нагибания» процессора в момент массового проведения документов пользователями.
Если же стоит задача изменить именно механизм формирования движений в момент проведения, проанализируем структуру общих модулей КА 2.5. Нам понадобятся следующие узлы:
ВзаиморасчетыСервер — здесь сосредоточена базовая логика формирования структур для движений. Ищите функции, возвращающие описание таблиц регистров.ДенежныеСредстваСервер — содержит процедуры СформироватьДвижения.... Именно здесь данные из таблиц значений превращаются в записи регистров накопления.ВзаиморасчетыРасшифровкаПлатежа — критически важный модуль, если вам нужно понять, как система распределяет суммы при частичных оплатах.Посмотрим на пример того, как в 2.5 реализована работа с таблицами движений. Система часто использует временные таблицы с именами типа ВТРасчетыПоСрокам. Чтобы добавить туда НДС, вам придется через расширение перехватить запрос в процедуре ПодготовитьТаблицыДляЗаписиВРегистры (или аналогичной в зависимости от версии подсистемы взаиморасчетов).
Обратите внимание на ставки НДС! Одна из главных проблем при выделении НДС в регистрах взаиморасчетов заключается в том, что в одном документе (например, «Реализация товаров и услуг») может быть несколько строк с разными ставками (20%, 10%, 0%). Типовой механизм онлайн-взаиморасчетов в 1С:КА 2.5 распределяет оплаты по документу в целом, а не по его товарному составу. Если клиент оплатил половину накладной, система не знает, какой именно товар (с какой ставкой НДС) был оплачен.
Поэтому при реализации расчета НДС мы рекомендуем использовать один из двух подходов к вычислению:
В заключение отметим: если вы не уверены в своих силах при работе с «ужасными запросами» менеджера взаиморасчетов, остановитесь на варианте с отдельным регистром-дублером. Это гарантирует, что даже при обновлении конфигурации на новый минорный релиз ваша доработка не «отвалится» и не заблокирует работу бухгалтерии.