Использование Универсального транспортного модуля ГИИС ДМДК в розничной торговле ювелирными изделиями

18.04.23

Интеграция - Обмен с ГосИС

Универсальный транспортный модуль "Государственная интегрированная информационная система "Драгоценные металлы и драгоценные камни". Разбор руководства программиста. Практическое использование регистрации розничных продаж ювелирных изделий.

Предлагаю на разбор появившееся в апреле Руководство программиста "Транспортный модуль" на сайте ГИИС ДМДК.

На сегодняшний день мы используем для регистрации списания в архив Ювелирных изделий методами SendBatchSale / CheckBatchSale. Для них необходимы параметры Номера фискального накопителя ККМ, Номера фискального документа ККМ и Дата фискального документа (без часов, минут и секунд) и собственно УИН Ювелирного изделия.

Если кому интересно, смотрите публикацию № 1522396. Там описаны способы получения параметров ККМ.

УТМ ГИИС ДМДК предполагает использование тех же параметров, плюс еще один - Номер смены ККМ:

/// Получить реквизиты чека ККМ для ГИИС ДМДК ////////////////////////////////////////////////////////////
					  Попытка  
						  
						    // Запрос информации о последнем чеке 
							
						    ECR.setParam(ECR.LIBFPTR_PARAM_FN_DATA_TYPE, ECR.LIBFPTR_FNDT_LAST_DOCUMENT);
							ECR.fnQueryData();

							ФискальныйДокумент  = ECR.getParamInt(ECR.LIBFPTR_PARAM_DOCUMENT_NUMBER);
							Сообщить("Номер Фискального Документа : " + ФискальныйДокумент);

							ФискальныйПризнакДокумента     = ECR.getParamString(ECR.LIBFPTR_PARAM_FISCAL_SIGN);  
							Сообщить("Фискальный признак документа : " + ФискальныйПризнакДокумента);

							ДатаФискальногоДокумента  = ECR.getParamDateTime(ECR.LIBFPTR_PARAM_DATE_TIME); 
						    Сообщить("Дата фискального документа : " + ДатаФискальногоДокумента);
							
							// Запрос информации о номере фискального накопителя
							
						    ECR.setParam(ECR.LIBFPTR_PARAM_FN_DATA_TYPE, ECR.LIBFPTR_FNDT_FN_INFO);
						    ECR.fnQueryData();

						    ФискальныйНакопитель      = ECR.getParamString(ECR.LIBFPTR_PARAM_SERIAL_NUMBER);
							Сообщить("Номер Фискального Накопителя : " + ФискальныйНакопитель);     
							
							// Запрос информации о номере смены
							ECR.setParam(ECR.LIBFPTR_PARAM_FN_DATA_TYPE, ECR.LIBFPTR_FNDT_SHIFT);
						    ECR.fnQueryData();

						    НомерСмены      = ECR.getParamInt(ECR.LIBFPTR_PARAM_SHIFT_NUMBER);
							Сообщить("Номер смены : " + НомерСмены); 
							
							
						Исключение      
							Сообщение = Новый СообщениеПользователю;
			                Сообщение.Текст = "Ошибка сохранения реквизитов ФД : " + ОписаниеОшибки();
			                Сообщение.Сообщить();
					  КонецПопытки;	  
					  /// Получить реквизиты чека ККМ для ГИИС ДМДК ////////////////////////////////////////////////////////////

 

Сформировать XML файл для УТМ значительно проще, чем для сервиса интеграции запрос SendBatchSale. И подписывать файл ЭП не нужно, т.е. для ККМ не потребуется флешка ЭЦП. 

Что понадобится для запуска УТМ:

1. Установка и настройка УТМ, тут вроде все понятно из руководства. Может на практике и будут сложности, пока не знаю, не устанавливал. 

2. Формирование XML файла - приводить текст формирования не буду, товарные программы у всех разные. Я пошел по пути "шаблона", см. скрин, примерно так:

СписокТовара = ЭлементДокумент.Список;
СтрокаТовары = "";
	Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл  
		Если СтрДлина(ТекСтрокаСписок.УИН) = 16 Тогда   
			 ЦенаТовара = Формат(ТекСтрокаСписок.Наличными + ТекСтрокаСписок.Безналичными + ТекСтрокаСписок.Кредитом,"ЧГ=; ЧДЦ=2");
			 СтрокаТовары = СтрокаТовары
			 + "<Bottle barcode=" 
			 + """ + ТекСтрокаСписок.УИН + """ 
			 + " price=" 
			 + """ + ЦенаТовара + """ 
			 + "/>"
			 + Символы.ПС;  
		КонецЕсли;	   
	КонецЦикла;	  
Сообщение = СтрЗаменить(Сообщение, "%<Bottleprice=barcode=/>%", СтрокаТовары);

3. Выполнить командой curl отправку сформированного файла чека (http запрос). Вот тут я долго вникал в руководство, и не сразу понял, что главный недостаток в описании - это получение ответа от УТМ в командную строку,  т.е. по сути мы не получаем ничего. Предлагаю следующее:

// создаем папку ответов от УТМ, номера файлов ответов можно нумеровать, скажем otvet1.xml, otvet2.xml ...
// параметр -o команды curl позволяет записать ответ запроса -F в файл 

ПутьКФайлуОтвета = "C:\УТМответ\otvet.xml"

СтрокаКоманды = ""curl -F "xml_file=@cheque.xml" http://localhost:8383/xml"";
СтрокаКоманды = СтрокаКоманды + " -o " +  ПутьКФайлуОтвета;

ЗапуститьПриложение(СтрокаКоманды);

  

4. Разбор полученного ответа. Если ответ "положительный" - имеем ввиду, что УИН ушел в архив и чек ККМ пробивается уже без изменений.

Критикуйте. Может, кто предложит свой вариант, например HTTPЗапрос средствами 1С, чем сейчас и занимаюсь.   

Интеграция 1С с ГИИС ДМДК

Работа с ГИИС ДМДК в 1С:УТ11, КА2, ERP, УНФ, Бухгалтерия 3, Розница и др. Загрузка партий изделий, создание карточек номенклатуры по данным ГИИС ДМДК. Создание документов поступления, документов инвентаризации с учетными данными ГИИС ДМДК и многое другое. Возможна доработка под любые конфигурации!


ГИИС ДМДК информационная интегрированная государственная система

См. также

Обмен с ГосИС Бюджетный учет Регламентированный учет и отчетность Бухгалтер Пользователь Платформа 1С v8.3 1С:Бухгалтерия 3.0 1С:Управление холдингом Химическая промышленность Государственные, бюджетные структуры Электротехника и микроэлектроника Машиностроение и приборостроение Металлургическая промышленность Россия Бухгалтерский учет Бюджетный учет Платные (руб)

Раздельный учет гособоронзаказа в 1С: Отчеты по исполнению госконтрактов, расчетно-калькуляционные материалы и контроль операций для исполнения в срок в 1С: Бухгалтерия 3.0 и Управление Холдингом 3.2. Простая настройка и полное соответствие законодательству. Профессиональный консалтинг и регулярные обновления продукта.

44000 руб.

28.08.2020    369892    2498    137    

1088

Обмен с ГосИС Бухгалтер Пользователь 8.3.14 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Ювелирная промышленность и торговля Россия Управленческий учет Платные (руб)

Интеграция для работы 1С с ГИИС ДМДК. Государственная интегрированная информационная система в сфере контроля за оборотом драгоценных металлов, драгоценных камней и изделий из них на всех этапах этого оборота.

65000 руб.

