Универсальный транспортный модуль "Государственная интегрированная информационная система "Драгоценные металлы и драгоценные камни". Разбор руководства программиста. Практическое использование регистрации розничных продаж ювелирных изделий.
Предлагаю на разбор появившееся в апреле Руководство программиста "Транспортный модуль" на сайте ГИИС ДМДК.
На сегодняшний день мы используем для регистрации списания в архив Ювелирных изделий методами 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С:Бухгалтерия 3.0 ПРОФ/КОРП и УХ 3.2. Отчеты по исполнению госконтрактов, расчетно-калькуляционные материалы и контроль операций для исполнения в срок. Готовое расширение подходит для всех бухгалтеров и руководителей производства, помогая вести правильный учет по гособоронзаказу в соответствии 275-ФЗ. Профессиональный консалтинг и регулярные обновления продукта.
Доработка конфигурации 1С:Бухгалтерия предприятия, редакция 3.0. реализована в виде расширения. Предназначена для ведения раздельного учета и автоматизации заполнения отчетности исполнения контрактов ГОЗ в конфигурациях 1С БП КОРП, ПРОФ, БИТ.ФИНАНС.
Интеграция и синхронизация Честный Знак и 1C - полноценная обработка, которая манипулирует сотнями задач по ведению учета в системе мониторинга честный знак, особенности: такие как полная поддержка учета карточек в национальном каталоге (модерация, редактирование, подписание, получение информации), получение кодов маркировок в станции управления заказами "СУЗ Облако", удобная отправка и получение "УПД" через систему "ЭДОЛайт" из документов реализации или корректировки, так же существует механизм приема через ЭДОЛайт, отправка и получения таких документов как перемаркировка , списание, отгрузка и еще более 40 типов документов в ГИСМТ которые описаны ниже, моментальное сопоставление и внедрение в типовую конфигурацию которое обеспечивает ракетную мега скорость
Для 1С: УПП 1.3 предлагаем Вашему вниманию подсистему "Раздельный учет результатов финансово-хозяйственной деятельности организаций, выполняющих государственный оборонный заказ (раздельный учет ГОЗ)". Ключевые возможности подсистемы: - Автоматическое заполнение регламентированного отчета «Исполнение контрактов ГОЗ»; - Расшифровка показателей отчета об исполнении контрактов ГОЗ с детализацией до документов; - Контроль хозяйственных операций на соответствие требованиям Постановления Правительства № 47; - Автоматизированный ввод начальных данных по контрактам, заключенным ранее даты начала использования подсистемы.
Полнофункциональное расширение (ранее известное как Модуль 1С-ЕГАИС) для взаимодействия типовых конфигураций 1С и ЕГАИС, предоставляющее максимум возможностей по работе с УТМ. Получение и отправка ТТН, отправка акта о постановке на баланс и акта о списании. Получение остатков. Загрузка и сопоставление номенклатуры и контрагентов. Оправка в ЕГАИС отчетов о производстве и импорте.
Расширение конфигурации для УТ 11.5, КА 2.5 ,ERP 2.5 (Управляемые формы) позволяет выполнять печать кассовых чеков на одну ККМ 54-ФЗ с нескольких рабочих мест. НИКАКИХ НАСТРОЕК В РАЗРАБОТКЕ - ПОДКЛЮЧИЛ И ПЕЧАТАЙ. Если у вас несколько отделов и одна ККМ - печатайте на одной ККМ! Если у вас две ККМ и одна поломалась - печатайте на одной ККМ, пока ремонтируете другую!
Работаете по контрактной схеме, сталкивались с проблемой, что в контракте жестко указаны наименование, цена, единица измерения товара. И не все готовы создавать новую номенклатуру под каждый контракт или менять наименование и единицу измерения для уже имеющейся. Тем более, бывает так, что контракт - это формальность. Контракт не описывает жесткие условия поставки, нужно соблюсти правильность в предоставлении документов. Данное решение позволит вам оперировать своей номенклатурой при оформлении реализаций по государственному контракту в УТ 11.5 и КА 2.5.11, в то же время выводить на печать документы, соответствующие данным контракта. Реализована выгрузка для сайта госзакупок (ЕИС) по 44-ФЗ.
Универсальная конфигурация Хамелеон Меркурий для взаимодействия с системой Меркурий (тестовый+рабочий+демо контур) может использоваться для интеграции в любую конфигурацию на базе 1С, версии ПРОФ и выше. Основное отличие от других решений - работа через веб-интерфейс и API 2.0(API 2.1). Для удобства реализован общий интерфейс в виде обработки, схожей с интерфейсом Меркурий, но возможностей гораздо больше, т.к. при интеграции в Вашу учетную систему, можно на основании Ваших справочников и документов, создавать соответствующие документы и справочники в системе Меркурий и наоборот.
Ну думаю, что то вот такое должно работать непосредственно из 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 Тогда
ПрочитатьОтвет(Результат.ПолучитьТелоКакСтроку());
КонецЕсли;
...
Есть также серьезный вопрос к ГИИС ДМДК. Вышла вторая редакция руководства программиста УТМ и в нем ни слова о КПП индивидуального предпринимателя. УТМ изначально написан для алкоголя, в алкогольной торговле нет ИП, там все юр. лица, соответственно проблема не стоит. Есть вероятность, что УТМ для ИП вообще не будет работать.
Вариантов к сожалению как оказывается масса, редактирую сообщение (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 Тогда
ПрочитатьОтвет(Результат.ПолучитьТелоКакСтроку());
КонецЕсли;
Удалось отправить через ТМ реальную продажу. Чек отразился в списке.
К примеру, на левый УИН ответ такой -
<?xml version="1.0" encoding="UTF-8" standalone="no"?><A><ver>2</ver><error>Партия не зарегистрирована: 6432400130000000</error></A>
Если с УИНом все в порядке, то ответ пустой.
(4) Добрый день! Подскажите пожалуйста, что вы указывали в заголовках запроса. Выполняли ли авторизацию? Нужно ли после установки ТМ что-то в нем настраивать?
К ТМ есть инструкция, где, как и чего надо скачать, прописать, настроить.
Авторизация там по умолчанию Admin, Admin. Нужно сертификаты скачать, установить. ОГРН,ИНН и ключ ТОПа (торговой точки). Ключ формируется в ЛК ДМДК, создается ТОП и для него ключ.
В файле конфигурации conf.env в каталоге C:\TMDMDK прописывается тестовый контур.
(6) Да надо подумать над вашим комментарием. Самое главное что я понял - если городить HTTP нужно отправлять именной файл! Тело сообщения в виде строки как обычно не пройдет. Только файл.
Ну в общем прилагаю свои общие наработки для любой программы 1с.
Выделю главное
- реквизит "Закончить продажу при отрицательном ответе УТМ" - предполагаю когда все активно начнут использовать УТМ (это 1 марта 2025 года) будут проблемы. Даже если будет отрицательный ответ УТМ ККМ чек пробьет, потом его разносим методом SendBatchSale / CheckBatchSale (пока его не прикроют)
- реквизит "Тестовый режим УТМ" - файл XML формируется но не отправляется. Это просто для отработки корректности составления XML. Запросы в УТМ и ответы из УТМ предлагаю сохранять - документ в конфигурации "Журнал событий УТМ".
Процедура получения данных чека для УТМ (для драйвера АТОЛ) . Обратите внимание - к фискальным документам относятся "Открыть смену", "Чек прихода/Чек возврата прихода", "Закрыть смену". Если у вас смена отрывается вместе с пробитием первого чека ККМ то к номеру смены и номеру фискального документа добавляем 1. В 1С есть проблема - она сама пытается вести за ККМ реквизиты фискальных документов, и может возникнуть ситуация рассинхронизации данных между 1С и ККМ - выражается это в основном в невозможности открыть или закрыть смену. Поэтому это все сразу убираем - данные получаем только из КММ.
// Переменные реквизитов чека для ГИИС
Перем ФискальныйНакопитель Экспорт;
Перем ФискальныйДокумент Экспорт;
Перем ФискальныйПризнакДокумента Экспорт;
Перем ДатаФискальногоДокумента Экспорт;
Перем НомерСмены Экспорт;
//// Переменная УТМ
Перем ОтветОтУТМПоложительный Экспорт;
Перем ТекстОшибкиПередачиВУТМ Экспорт;
//#Область ПроцедурыДляУТМ
// Функция проверки - есть ли в чеке товары с УИН
Функция ЧекСодержитУИН(ЭлементДокумент)
ВЧекеЕстьУИН = Ложь;
СписокТовара = ЭлементДокумент.Список;
Для КАЖДОГО ТекСтрокаСписок ИЗ СписокТовара Цикл
Если СтрДлина(ТекСтрокаСписок.УИН) = 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 по ТекстовыйДокументИзСтроки.КоличествоСтрок() цикл
Результат.Добавить(СокрЛП(ТекстовыйДокументИзСтроки.ПолучитьСтроку(СчетчикСтрок)));
КонецЦикла;
Возврат Результат;
КонецФункции
//#Область ФормированиеЗапросаВУТМ
////////////////////// ВСТАВКА ФОРМИРОВАНИЯ ЗАПРОСА ДЛЯ ПЕРЕДАЧИ В ГИИС ДМДК, ПОЛУЧЕНИЯ ОТВЕТА /////////////////////////////////////////////////////////////////////////////
//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) И (Константы.ТестовыйРежимУТМ.Получить()=Истина)) Тогда
Сообщить("Выполенено второе - тестовое условие");
КонецЕсли;
КонецЕсли;
////////////////////// ВСТАВКА ФОРМИРОВАНИЯ ЗАПРОСА ДЛЯ ПЕРЕДАЧИ В ГИИС ДМДК, ПОЛУЧЕНИЯ ОТВЕТА /////////////////////////////////////////////////////////////////////////////
//#КонецОбласти