Маркировка табака. Формирование тега 1162 "код товара" для передачи в ККТ и ОФД

С 01.07.2024 стартует новый этап маркировки сигарет. Теперь в кассе обязательно надо будет считывать марку с пачек табака, если она там есть. Считывать и передавать в ОФД через тег 1162 в онлайн-кассе. А как сформировать данные этого тега? Не все так просто…

Марка на табак — это последовательность символов. Например "00000046186195Xp4k=xyAQDPtFEa". Это штрихкод марки.

А передать в тег 1162 нужно байтовый массив. Описано тут: https://xn--80ajghhoc2aj1c8b.xn--p1ai/upload/iblock/784/Algoritm_zapisi_tega_1162_tabachnoy_produktsii.pdf

Предлагаю свой вариант, как это сделать средствами 1С:

Функция ПолучитьКодДляПередачиТега1162(ШтрихкодМарки)

//В штрихкоде марки нас интересуют первые 14 символов  - GTIN и вторые 7  - серия

ГТИН   = Лев(ШтрихкодМарки,14);
Серия  = Сред(ШтрихкодМарки,15,7);

//GTIN преобразуем в число, получаем строку байтов (HEX на самом деле), добиваем до 6 байтов

Попытка
ГТИНЧислом  = Число(ГТИН);
ГТИНБайтами = "";
Пока ГТИНЧислом > 0 Цикл
ГТИНБайтами = Сред("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", ГТИНЧислом%16 + 1, 1) + ГТИНБайтами;
ГТИНЧислом = Цел(ГТИНЧислом/16) ;
КонецЦикла;
Исключение
Возврат "";
Конецпопытки;

Пока СтрДлина(ГТИНБайтами)<12 Цикл
ГТИНБайтами = "0"+ГТИНБайтами;
КонецЦикла;

//Серию преобразуем в байты посимвольно старым методом - через временный файл

ИмяФ = ПолучитьИмяВременногоФайла("txt");
Т = Новый ТекстовыйДокумент();
Т.УстановитьТекст(Серия);
Т.Записать(ИмяФ,КодировкаТекста.ANSI);
ДД = Новый ДвоичныеДанные(ИмяФ);
СерияБайтами = Строка(ДД);
СерияБайтами = СтрЗаменить(СерияБайтами," ","");
УдалитьФайлы(ИмяФ);

//Формируем код товара для передачи. 0005 это код типа маркрировки - "табак".

мбКодТовара    = "0005"+ГТИНБайтами+СерияБайтами;
ВрКодТовара    = мбКодТовара;


МассивБайт  = "";

Пока СтрДлина(мбКодТовара)>0 Цикл

МассивБайт = МассивБайт+" "+Лев(мбКодТовара,2);
мбКодТовара = Сред(мбКодТовара,3);

КонецЦикла;


//Все!!! Вот эту строку с "массивом байт" можно передавать в тег 1162 в ККТ
Возврат СокрЛП(МассивБайт);

    
 Но если интересно, покажу дальше, как сделать из строки двоичные данные, а из них BASE64

 Ведь именно это мы увидим в личном кабинете ОФД….   

мбКодТовара = ВрКодТовара;

//Получаем из строки байтов двоичные данные

Попытка
ТипhexBinary    = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "hexBinary");
ДвоичныеДанные      = ФабрикаXDTO.Создать(ТипhexBinary,мбКодТовара);
Исключение
Возврат "";
КонецПопытки;

//Кодируем их в BASE64

Попытка
СтрКод = Base64Строка(ДвоичныеДанные.Значение);
Исключение
Возврат "";
КонецПопытки;

Возврат СтрКод;

КонецФункции

 

