В розничной и оптовой торговле часто возникает ситуация, когда в магазине или офисе продаж работают несколько менеджеров (кассиров), а физически установлена только одна онлайн-касса (ККТ). Покупка отдельного фискального регистратора на каждое рабочее место экономически нецелесообразна, особенно если поток покупателей небольшой. Но как организовать их совместную работу без аппаратных конфликтов и ошибок блокировки портов?
В этой статье мы подробно разберем, как решить эту задачу в экосистеме 1С. Мы рассмотрим как полностью бесплатный вариант самостоятельной разработки очереди печати внутри конфигурации, так и готовые современные альтернативы на уровне сетевых драйверов ККТ.
Самый очевидный и простой путь, который выбирают многие начинающие администраторы — это проброс виртуального COM-порта онлайн-кассы, подключенной по USB к локальному компьютеру, в сессию удаленного рабочего стола (RDP) на сервере 1С. Однако на практике такой подход быстро превращается в проблему:
Для стабильной работы нам потребуется централизованная очередь печати. Давайте проанализируем три основных способа ее реализации.
Это надежный классический метод автоматизации. Суть его заключается в том, что рабочие места пользователей не обращаются к кассе напрямую. Вместо этого они лишь формируют задание на печать и записывают его в специальную таблицу (очередь). Печатью же занимается один выделенный сеанс (робот) на том компьютере, к которому физически подключен аппарат.
Разберем по шагам, как спроектировать этот механизм.
Шаг 1. Создание метаданных в конфигураторе
Давайте создадим новый Регистр Сведений (назовем его ОчередьПечатиЧеков) со следующей структурой:
ИдентификаторЗадачи (Тип: Строка, длина 36 или УникальныйИдентификатор) — уникальный ключ задания.ДокументОснование (Тип: ДокументСсылка) — ссылка на чек, накладную или заказ, по которому бьется чек.ПараметрыЧека (Тип: ХранилищеЗначения) — здесь мы будем хранить сериализованную структуру данных чека (табличную часть товаров, ставки НДС, суммы оплат).Статус (Тип: ПеречислениеСсылка.СтатусыОчередиПечати) — значения: Новый, ВРаботе, Выполнен, Ошибка.ОписаниеОшибки (Тип: Строка) — текст системной ошибки ККТ в случае сбоя.ДатаСоздания (Тип: Дата) — дата и время добавления в очередь для соблюдения хронологического порядка.Шаг 2. Запись чека в очередь из рабочего места менеджера
Когда менеджер нажимает кнопку "Пробить чек", мы не вызываем обработку торгового оборудования напрямую. Вместо этого мы упаковываем все необходимые для чека данные в структуру и записываем ее в наш регистр:
// Функция записи чека в очередь
Процедура ДобавитьЧекВОчередь(ДокументСсылка, СтруктураПараметровЧека) Экспорт
НоваяЗапись = РегистрыСведений.ОчередьПечатиЧеков.СоздатьМенеджерЗаписи();
НоваяЗапись.ИдентификаторЗадачи = Новый УникальныйИдентификатор();
НоваяЗапись.ДатаСоздания = ТекущаяДатаСеанса();
НоваяЗапись.ДокументОснование = ДокументСсылка;
НоваяЗапись.Статус = Перечисления.СтатусыОчередиПечати.Новый;
// Помещаем структуру параметров чека в ХранилищеЗначения
НоваяЗапись.ПараметрыЧека = Новый ХранилищеЗначения(СтруктураПараметровЧека);
Попытка
НоваяЗапись.Записать();
ПоказатьОповещениеПользователя("Очередь ККТ", , "Чек успешно отправлен в очередь печати");
Исключение
ВызватьИсключение "Не удалось записать задачу в очередь печати чеков: " + ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
Шаг 3. Реализация обработчика очереди (Регламентное задание)
На компьютере, к которому физически подключен фискальный регистратор, должен работать фоновый процесс. Это может быть регламентное задание 1С, выполняющееся под определенным пользователем, либо запущенный в режиме "Печать чеков" специальный сеанс 1С.
Рассмотрим код обработчика, который раз в 10–15 секунд опрашивает регистр:
Процедура ОбработатьОчередьПечатиЧеков() Экспорт
// Выбираем новые задачи по порядку их поступления
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Очередь.ИдентификаторЗадачи КАК ИдентификаторЗадачи,
| Очередь.ДокументОснование КАК ДокументОснование,
| Очередь.ПараметрыЧека КАК ПараметрыЧека
|ИЗ
| РегистрСведений.ОчередьПечатиЧеков КАК Очередь
|ГДЕ
| Очередь.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыОчередиПечати.Новый)
|УПОРЯДОЧИТЬ ПО
| Очередь.ДатаСоздания ВОЗРАСТ";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Изменяем статус задачи, чтобы исключить повторную обработку в параллельных потоках
МенеджерЗаписи = РегистрыСведений.ОчередьПечатиЧеков.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ИдентификаторЗадачи = Выборка.ИдентификаторЗадачи;
МенеджерЗаписи.Прочитать();
Если МенеджерЗаписи.Выбран() Тогда
МенеджерЗаписи.Статус = Перечисления.СтатусыОчередиПечати.ВРаботе;
МенеджерЗаписи.Записать();
Иначе
Продолжить;
КонецЕсли;
// Получаем параметры чека из Хранилища Значения
ДанныеЧека = Выборка.ПараметрыЧека.Получить();
// Вызываем процедуру интеграции с БПО для непосредственной печати на ККТ
РезультатПечати = НапечататьФискальныйЧекНаОборудовании(ДанныеЧека);
МенеджерЗаписиОкончательный = РегистрыСведений.ОчередьПечатиЧеков.СоздатьМенеджерЗаписи();
МенеджерЗаписиОкончательный.ИдентификаторЗадачи = Выборка.ИдентификаторЗадачи;
МенеджерЗаписиОкончательный.Прочитать();
Если РезультатПечати.Успех Тогда
МенеджерЗаписиОкончательный.Статус = Перечисления.СтатусыОчередиПечати.Выполнен;
Иначе
МенеджерЗаписиОкончательный.Статус = Перечисления.СтатусыОчередиПечати.Ошибка;
МенеджерЗаписиОкончательный.ОписаниеОшибки = РезультатПечати.ТекстОшибки;
КонецЕсли;
МенеджерЗаписиОкончательный.Записать();
КонецЦикла;
КонецПроцедуры
Этот способ абсолютно надежен, не требует покупки стороннего ПО и работает в любых конфигурациях 1С. Однако пользователю на рабочем месте приходится ждать несколько секунд, пока регламентное задание отработает и напечатает чек.
Если вы работаете на современных версиях конфигураций 1С (например, "1С:Розница 3.0", "1С:УНФ 3.0" или "1С:Бухгалтерия 3.0"), то в них уже встроен штатный механизм работы с очередью чеков. Изначально он создавался для интернет-магазинов, но отлично подходит и для интеграции обычных рабочих мест.
В Библиотеке Подключаемого Оборудования (БПО) реализована функция "ККТ в общем доступе". Настройка выполняется следующим образом:
Очередь чеков ККТ. Программа сама берет на себя блокировку портов на время печати, а кассиры отправляют команды на фискализацию документов "из коробки" без написания кода.Если вы не хотите вносить изменения в конфигурацию 1С и желаете, чтобы чеки печатались мгновенно, лучшим решением будет использование специализированных программных прослоек, работающих по протоколу HTTP.
Давайте подробно рассмотрим архитектуру работы через сторонний веб-сервер:
Проанализируем пример кода отправки чека на KkmServer через HTTP-запрос из 1С:
Функция ОтправитьЧекНаKkmServer(ДанныеЗапросаJSON, IPАдресСервера)
// Создаем HTTP-соединение с компьютером, где установлена касса
НТТРСоединение = Новый HTTPСоединение(IPАдресСервера, 5893); // Порт по умолчанию для KkmServer
HTTPЗапрос = Новый HTTPЗапрос("/Execute");
HTTPЗапрос.УстановитьТелоИзСтроки(ДанныеЗапросаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json");
Попытка
HTTPОтвет = НТТРСоединение.ОтправитьДляОбъекта(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда
Возврат HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Иначе
Возврат "Ошибка сервера. Код ответа: " + HTTPОтвет.КодСостояния;
КонецЕсли;
Исключение
Возврат "Ошибка связи с KkmServer: " + ОписаниеОшибки();
КонецПопытки;
КонецФункции
Решая техническую сторону вопроса, крайне важно не нарушить требования Федерального закона № 54-ФЗ. Давайте выясним, в каких случаях одна касса на несколько рабочих мест абсолютно законна, а когда это грозит серьезными штрафами от налоговой инспекции.
Закон предъявляет жесткие требования к месту установки и процессу фискализации:
Мы проанализировали различные варианты создания очереди печати. Выбор конкретного пути зависит от специфики вашей ИТ-инфраструктуры: