Не нашел нигде описание процесса получения и проведения документов при обмене по универсальному формату. Ответ пришлось искать в недрах БСП (версии 3.0.3.164).
Логику поведения обмена документами можно понять из функции общего модуля ОбменДаннымиXDTOСервер.СтруктураОбъектаXDTOВДанныеИБ.
Логика получения документа из файла обмена:
1. Получаются данные из файла обмена и находится соответствующий им объект в базе.
ПолученнныеДанные — объект сформированный из полученных из xml файла обмена данных. Ссылку не содержит.
ДанныеИБ — объект информационной базы, соответсвующий (согласно правилам идентификации) объекту из файла. Если объекта в базе нет, то Неопределено.
2. Вызвается процедура из правил конвертации ПередЗаписьюПолученныхДанных, в которой с этими объектами можно произвести нужные манипуляции (но не все будет действовать). Или можно совсем отказаться от дальнейшей работы БСП, прописав свою логику и установив ПолученнныеДанные=Неопределено и ДанныеИБ=Неопределено.
3. Из ПолученнныеДанные и ДанныеИБ определяется объект ДанныеДляЗаписиВИБ с которым и происходит дальнейшая работа. Если ДанныеИБ существует, происходит заполнение его свойств из ПолученнныеДанные (ЗаполнитьДанныеИБПоПолученнымДанным), но при этом не переносится ПометкаУдаления и признак Проведено. По сути Проведено будет действовать только для новых документов. Для уже существующих будет использоваться их признак Проведено.
4. ПометкаУдаления сбрасывается.
5. Анализируется признак ДанныеДляЗаписиВИБ.Проведен. Если документ проведен, то проведение в ИБ отменяется и документ добавляется в таблицу для отложенного проведения КомпонентыОбмена.ДокументыДляОтложенногоПроведения. Если документ не проведен, то просто отменяется проведение. Кстати в дальнейшем, из таблицы строку документа можно удалить и проведение не произойдет.
В формате EnterpriseData для документов нет признаков ПометкаУдаления и Проведен.
Документы выгружаются, только если они проведены (указывается в правилах регистрации). Проводятся в базе получателе и далее состояние Проведен работает независимо в базе источнике и базе получателе. Если я правильно понял.
Реализация практической задачи
Встала задача. Организовать перенос из БП в УТ типового документа, которым они обмениваются в другом направлении. В БП документ реализован в расширении, в УТ это типовой документ. Необходимо синхронизировать состояние документа: проведен, не проведен, установлена пометка удаления.
Базы с поддержки не снимаем, используем расширения. Дорабатываем типовые правила обмена.
Решение:
1. Загружаем правила конвертации из баз БП и УТ. Тот еще квест. Подсказки можно найти в статье //infostart.ru/public/695523/. У меня так и не получилось, что бы в результате загрузки получились идентичные модули менеджера обмена. Но для доработки правила обмена одного документа это не критично.
2. Пишем правила отправки и получения документов в одной и другой конвертации. Не тема этой статьи, но в моем случае ничего сложного. Похоже на КД2, только нужно помнить, что табличные части нужно обрабатывать специальным образом.
Создаем Правило конвертации объекта, Правила конвертации свойств в нем. Для свойств табличных частей обязательно указываем «используется алгоритм конвертации» и обрабатываем заполнение в обработчиках.
3. Реализуем перенос состояния документа при отправке через AdditionalInfo (событие при отправке данных)
4. Реализуем логику приема со статусом в другой конвертации
4.1. Сначала в событии ПриКонвертацииДанныхXDTO получаем состояние документа из AdditionalInfo и заполняем им ПолученныеДанные
4.2. В событии ПередЗаписьюПолученныхДанных выставляем правильные флаги у правильных объектов, что бы алгоритмы БСП сделали синхронизацию состояния проведения объектов, а не взяли состояние текущего объекта.
Для этого нужно всего лишь статус ДанныеИБ.Проведен (если ДанныеИБ нашлись) заполнить из ПолученныеДанные.Проведен. Далее все произойдет корректно, документ из ИБ заполнистя данными из файла обмена, отменится его проведение и он будет добавлен в ДокументыДляОтложенногоПроведения если это необходимо.
Пометку удаления необходимо обрабатывать отдельно и отменять дальнейшее действие правила, потому что далее в БСП она игнорируется.
Можно также здесь отменить загрузку непроведенного документа, отсутствующего в базе приемнике (в тексте не реализовано).
5. Добавляем правила в расширения.
Из КД3 выгружаем модуль менеджера обмена для конвертации. Сравниваем его в с текущим модулем менеджера обмена (Файл — Сравнить файлы). Отличия реализуем через расширение (одних методов После вполне достаточно). Повторяем для другой конвертации.
6. Добавляем к Плану обмена обеих конфигураци СинхронизацияДанныхЧерезУниверсальныйФормат реквизит типа булево, включающий нашу функциональность (РасшБП_ВключитьНашОбмен). Выносим его на форму узла.
7. Реализуем регистрацию объекта на узлах плана обмена.
В моем случае в БП (источнике) документ был добавлен в расширение, а в УТ (получателе) уже был в конфигурации, но нужно было отменять отправку, если мы его получили.
Состав Плана обмена СинхронизацияДанныхЧерезУниверсальныйФормат можно дополнить через расширение (снимаем авторегистрацию).
Подписки на события изменять в расширении нельзя, но для одного документа можно просто дополнить процедуры ПередЗаписью и ПередУдалением, разместив там вызов процедуры из событий подписок СинхронизацияДанныхЧерезУниверсальныйФорматРегистрацияДокумента и СинхронизацияДанныхЧерезУниверсальныйФорматРегистрацияУдаления.
С этими процедурами будут отрабатывать правила регистрации, если их отредактировать.
И далее можно:
а) Изменить правила регистрации, указав зависимость регистрации документа от установки этого реквизита РасшБП_ВключитьНашОбмен (их можно загрузить из файла в пользовательском режиме), но потом возможно нужно будет обновлять правила регистрации при их обновлении в типовой, что может быть не удобно.
б) Либо программно убрирать лишние узлы в событии документа ПередЗаписью (так сказать, правила регистрации программно)
Если используется документ из типовой и он содержит подписки, необходимо использовать ПриЗаписи (вместо ПередЗаписью) для аналогичной функции, т.к. подписки отрабатывают после всех расширений (в моем случае это БП, код не привожу, он аналогичен).
Готово. Типовая может обновляться, правила типовой могут обновляться, переделка нашего правила при этом не потребуется.
Выводы:
1. Для проведения полученных документов используется таблица КомпонентыОбмена.ДокументыДляОтложенногоПроведения, по которой документы проводятся после обмена. Таблицу можно править в событиях.
2. Документы попадают в эту таблицу по признаку Проведен:
для нового документа — используется признак из обмена (ПолученныеДанные.Провден)
для существующего документа — используется признак из ИБ (ДанныеИБ.Проведен)
ДанныеИБ.Проведен не замещается из ПолученныеДанные.
3. Если нужно изменить это поведение, в событии ПередЗаписьюПолученныхДанных можно для ДанныеИБ.Проведен установить нужный признак. Или вообще реализовать свою логику и отказаться от дальнейшего выполнения правила.