В современных реалиях работы с контрольно-кассовой техникой (ККТ) по стандарту 54-ФЗ программисты часто сталкиваются с проблемой: как корректно отобразить в чеке скидку или оплату бонусами. Если раньше можно было просто вызвать метод Discount(), то современные форматы фискальных данных (ФФД 1.05 и выше) требуют передачи в кассу конечной цены товара уже с учетом всех уменьшений. В этой статье мы разберем, как реализовать этот механизм в самописной или типовой конфигурации 1С 8.2 или 8.3, избежав ошибок расхождения сумм.
Рассмотрим причину возникновения ошибки «Сумма всех типов оплаты меньше итога чека». Проблема заключается в том, что фискальный накопитель проверяет жесткое математическое правило: Цена × Количество = Сумма строки. Если вы пытаетесь передать исходную цену и отдельно сумму скидки через драйвер, ККТ может проигнорировать скидку для ОФД, или возникнет погрешность округления в несколько копеек, которую касса не пропустит.
Проанализируем ситуацию: налоговой важно видеть итоговую сумму реализации каждого товара. Поэтому правильный путь — это предварительный расчет цены со скидкой на стороне 1С и передача в параметр Price уже скорректированного значения.
Когда клиент оплачивает часть чека бонусами, нам необходимо распределить эту сумму между всеми товарами пропорционально их стоимости. Разберем по шагам, как это сделать, чтобы избежать «проблемы лишней копейки».
Посмотрим на пример кода, реализующий этот алгоритм:
// Пример распределения суммы бонусов по строкам ТЧ Товары
СуммаЧека = Товары.Итог("Сумма");
ОстатокБонусов = СуммаБонусовДляРаспределения;
ВсегоСтрок = Товары.Количество();
ТекущаяСтрока = 0;
Для Каждого Стр Из Товары Цикл
ТекущаяСтрока = ТекущаяСтрока + 1;
Если ТекущаяСтрока < ВсегоСтрок Тогда
// Рассчитываем долю скидки для текущей строки
СкидкаСтроки = Окр(Стр.Сумма * (СуммаБонусовДляРаспределения / СуммаЧека), 2);
ОстатокБонусов = ОстатокБонусов - СкидкаСтроки;
Иначе
// В последнюю строку записываем весь оставшийся «хвост»
СкидкаСтроки = ОстатокБонусов;
КонецЕсли;
// Вычисляем новую цену для передачи в ККТ
КонечнаяСуммаСтроки = Стр.Сумма - СкидкаСтроки;
ЦенаДляККТ = КонечнаяСуммаСтроки / Стр.Количество;
// Передача данных в драйвер Штрих-М
FR.Quantity = Стр.Количество;
FR.Price = ЦенаДляККТ;
FR.StringForPrinting = Стр.Номенклатура.Наименование;
FR.FNOperation();
КонецЦикла;
Если в вашем чеке присутствует весовой товар с дробным количеством (например, 1.345 кг), то при делении итоговой суммы на количество может получиться цена с большим числом знаков после запятой (более двух). Касса «Штрих-М» может не принять такую цену или самостоятельно округлить её, что снова приведет к ошибке итога чека.
Выясним, как с этим бороться. В таких случаях опытные разработчики рекомендуют разбивать одну позицию на две строки в чеке:
Поскольку в ОФД уходит цена уже за вычетом бонусов, клиент может не понять из чека, что он применил скидку. Чтобы сделать чек информативным и не нарушить закон, воспользуемся печатью текстовых строк. Проанализируем, как это добавить в код:
// После регистрации позиции можно добавить текстовую информацию
FR.StringForPrinting = "Скидка по бонусам: " + Строка(СкидкаСтроки) + " руб.";
FR.PrintString();
Метод PrintString() печатает обычный текст на чековой ленте. Это не влияет на фискальные данные, но повышает лояльность покупателя, так как он видит реальную выгоду.
Существует еще один способ отражения бонусов — использование типа оплаты «Встречное предоставление» (согласно ФФД). В этом случае цена товара в чеке остается полной, но в секции оплат указывается две суммы: например, «Наличные» и «Встречное предоставление» (бонусы).
Разберем реализацию через драйвер «Штрих-М»:
FNOperation() передаем полную цену товара без учета бонусов.FNCloseCheckEx() распределяем суммы по разным типам оплаты.
// Пример закрытия чека с комбинированной оплатой
FR.Summ1 = СуммаНаличные; // Тип оплаты 1 (Нал)
FR.Summ4 = СуммаБонусы; // Тип оплаты 4 (обычно Встречное предоставление в Штрих-М)
FR.FNCloseCheckEx();
Важное предупреждение: Прежде чем использовать «Встречное предоставление», обязательно проконсультируйтесь с бухгалтером. При таком способе выручка в отчетах может проходить по полной стоимости товара, что может повлиять на расчет налогов (особенно на УСН «Доходы»), в то время как прямая скидка в цене просто уменьшает налогооблагаемую базу.
Иногда ошибки возникают из-за внутренних настроек самого аппарата. Рекомендуется проверить через «Тест драйвера» следующие параметры:
FNDiscountOperation могут работать некорректно или не передавать данные в ОФД.Подводя итог, отметим: наиболее стабильный и универсальный метод — это самостоятельный расчет конечной цены в 1С с распределением «хвоста» копеек на последнюю позицию. Это гарантирует отсутствие ошибок в ККТ и полное соответствие требованиям налоговой службы.