Как правильно сформировать чек коррекции в 1С 7.7 с использованием драйверов АТОЛ и избежать ошибок с датой?

Программист 1С v7.7 Торговля и дистрибуция
← К списку

Мы с вами сталкиваемся с необходимостью формирования чеков коррекции в 1С 7.7, особенно когда речь идет о взаимодействии с современными драйверами фискальных регистраторов АТОЛ. Эта задача может быть сопряжена с определенными сложностями, но, как мы убедимся, у нее есть эффективные решения. Давайте вместе разберем, почему возникают трудности и как их преодолеть, чтобы ваши чеки коррекции формировались корректно и без ошибок.

Что такое чек коррекции и зачем он нужен?

Прежде чем мы углубимся в технические детали, давайте выясним, что представляет собой чек коррекции и в каких случаях он необходим. Чек коррекции используется, когда кассир допустил ошибку при расчетах, например, пробил неверную сумму, не применил онлайн-кассу из-за технического сбоя, или вовсе не зарегистрировал операцию. Его основная цель — привести в соответствие данные о выручке, переданные в налоговую службу, с фактическими данными. Обратите внимание на важные изменения: с 20 июля 2020 года (согласно ФЗ № 240) при формировании чека коррекции больше не требуется подавать в налоговую инспекцию объяснительную записку и акт о выявлении недостачи или излишков денежных средств; достаточно самого чека коррекции. Мы рекомендуем формировать чек коррекции в период между отчетами об открытии и закрытии смены. Не стоит откладывать его оформление, чтобы избежать возможных штрафов. Как правило, на каждый случай ошибочного расчета оформляется отдельный чек коррекции. Исключение составляют случаи массового сбоя ККТ, когда ФНС может допустить создание одного документа для всех операций. Давайте также рассмотрим различные типы чеков коррекции: это могут быть чеки прихода, расхода, возврата прихода и возврата расхода, в зависимости от характера корректируемой операции.

Обязательные реквизиты чека коррекции

Для того чтобы чек коррекции был признан действительным, он должен соответствовать требованиям 54-ФЗ и приказам ФНС о форматах фискальных документов. Помимо стандартных реквизитов фискального чека, он содержит специфические теги, которые мы обязательно должны заполнить:

  1. Тип коррекции: Мы указываем, была ли коррекция произведена самостоятельно или по предписанию налогового органа.
  2. Основание для коррекции: Это включает дату и время корректируемого расчета, а также номер предписания налоговых органов (если оно есть). Если точные сведения о дате корректируемого расчета отсутствуют, мы указываем дату из расчетного периода, в котором проведена коррекция.
  3. Кроме того, мы должны указать предмет расчета (наименование товара/услуги), количество, сумму, налог, способ расчета, итоговую сумму чека и тип оплаты.

Особенности работы с драйверами АТОЛ в 1С 7.7

Несмотря на то, что платформа 1С 7.7 считается устаревшей, мы можем успешно интегрировать ее с современными драйверами АТОЛ версии 10 (ДТО 10). Для этого часто используются внешние обработки обслуживания или специальные шаблоны. При работе с ДТО 10 в 1С 7.7 объект COM-драйвера обычно создается как СоздатьОбъект("AddIn.Fptr10"). Для корректного взаимодействия нам необходимо зарегистрировать файл addin_fptr10_x86.dll (который находится в папке установки драйвера АТОЛ) с помощью команды regsvr32. Очень важно отметить, что проблема с некорректной датой основания для коррекции (тег 1178), когда вместо указанной даты пробивается предыдущий день, действительно встречается с аппаратами АТОЛ. Это согласуется с решением, найденным нами на форуме, о котором мы поговорим подробнее ниже.

Разбираем проблему формирования чека коррекции в 1С 7.7 с драйверами АТОЛ

