В процессе работы с торговым оборудованием в 1С Розница часто возникает необходимость печати дополнительной, нефискальной информации на контрольно-кассовой технике (ККТ) непосредственно после того, как основной фискальный чек был успешно пробит и отрезан. Это может быть полезно для различных целей: например, для печати рекламных предложений, информации о предстоящих акциях, персональных скидочных купонов, условий гарантии или любой другой информации, которую мы хотим донести до покупателя сразу после совершения покупки. Однако, поскольку эта информация не является частью фискального документа, регулируемого Федеральным законом № 54-ФЗ, она требует особого подхода к реализации.
Давайте подробно разберем, как мы можем автоматизировать печать такой дополнительной информации, используя возможности платформы 1С и драйверов торгового оборудования.
Прежде чем мы перейдем к конкретным шагам в 1С, важно понять общие принципы, лежащие в основе печати на ККТ:
Теперь, когда мы освежили в памяти основные принципы, давайте рассмотрим два основных подхода к реализации этой задачи в 1С Розница.
Один из наиболее элегантных и рекомендуемых способов решения нашей задачи — это использование механизма подписок на события. Этот подход позволяет нам добавить дополнительную логику без изменения типовых конфигурационных объектов, что упрощает обновления системы в будущем.
Мы начнем с создания новой подписки на событие, которое срабатывает после того, как чек ККМ был успешно записан и, что важно, пробит на фискальном регистраторе. В 1С Розница для этого подойдет событие ПослеЗаписи объекта Документ.ЧекККМ или, как было предложено, более специфичное событие на клиенте, которое гарантирует, что фискализация уже произошла.
Давайте рассмотрим, как мы можем создать такую подписку. В конфигураторе мы переходим в раздел Общие -> Подписки на события и создаем новый элемент. Укажем:
ДополнительнаяПечатьПослеЧекаККМ.ПослеЗаписи.Документ.ЧекККМ.УправлениеПечатьюНаККТ) и экспортируем в нем процедуру, например, ДополнительнаяПечатьПослеЧекаККМПослеЗаписи.Важно! Если мы хотим убедиться, что чек уже пробит на фискальном регистраторе, нам нужно будет проверять статус чека внутри обработчика или использовать событие, которое срабатывает именно после успешной фискализации. В типовых конфигурациях 1С, как правило, процесс фискализации завершается перед окончательной записью чека в базу, но бывают нюансы. Если мы работаем на клиенте, нам может потребоваться подписка на событие, которое срабатывает после пробития чека на стороне ККМ.
В процедуре-обработчике подписки мы должны выполнить следующие действия:
ЧекККМ, таким как Пробит, СтатусЧекаККМ или другим, которые указывают на фискальный статус.Давайте посмотрим на примерную структуру обработчика:
// В общем модуле УправлениеПечатьюНаККТ
Процедура ДополнительнаяПечатьПослеЧекаККМПослеЗаписи(Источник, Отказ, ДополнительныеСвойства) Экспорт
// Источник - это Документ.ЧекККМСсылка
Если Не Источник.ЭтоНовый() Тогда
Перем ОбъектДрайвера;
Перем ПараметрыПодключения;
Перем ИдентификаторУстройства;
// Получаем объект документа для доступа к его данным
ДокументЧекККМ = Источник.ПолучитьОбъект();
// Проверяем, что чек был пробит и фискализирован успешно
Если ДокументЧекККМ.Пробит И ДокументЧекККМ.СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Пробит Тогда
// Можно добавить дополнительные условия для печати
// Например, если в чеке есть определенный товар или сумма > X
// Получаем параметры подключения к ККТ и объект драйвера
// (это стандартные функции, которые могут быть в общих модулях УТ/Розницы)
Если ПодключитьОборудование(ДокументЧекККМ.РабочееМесто.КассаККМ, ОбъектДрайвера, ПараметрыПодключения, ИдентификаторУстройства) Тогда
Попытка
// Формируем текст для печати
ТекстДляПечати = "===================================" + Символы.ПС;
ТекстДляПечати = ТекстДляПечати + "Спасибо за покупку!" + Символы.ПС;
ТекстДляПечати = ТекстДляПечати + "Предъявите этот купон для получения" + Символы.ПС;
ТекстДляПечати = ТекстДляПечати + "скидки 10% на следующую покупку!" + Символы.ПС;
ТекстДляПечати = ТекстДляПечати + "Акция действует до 31.12.2024" + Символы.ПС;
ТекстДляПечати = ТекстДляПечати + "===================================" + Символы.ПС;
// Вызываем метод печати нефискального текста драйвера
// Название метода зависит от конкретного драйвера (АТОЛ, ШТРИХ-М и т.д.)
// Пример для общего случая или ШТРИХ-М:
ОбъектДрайвера.PrintString(ТекстДляПепечати);
// Для АТОЛ может быть что-то вроде ОбъектДрайвера.НапечататьСтроку() или работа с объектом NonFiscalPrinter
// Если требуется отрезать дополнительный чек
ОбъектДрайвера.CutCheck(); // Отрезка чека
Исключение
ЗаписьЖурналаРегистрации(
"ДополнительнаяПечатьНаККТ",
УровеньЖурналаРегистрации.Ошибка,
ДокументЧекККМ.Метаданные(),
ДокументЧекККМ,
"Ошибка при печати дополнительной нефискальной информации: " + ОписаниеОшибки()
);
КонецПопытки;
// Важно: Отключение оборудования после использования, если оно было подключено специально для этой операции
ОтключитьОборудование(ИдентификаторУстройства);
Иначе
ЗаписьЖурналаРегистрации(
"ДополнительнаяПечатьНаККТ",
УровеньЖурналаРегистрации.Предупреждение,
ДокументЧекККМ.Метаданные(),
ДокументЧекККМ,
"Не удалось подключиться к ККТ " + ДокументЧекККМ.РабочееМесто.КассаККМ + " для дополнительной печати."
);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Вспомогательные функции для подключения/отключения оборудования
// (обычно существуют в общих модулях конфигурации, например, УправлениеТорговымОборудованиемКлиентСервер)
Функция ПодключитьОборудование(КассаККМ, ОбъектДрайвера, ПараметрыПодключения, ИдентификаторУстройства)
// ... логика подключения к ККТ ...
// Возвращает Истина, если подключение успешно, и заполняет ОбъектДрайвера, ПараметрыПодключения, ИдентификаторУстройства
Возврат Ложь; // Заглушка, здесь должна быть реальная логика
КонецФункции
Процедура ОтключитьОборудование(ИдентификаторУстройства)
// ... логика отключения ККТ ...
КонецПроцедуры
Обратите внимание, что функции ПодключитьОборудование и ОтключитьОборудование, а также конкретные методы драйвера (например, PrintString или CutCheck) могут отличаться в зависимости от используемой конфигурации 1С и модели ККТ/драйвера. Мы всегда должны обращаться к документации по драйверу ККТ и к существующим общим модулям конфигурации 1С, которые управляют торговым оборудованием.
Альтернативный подход, предложенный в сообщении на форуме, заключается в прямой модификации существующих процедур, которые отвечают за фискализацию чека. Этот метод более инвазивен, поскольку требует изменения типового кода конфигурации, что может усложнить процесс обновления. Однако он может быть предпочтителен, если нам нужен очень точный контроль над моментом печати и доступом к внутренним параметрам фискализации.
Нам необходимо найти в конфигурации процедуру или функцию, которая непосредственно осуществляет фискализацию чека и взаимодействует с драйвером ККТ. В 1С Розница и Управлении торговлей такие процедуры обычно находятся в модулях объектов документов, таких как Документ.ЧекККМ, или в общих модулях, отвечающих за работу с торговым оборудованием (например, УправлениеТорговымОборудованием, ПодключаемоеОборудованиеПереопределяемый или ОбменСКО).
Обычно процесс выглядит так: пользователь нажимает кнопку "Пробить чек", система формирует фискальные данные, передает их в общий модуль, который, в свою очередь, через COM-объект или нативный API взаимодействует с драйвером ККТ.
После того как мы идентифицировали нужную процедуру, нам нужно вставить вызов нашей функции для печати нефискальной информации *после* того, как произошло успешное пробитие основного фискального чека и, что важно, *после* команды отрезки основного чека (если она там присутствует). Если команда отрезки основного чека не выполняется автоматически драйвером после фискализации, нам, возможно, придется явно вызвать ее перед печатью дополнительной информации.
Примерная логика внутри типовой процедуры (предположим, что мы нашли место в процедуре ПробитьЧекНаККМ):
// Примерная типовая процедура фискализации чека в модуле объекта или общем модуле
Процедура ПробитьЧекНаККМ(ЧекККМ, ПараметрыПечати)
// ... Здесь идет подготовка данных для фискального чека ...
// ... Создание объекта драйвера ККТ ...
Перем ОбъектДрайвера;
Перем Результат;
// Получение объекта драйвера и подключение к ККТ
Если УправлениеТорговымОборудованием.ПодключитьДрайверККТ(ПараметрыПечати.КассаККМ, ОбъектДрайвера) Тогда
Попытка
// ... Здесь типовой код для открытия чека ...
// ОбъектДрайвера.ОткрытьЧек(...);
// ... Здесь типовой код для добавления позиций в чек ...
// Для КаждаяСтрока Из ЧекККМ.Товары Цикл
// ОбъектДрайвера.ДобавитьПозицию(...);
// КонецЦикла;
// ... Здесь типовой код для закрытия чека и фискализации ...
Результат = ОбъектДрайвера.ЗакрытьЧек(...);
// !!!!! ВАЖНО: Мы вставляем наш код СРАЗУ ПОСЛЕ УСПЕШНОЙ ФИСКАЛИЗАЦИИ !!!!!
Если Результат.Успех Тогда
// Основной фискальный чек успешно пробит.
// Возможно, здесь уже была команда отрезки чека от драйвера.
// Если нет, то ее можно добавить:
// ОбъектДрайвера.CutCheck();
// Теперь вызываем нашу функцию для печати дополнительной информации
// Мы можем передать ей нужные данные из текущего контекста чека
ВыполнитьПечатьДополнительногоЧека(ОбъектДрайвера, ЧекККМ);
КонецЕсли;
Исключение
// Обработка ошибок фискализации
ЗаписьЖурналаРегистрации(
"ФискализацияЧека",
УровеньЖурналаРегистрации.Ошибка,
ЧекККМ.Метаданные(),
ЧекККМ,
"Ошибка при фискализации чека: " + ОписаниеОшибки()
);
Возврат;
КонецПопытки;
// ... Типовой код для отключения драйвера ...
УправлениеТорговымОборудованием.ОтключитьДрайверККТ(ОбъектДрайвера);
Иначе
// ... Ошибка подключения ККТ ...
КонецЕсли;
КонецПроцедуры
// Новая функция, которую мы создаем для печати нефискальной информации
Процедура ВыполнитьПечатьДополнительногоЧека(ОбъектДрайвераККТ, ДокументЧекККМ) Экспорт
// Формируем текст для печати, как и в предыдущем методе
ТекстДляПечати = "===================================" + Символы.ПС;
ТекстДляПечати = ТекстДляПечати + "Дорогой покупатель!" + Символы.ПС;
ТекстДляПечати = ТекстДляПечати + "Ваш чек №" + ДокументЧекККМ.Номер + " от " + Формат(ДокументЧекККМ.Дата, "ДФ=dd.MM.yyyy") + Символы.ПС;
ТекстДляПечати = ТекстДляПечати + "Пожалуйста, оставьте отзыв о нашем магазине" + Символы.ПС;
ТекстДляПечати = ТекстДляПечати + "и получите бонусные баллы!" + Символы.ПС;
ТекстДляПечати = ТекстДляПечати + "===================================" + Символы.ПС;
Попытка
// Вызываем метод печати нефискального текста драйвера
ОбъектДрайвераККТ.PrintString(ТекстДляПечати);
// Обязательно отрезаем дополнительный чек, чтобы он был отделен от фискального
ОбъектДрайвераККТ.CutCheck();
Исключение
ЗаписьЖурналаРегистрации(
"ДополнительнаяПечатьНаККТ",
УровеньЖурналаРегистрации.Ошибка,
ДокументЧекККМ.Метаданные(),
ДокументЧекККМ,
"Ошибка при печати дополнительной информации после фискализации: " + ОписаниеОшибки()
);
КонецПопытки;
КонецПроцедуры
Важный момент: При внесении изменений в типовые процедуры мы всегда должны использовать механизмы расширений конфигурации, если это возможно, чтобы минимизировать риски при обновлении. Если же расширения не позволяют реализовать нужную логику (например, если нет подходящих точек расширения), то изменения следует вносить очень аккуратно, документировать их и быть готовыми к возможным доработкам после каждого обновления конфигурации.
Независимо от выбранного метода реализации, нам необходимо учитывать некоторые общие технические моменты, связанные с работой ККТ и ее драйверов:
CutCheck() (ОтрезатьЧек), который подает на принтер команду отрезки. Мы должны убедиться, что эта команда вызывается *после* печати фискального чека и *после* печати нашей нефискальной информации, если мы хотим, чтобы она была на отдельном листе. Если драйвер автоматически отрезает чек после фискализации, наша задача — лишь напечатать дополнительный текст и снова дать команду отрезки.PrintString(), НапечататьСтроку() или более комплексные методы для работы с нефискальным принтером.Реализация печати дополнительной нефискальной информации после отрезки фискального чека в 1С Розница является вполне осуществимой задачей. Она требует программной доработки, использующей возможности драйвера ККТ по печати произвольного текста или изображений, инициируемой событием после успешной фискализации основного чека.
Мы рассмотрели два основных подхода: использование подписок на события и прямую модификацию процедур фискализации. Выбор метода зависит от ваших предпочтений к инвазивности изменений и текущей архитектуры конфигурации.
В любом случае, нам придется глубоко погрузиться в работу с драйверами торгового оборудования, понять их API и обеспечить корректное взаимодействие между 1С и ККТ. Тщательное тестирование и внимание к деталям гарантируют стабильную и надежную работу нашей доработки.