Как разделить виды оплаты и передавать скидки в 1С 7.7 под ФФД 1.05?

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

Переход со старого формата фискальных данных (ФФД 1.0) на ФФД 1.05 на платформе 1С 7.7 вызывает немало трудностей у разработчиков. Стандартные механизмы конфигураций вроде «Торговля и Склад 7.7» зачастую используют устаревшие структуры XML-пакетов, которые не поддерживают новые требования законодательства. В ФФД 1.05 появились новые обязательные реквизиты, изменились правила применения скидок, а также расширился перечень типов оплаты. Рассмотрим подробно, как решить эти задачи в 1С 7.7.

Разделение видов оплаты в XML-пакете под ФФД 1.05

В ФФД 1.0 для передачи оплат использовались в основном два тега: наличные (Cash) и безналичные/электронные (ElectronicPayment). Начиная с ФФД 1.05, состав видов оплаты расширился до пяти обязательных реквизитов. В XML-структуре пакета CheckPackage (в блоке Payments) теперь необходимо передавать следующие атрибуты:

Проанализируем пример кода на языке 1С 7.7, который формирует правильную структуру блока оплат в XML в зависимости от используемой версии ФФД:


Если ВерсияФФД > 0 Тогда // Атрибуты для ФФД 1.05 и выше
    ЗаписьXML.ЗаписатьАтрибут("Cash"             , XMLСтрока(СуммаНаличными));
    ЗаписьXML.ЗаписатьАтрибут("ElectronicPayment", XMLСтрока(СуммаЭлектронными));
    ЗаписьXML.ЗаписатьАтрибут("Credit"           , XMLСтрока(СуммаПостоплатой));
    ЗаписьXML.ЗаписатьАтрибут("AdvancePayment"   , XMLСтрока(СуммаПредоплатой));
    ЗаписьXML.ЗаписатьАтрибут("CashProvision"    , XMLСтрока(СуммаПредоставлением));
Иначе // Устаревший формат ФФД 1.0
    ЗаписьXML.ЗаписатьАтрибут("Cash"             , XMLСтрока(СуммаНаличными));
    ЗаписьXML.ЗаписатьАтрибут("ElectronicPayment", XMLСтрока(СуммаЭлектронными + СуммаПостоплатой + СуммаПредоплатой + СуммаПредоставлением));
КонецЕсли;

Важно помнить, что сумма всех переданных видов оплат в блоке Payments должна копейка в копейку совпадать с итоговой суммой всех позиций чека в блоке Positions.

Новые обязательные реквизиты позиций (теги 1214 и 1212)

Для каждой товарной позиции (тег FiscalString) в формате ФФД 1.05 стали обязательными два ключевых признака:

  1. SignMethodCalculation (Признак способа расчета, тег 1214). Определяет, как именно происходит оплата (предоплата, аванс, полный расчет или кредит). Например, значение 4 означает «Полный расчет» (одновременная оплата и передача товара), а значение 1 — «Предоплата 100%».
  2. SignCalculationObject (Признак предмета расчета, тег 1212). Определяет тип продаваемой позиции (товар, услуга, подакцизный товар, работа и т.д.). Например, значение 1 используется для обычного товара, а 4 — для услуг.

Посмотрим на пример структуры готового XML-пакета чека, отправляемого на кассу:


<?xml version="1.0" encoding="UTF-8"?>
<CheckPackage>
    <Parameters PaymentType="1" TaxVariant="3" CashierName="Иванов И.И." CashierVATIN="123456789012" CustomerEmail="" CustomerPhone=""/>
    <Positions>
        <FiscalString Name="Омыватель стекол ZIMA" Quantity="1" PriceWithDiscount="130" SumWithDiscount="130" DiscountSum="" Department="2" Tax="none" SignMethodCalculation="4" SignCalculationObject="1" TaxSum=""/>
    </Positions>
    <Payments Cash="0" ElectronicPayment="130" Credit="0" AdvancePayment="0" CashProvision="0"/>
</CheckPackage>

Почему возникает ошибка «Операция не применима» при передаче скидки?

При переходе на ФФД 1.05 разработчики часто сталкиваются с ошибкой драйвера ККТ при попытке вызвать стандартный метод PercentsDiscount() или передать скидку отдельным параметром. Выясним причину этого поведения.

В новых форматах фискальных данных **скидки на уровне кассового аппарата больше не поддерживаются**. Касса не должна сама рассчитывать уменьшение стоимости. Вместо этого в фискальный накопитель и ОФД должны передаваться уже окончательно рассчитанные в учетной системе 1С значения:

Поэтому из кода обработки обслуживания в 1С 7.7 необходимо полностью исключить функции драйвера, отвечающие за начисление скидок. Все расчеты скидок должны происходить в модуле документа 1С перед формированием XML-чека.

Решение проблемы округления («копеечный» косяк)

Поскольку скидки рассчитываются на стороне 1С, возникает классическая проблема округления стоимости при делении общей суммы чека со скидкой на количество товара. Кассовый аппарат жестко проверяет математическое правило:

Количество * Цена со скидкой = Сумма со скидкой

Если при расчете скидки получается дробное число копеек (например, при распределении скидки на несколько единиц товара), касса выдаст ошибку расхождения сумм и откажется пробивать чек. Рассмотрим, как обойти это ограничение.

Единственным надежным решением является **программное разбиение строки товара на две позиции** (так называемый слайсинг):

Разберем пример: нам нужно продать 3 штуки товара на общую сумму 100 рублей. Ровно разделить 100 на 3 без бесконечной дроби нельзя ($33.333...$). Программа в 1С должна автоматически сформировать две строки в чеке:

Суммарно покупатель получает свои 3 штуки товара за 100 рублей, а кассовый аппарат успешно принимает чек, так как математика в каждой строке абсолютно корректна.

Альтернативный вариант: прямой вызов методов драйвера АТОЛ ДТО 10

Многие специалисты при обновлении оборудования отказываются от использования нестабильной прослойки XML-пакетов в 1С 7.7 и переписывают логику работы с кассой на прямое обращение к OLE/COM-объекту драйвера АТОЛ 10-й версии (AddIn.Fptr10). Это гарантирует стабильную работу без ошибок парсинга XML.

Проанализируем, как выглядит прямая регистрация позиции и закрытие чека на ДТО 10:


// Инициализация объекта драйвера
Касса = СоздатьОбъект("AddIn.Fptr10");
Касса.setParam(Касса.LIBFPTR_PARAM_RECEIPT_TYPE, Касса.LIBFPTR_RT_SELL);
Касса.openReceipt();

// Настройка параметров позиции товара
Касса.setParam(Касса.LIBFPTR_PARAM_COMMODITY_NAME, "Омыватель стекол ZIMA");
Касса.setParam(Касса.LIBFPTR_PARAM_PRICE, 130.00);
Касса.setParam(Касса.LIBFPTR_PARAM_QUANTITY, 1);
Касса.setParam(Касса.LIBFPTR_PARAM_TAX_TYPE, Касса.LIBFPTR_TAX_NO);

// Передача признаков ФФД 1.05 напрямую
Касса.setParam(Касса.LIBFPTR_PARAM_PAYMENT_METHOD, Касса.LIBFPTR_PM_FULL_PAYMENT); // Полный расчет
Касса.setParam(Касса.LIBFPTR_PARAM_PAYMENT_OBJECT, Касса.LIBFPTR_PO_COMMODITY);    // Товар
Касса.registration();

// Проведение оплаты (безналичный расчет)
Касса.setParam(Касса.LIBFPTR_PARAM_PAYMENT_TYPE, Касса.LIBFPTR_PT_ELECTRONICALLY);
Касса.setParam(Касса.LIBFPTR_PARAM_PAYMENT_SUM, 130.00);
Касса.closeReceipt();

Использование прямого API драйвера полностью избавляет разработчика от необходимости собирать и валидировать сложные XML-пакеты, а также позволяет гибко управлять всеми реквизитами чека напрямую из кода 1С 7.7.

← На главную