Класс для API АТОЛ «Драйвер ККТ версии 10»

Сканеры, кассы, ККТ и т.д.
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7735
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 26 раз
Поблагодарили: 73 раза

Класс для API АТОЛ «Драйвер ККТ версии 10»

Сообщение Игорь Столяров »

Привет всем !

Класс работы с драйвером ККТ АТОЛ 10 на основе JSON заданий.
(форк класса ADMIN'а 2019 г.)

Класс рабочий, в комплекте примеры использования. Любые замечания и дополнения - приветствуются. :)
В FTP разделе форума создана папка: /_Books/Atol.KKT со всей сопутствующей документацией.

ВНИМАНИЕ !
Для работы с КМ (кодами маркировки) через JSON задания требуется прошивка ККТ 5.12 и выше (двухлетней давности).
На старых прошивках будет ошибка: Объекту 0x05C1E828 присвоен код ошибки 148 [Ошибка программирования реквизита 1023]

atol2.png
Вложения
Admin-2019.zip
Оригинальный класс 2019 г.
(27.92 КБ) 332 скачивания
Atol-2024-11-29.zip
Версия от 29.11.2024 г.
(82.93 КБ) 64 скачивания
Последний раз редактировалось Игорь Столяров 09 Декабрь 2024, 14:05, всего редактировалось 35 раз.
Make Clarion Great Again ! 😎
Аватара пользователя
SergioRaguzini
Старожил
Сообщения: 244
Зарегистрирован: 08 Декабрь 2009, 19:16
Откуда: Краснодарский край
Благодарил (а): 10 раз

ATOL драйвер 10.x

Сообщение SergioRaguzini »

Привет Всем!
С Атолом для разливного пива в общепите все получилось - чеки стали уходить в ЧЗ. В моем случае (весь общепит - это оказывается "Хорека", я всегда думал что это только те, что при гостиницах и санаториях) я игнорировал при регистрации позиции теги 1260 (1262-1265). Оказалось что их необходимо добавлять обязательно. Если кто будет в дальнейшем интегрироваться, то это необходимо учесть.
А вот "упакованная вода" и "молочка" нормально уходят в ЧЗ и без заполнения таких тегов.
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4933
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 10 раз
Поблагодарили: 44 раза

ATOL драйвер 10.x

Сообщение finsoftrz »

Вопрос по составным реквизитам. Раньше не нужны были, а дока у атола голову сломаешь.
Чтобы сделать составной параметр, мы устанавливаем входящие в его состав, а затем делаем libfptr_util_form_tlv (SELF.SetParamTlv). Что-то типа такого:

Код: Выделить всё

               SELF.SetParamStr(1262, '030')               
               SELF.SetParamStr(1263, '21.11.2023')               
               SELF.SetParamStr(1264, '1944')               
               SELF.SetParamStr(1265, 'UUID=' & clip(SELF.QueueSale.CodeMarkReqId) & '&Time=' & SELF.QueueSale.CodeMarkReqShtamp)               
               SELF.SetParamTlv
               SELF.SetParamByteArray(1260,SELF.GetParamByteArray(LIBFPTR_PARAM_TAG_VALUE))
А как быть с предыдущими установленными параметрами? Вызов libfptr_util_form_tlv очищает все. Разместить в начале кода не вариант. В общем, что-то не понимаю. У Штриха все прозрачно сделано, есть начало и завершение формирования комплексного параметра.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7735
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 26 раз
Поблагодарили: 73 раза

ATOL драйвер 10.x

Сообщение Игорь Столяров »

ДД ! Здесь (как бы) ответ надо разделить на два ...

1. Комплексные реквизиты сделаны просто ... но для программирования на сях. :)
В Clarion - мы вот здесь рассматривали на примере тега 1174 (посмотрите по тегу код в справке):
viewtopic.php?t=4420&start=60

2. Я немного не понял из кода, что Вы задумали ... но если формируется отраслевой реквизит, то он особый
(тоже где-то разбирали и в справке по номеру тега есть)

Код: Выделить всё

           ! --- 1261 Отраслевой реквизит чека (для ФФД 1.2)
           Self.SetParamStr(1228, GHeader.Client.CliINN)   ! 1228 ИНН
           Self.SetParamStr(1262, GHeader.Notice.T1262)   ! 1262 Идентификатор ФОИВ        '016'
           Self.SetParamStr(1263, GHeader.Notice.T1263)   ! 1263 Дата документа основания  '24.09.2020'
           Self.SetParamStr(1264, GHeader.Notice.T1264)   ! 1264 Номер документа основания '8252'
           Self.SetParamStr(1265, GHeader.Notice.T1265)   ! 1265 Отраслевой реквизит       'Значение'
           If libfptr_write_sales_notice(Self.fptr) = LIBFPTR_OK.
