Как организовать очередь печати чеков на одной онлайн-кассе с нескольких рабочих мест в 1С?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

В розничной и оптовой торговле часто возникает ситуация, когда в магазине или офисе продаж работают несколько менеджеров (кассиров), а физически установлена только одна онлайн-касса (ККТ). Покупка отдельного фискального регистратора на каждое рабочее место экономически нецелесообразна, особенно если поток покупателей небольшой. Но как организовать их совместную работу без аппаратных конфликтов и ошибок блокировки портов?

В этой статье мы подробно разберем, как решить эту задачу в экосистеме 1С. Мы рассмотрим как полностью бесплатный вариант самостоятельной разработки очереди печати внутри конфигурации, так и готовые современные альтернативы на уровне сетевых драйверов ККТ.

Архитектурная проблема: Почему нельзя просто пробросить COM-порт по RDP?

Самый очевидный и простой путь, который выбирают многие начинающие администраторы — это проброс виртуального COM-порта онлайн-кассы, подключенной по USB к локальному компьютеру, в сессию удаленного рабочего стола (RDP) на сервере 1С. Однако на практике такой подход быстро превращается в проблему:

  1. Монопольный захват порта. Драйвер ККТ при подключении к кассе захватывает COM-порт монопольно. Если один пользователь открыл форму чека и драйвер инициализировал связь, второй пользователь при попытке пробить чек получит ошибку "Порт занят" или "ККТ не найдена".
  2. Низкая скорость передачи данных. Проброс портов через RDP чувствителен к стабильности сетевого соединения. Чек с большим количеством номенклатурных позиций может печататься до одной-двух минут, при этом сессия 1С пользователя будет "зависать".
  3. Постоянные обрывы связи. При малейшем сбое сети виртуальный COM-порт "отваливается", и восстановить его работу зачастую удается только перезапуском RDP-сессии или службы печати.

Для стабильной работы нам потребуется централизованная очередь печати. Давайте проанализируем три основных способа ее реализации.

Способ 1. Разработка собственной очереди печати на регистрах сведений 1С

Это надежный классический метод автоматизации. Суть его заключается в том, что рабочие места пользователей не обращаются к кассе напрямую. Вместо этого они лишь формируют задание на печать и записывают его в специальную таблицу (очередь). Печатью же занимается один выделенный сеанс (робот) на том компьютере, к которому физически подключен аппарат.

Разберем по шагам, как спроектировать этот механизм.

Шаг 1. Создание метаданных в конфигураторе

Давайте создадим новый Регистр Сведений (назовем его ОчередьПечатиЧеков) со следующей структурой:

Шаг 2. Запись чека в очередь из рабочего места менеджера

Когда менеджер нажимает кнопку "Пробить чек", мы не вызываем обработку торгового оборудования напрямую. Вместо этого мы упаковываем все необходимые для чека данные в структуру и записываем ее в наш регистр:


// Функция записи чека в очередь
Процедура ДобавитьЧекВОчередь(ДокументСсылка, СтруктураПараметровЧека) Экспорт

	НоваяЗапись = РегистрыСведений.ОчередьПечатиЧеков.СоздатьМенеджерЗаписи();
	НоваяЗапись.ИдентификаторЗадачи = Новый УникальныйИдентификатор();
	НоваяЗапись.ДатаСоздания = ТекущаяДатаСеанса();
	НоваяЗапись.ДокументОснование = ДокументСсылка;
	НоваяЗапись.Статус = Перечисления.СтатусыОчередиПечати.Новый;
	
	// Помещаем структуру параметров чека в ХранилищеЗначения
	НоваяЗапись.ПараметрыЧека = Новый ХранилищеЗначения(СтруктураПараметровЧека);
	
	Попытка
		НоваяЗапись.Записать();
		ПоказатьОповещениеПользователя("Очередь ККТ", , "Чек успешно отправлен в очередь печати");
	Исключение
		ВызватьИсключение "Не удалось записать задачу в очередь печати чеков: " + ОписаниеОшибки();
	КонецПопытки;

КонецПроцедуры

Шаг 3. Реализация обработчика очереди (Регламентное задание)

На компьютере, к которому физически подключен фискальный регистратор, должен работать фоновый процесс. Это может быть регламентное задание 1С, выполняющееся под определенным пользователем, либо запущенный в режиме "Печать чеков" специальный сеанс 1С.

Рассмотрим код обработчика, который раз в 10–15 секунд опрашивает регистр:


