Переход платформы «1С:Предприятие 7.7» на работу с онлайн-кассами по требованиям 54-ФЗ требует обновления механизмов взаимодействия с кассовым оборудованием. В отличие от старых версий фискальных регистраторов с ЭКЛЗ, современные аппараты требуют обязательной передачи номенклатурного состава, ставок НДС, реквизитов кассира, систем налогообложения и контактных данных покупателя для отправки электронного чека.
Разберем подробно два основных подхода к интеграции: использование стандартизированного XML-пакета через компоненту интеграции (БПО) и прямое управление регистрацией через низкоуровневые COM-драйверы производителей.
При использовании драйверов АТОЛ (библиотека FprnM1C82_54FZ.dll / ATOL_KKM_1C82_54FZ) передача данных о чеке выполняется через XML-структуру определенного формата. Для корректной обработки данных платформой 1С 7.7 требуется сформировать документ в кодировке UTF-8 без BOM и передать его в метод драйвера СформироватьЧек.
Рассмотрим пример функции печати фискального чека с передачей товарных позиций, безналичной оплаты и контактов покупателя:
Функция ПечататьЧекАТОЛ(Объект, Кассир, ПризнВозврата, СНО, МылоПолучателя, ТелПолучателя, СписокТоваров, СуммаЧека, СуммаНал, СуммаБезнал)
Перем XMLАнализатор, XMLДанныеЧека, XMLCheckPackage, XMLParameters, XMLPositions, XMLPayments;
Перем XMLFiscalString, АдоДБСтрим, ТекстXML, ОписаниеОшибки, КодОшибки;
Перем НомерЧека, НомерСмены, ФискальныйПризнак, АдресСайтаПроверки;
XMLАнализатор = СоздатьОбъект("AddIn.XMLParser");
XMLДанныеЧека = XMLАнализатор.СоздатьДокумент();
XMLДанныеЧека.Кодировка = "UTF-8";
XMLCheckPackage = XMLДанныеЧека.СоздатьПодчиненныйЭлемент("CheckPackage");
XMLParameters = XMLCheckPackage.СоздатьПодчиненныйЭлемент("Parameters");
// Тип расчета: 1 - Приход, 2 - Возврат прихода
Атрибут(XMLParameters, "PaymentType", ?(ПризнВозврата = 1, 2, 1));
Атрибут(XMLParameters, "TaxVariant", СНО);
Если ПустаяСтрока(МылоПолучателя) = 0 Тогда
Атрибут(XMLParameters, "CustomerEmail", СокрЛП(МылоПолучателя));
КонецЕсли;
Если ПустаяСтрока(ТелПолучателя) = 0 Тогда
Атрибут(XMLParameters, "CustomerPhone", СокрЛП(ТелПолучателя));
КонецЕсли;
XMLPositions = XMLCheckPackage.СоздатьПодчиненныйЭлемент("Positions");
СписокТоваров.ВыбратьСтроки();
Пока СписокТоваров.ПолучитьСтроку() = 1 Цикл
XMLFiscalString = XMLPositions.СоздатьПодчиненныйЭлемент("FiscalString");
Атрибут(XMLFiscalString, "Name", СокрЛП(СписокТоваров.ТовНаим));
Атрибут(XMLFiscalString, "Quantity", СписокТоваров.Количество);
Атрибут(XMLFiscalString, "Price", Окр(СписокТоваров.Цена, 2));
Атрибут(XMLFiscalString, "Amount", Окр(СписокТоваров.Сумма, 2));
Атрибут(XMLFiscalString, "Tax", СписокТоваров.СтавкаНДС); // Значения: "18", "10", "0", "none"
Атрибут(XMLFiscalString, "Department", СписокТоваров.Секция);
КонецЦикла;
XMLPayments = XMLCheckPackage.СоздатьПодчиненныйЭлемент("Payments");
Атрибут(XMLPayments, "Cash", СуммаНал);
Атрибут(XMLPayments, "CashLessType1", "0");
Атрибут(XMLPayments, "CashLessType2", "0");
Атрибут(XMLPayments, "CashLessType3", СуммаБезнал); // Оплата платежной картой
XMLДанныеЧека.Записать(КаталогПользователя() + "check.xml");
// Чтение XML в формате UTF-8
АдоДБСтрим = CreateObject("Adodb.Stream");
АдоДБСтрим.Charset = "utf-8";
АдоДБСтрим.Type = 2;
АдоДБСтрим.Mode = 3;
АдоДБСтрим.Open();
АдоДБСтрим.LoadFromFile(КаталогПользователя() + "check.xml");
ТекстXML = АдоДБСтрим.ReadText();
АдоДБСтрим.Close();
Электронно = ?((ПустаяСтрока(МылоПолучателя) = 0) ИЛИ (ПустаяСтрока(ТелПолучателя) = 0), 1, 0);
Объект.СформироватьЧек(глФРИДУстройства, Кассир, Электронно, ТекстXML, НомерЧека, НомерСмены, ФискальныйПризнак, АдресСайтаПроверки);
ОписаниеОшибки = "";
КодОшибки = Объект.GetLastError(ОписаниеОшибки);
Если КодОшибки <> 0 Тогда
Сообщить("Ошибка печати чека: " + ОписаниеОшибки, "!");
Возврат 0;
КонецЕсли;
Возврат 1;
КонецФункции
Если используется прямое подключение через объект AddIn.FprnM45 (драйвер ККТ 8.x), чек пробивается последовательным вызовом методов устройства. Важным моментом является передача тега кассира (тег 1021) перед открытием чека или снятием Z-отчета:
// Установка кассира и открытие чека продажи
глФР.DeviceEnabled = 1;
глФР.Mode = 1; // Режим регистрации
глФР.SetMode();
// Запись реквизита "Кассир" (Тег 1021)
глФР.AttrNumber = 1021;
глФР.AttrValue = "Кассир Иванов И.И.";
глФР.AttrPrint = 1;
глФР.WriteAttribute();
глФР.CheckType = 1; // 1 - Продажа, 2 - Возврат продажи
глФР.OpenCheck();
// Регистрация позиции
глФР.Name = "Товар 1";
глФР.Price = 150.00;
глФР.Quantity = 2;
глФР.Department = 1;
глФР.TaxTypeNumber = 4; // 4 - Без НДС, 1 - 18%, 2 - 10%, 3 - 0%
глФР.Registration();
// Закрытие чека с типом оплаты
глФР.Summ = 300.00;
глФР.TypeClose = 0; // 0 - Наличные, 3 - Электронными (карта)
глФР.Delivery();
глФР.CloseCheck();
При интеграции ККТ семейства «Штрих-М» через библиотеку DrvFR.dll часто возникает проблема, когда наименование товара печатается на бумажной ленте, но не уходит в электронном виде в ОФД. Проанализируем причину: свойство StringForPrinting должно заполняться строго до вызова метода регистрации продажи Sale(), а вызов методов печати нефискального текста не должен перекрывать фискальные реквизиты.
Посмотрим на пример правильной регистрации продажи на ККТ «Штрих-М»:
// Вход в режим регистрации
глФР.Password = 30; // Пароль системного администратора
глФР.SetMode();
// Установка ФИО кассира в таблицу паролей (Таблица №2, поле №2)
глФР.TableNumber = 2;
глФР.RowNumber = 1; // Номер кассира
глФР.FieldNumber = 2;
глФР.ValueOfFieldString = "Иванов И.И.";
глФР.WriteTable();
глФР.Password = 1; // Пароль кассира
глФР.OpenCheck();
СписокТоваров.ВыбратьСтроки();
Пока СписокТоваров.ПолучитьСтроку() = 1 Цикл
// Передаем наименование в StringForPrinting ДО вызова фискальной операции
глФР.StringForPrinting = Лев(СписокТоваров.ТовНаим, 64);
глФР.Price = Окр(СписокТоваров.Цена, 2);
глФР.Quantity = СписокТоваров.Количество;
глФР.Department = 1;
глФР.Tax1 = 0; // Налоговая группа
глФР.Sale();
КонецЦикла;
// Закрытие чека
глФР.Summ1 = СуммаНал; // Оплата наличными
глФР.Summ2 = СуммаБезнал; // Оплата безналичными (тип 2/3)
глФР.StringForPrinting = "";
глФР.CloseCheck();
5.005 при выделении НДС «сверху») приводит к ошибкам драйвера или подстановке значений из предыдущих строк. Всегда применяйте явное округление: Цена = Окр(Сумма / Количество, 2, 1).EthOverUsb требует жесткого закрепления номеров виртуальных COM-портов в файле settings.xml. Для аппаратов Штрих-М при сбоях протокола RNDIS оптимальным решением является подключение ККТ по интерфейсу Ethernet.