Данная статья является второй статьей в цикле посвященном маркировке лекарственных препаратов. Ссылка на первую статью Маркировка лекарственных препаратов. Часть первая "Быстрая интеграция" //infostart.ru/1c/articles/1254468/ .
В данной статья я постараюсь поделиться собственным опытом работы с РВ, описанием работы с АПИ (для разработчиков), интересные моменты выявленные в ходе эксплуатации и уделить часть статьи пользователям, а именно ошибочным ситуациям и что с ними делать.
Регистратор выбытия (далее РВ) устройство для вывода лекарственных препаратов (далее ЛП) из оборота. На текущий момент нами используются две модели РВ – Штрих и АТОЛ. (Инструкции https://честныйзнак.рф/upload/iblock/2f6/Registrator_3.0.pdf, https://честныйзнак.рф/upload/iblock/c53/ATOL-RV-v.1.0.PDF ).
Настоятельно рекомендую регулярно проверять обновление документации на сайте Честного знака https://честныйзнак.рф/business/projects/medicines/documents/for_developers/ во избежание ошибок при разработке.
Порядок использования и основные моменты привожу по ссылке Честного Знака https://честныйзнак.рф/upload/iblock/33f/is_mp_opisanie_v2.2.0.pdf , чтобы не перегружать статью справочной информацией.
На текущий момент работа с РВ поддерживается библиотекой МДЛП (работа под веб не поддерживается) и если Вы не разработчик или Вам не актуально корректировать этот механизм можете пропустить часть статьи по разработке. Для всех интересующихся опишу свой опыт по данному вопросу.
Разработка
Взаимодействие с АПИ РВ я реализовывал еще до того как библиотека МДЛП начала поддержку РВ в своем составе, поэтому на текущий момент используются в коде те самописные методы что были реализованы ранее.
За работу с РВ отвечает документ Уведомление о выдаче в отделения. Перед отправкой документа выполняется несколько проверок во избежание ошибок обработки документа РВ.
Первая проверка это запакованность SGTIN. Если отправите не разупакованный SGTIN все равно по итогу получите ошибку. Данную проверку например можно выполнять методом АПИ МДЛП по запросу информации о SGTIN (https://честныйзнак.рф/upload/iblock/200/IS-_Markirovka_.-MDLP.-Protokol-obmena-interfeysnogo-urovnya-v3.11.pdf ) с помощью 8.3.3. Метод поиска по общедоступному реестру КИЗ по списку значений Endpoint: POST <endpoint>/<version>/reestr/sgtin/public/sgtins-by-list.
В таком случае перед отправкой будет необходимо выполнять лишний запрос в МДЛП, чего я рекомендую избегать по возможности. Альтернативой может являться ведение регистра накопления в который пишутся все движения нужных документов (в нем же хранить запакованность). Либо же можно использовать типовой регистр сведений УпаковкиМДЛП, однако в силу специфичности этого регистра и некоторых ошибок записи в него в типовой библиотеке я стараюсь избегать строить решения с его использованием.
Вторая проверка это заполнение Base64 в ТЧ упаковки. Так как в РВ отправляется SGTIN упакованный вместе с криптохвостом, то отправка документа где есть незаполненные значения приведет к ошибке.
Третья проверка это наличие и длина криптохвоста. 92 часть SGTIN должна присутствовать и иметь длину строго 44 символа (на текущий момент имеется небольшой процент ЛП на которые производители нанесли неверный криптохвост).
Четвертая проверка наличие этого SGTIN на данном Месте деятельности (далее МД). Позволяет избежать ошибок если например у организации есть 2 и более МД или выдача была уже произведена другим документом. Аналогично пункту 1 либо запросом, либо хранить в базе состояния упаковок, либо через УпаковкиМДЛП.
Пятая проверка относится к первичным упаковкам. МДЛП позволяет выдавать SGTIN частично. В АПИ за это отвечает ключ sold_part который представляет собой дробь, например 1/2, где 2 количество блистеров в упаковке, как на рисунке. Выдали из них в документе 1 блистер.
Осуществляется контроль не превышения этого количества по нескольким документам (остатки в регистре собираются по частям упаковок). Так как МДЛП не контролирует эти дробные части контроль остается на стороне 1С. Также нельзя передавать в РВ дроби типа 1/1, 5/5 и подобные, будет возвращена ошибка.
Любопытный факт – по одному SGTIN можно например выдать 5/10, 5/15, 14/15 последовательно разными документами и это не вернет ошибку. Упаковка по итогу спишется целиком если последняя отправка перекроет остаток в МДЛП на больше или равно.
Данные проверки уже позволят избежать множественных ошибок при отправке в РВ. Реализованы они на этапе Выполните проверку в документе. Пример кода проверок ниже. Вы можете адаптировать его под свои базы. Проверки количества и первичных упаковок не привожу, т.к. они работают только при наличии регистра накопления, отсутствующего в библиотеке МДЛП.
Для каждого стр из Объект.НомераУпаковок Цикл
Если Объект.ПередачаСведенийЧерезСКЗКМ Тогда
Если НЕ ЗначениеЗаполнено(стр.ШтрихкодBase64) Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "У КИЗ: " + стр.НомерКИЗ + " - не заполнен штрихкод BASE64";
Сообщение.Поле = "НомераУпаковок[" + (стр.НомерСтроки - 1) + "].НомерКИЗ";
Сообщение.КлючДанных = Объект.Ссылка;
Сообщение.ПутьКДанным = "Объект";
Сообщение.Сообщить();
ОшибкиПроверки = ОшибкиПроверки + 1;
Продолжить;
КонецЕсли;
// Удаление лишних символов.
стр.ШтрихкодBase64 = СтрЗаменить(стр.ШтрихкодBase64, Символы.ВК, "");
стр.ШтрихкодBase64 = СтрЗаменить(стр.ШтрихкодBase64, Символы.ПС, "");
//проверка Base64 на наличие и корректность криптохвоста
ДвоичныеДанныеСтроки = Base64Значение(стр.ШтрихкодBase64);
Если ДвоичныеДанныеСтроки <> Неопределено Тогда
Штрихкод = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанныеСтроки);
СтруктураШтрихкода = ИнтеграцияМДЛПКлиентСервер.ДанныеШтрихкода(Штрихкод);
КриптохвостЗначение = "";
Для каждого ЧастьШтрихкода Из СтруктураШтрихкода.ДанныеШтрихкода Цикл
Если ЧастьШтрихкода.ИдентификаторПрименения = "92" Тогда
КриптохвостЗначение = ЧастьШтрихкода.Значение;
Если НЕ СтрДлина(ЧастьШтрихкода.Значение) = 44 Тогда
ЗаполненоBase64 = Ложь;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "КИЗ: " + стр.НомерКИЗ + " - имеет ошибочный криптохвост(92)";
Сообщение.Поле = "НомераУпаковок[" + (стр.НомерСтроки - 1) + "].НомерКИЗ";
Сообщение.КлючДанных = Объект.Ссылка;
Сообщение.ПутьКДанным = "Объект";
Сообщение.Сообщить();
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ЗначениеЗаполнено(КриптохвостЗначение) = Ложь Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "У КИЗ: " + стр.НомерКИЗ + " - отсутствует криптохвост(92)";
Сообщение.Поле = "НомераУпаковок[" + (стр.НомерСтроки - 1) + "].НомерКИЗ";
Сообщение.КлючДанных = Объект.Ссылка;
Сообщение.ПутьКДанным = "Объект";
Сообщение.Сообщить();
ОшибкиПроверки = ОшибкиПроверки + 1;
КонецЕсли;
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "У КИЗ: " + стр.НомерКИЗ + " - некорректный BASE64";
Сообщение.Поле = "НомераУпаковок[" + (стр.НомерСтроки - 1) + "].НомерКИЗ";
Сообщение.КлючДанных = Объект.Ссылка;
Сообщение.ПутьКДанным = "Объект";
Сообщение.Сообщить();
ОшибкиПроверки = ОшибкиПроверки + 1;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Также перед отправкой в РВ требуется проверить не заблокирован ли РВ (данная проверка реализована на текущий момент в библиотеке МДЛП). Осуществляется методами «Запросить состояние РВ» (RequestStatusRv) и «Получить информацию об устройстве» (GetInformationRv) (документация https://честныйзнак.рф/upload/iblock/92b/TC-RV-v25_07.06.2019_Publichnaya-versiya.pdf ). Здесь нас интересует ключ «timeBlock» в котором хранится время до блокировки. Если отправить документ в заблокированный РВ, а после этого его разблокировать, то с большой долей вероятности документ так и останется висеть в очереди.
После выполнения проверок документ упаковывается в json и отправляется методом «Записать задание в очередь» (QueueUp).
Рекомендация – хранить эти идентификаторы запроса, многократно возникала ситуация когда один из документов вешал очередь в РВ и все остальные документы повисали в ожидании. Исправляется либо перезагрузками РВ, либо что более надежно очисткой очереди методом «Отменить задание» (Delete). Для очистки очереди (а также очистки задания после успешного запроса статуса) и необходимо хранить все ранее переданные идентификаторы.
В случае положения успешного ответа следом отправляется запрос статуса задания методом «Запросить статус задания» (RequestStatus), где rvRequestId это идентификатор запроса, который присваивается в 1С (GUID). При успешном запросе статуса будет получено значение ключа «mdlpRequestId» по которому этот документ в дальнейшем можно найти в ЛК и получить квитанцию(и).
Важное замечание – на один документ выдачи в 1С через РВ может быть создано несколько документов в ЛК. Документы могут быть разбиты по типам ошибок, если таковые имеются в квитанциях, либо на текущий момент разбиение по 50 SGTIN, либо по различным GTIN.
После получения mdlpRequestId рекомендуется очистить очередь от этого документа в РВ методом «Отменить задание» (Delete).
Следующий метод является не обязательным и вариативным для каждого типа РВ. Речь о методе «Получить отчёты о выбытии» (GetReports) который поддерживается РВ Штрих и на момент написания статьи не поддерживается РВ АТОЛ. Данный метод позволяет получить ответ от РВ по каждому заданию и по каждому SGTIN прошла ли проверка этих SGTIN в РВ будут ли они отправлены в МДЛП (к сожалению это не всегда так, возможна ситуация - для ЛП выпущенных до 01.07.2020 будет написано, что выдача подтверждена, а по факту они так и не уйдут в МДЛП).
Для получения квитанции последовательно реализованы несколько методов АПИ МДЛП (документация https://честныйзнак.рф/upload/iblock/200/IS-_Markirovka_.-MDLP.-Protokol-obmena-interfeysnogo-urovnya-v3.11.pdf ) .
Для начала используется метод 5.18. Прослеживание документов по отчёту из СУЗ в фильтр которого передается mdlp_request_id. Данный метод вернет список document_id которые требуется загрузить методом 5.14. Получение документа по идентификатору. После получения списка требуется методом 5.16. Получение квитанции по номеру исходящего документа получить link по которому скачивается квитанция.
Важный момент – так как один документ в 1С может разделиться на несколько в МДЛП, причем каждый из этих документов будет иметь свою квитанцию, то по части документов может уже пройти обработка, а по части нет. Соответственно на какой-то момент времени документ будет находиться в статусе частичного получения квитанции. Но может возникнуть ситуация когда РВ некоторые SGTINы не отправил и не отправит уже в МДЛП. В таком случае необходим анализ документов в ЛК и правка документа в 1С. Для упаковок которые не выдались потребуется либо повторная отправка новым документом через РВ, либо в обход РВ (по 531 схеме). В таком случае документ отправится напрямую и будет видна квитанция по нему после обработки.
Как я писал ранее работа под веб типовой библиотекой МДЛП не поддерживается, но это не значит, что данная задача не решаема. Небольшая доработка напильником и методы работы с РВ становятся доступны в браузере.
Ошибочные ситуации
При работе с РВ возможны ошибочные ситуации, как по причине ошибок в 1С, так и по причине проверок в РВ или МДЛП.
Часть проверок реализована библиотекой МДЛП, разбор ошибочных ответов от РВ так же должен разбираться корректно. При этом, как я обозначал выше, могут быть проблемные ситуации не самые очевидные.
Самой часто встречающейся ошибкой на текущий момент является ошибочность КМ при создании его поставщиком. Зачастую это относится к КМ выпущенным до 01.07.2020, но изредка встречаются КМ выпущенные позже, но имеющие те же самые проблемы.
Что происходит в данной ситуации? Документ с такими КМ отправляется в РВ, тот возвращает успешный ответ постановки в очередь, после запроса статуса он тоже будет возвращен успешный. Для РВ ШТРИХ можно запросить статусы выбытия и там они тоже будут как «Выбытие подтверждено». Но в ЛК эти КМ так и не придут.
Что предпринять в данном случае?
Первое подождать от 1 часа до 24 пока документ не появится в ЛК (возможны задержки обработки очереди).
Второе проверить КМ в ЛК на дату их выпуска на вкладке Товары и если имеются выпущенные ранее 01.07.2020, которые так и не появились в ЛК после отправки в РВ, необходимо рассмотреть возможность создания нового документа выдачи с отправкой по схеме 531, минуя РВ.
Следующая ошибка относится исключительно к РВ АТОЛ. Отправка документа вызывает ошибку – срок действия пин-кода истек, требуется ввести заново. Тут все просто, как и в ситуации с заблокированным РВ. Просто вводится новый пин-код с перезагрузкой или восстанавливается связь со спутниками.
Также есть частая ошибка, одна из самых непонятных для пользователя на текущий момент возврат ошибки из МДЛП «Недопустимый переход в товаропроводящей цепочке». Под этой ошибкой может пониматься целое подмножество ошибок:
- КМ находился не в статусе «В обороте» на момент выдачи (выдан ранее, не принят);
- КМ выбывается не с того МД на котором находится (если МД у организации несколько);
- нарушена временная последовательность выдачи (ситуация когда приемка была позже чем выдача).
Тут надо остановиться подробнее с конкретным примером. Допустим, есть ситуация когда приемка зафиксирована в 12.00, но поставщик не учел рекомендации по указанию часового пояса и отправил без +03.00 в дате. РВ игнорирует передаваемое время в json и выставляет свое время фактическое. Таким образом любая выдача до 15.00 будет приводить к ошибке. Ситуация к счастью довольно редкая, но возможная.
В такой ситуации рекомендую обратить на время указанное в xml документа приемки, а именно передал ли поставщик часовой пояс в дате.
Возможно Вы наталкиваетесь на другие ошибки при использовании РВ, которые я забыл или не встречал. Напишите, пожалуйста, о них в комментариях и возможно решения по ним я смогу включить в статью для помощи другим пользователям.
Если Вас интересуют какие-то определенные темы напишите, пожалуйста, в комментариях. Возможно я включу их в последующие статьи. Также приветствуется здоровая критика статьи, которая поможет сделать ее лучше.
P.S. Довольно часто наталкиваюсь на обвинения что маркировка ухудшает работу, Честный Знак работает плохо и т.д. Тут выражу исключительно собственное мнение по данной ситуации. Идея маркировки ЛП исходит из уменьшения контрафактных ЛП и прослеживаемости каждого этапа жизненного цикла ЛП, что в целом приведет к улучшению медицины. За маркировку требуют денег – когда Вы начнете работать бесплатно можем вернуться к этому вопросу. РВ организациям выдают бесплатно. Нестабильная работа Честного Знака – я занимаюсь маркировкой ЛП уже 3й год и хорошо видел развитие с точки зрения разработчика. Служба поддержки всегда реагировала на мои заявки адекватно, некоторые пожелания были действительно учтены в новых релизах. Документация для разработчиков очень удобная и детальная. Я брал ее за образец при написании собственных АПИ например. Нестабильная работа и ошибки – да имеют место, но как разработчик я прекрасно понимаю какой объем работы необходимо проделывать чтобы система работала стабильно по всей нашей весьма немаленькой стране.
Разумеется, есть негативные моменты которые постоянно всплывают в обсуждениях. Я со своей стороны прошу пользователей относиться с терпением к данной системе, которая все-таки становится лучше и будет стабильнее со временем. А с разработчиками готов поделиться своим опытом в данном направлении чтобы делать качественный продукты для пользователей.
P.P.S. Хочу поблагодарить свою проектную команду, благодаря которой мы успешно развиваемся. Спасибо. Эта статья и ваша заслуга.