С переходом на поштучный (помарочный) учет алкогольной продукции в ЕГАИС разработчики и администраторы систем на базе 1С столкнулись с серьезным изменением структуры штрихкодов. Если раньше из старых марок формата PDF417 можно было относительно легко «выдернуть» код алкогольной продукции (алкокод) с помощью несложного алгоритма декодирования, то новые марки формата DataMatrix поставили многих в тупик. В этой статье мы подробно разберем, почему старый подход больше не работает, детально изучим анатомию новой марки и рассмотрим практические способы решения задачи сопоставления марки и алкокода в 1С.
Для начала вспомним, как это работало ранее. Старые акцизные марки длиной 68 символов в формате PDF417 содержали информацию об алкокоде непосредственно внутри своего тела. Он был зашит в штрихкод со 3-го по 18-й символ и зашифрован по алгоритму Base36. Разработчикам было достаточно написать простую функцию преобразования из 36-ричной системы счисления в 10-тичную, чтобы получить привычный 19-значный числовой алкокод. Это происходило мгновенно на стороне клиента и не требовало никаких запросов к базе данных ЕГАИС.
С новыми марками DataMatrix ситуация принципиально иная. Эти марки печатает не сам производитель алкоголя в момент розлива, а АО «Гознак». На момент печати марка является «пустышкой» — она еще не привязана к конкретной бутылке, заводу, партии или наименованию продукции. Связка между физической маркой и конкретным алкогольным продуктом (и, соответственно, его алкокодом) создается значительно позже — когда производитель или импортер наклеивает марку на бутылку и отправляет в ЕГАИС документ «Отчет о производстве» или «Импорт продукции». Таким образом, внутри самой новой марки алкокода физически нет. Он хранится исключительно в облачной базе данных ЕГАИС.
Давайте проанализируем структуру штрихкода новой марки. Он имеет строго регламентированную длину — 150 символов — и состоит из следующих блоков данных:
Несмотря на то, что алкокод отсюда извлечь нельзя, мы можем легко вырезать уникальный идентификатор марки — её серию и номер. Эти данные полностью соответствуют визуальной информации, напечатанной на бутылке.
Для программного извлечения серии и номера в среде 1С мы можем использовать стандартную строковую функцию Сред. Разберем несложный пример кода:
// Функция принимает на вход считанный сканером штрихкод марки (150 символов)
// и возвращает структуру с типом, серией и номером марки.
Функция РазобратьНовуюМарку(ШтрихкодМарки) Экспорт
Результат = Новый Структура("Тип, Серия, Номер, Успешно", "", "", "", Ложь);
// Проверяем, что длина штрихкода соответствует новому формату
Если СтрДлина(ШтрихкодМарки) = 150 Тогда
Результат.Тип = Сред(ШтрихкодМарки, 1, 3);
// Извлекаем серию и номер. Начиная с 4-го символа берем 11 знаков:
// 3 символа серии + 8 символов номера = 11 символов.
СерияИНомер = Сред(ШтрихкодМарки, 4, 11);
Результат.Серия = Лев(СерияИНомер, 3);
Результат.Номер = Прав(СерияИНомер, 8);
Результат.Успешно = Истина;
КонецЕсли;
Возврат Результат;
КонецФункции
Этот код позволяет нам получить текстовые реквизиты марки для последующего поиска или отправки запросов.
Поскольку напрямую расшифровать алкокод из штрихкода невозможно, нам придется использовать окружение нашей учетной системы и механизмы ЕГАИС. Рассмотрим основные рабочие сценарии решения этой задачи.
При поштучном учете поставщик присылает вам ТТН ЕГАИС, в XML-файле которой содержится жесткая связка: конкретный код марки привязан к конкретной позиции номенклатуры поставщика. У этой позиции в классификаторе алкогольной продукции ЕГАИС обязательно прописан алкокод.
В типовых конфигурациях 1С (таких как «1С:Управление торговлей», «1С:Розница» или «1С:ERP») при загрузке и проверке входящей ТТН система автоматически записывает эту связь в специальный регистр сведений (например, РегистрСведений.НоменклатураЕГАИС или регистры штрихкодов упаковок). Таким образом, если вы уже приняли эту продукцию на баланс, вам достаточно сделать поисковый запрос к вашей локальной базе данных 1С, сопоставив считанный штрихкод с записями в регистре.
Если продукция числится у вас на балансе (на Регистре 1), но вы не знаете, какая именно марка привязана к какому алкокоду, вы можете воспользоваться функционалом Универсального Транспортного Модуля (УТМ). Для этого формируется специальный исходящий запрос QueryRestBCode (запрос остатков штрихкодов по Справке Б).
В ответ от ЕГАИС придет XML-документ ReplyRestBCode, содержащий список всех марок, которые числятся за этой партией (справкой). Так как сама справка однозначно связана со справочником алкогольной продукции в вашей системе, вы легко сопоставите полученный массив марок с искомым алкокодом.
Если перед вами стоит задача определить параметры единичной «неизвестной» бутылки, которой нет в вашей локальной базе 1С, можно прибегнуть к официальным порталам проверки:
В некоторых случаях кассовое ПО позволяет продавать товар без предварительного сопоставления марки в локальной базе. При сканировании DataMatrix на кассе штрихкод отправляется напрямую в УТМ для проверки в ЕГАИС. Облачный сервер ФСРАР сам находит сопоставленный алкокод, проверяет легальность продажи и возвращает результат. Данные о сопоставленном алкокоде затем можно извлечь из суточного отчета о розничных продажах или логов УТМ. Однако мы не рекомендуем использовать этот метод массово во избежание возникновения пересортицы на складе.
Рассмотрим пример того, как программист 1С может реализовать функцию поиска алкокода в локальной базе данных по считанному штрихкоду DataMatrix. Предположим, что данные о сопоставлении хранятся в регистре сведений ШтрихкодыУпаковокТоваров (структура регистра может незначительно отличаться в зависимости от вашей конфигурации).
Функция НайтиАлкокодПоМарке(ШтрихкодМарки) Экспорт
// Сначала проверим марку по структуре
ИнформацияОМарке = РазобратьНовуюМарку(ШтрихкодМарки);
Если Не ИнформацияОМарке.Успешно Тогда
ЗаписатьЛогСобытия("Неверный формат штрихкода ЕГАИС: " + ШтрихкодМарки);
Возврат "";
КонецЕсли;
// Формируем запрос к регистру сведений, где хранятся связи марок
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Штрихкоды.Номенклатура.Алкокод КАК Алкокод
|ИЗ
| РегистрСведений.ШтрихкодыУпаковокТоваров КАК Штрихкоды
|ГДЕ
| Штрихкоды.ЗначениеШтрихкода = &Штрихкод";
Запрос.УстановитьПараметр("Штрихкод", ШтрихкодМарки);
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
Возврат Выборка.Алкокод;
КонецЕсли;
// Если в лоб по штрихкоду не нашли, попробуем поискать по Серии и Номеру
ЗапросСерияНомер = Новый Запрос;
ЗапросСерияНомер.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| АкцизныеМарки.АлкогольнаяПродукция.Код КАК Алкокод
|ИЗ
| Справочник.ШтрихкодыУпаковокИТоваров КАК АкцизныеМарки
|ГДЕ
| АкцизныеМарки.Серия = &Серия
| И АкцизныеМарки.Номер = &Номер";
ЗапросСерияНомер.SetParam("Серия", ИнформацияОМарке.Серия);
ЗапросСерияНомер.SetParam("Номер", ИнформацияОМарке.Номер);
// (Примечание: имена параметров и полей справочников адаптируйте под вашу конфигурацию)
Возврат ""; // Возвращаем пустое значение, если соответствие не найдено
КонецФункции
Мы выяснили, что времена простого офлайн-декодирования алкокодов ушли в прошлое вместе со старым форматом марок PDF417. Современный помарочный учет ЕГАИС 3.0 базируется на онлайн-связях данных.
Для успешной работы вашей системы автоматизации в 1С придерживайтесь следующих правил:
Сред()).