При интеграции сторонних систем с 1С через протокол OData (REST API) разработчики часто сталкиваются с неприятной особенностью: после записи документа (например, счета на оплату) суммы в табличной части остаются нулевыми или не соответствуют переданным цене и количеству. Рассмотрим подробнее, почему это происходит и как заставить систему выполнять расчеты автоматически.
Проанализируем архитектуру платформы 1С. В типовых конфигурациях большая часть логики «интерактивного» пересчета (когда вы меняете количество и тут же меняется сумма) сосредоточена в модуле формы. События типа ПриИзменении привязаны к элементам управления интерфейса.
Когда мы используем OData, мы работаем напрямую с объектом базы данных, минуя визуальный интерфейс. Платформа просто записывает переданные поля в таблицу. Если вы не передали значение в поле Сумма, 1С не будет «угадывать», что его нужно рассчитать, так как в модуле самого объекта (документа) такие триггеры часто отсутствуют для обеспечения высокой скорости массовой загрузки данных.
Разберем основные стратегии решения этой задачи.
Это самый простой и рекомендуемый путь для стандартных конфигураций, которые нельзя снимать с поддержки. Раз мы знаем количество, цену и ставку НДС на стороне нашего внешнего приложения, мы должны самостоятельно вычислить все производные поля.
Что необходимо передавать в JSON-пакете:
КоличествоЦенаСтавкаНДССуммаНДС (рассчитанная вручную)Сумма (Цена * Количество)Всего (Сумма + СуммаНДС, если это предусмотрено структурой)Проанализируем ситуацию: если мы передадим только базовые значения, 1С запишет их «как есть». Использование этого метода гарантирует, что данные в базе будут корректны, даже если в самой конфигурации 1С не прописаны серверные обработчики пересчета.
Если вы хотите, чтобы 1С сама считала суммы при поступлении данных через OData, логику пересчета необходимо перенести из модуля формы в модуль объекта (событие ПередЗаписью).
Однако здесь есть важный технический нюанс: при записи через OData платформа устанавливает признак ОбменДанными.Загрузка = Истина. В этом режиме стандартные проверки и алгоритмы в модулях объектов обычно блокируются, чтобы не мешать миграции данных.
Для реализации автоматического расчета выполним следующие шаги:
ПередЗаписью для целевого документа.Загрузка.Пример кода, который можно разместить в расширении модуля объекта:
&ИзменениеИКонтроль("ПередЗаписью")
Процедура Расш1_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем, что запись идет через внешний интерфейс
Если ДополнительныеСвойства.Свойство("ЭтоOData") Или ОбменДанными.Загрузка Тогда
Для Каждого СтрокаТЧ Из Товары Цикл
// Вызываем стандартную процедуру пересчета из общего модуля
ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(СтрокаТЧ, ЭтотОбъект);
ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТЧ, ЭтотОбъект);
КонецЦикла;
КонецЕсли;
// Продолжение стандартной логики
ПродолжитьВызов(Отказ, РежимЗаписи, РежимПроведения);
КонецПроцедуры
Посмотрим на пример внимательнее: мы используем методы общего модуля ОбработкаТабличныхЧастей, которые уже содержат всю бизнес-логику вашей конфигурации. Это позволяет избежать дублирования кода и гарантирует идентичность расчетов.
Начиная с версии платформы 8.3.10, 1С поддерживает механизм Actions в OData. Это позволяет вызывать экспортные методы из модуля менеджера объекта. Это «продвинутый» способ, который позволяет не просто записывать данные, а выполнять сложные операции.
Разберем алгоритм действий:
СоздатьСчетСПересчетом(Параметры).Заполнить() или специфические функции расчета.Это позволяет инкапсулировать всю логику внутри 1С, а извне передавать лишь минимальный набор данных.
При заполнении документов через OData важно помнить о реквизитах связи. Проанализируем типичную ошибку: пользователь передает номенклатуру и количество, но забывает про единицу измерения или ставку НДС. В интерфейсе 1С эти поля подставляются автоматически при выборе товара. В OData автоматического подставления (автозаполнения) не происходит.
Перед отправкой данных убедитесь, что:
ЕдиницаИзмерения.СтавкаНДС (как ссылка на справочник или перечисление, в зависимости от конфигурации).Коэффициент (обычно 1).ВалютаДокумента и КурсВзаиморасчетов, иначе расчет суммы в регламентированном учете может быть некорректным.Подведем итог: чтобы 1С пересчитала табличную часть, у вас есть два пути — либо взять на себя роль «движка расчетов» и передавать готовые суммы извне, либо модифицировать серверную часть 1С (модуль объекта), чтобы она реагировала на запись объекта через программный интерфейс. Второй вариант более надежен с точки зрения целостности данных, но требует навыков программирования на языке 1С и использования расширений.