Переход со старого формата фискальных данных (ФФД 1.0) на ФФД 1.05 на платформе 1С 7.7 вызывает немало трудностей у разработчиков. Стандартные механизмы конфигураций вроде «Торговля и Склад 7.7» зачастую используют устаревшие структуры XML-пакетов, которые не поддерживают новые требования законодательства. В ФФД 1.05 появились новые обязательные реквизиты, изменились правила применения скидок, а также расширился перечень типов оплаты. Рассмотрим подробно, как решить эти задачи в 1С 7.7.
В ФФД 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.
Для каждой товарной позиции (тег FiscalString) в формате ФФД 1.05 стали обязательными два ключевых признака:
4 означает «Полный расчет» (одновременная оплата и передача товара), а значение 1 — «Предоплата 100%».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С значения:
PriceWithDiscount).SumWithDiscount).DiscountSum в XML-пакете оставляется пустым или передается как 0.Поэтому из кода обработки обслуживания в 1С 7.7 необходимо полностью исключить функции драйвера, отвечающие за начисление скидок. Все расчеты скидок должны происходить в модуле документа 1С перед формированием XML-чека.
Поскольку скидки рассчитываются на стороне 1С, возникает классическая проблема округления стоимости при делении общей суммы чека со скидкой на количество товара. Кассовый аппарат жестко проверяет математическое правило:
Количество * Цена со скидкой = Сумма со скидкой
Если при расчете скидки получается дробное число копеек (например, при распределении скидки на несколько единиц товара), касса выдаст ошибку расхождения сумм и откажется пробивать чек. Рассмотрим, как обойти это ограничение.
Единственным надежным решением является **программное разбиение строки товара на две позиции** (так называемый слайсинг):
Разберем пример: нам нужно продать 3 штуки товара на общую сумму 100 рублей. Ровно разделить 100 на 3 без бесконечной дроби нельзя ($33.333...$). Программа в 1С должна автоматически сформировать две строки в чеке:
Суммарно покупатель получает свои 3 штуки товара за 100 рублей, а кассовый аппарат успешно принимает чек, так как математика в каждой строке абсолютно корректна.
Многие специалисты при обновлении оборудования отказываются от использования нестабильной прослойки 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.