При настройке правил обмена в конфигурации «Конвертация данных 2.1» часто возникает задача полиморфной конвертации, когда один документ базы-источника в зависимости от условий (например, установленного флага или выбранной хозяйственной операции) должен трансформироваться в разные виды документов базы-приемника.
Типичный пример: в «1С:Управление торговлей» оформлен документ, который при установленном флаге должен загружаться в «1С:Бухгалтерию предприятия» как Передача товаров (передача в переработку), а при снятом флаге — как Реализация товаров и услуг. Если пользователь сначала провел документ с признаком передачи, объект успешно выгрузился в приемник и сформировал проводки. Однако, если затем в источнике флаг сняли и повторно запустили синхронизацию, в приемник загрузится реализация, а ранее созданный документ передачи останется проведенным, что приведет к задвоению движений и остатков.
Проанализируем причины такого поведения платформы и подробно разберем практические способы решения этой проблемы.
Выясним причину, из-за которой стандартный механизм обмена не может автоматически нейтрализовать старый документ:
Рассмотрим наиболее популярный и надежный подход: при загрузке документа в базу-приемник программно проверять наличие альтернативного документа по тому же идентификатору и отменять его проведение (или помечать на удаление).
Разберем реализацию этого алгоритма по шагам в обработчике «После загрузки» целевого правила конвертации объекта (ПКО):
Объект.Ссылка.УникальныйИдентификатор().Посмотрим на пример кода на встроенном языке 1С:
УИД = Объект.Ссылка.УникальныйИдентификатор();
// Формируем ссылку на альтернативный документ по тому же УИД
СсылкаДубль = Документы.ПередачаТоваров.ПолучитьСсылку(УИД);
// Проверяем физическое существование объекта в информационной базе
ОбъектДубль = СсылкаДубль.ПолучитьОбъект();
Если ОбъектДубль <> Неопределено Тогда
Попытка
Если ОбъектДубль.Проведен Тогда
ОбъектДубль.Записать(РежимЗаписиДокумента.ОтменаПроведения);
КонецЕсли;
// Дополнительно можно пометить документ на удаление
Если Не ОбъектДубль.ПометкаУдаления Тогда
ОбъектДубль.УстановитьПометкуУдаления(Истина);
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации("Синхронизация данных. Снятие с проведения дубля",
УровеньЖурналаРегистрации.Предупреждение,
ОбъектДубль.Метаданные(),
ОбъектДубль.Ссылка,
ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Аналогичный симметричный код следует поместить и во второе ПКО, чтобы при возврате флага обратно в состояние «Передача» автоматически отменялось проведение у документа реализации.
Второй вариант заключается в том, чтобы решать задачу непосредственно на стороне базы-источника в обработчике «Перед выгрузкой» или «После выгрузки» основного правила:
ВыгрузитьПоПравилу(...), передавая специальную структуру или объект с признаками Проведен = Ложь и ПометкаУдаления = Истина.Разберем пример вызова выгрузки пустого объекта-заглушки для нейтрализации альтернативного типа документа:
Если Не Источник.ПередачаВПереработку Тогда
// Основной документ выгружается как РеализацияТоваровУслуг
// Параллельно инициируем отмену для ПередачиТоваров
ПараметрыВыгрузки = Новый Структура;
ПараметрыВыгрузки.Вставить("Ссылка", Источник.Ссылка);
ПараметрыВыгрузки.Вставить("ПометкаУдаления", Истина);
ПараметрыВыгрузки.Вставить("Проведен", Ложь);
ВыгрузитьПоПравилу(ПараметрыВыгрузки, , , , "ПередачаТоваров");
КонецЕсли;
При реализации автоматической отмены проведения документов в процессе загрузки обмена необходимо учитывать следующие платформенные ограничения:
Записать(РежимЗаписиДокумента.ОтменаПроведения) вызовет исключение и полностью прервет транзакцию загрузки данных. Обязательно используйте конструкцию Попытка ... Исключение.Счет-фактура выданный), отмена проведения может быть заблокирована проверками типовой конфигурации.Если логика бизнес-процесса позволяет, рекомендуется рассмотреть архитектурные меры, предотвращающие возникновение таких коллизий: