Неправильное округление скидки в чеке

1. veyrence 16.12.11 21:11 Сейчас в теме
Помогите, пожалуйста, с округлением суммы строки документа "Чек ККМ" и суммы скидки. На POS-системе стоит Розница, редакция 1.0.4.1; фискальник Штрих-Мини-ФРК. В чеке при продаже товара (цена 66р) со скидкой 10%, сумма скидки округляется в большую сторону до 7р., сумма продажи в строке соответсвенно 59р. А по фискальнику сумма скидки и сумма продажи округляются в меньшую сторону, соответственно 6р. и 60р (именно такой вариант мне и нужен в чеке ккм - с округлением суммы скидки и суммы продажи в меньшую сторону до целого рубля). При закрытии чека сабж "Сумма всех типов оплат меньше суммы документа!". Однако если количество копеек в сумме скидки равно 50 или меньше, то скидка и сумма строки округляются нормально, проблема только со скидкой, в которой количество копеек 51 или больше. Вот некоторые модули:

1. Модуль объекта: Документ ЧекККМ

Процедура ПроверитьЗаполнениеТабличнойЧастиОплата(ТаблицаПоОплате, СтруктураШапкиДокумента, Отказ, Заголовок)

СуммаВсего = Товары.Итог("Сумма");
ОплаченоНал = ПолучитьСуммуНаличнойОплаты();
ОплаченоБезнал = ПолучитьСуммуБезналичнойОплаты();
ОплаченоВсего = Оплата.Итог("Сумма");

Если ОплаченоВсего < СуммаВсего Тогда
ОбщегоНазначения.СообщитьОбОшибке("Сумма всех типов оплат меньше суммы документа!", Отказ, Заголовок);
КонецЕсли;
...

2. Модуль объекта: ShtrihMFiscalPrinters_v2.epf (внешняя обработка фискальника)

Функция ПечататьСтроку(Объект, Наименование, Количество, Цена,
Скидка, Отдел, НДС) Экспорт
...
Наценка = ?(Скидка < 0, -Скидка, 0);
СуммаБС = Цена * Количество;
//НЪА
СуммаСК = СуммаБС - Ценообразование.ОкруглитьЦену(СуммаБС*(100-Скидка)/100,Перечисления.ПорядкиОкругления.Окр1,Истина);
//КЪА
СуммаНац = СуммаБС * Наценка / 100;
Если Наценка > 0 Тогда
Объект.Драйвер.Сумма1 = СуммаНац;
Объект.Драйвер.СтрокаДляПечати = Формат(Наценка, "ЧЦ=15; ЧДЦ=2") + "%";
Объект.Драйвер.Надбавка();
Если Объект.Драйвер.Результат <> 0 Тогда
Объект.ОписаниеОшибки = Объект.Драйвер.ОписаниеРезультата;
Объект.Драйвер.АннулироватьЧек();
Результат = мОшибкаНеизвестно;
Возврат Результат;
КонецЕсли;
КонецЕсли;

Если Скидка > 0 Тогда
Объект.Драйвер.Сумма1 = СуммаСК;
Объект.Драйвер.СтрокаДляПечати = Формат(Скидка, "ЧЦ=15; ЧДЦ=2") + "%";
Объект.Драйвер.Скидка();
Если Объект.Драйвер.Результат <> 0 Тогда
Объект.ОписаниеОшибки = Объект.Драйвер.ОписаниеРезультата;
Объект.Драйвер.АннулироватьЧек();
Результат = мОшибкаНеизвестно;
Возврат Результат;
КонецЕсли;
КонецЕсли;

Если Результат = мОшибкаНеизвестно Тогда
ПроверкаСостоянияЧековойЛенты(Объект);
КонецЕсли;

Возврат Результат;

КонецФункции // ПечататьСтроку()

3. Модуль объекта: Обработка ТОСервер

Функция ПечатьЧека(Идентификатор, НомерЧека, НомерСмены,
ОписаниеЧека, СуммаНал, СуммаБезнал, ПризнакВозврата) Экспорт
...
Для Каждого Позиция Из ОписаниеЧека Цикл

ЗначениеСкидки = Позиция.Количество * Позиция.Цена * Позиция.Скидка * 0.01;
//НЪА
СуммаСоСкидкой1С = Окр(Ценообразование.ОкруглитьЦену((Позиция.Количество * Позиция.Цена - ЗначениеСкидки),Перечисления.ПорядкиОкругления.Окр1,Истина), 2);
СуммаСоСкидкойФР = Окр(Ценообразование.ОкруглитьЦену((Позиция.Количество * Позиция.Цена - Окр(ЗначениеСкидки, 2)),Перечисления.ПорядкиОкругления.Окр1,Истина), 2);
//КЪА
Если СуммаСоСкидкой1С = СуммаСоСкидкойФР Тогда
Результат = Обработка.ПечататьСтроку(Объект,
Позиция.Наименование,
Позиция.Количество,
Позиция.Цена,
Позиция.Скидка,
Позиция.НомерСекции,
Позиция.СтавкаНДС);
Иначе
Результат = Обработка.ПечататьСтроку(Объект,
Позиция.Наименование,
1,
СуммаСоСкидкой1С,
0,
Позиция.НомерСекции,
Позиция.СтавкаНДС);
КонецЕсли;

4.1. Модуль объекта: Общий модуль ОбработкаТабличныхЧастей

Процедура РассчитатьСуммуТабЧасти(СтрокаТабличнойЧасти, ДокументОбъект, СпособРасчета = Неопределено) Экспорт

...
Сумма = СтрокаТабличнойЧасти.Цена * СтрокаТабличнойЧасти.Количество;
СуммаСкидки = 0;

Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("ПроцентАвтоматическихСкидок", МетаданныеДокумента, ИмяТабличнойЧасти) Тогда
СуммаСкидки = Сумма * СтрокаТабличнойЧасти.ПроцентАвтоматическихСкидок / 100;
КонецЕсли;

Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("ПроцентСкидкиНаценки", МетаданныеДокумента, ИмяТабличнойЧасти) Тогда
СуммаСкидки = СуммаСкидки + (Сумма * СтрокаТабличнойЧасти.ПроцентСкидкиНаценки / 100);
КонецЕсли;

СтрокаТабличнойЧасти.Сумма = Сумма - СуммаСкидки;

КонецПроцедуры // РассчитатьСуммуТабЧасти()

4.2. Модуль объекта: Общий модуль ОбработкаТабличныхЧастей

Процедура РассчитатьСкидкиПриПродаже(ДокументОбъект, ТабличнаяЧастьНоменклатуры,
СтруктураПараметров) Экспорт

...
Для Каждого СтрокаТЧ Из ТаблицаТоваров Цикл

Если СтрокаТЧ.СуммаБезСкидки <> 0 Тогда
СтруктураПоиска.Номенклатура = СтрокаТЧ.Номенклатура;

МассивСтрок = ТаблицаСкидок.НайтиСтроки(СтруктураПоиска);

СтруктураПоиска.Номенклатура = ПустаяНоменклатура;

МассивСтрокБезНоменклатуры = ТаблицаСкидок.НайтиСтроки(СтруктураПоиска);

Для Каждого СтрокаБезНоменклатуры Из МассивСтрокБезНоменклатуры Цикл
МассивСтрок.Добавить(СтрокаБезНоменклатуры);
КонецЦикла;

МаксСуммаСкидки = Неопределено;
ПодходящаяСкидка = Неопределено;
ПроцентСкидки = Неопределено;
ПодходящаяСкидкаНоменклатура = Неопределено;

Для Каждого СтрокаСкидок Из МассивСтрок Цикл

Если (СтрокаСкидок.НУсловие = УсловиеКолво И СтрокаСкидок.НЗначениеУсловия < СтрокаТЧ.Количество
Или СтрокаСкидок.НУсловие <> УсловиеКолво) Тогда

Если СтрокаСкидок.НПроцентСкидкиНаценки <> Null Тогда
СуммаСкидки = СтрокаТЧ.СуммаБезСкидки * СтрокаСкидок.НПроцентСкидкиНаценки / 100;
Ограничение = СтрокаСкидок.НОграничениеСкидкиНаценки * СтрокаТЧ.Количество;

// Проверим ограничение скидки.
Если (Ограничение > 0 И СуммаСкидки > Ограничение)
Или (Ограничение < 0 И СуммаСкидки < Ограничение) Тогда
СуммаСкидки = Ограничение;
КонецЕсли;

Если МаксСуммаСкидки = Неопределено
Или (МаксСуммаСкидки < 0 И МаксСуммаСкидки > СуммаСкидки)
Или (МаксСуммаСкидки > 0 И МаксСуммаСкидки < СуммаСкидки) Тогда

МаксСуммаСкидки = СуммаСкидки;
ПодходящаяСкидка = СтрокаСкидок;
ПроцентСкидки = Окр((СуммаСкидки / СтрокаТЧ.СуммаБезСкидки) * 100, 2);
ПодходящаяСкидкаНоменклатура = Истина;

КонецЕсли;

КонецЕсли;

КонецЕсли;

КонецЦикла;

Если МаксСуммаСкидки <> Неопределено Тогда

СтрокаТЧ.ПроцентАвтоматическихСкидок = ПроцентСкидки;
СтрокаТЧ.Сумма = Окр(СтрокаТЧ.СуммаБезСкидки / СтрокаТЧ.Количество * (1 - (СтрокаТЧ.ПроцентСкидкиНаценки) / 100), 2) * СтрокаТЧ.Количество - МаксСуммаСкидки;
СтрокаТЧ.УсловиеАвтоматическойСкидки = ПодходящаяСкидка.НУсловие;
СтрокаТЧ.ЗначениеУсловияАвтоматическойСкидки = ПодходящаяСкидка.НЗначениеУсловия;

КонецЕсли;

КонецЕсли;

КонецЦикла;

Для Каждого СтрокаТЧ ИЗ ТаблицаТоваров Цикл

СтрокаТЧ.Сумма = СтрокаТЧ.СуммаБезСкидки * (1 - (СтрокаТЧ.ПроцентАвтоматическихСкидок + СтрокаТЧ.ПроцентСкидкиНаценки) / 100);
...
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. FReIM 10 16.12.11 21:15 Сейчас в теме
Хм. Встречал похожую проблему. Суть крылась в несоответствии округления в 1с и в фискальном регистраторе. Округление с точностью 1, 0.1, 0.01 решал сию проблему через звонок в тех поддержку в фирму эти фискальные регистраторы обслуживающую.
3. veyrence 16.12.11 21:49 Сейчас в теме
Как раз в фискальнике меня устраивает округление любых копеек в меньшую сторону. а в чеке <=50коп округляется в меньшую сторону, >50 - в большую. очень нужно округление в чеке такое же как в фискальнике. кроме звонка в суппорт можно исправить в модуле округление?
4. ifarkhetdinov 17.12.11 03:34 Сейчас в теме
мне кажется скорее подойдет не окр(), а цел()


Цел (Int)
Синтаксис:

Цел(<Число>)
Параметры:

<Число> (обязательный)

Тип: Число.
Исходное число.
Возвращаемое значение:

Тип: Число.
Результат выделения целой части.
Описание:

Вычисляет целую часть переданного числа, полностью отсекая дробную часть.

Доступность:

Тонкий клиент, веб-клиент, сервер, толстый клиент, внешнее соединение.
Пример:

МожноКупить = Цел(Наличность/Цена);
veyrence; +1 Ответить
5. veyrence 17.12.11 12:04 Сейчас в теме
В обработке фискальника Окр, и все копейки округляются до целого значения в меньшую сторону. Проблема именно в несоответствии округления документа ЧекККМ и фискальника. Если поставить в модуле ОбработкаТабличныхЧастей Процедура РассчитатьСкидкиПриПродаже
...
СтрокаТЧ.Сумма = Окр(СтрокаТЧ.СуммаБезСкидки * (1 - (СтрокаТЧ.ПроцентАвтоматическихСкидок + СтрокаТЧ.ПроцентСкидкиНаценки) / 100)-0.5, 0);

то все равно округление >=50 коп - в большую сторону до рубля.

Как/где исправить округление всех значений дробной части документа ЧекККМ до целого значения в меньшую сторону?
6. ifarkhetdinov 17.12.11 15:09 Сейчас в теме
Общий модуль ОбработкаТабличныхЧастей


Процедура РассчитатьСуммуТабЧасти(СтрокаТабличнойЧасти, ДокументОбъект, СпособРасчета = Неопределено, ЦенаДокумента = 0, ЦенаДокументаСУчетомРучнойСкикди = Ложь) Экспорт

ИмяТабличнойЧасти = ОбщегоНазначения.ПолучитьИмяТабличнойЧастиПоСсылкеНаСтроку(СтрокаТабличнойЧасти);

МетаданныеДокумента = ДокументОбъект.Метаданные();

Если ЗначениеЗаполнено(ЦенаДокумента) Тогда
Сумма = ЦенаДокумента * СтрокаТабличнойЧасти.Количество;
Иначе
Сумма = СтрокаТабличнойЧасти.Цена * СтрокаТабличнойЧасти.Количество;
КонецЕсли;
СуммаСкидки = 0;

Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("ПроцентСкидкиНаценки", МетаданныеДокумента, ИмяТабличнойЧасти)
И (НЕ ЦенаДокументаСУчетомРучнойСкикди ИЛИ ЦенаДокумента = 0) Тогда

СуммаСкидки = Цел(СуммаСкидки + (Сумма * СтрокаТабличнойЧасти.ПроцентСкидкиНаценки / 100));

КонецЕсли;

СтрокаТабличнойЧасти.Сумма = Сумма - СуммаСкидки;

КонецПроцедуры // РассчитатьСуммуТабЧасти()
veyrence; +1 Ответить
7. nle 19.12.11 21:42 Сейчас в теме
Справочники-Магазин-Порядок округления суммы в пользу покупателя должно помочь.
dutlovva; Liris; +2 Ответить
8. пользователь 05.01.12 02:53
Сообщение было скрыто модератором.
...
9. veyrence 07.01.12 14:42 Сейчас в теме
Всем спасибо за помощь, проблема решилась функцией Цел (Int), правил Модуль объекта: Общий модуль ОбработкаТабличныхЧастей:

Процедура РассчитатьСкидкиПриПродаже(ДокументОбъект, ТабличнаяЧастьНоменклатуры,
СтруктураПараметров) Экспорт
...
Для Каждого СтрокаСкидок Из МассивСтрок Цикл

Если (СтрокаСкидок.НУсловие = УсловиеКолво И СтрокаСкидок.НЗначениеУсловия < СтрокаТЧ.Количество
Или СтрокаСкидок.НУсловие <> УсловиеКолво) Тогда

Если СтрокаСкидок.НПроцентСкидкиНаценки <> Null Тогда
СуммаСкидки = СтрокаТЧ.СуммаБезСкидки * СтрокаСкидок.НПроцентСкидкиНаценки / 100;
СуммаСкидки2 = Цел(СтрокаТЧ.СуммаБезСкидки * СтрокаСкидок.НПроцентСкидкиНаценки / 100);
Ограничение = СтрокаСкидок.НОграничениеСкидкиНаценки * СтрокаТЧ.Количество;

// Проверим ограничение скидки.
Если (Ограничение > 0 И СуммаСкидки > Ограничение)
Или (Ограничение < 0 И СуммаСкидки < Ограничение) Тогда
СуммаСкидки = Ограничение;
КонецЕсли;

Если МаксСуммаСкидки = Неопределено
Или (МаксСуммаСкидки < 0 И МаксСуммаСкидки > СуммаСкидки)
Или (МаксСуммаСкидки > 0 И МаксСуммаСкидки < СуммаСкидки) Тогда

МаксСуммаСкидки = СуммаСкидки2;
ПодходящаяСкидка = СтрокаСкидок;
ПроцентСкидки = Окр((СуммаСкидки / СтрокаТЧ.СуммаБезСкидки) * 100, 2);
ПодходящаяСкидкаНоменклатура = Истина;

КонецЕсли;

КонецЕсли;

КонецЕсли;

КонецЦикла;

Если МаксСуммаСкидки <> Неопределено Тогда

СтрокаТЧ.ПроцентАвтоматическихСкидок = ПроцентСкидки;
СтрокаТЧ.Сумма = Окр(СтрокаТЧ.СуммаБезСкидки / СтрокаТЧ.Количество * (1 - (СтрокаТЧ.ПроцентСкидкиНаценки) / 100), 2) * СтрокаТЧ.Количество - МаксСуммаСкидки;
СтрокаТЧ.УсловиеАвтоматическойСкидки = ПодходящаяСкидка.НУсловие;
СтрокаТЧ.ЗначениеУсловияАвтоматическойСкидки = ПодходящаяСкидка.НЗначениеУсловия;

КонецЕсли;

КонецЕсли;

КонецЦикла;

Для Каждого СтрокаТЧ ИЗ ТаблицаТоваров Цикл

//СтрокаТЧ.Сумма = СтрокаТЧ.СуммаБезСкидки * (1 - (СтрокаТЧ.ПроцентАвтоматическихСкидок + СтрокаТЧ.ПроцентСкидкиНаценки) / 100);
10. djyarilo 8 25.07.14 09:40 Сейчас в теме
Ребята я тоже столкнулся с такой проблемой Решение которое тут описано не помогло, тогда я полез в код формирования ЧЕКккм и нашел запрос по документу ЧЕКккм, в этом запросе 1сники процентСкидки пересчитывали, потом из него получали сумму и соответственно они были не равны. Если сделать в запросе процент скидки из документа, тогда ЧеККМ пробивается. Запрос находится в документе ЧекККМ. ТАм что то вроде ОшибкаТО()=обращение к процедуре и передает параметры.
Glebb_NSK; +1 Ответить
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот