Как правильно сворачивать чеки из ККМ-Offline в 1С:Торговля и Склад 7.7 при наличии скидок и возвратов?

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

При организации обмена с кассовым программным обеспечением в режиме ККМ-Offline (например, Frontol или АТОЛ РМК) обработка загрузки смены считывает отчет о продажах во временную таблицу значений, после чего выполняет агрегацию данных. Довольно часто разработчики сталкиваются с ситуацией, когда в течение смены произошел возврат товара, проданного ранее со скидкой (количество -1), а затем был продан такой же товар, но уже по полной цене (количество +1).

Если в алгоритме обработки предусмотрена свертка только по номенклатуре и базовой цене из справочника, итоговое количество по позиции превращается в ноль (-1 + 1 = 0). В результате строка удаляется или отсекается условием проверки количества, а разница в сумме (размер скидки) бесследно исчезает из учета. Разберем детально, почему это происходит и как правильно модернизировать алгоритм загрузки чеков в конфигурации «1С:Торговля и Склад 7.7».

Причина ошибки при стандартной свертке таблицы значений

Проанализируем механику работы метода Свернуть() в 1С 7.7. Типовая группировка по колонкам "Товар, Цена" предполагает, что цена позиции всегда однозначна. Однако при продаже со скидкой касса фиксирует:

  1. Базовую цену номенклатуры (по прайс-листу).
  2. Сумму скидки или итоговую фактическую сумму продажи.

Если возврат оформляется по чеку со скидкой, а повторная продажа идет по базовой цене, то при одинаковой базовой цене строки попадают в одну группу группировки. Количество суммируется и дает 0, а в колонке Сумма остается суммовая разница. Документ Отчет ККМ не может содержать строки с нулевым количеством и ненулевой суммой, поэтому данные теряются, вызывая расхождение между Z-отчетом кассы и учетной базой.

Способ 1. Свертка по расчетной фактической (эффективной) цене реализации

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

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


// Добавляем расчетную колонку в Таблицу Значений чеков
ТЗЧеков.НоваяКолонка("ФактическаяЦена", "Число", 15, 2);

ТЗЧеков.ВыбратьСтроки();
Пока ТЗЧеков.ПолучитьСтроку() = 1 Цикл
    Если ТЗЧеков.Количество <> 0 Тогда
        // Рассчитываем фактическую цену с учетом знака операции
        ТЗЧеков.ФактическаяЦена = Окр(Абс(ТЗЧеков.Сумма) / Абс(ТЗЧеков.Количество), 2);
    Иначе
        ТЗЧеков.ФактическаяЦена = 0;
    КонецЕсли;
КонецЦикла;

// Выполняем свертку по номенклатуре и фактической цене
ТЗЧеков.Свернуть("Номенклатура, ФактическаяЦена", "Количество, Сумма");

Посмотрим на результат выполнения этого алгоритма:

  1. Если товар был продан и возвращен по одной и той же цене (например, ошибочно пробитый чек или отмена), обе записи получат одинаковую фактическую цену и корректно схлопнутся в ноль.
  2. Если продажа и возврат происходили по разным ценам (с разным уровнем скидки), строки получат разные значения в колонке ФактическаяЦена, не будут объединены и попадут в документ отдельными записями.

Способ 2. Разделение потоков продаж и возвратов до этапа свертки (Рекомендуемый подход)

Выясним причину, почему смешивать продажи и возвраты в одной таблице не всегда правильно с точки зрения методологии учета 1С 7.7. Документ Отчет ККМ в конфигурации «Торговля и Склад 7.7» предназначен для списания проданного товара (движение расхода по регистру ПартииНаличие). Появление отрицательных строк в документе приводит к сторнированию расхода, что при партионном учете (FIFO/LIFO) может исказить себестоимость, если товар был продан в прошлые смены.

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

  1. Таблица продаж — строки с положительным количеством (Количество > 0).
  2. Таблица возвратов — строки возвратов и сторно (Количество < 0 или транзакции возврата).

Рассмотрим пример кода для раздельной обработки чеков:


// Создаем отдельные таблицы для продаж и возвратов
ТЗПродажи = СоздатьОбъект("ТаблицаЗначений");
ТЗВозвраты = СоздатьОбъект("ТаблицаЗначений");

ТЗЧеков.Выгрузить(ТЗПродажи);
ТЗЧеков.Выгрузить(ТЗВозвраты);

// Фильтруем продажи
ТЗПродажи.ВыбратьСтроки();
НомСтр = 1;
Пока НомСтр <= ТЗПродажи.КоличествоСтрок() Цикл
    ТЗПродажи.ПолучитьСтрокуПоНомеру(НомСтр);
    Если ТЗПродажи.Количество <= 0 Тогда
        ТЗПродажи.УдалитьСтроку(НомСтр);
    Иначе
        НомСтр = НомСтр + 1;
    КонецЕсли;
КонецЦикла;

// Фильтруем возвраты
ТЗВозвраты.ВыбратьСтроки();
НомСтр = 1;
Пока НомСтр <= ТЗВозвраты.КоличествоСтрок() Цикл
    ТЗВозвраты.ПолучитьСтрокуПоНомеру(НомСтр);
    Если ТЗВозвраты.Количество >= 0 Тогда
        ТЗВозвраты.УдалитьСтроку(НомСтр);
    Иначе
        // Делаем количество и сумму положительными для оформления документа возврата
        ТЗВозвраты.Количество = -ТЗВозвраты.Количество;
        ТЗВозвраты.Сумма = -ТЗВозвраты.Сумма;
        НомСтр = НомСтр + 1;
    КонецЕсли;
КонецЦикла;

// Выполняем раздельную свертку
ТЗПродажи.Свернуть("Номенклатура, Цена", "Количество, Сумма");
ТЗВозвраты.Свернуть("Номенклатура, Цена", "Количество, Сумма");

После разделения данных:

  1. Таблица ТЗПродажи загружается в документ Отчет ККМ (или документ Чек ККМ).
  2. Таблица ТЗВозвраты формирует документ Возврат ТМЦ от покупателя с признаком розничного возврата, что гарантирует правильное восстановление партий на складе и точность кассовой выручки.

Особенности разбора файлов обмена АТОЛ и Frontol

При доработке модуля загрузки обратим внимание на нюансы протоколов обмена АТОЛ:

  1. Учет чековых скидок: Скидка может начисляться не только на конкретную позицию, но и распределяться на весь чек пропорционально суммам строк. При чтении файла обмена обязательно берите конечное суммовое поле регистрации позиции с учетом всех распределенных скидок, а не умножайте базовую цену на количество.
  2. Коды транзакций: В отчетах Frontol и АТОЛ транзакция 11 обозначает продажу, транзакция 12 — сторно, а транзакция 14 — возврат. Корректнее анализировать не только знак числа в поле количества, но и сам код транзакции кассового аппарата.
← На главную