12.04.2022    18815    160    34    

41

Бюджетный учет Обмен с ГосИС Бухгалтер Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Государственные, бюджетные структуры Россия Бухгалтерский учет Платные (руб)

Доработка конфигурации 1С:Бухгалтерия предприятия, редакция 3.0. реализована в виде расширения. Предназначена для ведения раздельного учета и автоматизации заполнения отчетности исполнения контрактов ГОЗ в конфигурациях 1С БП КОРП, ПРОФ, Базовая, БИТ.ФИНАНС.

55200 руб.

16.08.2019    94077    257    89    

151

Оптовая торговля Производство готовой продукции (работ, услуг) Обмен с ГосИС Программист Бухгалтер Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 1.6 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Оптовая торговля, дистрибуция, логистика Пищевая промышленность Россия Бухгалтерский учет Платные (руб)

Автоматический обмен данными с системой ФГИС Меркурий из 1С через ВетИС API: загрузка данных по хозяйствующим субъектам, предприятиям; типов, групп, видов, наименований продукции, сопоставление данных и запись их в базу данных; создание на основании расходных документов транспортных партий, отправка на сервер, печать полученных ветеринарных свидетельств, запрос остатков складского журнала, проведение инвентаризаций, оформление производственных партий.

11500 руб.

08.12.2017    106046    291    110    

147

Оптовая торговля Розничная торговля Обмен с ГосИС Бухгалтер Платформа 1С v8.3 1С:Управление торговлей 10 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Розничная и сетевая торговля (FMCG) Оптовая торговля, дистрибуция, логистика Рестораны, кафе и фаст-фуд Россия Бухгалтерский учет Управленческий учет Акцизы Платные (руб)

Автоматизация учета ЕГАИС в 1С для оптовой торговли, производства и импорта. Получение и отправка ТТН, отправка акта о постановке на баланс и акта о списании. Получение остатков. Загрузка и сопоставление номенклатуры и контрагентов. Оправка в ЕГАИС отчетов о производстве и импорте.

828 руб.

15.12.2015    172674    864    370    

407

Обмен с ГосИС Бухгалтер Платформа 1С v8.3 Бухгалтерский учет 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Комплексная автоматизация 2.х Россия Бухгалтерский учет Платные (руб)

Обработка для обмена платежными документами в формате xml для системы Федерального казначейства "Электронный бюджет" из конфигураций 1С. Поставляется для БП 3.0 Работа только с контрагентами. Сайт "Электронного Бюджета": https://www.budget.gov.ru/

19200 руб.

14.10.2020    64457    392    103    

324

Обмен с ГосИС Программист Пользователь Платформа 1С v8.3 1С:Розница 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Россия Платные (руб)

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

6540 руб.

09.01.2024    6320    81    21    

83

Обмен с ГосИС Программист Платформа 1С v8.3 1C:Бухгалтерия Оптовая торговля, дистрибуция, логистика Россия Управленческий учет Платные (руб)

Универсальная конфигурация ХамелеонЗерно для взаимодействия с системой ФГИС Зерно (тестовый+рабочий контур) может использоваться для интеграции в любую конфигурацию на базе 1С, версии ПРОФ и выше. Работа через API 1.0.7 и на API 1.0.8. Для удобства реализован общий интерфейс в виде обработки, схожей с интерфейсом ФГИС Зерно, но возможностей гораздо больше, т.к. при интеграции в Вашу учетную систему, можно на основании Ваших справочников и документов, создавать соответствующие документы и справочники в системе ФГИС Зерно и наоборот.

6000 руб.

27.06.2023    5062    20    2    

17
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. guglion 3 28.04.23 09:39 Сейчас в теме
Ну думаю, что то вот такое должно работать непосредственно из 1С

Процедура ПрочитатьОтвет(СтрокаОтвета)
// разбираем полученый ответ
// скорее всего он придет не как показано в описании, а одной строй, без символов переноса
// это на основанни, что все ответы "Сheck" их ДМДК приходят одной строкой
МассивОтвета = Новый Массив();
МассивОтвета = ИзСтрокиВМассив(СтрокаОтвета, "><");

// либо ИзСтрокиВМассив(СтрокаОтвета, ">" + Символы.ПС+"<"); если ответ будет с сиволами переноса 

// анализировать массив  МассивОтвета думаю лучше простым перебором строк, без XML разбора, так как файл буквально на пять стро

Для Каждого ЭлементМассива ИЗ МассивОтвета Цикл
        // все приводить не буду, только "положительную строку"
        Если СтрНайти(ЭлементМассива, "<sign>") > 0 Тогда
                  // xml содержит тэг sign - подпись ГИИС о успешном ответе
        КонецЕсли;
КонецЦикла

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

Функция ИзСтрокиВМассив(НачальнаяСтрока,Разделитель) экспорт
    
    СтрокаПреобразованнаяВМногострочныйТекст     = СтрЗаменить(НачальнаяСтрока,Разделитель,Символы.ПС);
    ТекстовыйДокументИзСтроки                                   = Новый ТекстовыйДокумент;
    Результат                                                                       = Новый Массив;
    ТекстовыйДокументИзСтроки.УстановитьТекст(СтрокаПреобразованнаяВМногострочныйТекст);
    Для СчетчикСтрок = 1 по ТекстовыйДокументИзСтроки.КоличествоСтрок() цикл
        Результат.Добавить(СокрЛП(ТекстовыйДокументИзСтроки.ПолучитьСтроку(СчетчикСтрок));
    КонецЦикла;
    Возврат Результат;
    
КонецФункции

...

// Сообщение - это наш подготовленный запрос на УТМ. Например:
//?xml version="1.0" encoding="UTF-8"?>
//<Cheque
//shift="1"
//number="2"
//name="ИП Иванов"
//address="Россия,117105,Москва Г"
//kassa="93030781125555110367"
//kpp="781301001"
//datetime="0308221103"
//inn="7813252159">
//<Bottle price="2550.00" barcode="6432200004560697"/>
//</Cheque>

Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "text/xml;charset=UTF-8");

Соединение = Новый HTTPСоединение("http://localhost:8383/xml");

HTTPЗапрос = Новый HTTPЗапрос("/" + ПараметрыВыполнения.ИмяМетода,Заголовки);
HTTPЗапрос.УстановитьТелоИзСтроки(Сообщение);

Результат = Соединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
//
Если Результат.КодСостояния = 200 Тогда
		
	ПрочитатьОтвет(Результат.ПолучитьТелоКакСтроку());
		
КонецЕсли;
...
Показать
2. guglion 3 02.05.23 05:20 Сейчас в теме
Есть также серьезный вопрос к ГИИС ДМДК. Вышла вторая редакция руководства программиста УТМ и в нем ни слова о КПП индивидуального предпринимателя. УТМ изначально написан для алкоголя, в алкогольной торговле нет ИП, там все юр. лица, соответственно проблема не стоит. Есть вероятность, что УТМ для ИП вообще не будет работать.
3. guglion 3 03.05.23 11:31 Сейчас в теме
Вариантов к сожалению как оказывается масса, редактирую сообщение (1):
при этом руководствуюсь текстом отправки в ГИИС ДМДК сообщений из БСП 3.1.5, которая однозначно работает и позволяет надеяться, что сработает и с УТМ

// Содержит Истина при положительном ответе, Ложь при ошибке

Перем ОтветОтУТМПоложительный Экспорт;