31 Comments

  1. philya

    BASE64 на последнем шаге не всегда нужен. Меркурий 119Ф съедает реквизит без перекодировки и передает в ОФД.

    Reply
  2. succub1_5

    Атол — ДТО 10 — кодировать или нет?

    Reply
  3. kirlog

    Дто 10 кодирует сам. Он и в байты переводит сам. Не нужно кодировать отдельно. На форуме Атола есть примеры.

    Reply
  4. succub1_5

    (3)т.е. этого хватит?

    //Формируем коды в соответствии с документацией на драйвер.
    fptr.setParam(fptr.LIBFPTR_PARAM_NOMENCLATURE_TYPE, fptr.LIBFPTR_NT_TOBACCO);
    fptr.setParam(fptr.LIBFPTR_PARAM_GTIN, «04600266011725»);
    fptr.setParam(fptr.LIBFPTR_PARAM_SERIAL_NUMBER, «2095134»);
    fptr.utilFormNomenclature();
    nomenclatureCode = fptr.getParamByteArray(fptr.LIBFPTR_PARAM_TAG_VALUE);
    рез = fptr.setParam(1162, nomenclatureCode);

    *а духи тоже так?

    Reply
  5. kirlog

    Да. Я именно эту ветку на форуме Атола имел в виду. Судя по тому, что там в итоге отвечают, этого достаточно.

    Для духов, думаю, надо будет поменять вот этот параметр fptr.LIBFPTR_NT_TOBACCO. Остальная логика останется той же.

    Но по духам пока рано говорить что то конкретное До Ноября 2019г идет эксперимент.

    Скорее всего, все будет по аналогии с табаком.

    Reply
  6. plutonii

    а по обуви есть какие то наработки? информация?

    Reply
  7. kirlog

    Наработок пока нет.

    А информация некоторая есть.

    — Вот тут хорошо написано о сроках: https://kontur.ru/articles/5455

    — 1С в своих типовых программах начнет поддерживать маркировку обуви в Сентябре: http://v8.1c.ru/lawmonitor/lawchanges.jsp?lawSectionUuid=31711cc6-fa27-4d5e-aed9-65466ded7524

    Пока методологии маркировки остатков, например, нет. Самих марок на обуви мало. Рано говорить о разработке чего либо, пока нет полной ясности, что как должно быть. Как обычно, инфа появится в последний момент, как было уже с алкоголем и табаком. Видимо, нас ждет веселый Октябрь:)

    Reply
  8. pkMIXER

    Здравствуйте, коллеги, а есть у кого-нибудь опыт по передачи на фискальник данных о марке? Судя по всему в УТ 10.3.55.1 не доделали этот момент и на фискальный регистратор данные о марке не передаются…

    Reply
  9. kirlog

    Здравствуйте.

    Для ДТО 10 в посте (4) приведен пример.

    Для ДТО 8 вот пример:

    StreamFormat = Объект.Драйвер.StreamFormat;
    Объект.Драйвер.StreamFormat        = 5;
    Объект.Драйвер.AttrValue          = КодМаркиДляПередачи;
    Объект.Драйвер.AttrNumber  = 1162;
    Объект.Драйвер.WriteAttribute();
    Если Объект.Драйвер.ResultCode <> 0 Тогда
    
    ПолучитьОписаниеОшибки(Объект, Истина);
    
    Объект.Драйвер.StreamFormat = StreamFormat;
    
    Возврат мОшибкаНеизвестно;
    
    Иначе
    
    Объект.Драйвер.StreamFormat = StreamFormat;
    
    КонецЕсли;
    

    Показать

    Reply
  10. Vitaly

    Народ! Нужна помощь в передаче данных в тег 1162. Конфигурация 1С 7.7 самописная. Строку, как в примере, получаю. ДТО8.16.6 выдает ошибку:

    30.07.2019 20:42:28.437 0000000047 Driver.Set_AttrNumber 1162

    30.07.2019 20:42:28.437 0000000000 Driver.Set_AttrValue 00 05 00 00 02 C1 4C 3E 27 4B 3F 39 4E 4C 73

    30.07.2019 20:42:28.437 0000000000 Driver.WriteAttribute

    30.07.2019 20:42:28.437 0000000000 Non-driver exception caught. Class: EAbort; text: Operation aborted

    30.07.2019 20:42:28.437 0000000000 Ошибка! ResultCode = -199 ResultDescription = «Неизвестная ошибка (Operation aborted)» BadParam = 0 BadParamDescription = «Ошибок в параметрах нет»

    30.07.2019 20:42:28.437 0000000000 Driver.Set_Name 8084 Плей Блю-Рэй

    30.07.2019 20:42:28.437 0000000000 Driver.Set_Price 90

    30.07.2019 20:42:28.437 0000000000 Driver.Set_Quantity 1

    30.07.2019 20:42:28.437 0000000000 Driver.Set_Department 1

    30.07.2019 20:42:28.437 0000000000 Driver.Set_TaxTypeNumber 4

    30.07.2019 20:42:28.437 0000000000 Driver.Registration

    30.07.2019 20:42:28.437 0000000047 TCustomTechThread.SetResult -1:

    Reply
  11. kirlog

    (8) Смотрите мой 9-й пост.

    Reply
  12. kirlog

    (10) Вот это свойство передаете? StreamFormat = 5

    Reply
  13. Vitaly

    Да, StreamFormat = 5 передаю…

    Reply
  14. kirlog

    (13) фискальную строку формируете через BeginItem? Код свой можете привести?

    У меня работает без проблем вот так:

    ОбъектДрайвера.BeginItem();
    ОбъектДрайвера.ItemType=1;
    
    ОбъектДрайвера.StreamFormat        = 5;
    ОбъектДрайвера.AttrValue                = КодМаркиДляПередачи;
    ОбъектДрайвера.AttrNumber        = 1162;
    ОбъектДрайвера.WriteAttribute();
    
    ОбъектДрайвера.Name = Наименование;
    ОбъектДрайвера.Price = Цена;
    ОбъектДрайвера.Quantity = Количество;
    ОбъектДрайвера.Department = Отдел;
    ОбъектДрайвера.Summ = СуммаСоСкидкой;
    ОбъектДрайвера.TaxTypeNumber = НомерСтавкиНДС;
    
    ОбъектДрайвера.EndItem();

    Показать

    Reply
  15. pkMIXER

    Спасибо большое, мне непонятно было что за переменная в 4 посте, если честно)

    Еще вопрос такой, уже много пачек содержат мрц(цену) в себе, перепрошитый элвес-м(древний автономный франкенштейн) умеет ее читать, где нибудь есть документация по поводу того, как из сосканированного кода достать цифру цены??

    (12)

    Reply
  16. kirlog

    (15)

    Вы о переменной КодМаркиДляПередачи? Смотрите тогда исходный пост публикации. Там как раз описано, как ее получать.

    Цену МРЦ передавать в тег 1162 не надо.

    Структура марки табака, 29 знаков:

    14 знаков. Код товара — GTIN. У меня показано как получать.

    7 знаков. Серия. Также показано.

    4 знака. МРЦ. Она закодирована тут аж в 80-чной системе счисления.

    4 знака. Контроль.

    Алгоритм кодирования МРЦ основан на переводе МРЦ в копейках в 80-чную систему счисления, используя следующий алфавит: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567­89!»%&’*+-./_,:;=<>?

    Могу написать код расшифровки МРЦ, если нужно.

    Reply
  17. Vitaly

    Спасибо все заработало!

    Reply
  18. pkMIXER

    (16) пожалуйста, если вас не сильно затруднит, был бы очень признателен!

    И ещё, подскажите, откуда вы берете информацию по поводу 80-тичной системы и количества знаков на каждый «блок»?

    Reply
  19. pkMIXER

    (16)

    Посмею немного опередить вас. Проверено на сигаретах всех основных производителей (филип морис, бат, JTI), код, там где он вшит верно, а не в тестовом режиме, корректно переводится в МРЦ, указанное на пачке. По упаковкам метод. данных не имею к сожалению пока, жду ответа на прошлое сообщение)

    Код для дешифровки МРЦ:

    АлфавитМРЦ = «ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!»»%&’*+-./_,:;=<>?»;
    ШКМрц = Сред(ШтрихкодМарки,22,4);
    
    Шаг = 3;
    ЦенаКоп = 0;
    Пока СтрДлина(ШКМрц)>0 Цикл
    Цифра = Лев(ШКМрц,1);
    ЦенаКоп = ЦенаКоп + (Найти(АлфавитМРЦ,Цифра)-1)*Pow(80,Шаг);
    Шаг = Шаг — 1;
    ШКМрц = Сред(ШКМрц,2);
    КонецЦикла;
    Если ЦенаКоп > 500000 Тогда
    //Убираем возможность нереальной цены > 5000 руб за пачкублок, таких сигарет пока не существует.
    Сообщить(«Цена закодирована в тестовом режиме и неверна»);
    Иначе
    Сообщить (ЦенаКоп/100);
    КонецЕсли;
    

    Показать

    Reply
  20. kirlog

    (19)

    По маркировке упаковок у меня инфы пока нет, к сожалению.

    Reply
  21. pkMIXER

    В последней версии УТ 10.3.55.2 вышел новый драйвер, который взаимодействует по ХМЛ с чеками, при передаче штрихкола ругается на то что ШК не 13-ти значный, я насколько понял он хочет получить бейс64 без ШК только серия, никто не в курсе?

    Reply
  22. karpik666

    (21) компонента ждет уже разобранный штрихкод, 3 поля gtin, серия и тип маркировки.

    Reply
  23. pkMIXER

    Простите, если туплю, но не могу понять что нужно в то поле отдавать, где просит 13 значный код?

    Reply
  24. kirlog

    Видимо, gtin, добитый нулями слева до 13 знаков.

    Reply
  25. pkMIXER

    (24) К сожалению не ГТИН он просит, а именно серийный номер, тот реквизит куда встаёт 2 группа кодировки, т.е. либо base либо бинарный код… Только почему он просит 13 символов непонятно.

    Reply
  26. pkMIXER

    (25) Забыл написать, что удалось определить причину, драйвер запрашивал 13 символов, потому что неверно передавался параметр типа маркировки, вместо нужного кода проставлялась строка названия типа, при замене на код все встает на свои места и код принимается тот что нужно.

    Reply
  27. kravec2001

    Вопрос по маркировки обуви:

    MarkingType – равно 5408 для обуви

    2. GTIN – равно 14-ти знаком после первых символов 01

    3. SerialNumber – 13 символов после значения 21 (т.е. начиная с 19)

    4. Далее передаём ККМ команду FNSendItemCodeData()

    а если в чеке несколько позиций с обувью как заполнять эти кода при этом они же разные на каждый товар?

    Reply
  28. succub1_5

    (27)так для каждой позиции же передается.

    Reply
  29. succub1_5

    а кстати, QR код если передать не разбирая на GTIN и SerialNumber — в 1162 тег, пишут что ДТО 10 и выше само перобразует, или из GTIN и SerialNumber формирует?

    просто не видел еще — что на выходе?

    QR = (01)00000046210654(21)ADgopSq(91)12(92)1234v67i

    GTIN = 00000046210654

    SerialNumber = ADgopSq (?)

    fptr.setParam(fptr.LIBFPTR_PARAM_NOMENCLATURE_TYPE, fptr.LIBFPTR_NT_TOBACCO);
    fptr.setParam(fptr.LIBFPTR_PARAM_GTIN, «00000046210654»);
    fptr.setParam(fptr.LIBFPTR_PARAM_SERIAL_NUMBER, «ADgopSq»);
    fptr.utilFormNomenclature();
    nomenclatureCode = fptr.getParamByteArray(fptr.LIBFPTR_PARAM_TAG_VALUE);
    рез = fptr.setParam(1162, nomenclatureCode);
    

    или сразу можно:

    рез = fptr.setParam(1162, «(01)00000046210654(21)ADgopSq(91)12(92)1234v67i»);
    

    и для духов вместо fptr.LIBFPTR_NT_TOBACCO что надо указать?

    Reply
  30. grafit

    Чек на сигареты! Корректный или нет?

    Сформировано на ККТ Атол.

    ККТ в режиме продажи подакцизного товара.

    ПО Розница 1.0.

    Драйвер Атол 10.6

    Reply
  31. grafit

    Чек ушел, ОФД принял.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *