Как решить проблему с округлением скидок и копеек в Штрих-М: Кассир на 1С 7.7 при работе по 54-ФЗ?

Программист 1С v7.7 Торговля и дистрибуция
← На главную

При переходе на требования закона 54-ФЗ и форматы фискальных данных (ФФД 1.05, 1.1 и 1.2) многие пользователи и администраторы кассовых узлов под управлением конфигурации «Штрих-М: Кассир» версий 1.х и 2.х на платформе 1С 7.7 столкнулись с систематическими сбоями при печати фискальных чеков со скидками. Кассовый аппарат либо блокирует операцию с ошибкой несовпадения итоговой суммы, либо выдает ошибку превышения скидки над суммой позиции.

В этой статье мы подробно разберем, почему возникает данная проблема, как устроена математика чека по новым требованиям ФФД, почему изменение параметров в таблицах фискального регистратора не всегда спасает ситуацию и какие существуют практические пути решения проблемы.

---

Причины возникновения копеечных расхождений в онлайн-кассах

Давайте проанализируем фундаментальные изменения в кассовом законодательстве, из-за которых старые алгоритмы расчета скидок перестали работать:

  1. Позиционный расчет скидки вместо итоговой скидки на чек. В старых версиях кассового ПО (до введения ФФД 1.05 или в формате ФФД 1.0 BETA) кассовый аппарат позволял передавать общую сумму скидки на весь чек. Внутренняя прошивка фискального регистратора самостоятельно распределяла эту сумму по строкам либо просто уменьшала итог чека. Начиная с формата ФФД 1.05, требования налоговой службы ужесточились: чек обязан содержать строго выверенные данные по каждой товарной позиции, где выполняется жесткое математическое правило: Количество × Цена = СтоимостьПозиции. Сумма всех строк позиций с учетом скидок обязана до копейки равняться итогу чека и сумме всех видов оплат.
  2. Математическая погрешность при распределении скидок. Когда применяется процентная скидка (например, 3% или 7%) или фиксированная сумма скидки распределяется на несколько позиций, возникают дробные доли копеек. Если управляющая программа округляет каждую строку по стандартным математическим правилам, итоговая сумма строк часто не совпадает с суммой чека на 1–2 копейки. Для фискального накопителя и онлайн-ККТ такое расхождение считается критической ошибкой, и чек отклоняется.
  3. Параметры Таблицы 17 в драйвере ККТ «Штрих-М». В драйвере фискальных регистраторов «Штрих-М» существует Таблица 17 («Настройки ККТ»), содержащая поле Режим исчисления скидок:
    • Значение 0: Скидка вычисляется аппаратно самим фискальным регистратором. Данный режим был допустим только в устаревших прошивках и формате ФФД 1.0 BETA.
    • Значение 2: Скидки рассчитываются исключительно на стороне верхнего программного обеспечения (управляющей кассовой программы). Для форматов ФФД 1.05, 1.1 и 1.2 использование значения 2 является обязательным требованием стандарта.
    Если принудительно переключить данный параметр в 0 на прошивках с ФФД 1.05+, касса вернет ошибку недопустимого режима работы или продолжит отвергать чеки с некорректно распределенными строками.

---

Специфика архитектуры «Штрих-М: Кассир 1.х / 2.х» на платформе 1С 7.7

Давайте выясним, почему проблему со скидками сложно исправить стандартными средствами конфигуратора 1С 7.7.

В линейках «Штрих-М: Кассир» версий 1.х и 2.х разработчики вынесли ключевые алгоритмы расчета чека, взаимодействия с оборудованием и вызова методов DrvFR.dll в закрытые скомпилированные библиотеки (компоненты PosEngine.dll, SMKassir.dll). В программном коде 1С 7.7 формируется только высокоуровневый список товаров, после чего управление передается во внешнюю компоненту, которая выполняет вызовы фискального регистратора по собственным зашитым алгоритмам.

Поскольку поддержка версий кассового ПО для 1С 7.7 производителем полностью прекращена, официальных обновлений с корректной математикой распределения копеек под ФФД 1.05/1.2 для этих конфигураций больше не выпускается.

---

Варианты решения проблемы и обходные пути

Рассмотрим все доступные на практике способы преодоления данной ошибки — от организационных настроек до модификации логики работы кассового узла.

Способ 1. Отказ от чековых скидок и перенос скидок на уровень номенклатуры

Самый быстрый и надежный способ избежать сбоев кассы без перепрограммирования закрытых библиотек — исключить возникновение дробных копеек при регистрации позиций:

  1. Запрет итоговых скидок на чек. В настройках кассовой программы отключим автоматические процентные скидки на весь документ и ручные скидки на итог.
  2. Использование фиксированных прайс-листов и дисконтных цен. Если покупателю предоставляется скидка (по дисконтной карте или акции), пересчитаем цену каждой конкретной позиции так, чтобы при умножении на количество получалась точная сумма в рублях и копейках без остаточных дробей.
  3. Округление цен номенклатуры. Настроим в учетной системе округление розничных цен до целых рублей (или до 10 копеек), чтобы при расчете типовых скидок (например, 5% или 10%) математический результат всегда представлял собой целое число копеек.

---

Способ 2. Корректировка алгоритма распределения скидок в доступном коде 1С

Если в используемой редакции конфигурации часть логики расчета скидок доступна в модулях документов или глобальном модуле до передачи данных во внешнюю DLL, применим алгоритм пропорционального распределения с остатком на позицию с максимальной стоимостью.

Разберем пример реализации такого алгоритма на встроенном языке 1С 7.7:


// Процедура корректного распределения скидки по позициям чека
Процедура РаспределитьСкидкуНаЧек(СуммаСкидкиВсего)
    Перем ВсегоСуммаБезСкидки, НакопленнаяСкидка, НомерСтрокиМакс, МаксСуммаСтроки;
    Перем КолвоСтрок, ТекСкидка, ТекСумма;
    
    ВсегоСуммаБезСкидки = 0;
    МаксСуммаСтроки = 0;
    НомерСтрокиМакс = 1;
    КолвоСтрок = КоличествоСтрок();
    
    // Шаг 1. Вычисляем общую сумму чека и находим позицию с максимальной суммой
    ВыбратьСтроки();
    Пока ПолучитьСтроку() = 1 Цикл
        ТекСумма = Окр(Количество * Цена, 2, 1);
        ВсегоСуммаБезСкидки = ВсегоСуммаБезСкидки + ТекСумма;
        Если ТекСумма > МаксСуммаСтроки Тогда
            МаксСуммаСтроки = ТекСумма;
            НомерСтрокиМакс = НомерСтроки;
        КонецЕсли;
    КонецЦикла;
    
    Если ВсегоСуммаБезСкидки = 0 Тогда
        Возврат;
    КонецЕсли;
    
    // Шаг 2. Пропорционально распределяем скидку по строкам чека
    НакопленнаяСкидка = 0;
    ВыбратьСтроки();
    Пока ПолучитьСтроку() = 1 Цикл
        ТекСумма = Окр(Количество * Цена, 2, 1);
        // Вычисляем скидку на строку с округлением до копеек
        ТекСкидка = Окр((ТекСумма / ВсегоСуммаБезСкидки) * СуммаСкидкиВсего, 2, 1);
        Скидка = ТекСкидка;
        Сумма = ТекСумма - ТекСкидка;
        НакопленнаяСкидка = НакопленнаяСкидка + ТекСкидка;
    КонецЦикла;
    
    // Шаг 3. Корректируем копеечную погрешность на строке с наибольшей стоимостью
    Если НакопленнаяСкидка <> СуммаСкидкиВсего Тогда
        Погрешность = СуммаСкидкиВсего - НакопленнаяСкидка;
        ПолучитьСтрокуПоНомеру(НомерСтрокиМакс);
        Скидка = Скидка + Погрешность;
        Сумма = Сумма - Погрешность;
    КонецЕсли;
КонецПроцедуры

Рассмотрим, как работает этот алгоритм:

  1. Мы подсчитываем сумму всех строк чека по базовым ценам.
  2. По каждой строке вычисляем долю скидки с округлением до 2 знаков после запятой (до копейки).
  3. Сравниваем сумму распределенных скидок с требуемой итоговой суммой скидки.
  4. Возникшую разницу в 1–2 копейки принудительно относим на строку с наибольшей стоимостью. Это гарантирует, что скидка не превысит стоимость самого товара, а итоговая сумма строк сойдется с точностью до копейки.

---

Способ 3. Использование промежуточного кассового сервера (драйвера-прокси)

Если изменить исходный код и поведение внутренних DLL невозможно, эффективным инженерным решением является использование промежуточных кассовых серверов (например, KKMServer или специализированных прокси-драйверов).

При таком подходе схема взаимодействия выглядит следующим образом:

  1. 1С 7.7 формирует фискальный чек и отправляет его по протоколу HTTP/JSON или через виртуальный COM-порт на кассовый сервер.
  2. Промежуточный сервер производит валидацию чека на соответствие требованиям ФФД:
    • Проверяет математику Количество × Цена = Сумма.
    • Если обнаружена неделимая копейка на штучном товаре, сервер автоматически разбивает строку чека на две подстроки (например, позиция «Кофе 2 шт. по 100 руб. со скидкой 1 копейка» преобразуется в «Кофе 1 шт. по 100.00 руб.» и «Кофе 1 шт. по 99.99 руб.»).
  3. Кассовый сервер отправляет идеально сбалансированный пакет команд в фискальный регистратор «Штрих-М» через штатный драйвер, исключая любые ошибки ФН.

---

Способ 4. Переход на современное кассовое программное обеспечение

Платформа 1С 7.7 и конфигурация «Штрих-М: Кассир 1.х / 2.х» разрабатывались задолго до появления онлайн-касс, обязательной маркировки «Честный Знак», ФФД 1.2 и разрешительного режима продаж. Поддержание старых решений в рабочем состоянии требует постоянных доработок и сопряжено с рисками блокировки кассы в торговой точке.

Рекомендуемым долгосрочным решением является перевод кассового узла на современные специализированные решения (например, «Штрих-М: Кассир 5.х», «1С:Рабочее место кассира» или Frontol). При этом учетная система на базе 1С 7.7 может оставаться в качестве бэк-офиса, обмениваясь с кассой стандартными файлами выгрузки/загрузки товаров и продаж.

← На главную