Переходим с Атол 2.5 (ДТО 8) на 5.0 (ДТО 10)

В процессе подключения кассы ККМ на новую точку у клиента столкнулся с проблемой — касса не обнаруживается драйвером торгового оборудования.

Предложил позвонить клиенту в поддержку организации, занимающейся у него настройкой касс. И тут выяснилось, что с 31 марта 2020 года Атол перестал поддерживать платформу 2.5:

Т.е. новых касс, которые работали бы на ДТО 8, уже было не купить. Пришлось клиенту переписывать свою нетиповую программу на поддержку ДТО 10.

Подключившись к компьютеру, я обнаружил, что там установлено 64-разрядное ДТО 10. Умудренный опытом, поставил на тестовый компьютер Атолл ДТО10 под 32-разряда.

Далее скачал обработку с инфостарта: «Работа с драйвером «Атол v.10» через COM Объект для 1С: 8.3«. Но она была написана под обычные формы.

Пришлось переписать на управляемые:

ДТО8 работал с COM-объектом AddIn.FprnM45, ДТО10 работает с AddIn.Fptr10:

COM-объект AddIn.Fptr10 регистрировать не надо, ДТО10 при установке его регистрирует в системе, поэтому и важно поставить 32-разрядную версию драйвера, чтобы объект нормально подключался из 32-разрядного приложения 1С.

Обработка прямо из коробки напечатала чеки продажи с оплатой наличными и безналом:

Клиент сразу подсказал, что пробивается ставка НДС, хотя он на УСН, т.е. без НДС. Поправил.

В итоге сделал возвраты на ту же сумму, что и продажи, чтобы занулить смену.

Также без проблем снялся Х-отчет и Z-отчет:

Я скопировал рабочую базу клиента на локальный удаленный компьютер, к которому клиент подключил ККМ.

Далее я открыл документация по драйверу и приступил к переписыванию использования драйвера Атолл в нетиповой конфигурации клиента.

Драйвер создавался через оператор Новый, пришлось переделать под COMОбъект:

Далее я везде для версии 10 прописываю свой код под ветку условия ЭтоДрайверАтол10:

Достаточно просто получилось снять X-отчет:

Объект.setParam(Объект.LIBFPTR_PARAM_REPORT_TYPE, Объект.LIBFPTR_RT_X);
Объект.report();
Ответ = Объект.checkDocumentClosed();
Если
Ответ <> 0 Тогда
   
ОШИБКА(Ответ, «Не удалось сформировать Х-отчет!»);
   
Рез = Ложь;
КонецЕсли;

Аналогичным путем сделал Z-отчет:

Объект.setParam(Объект.LIBFPTR_PARAM_REPORT_TYPE, Объект.LIBFPTR_RT_CLOSE_SHIFT);
Объект.report();
Ответ = Объект.checkDocumentClosed();
Если
Ответ <> 0 Тогда   // Наиболее вероятны две причины — нарушение обмена Драйвер-ККТ и нарушение обмена ККТ-ФН. В первом случае нужно проверить физическое состояние используемого канала обмена, во втором может помочь перезагрузка ККТ.
   
ОШИБКА(Ответ, «Не удалось сформировать Z-отчет!»);
   
Рез = Ложь;
КонецЕсли;

Чтобы сильно не менять код, пришлось вызовы методов драйвера вынести в процедуры, старые вызовы оставил на всякий случай закомментированными:

Повозился с оплатой и закрытием чеков. Как это делается, можно посмотреть в приложенной обработке.

Некоторые команды драйвера вынес в отдельные функции:

&НаКлиенте
Функция ДлинаСтрокиСимволов(Объект)
    Если
ЭтоДрайверАтол10() Тогда
        Возврат
32;
    Иначе
        Возврат
Объект.ДлинаСтрокиСимволов;
    КонецЕсли;
КонецФункции

Функция
УстановитьСтроку(Объект, Строка) Экспорт
    Если
ККМ.ЭтоДрайверАтол10() Тогда
       
Объект.setParam(Объект.LIBFPTR_PARAM_TEXT, Строка);
    Иначе
       
Объект.Строка = Строка;
    КонецЕсли;
КонецФункции

Функция
ПечатьКлише(Объект) Экспорт
    Если
ККМ.ЭтоДрайверАтол10() Тогда
       
