Как при обмене в Конвертации данных 2.1 разделить один документ источника на два документа приемника (на примере Отчета о розничных продажах)

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

При настройке обмена данными между конфигурациями 1С часто возникают ситуации, когда методология учета в базе-источнике отличается от методологии в базе-приемнике. Яркий пример — обмен между конфигурациями 1С:Розница и 1С:Управление торговлей (УТ). В «1С:Розница» документ ОтчетОРозничныхПродажах может одновременно содержать информацию как о продажах (табличная часть «Товары»), так и о возвратах в течение кассовой смены (табличная часть «Возвращенные товары»).

Однако руководство компании или методология ведения учета в «1С:Управление торговлей» могут требовать, чтобы эти операции разделялись на два самостоятельных документа: один документ должен фиксировать исключительно продажи, а второй — исключительно возвраты от розничного покупателя. В этой статье мы подробно разберем, как решить эту задачу с помощью правил обмена в Конвертации данных 2.1 (КД 2.1).

Почему стандартный подход с двумя ПВД не работает?

Первое решение, которое приходит в голову начинающему разработчику, — создать два отдельных Правила выгрузки данных (ПВД) и два Правила конвертации объектов (ПКО):

  1. Первая пара (ПВД_Продажи + ПКО_Продажи) — для выгрузки только продаж.
  2. Вторая пара (ПВД_Возвраты + ПКО_Возвраты) — для выгрузки возвратов.

Выясним причину, почему этот подход не сработает в реальном обмене. Платформа 1С при выполнении выгрузки по правилам обмена использует внутренний механизм оптимизации и кэширования. Когда объект (ссылка на документ) выгружается через первое ПВД, его уникальный идентификатор (UUID) регистрируется в специальном соответствии выгруженных объектов. При попытке обработать тот же самый объект вторым ПВД система видит, что этот объект уже был выгружен в текущем сеансе обмена, и просто пропускает его. В итоге второй документ в базе-приемнике так и не создается.

Для обхода этого ограничения нам потребуется использовать **одно ПВД** и механизм программного вызова выгрузки по правилам с помощью функции ВыгрузитьПоПравилу.

Пошаговое руководство по реализации разделения документов

Рассмотрим по шагам правильный алгоритм настройки правил конвертации в КД 2.1 для решения нашей задачи.

Шаг 1. Создание Правил конвертации объектов (ПКО)

Нам понадобятся два ПКО для одного и того же типа документа источника ДокументСсылка.ОтчетОРозничныхПродажах:

  1. ПКО_ОтчетОРозничныхПродажах_Продажи (приемник — ОтчетОРозничныхПродажах). Это правило будет переносить стандартные продажи. Табличную часть «Товары» сопоставляем стандартным образом.
  2. ПКО_ОтчетОРозничныхПродажах_Возврат (приемник — ОтчетОРозничныхПродажах). Это правило будет создавать документ возврата. Табличную часть «Товары» в приемнике мы будем заполнять данными из таблицы «Возвращенные товары» источника.

Шаг 2. Программная выгрузка в Правиле выгрузки данных (ПВД)

Создаем одно общее ПВД для документа ОтчетОРозничныхПродажах. В настройках ПВД способ выгрузки выбираем «Произвольный алгоритм». Нам необходимо переопределить стандартную выгрузку и программно запустить обработку объекта по двум разным ПКО.

Переходим в обработчик ПВД «Перед выгрузкой объекта» и пишем следующий код:


// 1. Выгружаем первый документ (Продажи) по стандартному правилу
ВыгрузитьПоПравилу(Объект, , , , "ПКО_ОтчетОРозничныхПродажах_Продажи");

