Показать сообщение отдельно
Старый 03.12.2012, 21:56   #1  
EVGL is offline
EVGL
Banned
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
4,445 / 3001 (0) ++++++++++
Регистрация: 09.07.2002
Адрес: Parndorf, AT
Опыт: синхронизация справочников через AIF в AX2012
Поделюсь опытом: задача синхронизации справочников поставщиков и клиентов через AIF (в моем случае - из AX 4.0 в AX 2012) ... в общем случае не решается без интерактивной работы и адаптации ведущей программы (CRM итд.) к ведомой (AX2012). Кое-чего, однако, можно добиться с минимумом программирования.

Пусть ведущая система (здесь: AX 4.0) ничего не знает о ведомой. Сразу возникает вопрос: когда новая запись в справочнике достигает той степени полноты, чтобы передать его в ведомую систему? В худшем случае над записью работает несколько отделов. Можно запускать пересылку в конце рабочего дня, можно проверять заполнение обязательных полей.

Так или иначе, ведущая система дает толчок и размещает файл с клиентом/поставщиков в заданном каталоге сети. Для этого в AX 4.0 есть классический код из \Data Dictionary\Tables\CustInvoiceJour\Methods\sendElectronically(). Учетная запись процесса, записывающего файл, должна быть именованной и быть Owner-ом файла: http://msdn.microsoft.com/en-us/libr...=ax.10%29.aspx

В AX2012 создается входящий порт, который читает каталог и передает файл сервису CustCustomerService.create, CustCustomerService.update. В параметрах порта добавляем в Pipeline входящее преобразование XSLT к схеме AX2012 (см. ниже).

Создается batch job, в котором вручную (!) прописываются классические 2 процесса для чтения:
- AifGatewayReceiveService
- AifInboundProcessingService

Запускаем batch job, и после 100 проб и ошибок получаем первую запись.
Характерно, что можно создать CustTable, DirPartyTable и все до единой связанные таблицы, даже стандартную аналитику. Ключевое слово здесь - это "создать".

Вслепую обновить удастся только саму CustTable, поскольку AX2012 требует <EntityKeys> того, что надо обновлять. В качестве этих Keys можно взять Primary Key или RecId таблицы. Если для CustTable есть натуральный ключ AccountNum, то для DirPartyTable есть только PartyId = RecId, который внешней программе не известен без дополнительного запроса getKeys и целой программной машинерии для обработки этого запроса. Впрочем, и без этого есть пара подводных камней:

1) При запросе на обновление система требует текущую RecVersion записи или Hash записи, который опять-таки надо получать интерактивным запросом. Тем самым система пытается предотвратить конкурентные обновления. Можно вырвать системе ядовитые зубы, закомментировав все проверки на Hash в классе AxdBaseUpdate.

2) Для обновления AX требует дату и время документа в элементе <ValidAsOfDateTime>. Если ведущая система такой информации не дает, то приходится извращаться, ибо .NET не поддерживает стандарт XSL/XPath 2.0 и, в частности, такую функцию как fn:current-DateTime()

3) Если в атрибуте action не указать "update", чтобы ввести систему в режим "инкрементного обновления", то AX2012 попытается стереть связанные таблицы типа DirPartyTable. Т.е. в XML файле должно стоять <CustTable class="entity" action="update">

А теперь привожу плод бессонных ночей - трансформацию XSLT, которая преобразует "плоскую" запись в формат AX2012, включая адреса и телефоны. Это преобразование реагирует на сигнал <DocPurpose>Duplicate</DocPurpose> и переходит из режима полного create в частичный update:

CustTable_AX40_to_AX2012.zip

Последний раз редактировалось EVGL; 03.12.2012 в 22:21.
За это сообщение автора поблагодарили: Ruff (5), belugin (10).