Make Clarion Great Again ! 😎
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4933
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 10 раз
Поблагодарили: 44 раза

ATOL драйвер 10.x

Сообщение finsoftrz »

Во всяком случае, я их документацию плохо понимаю.
По ссылке ничего по 1174 нет.
Да, речь про отраслевой реквизит, который 1260. Он передается на каждую строку чека, в котором есть марка. Состоит из 4 вложенных - 1262, 1263, 1264, 1265.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4933
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 10 раз
Поблагодарили: 44 раза

ATOL драйвер 10.x

Сообщение finsoftrz »

Игорь, а у вас никто из клиентов табачными и разливным пивом не торгует? Изменения довольно приличные, а беспокоятся только крупные разработчики. Срок с 1 апреля, и это не шутка. :-) Я необходимые изменения внес, траблы только с отправкой составного отраслевого реквизита на ккм. Возможно, еще обновлять прошивки/драйвера придется.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7735
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 26 раз
Поблагодарили: 73 раза

ATOL драйвер 10.x

Сообщение Игорь Столяров »

finsoftrz писал(а): 28 Март 2024, 16:57 По ссылке ничего по 1174 нет
Здесь же ссылка идёт на страницу форума и наверно зависит от сортировки постов (у меня убывающая).
Что бы не заморачиваться с поиском я продублирую (в справке аналогичный код нашли ?):

Код: Выделить всё

     If InList(GHeader.CheckType, |                                 ! --- Добавление атрибутов по чеку коррекции
                                 LIBFPTR_RT_SELL_CORRECTION,        |   ! КОРРЕКЦИЯ ПРИХОДА
                                 LIBFPTR_RT_SELL_RETURN_CORRECTION, |   ! КОРРЕКЦИЯ ВОЗВРАТА ПРИХОДА
                                 LIBFPTR_RT_BUY_CORRECTION,         |   ! КОРРЕКЦИЯ РАСХОДА
                                 LIBFPTR_RT_BUY_RETURN_CORRECTION)      ! КОРРЕКЦИЯ ВОЗВРАТА РАСХОДА

        Self.SetParamStr(      1177, GHeader.Correction.Text)        ! Наименование основания для коррекции
        Self.SetParamDateTime( 1178, GHeader.Correction.DocDate, 0)  ! Дата документа основания для коррекции (время всегда 00:00:00)
        Self.SetParamStr(      1179, GHeader.Correction.DocNum)      ! Номер документа основания для коррекции
        Self.UtilFormTlv(Self.TlvBuffer)                             ! Запись комплексного реквизита в буфер

        Self.SetParamInt(      1173, GHeader.Correction.Vid)         ! Вид коррекции: 0 - самостоятельная операция / 1 - операция по предписанию
        Self.SetParamBiteArray(1174, Self.TlvBuffer.Str()  )         ! Запись комплексного реквизита из буфера Self.TlvBuffer
     else
        ! Запись тега 1256
     end 
Про отраслевой реквизит (ОР) - см. в предыдущем сообщении.
Там могут быть навороты в том, что ОР может передаваться как на чек, так и на строку чека.
И их может быть несколько - поэтому и особый порядок формирования (в справке пример).
Make Clarion Great Again ! 😎
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7735
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 26 раз
Поблагодарили: 73 раза

ATOL драйвер 10.x

Сообщение Игорь Столяров »

finsoftrz писал(а): 28 Март 2024, 17:11 Срок с 1 апреля, и это не шутка
Вроде бы пока никто не спрашивал ...
Я с ужасом смотрю на описываемые Вами навороты - потому что ведь тоже придётся когда-нибудь это делать. :(
Make Clarion Great Again ! 😎
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4933
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 10 раз
Поблагодарили: 44 раза

ATOL драйвер 10.x

Сообщение finsoftrz »

Давайте на примере.
Self.SetParamStr - устанавливает параметр
Self.UtilFormTlv - формирует комплексный параметр и очищает все значения, созданные Self.SetParamStr.
Теперь представьте, что перед Self.SetParamStr(1177, GHeader.Correction.Text) есть другие параметры, установленные Self.SetParamStr, и их очищать нельзя.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4933
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 10 раз
Поблагодарили: 44 раза

ATOL драйвер 10.x

Сообщение finsoftrz »

Игорь Столяров писал(а): 28 Март 2024, 18:19
finsoftrz писал(а): 28 Март 2024, 17:11 Срок с 1 апреля, и это не шутка
Вроде бы пока никто не спрашивал ...
Я с ужасом смотрю на описываемые Вами навороты - потому что ведь тоже придётся когда-нибудь это делать. :(
Самое смешное, у меня тоже никто не спрашивал. :-) Сегодня только одна девочка переслала, что им в рассылке от ЧЗ пришло. Я уже третий день сижу. Когда-нибудь это с 1.04, осталось 3 дня. Я не думаю, конечно, что штрафы посыпятся, многие, наверно, только в начале апреля об этом новшестве узнают.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7735
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 26 раз
Поблагодарили: 73 раза

ATOL драйвер 10.x

Сообщение Игорь Столяров »

finsoftrz писал(а): 28 Март 2024, 18:25 Теперь представьте, что перед Self.SetParamStr(1177, GHeader.Correction.Text) есть другие параметры
Сначала формируются и передаются комплексные реквизиты, а потом обычные.
Или как с оплатой - т.е. формируем обычные реквизиты и регистрируем строки, потом формируем и записываем
комплексный реквизит. Закрываем чек.
Make Clarion Great Again ! 😎
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4933
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 10 раз
Поблагодарили: 44 раза

ATOL драйвер 10.x

Сообщение finsoftrz »

Игорь Столяров писал(а): 28 Март 2024, 18:42
finsoftrz писал(а): 28 Март 2024, 18:25 Теперь представьте, что перед Self.SetParamStr(1177, GHeader.Correction.Text) есть другие параметры
Сначала формируются и передаются комплексные реквизиты, а потом обычные.
Или как с оплатой - т.е. формируем обычные реквизиты и регистрируем строки, потом формируем и записываем
комплексный реквизит. Закрываем чек.
Так не получается. Часть реквизитов в заголовке чека. И они очищаются тоже при формировании комплексного реквизита строки. Может, какая-то фиксация должна быть для заголовочных.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4933
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 10 раз
Поблагодарили: 44 раза

ATOL драйвер 10.x

Сообщение finsoftrz »

Точнее сказать, когда я поставил формирование комплексного реквизита строки в самое начало, ккм вернула ошибку, что пустой документ.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7735
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 26 раз
Поблагодарили: 73 раза

ATOL драйвер 10.x

Сообщение Игорь Столяров »

finsoftrz писал(а): 28 Март 2024, 18:46 Может, какая-то фиксация должна быть для заголовочных.
Странно. :( Пардон, но спрошу. После установки реквизитов шапки - Вы же открываете чек (как учил нас Admin) ?:

Код: Выделить всё

   If libfptr_open_receipt(Self.fptr) <> LIBFPTR_OK
       ...
Это и исть фиксация шапки, далее уже пошла тушка чека со всеми тяжкими марками и т.д. ...
Make Clarion Great Again ! 😎
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4933
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 10 раз
Поблагодарили: 44 раза

ATOL драйвер 10.x

Сообщение finsoftrz »

Да, так и есть, открываю.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
SergioRaguzini
Старожил
Сообщения: 244
Зарегистрирован: 08 Декабрь 2009, 19:16
Откуда: Краснодарский край
Благодарил (а): 10 раз

ATOL драйвер 10.x

Сообщение SergioRaguzini »

finsoftrz писал(а): 28 Март 2024, 18:50 Точнее сказать, когда я поставил формирование комплексного реквизита строки в самое начало, ккм вернула ошибку, что пустой документ.
Привет Всем!
Разбирался с "пивом в кегах" для Horecа в начале года (поднимал эту тему, но тогда тишина была), вот рабочий пример (все, как положено уходитв ЧЗ):
в секции данных сделал универсально (чтобы использовать для Атол и Штрих):

в Atol.inc добавил:

Код: Выделить всё

ATOL:Industry_Props	GROUP,TYPE	! отраслевой реквизит 		25/01/24
id_FedOrg		  STRING(3)		! идентификатор федерального органа исп.власти	
doc_Date		  STRING(10)		! дата документа основания (как строка)
doc_Num			  STRING(10)		! номер документа основания
value_InPr		  STRING(20)		! значение отраслевого реквизита
                  END
                  
и потом там же в очередь товаров:

Код: Выделить всё

! товар           
ATOL:Goods        QUEUE,TYPE
GoodsName           STRING(64)
Price               DECIMAL(20,2)
Qty                 DECIMAL(20,3)
MeasureUnit         BYTE			! код единицы измерения: штучный, весовой и т.п. для ФФД 1.2	18/09/22
...
Industry_Props	    GROUP(ATOL:Industry_Props) .	! отраслевой реквизит 		25/01/24
...
                 END
в Data кассовой процедуры:

Код: Выделить всё

константы для передачи "Отраслевого реквизита", в наст. момент это составной тег 1260:              25/01/24
beerKeg:id_FedOrg      EQUATE('030')              ! 1262 - идентификатор федерального органа исп.власти
beerKeg:doc_Date       EQUATE('26.03.2022')       ! 1263 - дата документа основания (передаю как строковая)
beerKeg:doc_Num        EQUATE('477')              ! 1264 - номер документа основания
beerKeg:value_InPr     EQUATE('mode=horeca')      ! 1265 - значение отраслевого реквизита
в подпрограмме передаче на кассу заполнил:

Код: Выделить всё

                          G.Industry_Props.id_FedOrg  = beerKeg:id_FedOrg
                          G.Industry_Props.doc_Date   = beerKeg:doc_Date
                          G.Industry_Props.doc_Num    = beerKeg:doc_Num
                          G.Industry_Props.value_InPr = beerKeg:value_InPr

после открытия чека:

Код: Выделить всё

! О Т К Р Ы Т Ь   чек:
  ....
  ELSE           ! чек успешно открыт

! Текст в заголовке:
    if CLIP(GHeader.AccountStr) <> '' then SELF.PrintText(GHeader.AccountStr, LIBFPTR_TW_WORDS) .


! Регистрация списка товара:

    LOOP Pos# = 1 TO RECORDS(QGoods)     ! сканировать очередь товарных позиций
!- . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . - . -!
      GET(QGoods, Pos#)                     ! считать запись очереди

....
      if QGoods.DataMatrix <> '' then DO Atol10:Test_Mark .   ! проверить КМ маркированного товара    31/03/23


! передать Отраслевой реквизит:                                               25/01/24
      if QGoods.Industry_Props.id_FedOrg <> ''
                                                          SELF.SetParamStr(1262, QGoods.Industry_Props.id_FedOrg)
           if QGoods.Industry_Props.doc_Date   <> '' then SELF.SetParamStr(1263, QGoods.Industry_Props.doc_Date)         .
           if QGoods.Industry_Props.doc_Num    <> '' then SELF.SetParamStr(1264, CLIP(QGoods.Industry_Props.doc_Num))    .
           if QGoods.Industry_Props.value_InPr <> '' then SELF.SetParamStr(1265, CLIP(QGoods.Industry_Props.value_InPr)) .
           SELF.ParamBuild
           SELF.SetParamBiteArray(1260, SELF.GetParamBiteArray(LIBFPTR_PARAM_TAG_VALUE))  ! запись комплексного атрибута
еще важный момент при проверке макри:

Код: Выделить всё

! Входные параметры для метода beginMarkingCodeValidation():

     SELF.SetParamBiteArray(LIBFPTR_PARAM_MARKING_CODE , CLIP(QGoods.DataMatrix))          ! код марки
     SELF.SetParamInt(LIBFPTR_PARAM_MARKING_CODE_TYPE  , LIBFPTR_MCT12_AUTO)               ! определить автоматически
     DO set:LIBFPTR_PARAM_MARKING_CODE_STATUS                                              ! установить тег планируемый статус КМ (тег 2003)


! при продаже разливного пива при оказании услуг общественного питания в ФР передаётся GTIN, а не марка и коды в виде GTIN
! не подлежат проверки через ИСМ, поэтому при проверке КМ через ИСМ для GTIN отключаем передачу данных на сервер ИСМ
! и если это такой случай, то перед вызовом метода beginMarkingCodeValidation 
! необходимо установить свойство LIBFPTR_PARAM_MARKING_NOT_SEND_TO_SERVER в значение TRUE               24/01/24

! дополнительные для некоторых типов:
     case QGoods.mark_Type
       of 18                       ! 18-пиво в кеге       25/01/24
            SELF.SetParamDouble(LIBFPTR_PARAM_QUANTITY, QGoods.Qty)                               ! количество товара (тег 1023)
            SELF.SetParamInt(LIBFPTR_PARAM_MEASUREMENT_UNIT, QGoods.MeasureUnit)                  ! соответствует тегу 2108
            SELF.SetParamBool(LIBFPTR_PARAM_MARKING_NOT_SEND_TO_SERVER, TRUE)
      end !case
Описал все пункты, все успешно работает
Ответить