Процедура ПрочитатьОтвет(СтрокаОтвета)
// разбираем полученый ответ
// скорее всего он придет не как показано в описании, а одной строй, без символов переноса
// это на основанни, что все ответы "Сheck" их ДМДК приходят одной строкой
МассивОтвета = Новый Массив();
МассивОтвета = ИзСтрокиВМассив(СтрокаОтвета, "><");

// либо ИзСтрокиВМассив(СтрокаОтвета, ">" + Символы.ПС+"<"); если ответ будет с сиволами переноса 

// анализировать массив  МассивОтвета думаю лучше простым перебором строк, без XML разбора, так как файл буквально на пять стро

ОтветОтУТМПоложительный = Ложь;
Для Каждого ЭлементМассива ИЗ МассивОтвета Цикл
        // все приводить не буду, только "положительную строку"
        Если СтрЧислоВхождений(ЭлементМассива, "<sign>") > 0 Тогда
                  // xml содержит тэг sign - подпись ГИИС о успешном ответе 
				  ОтветОтУТМПоложительный = Истина;
				  Перейти ~ВыходИзЦикла;   
			  ИначеЕсли СтрЧислоВхождений(ЭлементМассива, "<error>") > 0 Тогда
				  // вывести сообщение об ошибке    
				  // пока просто в формате текста
				  // скорее всего этот текст нужно будет сохранять на всякий случай в отдельном журнале обмена с УТМ
        КонецЕсли;
КонецЦикла;
~ВыходИзЦикла:

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

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

// Сообщение - это наш подготовленный запрос на УТМ. Например:
//?xml version="1.0" encoding="UTF-8"?>
//<Cheque
//shift="1"
//number="2"
//name="ИП Иванов"
//address="Россия,117105,Москва Г"
//kassa="93030781125555110367"
//kpp="781301001"
//datetime="0308221103"
//inn="7813252159">
//<Bottle price="2550.00" barcode="6432200004560697"/>
//</Cheque>

Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "text/xml;charset=UTF-8");
					  
// Константа АдресДляСообщенийУТМ = http://localhost:8383/xml
					  
Соединение = Новый HTTPСоединение(СокрЛП(Константы.АдресДляСообщенийУТМ.Получить()));

HTTPЗапрос = Новый HTTPЗапрос;
HTTPЗапрос.Заголовки = Заголовки;
HTTPЗапрос.УстановитьТелоИзСтроки(Сообщение,КодировкаТекста.UTF8);

Результат = Соединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
						
Если Результат.КодСостояния = 200 Тогда 
	ПрочитатьОтвет(Результат.ПолучитьТелоКакСтроку());
КонецЕсли;
Показать
4. grafit 8 17.05.24 07:52 Сейчас в теме
Удалось отправить через ТМ реальную продажу. Чек отразился в списке.
К примеру, на левый УИН ответ такой -
<?xml version="1.0" encoding="UTF-8" standalone="no"?><A><ver>2</ver><error>Партия не зарегистрирована: 6432400130000000</error></A>
Если с УИНом все в порядке, то ответ пустой.
5. hombre 14 20.08.24 08:47 Сейчас в теме
(4) Добрый день! Подскажите пожалуйста, что вы указывали в заголовках запроса. Выполняли ли авторизацию? Нужно ли после установки ТМ что-то в нем настраивать?
6. grafit 8 20.08.24 10:43 Сейчас в теме
К ТМ есть инструкция, где, как и чего надо скачать, прописать, настроить.
Авторизация там по умолчанию Admin, Admin. Нужно сертификаты скачать, установить. ОГРН,ИНН и ключ ТОПа (торговой точки). Ключ формируется в ЛК ДМДК, создается ТОП и для него ключ.
В файле конфигурации conf.env в каталоге C:\TMDMDK прописывается тестовый контур.

Заголовки
РазделительСтрок = Символы.ВК + Символы.ПС;
Разделитель = "----" + СтрЗаменить(Новый УникальныйИдентификатор, "-", "");

Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Разделитель);
Прикрепленные файлы:
12. guglion 3 08.10.24 03:35 Сейчас в теме
(6) Да надо подумать над вашим комментарием. Самое главное что я понял - если городить HTTP нужно отправлять именной файл! Тело сообщения в виде строки как обычно не пройдет. Только файл.
7. guglion 3 08.10.24 03:22 Сейчас в теме
Ну в общем прилагаю свои общие наработки для любой программы 1с.

Выделю главное

- реквизит "Закончить продажу при отрицательном ответе УТМ" - предполагаю когда все активно начнут использовать УТМ (это 1 марта 2025 года) будут проблемы. Даже если будет отрицательный ответ УТМ ККМ чек пробьет, потом его разносим методом SendBatchSale / CheckBatchSale (пока его не прикроют)

- реквизит "Тестовый режим УТМ" - файл XML формируется но не отправляется. Это просто для отработки корректности составления XML. Запросы в УТМ и ответы из УТМ предлагаю сохранять - документ в конфигурации "Журнал событий УТМ".
Прикрепленные файлы:
8. guglion 3 08.10.24 03:29 Сейчас в теме
Процедура получения данных чека для УТМ (для драйвера АТОЛ) . Обратите внимание - к фискальным документам относятся "Открыть смену", "Чек прихода/Чек возврата прихода", "Закрыть смену". Если у вас смена отрывается вместе с пробитием первого чека ККМ то к номеру смены и номеру фискального документа добавляем 1. В 1С есть проблема - она сама пытается вести за ККМ реквизиты фискальных документов, и может возникнуть ситуация рассинхронизации данных между 1С и ККМ - выражается это в основном в невозможности открыть или закрыть смену. Поэтому это все сразу убираем - данные получаем только из КММ.
9. guglion 3 08.10.24 03:30 Сейчас в теме
// Переменные реквизитов чека для ГИИС
Перем ФискальныйНакопитель  Экспорт;
Перем ФискальныйДокумент    Экспорт;
Перем ФискальныйПризнакДокумента Экспорт;
Перем ДатаФискальногоДокумента   Экспорт; 
Перем НомерСмены                 Экспорт;

//// Переменная УТМ
Перем ОтветОтУТМПоложительный    Экспорт;     
Перем ТекстОшибкиПередачиВУТМ    Экспорт; 

//#Область ПроцедурыДляУТМ
// Функция проверки - есть ли в чеке товары с УИН 
Функция ЧекСодержитУИН(ЭлементДокумент)
	    ВЧекеЕстьУИН = Ложь;
		СписокТовара = ЭлементДокумент.Список;
		Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл  
			Если СтрДлина(ТекСтрокаСписок.УИН) = 16 Тогда 
				 ВЧекеЕстьУИН = Истина;
			КонецЕсли;	
		КонецЦикла;
		Возврат ВЧекеЕстьУИН;
КонецФункции   

// Процедура получает информацию о последнем чеке и записывает значения переменных:
// для последующего чека, при этом НомерДокумента увеличивается на 1, и если смена новая, то НомерСмены увеличивается на 1 
Процедура ЗапросИнформацииОПоследнемЧеке()       
	                // Получить реквизиты чека ККМ для ГИИС ДМДК ////////////////////////////////////////////////////////////­ 
	                // Запрос информации о последнем документе  (открыти смены, чек и закрытие смены - это все фискальные документы) 
					// поэтому получаем информацию о последнем документе, а не чеке
					Попытка						    
							ECR.setParam(ECR.LIBFPTR_PARAM_FN_DATA_TYPE, ECR.LIBFPTR_FNDT_LAST_DOCUMENT);
							ECR.fnQueryData();

							ФискальныйДокумент  = ECR.getParamInt(ECR.LIBFPTR_PARAM_DOCUMENT_NUMBER);
							// Добавляем единицу, так как документ будет с следующим номером
							ФискальныйДокумент  = ФискальныйДокумент + 1;

							// ДатаФискальногоДокумента  = ECR.getParamDateTime(ECR.LIBFPTR_PARAM_DATE_TIME);   
							// Дату можно пропустить. Она все равно будет ТекущаяДата().   
							
							// Запрос информации о номере фискального накопителя	
						    ECR.setParam(ECR.LIBFPTR_PARAM_FN_DATA_TYPE, ECR.LIBFPTR_FNDT_FN_INFO);
						    ECR.fnQueryData();
						    ФискальныйНакопитель      = ECR.getParamString(ECR.LIBFPTR_PARAM_SERIAL_NUMBER);
    	
							// Запрос информации о смене
							ECR.setParam(ECR.LIBFPTR_PARAM_DATA_TYPE, ECR.LIBFPTR_DT_SHIFT_STATE);
                            ECR.queryData();

                            СостояниеСмены       = ECR.getParamInt(ECR.LIBFPTR_PARAM_SHIFT_STATE);
							НомерСмены           = ECR.getParamInt(ECR.LIBFPTR_PARAM_SHIFT_NUMBER);
							
							Если СостояниеСмены = ECR.LIBFPTR_SS_CLOSED Тогда
								 //Смена закрыта, следующий фискальный чек откроет смену, номер фискального документа увеличим еще на еденицу
								 НомерСмены = НомерСмены + 1; 
								 ФискальныйДокумент  = ФискальныйДокумент + 1;
							КонецЕсли;	   
								
						Исключение                        
							// Устанавливаем переменную положительного ответа от УТМ в "Ложь", так как на этапе произошла ошибка 
	                        ОтветОтУТМПоложительный = Ложь;  
							ТекстОшибкиПередачиВУТМ = "Ошибка на этапе №1 получения данных Фискального документа";
						    	
							Сообщение = Новый СообщениеПользователю;
			                Сообщение.Текст = "Ошибка получения реквизитов ФД : " + ОписаниеОшибки(); 
			                Сообщение.Сообщить();
							
							// Записать ошибку формирования данных чека в переменную
							ОшибкаПолученияДанныхОПоследнемЧеке = "Ошибка получения реквизитов ФД : " + ОписаниеОшибки();
							
					   КонецПопытки;	
					  /// Получить реквизиты чека ККМ для ГИИС ДМДК ////////////////////////////////////////////////////////////­
КонецПроцедуры	            

Процедура ПрочитатьОтвет(СтрокаОтвета)
// разбираем полученый ответ
// скорее всего он придет не как показано в описании, а одной строй, без символов переноса
// это на основании, что все ответы "Сheck" их ДМДК приходят одной строкой
МассивОтвета = Новый Массив();
МассивОтвета = ИзСтрокиВМассив(СтрокаОтвета, "><");

// либо ИзСтрокиВМассив(СтрокаОтвета, ">" + Символы.ПС+"<"); если ответ будет с символами переноса 

// анализировать массив  МассивОтвета думаю лучше простым перебором строк, без XML разбора, так как файл буквально на пять стро

ОтветОтУТМПоложительный = Ложь;
Для Каждого ЭлементМассива ИЗ МассивОтвета Цикл
        // все приводить не буду, только "положительную строку"
        Если СтрЧислоВхождений(ЭлементМассива, "<sign>") > 0 Тогда
                  // xml содержит тэг sign - подпись ГИИС о успешном ответе 
				  ОтветОтУТМПоложительный = Истина;
				  Перейти ~ВыходИзЦикла;   
			  ИначеЕсли СтрЧислоВхождений(ЭлементМассива, "<error>") > 0 Тогда
				  // вывести сообщение об ошибке    
				  // пока просто в формате текста
				  // скорее всего этот текст нужно будет сохранять на всякий случай в отдельном журнале обмена с УТМ
				  ФормаОшибкиУТМ = Документы.ЧекиПродаж.ПолучитьФорму("ФормаСообщенияОбОшибкеУТМ"); 
	              ЭлементФ    = ФормаОшибкиУТМ.ЭлементыФормы.Найти("ПолеОшибки");
	              ЭлементФ.Значение = СтрокаОтвета; 
				  ФормаОшибкиУТМ.ОткрытьМодально();
        КонецЕсли;
КонецЦикла;
~ВыходИзЦикла:

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

Функция ИзСтрокиВМассив(НачальнаяСтрока,Разделитель)
    
    СтрокаПреобразованнаяВМногострочныйТекст     = СтрЗаменить(НачальнаяСтрока,Разделитель,Символы.ПС);
    ТекстовыйДокументИзСтроки                    = Новый ТекстовыйДокумент;
    Результат                                    = Новый Массив;
    ТекстовыйДокументИзСтроки.УстановитьТекст(СтрокаПреобразованнаяВМногострочныйТекст);
    Для СчетчикСтрок = 1 по ТекстовыйДокументИзСтроки.КоличествоСтрок() цикл
        Результат.Добавить(СокрЛП(ТекстовыйДокументИзСтроки.ПолучитьСтроку(СчетчикСтрок)));
    КонецЦикла;
    Возврат Результат;
    