Основная сложность, с которой мы столкнулись, заключается в правильной передаче информации об основании для коррекции драйверу АТОЛ, чтобы он сформировал корректный массив байтов. В частности, речь идет о теге 1178, который отвечает за дату документа-основания. Мы выяснили, что при попытке сформировать массив байтов (или его строковое HEX-представление) для параметра correctionInfo с использованием метода getParamByteArray() или getParamStringHex() после установки всех необходимых параметров, результаты в 1С 7.7 и 1С 8 могут отличаться. Это приводило к тому, что сформированный в 1С 7.7 массив байтов оказывался недействительным для фискального регистратора, и чек коррекции не пробивался или пробивался с ошибками. Давайте проанализируем ситуацию подробнее. В 1С 8.x передача даты в метод setParam() для тега 1178 работала без проблем. Однако в 1С 7.7, если мы формировали дату как строку, драйвер мог интерпретировать ее некорректно, что приводило к ошибкам в итоговом массиве данных для чека коррекции. Мы рассмотрим несколько решений этой проблемы.

Решение 1: Корректная передача даты основания для коррекции (Тег 1178)

Ключевым моментом в решении проблемы с формированием чека коррекции оказалось правильное указание даты основания для коррекции (тег 1178). Мы обнаружили, что драйвер АТОЛ, работая через COM-объект в 1С 7.7, требовал специфического формата для даты. Ранее мы могли использовать такой подход, формируя дату как строку:


ДатаКоррекции = День + "." + Месяц + "." + Год + " 00:00:00";
FR.setParam(1178, ДатаКоррекции); // Некорректно

Такой подход приводил к тому, что строка correctionInfo, получаемая методом getParamStringHex(), была некорректной по длине и содержанию, что вызывало ошибки при попытке пробить чек. Правильный подход заключается в том, чтобы передавать в метод setParam(1178) не строковое представление даты, а непосредственно объект даты 1С. Давайте посмотрим на пример:


// Предполагаем, что у нас есть переменная ЧекОснование, содержащая дату документа
// Например, ЧекОснование.ДатаДок - это стандартный объект даты 1С 7.7
FR.setParam(1178, ЧекОснование.ДатаДок);

Или, если мы формируем дату из отдельных компонентов:


FR.setParam(1178, Дата(Год, Месяц, День));

Почему это работает? Мы полагаем, что COM-объект драйвера АТОЛ в 1С 7.7 лучше "понимает" и преобразует внутренний формат даты 1С в нужный ему бинарный вид, нежели пытается парсить строковое представление, которое может быть интерпретировано неоднозначно. Передача прямого объекта даты 1С обеспечивает корректное формирование тега 1178, что в свою очередь приводит к правильному формированию всего массива данных для чека коррекции.

Решение 2: Использование методов getParamStringHex() и setParamStrHex()

Если мы сталкиваемся с проблемами при работе с массивами байтов напрямую (например, если наш язык программирования, в данном случае 1С 7.7, не поддерживает прямое получение из драйвера параметра типа bytearray), драйвер АТОЛ предлагает обходной вариант. Мы можем запросить такой параметр через метод getParamStringHex(), который вернет строку с последовательностью байтов в шестнадцатеричном формате. Далее, эту строку можно записать во входной параметр любого метода через методы setParamStrHex() или setNonPrintableParamStrHex(), и она запишется в драйвер как bytearray. Разберем по шагам, как это реализовать:

  1. Подготовка параметров: Сначала мы устанавливаем все необходимые параметры для чека коррекции, включая корректную дату, как мы рассмотрели в Решении 1.
    
    FR.setParam(1177, "Служебная записка"); // Наименование основания для коррекции
    FR.setParam(1178, ЧекОснование.ДатаДок); // Дата документа основания для коррекции (объект Дата 1С)
    FR.setParam(1179, "117"); // Номер документа основания для коррекции
    
  2. Формирование TLV-структуры: Затем мы вызываем метод utilFormTlv(), который формирует внутреннюю TLV-структуру (Tag-Length-Value) из установленных параметров.
    
    FR.utilFormTlv(); // Основание для коррекции
    
  3. Получение HEX-строки: После этого мы получаем сформированную информацию об основании для коррекции в виде шестнадцатеричной строки.
    
    ИнфоКоррекции = FR.getParamStringHex(FR.LIBFPTR_PARAM_TAG_VALUE);
    
    Полученная строка ИнфоКоррекции будет содержать последовательность байтов, например: "99 04 11 00 91 AB E3 A6 A5 A1 AD A0 EF 20 A7 A0 AF A8 E1 AA A0 9A 04 04 00 00 54 70 68 9B 04 03 00 31 31 37".
  4. Передача HEX-строки: Если нам потребуется передать эту информацию куда-либо (например, если мы хотим использовать ее в другом месте или сохранить), мы можем использовать метод setParamStrHex(). Например, если мы хотим установить параметр 1174 (который может быть параметром correctionInfo) с нашей HEX-строкой:
    
    FR.setParamStrHex(1174, ИнфоКоррекции);
    
    На форуме был пример, когда такая строка, полученная в 1С 8, успешно использовалась в 1С 7.7, что подтверждает работоспособность этого механизма.

