При интеграции кассового оборудования ШТРИХ-М (например, ШТРИХ-М-02Ф) напрямую через низкоуровневый COM-драйвер часто возникает необходимость программного формирования фискального документа. Разберем детально, как устроен процесс открытия, наполнения строками, расчета налогов и закрытия чека при помощи объекта AddIn.Drvfr.
Для взаимодействия с фискальным регистратором создается COM-объект драйвера. Перед началом печати важно установить пароль доступа (по умолчанию для оператора/кассира используется 30 или переданный пароль пользователя), а также проверять состояние устройства.
Рассмотрим типовой сценарий функции печати фискального чека на основе параметров торговой операции:
Функция ПечататьЧек(Объект, Пароль, СписокТоваров, Получено1, Скидка, ПризнВозврата, НомерСекции, НомерЧека, ТипНалогов)
// Установка системы налогообложения для чека
Объект.TaxType = ТипНалогов;
Получено1 = 0;
СуммаСкидкиНаЧек = 0;
СписокТоваров.ВыбратьСтроки();
Пока СписокТоваров.ПолучитьСтроку() = 1 Цикл
СтрокаДляПечати = СписокТоваров.ТовНаим;
Объект.Password = Пароль;
Объект.StringForPrinting = Лев(СтрокаДляПечати, 48);
Если СуммаСкидки = 0 Тогда
Объект.Price = СписокТоваров.Цена;
Получено1 = Получено1 + СписокТоваров.Цена * СписокТоваров.Количество;
Иначе
СуммаСкидкиНаЧек = СуммаСкидкиНаЧек + (СписокТоваров.Цена * СписокТоваров.Количество - СписокТоваров.Сумма);
ЦенаЦены = Окр(СписокТоваров.Сумма / СписокТоваров.Количество, 2);
Объект.Price = ЦенаЦены;
Получено1 = Получено1 + ЦенаЦены * СписокТоваров.Количество;
КонецЕсли;
Объект.Quantity = СписокТоваров.Количество;
Объект.Department = НомерСекции;
// Настройка передачи ставки НДС в позицию
НДСЕсть = 0;
Попытка
НДС = СписокТоваров.НДС;
НДСЕсть = 1;
Исключение
НДСЕсть = 0;
КонецПопытки;
Если НДСЕсть = 1 Тогда
// Настройка налоговых ставок согласно таблицам ФР:
// 1 - НДС 18%, 2 - НДС 10%, 3 - НДС 20%, 0 - без НДС
Если СписокТоваров.НДС = 18 Тогда
Объект.Tax1 = 1;
ИначеЕсли СписокТоваров.НДС = 10 Тогда
Объект.Tax1 = 2;
ИначеЕсли СписокТоваров.НДС = 20 Тогда
Объект.Tax1 = 3;
Иначе
Объект.Tax1 = 0;
КонецЕсли;
Объект.Tax2 = 0;
Объект.Tax3 = 0;
Объект.Tax4 = 0;
КонецЕсли;
// Регистрация продажи или возврата продажи
Если ПризнВозврата = 0 Тогда
Объект.Sale();
Иначе
Объект.ReturnSale();
КонецЕсли;
// Проверка результата выполнения операции регистрации
Если Объект.ResultCode <> 0 Тогда
ОписаниеРезультата = ПолучитьОписаниеРезультата(Объект);
Объект.CancelCheck();
Возврат 0;
КонецЕсли;
КонецЦикла;
// Печать дополнительной текстовой информации при необходимости
СтрокаДляПечати = "================================";
Объект.Password = Пароль;
Объект.StringForPrinting = Лев(СтрокаДляПечати, 48);
Объект.PrintString();
// Распределение сумм оплаты по типам платежей
Объект.Password = Пароль;
Если ВидПлатежа = Перечисление.ВидыПлатежа.Нал Тогда
Объект.Summ1 = Получено1; // Наличные
Объект.Summ2 = 0;
Иначе
Объект.Summ1 = 0;
Объект.Summ2 = Получено1; // Безналичная (электронная) оплата
КонецЕсли;
Объект.Summ3 = 0; // Аванс / Предоплата
Объект.Summ4 = 0; // Кредит / Постоплата
// Закрытие чека в фискальном накопителе
Объект.FNCloseCheckEx();
Объект.CloseCheck();
Если Объект.ResultCode <> 0 Тогда
ОписаниеРезультата = ПолучитьОписаниеРезультата(Объект);
Объект.CancelCheck();
Возврат 0;
КонецЕсли;
// Получение номера закрытого документа
Объект.Password = Пароль;
Объект.GetECRStatus();
Если Объект.ResultCode = 0 Тогда
НомерЧека = Объект.OpenDocumentNumber + ?(Объект.ECRAdvancedMode = 5, 1, 0);
КонецЕсли;
Возврат 1;
КонецФункции
Разберем по шагам, на какие нюансы низкоуровневой работы с драйвером ШТРИХ-М следует обратить особое внимание:
Sale() используется для операции продажи, а ReturnSale() — для оформления возврата. Наименование товара задается свойством StringForPrinting (длина строки зависит от ширины кассовой ленты конкретной модели, как правило, до 48 символов), цена — через Price, количество — через Quantity, а отдел/секция — через Department.Tax1–Tax4, соответствующие номерам налоговых ставок, настроенным в таблицах самого фискального регистратора.Summ1 отвечает за наличный расчет, Summ2 — за безналичные (электронные) средства, Summ3 — за предоплату (аванс), а Summ4 — за постоплату (кредит). Важно: сумма всех заполненных полей Summ1–Summ5 обязана с точностью до копейки совпадать с итоговой суммой зарегистрированных позиций, иначе касса вернет ошибку несовпадения итогов.CancelCheck() для сброса состояния документа, чтобы ККТ не осталась заблокированной.GetECRStatus() позволяет проверить текущий режим кассы. Если длительность смены превысила 24 часа, печать чеков будет заблокирована до формирования отчета с гашением (Z-отчета) методом PrintReportWithCleaning().Проанализируем технические требования к окружению при использовании прямой печати:
AddIn.DrvFR является 32-разрядным (x86). При запуске кода в 64-битном клиенте 1С или на сервере вызов Новый("AddIn.DrvFR") вызовет системную ошибку загрузки компоненты. Для серверных и 64-битных сценариев рекомендуется использовать 64-битные Native-компоненты либо выносить взаимодействие с ККТ на сторону 32-разрядного клиента.