Данная публикация основана на 4-х месячном опыте интеграции учетных систем оптовых организаций с УТМ ЕГАИС, и будет полезна в первую очередь тем, кто только в начале этого пути.
Тем, кто хочет срезать путь:
С наступающим, коллеги!
Как, наверное, многим уже известно, разработчики ЕГАИС взяли на себя только серверную часть системы и транспортную службу (УТМ), переложив значительную часть работы по разработке клиентской части ЕГАИС на организации оптовой и розничной торговли алкоголем.
Практика покажет, как разработчики справились со своей частью системы. Форум информационного портала ЕГАИС http://egais2024.ru/forum/ переполнен темами о проблемах с УТМ и серверной частью ЕГАИС.
В целом же, в совокупности с клиентской частью, разрабатываемой разношерстной ордой штатных программистов организаций алкогольной отрасли, а также коммерческими решениями разного уровня качества, от системы ЕГАИС сложно ожидать качественного результата.
Вам повезет, если служба УТМ с первого раза установится и заработает. ПО бесплатное, но шаманский бубен для танцев с ним уже за ваш счет. Техподержка со стороны разработчика ЕГАИС (ФГУП «ЦентрИнформ») оказывается в недостаточном объеме, фактически её нет.
Документация доступна в личном кабинете на сайте egais.ru, для доступа в который необходим крипто-ключ. Но интернет не без добрых людей, и вот она у вас в руках. Подвох в том, что документацией назвать этот сборник примеров можно лишь с большой натяжкой. Отсутствует самое необходимое — описание форматов обмена, структуры полей, правил их заполнения. Разработка интеграции по приведенным примерам xml запросов больше похоже на игру «угадайка», чем на разработку интеграции по техзаданию.
Методом «научного тыка» за истекший квартал было выявлено множество «подводных камней» при интеграции с УТМ ЕГАИС, итак…
Специфический формат http запроса к УТМ
УТМ не принимает xml объекты в http запросе так, как это делают «нормальные веб-сервисы». Т.е. запрос к примеру HttpRequest.Send(XMLobject) не будет принят веб-сервисом.
При детальном анализе приведенных в документации примеров работы утилиты curl выяснилось, что xml запрос отправляется файлом, вложенным в тело http запроса. Получить детали отправки запроса утилитой curl можно с помощью параметров -v и —trace-ascii
C:UsersPalmer>d:curlcurl -F «xml_file=@d:curl
ests.xml» http://localhost:8080/opt/in/QueryRests -v
* About to connect() to localhost port 8080 (#0)
* Trying localhost…
* Adding handle: conn: 0x981460
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* — Conn 0 (0x981460) send_pipe: 1, recv_pipe: 0
* Connected to localhost port 8080 (#0)
> POST /opt/in/QueryRests HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:8080
> Accept: */*
> Content-Length: 578
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=—————————-8d32aca7ce7b
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Content-Type: text/xml;charset=UTF-8
< Content-Length: 261
* Server Jetty(8.1.14.v20131031) is not blacklisted
< Server: Jetty(8.1.14.v20131031)
<
<?xml version=»1.0″ encoding=»UTF-8″ standalone=»no»?><A><url>f541c64f-85fb-4e8d-8c29-9d604aaf451b</url><sign>7D75C3A62F
DBE2740AE8EC695008DF27FFA8F1258D8101A5B962370086892772B2573C5C4C6D7E1D15A6EC0E383EDE432C11F63F8976BD17052401EF3B9D5CD3</
sign><ver>2</ver></A>* Connection #0 to host localhost left intact
boundary — это случайным образом сгененерированный разделитель, которые обрамляет вложение
d:curlcurl -F «xml_file=@d:curl
ests.xml» http://localhost:8080/opt/in/QueryRests —trace-ascii d:curl race.txt
== Info: About to connect() to localhost port 8080 (#0)
== Info: Trying localhost…
== Info: Adding handle: conn: 0x4a1508
== Info: Adding handle: send: 0
== Info: Adding handle: recv: 0
== Info: Curl_addHandleToPipeline: length: 1
== Info: — Conn 0 (0x4a1508) send_pipe: 1, recv_pipe: 0
== Info: Connected to localhost (localhost) port 8080 (#0)
=> Send header, 228 bytes (0xe4)
0000: POST /opt/in/QueryRests HTTP/1.1
0022: User-Agent: curl/7.30.0
003b: Host: localhost:8080
0054: Accept: */*
0061: Content-Length: 578
0076: Expect: 100-continue
008c: Content-Type: multipart/form-data; boundary=———————
00cc: ———83e52bad6452
00e2:
<= Recv header, 23 bytes (0x17)
0000: HTTP/1.1 100 Continue
=> Send data, 148 bytes (0x94)
0000: ——————————83e52bad6452
002c: Content-Disposition: form-data; name=»xml_file»; filename=»rests
006c: .xml»
0073: Content-Type: application/xml
0092:
=> Send data, 382 bytes (0x17e)
0000: …<?xml version=»1.0″ encoding=»UTF-8″?>
002b: <ns:Documents Version=»1.0″
0048: xmlns:xsi=»http://www.w3.org/2001/XMLSchema-instance»
007f: xmlns:ns=»http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01″
00b3: xmlns:qp=»http://fsrar.ru/WEGAIS/QueryParameters»>….
00eb: <ns:Owner>
00f7: <ns:FSRAR_ID>030000000000</ns:FSRAR_ID>
0120: </ns:Owner>
012d: <ns:Document>
013c: <ns:QueryRests>
014d: </ns:QueryRests>
015f: </ns:Document>
016f: </ns:Documents>
=> Send data, 48 bytes (0x30)
0000:
0002: ——————————83e52bad6452—
<= Recv header, 17 bytes (0x11)
0000: HTTP/1.1 200 OK
<= Recv header, 38 bytes (0x26)
0000: Content-Type: text/xml;charset=UTF-8
<= Recv header, 21 bytes (0x15)
0000: Content-Length: 261
== Info: Server Jetty(8.1.14.v20131031) is not blacklisted
<= Recv header, 33 bytes (0x21)
0000: Server: Jetty(8.1.14.v20131031)
<= Recv header, 2 bytes (0x2)
0000:
<= Recv data, 261 bytes (0x105)
0000: <?xml version=»1.0″ encoding=»UTF-8″ standalone=»no»?><A><url>ec
0040: 24fa9c-9f50-4383-b8bb-f2f76ccac7e5</url><sign>F7593B4E7742DA4C8A
0080: A8E393B99D5AB06BFE86757C38DAC31E81514D3175ED06BCC86069CF06732856
00c0: 4B30651DBE97ABB5EC109C7BBA378BA559585BB47ABE90</sign><ver>2</ver
0100: ></A>
== Info: Connection #0 to host localhost left intact
Причем xml ответы на запросы УТМ возвращает уже нормальным способом, и с ними можно сразу работать как с xml объектами класса MSXML.DOMDocument.
Решение
Пример рабочего алгоритма формирования http запроса к УТМ на платформе 1С 7.7
Пример рабочего алгоритма формирования http запроса к УТМ на платформе 1С 8
УТМ не дружит с кириллицей
В ответах на ошибочные запросы (а у вас при отладке интеграции они будут), содержащие описание ошибки, вместо символов кириллицы отображаются ?????.
Решение
Найти описание ошибки в нормальной кодировке можно в логах УТМ:
C:TT ransporterlogs ransport_info.log
C:TT ransporterlogs ransport_error.log
Схема работы ЕГАИС
На информационном портале ЕГАИС приведена следующая схема работы ЕГАИС:
Однако производители и импортеры работают в «старом» ЕГАИС, который с «новым» ЕГАИС полностью так и не состыковали. Схема работы с ними полностью не реализована, и вероятно по факту выглядит так:
Решение
Учесть в своих алгоритмах обмена данными с УТМ, что от производителя/импортера не нужно ждать подтверждения на акт расхождений. Вместо него от сервера ЕГАИС сразу приходит квитанция о том, что ТТН проведена.
Нумерация ТТН
По этой же причине в ТТН от производителей/импортеров не соблюдается уникальность нумерации ТТН. По одной бумажной ТТН от производителя через ЕГАИС может прийти несколько электронных под одним номером, например в разбивке на импортный и отечественный товар. Остальным же система не даст отправить еще раз ТТН с тем же номером и датой.
Решение
Нумерацию загруженных ТТН нужно вести по уникальному идентификатору в системе ЕГАИС (тег wbr:WBRegId в FORMBREGINFO)
Двухкомпонентный формат ТТН
Каждая ТТН приходит парой xml файлов, WAYBILL и FORMBREGINFO. И в них нет идентификатора, по которому их было бы можно сопоставить друг другу.
Идентификатор ТТН есть только в FORMBREGINFO, в WAYBILL его нет. В обоих есть тег identity, но он не обязателен к заполнению, поэтому не подходит на эту роль.
Решение
Однозначное сопоставление достигается по составному ключу: номер ТТН + дата ТТН + идентификатор грузоотправителя + identity
Составной ключ для WAYBILL: wb:NUMBER + wb:Date + wb:Shipper/oref:ClientRegId + wb:Identity
Составной ключ для FORMBREGINFO: wbr:WBNUMBER + wbr:WBDate + wbr:Shipper/oref:ClientRegId + wbr:Identity
Единица измерения отсутствует
В каких единицах измерения указано количество можно узнать только по ТТН, в ней есть признак типа продукции фасованная/нефасованная (packed/unpacked). В зависимости от этого признака, количество указано сответственно в штуках/декалитрах. Справочник номенклатуры ЕГАИС такого признака не содержит. Ваши остатки в ЕГАИС — тоже. В каких единицах измерения отображаются ваши остатки, а также в каких делать ввод остатка — можно только угадывать. Если не угадали — это выяснится только в момент реализации.
Решение
Добавить признак типа продукции в справочник номенклатуры, заполнять его при получении ТТН с этой продукцией, и использовать в дальнейшем. Не допускать смешивания в одной ТТН номенклатуры с разными признаками. Вопрос с единицей измерения ввода остатков номенклатуры, которую еще не получали — остается открытым.
Размерность полей даных
В xsd-схемах формата обмена с УТМ самая популярная размерность полей данных — строка 50 символов.
Сами данные по факту занимают гораздо меньше. Те, кто ограничил размерность полей в своих базах данных интеграций длиной по факту, в дальнейшем могут столкнуться с потерей данных при внезапном увеличении их длины. Прецедент уже был при внезапном объявлении текущей ЕГАИС тестовой и появлении дополнительного префикса «TEST- в идентификаторах. Размерность некоторых полей в xsd-схемах была изменена буквально за неделю до Нового Года.
Решение
После записи данных, полученных из ЕГАИС в вашу базу данных, необходимо проверять результат на предмет потери исходной длины/точности. И следите за обновлением xsd-схем в веб-интерфейсе УТМ ЕГАИС.
Порядок позиций документа в xml
Порядок позиций в xml файлов может не соответствовать порядку позиций в документе. Например документ состоит из нескольких xml файлов, в которых разный порядок позиций (ACTCHARGEON и INVENTORYREGINFO). Данные могут перемешаться при последовательной записи «в лоб» позиций в базу данных.
Решение
Необходимо учитывать номер идентификатор позиции, указанный в теге Identity. Данные по позиции из второго xml файла дописывать в соответствующую ей позицию документа, спозиционировавшись на неё по номеру идентификатору позции из тега Identity. Идентификатор позиции имеет тип данных — строка 50 символов.
Некорректные данные
Файлы xml (например WAYBILL), которые формируются клиентской частью ЕГАИС грузоотправителя, переслаются грузополучателю в исходном виде «как есть», даже если они сформированы с ошибками и не соответствуют описанному в документации формату. Например используются префиксы тегов, отличные от префиксов, приведенных в примерах в документации.
Решение
Необходимо проверять получаемые данные на соответствие формату хотябы поверхностно, и обязательно сохранять исходные данные перед удалением из базы данных УТМ для последующего разбирательства.
Необязательные теги
Некоторые ключевые теги объявлены необязательными, и могут отсутствовать в полученных xml. Например Identity во всех документах, IsAccept в WAYBILLACT, IsConfirm в WAYBILLTICKET.
Решение
Изучить утвержденный формат и обеспечить корректную обработку в алгоритмах отсутствия необязательных тегов либо заполнение их значением по-умолчанию.
Продолжение следует…
Из очевидных проблем автоматизации еще можно выделить такие:
http://forum.fsrar.ru/viewtopic.php?f=101&t=37549&p=250414#p250414
— нужно сканировать марки при постановке на баланс, хотя они не участвуют в товародвижении
— тэг IsAccept в акте подтверждения/отказа является не обязательным
— сделано разделение, что фасованную продукцию нужно хранить в ЕГАИС в штуках, а нефасованную в декалитрах. Нужно при выгрузке ТТН, загрузке ТТН переводить туда-сюда эти данные
— признак фасовки принадлежит ТТН, а не товару, поэтому нужно делить ТТН на фасованные и нефасованные
— акт отказа на акт расхождения покупателя возвращает ВЕСЬ товар по ТТН обратно на склад, и подразумевает отправку новой ТТН покупателю, хотя это совсем не очевидно
— передача всех данных по товарам (название, параметры) и контрагентам через xml, хотя если бы оставили только коды, которые уникальны, файлы бы уменьшились в объеме в десятки раз. На распаковку таких файлов серверу ЕГАИС требуется больше времени
— получение ответа от ЕГАИС сейчас занимает в среднем 2,5-3 минуты
— сервер ЕГАИС часто вообще не возвращает ответ на запрос
— постоянные проблемы с УТМ, отваливаются службы, ключи, становятся недействительными сертификаты на ключе
— дубли ТТН входящих при повторной отправке поставщиком, нужно работать со вторым экземпляром
— дубли в справочниках товаров и контрагентов ЕГАИС, что делает порой невозможным уникально сделать привязку своих справочников к справочникам ЕГАИС
список можно продолжить…
Все верно. А риторика и действия гос.службы напоминает …СССР!
С их стороны мы уже в коммунизме или вот вот в него попадем. На сайте фсрар вывесили пузометр как много уже оптовиков в егаисе- очковтирательсто полное. Мы оптовики нижнего уровня, а от наших поставщиков не производителей/импортеров приходит через Егаис только 10%, остальные вот -вот говорят сейчас.
И я их понимаю, т.к. сами тоже будем готовы вот-вот скоро.
Ну а как это — запускать систему если официально формат обмена был принят за месяц до ввода в эксплуатацию при отсутствии документации на систему, я вообще не могу понять.
Партия сказала надо- комсомол ответил есть!
p.s.
извините за грустный выброс наболевшего
Всех с наступающим Новым Годом, да прибудет с Вами Сила!
p.p.s. это не реклама фильма, однако… 🙂
Еще добавлю несколько моментов:
1) При переустановке УТМ (плановое/сбой и т.д.) — имеется шанс потерять входящие документы (к примеру входящие ТТН). Те документы-ссылки, которые уже загрузились в УТМ, но не были вами обработаны. На вновь переустановленный УТМ эти документы уже никак не перегрузить (если только просить поставщика отменить ТТН и перевыгрузить в ЕГАИС заново).
2) В постановке на баланс в офиц. документации (если так можно назвать это недоразумение), существовали 2 схемы:
а) InformABKey — постановка на баланс продукции с известными ИД СправкиА/СправкиБ;
б) InformABReg — постановка на баланс продукции с неизвестными заранее ИД СправкиА/СправкиБ;
Все бы здорово — поставили на баланс по неизвестным справкам — получили в ответ ИД СправкиА/СправкиБ — привязали данные ИД к партии в учетной системе. Если в будущем появляется пересорт по партиям с привязанными ИД СправкиА/СправкиБ — просто делаем InformABKey по известным ИД и радуемся соответствию остатков УС и ЕГАИС.
И тут разработчики УТМ делают нерабочей схему InformABKey! Проблема в том, что при схеме InformABReg ЕГАИС возвращает ВСЕГДА разные ИД СправкиБ (ИД СправкиА одинаковые при идентичных параметрах схемы InformABReg )! Прозрачная схема сопоставления партий ЕГАИС и УС летит ко всем чертям! Теперь, чтобы привязать «+» по «уже привязанной» партии — этот «+» надо сначала увести на новую партию в УС, а затем уже эту партию ставить на баланс в ЕГАИС. Все конечно зависит от конкретной реализации партионного учета и сопоставления данного учета с ЕГАИС, но, думаю, 95% разработчиков просто добавили в свои партии ссылки на партию ЕГАИС (дабы не реализовывать отдельный партионный учет партий ЕГАИС на отдельных регистрах).
3) На конференции 02.12.15 в Москве с трибуны говорили, что поставщики смогут подтвердить за покупателя ТТН, если покупатель не подключен к ЕГАИС. В видеоконференции от 18.12.2015 уже говорят, что данную возможность будут убирать.
Складывается впечатление, что все делается «на ходу» — «тут подделаем, тут подлатаем — авось заработает».
Вообще после общения на форуме forum.fsrar.ru — ощущение жутчайшего дедлайна!
ЕГАИС запускается уж какая есть, кривая-косая.
И изменения в системе в последний момент перед запуском увеличивают количество ошибок в клиентской части системы, не успевающей за её метаморфозами.
Из последних метаморфоз: для нефасованной номенклатуры объем (тег <pref:Capacity>) теперь не указывается вовсе (ранее был =1); нулевое значение в этом теге вызывает ошибку;
как следствие — отсутствие объема у номенклатуры косвенный признак того, что она нефасованная, и её учет ведется в декалитрах.
Еще раз с наступающим! С НОВЫМ ГОДОМ!
(4) Ага ! Не давно тоже разбирался с тегом pref:Capacity. Реквизит не обязательный, но для многих он очень важен. Тип у реквизита: type=»c:PositiveDecimalType»
<xs:simpleType name=»PositiveDecimalType»>
<xs:restriction base=»xs:decimal»>
<xs:minExclusive value=»0″/>
</xs:restriction>
</xs:simpleType>
При попытки отправить xml с товаром где capacity 0 будет ошибка и xml не уйдёт. При отправки нужно делать проверку по заполненной емкости в номенклатуре. полный метаформоз 🙂
Еще одна «особенность» ЕГАИС. Поле «КПП» может содержать в себе подчеркивание. Пример:
Показать
(6) amoarok, это не особенность, это кривые руки при вводе этих данных