Организация автоматического пробития чеков в Розница 2.3

Продолжая делать связку Розницы 2.3 и Мобильной Кассы, завершил этап отправки пробитых чеков в МК, и дошел до этапа, когда требуется собственно автоматически пробивать чеки на кассе.

Попытка добавлять чеки в очередь прямой записью

Погуглил, ничего похожего не нашел, решил попробовать напрямую добавлять запись в регистр «Очередь чеков ККТ».

Посмотрел, пробитые чеки там присутствуют:

Создать вручную не получилось — у формы e1cib/list/РегистрСведений.ОчередьЧековККТ только просмотр:

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

После чего добавляею чек в очередь консолью кода:

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

Параметры для этого кода задаю на отдельной закладке:

Удивительно, код просто отрабатывал и ничего не делал. Потом я понял, что если стоят галочка «Показывать фискализированные», то показываются только фискализированные, а если ее убрать, то показываются новые чеки.

Однако чеки из очереди не пробились почему-то.

Попытка добавлять чек в очередь через функцию

Поиском по конфигурации я нашел готовую функцию, которая помещает чек в очередь.

Набросал код согласно своему пониманию этой проблемы:

НомерЧека = Неопределено;

СтруктураДанных = РозничныеПродажиКлиентСервер.СтруктураДанныхДляПробитияЧека();
СтруктураДанных.ЧекККМСсылка = Документ.Ссылка;
СтруктураДанных.НомерЧека = НомерЧека;
СтруктураДанных.Объект = Документ.ПолучитьОбъект();
СтруктураДанных.ЭтоВозвратПродукцииИСМПБезМарки = ложь;
СтруктураДанных.НеПечататьБумажныйЧек = ложь;

ДанныеГосИСДостаточны = истина;
	
ДанныеЧека = РозничныеПродажиСервер.ПодготовитьДанныеДляПробитияЧека(СтруктураДанных, ДанныеГосИСДостаточны);
ИдентификаторЧекаВОчереди = ОборудованиеЧекопечатающиеУстройстваВызовСервера.ДобавитьЧекВОчередьЧековККТ(ДанныеЧека);

И о чудо, чек пробился и даже получит номер чека и смены:

Финально рабочий код

Пришлось, однако, еще добавить функцию по уведомлению очереди, чтобы начиналась печать очереди:

Процедура дор_ОтправитьЧекНепосредственноВФискальнуюОчередь(ЧекСсылка, КассаККМ) Экспорт
	
	//ПараметрыКассыККМ = ЗначениеНастроекВызовСервера.ПараметрыКассыККМ(КассаККМ);
	
	СтруктураДанных = РозничныеПродажиКлиентСервер.СтруктураДанныхДляПробитияЧека();
	СтруктураДанных.ЧекККМСсылка = ЧекСсылка;
	СтруктураДанных.НомерЧека = Неопределено;
	СтруктураДанных.Объект = ЧекСсылка;
	СтруктураДанных.ЭтоВозвратПродукцииИСМПБезМарки = ложь;
	СтруктураДанных.НеПечататьБумажныйЧек = ложь;
	
	ДанныеГосИСДостаточны = истина;
	ДанныеЧека = РозничныеПродажиСервер.ПодготовитьДанныеДляПробитияЧека(СтруктураДанных, ДанныеГосИСДостаточны);
	
	//Указываем 1С, что нужно пробить чек
	ИдентификаторЧека = ОборудованиеЧекопечатающиеУстройстваВызовСервера.ДобавитьЧекВОчередьЧековККТ(ДанныеЧека);
	Если СистемаВзаимодействия.ИнформационнаяБазаЗарегистрирована() Тогда
		
		УстановитьПривилегированныйРежим(Истина);
		ИдентификаторОбсужденияСтрока = Константы.ИдентификаторОбсужденияФискализации.Получить();
		Если ЗначениеЗаполнено(ИдентификаторОбсужденияСтрока) Тогда
			ИдентификаторОбсуждения = Новый ИдентификаторОбсужденияСистемыВзаимодействия(ИдентификаторОбсужденияСтрока);
			Обсуждение = СистемаВзаимодействия.ПолучитьОбсуждение(ИдентификаторОбсуждения);
			НовоеСообщение = СистемаВзаимодействия.СоздатьСообщение(ИдентификаторОбсуждения);
			НовоеСообщение.Дата = ТекущаяДата();
			ТекстСообщения = НСтр("ru='Фискализация чека'") + Символы.НПП + ИдентификаторЧека;
			//Если Не ПустаяСтрока(ДанныеОплаты.ОрганизацияИНН) Тогда
			//	ТекстСообщения = ТекстСообщения + Символы.НПП + ДанныеОплаты.ОрганизацияИНН;
			//КонецЕсли;
			НовоеСообщение.Текст = ТекстСообщения;
			НовоеСообщение.Записать();
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