КонецФункции
Показать
10. guglion 3 08.10.24 03:32 Сейчас в теме
Следующий код - решайте сами как его вставить, думаю он интуитивно понятен. И самое главное проверен - работает.
11. guglion 3 08.10.24 03:32 Сейчас в теме
//#Область ФормированиеЗапросаВУТМ
   ////////////////////// ВСТАВКА ФОРМИРОВАНИЯ ЗАПРОСА ДЛЯ ПЕРЕДАЧИ В ГИИС ДМДК, ПОЛУЧЕНИЯ ОТВЕТА ////////////////////////////////////////////////////////////­/////////////////  
   //1. Передавать запросы в УТМ установлено в Истина 
   //2. фискальный регистратор включен
   //3. Версия драйвера ККМ = 10
   //4. В чеке есть УИН
   //5. Есть оплата наличными или безналичными    
   // Для проведения тестирования:
   // из следующей строки необходимо исключить условие для проведения тестирования программы  - 
   // И Константы.ФискальныйРегистраторВключен.Получить() = Истина И глНомерВерсииДрайвераККМ = 10
   Если (Константы.ПередаватьЗапросыВУТМ.Получить() = Истина И Константы.ФискальныйРегистраторВключен.Получить() = Истина И глНомерВерсииДрайвераККМ = 10 И ЧекСодержитУИН(ЭлементДокумент) И (ЧекНаличными > 0 ИЛИ ЧекБезналичными > 0)) ИЛИ (Константы.ПередаватьЗапросыВУТМ.Получить() = Истина И ЧекСодержитУИН(ЭлементДокумент) И (ЧекНаличными > 0 ИЛИ ЧекБезналичными > 0) И (Константы.ТестовыйРежимУТМ.Получить()=Истина)) Тогда       
	   
	                  // Устанавливаем переменную положительного ответа от УТМ в "Истина" 
	                  ОтветОтУТМПоложительный = Истина;
					  ТекстОшибкиПередачиВУТМ = "";
					  
	                  // Получаем шаблон сообщения		              
					  Сообщение = Константы.КонвертУТМ.Получить();
					  
					  // 1. Сформировать реквизиты чека еще до его пробития (номер ФН, ФД, ДатаФД, НомерСмены) 
					  ОшибкаПолученияДанныхОПоследнемЧеке = "";
					  Если Константы.ТестовыйРежимУТМ.Получить()=Истина Тогда
						     Попытка
						   	    ЗапросИнформацииОПоследнемЧеке(); 
						     Исключение	  
						            
							 КонецПопытки;	
							 Если ФискальныйНакопитель = "" И ФискальныйДокумент = 0 И НомерСмены = 0 Тогда 
								 ФискальныйДокумент = 1;
                                 ФискальныйНакопитель = "1";
                                 НомерСмены = 1;
							 КонецЕсли;	 
                      Иначе
		                      ЗапросИнформацииОПоследнемЧеке();
					  КонецЕсли;
					  
					  Если СтрДлина(ОшибкаПолученияДанныхОПоследнемЧеке) > 0 Тогда
						   ЭлементДокумент.ОшибкаФормированияДанныхЧека = ОшибкаПолученияДанныхОПоследнемЧеке;
						   ЭлементДокумент.Записать();
					  КонецЕсли;	  
					  
						  
						  // 2. Заполняем шаблон сообщения
						  Сообщение = СтрЗаменить(Сообщение, "%shift%",  """" + СтрЗаменить(Строка(НомерСмены),Символы.НПП,"") + """");   
						  Сообщение = СтрЗаменить(Сообщение, "%number%", """" + СтрЗаменить(Строка(ФискальныйДокумент),Символы.НПП,"") + """");      
						  ЭлементОрганизацияПоУмолчанию = Справочники.Организации.НайтиПоРеквизиту("ПоУмолчанию", Истина); 
						  НаименованиеОрганизации = СокрЛП(ЭлементОрганизацияПоУмолчанию.Имя);
						  Сообщение = СтрЗаменить(Сообщение, "%name%", """" + ВРЕГ(НаименованиеОрганизации) + """"); 
						  ЭлементМагазинСкладПоУмолчанию = Справочники.Магазины.НайтиПоРеквизиту("ПоУмолчанию", Истина);
						  АдресМагазина = СокрЛП(ЭлементМагазинСкладПоУмолчанию.АдресДляУТМ);
						  Сообщение = СтрЗаменить(Сообщение, "%address%", """" + ВРЕГ(АдресМагазина) + """");
						  Сообщение = СтрЗаменить(Сообщение, "%kassa%", """" + ФискальныйНакопитель + """"); 
						  КППОрганизации = СокрЛП(ЭлементОрганизацияПоУмолчанию.Кпп);   
						  Если СтрДлина(КППОрганизации) = 9 Тогда
						       Сообщение = СтрЗаменить(Сообщение, "%kpp%", """" + КППОрганизации + """"); 
						   Иначе
							   Сообщение = СтрЗаменить(Сообщение, "kpp=%kpp%", "");
						  КонецЕсли;	   
						  ТекущаяДатаИВремя = ТекущаяДата();  
						  Если День(ТекущаяДатаИВремя)<10 Тогда
						       ДатаИВремя = "0"+Строка(День(ТекущаяДатаИВремя));
						   Иначе
							   ДатаИВремя = Строка(День(ТекущаяДатаИВремя));
						  КонецЕсли;	   
						  Если Месяц(ТекущаяДатаИВремя)<10 Тогда
						       ДатаИВремя = ДатаИВремя+"0"+Строка(Месяц(ТекущаяДатаИВремя));
						   Иначе
							   ДатаИВремя = ДатаИВремя+Строка(Месяц(ТекущаяДатаИВремя));
						  КонецЕсли;                               
						  ДатаИВремя = ДатаИВремя + Строка(ГОД(ТекущаяДатаИВремя)-2000);
						  Если Час(ТекущаяДатаИВремя)<10 Тогда
						       ДатаИВремя = ДатаИВремя+"0"+Строка(Час(ТекущаяДатаИВремя));
						   Иначе
							   ДатаИВремя = ДатаИВремя+Строка(Час(ТекущаяДатаИВремя));
						  КонецЕсли;
						  Если Минута(ТекущаяДатаИВремя)<10 Тогда
						       ДатаИВремя = ДатаИВремя+"0"+Строка(Минута(ТекущаяДатаИВремя));
						   Иначе
							   ДатаИВремя = ДатаИВремя+Строка(Минута(ТекущаяДатаИВремя));
						  КонецЕсли;                                
						  Сообщение = СтрЗаменить(Сообщение, "%datetime%", """" + ДатаИВремя + """"); 
						  ИННОрганизации = СокрЛП(ЭлементОрганизацияПоУмолчанию.Инн);
						  Сообщение = СтрЗаменить(Сообщение, "%inn%", """" + ИННОрганизации + """"); 
						  
						  СписокТовара = ЭлементДокумент.Список;
						  СтрокаТовары = "";     
						  ЭтоПервыйУИН = Истина;
						  Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл  
							  Если СтрДлина(ТекСтрокаСписок.УИН) = 16 Тогда   
								   ЦенаТовара = Формат(ТекСтрокаСписок.Наличными + ТекСтрокаСписок.Безналичными + ТекСтрокаСписок.Кредитом,"ЧГ=; ЧДЦ=2");    
								   ЦенаТовара = СтрЗаменить(ЦенаТовара, ",", "."); 
								   Если ЭтоПервыйУИН = Ложь Тогда 
									    СтрокаТовары = СтрокаТовары + Символы.ПС; 
								   КонецЕсли;	   
								   СтрокаТовары = СтрокаТовары + "<Bottle price=" + """" + ЦенаТовара + """" + "  barcode=" + """" + ТекСтрокаСписок.УИН + """" + "/>";    
								   ЭтоПервыйУИН = Ложь;
							  КонецЕсли;	   
						  КонецЦикла;	  
	                      Сообщение = СтрЗаменить(Сообщение, "%<Bottle price=barcode=/>%", СтрокаТовары);
						  ЭлементДокумент.ЗапросНаУТМ = Сообщение;
						  ЭлементДокумент.Записать();     
 					  
		// 3. передать HTTP запрос в ГИИС ДМДК - тут пока тормознем, надо рещить делать это с помощью cUrl или HTTP запросом     
		// пока текст пишем для HTTP запроса, так как его использование позволяет обойтись без громоздкой файловой системы cUrl  
		
		// тут вариантов масса к сожалению, надо искать тот самый		
		Если Константы.ИспользоватьcUrl.Получить() = Ложь Тогда
			          // используем методы http запросов 1С
					  // передать нужно именно файл - информация их ЕГАИС по алкоголю
					  // сделаем из Сообщения xml файл
					  
					  ИмяФайлаОтправки = ПолучитьимяВременногоФайла("xml");
 
                      ОбъектXML = Новый ЗаписьXML;
                      ОбъектXML.ОткрытьФайл(ИмяФайлаОтправки, "UTF-8");
                      ОбъектXML.ЗаписатьОбъявлениеXML();
                      ОбъектXML.ЗаписатьБезОбработки(Сообщение);
                      ОбъектXML.Закрыть();       
					  
					  // сделаем из Сообщения xml файл  
					  
					  // ИмяВыходногоФайла = ПолучитьимяВременногоФайла("xml");  // наш сервер возвращает ответы в виде XML - может и не надо
					                                                             // может стоить получить результат как строку
					  
					  ФайлОтправки = Новый Файл(ИмяФайлаОтправки);            // файл отправки содержит Сообщение как временный xml файл
                      РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер()); // размер файла для заголовка HTTP запроса
					  
					  Если Константы.ТестовыйРежимУТМ.Получить() = Ложь Тогда // если не тестовый режим выполняем отправку запроса
						  
						  // Журнал сообщений УТМ запрос
						  ЭлементЖурналУТМ = Документы.ЖурналСобытийУТМ.СоздатьДокумент();
						  ЭлементЖурналУТМ.Дата = ТекущаяДата();      
						  ЭлементЖурналУТМ.ТипЭлементаЖурнала = Перечисления.ТипЭлементаЖурналаУТМ.Запрос;
						  ЭлементЖурналУТМ.СобытиеУТМ = Сообщение; 
						  ЭлементЖурналУТМ.КомандаУТМ = "HTTP запрос";
						  СписокУИНЖурналаУТМ = ЭлементЖурналУТМ.Список;
							    Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл  
								     Если СтрДлина(ТекСтрокаСписок.УИН) = 16 Тогда
								          НоваяСтрокаУИНЖурналаУТМ     =  СписокУИНЖурналаУТМ.Добавить();  
										  НоваястрокаУИНЖурналаУТМ.УИН = ТекСтрокаСписок.УИН;
								     КонецЕсли;	   
							    КонецЦикла;	  
						  ЭлементЖурналУТМ.Записать();
						  // Журнал сообщений УТМ запрос
						  
			              Заголовки = Новый Соответствие;
						  Заголовки.Вставить("Content-Type", "text/xml;charset=UTF-8");
						  Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);
						  
						  // Константа АдресДляСообщенийУТМ = http://localhost:8383/xml
						  
						  // соединение с параметрами по умолчанию
						  Соединение = Новый HTTPСоединение(СокрЛП(Константы.АдресДляСообщенийУТМ.Получить()));

						  HTTPЗапрос = Новый HTTPЗапрос;
						  HTTPЗапрос.Заголовки = Заголовки;
						  HTTPЗапрос.УстановитьИмяФайлаТела(ФайлОтправки); // устанавливаем тело запроса как имя файла
						  
						  //HTTPЗапрос.УстановитьТелоИзСтроки(Сообщение,КодировкаТекста.UTF8); - тело из строки видимо не работае, передавать нужно файл

						  Результат = Соединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
							
						  Если Результат.КодСостояния = 200 Тогда 
							  
							    // 4. получить ответ   
								// записываем ответ в любом случае, если все хорошо - он сохранится, если нет - будет удален вместе с документом ЧекПродажи 
								ЭлементДокумент.ОтветНаЗапросОтУТМ = Результат.ПолучитьТелоКакСтроку();
								ЭлементДокумент.Записать();
								
							    ПрочитатьОтвет(Результат.ПолучитьТелоКакСтроку());
								
								// Журнал сообщений УТМ ответ
							    ЭлементЖурналУТМ = Документы.ЖурналСобытийУТМ.СоздатьДокумент();
							    ЭлементЖурналУТМ.Дата = ТекущаяДата();
							    ЭлементЖурналУТМ.СобытиеУТМ = Результат.ПолучитьТелоКакСтроку();
							    СписокУИНЖурналаУТМ = ЭлементЖурналУТМ.Список;
							    Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл  
								     Если СтрДлина(ТекСтрокаСписок.УИН) = 16 Тогда
								          НоваяСтрокаУИНЖурналаУТМ     =  СписокУИНЖурналаУТМ.Добавить();  
										  НоваястрокаУИНЖурналаУТМ.УИН = ТекСтрокаСписок.УИН;
								     КонецЕсли;	   
							    КонецЦикла;	  
							    ЭлементЖурналУТМ.Записать();
							    // Журнал сообщений УТМ ответ
			
							Иначе
								
								ОтветОтУТМПоложительный = Ложь;
								ТекстОшибкиПередачиВУТМ = "Ошибка на этапе №3 передачи данных в УТМ";
								Сообщить("Код состояния : " + Строка(Результат.КодСостояния), СтатусСообщения.Важное);
								Сообщить(ТекстОшибкиПередачиВУТМ);
								
							КонецЕсли;  
						Иначе  // режим тестовый
							// Журнал сообщений УТМ запрос
							ЭлементЖурналУТМ = Документы.ЖурналСобытийУТМ.СоздатьДокумент();
							ЭлементЖурналУТМ.Дата = ТекущаяДата();  
							ЭлементЖурналУТМ.ТипЭлементаЖурнала = Перечисления.ТипЭлементаЖурналаУТМ.Запрос; 
							ЭлементЖурналУТМ.ТестовыйРежим = Истина;
							ЭлементЖурналУТМ.СобытиеУТМ = Сообщение; 
							ЭлементЖурналУТМ.КомандаУТМ = "HTTP запрос";
							СписокУИНЖурналаУТМ = ЭлементЖурналУТМ.Список;
							    Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл  
								     Если СтрДлина(ТекСтрокаСписок.УИН) = 16 Тогда
								          НоваяСтрокаУИНЖурналаУТМ     =  СписокУИНЖурналаУТМ.Добавить();  
										  НоваястрокаУИНЖурналаУТМ.УИН = ТекСтрокаСписок.УИН;
								     КонецЕсли;	   
							    КонецЦикла;	  
							 ЭлементЖурналУТМ.Записать();
							 // Журнал сообщений УТМ запрос
                             // Журнал сообщений УТМ ответ
							 ЭлементЖурналУТМ = Документы.ЖурналСобытийУТМ.СоздатьДокумент();
							 ЭлементЖурналУТМ.Дата = ТекущаяДата();  
							 ЭлементЖурналУТМ.ТипЭлементаЖурнала = Перечисления.ТипЭлементаЖурналаУТМ.Ответ;  
							 ЭлементЖурналУТМ.ТестовыйРежим = Истина;
							 ЭлементЖурналУТМ.СобытиеУТМ = "тестовый ответ"; 
							 ЭлементЖурналУТМ.КомандаУТМ = "ответ на HTTP запрос";
							 СписокУИНЖурналаУТМ = ЭлементЖурналУТМ.Список;
							    Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл  
								     Если СтрДлина(ТекСтрокаСписок.УИН) = 16 Тогда
								          НоваяСтрокаУИНЖурналаУТМ     =  СписокУИНЖурналаУТМ.Добавить();  
										  НоваястрокаУИНЖурналаУТМ.УИН = ТекСтрокаСписок.УИН;
								     КонецЕсли;	   
							    КонецЦикла;	  
							  ЭлементЖурналУТМ.Записать();
							  // Журнал сообщений УТМ ответ
							
		              КонецЕсли;
				  Иначе 
					  // используем cUrl
					  // 1. Записать Сообщение как файл cheque.xml в каталог установленный УТМ  
					  Текст = Новый ЗаписьТекста(СокрЛП(Константы.ПутьПодготовленногоФайлаCheque.Получить()), КодировкаТекста.UTF8);
	                  Текст.ЗаписатьСтроку(Сообщение);
	                  Текст.Закрыть();				
	                  // Пауза 1 сек
					  сек = 1;
                      КонДата = ТекущаяДата() + сек;
                      Пока ТекущаяДата() < КонДата Цикл
                          // ждемссс....
                      КонецЦикла;
					  
					  // 2. выполнить 
					  
					  ПутьКФайлуОтвета = СокрЛП(Константы.ПутьФайловОтветовОтУТМ.Получить()) + "otv" + СокрЛП(СтрЗаменить(Строка(ФискальныйДокумент),Символы.НПП, "")) + ".xml";   
					  
					  // Прежде всего работоспособна слудующая строка cUrl - проверено экспериментальным путем  					  
					  // curl -F "xml_file=@"c:/utm/cheque.xml"" 127.0.0.1:1500/ws/v3 -o "c:\utm\otv\otv1.xml"
					  // ответ в файле c:\utm\otv\otv1.xml
					  // {"timestamp":"2024-04-17T09:18:56.940+00:00","status":500,"error":"Internal Server Error","path":"/ws/v3"} 
					  
					  // Для загрузки файла с помощью cURL нужно использовать следующую команду:
                      // curl -F "file=@путь_к_файлу" URL_адрес_запроса
                      // Где:
                      // -F - указывает, что мы отправляем форму, содержащую файл
                      // "file=@путь_к_файлу" - указывает, что мы отправляем файл, который находится по указанному пути
                      // URL_адрес_запроса - адрес, куда мы отправляем запрос 
					  // Обратите внимание на символ @ - он нужен для того, 
					  // чтобы параметру file было присвоено не значение строки «/путь/до/файла», 
					  // а содержимое того самого файла, который находится по пути /путь/до/файла.
                      // Например, чтобы загрузить файл example.txt на сайт example.com/upload, нужно выполнить следующую команду:
                      // curl -F "file=@/путь_к_файлу/example.txt" example.com/upload
                      // После этого cURL отправит файл на указанный адрес.       
					  
					  // Преобразование пути к файлу cheque.xml
					  ПутьДоФайла = СокрЛП(Константы.ПутьПодготовленногоФайлаCheque.Получить());                                   
					  ПутьДоФайла = СтрЗаменить(ПутьДоФайла, "\", "/");        // переворачиваем слеш                      
					  ПутьДоФайла = """" + ПутьДоФайла + """";                 // полный путь забираем в кавычки
					  ПутьДоФайла = """" + "xml_file=@" + ПутьДоФайла + """";  // добавляем кавычку + формулу "Переменная" "Значение" + закрываем кавычку
                
					  СтрокаКоманды = "curl -F " +  ПутьДоФайла + " " + СокрЛП(Константы.АдресДляСообщенийУТМ.Получить()); // плюс пробел и плюс адрес УТМ на локалхосте
					  
					  СтрокаКоманды = СтрокаКоманды + " -o " + """" + ПутьКФайлуОтвета + """"; // плюс пробел, плюс -o, плюс путь дофайла ответа в кавычках 
					  
					  Сообщить("Строка команды УТМ : " + СтрокаКоманды); // визуально видим строку команду УТМ
					  
					  // Строка команды должна принять вид - собледение кавычек, пробелов, слешей, перевернутых слешей проверено
					  // curl -F "xml_file=@"c:/utm/cheque.xml"" http://localhost:8383/xml -o "c:\utm\otv\otv1.xml"
					  
					  Если Константы.ТестовыйРежимУТМ.Получить() = Ложь Тогда     // если не тестовый режим выполняем cUrl или WindowsScriptHost
						  
						  // Журнал сообщений УТМ запрос
						  ЭлементЖурналУТМ = Документы.ЖурналСобытийУТМ.СоздатьДокумент();
						  ЭлементЖурналУТМ.Дата = ТекущаяДата();  
						  ЭлементЖурналУТМ.ТипЭлементаЖурнала = Перечисления.ТипЭлементаЖурналаУТМ.Запрос;
						  ЭлементЖурналУТМ.СобытиеУТМ = Сообщение; 
						  ЭлементЖурналУТМ.КомандаУТМ = СтрокаКоманды;
						  СписокУИНЖурналаУТМ = ЭлементЖурналУТМ.Список;
							    Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл  
								     Если СтрДлина(ТекСтрокаСписок.УИН) = 16 Тогда
								          НоваяСтрокаУИНЖурналаУТМ     =  СписокУИНЖурналаУТМ.Добавить();  
										  НоваяСтрокаУИНЖурналаУТМ.УИН = ТекСтрокаСписок.УИН;
								     КонецЕсли;	   
							    КонецЦикла;	  
						   ЭлементЖурналУТМ.Записать();
						   // Журнал сообщений УТМ запрос
	  
						  Если Константы.МетодЗапускаКомандыУТМ.Получить() = Перечисления.МетодЗапускаКомандыУТМ.КакПриложение ИЛИ Константы.МетодЗапускаКомандыУТМ.Получить() = Перечисления.МетодЗапускаКомандыУТМ.ПустаяСсылка() Тогда
							  
							  
							  // 1. Вариант запуска команды
		                      ЗапуститьПриложение(СтрокаКоманды);
							  
							  
						  КонецЕсли;
						  
						  Если Константы.МетодЗапускаКомандыУТМ.Получить() = Перечисления.МетодЗапускаКомандыУТМ.КакОбъектWindowsScriptHost Тогда
							  // 2. вариант запуска команды  
							  // Run(strCommand, [intWindowStyle], [bWaitOnReturn])   
							  // strCommand – данный параметр является обязательным, поскольку задает путь для файла или команды. 
							  // Стоит учитывать, что если путь содержит пробелы, то его обязательно стоит заключать в двойные кавычки, 
						      // иначе, возникнет ошибка «The system cannot find the file specified» – система не может найти указанный файл. 
							  // Также полезно, использовать переменные окружения в пути к приложению, это экономит время. 
							  // intWindowStyle – является необязательным, и задает стиль окна. Параметр может принимать целые значения от 0 до 10. 
							  // Согласно документации, в языке vbscript можно использовать именованные константы, но, они не всегда дают ожидаемый результат, 
							  // и так как эти значения между собой повторяются, я упомянул лишь три:
		                      // 0 – скрывает окно, будет виден только процесс в диспетчере задач.
		                      // 1 – нормальный режим
		                      // 2 – свернутый вид
		                      // 3 – развернутый вид 
							  // bWaitOnReturn – может принимать true – сценарий будет ожидать завершения работы запущенного приложения, 
							  // и только потом перейдет к выполнению следующей строчки кода, 
							  // false – будет продолжатся выполнение сценария независимо от того, завершилась работа запущенного приложения или нет. 
							  // Также следует учесть, что если установлено true, то метод вернет код выхода вызванного приложения, 
							  // если установлено false – всегда будет возвращаться ноль.
							  
							  
							  objShell = Новый COMОбъект("WScript.Shell") ;
				              objShell.Run(СтрокаКоманды, 0, true);
						  КонецЕсли;        
					   Иначе
						  // Журнал сообщений УТМ запрос
						  ЭлементЖурналУТМ = Документы.ЖурналСобытийУТМ.СоздатьДокумент();
						  ЭлементЖурналУТМ.Дата = ТекущаяДата();  
						  ЭлементЖурналУТМ.ТипЭлементаЖурнала = Перечисления.ТипЭлементаЖурналаУТМ.Запрос; 
						  ЭлементЖурналУТМ.ТестовыйРежим = Истина;
						  ЭлементЖурналУТМ.СобытиеУТМ = Сообщение; 
						  ЭлементЖурналУТМ.КомандаУТМ = СтрокаКоманды;
						  СписокУИНЖурналаУТМ = ЭлементЖурналУТМ.Список;
							    Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл  
								     Если СтрДлина(ТекСтрокаСписок.УИН) = 16 Тогда
								          НоваяСтрокаУИНЖурналаУТМ     =  СписокУИНЖурналаУТМ.Добавить();  
										  НоваяСтрокаУИНЖурналаУТМ.УИН = ТекСтрокаСписок.УИН;
								     КонецЕсли;	   
							    КонецЦикла;	  
						   ЭлементЖурналУТМ.Записать();
						   // Журнал сообщений УТМ запрос
					  КонецЕсли;
					  // 3. Прочитать ответ "C:\УТМответ\otvet.xml";    
					  // Нужно определиться сколько попыток необходимо
					  // Пауза 1 сек
					  сек = 1;
                      КонДата = ТекущаяДата() + сек;
                      Пока ТекущаяДата() < КонДата Цикл
                          // ждемссс....
                      КонецЦикла;
					  Попытка
						  
						  Текст = Новый ЧтениеТекста(ПутьКФайлуОтвета, КодировкаТекста.UTF8);
		                  СтрокаОтвета = Текст.Прочитать();	
		                  Текст.Закрыть();	
		                  ПрочитатьОтвет(СтрокаОтвета);
						  // записываем ответ в любом случае, если все хорошо - он сохранится, если нет - будет удален вместе с документом ЧекПродажи 
						  ЭлементДокумент.ОтветНаЗапросОтУТМ = СтрокаОтвета;
						  ЭлементДокумент.Записать();
						  
						  // Журнал сообщений УТМ ответ
						  ЭлементЖурналУТМ = Документы.ЖурналСобытийУТМ.СоздатьДокумент();
						  ЭлементЖурналУТМ.Дата = ТекущаяДата();   
						  ЭлементЖурналУТМ.ТипЭлементаЖурнала = Перечисления.ТипЭлементаЖурналаУТМ.Ответ; 
						  Если Константы.ТестовыйРежимУТМ.Получить() = Истина Тогда 
							   ЭлементЖурналУТМ.ТестовыйРежим = Истина;
						  КонецЕсли;	  
						  ЭлементЖурналУТМ.СобытиеУТМ = СтрокаОтвета;
						  СписокУИНЖурналаУТМ = ЭлементЖурналУТМ.Список;
						  Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл  
								     Если СтрДлина(ТекСтрокаСписок.УИН) = 16 Тогда
								          НоваяСтрокаУИНЖурналаУТМ     =  СписокУИНЖурналаУТМ.Добавить();
										  НоваяСтрокаУИНЖурналаУТМ.УИН = ТекСтрокаСписок.УИН;
								     КонецЕсли;	   
						  КонецЦикла;	  
						  ЭлементЖурналУТМ.Записать();
						  // Журнал сообщений УТМ ответ 
					  Исключение 
						  // Неудача чтения файла ответа от УТМ
						  // Из описания у УТМ такое невозможно
						  // смысла мониторить папку нет, если не запускаешь курл в асинхронном потоке, просто когда команда отработает файлик там гарантированно будет 
						  // Журнал сообщений УТМ ответ
						  ЭлементЖурналУТМ = Документы.ЖурналСобытийУТМ.СоздатьДокумент();
						  ЭлементЖурналУТМ.Дата = ТекущаяДата();    
						  ЭлементЖурналУТМ.ТипЭлементаЖурнала = Перечисления.ТипЭлементаЖурналаУТМ.Ответ;  
						  Если Константы.ТестовыйРежимУТМ.Получить() = Истина Тогда 
							   ЭлементЖурналУТМ.ТестовыйРежим = Истина;
						  КонецЕсли;
						  ЭлементЖурналУТМ.СобытиеУТМ = "файл " + ПутьКФайлуОтвета + " не найден. Команда cUrl не исполнена";
						  СписокУИНЖурналаУТМ = ЭлементЖурналУТМ.Список;
						  Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл  
								     Если СтрДлина(ТекСтрокаСписок.УИН) = 16 Тогда
								          НоваяСтрокаУИНЖурналаУТМ     =  СписокУИНЖурналаУТМ.Добавить(); 
										  НоваяСтрокаУИНЖурналаУТМ.УИН = ТекСтрокаСписок.УИН;
								     КонецЕсли;	   
						  КонецЦикла;	  
						  ЭлементЖурналУТМ.Записать();
						  // Журнал сообщений УТМ ответ
					КонецПопытки;	  
					  
		КонецЕсли;		
				  
		// 5. если ответ положительный (ОтветОтУТМПоложительный = Истина) пробить чек, если отрицательный удалить чек
		Если ОтветОтУТМПоложительный = Ложь И Константы.ТестовыйРежимУТМ.Получить() = Ложь Тогда 
			Если Константы.ЗакончитьПродажуПриОтрицательномОтветеУТМ.Получить() = Истина Тогда
				     // ничего не делаем, продолжаем выполнение программы
				     // игнорируем ошибку УТМ
				 Иначе
			         ЧекПробит = Ложь;
                     ЭтаФорма.Закрыть(Истина);  // Дальше выполнится ПриЗакрытии(), чек будет удален, операция прервана  
		     конецЕсли;		 
		Иначе 
			// записываем признак УСПЕХ выполения операции УТМ
			 Если Константы.ТестовыйРежимУТМ.Получить() = Ложь  Тогда			 
				ЭлементДокумент.УТМ = Истина;
			 КонецЕсли;	
			 ЭлементДокумент.Записать();
		КонецЕсли;	
		
	
	Иначе
		Сообщить("Условия работы УТМ не выполнены", СтатусСообщения.Обычное);
		 Если ЧекСодержитУИН(ЭлементДокумент) Тогда
			 Сообщить("Чек содержит товары с УИН", СтатусСообщения.Обычное);    
			 Иначе
			 Сообщить("Чек не содержит товаров с УИН", СтатусСообщения.Обычное);
		 КонецЕсли;  
		 Если (Константы.ПередаватьЗапросыВУТМ.Получить() = Истина И Константы.ФискальныйРегистраторВключен.Получить() = Истина И глНомерВерсииДрайвераККМ = 10 И ЧекСодержитУИН(ЭлементДокумент) И (ЧекНаличными > 0 ИЛИ ЧекБезналичными > 0)) Тогда
			 Сообщить("Выполнено первое условие"); 
		 КонецЕсли;	
		 Если (Константы.ПередаватьЗапросыВУТМ.Получить() = Истина И ЧекСодержитУИН(ЭлементДокумент) И (ЧекНаличными > 0 ИЛИ ЧекБезналичными > 0) И (Константы.ТестовыйРежимУТМ.Получить()=Истина)) Тогда
			 Сообщить("Выполенено второе - тестовое условие");
		 КонецЕсли;	 
   КонецЕсли;		 
   ////////////////////// ВСТАВКА ФОРМИРОВАНИЯ ЗАПРОСА ДЛЯ ПЕРЕДАЧИ В ГИИС ДМДК, ПОЛУЧЕНИЯ ОТВЕТА ////////////////////////////////////////////////////////////­/////////////////
   //#КонецОбласти
Показать
13. grafit 8 02.11.24 14:37 Сейчас в теме
Обновленный ТМ вышел. Там появился ключ (вероятно для ТОПа). До сих пор непонятно, как в одной учетной базе использовать несколько ТМ.
14. hypersib 23.01.25 10:57 Сейчас в теме
(13) у них есть несколько схем работы.

Вот тут они описаны

Мы выбрали схему работы где все ТМ расположены у нас на серваке (докер контейнер) а кассы шлют им запрос по api, где он уже распределяется на нужный контейнер. (правый нижний угол на схеме).
15. user1792010 24.02.25 14:12 Сейчас в теме
Получилось у кого нибудь взаимодействовать с ТМ через HTTP запрос ? попробовал по примеру выше получаю сообщение что сервис не найден, хотя ТМ установлен и функционирует без ошибок на том же ПК вместе с программой....
16. Zagon 24.02.25 16:40 Сейчас в теме
Пример работы с ТМ есть в бухе (я смотрел в 3.0.169.18). В модуле ОбменДаннымиЕГАИСВызовСервера есть функция ПередатьСообщениеВУТМ.
Оставьте свое сообщение