Каждый системный администратор и программист 1С, работающий в сфере розничной торговли, рано или поздно сталкивается с крайне неприятной ситуацией: кассир пробивает чек, фискальный регистратор (ККТ) успешно печатает бумажную ленту и отправляет данные в ОФД, но на экране компьютера возникает ошибка транзакции. В результате документ Чек ККМ в информационной базе остаётся непроведенным, с пустым статусом и без заполненных фискальных реквизитов (таких как номер чека и номер смены). При попытке закрыть смену кассир получает серьезное расхождение между данными Z-отчета и выручкой в программе.
В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем её глубокие технические и аппаратные причины, а также предложим несколько надежных вариантов решения — от настройки параметров торгового оборудования до доработки программного кода 1С.
Для того чтобы понять логику возникновения этой ошибки, рассмотрим пошагово, как именно программный комплекс взаимодействует с фискальным регистратором в момент оплаты:
Чек ККМ полученный номер смены, номер чека, установить статус «Пробит» и выполнить проведение документа по регистрам накопления (списание остатков товаров, фиксация выручки и т.д.).Если на последнем, пятом шаге происходит сбой (микросекундный обрыв связи, зависание СУБД, блокировка таблиц базы данных из-за фонового процесса), транзакция записи в 1С аварийно откатывается. В итоге физическая продажа на кассе уже совершена и зафиксирована в ФН, а в учетной системе документ остается «висеть» непроведенным.
Проанализируем основные факторы, вызывающие этот сбой:
Чек ККМ не может записаться за отведенное время и откатывается.Рассмотрим детально, как решить эту проблему на всех уровнях информационной системы.
Начнем с самого простого и действенного административного шага — регулировки времени ожидания ответа от ККТ. Нам необходимо увеличить таймаут, чтобы программа гарантированно дожидалась ответа от драйвера даже в случае медленной печати чека или задержек со стороны ККТ.
Кроме того, регулярно обновляйте драйвер ККТ. В старых версиях драйверов (например, Штрих-М серии 4.9) наблюдались внутренние ошибки работы памяти, из-за которых драйвер периодически возвращал пустые значения номера смены и номера чека в обработку обслуживания 1С.
Если вы используете распределенные информационные базы (РИБ) с файловой СУБД, параллельные процессы записи при обмене гарантированно будут вызывать конфликты транзакций с РМК. Чтобы устранить эту проблему, применим комплекс мер:
1Cv8.1CD, так как клиент-серверная архитектура блокирует только конкретные строки данных, позволяя кассиру беспрепятственно пробивать чеки параллельно с любыми фоновыми загрузками.Если полностью исключить аппаратные сбои или микросекундные зависания сети не удается, мы можем внести изменения в код конфигурации. Реализуем механизм защиты: если ККТ выдала ошибку при попытке закрыть чек, программа спросит кассира, напечатался ли чек физически. Если кассир отвечает «Да», программа запишет и проведет документ в 1С без повторной отправки команды на фискальный регистратор.
Рассмотрим, как реализовать этот алгоритм. В конфигурации «1С:Розница» (ред. 2.0 / 2.2) откроем модуль управляемой формы РМК и найдем процедуру создания и проведения чеков (например, метод СоздатьЧеки или ПробитьЧекВыполнитьЗавершение).
Найдем фрагмент кода, отвечающий за выполнение печати фискального чека:
Отказ = НЕ ПробитьЧекВыполнить(ОбъектЧекККМ, Ответ);
Модифицируем этот участок кода, добавив интерактивный диалог с пользователем в случае возникновения ошибки:
Отказ = НЕ ПробитьЧекВыполнить(ОбъектЧекККМ, Ответ);
Если Отказ Тогда
ТекстВопроса = "ВНИМАНИЕ!!! Возникла ошибка при пробитии чека на ККМ!
|Пожалуйста, проверьте бумажную ленту устройства.
|Вышел ли фискальный чек полностью и напечатана ли сумма?";
КодВозврата = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет, 0, КодВозвратаДиалога.Нет, "Проверка состояния ККТ");
Если КодВозврата = КодВозвратаДиалога.Да Тогда
// Кассир подтвердил, что чек физически напечатан.
// Принудительно сбрасываем признак ошибки ("Отказ"), позволяя 1С провести документ.
Отказ = Ложь;
// Попытаемся программно получить актуальные реквизиты из ФР, чтобы заполнить документ
Попытка
НомерЧекаККМ = "";
НомерСменыККМ = "";
// Здесь вызываются стандартные методы интеграционной библиотеки для чтения параметров ККТ
ПолучитьПараметрыПоследнейОперацииККМ(НомерЧекаККМ, НомерСменыККМ);
ОбъектЧекККМ.НомерЧекаККМ = НомерЧекаККМ;
ОбъектЧекККМ.НомерСменыККМ = НомерСменыККМ;
Исключение
// Если прочитать реквизиты не удалось, запишем хотя бы пустые, чтобы провести документ
ЗаписьЖурналаРегистрации("ККМ", УровеньЖурналаРегистрации.Предупреждение, , ,
"Не удалось прочитать номера чека/смены с ККТ: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЕсли;
Данная доработка полностью исключает ситуации, когда кассиры, испугавшись ошибки на экране, нажимают «Оплатить» повторно, из-за чего по фискальному накопителю ККТ регистрируются две продажи, а в 1С проводится только один документ.
Если сбои происходят хаотично и в логах драйвера регистрируется ошибка FFFFFFFFh (нет связи с устройством) или наблюдается кратковременное «зависание» кассового бокса на этапе оплаты картой, обратим внимание на аппаратное подключение периферии:
Если смена уже закрылась, а в базе остались непроведенные чеки с пустым статусом, которые привели к расхождению с Z-отчетом, необходимо выполнить ручную коррекцию данных.
В этом случае мы можем восстановить соответствие данных программным путем:
Чек ККМ.Статус в положение «Пробит».НомерЧекаККМ и НомерСменыККМ (данные возьмите из физической копии чека ККТ или из личного кабинета ОФД).Отчет о розничных продажах.Если смена закрыта, документ Чек ККМ изменить стандартным образом уже нельзя. Действуем по следующей схеме:
Отчет о розничных продажах.Отчет о розничных продажах.Применяя данные методики в комплексе, мы сможем полностью избавить розничную точку от регулярных расхождений между фактической выручкой фискального регистратора и учетными данными в системе 1С.