Как устранить расхождение в копейках при передаче чека в ККМ в 1С?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При пробитии чеков на контрольно-кассовой технике (ККТ) разработчики и пользователи конфигураций 1С (в частности, 1С:Управление торговлей 10.3) часто сталкиваются с ошибкой форматно-логического контроля: сумма по строкам или итог документа не совпадает с суммой, которую рассчитывает сама онлайн-касса. Проанализируем природу этой ошибки, разберем ограничения протоколов фискализации и выясним, как правильно решить проблему.

В чем суть проблемы «правила 1 копейки»

Посмотрим на типовую ситуацию. Документ содержит весовой товар, где количество указано с точностью до тысячных долей (например, тонны), а расчет НДС настроен по схеме «сверху»:

  1. Количество товара составляет 26.4 тонны.
  2. Сумма документа с НДС равна 5279.96 руб.
  3. При попытке вычислить цену для фискализации получаем: 5279.96 / 26.4 = 199.884848... руб.
  4. После стандартного округления до двух знаков цена становится равной 199.88 руб.
  5. Касса при фискализации жестко перемножает цену на количество: 199.88 * 26.4 = 5276.83 руб.

В результате возникает расхождение в 3.13 руб. между итогом документа и суммой, вычисленной кассовым аппаратом. Согласно требованиям форматов фискальных документов (ФФД), реквизиты «цена за единицу» (тег 1079) и «стоимость предмета расчета» (тег 1043) ограничены двумя знаками после запятой (копейки), а «количество» (тег 1023) в большинстве ККТ — тремя знаками. Кроме того, драйверы ККТ запрещают передавать отрицательные позиции (например, сторнирующие строки услуг или корректировки), поэтому просто отправить разницу отдельной строкой невозможно.

Анализ попытки разбиения товара на две строки

Часто программисты пытаются решить эту задачу программным разбиением одной товарной позиции на две строки с ценами, отличающимися на 1 копейку. Рассмотрим предложенный на практике алгоритм перебора:


КолВо = 26.4;
СуммаДок = 5279.96;
Цена = Окр(СуммаДок / КолВо, 2);    
СуммаВыч = Окр(Цена * КолВо, 2);

Если (СуммаВыч = СуммаДок) или (КолВо <= 1) Тогда
    Сообщить("" + Цена + " * " + КолВо + " = " + СуммаВыч);
Иначе
    КолВоМинус = 0;
    Дельта = 1;
    ФлагВывести = Истина;
    Пока КолВоМинус >= 0 Цикл
        КолВоМинус = КолВо - Дельта;
        СуммаМинус = КолВоМинус * Цена;
        НовЦена = (СуммаДок - СуммаМинус) / Дельта;
        РазницаЦен = Макс(НовЦена - Цена, -(НовЦена - Цена));
        Если РазницаЦен = 0.01 Тогда
            Сообщить("" + Цена + " * " + КолВоМинус + " = " + СуммаМинус);
            Сообщить("" + НовЦена + " * " + Дельта + " = " + НовЦена * Дельта);
            ФлагВывести = Ложь;
            Прервать;
        Иначе
            Дельта = Дельта + 1;
        КонецЕсли;
    КонецЦикла;
    Если ФлагВывести Тогда 
        Сообщить("!! " + Цена + " * " + КолВо + " = " + СуммаВыч);
    КонецЕсли;
КонецЕсли;

Разберем по шагам, почему данный алгоритм приводит к ошибкам:

  1. Целочисленный шаг дельты: Приращение Дельта = Дельта + 1 отнимает от общего объема целые единицы. Для дробного количества (26.4 т) расчет КолВоМинус = КолВо - Дельта всегда оставляет дробную часть (25.4, 24.4 и т.д.), что делает математически невозможным подбор ровной копейки целыми шагами. Шаг должен быть согласован с минимальной дискретностью единицы (0.001), а не единицей.
  2. Недопустимость перебора: Задача разбиения на две цены (Цена1 и Цена2 = Цена1 + 0.01) решается аналитически через систему линейных уравнений за одно действие:
    
    Цена1 = ОкрВниз(СуммаДок / КолВо, 2);
    Цена2 = Цена1 + 0.01;
    КолВо2 = (СуммаДок - (Цена1 * КолВо)) / 0.01;
    КолВо1 = КолВо - КолВо2;
    
  3. Ограничение точности ККТ: При дробных значениях вычисленное КолВо2 почти всегда получает более трех знаков после запятой. Округление количества до допустимых кассой трех знаков снова разрушает баланс, и касса выдает ошибку несоответствия сумм.

Корректные способы устранения расхождений

Рассмотрим проверенные и методически верные способы решения проблемы округления при печати чеков:

  1. Переход на ценообразование «НДС в том числе»:
    Это наиболее правильный системный подход. Когда налог начисляется сверху на цену без НДС, при умножении на дробное количество появление долей копеек неизбежно. Если в виде цен или договоре включить флаг «Цены включают НДС», то базовая розничная цена сразу фиксируется с двумя знаками. В таком случае сумма позиции всегда строго равна Окр(Цена * Количество, 2), и касса принимает чек без единой ошибки.
  2. Округление чека в пользу покупателя:
    В розничной торговле законодательно разрешено производить округление итоговой суммы чека за счет предоставления скидки покупателю. Разница между суммой документа и суммой, рассчитанной по кассовым правилам, списывается на внереализационные расходы предприятия. Такой подход полностью исключает появление претензий со стороны налоговых органов и исключает сбои драйвера ККТ.
  3. Пересчет в меньшую единицу измерения для чека:
    Если изменить единицы измерения в чеке с тонн на килограммы (или граммы), дробная часть количества сократится или исчезнет вовсе (вместо 26.4 т передается 26400 кг). При этом важно контролировать, чтобы цена за единицу не опустилась ниже 0.01 руб., иначе касса отклонит операцию с нулевой ценой.
  4. Использование типовых механизмов БПО:
    В современных конфигурациях 1С логика распределения копеек и скидок реализована внутри Библиотеки подключаемого оборудования (БПО). Рекомендуется использовать штатные модули БПО, где алгоритмы форматно-логического контроля фискализации уже протестированы на совместимость со всеми актуальными прошивками касс.
← На главную