Процедура ОбработатьОчередьПечатиЧеков() Экспорт

	// Выбираем новые задачи по порядку их поступления
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	Очередь.ИдентификаторЗадачи КАК ИдентификаторЗадачи,
		|	Очередь.ДокументОснование КАК ДокументОснование,
		|	Очередь.ПараметрыЧека КАК ПараметрыЧека
		|ИЗ
		|	РегистрСведений.ОчередьПечатиЧеков КАК Очередь
		|ГДЕ
		|	Очередь.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыОчередиПечати.Новый)
		|УПОРЯДОЧИТЬ ПО
		|	Очередь.ДатаСоздания ВОЗРАСТ";
		
	РезультатЗапроса = Запрос.Выполнить();
	Выборка = РезультатЗапроса.Выбрать();
	
	Пока Выборка.Следующий() Цикл
		
		// Изменяем статус задачи, чтобы исключить повторную обработку в параллельных потоках
		МенеджерЗаписи = РегистрыСведений.ОчередьПечатиЧеков.СоздатьМенеджерЗаписи();
		МенеджерЗаписи.ИдентификаторЗадачи = Выборка.ИдентификаторЗадачи;
		МенеджерЗаписи.Прочитать();
		
		Если МенеджерЗаписи.Выбран() Тогда
			МенеджерЗаписи.Статус = Перечисления.СтатусыОчередиПечати.ВРаботе;
			МенеджерЗаписи.Записать();
		Иначе
			Продолжить;
		КонецЕсли;
		
		// Получаем параметры чека из Хранилища Значения
		ДанныеЧека = Выборка.ПараметрыЧека.Получить();
		
		// Вызываем процедуру интеграции с БПО для непосредственной печати на ККТ
		РезультатПечати = НапечататьФискальныйЧекНаОборудовании(ДанныеЧека);
		
		МенеджерЗаписиОкончательный = РегистрыСведений.ОчередьПечатиЧеков.СоздатьМенеджерЗаписи();
		МенеджерЗаписиОкончательный.ИдентификаторЗадачи = Выборка.ИдентификаторЗадачи;
		МенеджерЗаписиОкончательный.Прочитать();
		
		Если РезультатПечати.Успех Тогда
			МенеджерЗаписиОкончательный.Статус = Перечисления.СтатусыОчередиПечати.Выполнен;
		Иначе
			МенеджерЗаписиОкончательный.Статус = Перечисления.СтатусыОчередиПечати.Ошибка;
			МенеджерЗаписиОкончательный.ОписаниеОшибки = РезультатПечати.ТекстОшибки;
		КонецЕсли;
		
		МенеджерЗаписиОкончательный.Записать();
		
	КонецЦикла;

КонецПроцедуры

Этот способ абсолютно надежен, не требует покупки стороннего ПО и работает в любых конфигурациях 1С. Однако пользователю на рабочем месте приходится ждать несколько секунд, пока регламентное задание отработает и напечатает чек.

Способ 2. Использование штатной "Очереди чеков" в современных БПО 1С

Если вы работаете на современных версиях конфигураций 1С (например, "1С:Розница 3.0", "1С:УНФ 3.0" или "1С:Бухгалтерия 3.0"), то в них уже встроен штатный механизм работы с очередью чеков. Изначально он создавался для интернет-магазинов, но отлично подходит и для интеграции обычных рабочих мест.

В Библиотеке Подключаемого Оборудования (БПО) реализована функция "ККТ в общем доступе". Настройка выполняется следующим образом:

  1. Компьютер, к которому подключена касса, объявляется сервером ККТ в настройках торгового оборудования.
  2. На других рабочих местах в настройках оборудования указывается, что ККТ подключена через сеть (указывается сетевое имя или IP-адрес основного компьютера).
  3. 1С использует стандартный регистр сведений Очередь чеков ККТ. Программа сама берет на себя блокировку портов на время печати, а кассиры отправляют команды на фискализацию документов "из коробки" без написания кода.

Способ 3. Перенос очереди на уровень драйверов (KkmServer и АТОЛ Web-Requests)

Если вы не хотите вносить изменения в конфигурацию 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-ФЗ)

Решая техническую сторону вопроса, крайне важно не нарушить требования Федерального закона № 54-ФЗ. Давайте выясним, в каких случаях одна касса на несколько рабочих мест абсолютно законна, а когда это грозит серьезными штрафами от налоговой инспекции.

Закон предъявляет жесткие требования к месту установки и процессу фискализации:

  1. Территориальное единство (один адрес): Использовать одну кассу на несколько компьютеров разрешено только в пределах одного адреса установки (один торговый зал, один офис продаж). Адрес фактического нахождения ККТ должен строго совпадать с адресом, указанным при регистрации аппарата в ФНС. Нельзя использовать одну физическую кассу, установленную в офисе, для пробития чеков в розничной точке на другом конце города.
  2. Ограничение по ИНН: Онлайн-касса регистрируется на один определенный ИНН налогоплательщика. Использовать одно физическое устройство для печати чеков от имени двух разных ИП или ООО (даже если они делят один прилавок) запрещено законом.
  3. Выдача чека покупателю: Согласно закону, бумажный чек должен быть выдан покупателю в момент расчета. Если менеджеры сидят в разных кабинетах одного здания, один из них должен будет физически сходить к принтеру ККТ, забрать бумажный чек и передать его клиенту. Альтернативный законный вариант — отправка электронного чека на email или СМС покупателя до момента расчета, если клиент выразил на это согласие.

Резюме: какой путь выбрать?

Мы проанализировали различные варианты создания очереди печати. Выбор конкретного пути зависит от специфики вашей ИТ-инфраструктуры:

← На главную