XMLTsdMagazinVasilek/CommonModules/Синхронизация/Ext/Module.bsl

1022 lines
50 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Функция ДанныеОбновленияПубликации() Экспорт
Результат = Новый Структура("ЕстьОбновление, ТекстСообщения, Идентификатор", Ложь, "", "");
ДанныеПубликации = ПолучитьДанныеПубликации();
Если ПустаяСтрока(ДанныеПубликации.Идентификатор)
И ПустаяСтрока(ДанныеПубликации.Версия) Тогда
Возврат Результат;
КонецЕсли;
ЕстьОбновление = ЭтоНоваяВерсияКонфигурации(ДанныеПубликации.Версия);
ЗаписатьПризнакАвтообновления(ЕстьОбновление, ДанныеПубликации.Адрес);
Если Не ЕстьОбновление Тогда
Если Не ПустаяСтрока(ДанныеПубликации.Идентификатор) Тогда
ЗафиксироватьИдентификаторПубликации(ДанныеПубликации.Идентификатор);
КонецЕсли;
Возврат Результат;
КонецЕсли;
Результат.ЕстьОбновление = Истина;
Результат.Идентификатор = ДанныеПубликации.Идентификатор;
Результат.ТекстСообщения = "Обнаружена новая версия приложения";
Возврат Результат;
КонецФункции
Процедура ЗафиксироватьИдентификаторПубликации(ИдентификаторПубликации) Экспорт
Если Не ЗначениеЗаполнено(ИдентификаторПубликации) Тогда
Возврат;
КонецЕсли;
ХранилищеОбщихНастроек.Сохранить("ОбновлениеКонфигурации", "ИдентификаторПубликации", ИдентификаторПубликации);
КонецПроцедуры
Функция ПодготовитьЗагрузкуОбновления() Экспорт
Возврат ДанныеОбновленияПубликации();
КонецФункции
Функция ЭтоНоваяВерсияКонфигурации(ВерсияПубликации)
ВерсияНаСервере = СокрЛП(Строка(ВерсияПубликации));
Если ПустаяСтрока(ВерсияНаСервере) Тогда
Возврат Ложь;
КонецЕсли;
Возврат ВерсияНаСервере <> СокрЛП(Строка(Метаданные.Версия));
КонецФункции
Функция ПолучитьДанныеПубликации()
Результат = Новый Структура("Идентификатор, Версия, Адрес", "", "", "");
ПараметрыАдреса = ПараметрыАдресаПубликации();
Результат.Адрес = ПараметрыАдреса.Адрес;
Если ПустаяСтрока(ПараметрыАдреса.Хост) Тогда
Возврат Результат;
КонецЕсли;
Попытка
HTTPСоединение = Новый HTTPСоединение(
ПараметрыАдреса.Хост,
ПараметрыАдреса.Порт,
,
,
,
10);
HTTPЗапрос = Новый HTTPЗапрос(ПараметрыАдреса.Путь);
Ответ = HTTPСоединение.Получить(HTTPЗапрос);
Если Ответ.КодСостояния < 200 Или Ответ.КодСостояния > 299 Тогда
Возврат Результат;
КонецЕсли;
ЗаполнитьДанныеИзФайлаПубликации(Результат, Ответ.ПолучитьТелоКакСтроку("UTF-8"));
Исключение
КонецПопытки;
Возврат Результат;
КонецФункции
Процедура ЗаполнитьДанныеИзФайлаПубликации(ДанныеПубликации, ТекстФайла)
Если ПустаяСтрока(ТекстФайла) Тогда
Возврат;
КонецЕсли;
Попытка
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ТекстФайла);
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
Продолжить;
КонецЕсли;
Идентификатор = СокрЛП(Строка(ЧтениеXML.ЗначениеАтрибута("lastUpdateUUID")));
Если Не ЗначениеЗаполнено(Идентификатор) Тогда
Продолжить;
КонецЕсли;
ДанныеПубликации.Идентификатор = Идентификатор;
ДанныеПубликации.Версия = СокрЛП(Строка(ЧтениеXML.ЗначениеАтрибута("version")));
ЧтениеXML.Закрыть();
Возврат;
КонецЦикла;
ЧтениеXML.Закрыть();
Исключение
КонецПопытки;
КонецПроцедуры
Функция ПолучитьИдентификаторПубликации()
Возврат ПолучитьДанныеПубликации().Идентификатор;
КонецФункции
Функция ИдентификаторИзФайлаПубликации(ТекстФайла)
ДанныеПубликации = Новый Структура("Идентификатор, Версия, Адрес", "", "", "");
ЗаполнитьДанныеИзФайлаПубликации(ДанныеПубликации, ТекстФайла);
Возврат ДанныеПубликации.Идентификатор;
КонецФункции
Функция ПараметрыАдресаПубликации()
Результат = Новый Структура("Хост, Порт, Путь, Адрес", "", 80, "/1cema.xml", "");
СерверИсточник = СокрЛП(Константы.СерверИсточникОбновлений.Получить());
Если ПустаяСтрока(СерверИсточник) Тогда
СерверИсточник = СокрЛП(Константы.Сервер.Получить());
КонецЕсли;
Если ПустаяСтрока(СерверИсточник) Тогда
Возврат Результат;
КонецЕсли;
СерверИсточник = СтрЗаменить(СерверИсточник, "https://", "");
СерверИсточник = СтрЗаменить(СерверИсточник, "http://", "");
ХостПубликации = СерверИсточник;
ПутьКФайлуПубликации = "/1cema.xml";
ПозицияПути = СтрНайти(СерверИсточник, "/");
Если ПозицияПути > 0 Тогда
ХостПубликации = Лев(СерверИсточник, ПозицияПути - 1);
ПутьПубликации = Сред(СерверИсточник, ПозицияПути);
Если Прав(ПутьПубликации, 1) = "/" Тогда
ПутьКФайлуПубликации = ПутьПубликации + "1cema.xml";
ИначеЕсли СтрНайти(НРег(ПутьПубликации), ".xml") = 0 Тогда
ПутьКФайлуПубликации = ПутьПубликации + "/1cema.xml";
Иначе
ПутьКФайлуПубликации = ПутьПубликации;
КонецЕсли;
КонецЕсли;
ПортПубликации = 80;
ПозицияПорта = СтрНайти(ХостПубликации, ":");
Если ПозицияПорта > 0 Тогда
ПортСтрока = Сред(ХостПубликации, ПозицияПорта + 1);
ХостПубликации = Лев(ХостПубликации, ПозицияПорта - 1);
Попытка
ПортПубликации = Число(ПортСтрока);
Исключение
ПортПубликации = 80;
КонецПопытки;
КонецЕсли;
Если ПустаяСтрока(ХостПубликации) Тогда
Возврат Результат;
КонецЕсли;
Если Лев(ПутьКФайлуПубликации, 1) <> "/" Тогда
ПутьКФайлуПубликации = "/" + ПутьКФайлуПубликации;
КонецЕсли;
Адрес = "http://" + ХостПубликации;
Если ПортПубликации <> 80 И ПортПубликации <> 0 Тогда
Адрес = Адрес + ":" + Формат(ПортПубликации, "ЧГ=");
КонецЕсли;
Адрес = Адрес + ПутьКФайлуПубликации;
Результат.Хост = ХостПубликации;
Результат.Порт = ПортПубликации;
Результат.Путь = ПутьКФайлуПубликации;
Результат.Адрес = Адрес;
Возврат Результат;
КонецФункции
Процедура ЗаписатьПризнакАвтообновления(Автообновление, АдресПубликации)
#Если МобильноеПриложениеСервер Тогда
Попытка
ПутьКФайлу = НайтиФайлСпискаБаз();
Если ПустаяСтрока(ПутьКФайлу) Тогда
Возврат;
КонецЕсли;
ЗаписатьПараметрыОбновленияВСпискеБаз(ПутьКФайлу, АдресПубликации, Автообновление);
Исключение
КонецПопытки;
#КонецЕсли
КонецПроцедуры
Функция НайтиФайлСпискаБаз()
ИмяФайла = "ibases.v8i";
КаталогиПоиска = Новый Массив;
КаталогВрем = КаталогВременныхФайлов();
КаталогиПоиска.Добавить(СтрЗаменить(КаталогВрем, "/cache/", "/files/1C/1cem/"));
КаталогиПоиска.Добавить(СтрЗаменить(КаталогВрем, "\cache\", "\files\1C\1cem\"));
КаталогиПоиска.Добавить(КаталогВрем);
КаталогиПоиска.Добавить("/Library/1C/1cem/");
Для Каждого КаталогПоиска Из КаталогиПоиска Цикл
Если ПустаяСтрока(КаталогПоиска) Тогда
Продолжить;
КонецЕсли;
Попытка
Найденные = НайтиФайлы(КаталогПоиска, ИмяФайла, Истина);
Если Найденные.Количество() > 0 Тогда
Возврат Найденные[0].ПолноеИмя;
КонецЕсли;
Исключение
КонецПопытки;
КонецЦикла;
Возврат "";
КонецФункции
Процедура ЗаписатьПараметрыОбновленияВСпискеБаз(ПутьКФайлу, АдресПубликации, Автообновление)
СтрокиФайла = Новый Массив;
ЧтениеТекста = Новый ЧтениеТекста(ПутьКФайлу);
СтрокаТекста = ЧтениеТекста.ПрочитатьСтроку();
Пока СтрокаТекста <> Неопределено Цикл
СтрокиФайла.Добавить(СтрокаТекста);
СтрокаТекста = ЧтениеТекста.ПрочитатьСтроку();
КонецЦикла;
ЧтениеТекста.Закрыть();
ЗначениеAutoUpdate = ?(Автообновление, "1", "0");
НовыеСтроки = Новый Массив;
ЕстьСекция = Ложь;
ЕстьAutoUpdateВСекции = Ложь;
ЕстьUpdateURLВСекции = Ложь;
Для Индекс = 0 По СтрокиФайла.ВГраница() Цикл
СтрокаФайла = СтрокиФайла[Индекс];
СтрокаБезПробелов = СокрЛП(СтрокаФайла);
ЭтоНачалоСекции = Лев(СтрокаБезПробелов, 1) = "["
И Прав(СтрокаБезПробелов, 1) = "]";
Если ЭтоНачалоСекции Тогда
Если ЕстьСекция Тогда
ДобавитьПараметрыОбновленияВСекцию(
НовыеСтроки,
ЕстьAutoUpdateВСекции,
ЕстьUpdateURLВСекции,
АдресПубликации,
ЗначениеAutoUpdate);
КонецЕсли;
ЕстьСекция = Истина;
ЕстьAutoUpdateВСекции = Ложь;
ЕстьUpdateURLВСекции = Ложь;
НовыеСтроки.Добавить(СтрокаФайла);
Продолжить;
КонецЕсли;
Если СтрНайти(СтрокаБезПробелов, "AutoUpdate=") = 1 Тогда
НовыеСтроки.Добавить("AutoUpdate=" + ЗначениеAutoUpdate);
ЕстьAutoUpdateВСекции = Истина;
Продолжить;
КонецЕсли;
Если СтрНайти(СтрокаБезПробелов, "UpdateURL=") = 1 Тогда
Если ПустаяСтрока(АдресПубликации) Тогда
НовыеСтроки.Добавить(СтрокаФайла);
Иначе
НовыеСтроки.Добавить("UpdateURL=" + АдресПубликации);
КонецЕсли;
ЕстьUpdateURLВСекции = Истина;
Продолжить;
КонецЕсли;
НовыеСтроки.Добавить(СтрокаФайла);
КонецЦикла;
ДобавитьПараметрыОбновленияВСекцию(
НовыеСтроки,
ЕстьAutoUpdateВСекции,
ЕстьUpdateURLВСекции,
АдресПубликации,
ЗначениеAutoUpdate);
ЗаписьТекста = Новый ЗаписьТекста(ПутьКФайлу);
Для Каждого СтрокаФайла Из НовыеСтроки Цикл
ЗаписьТекста.ЗаписатьСтроку(СтрокаФайла);
КонецЦикла;
ЗаписьТекста.Закрыть();
КонецПроцедуры
Процедура ДобавитьПараметрыОбновленияВСекцию(СтрокиФайла, ЕстьAutoUpdate, ЕстьUpdateURL, АдресПубликации, ЗначениеAutoUpdate)
Если Не ЕстьAutoUpdate Тогда
СтрокиФайла.Добавить("AutoUpdate=" + ЗначениеAutoUpdate);
КонецЕсли;
Если Не ЕстьUpdateURL И Не ПустаяСтрока(АдресПубликации) Тогда
СтрокиФайла.Добавить("UpdateURL=" + АдресПубликации);
КонецЕсли;
КонецПроцедуры
Функция ЗапускСинхронизации() Экспорт
Сообщения = Новый Массив;
ДобавитьСообщение(Сообщения, "Синхронизация " + Формат(ТекущаяДата(), "ДФ='dd.MM.yyyy HH:mm'"));
ЗагрузитьНоменклатуру(Сообщения);
ОтправитьДокументыВыводаИзОборота(Сообщения);
ОбновитьСтатусыДокументовВыводаИзОборота(Сообщения);
Возврат ТекстИзСообщений(Сообщения);
КонецФункции
Процедура ЗагрузитьНоменклатуру(Сообщения)
Попытка
ДанныеНом = ВыполнитьЗапрос("/utip_curent/hs/tdp", Неопределено, Сообщения);
Если Не ЗапросВыполненУспешно(ДанныеНом) Тогда
ДобавитьСообщение(Сообщения, "Ошибка получения товаров.");
Возврат;
КонецЕсли;
СписокНом = ДанныеНом.Получить("nom");
Если СписокНом = Неопределено Тогда
ДобавитьСообщение(Сообщения, "Номенклатура: УТ11 не вернула список товаров.");
Возврат;
КонецЕсли;
КоличествоЗаписано = 0;
Для Каждого Ном Из СписокНом Цикл
Номенклатура = Справочники.Номенклатура.НайтиПоКоду(Ном["code"]);
Если Не ЗначениеЗаполнено(Номенклатура) Тогда
Номенклатура = Справочники.Номенклатура.СоздатьЭлемент();
Иначе
Номенклатура = Номенклатура.ПолучитьОбъект();
КонецЕсли;
Номенклатура.Код = Ном["code"];
Номенклатура.Наименование = Ном["name"];
Номенклатура.Barcode = Ном["barcode"];
Номенклатура.Записать();
КоличествоЗаписано = КоличествоЗаписано + 1;
КонецЦикла;
Если КоличествоЗаписано = 0 Тогда
ДобавитьСообщение(Сообщения, "Номенклатура: нет данных для загрузки.");
Иначе
ДобавитьСообщение(Сообщения, "Загружена номенклатура: " + XMLСтрока(КоличествоЗаписано));
КонецЕсли;
Исключение
ДобавитьСообщение(Сообщения, "Ошибка получения товаров. " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура ОтправитьДокументыВыводаИзОборота(Сообщения)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВыводИзОборота.Ссылка КАК Ссылка
|ИЗ
| Документ.ВыводИзОборота КАК ВыводИзОборота
|ГДЕ
| ВыводИзОборота.СтатусВыводаИзОборота = &СтатусВыводаИзОборота
| И ВыводИзОборота.ПометкаУдаления = ЛОЖЬ
|
|УПОРЯДОЧИТЬ ПО
| ВыводИзОборота.Дата,
| ВыводИзОборота.Номер";
Запрос.УстановитьПараметр("СтатусВыводаИзОборота", Перечисления.Status.ГотовКОтправке);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Количество() = 0 Тогда
ДобавитьСообщение(Сообщения, "Нет документов для отправки.");
Возврат;
КонецЕсли;
МассивЗапроса = Новый Массив;
ДокументыКОтправке = Новый Массив;
СоответствиеПоНомеру = Новый Соответствие;
ИНН = Константы.ИНН.Получить();
Префикс = СокрЛП(Константы.Префикс.Получить());
Пока Выборка.Следующий() Цикл
Вывод = Выборка.Ссылка.ПолучитьОбъект();
НомерДокумента = НомерДокументаСтрокой(Вывод.Номер);
СтруктураМассива = Новый Структура("id,inn,prefix,tt,operation,nupd,dupd,marks");
СтруктураМассива.id = НомерДокумента;
СтруктураМассива.inn = ИНН;
СтруктураМассива.prefix = Префикс;
СтруктураМассива.tt = СокрЛП(Константы.ТТ.Получить());
СтруктураМассива.operation = Строка(Вывод.Операция);
СтруктураМассива.nupd = Вывод.nupd;
СтруктураМассива.dupd = Формат(Вывод.dupd, "ДФ=dd.MM.yyyy");
Marks = Новый Массив;
Для Каждого Товар Из Вывод.ТЧТовары Цикл
СтруктураMarks = Новый Структура("mark,kol");
СтруктураMarks.mark = Товар.Mark;
СтруктураMarks.kol = Товар.Вес;
Marks.Добавить(СтруктураMarks);
КонецЦикла;
СтруктураМассива.marks = Marks;
МассивЗапроса.Добавить(СтруктураМассива);
ДокументыКОтправке.Добавить(Выборка.Ссылка);
СоответствиеПоНомеру.Вставить(НомерДокумента, Выборка.Ссылка);
ДобавитьКлючиПоискаДокумента(СоответствиеПоНомеру, Выборка.Ссылка, Вывод.Номер, Префикс);
КонецЦикла;
Попытка
Результат = ВыполнитьЗапрос("/utip_curent/hs/tdp", МассивЗапроса, Сообщения);
Если Не ЗапросВыполненУспешно(Результат) Тогда
ДобавитьСообщение(Сообщения, "Ошибка отправки документов вывода из оборота: УТ11 не подтвердила запись.");
Возврат;
КонецЕсли;
ПодтвержденныеСсылки = ПодтвержденныеДокументы(Результат, ДокументыКОтправке, СоответствиеПоНомеру);
Если ПодтвержденныеСсылки.Количество() = 0 Тогда
ДобавитьСообщение(Сообщения, "Ошибка отправки документов вывода из оборота: УТ11 не подтвердила запись.");
СообщитьОшибкиЗаписиУТ(Результат, Сообщения);
Возврат;
КонецЕсли;
НачатьТранзакцию();
Попытка
Для Каждого СсылкаДокумента Из ПодтвержденныеСсылки Цикл
Вывод = СсылкаДокумента.ПолучитьОбъект();
Вывод.СтатусВыводаИзОборота = Перечисления.Status.Отправлен;
Вывод.Записать();
КонецЦикла;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
ДобавитьСообщение(Сообщения, "Отправлено документов: " + XMLСтрока(ПодтвержденныеСсылки.Количество()));
Если ПодтвержденныеСсылки.Количество() < ДокументыКОтправке.Количество() Тогда
ДобавитьСообщение(Сообщения, "Не записаны в УТ11: "
+ XMLСтрока(ДокументыКОтправке.Количество() - ПодтвержденныеСсылки.Количество())
+ ". Они остались в статусе «Готов к отправке».");
СообщитьОшибкиЗаписиУТ(Результат, Сообщения);
КонецЕсли;
Исключение
ДобавитьСообщение(Сообщения, "Ошибка отправки документов вывода из оборота. " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура ОбновитьСтатусыДокументовВыводаИзОборота(Сообщения)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВыводИзОборота.Ссылка КАК Ссылка,
| ВыводИзОборота.Номер КАК Номер,
| ВыводИзОборота.Дата КАК Дата
|ИЗ
| Документ.ВыводИзОборота КАК ВыводИзОборота
|ГДЕ
| ВыводИзОборота.СтатусВыводаИзОборота В (&Статусы)
| И ВыводИзОборота.ПометкаУдаления = ЛОЖЬ
|
|УПОРЯДОЧИТЬ ПО
| ВыводИзОборота.Дата,
| ВыводИзОборота.Номер";
Запрос.УстановитьПараметр("Статусы", СтатусыДляПроверкиВУТ());
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
Если РезультатЗапроса.Количество() = 0 Тогда
ДобавитьСообщение(Сообщения, "Нет документов для проверки статусов.");
Возврат;
КонецЕсли;
МассивЗапроса = Новый Массив;
СоответствиеПоНомеру = Новый Соответствие;
ИНН = Константы.ИНН.Получить();
Префикс = СокрЛП(Константы.Префикс.Получить());
Для Каждого Строка Из РезультатЗапроса Цикл
СтруктураМассива = Новый Структура("id,inn,prefix,tt,operation,dupd,nupd");
СтруктураМассива.id = НомерДокументаСтрокой(Строка.Номер);
СтруктураМассива.inn = ИНН;
СтруктураМассива.prefix = Префикс;
СтруктураМассива.tt = СокрЛП(Константы.ТТ.Получить());
СтруктураМассива.operation = Строка(Строка.Ссылка.Операция);
СтруктураМассива.dupd = Формат(Строка.Ссылка.dupd, "ДФ=dd.MM.yyyy");
СтруктураМассива.nupd = Строка(Строка.Ссылка.nupd);
МассивЗапроса.Добавить(СтруктураМассива);
ДобавитьКлючиПоискаДокумента(СоответствиеПоНомеру, Строка.Ссылка, Строка.Номер, Префикс);
КонецЦикла;
ДобавитьСообщение(Сообщения, "Проверка статусов документов: " + XMLСтрока(РезультатЗапроса.Количество()));
Попытка
Результат = ВыполнитьЗапрос("/utip_curent/hs/tdpd", МассивЗапроса, Сообщения);
Если Не ЗапросВыполненУспешно(Результат) Тогда
ДобавитьСообщение(Сообщения, "Ошибка получения статусов документов: УТ11 не вернула корректный ответ.");
Возврат;
КонецЕсли;
Доки = Неопределено;
Если ТипЗнч(Результат) = Тип("Соответствие") Тогда
Доки = Результат.Получить("docs");
КонецЕсли;
Если Не ЗначениеЗаполнено(Доки) Тогда
ДобавитьСообщение(Сообщения, "УТ11 не вернула статусы документов.");
Возврат;
КонецЕсли;
Обновлено = 0;
ИзмененияСтатусов = Новый Массив;
НачатьТранзакцию();
Попытка
Для Каждого Док Из Доки Цикл
Если Не ЭтоСтруктураОтветаУТ(Док) Тогда
Продолжить;
КонецЕсли;
НомерИзУТ = НомерИзОтветаУТ(Док);
ДокументСсылка = НайтиДокументПоКлючу(СоответствиеПоНомеру, НомерИзУТ, Префикс);
Если Не ЗначениеЗаполнено(ДокументСсылка) Тогда
ДокументСсылка = ПолучитьВыводИзОборота(НомерИзУТ);
КонецЕсли;
Если Не ЗначениеЗаполнено(ДокументСсылка) Тогда
Продолжить;
КонецЕсли;
НовыйСтатус = СтатусПоОтветуУТ(Док);
Если Не ЗначениеЗаполнено(НовыйСтатус) Тогда
Продолжить;
КонецЕсли;
ДокументОбъект = ДокументСсылка.ПолучитьОбъект();
Если ДокументОбъект.СтатусВыводаИзОборота = НовыйСтатус Тогда
Продолжить;
КонецЕсли;
СтарыйСтатус = Строка(ДокументОбъект.СтатусВыводаИзОборота);
ДокументОбъект.СтатусВыводаИзОборота = НовыйСтатус;
ДокументОбъект.Записать();
Обновлено = Обновлено + 1;
ИзмененияСтатусов.Добавить("Документ " + НомерДокументаСтрокой(ДокументОбъект.Номер)
+ ": " + СтарыйСтатус + " → " + Строка(НовыйСтатус));
КонецЦикла;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
Для Каждого СтрокаИзменения Из ИзмененияСтатусов Цикл
ДобавитьСообщение(Сообщения, СтрокаИзменения);
КонецЦикла;
Если Обновлено = 0 Тогда
ДобавитьСообщение(Сообщения, "Статусы проверены. Изменений нет.");
Иначе
ДобавитьСообщение(Сообщения, "Обновлены статусы документов: " + XMLСтрока(Обновлено));
КонецЕсли;
Исключение
ДобавитьСообщение(Сообщения, "Ошибка получения статусов документов. " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Функция СтатусыДляПроверкиВУТ()
Статусы = Новый Массив;
Статусы.Добавить(Перечисления.Status.Отправлен);
Статусы.Добавить(Перечисления.Status.ОшибкаВывода);
Возврат Статусы;
КонецФункции
Функция ПолучитьВыводИзОборота(Номер)
НомерЧисло = НомерДокументаЧислом(Номер);
Если НомерЧисло = Неопределено Тогда
Возврат Документы.ВыводИзОборота.ПустаяСсылка();
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ВыводИзОборота.Ссылка КАК Ссылка
|ИЗ
| Документ.ВыводИзОборота КАК ВыводИзОборота
|ГДЕ
| ВыводИзОборота.Номер = &Номер
| И ВыводИзОборота.Дата МЕЖДУ &Дата1 И &Дата2
|
|УПОРЯДОЧИТЬ ПО
| ВыводИзОборота.Дата УБЫВ";
Запрос.УстановитьПараметр("Номер", НомерЧисло);
Запрос.УстановитьПараметр("Дата1", НачалоГода(ДобавитьМесяц(ТекущаяДата(), -12)));
Запрос.УстановитьПараметр("Дата2", КонецГода(ТекущаяДата()));
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Ссылка;
КонецЕсли;
Возврат Документы.ВыводИзОборота.ПустаяСсылка();
КонецФункции
Функция ВыполнитьЗапрос(АдресРесурса, ПараметрыЗапроса = Неопределено, Сообщения = Неопределено)
СерверИсточник = Константы.Сервер.Получить();
ИмяФайлаЗапроса = "";
Попытка
HTTPСоединение = Новый HTTPСоединение(
СерверИсточник,
80,
Константы.Логин.Получить(),
Константы.Пароль.Получить(),
,
60);
Исключение
ДобавитьСообщение(Сообщения, "Не удалось соединиться с сервером: " + СерверИсточник);
Возврат Ложь;
КонецПопытки;
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json");
Если ЗначениеЗаполнено(ПараметрыЗапроса) Тогда
ИмяФайлаЗапроса = ПолучитьИмяВременногоФайла("json");
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ИмяФайлаЗапроса);
ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса);
ЗаписьJSON.Закрыть();
ФайлОтправки = Новый Файл(ИмяФайлаЗапроса);
Заголовки.Вставить("Content-Length", XMLСтрока(ФайлОтправки.Размер()));
КонецЕсли;
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
РезультатВозврата = Ложь;
Попытка
Если ЗначениеЗаполнено(ПараметрыЗапроса) Тогда
HTTPЗапрос.УстановитьИмяФайлаТела(ИмяФайлаЗапроса);
Результат = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Иначе
Результат = HTTPСоединение.Получить(HTTPЗапрос);
КонецЕсли;
РезультатСтрока = Результат.ПолучитьТелоКакСтроку("UTF-8");
Если Результат.КодСостояния < 200 Или Результат.КодСостояния > 299 Тогда
ДобавитьСообщение(Сообщения, "УТ11 вернула код " + XMLСтрока(Результат.КодСостояния)
+ ?(ПустаяСтрока(РезультатСтрока), "", ": " + РезультатСтрока));
ИначеЕсли ПустаяСтрока(СокрЛП(РезультатСтрока)) Тогда
ДобавитьСообщение(Сообщения, "УТ11 вернула пустой ответ.");
Иначе
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(РезультатСтрока);
ОбъектJSON = ПрочитатьJSON(ЧтениеJSON, Истина);
Если ОтветСодержитОшибку(ОбъектJSON) Тогда
ДобавитьСообщение(Сообщения, ТекстОшибкиИзОтвета(ОбъектJSON));
Иначе
РезультатВозврата = ОбъектJSON;
КонецЕсли;
КонецЕсли;
Исключение
ДобавитьСообщение(Сообщения, ОписаниеОшибки());
РезультатВозврата = Ложь;
КонецПопытки;
Если Не ПустаяСтрока(ИмяФайлаЗапроса) Тогда
Попытка
УдалитьФайлы(ИмяФайлаЗапроса);
Исключение
КонецПопытки;
КонецЕсли;
Возврат РезультатВозврата;
КонецФункции
Функция ЗапросВыполненУспешно(Результат)
Возврат Результат <> Ложь И Результат <> Неопределено;
КонецФункции
Функция ОтветСодержитОшибку(Результат)
Если ТипЗнч(Результат) <> Тип("Соответствие") Тогда
Возврат Ложь;
КонецЕсли;
Ошибка = Результат.Получить("error");
Если ЗначениеЗаполнено(Ошибка) Тогда
Возврат Истина;
КонецЕсли;
Ошибки = Результат.Получить("errors");
Если ЗначениеЗаполнено(Ошибки) Тогда
Возврат Истина;
КонецЕсли;
Успех = Результат.Получить("result");
Если Успех = Ложь Или Успех = "false" Или Успех = "error" Тогда
Возврат Истина;
КонецЕсли;
Успех = Результат.Получить("success");
Если Успех = Ложь Или Успех = "false" Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ТекстОшибкиИзОтвета(Результат)
Ошибка = Результат.Получить("error");
Если ЗначениеЗаполнено(Ошибка) Тогда
Возврат Строка(Ошибка);
КонецЕсли;
Ошибки = Результат.Получить("errors");
Если ЗначениеЗаполнено(Ошибки) Тогда
Возврат Строка(Ошибки);
КонецЕсли;
Возврат "УТ11 вернула ошибку записи документа.";
КонецФункции
Функция ПодтвержденныеДокументы(Результат, ДокументыКОтправке, СоответствиеПоНомеру)
Подтвержденные = Новый Массив;
СписокИзОтвета = СписокДокументовИзОтвета(Результат);
Если Не ЗначениеЗаполнено(СписокИзОтвета) Тогда
Возврат Подтвержденные;
КонецЕсли;
Префикс = СокрЛП(Константы.Префикс.Получить());
Для Каждого Элемент Из СписокИзОтвета Цикл
Если Не ЭтоСтруктураОтветаУТ(Элемент) Тогда
Продолжить;
КонецЕсли;
Если Не СтатусОтветаЭтоУспешнаяЗапись(Элемент) Тогда
Продолжить;
КонецЕсли;
НомерИзУТ = НомерИзОтветаУТ(Элемент);
СсылкаДокумента = НайтиДокументПоКлючу(СоответствиеПоНомеру, НомерИзУТ, Префикс);
Если ЗначениеЗаполнено(СсылкаДокумента) И Подтвержденные.Найти(СсылкаДокумента) = Неопределено Тогда
Подтвержденные.Добавить(СсылкаДокумента);
КонецЕсли;
КонецЦикла;
Возврат Подтвержденные;
КонецФункции
Функция СписокДокументовИзОтвета(Результат)
Если ТипЗнч(Результат) = Тип("Соответствие") Тогда
СписокИзОтвета = Результат.Получить("docs");
Если СписокИзОтвета = Неопределено Тогда
СписокИзОтвета = Результат.Получить("ids");
КонецЕсли;
Возврат СписокИзОтвета;
ИначеЕсли ТипЗнч(Результат) = Тип("Массив") Тогда
Возврат Результат;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Процедура СообщитьОшибкиЗаписиУТ(Результат, Сообщения)
СписокИзОтвета = СписокДокументовИзОтвета(Результат);
Если Не ЗначениеЗаполнено(СписокИзОтвета) Тогда
Возврат;
КонецЕсли;
Для Каждого Элемент Из СписокИзОтвета Цикл
Если Не ЭтоСтруктураОтветаУТ(Элемент) Тогда
Продолжить;
КонецЕсли;
Если СтатусОтветаЭтоУспешнаяЗапись(Элемент) Тогда
Продолжить;
КонецЕсли;
СтатусУТ = СокрЛП(Строка(ЗначениеПоляОтвета(Элемент, "status")));
Если Не ПустаяСтрока(СтатусУТ) Тогда
ДобавитьСообщение(Сообщения, "УТ11: " + Строка(НомерИзОтветаУТ(Элемент)) + " — " + СтатусУТ);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ЭтоСтруктураОтветаУТ(Элемент)
Возврат ТипЗнч(Элемент) = Тип("Соответствие") Или ТипЗнч(Элемент) = Тип("Структура");
КонецФункции
Функция ЗначениеПоляОтвета(Элемент, ИмяПоля)
Если ТипЗнч(Элемент) = Тип("Соответствие") Тогда
Возврат Элемент.Получить(ИмяПоля);
ИначеЕсли ТипЗнч(Элемент) = Тип("Структура") Тогда
Если Элемент.Свойство(ИмяПоля) Тогда
Возврат Элемент[ИмяПоля];
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Функция НомерИзОтветаУТ(Элемент)
Если Не ЭтоСтруктураОтветаУТ(Элемент) Тогда
Возврат Неопределено;
КонецЕсли;
НомерИзУТ = ЗначениеПоляОтвета(Элемент, "docnom");
Если НомерИзУТ = Неопределено Тогда
НомерИзУТ = ЗначениеПоляОтвета(Элемент, "id");
КонецЕсли;
Если НомерИзУТ = Неопределено Тогда
НомерИзУТ = ЗначениеПоляОтвета(Элемент, "number");
КонецЕсли;
Возврат НомерИзУТ;
КонецФункции
Функция СтатусОтветаСтрокой(Элемент)
Возврат НРег(СокрЛП(Строка(ЗначениеПоляОтвета(Элемент, "status"))));
КонецФункции
Функция СтатусОтветаЭтоУспешнаяЗапись(Элемент)
СтатусУТ = СтатусОтветаСтрокой(Элемент);
Возврат СтатусУТ = "отправлен" Или СтатусУТ = "sent" Или СтатусУТ = "ok";
КонецФункции
Функция СтатусПоОтветуУТ(Док)
Если Не ЭтоСтруктураОтветаУТ(Док) Тогда
Возврат Неопределено;
КонецЕсли;
Если ЗначениеЗаполнено(ЗначениеПоляОтвета(Док, "error")) Тогда
Возврат Перечисления.Status.ОшибкаВывода;
КонецЕсли;
СтатусУТ = СтатусОтветаСтрокой(Док);
Если ПустаяСтрока(СтатусУТ) Тогда
Возврат Неопределено;
КонецЕсли;
Если СтатусУТ = "выведен из оборота" Или СтатусУТ = "выведенизоборота" Тогда
Возврат Перечисления.Status.ВыведенИзОборота;
КонецЕсли;
Если СтатусУТ = "отправлен" Или СтатусУТ = "sent" Тогда
Возврат Неопределено;
КонецЕсли;
Возврат Перечисления.Status.ОшибкаВывода;
КонецФункции
Функция НомерДокументаСтрокой(Номер)
Возврат Формат(Номер, "ЧГ=0");
КонецФункции
Функция НомерДокументаЧислом(Номер)
Если ТипЗнч(Номер) = Тип("Число") Тогда
Возврат Номер;
КонецЕсли;
СтрокаНомера = СокрЛП(Строка(Номер));
СтрокаНомера = СтрЗаменить(СтрокаНомера, Символы.НПП, "");
СтрокаНомера = СтрЗаменить(СтрокаНомера, " ", "");
Префикс = СокрЛП(Константы.Префикс.Получить());
Если Не ПустаяСтрока(Префикс) И ВРег(Лев(СтрокаНомера, СтрДлина(Префикс))) = ВРег(Префикс) Тогда
СтрокаНомера = СокрЛП(Сред(СтрокаНомера, СтрДлина(Префикс) + 1));
КонецЕсли;
Если Лев(СтрокаНомера, 1) = "-" Тогда
СтрокаНомера = СокрЛП(Сред(СтрокаНомера, 2));
КонецЕсли;
Цифры = "";
Для Индекс = 1 По СтрДлина(СтрокаНомера) Цикл
Символ = Сред(СтрокаНомера, Индекс, 1);
Если СтрНайти("0123456789", Символ) > 0 Тогда
Цифры = Цифры + Символ;
КонецЕсли;
КонецЦикла;
Если ПустаяСтрока(Цифры) Тогда
Возврат Неопределено;
КонецЕсли;
Попытка
Возврат Число(Цифры);
Исключение
Возврат Неопределено;
КонецПопытки;
КонецФункции
Процедура ДобавитьКлючиПоискаДокумента(СоответствиеПоНомеру, СсылкаДокумента, Номер, Префикс)
НомерСтрокой = НомерДокументаСтрокой(Номер);
СоответствиеПоНомеру.Вставить(НомерСтрокой, СсылкаДокумента);
СоответствиеПоНомеру.Вставить(XMLСтрока(Номер), СсылкаДокумента);
Если Не ПустаяСтрока(Префикс) Тогда
СоответствиеПоНомеру.Вставить(Префикс + НомерСтрокой, СсылкаДокумента);
СоответствиеПоНомеру.Вставить(Префикс + "-" + НомерСтрокой, СсылкаДокумента);
СоответствиеПоНомеру.Вставить(Префикс + Прав("0000000000" + НомерСтрокой, 10), СсылкаДокумента);
СоответствиеПоНомеру.Вставить(Префикс + "-" + Прав("0000000000" + НомерСтрокой, 10), СсылкаДокумента);
КонецЕсли;
КонецПроцедуры
Функция НайтиДокументПоКлючу(СоответствиеПоНомеру, НомерИзУТ, Префикс)
Если НомерИзУТ = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Ключи = Новый Массив;
Ключи.Добавить(СокрЛП(Строка(НомерИзУТ)));
Ключи.Добавить(НомерДокументаСтрокой(НомерИзУТ));
НомерЧисло = НомерДокументаЧислом(НомерИзУТ);
Если НомерЧисло <> Неопределено Тогда
Ключи.Добавить(НомерДокументаСтрокой(НомерЧисло));
Если Не ПустаяСтрока(Префикс) Тогда
НомерКакВУТ = НомерДокументаСтрокой(НомерЧисло);
Ключи.Добавить(Префикс + НомерКакВУТ);
Ключи.Добавить(Префикс + "-" + НомерКакВУТ);
Ключи.Добавить(Префикс + Прав("0000000000" + НомерКакВУТ, 10));
Ключи.Добавить(Префикс + "-" + Прав("0000000000" + НомерКакВУТ, 10));
КонецЕсли;
КонецЕсли;
Для Каждого Ключ Из Ключи Цикл
Если Не ЗначениеЗаполнено(Ключ) Тогда
Продолжить;
КонецЕсли;
СсылкаДокумента = СоответствиеПоНомеру.Получить(Ключ);
Если ЗначениеЗаполнено(СсылкаДокумента) Тогда
Возврат СсылкаДокумента;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Процедура ДобавитьСообщение(Сообщения, Текст)
Если Сообщения = Неопределено Или Не ЗначениеЗаполнено(Текст) Тогда
Возврат;
КонецЕсли;
Сообщения.Добавить(Текст);
КонецПроцедуры
Функция ТекстИзСообщений(Сообщения)
Результат = "";
Для Каждого СтрокаСообщения Из Сообщения Цикл
Если Не ПустаяСтрока(Результат) Тогда
Результат = Результат + Символы.ПС;
КонецЕсли;
Результат = Результат + СтрокаСообщения;
КонецЦикла;
Возврат Результат;
КонецФункции