// Проверяем, есть ли возвраты в документе источника
Если Объект.ВозвращенныеТовары.Количество() > 0 Тогда
    
    // Формируем структуру входящих данных для документа возврата
    ВходящиеДанныеДляВозврата = Новый Структура;
    
    // Генерируем уникальный номер для документа возврата, чтобы избежать совпадения номеров
    НовыйНомер = СтрЗаменить(Объект.Номер, "-", "В"); 
    ВходящиеДанныеДляВозврата.Вставить("Номер", НовыйНомер);
    ВходящиеДанныеДляВозврата.Вставить("Комментарий", "Документ возврата создан автоматически на основании ООРП №" + Объект.Номер);
    
    // Получаем таблицу возвращенных товаров запросом (или напрямую из ТЧ объекта)
    ТаблицаВозвратов = Объект.ВозвращенныеТовары.Выгрузить();
    ВходящиеДанныеДляВозврата.Вставить("Товары", ТаблицаВозвратов);
    
    // Рассчитываем сумму возврата
    СуммаВозврата = ТаблицаВозвратов.Итог("Сумма");
    ВходящиеДанныеДляВозврата.Вставить("СуммаДокумента", СуммаВозврата);
    
    // 2. Выгружаем второй документ (Возврат) по специальному правилу
    ВыгрузитьПоПравилу(Объект, , ВходящиеДанныеДляВозврата, , "ПКО_ОтчетОРозничныхПродажах_Возврат");
    
КонецЕсли;

Шаг 3. Настройка ПКО для возвратов и прием входящих данных

Теперь проанализируем, как правильно принять переданные нами из ПВД параметры во втором ПКО (ПКО_ОтчетОРозничныхПродажах_Возврат). В сообщениях темы на форуме была совершена частая ошибка: автор пытался заполнить структуру ВходящиеДанные непосредственно в обработчиках ПКО. Запомните: менять ВходящиеДанные внутри ПКО бессмысленно, так как ПКО их только получает от вызывающей процедуры выгрузки.

Для того чтобы ПКО приняло параметры из структуры ВходящиеДанныеДляВозврата, выполним следующие настройки:

  1. В ПКО для свойств Номер, СуммаДокумента, Комментарий и табличной части Товары установим флаг «Получить из входящих данных».
  2. В обработчике ПКС (Правила конвертации свойств) для табличной части Товары в событии «Перед выгрузкой» укажем соответствие колонок, если имена реквизитов ТЧ «Возвращенные товары» источника отличаются от ТЧ «Товары» приемника.

Важный подводный камень: Проблема совпадения UUID (GUID)

Проанализируем крайне важный нюанс, который часто упускают из виду. При вызове функции ВыгрузитьПоПравилу для одного и того же объекта (в нашем случае переменная Объект), КД 2.1 по умолчанию выгружает оригинальный UUID (Уникальный идентификатор) ссылки источника в XML-файл.

Если оба правила запишут один и тот же UUID в файл выгрузки, то при загрузке в базу-приемник произойдет коллизия: второй документ (возврат) просто затрет первый документ (продажи) по ссылке, так как у них будет одинаковый GUID. Поиск по полям поиска (Номер + Дата) в данном случае не спасет, так как идентификация по UUID имеет наивысший приоритет.

Как решить эту проблему?

Необходимо переопределить ключевое свойство идентификации для второго документа. Для этого в ПКО возвратов (ПКО_ОтчетОРозничныхПродажах_Возврат) в обработчике «Перед выгрузкой» переопределим параметр КлючВыгружаемыхДанных:


// Генерируем уникальный ключ выгрузки на основании исходной ссылки
КлючВыгружаемыхДанных = "Return_" + Строка(Источник.Ссылка.УникальныйИдентификатор());

Благодаря этой строчке кода КД 2.1 сгенерирует для документа возврата новый, детерминированный UUID в базе-приемнике. Он будет постоянным при последующих обменах, что предотвратит появление дублей и затирание документов.

Особенности распределения оплат и проведения документов

Посмотрим на ситуацию со стороны бизнес-логики. Документ ОтчетОРозничныхПродажах содержит не только информацию о товарах, но и информацию о способах оплаты (вкладка «Оплата» или «Оплата платежными картами»). Если мы просто разделим товары, но оставим все оплаты в первом документе:

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

Также рекомендуется в ПКО для документа возврата в обработчике «После загрузки» установить режим записи документа. Возвраты — это операции, требующие повышенного контроля, и часто их безопаснее загружать непроведенными (в состоянии «Записан»), чтобы менеджеры в базе-приемнике перепроверяли их вручную:


РежимЗаписи = "Записать"; // или "Проводить", если уверены в автоматическом балансе партий и касс

Резюме

Мы подробно разобрали, как с помощью одного ПВД и программного вызова функции ВыгрузитьПоПравилу реализовать разделение одной транзакции в источнике на несколько независимых документов в приемнике. Этот метод является стандартным и наиболее надежным инструментом при работе с Конвертацией данных 2.1, позволяя гибко управлять бизнес-логикой обмена любой сложности.

← На главную