При настройке обмена данными между конфигурациями «Управление торговлей 11» (УТ) и «Бухгалтерия предприятия 3.0» (БП) часто возникает архитектурная нестыковка. В УТ 11.5 функциональная опция использования договоров может быть отключена, и учет ведется в разрезе «Соглашений». В то же время, в БП 3.0 реквизит «Договор контрагента» является обязательным для учета взаиморасчетов. Рассмотрим подробно, как решить эту задачу с помощью инструмента «Конвертация данных 2.0» (КД 2.0).
Мы переносим документ (например, «Реализация товаров и услуг»). В источнике (УТ) реквизит Договор пуст, но заполнено Соглашение. В приемнике (БП) необходимо заполнить реквизит ДоговорКонтрагента, создав его на лету или найдя существующий на основании данных соглашения (Наименование, Организация, Контрагент, Валюта).
Автор темы пытался использовать глобальные алгоритмы и параметры, но этот путь сложен и неочевиден. Разберем более правильный и элегантный подход, использующий механизм ИсходящиеДанные.
Это наиболее гибкий способ, когда источник (договор) пуст или отсутствует, но нам нужно сформировать объект в приемнике на основе других данных документа.
Суть метода заключается в следующем: в правиле конвертации свойств (ПКС) документа мы программно собираем структуру данных и передаем её в правило конвертации объектов (ПКО) договора.
Шаг 1. Настройка ПКС в документе
Откроем правило конвертации документа «Реализация товаров и услуг». Найдем ПКС для реквизита ДоговорКонтрагента. Поскольку в УТ 11 реквизит Договор может быть пустым, нам нужно перехватить управление в обработчике ПередВыгрузкой.
В этом обработчике мы сформируем структуру ИсходящиеДанные, куда поместим все необходимые свойства для создания или поиска договора в БП.
// Обработчик "ПередВыгрузкой" для ПКС ДоговорКонтрагента
// Если в источнике договора нет, будем формировать данные из Соглашения
Если ЗначениеЗаполнено(Источник.Соглашение) Тогда
ИсходящиеДанные = Новый Структура;
// Передаем основные реквизиты, необходимые для договора в БП
ИсходящиеДанные.Вставить("Организация", Источник.Организация);
// В качестве наименования договора берем наименование соглашения или формируем свое
ИсходящиеДанные.Вставить("Наименование", Источник.Соглашение.Наименование);
// Важно правильно передать владельца (Контрагента)
// В УТ это может быть Партнер или Контрагент, в БП - строго Контрагент
ИсходящиеДанные.Вставить("Владелец", Источник.Контрагент);
// Валюта взаиморасчетов (критично для БП)
// В соглашении валюта может называться иначе, убедитесь, что передаете ссылку на валюту
ИсходящиеДанные.Вставить("ВалютаВзаиморасчетов", Источник.Соглашение.Валюта);
// Вид договора (СПокупателем, СПоставщиком и т.д.)
// Его нужно определить в зависимости от типа документа или соглашения
ИсходящиеДанные.Вставить("ВидДоговора", "СПокупателем");
КонецЕсли;
Шаг 2. Настройка ПКО «ДоговорыКонтрагентов»
Теперь перейдем к правилу конвертации объектов (ПКО), на которое ссылается наше ПКС (например, ДоговорыКонтрагентов).
Шаг 3. Настройка ПКС внутри ПКО договора
Внутри правила конвертации договора для каждого реквизита (Организация, Наименование, Владелец и т.д.) необходимо установить флажок Получить из входящих данных. Имя параметра должно совпадать с ключом структуры, которую мы создали на Шаге 1.
Например, для ПКС Наименование ставим галочку «Получить из входящих данных». Система автоматически возьмет значение ИсходящиеДанные.Наименование.
Если ваша задача не создавать новый договор по сложной структуре, а просто найти подходящий (например, «Основной договор») в базе приемнике, можно использовать другой подход.
В ПКС документа для реквизита Договор в обработчике ПередВыгрузкой можно сразу присвоить значение переменной Значение. Однако, так как мы выгружаем из УТ, у нас нет ссылки на договор БП. Поэтому этот метод чаще используется, если мы хотим подставить конкретную ссылку источника, найденную программно.
Например, если бы в УТ все-таки были договоры, но они лежали не в реквизите документа, мы могли бы написать:
// Пример поиска договора в базе источника (УТ)
// НайтиДоговорПоСоглашению - это условная функция
НайденныйДоговор = НайтиДоговорПоСоглашению(Источник.Соглашение);
Значение = НайденныйДоговор;
Но в нашем случае (когда договоров в УТ нет совсем) этот метод менее удобен, так как требует создания правил конвертации для виртуальных объектов. Поэтому Решение 1 является предпочтительным.
Обратите внимание на особенность работы КД 2.0. Если в ПКС указан Источник (имя реквизита), и это значение в базе ПустаяСсылка или Неопределено, то обработчики правил могут не отработать, если не настроены соответствующие опции, или правило просто проигнорируется.
Чтобы правило отработало даже при пустом реквизите в источнике, в ПКС поле «Источник» лучше оставить пустым, а получение данных прописать полностью в коде ПередВыгрузкой, либо убедиться, что ваша логика заполнения ИсходящиеДанные обрабатывает ситуацию отсутствия данных.
В обсуждении верно подметили:
// Если источник - пусто, тогда все бери или из ИсходящиеДанные или создавай программно.
// И тогда в ПКС нужно условие проверки, что Договор в источнике заполнен.
При использовании метода с ИсходящиеДанные крайне важно правильно настроить Поля поиска в ПКО Договора. Иначе при каждой выгрузке документа будет создаваться новый договор.
Рекомендуется установить поиск по следующим полям (установить галочки «Поиск» в ПКС договора):
Если поиск только по наименованию ненадежен (пользователи могут менять названия), можно использовать обработчик ПоляПоиска в ПКО Договора, чтобы реализовать более сложную логику. Например, искать любой договор с этой организацией и валютой, и если их несколько — брать первый попавшийся или «Основной».
ИсходящиеДанные, заполняя её данными из Источник.Соглашение.ДоговорыКонтрагентов. Ставим флаг «Получить из входящих данных».