Объект.printCliche();
        Возврат
0; //Все ок типа. Осипов
   
Иначе
        Возврат
Объект.ПечатьКлише()
    КонецЕсли;
КонецФункции

Функция
ПечатьПоля(Объект) Экспорт
    Если
ККМ.ЭтоДрайверАтол10() Тогда
       
Объект.printText();
        Возврат
0; //Все ок типа. Осипов
   
Иначе
        Возврат
Объект.ПечатьПоля()
    КонецЕсли;
КонецФункции

Не обошлось и без забавного, тут перепутал названия методов драйвера:

В итоге вместо не-фискальных строк в чек многократно печатался логотип:

Вот, наконец, получилось напечатать чек продажи из 1С:

Увы, касса никак не отдавала номер чека, он все время выдается нулевым:

НомерЧека = Объект.getParamInt(Объект.LIBFPTR_PARAM_RECEIPT_NUMBER);

Пришлось обращаться на мисту, где мне оперативно помогли, спасибо им. В итоге получился такой код:

Объект.setParam(Объект.LIBFPTR_PARAM_DATA_TYPE, Объект.LIBFPTR_DT_STATUS);
Объект.queryData();
Рез.НомерЧека = Объект.getParamInt(Объект.LIBFPTR_PARAM_RECEIPT_NUMBER);

Доработал также отправку чека на электронный адрес, если он введен для клиента.

Осталось доработать пробитие по кассе внесения и изъятия денег через ПКО/РКО:

Код для этого выглядит так:

//Внесение денег в кассу
Объект.setParam(Объект.LIBFPTR_PARAM_SUM, СуммаЧека);
Объект.cashIncome();
Ответ = Объект.checkDocumentClosed();
Если
Ответ <> 0 тогда
   
ОШИБКА(«-«, «Не удалось открыть смену»);ОтменаЧекаККМ(Объект);Возврат Рез;
КонецЕсли;

//Изъятие денег из кассы
Объект.setParam(Объект.LIBFPTR_PARAM_SUM, СуммаЧека);
Объект.cashOutcome();
Ответ = Объект.checkDocumentClosed();
Если
Ответ <> 0 тогда
   
ОШИБКА(«-«, «Не удалось открыть смену»);ОтменаЧекаККМ(Объект);Возврат Рез;
КонецЕсли;

В этой работе мне помог коллективный разум Мисты — подсказали с номером чека. А в конце Вселенная прикололась надо мной — перестала работать отладка, все точки останова становились серыми. Но основное я уже отладил, так что не помешало.

В конце я снял X отчет, не сразу понял, что обозначает 13. Вроде бы пробито на 15 (12 налом и 3 безналом). Потом сообразил, что 13 — это количество чеков.

В драйвере я закрыл продажи возвратами, чтобы обнулить итог. Для этого нажимаем Открыть чек, Регистрация, Регистрация итога чека, Оплата, Закрыть чек:

Регистрация налога не нажимал. Но и без него прошло.

В итоге смена полностью занулена:

Осталось проверить, как работает старый драйвер ДТО8, потому что я мог невольно внести ошибки. Учитывая, что у клиента было УРБД, обновил конфигурацию и выгрузил на одну точку. Там пробили и оказалось, что все, к счастью, работает.

Важно! После внедрения выявилась ошибка. После истечения 24 часов смены касса начала выдавать ошибку и не печатать чек, но 1С воспринимала ответ кассы, будто чек пробит. Оказывается, проверять ошибку нужно по другому — не через checkDocumentClosed, а через errorCode:

Ответ = Объект.errorCode();
Если
Ответ <> 0 тогда
   
ОШИБКА(«-«, «Не удалось пробить ПКО: » + Объект.ErrorDescription());ОтменаЧекаККМ(Объект);Возврат Рез;
КонецЕсли;

Это касается пробития чека продажи, возврата, внесения и изъятия денег и других операций:

Время факт: 6 час. Среда: самописная торговая программа.

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

комментария 2

  1. Илья:

    Отличная статья, но не описан метод скидки/надбавки на чек. Например общая сумма по чеку 50р, количество товара 150, цена после округления 0,33. Но 0,33*150 = 49.5 — в какой параметр забить пол рубля? чтобы и цена и количество и сумма были исходными.

Добавить комментарий для Илья Отменить ответ

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