Решение 3: Использование объекта OLEExSup для работы с массивами байтов

В некоторых случаях, для более прямого взаимодействия с COM-объектами и их методами, которые возвращают или ожидают массивы байтов, мы можем использовать внешний объект OLEExSup. Этот объект является надстройкой для 1С 7.7, позволяющей более гибко работать с COM-объектами, в частности, вызывать методы, которые не поддерживаются напрямую стандартным механизмом OLE в 1С 7.7. Давайте разберем, как это можно применить:

  1. Создание объекта OLEExSup: Сначала мы создаем экземпляр объекта OLEExSup. Предполагается, что библиотека OLEExSup.dll зарегистрирована в системе.
    
    OLEExSup = СоздатьОбъект("OLEExSup");
    
  2. Получение массива байтов: Используя метод InvokeOLEMethod() объекта OLEExSup, мы можем вызвать метод getParamByteArray() драйвера фискального регистратора (в нашем примере FR) и получить результат в виде массива байтов.
    
    ИнфоКоррекцииМассив = OLEExSup.InvokeOLEMethod(FR, "getParamByteArray", FR.LIBFPTR_PARAM_TAG_VALUE);
    
    Здесь FR.LIBFPTR_PARAM_TAG_VALUE указывает, что мы хотим получить значение, связанное с тегом.
  3. Установка массива байтов: Аналогично, мы можем использовать InvokeOLEMethod() для вызова метода setParamByteArray() и передать ему полученный массив байтов для установки соответствующего параметра.
    
    OLEExSup.InvokeOLEMethod(FR, "setParamByteArray", 1174, ИнфоКоррекцииМассив);
    
    В этом примере 1174 — это код параметра, который мы хотим установить (например, параметр для correctionInfo), а ИнфоКоррекцииМассив — это массив байтов, который мы получили.

Этот подход позволяет нам работать с массивами байтов более "напрямую", минуя промежуточное преобразование в HEX-строку, что может быть предпочтительнее в некоторых сценариях.

Дополнительные рекомендации и методы драйвера

Помимо основного решения, мы также хотим обратить ваше внимание на несколько важных моментов и полезных методов драйвера: * Метод utilFormTlv(): Мы уже упоминали его, но хотим подчеркнуть его важность. После установки всех необходимых параметров для чека коррекции (теги 1177, 1178, 1179 и другие), обязательно вызовите метод FR.utilFormTlv(). Этот метод формирует внутреннюю TLV-структуру, которая затем будет использоваться для получения итогового массива байтов или HEX-строки для чека коррекции. * Получение статуса ККТ: Для получения текущего статуса ККТ, состояния смены, даты и времени, а также других параметров, мы можем использовать следующие методы драйвера:


FR.setParam(FR.LIBFPTR_PARAM_DATA_TYPE, FR.LIBFPTR_DT_STATUS);
FR.queryData();
// После этого можно получать различные параметры статуса
// Например, FR.getParamInt(FR.LIBFPTR_PARAM_SHIFT_STATE)

Это полезно для проверки готовности кассы к работе перед формированием чека. * Версия формата фискальных документов (ФФД): При работе с чеками коррекции важно учитывать версию ФФД, поддерживаемую вашей кассой. В ФФД 1.05, например, отсутствуют данные о предмете расчета, и доступны только два значения признака расчета: приход и расход. Для разных версий ФФД могут рекомендоваться различные подходы к корректировке и набору обязательных реквизитов. Всегда сверяйтесь с актуальной документацией по вашему драйверу и версии ФФД. Мы рассмотрели основные подходы к решению проблемы формирования чеков коррекции в 1С 7.7 с драйверами АТОЛ. Надеемся, что эти подробные объяснения и примеры кода помогут вам успешно реализовать необходимый функционал. Удачи в вашей работе!

← К списку