Но я столкнулся с тем, что пробитые чеки пытаются заново пробиться, т.е. очередь не очищается, выкрутился с помощью патчей.

Для модуля МенеджерОборудованияВызовСервераПереопределяемый:

&Вместо("ФискализацияЧекаВОчереди")
Процедура дор_ФискализацияЧекаВОчереди(ИдентификаторФискальнойЗаписи, ПараметрыФискализации, ОборудованиеККТ, РезультатФискализации)
	//Если чек проведен, то удаляем все проведенные чеки и не фискализируем
	Если НЕ дор_Сервер.ПроверитьКорректностьЧекаЧтоОнНеПробит(ПараметрыФискализации) Тогда 
		Возврат 
	КонецЕсли;
	ПродолжитьВызов(ИдентификаторФискальнойЗаписи, ПараметрыФискализации, ОборудованиеККТ, РезультатФискализации);
КонецПроцедуры

И для модуля ОборудованиеЧекопечатающиеУстройстваВызовСервера:

&Вместо("ЗаписатьСтатусЧекаВОчереди")
Процедура дор_ЗаписатьСтатусЧекаВОчереди(ПараметрыФискализации, СтатусЧека, ОборудованиеККТ, ТекстОшибки)
	
	//Корректируем тип значения идентификатора фискальной записи - ошибка в 1С
	
	Если ПустаяСтрока(ПараметрыФискализации.ИдентификаторФискальнойЗаписи) Тогда
		ИдентификаторЗаписи = Новый УникальныйИдентификатор;
	Иначе
		ИдентификаторЗаписи = ПараметрыФискализации.ИдентификаторФискальнойЗаписи;
	КонецЕсли;
	
	ПараметрыФискализации.Вставить("ИдентификаторФискальнойЗаписи", Строка(ИдентификаторЗаписи));

	
	Если НЕ дор_Сервер.ПроверитьКорректностьЧекаЧтоОнНеПробит(ПараметрыФискализации) Тогда 
		Возврат 
	КонецЕсли;
	
	ПродолжитьВызов(ПараметрыФискализации, СтатусЧека, ОборудованиеККТ, ТекстОшибки);
	
КонецПроцедуры

И для модуля ОборудованиеЧекопечатающиеУстройстваКлиент (думаю, достаточно было только здесь поставить проверку):


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

	ПродолжитьВызов(ОповещениеПриЗавершении, ИдентификаторКлиента, ИдентификаторУстройства, ПараметрыОперации, ДополнительныеПараметры);
КонецПроцедуры

Сама функция по проверке фискализации еще и удаляет все пробитые чеки из очереди:

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

Среда: 1С:Розница (2.3.10.61), 1С:Мобильная касса (для разработчиков), редакция 3 (3.14.7.0)
Объем: 3 час

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

комментария 3

  1. Иван:

    Добрый день, столкнулся с такой же задачей, что описана здесь. Повторил код (переделав его под УНФ), но чеки не пробиваются, только добавляются в регистр в статусе «Новый».
    Подскажите, пожалуйста, нужно ли что-то включать (кроме обсуждений) или настраивать в базе для того, чтобы чеки автоматически фискализировались?

    • Я давно уже не занимался этой темой.
      Но рекомендую все те же способы — пробить чек, в замерах производительности посмотреть, что происходит.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *