Когда округление мешает пробитию чека
В современных фискальных регистраторах должно строго соблюдаться правило: Количество * Цена = Сумма.
Иногда, в процессе применения скидок, это правило нарушается.
Некоторые чеки не пробивались с ошибкой неправильной суммы:
При печати чека произошла ошибка.
Чек не напечатан на фискальном устройстве.
Дополнительное описание:
При выполнении операции произошла ошибка: Неверная цена (сумма)
Я начал разбираться и выявил среди отложенных чеков такие.
Использовал запрос по отложенным без резервирования чекам:
ВЫБРАТЬ
Т.Ссылка КАК Ссылка,
//Т.Номенклатура КАК Номенклатура,
Т.Количество КАК Количество,
Т.Цена КАК Цена,
Т.Сумма КАК Сумма,
Т.Количество * Т.Цена КАК СуммаПоПроизведению,
Сумма / Т.Количество КАК РасчетнаяЦена,
Т.СуммаАвтоматическойСкидки КАК СуммаАвтоматическойСкидки,
Т.СуммаРучнойСкидки КАК СуммаРучнойСкидки,
Т.Ссылка.Статус КАК Статус
ИЗ
Документ.ЧекККМ.Товары КАК Т
ГДЕ
Т.Ссылка.Статус = &Статус
И Т.Количество * Т.Цена <> Т.Сумма
Здесь в 1С устроено так, что Цена — это цена без скидки, Сумма — это сумма со скидкой.
Получил вот такой результат, где видно, что один из товаров в чеке дает неправильную цену, которая не может округлиться до двух знаков (339,983…):
Как видно из отладки, «глючит» именно типовой функционал, выдавая скидку 170.14:
Чтобы исправить ситуацию, нужно взять скидку, разделить на количество, округлить полученную цену до двух разрядов и умножить цену обратно на количество. Таким образом, скидка будет гарантированно делиться на количество с точностью до двух разрядов.
В нашем примере: 170.14 : 17 = 10,00823… → получаем цену 10,01 → 10,01 * 17 = 170,17
Причем поправлять надо в двух местах, общую функцию расчета ручной скидки разработчики УТ не написали. Расширяем модуль ОбработкаТабличнойЧастиКлиентСервер:
&ИзменениеИКонтроль("ПересчитатьСуммуСУчетомРучнойСкидкиВСтрокеТЧ") Процедура дор_ПересчитатьСуммуСУчетомРучнойСкидкиВСтрокеТЧ(ТекущаяСтрока, СтруктураДействий, КэшированныеЗначения) СтруктураПараметровДействия = Неопределено; Если СтруктураДействий.Свойство("ПересчитатьСуммуСУчетомРучнойСкидки", СтруктураПараметровДействия) Тогда Очищать = Неопределено; ПересчитыватьСуммуРучнойСкидки = Неопределено; ИмяКоличества = Неопределено; Если СтруктураПараметровДействия <> Неопределено Тогда СтруктураПараметровДействия.Свойство("Очищать", Очищать); СтруктураПараметровДействия.Свойство("ПересчитыватьСуммуРучнойСкидки", ПересчитыватьСуммуРучнойСкидки); СтруктураПараметровДействия.Свойство("ИмяКоличества", ИмяКоличества); Если НЕ ЗначениеЗаполнено(ИмяКоличества) Тогда ИмяКоличества = "КоличествоУпаковок"; КонецЕсли; Если Очищать = Истина Тогда ТекущаяСтрока.СуммаРучнойСкидки = 0; ТекущаяСтрока.ПроцентРучнойСкидки = 0; КонецЕсли; КонецЕсли; Если ПересчитыватьСуммуРучнойСкидки = Ложь Тогда Иначе ТекущаяСтрока.СуммаРучнойСкидки = Окр(ТекущаяСтрока[ИмяКоличества] *ТекущаяСтрока.Цена * ТекущаяСтрока.ПроцентРучнойСкидки / 100, 2); КонецЕсли; #Вставка //Осипов 2022-10-01 важно крайне для того чтобы чек пробивался. Если ТекущаяСтрока.Количество <> 0 Тогда ТекущаяСтрока.СуммаРучнойСкидки = ОКР(ТекущаяСтрока.СуммаРучнойСкидки / ТекущаяСтрока.Количество, 2) * ТекущаяСтрока.Количество; КонецЕсли; #КонецВставки ТекущаяСтрока.Сумма = ТекущаяСтрока.Сумма - ТекущаяСтрока.СуммаРучнойСкидки; КонецЕсли; КонецПроцедуры &ИзменениеИКонтроль("ПересчитатьСуммуРучнойСкидкиВСтрокеТЧ") Процедура дор_ПересчитатьСуммуРучнойСкидкиВСтрокеТЧ(ТекущаяСтрока, СтруктураДействий, КэшированныеЗначения) ИмяКоличества = Неопределено; Если СтруктураДействий.Свойство("ПересчитатьСуммуРучнойСкидки", ИмяКоличества) Тогда Если НЕ ЗначениеЗаполнено(ИмяКоличества) Тогда ИмяКоличества = "КоличествоУпаковок"; КонецЕсли; ТекущаяСтрока.СуммаРучнойСкидки = Окр(ТекущаяСтрока[ИмяКоличества] *ТекущаяСтрока.Цена * ТекущаяСтрока.ПроцентРучнойСкидки / 100, 2); #Вставка //Осипов 2022-10-01 важно крайне для того чтобы чек пробивался. Если ТекущаяСтрока.Количество <> 0 Тогда ТекущаяСтрока.СуммаРучнойСкидки = ОКР(ТекущаяСтрока.СуммаРучнойСкидки / ТекущаяСтрока.Количество, 2) * ТекущаяСтрока.Количество; КонецЕсли; #КонецВставки КонецЕсли; КонецПроцедуры
Автоматические скидки не используются, поэтому корректность их работы не проверял.
Проверьте актуальные релизы, взяв количество 17, скидку 2.78% и цену 360.
Как вариант, можно запретить использовать дробные проценты. Потому что такая ситуация возникала у клиента только тогда, когда он использовал дробные проценты скидки. Если при этом количество было не очень красивым, как 17, то могли возникнуть проблемы.
Но и в таком случае, все же, вина на разработчиках УТ. Они должны были предусмотреть округление скидки под кратность количества.
Среда: 11.4.13.46. Объем: 1 час.
Свежие комментарии