///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область СлужебныйПрограммныйИнтерфейс

// Функция по переданному идентификатору скачивает файл из сервиса передачи файлов.
//
// Параметры:
//  ИдентификаторФайла       - УникальныйИдентификатор - идентификатор получаемого файла.
//  УзелИнформационнойБазы   - ПланОбменаСсылка - узел плана обмена, для которого необходимо получить файл.
//  РазмерЧасти              - Число - размер части в килобайтах. Если значение равно 0,
//                             то разбивка на части не производится.
//  ПараметрыАутентификации  - Структура: АдресСервиса, ИмяПользователя, ПарольПользователя.
//
// Возвращаемое значение:
//  Строка - путь к полученному файлу.
//
Функция ПолучитьФайлИзХранилищаВСервисе(Прокси, Знач ИдентификаторФайла, Знач УзелИнформационнойБазы = Неопределено,
	Знач РазмерЧасти = 1024, Знач ОбластьДанных = 0) Экспорт
	
	// Возвращаемое значение функции.
	ИмяФайлаРезультата = "";
	
	ИдентификаторСессии = Неопределено;
	КоличествоЧастей    = Неопределено;
	
	ПодготовитьФайлДляПолучения(Прокси, ИдентификаторФайла, РазмерЧасти, ИдентификаторСессии, КоличествоЧастей, ОбластьДанных);
	
	ИменаФайлов = Новый Массив;
	
	КаталогСборки = ПолучитьИмяВременногоФайла();
	СоздатьКаталог(КаталогСборки);
	
	ШаблонИмениФайла = "data.zip.[n]";
	
	// Протоколирование событий обмена.
	Если ЗначениеЗаполнено(УзелИнформационнойБазы) Тогда
		
		СтруктураНастроекОбмена = ОбменДаннымиСервер.НастройкиОбменаДляУзлаИнформационнойБазы(
			УзелИнформационнойБазы, Перечисления.ДействияПриОбмене.ВыгрузкаДанных);

		СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации = ОбменДаннымиСервер.КлючСообщенияЖурналаРегистрации(
			УзелИнформационнойБазы, Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
		
		Комментарий = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Начало получения сообщения обмена из Интернета (количество частей файла %1).'"),
			Формат(КоличествоЧастей, "ЧН=0; ЧГ=0"));
			
		ОбменДаннымиСервер.ЗаписьЖурналаРегистрацииОбменаДанными(Комментарий, СтруктураНастроекОбмена);
		
	КонецЕсли;
	
	Для НомерЧасти = 1 По КоличествоЧастей Цикл
		
		ДанныеЧасти = Неопределено; // ДвоичныеДанные
		
		Попытка
			ПолучитьЧастьФайла(Прокси, ИдентификаторСессии, НомерЧасти, ДанныеЧасти, ОбластьДанных);
		Исключение
			Прокси.ReleaseFile(ИдентификаторСессии);
			ВызватьИсключение;
		КонецПопытки;
		
		ИмяФайла = СтрЗаменить(ШаблонИмениФайла, "[n]", Формат(НомерЧасти, "ЧГ=0"));
		ИмяФайлаЧасти = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогСборки, ИмяФайла);
		
		ДанныеЧасти.Записать(ИмяФайлаЧасти);
		ИменаФайлов.Добавить(ИмяФайлаЧасти);
		
	КонецЦикла;
	
	ДанныеЧасти = Неопределено;
	
	Прокси.ReleaseFile(ИдентификаторСессии);
	
	ИмяАрхива = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогСборки, "data.zip");
	
	ОбъединитьФайлы(ИменаФайлов, ИмяАрхива);
		
	Разархиватор = Новый ЧтениеZipФайла(ИмяАрхива);
	Если Разархиватор.Элементы.Количество() = 0 Тогда
		Попытка
			УдалитьФайлы(КаталогСборки);
		Исключение
			ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУдалениеВременногоФайла(),
				УровеньЖурналаРегистрации.Ошибка,,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		КонецПопытки;
		ВызватьИсключение(НСтр("ru = 'Файл архива не содержит данных.'"));
	КонецЕсли;
	
	// Протоколирование событий обмена.
	ФайлАрхива = Новый Файл(ИмяАрхива);
	
	Если ЗначениеЗаполнено(УзелИнформационнойБазы) Тогда
	
		Комментарий = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Окончание получения сообщения обмена из Интернета (размер сжатого сообщения обмена %1 Мб).'"),
			Формат(Окр(ФайлАрхива.Размер() / 1024 / 1024, 3), "ЧН=0; ЧГ=0"));
			
		ОбменДаннымиСервер.ЗаписьЖурналаРегистрацииОбменаДанными(Комментарий, СтруктураНастроекОбмена);
	
	КонецЕсли;
	
	ЭлементАрхива = Разархиватор.Элементы.Получить(0);
	ИмяФайла = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогСборки, ЭлементАрхива.Имя);
	
	Разархиватор.Извлечь(ЭлементАрхива, КаталогСборки);
	Разархиватор.Закрыть();
	
	Файл = Новый Файл(ИмяФайла);
	
	ВременныйКаталог = ПолучитьИмяВременногоФайла(); //АПК:441 удаление каталога происходит при получении данных обмена в другой ИБ
	СоздатьКаталог(ВременныйКаталог);
	
	ИмяФайлаРезультата = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(ВременныйКаталог, Файл.Имя);
	
	ПереместитьФайл(ИмяФайла, ИмяФайлаРезультата);
	
	Попытка
		УдалитьФайлы(КаталогСборки);
	Исключение
		ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУдалениеВременногоФайла(),
			УровеньЖурналаРегистрации.Ошибка,,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
	КонецПопытки;
		
	Возврат ИмяФайлаРезультата;
	
КонецФункции

// Функция передает указанный файл в сервис передачи файлов.
//
// Параметры:
//  Прокси
//  СтруктураНастроекОбмена  - Структура - структура со всеми необходимыми данными и объектами для выполнения обмена.
//  ИмяФайла                 - Строка - путь к передаваемому файлу.
//  УзелИнформационнойБазы   - ПланОбменаСсылка - узел плана обмена, для которого необходимо получить файл. 
//  РазмерЧастиКБ            - Число - размер части в килобайтах. Если значение равно 0,
//                             то разбивка на части не производится.
//  ИдентификаторФайла       - УникальныйИдентификатор - идентификатор помещаемого в сервис файла.
//
// Возвращаемое значение:
//  УникальныйИдентификатор  - идентификатор файла в сервисе передачи файлов.
//
Функция ПоместитьФайлВХранилищеВСервисе(Прокси, Знач ИмяФайла, 
	Знач РазмерЧастиКБ = 1024, ИдентификаторФайла = Неопределено, ОбластьДанных = 0) Экспорт
	
	Если Прокси = Неопределено Тогда
		
		ВызватьИсключение НСтр("ru ='Не определен WS-прокси передачи файла выгрузки в базу приемник. 
			|Обратитесь к администратору.'", ОбщегоНазначения.КодОсновногоЯзыка());
		
	КонецЕсли;
	
	КаталогФайлов = ПолучитьИмяВременногоФайла();
	СоздатьКаталог(КаталогФайлов);
	
	// Архивирование файла.
	ИмяНеразделенногоФайла = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогФайлов, "data.zip");
	Архиватор = Новый ЗаписьZipФайла(ИмяНеразделенногоФайла,,,, УровеньСжатияZIP.Максимальный);
	Архиватор.Добавить(ИмяФайла);
	Архиватор.Записать();
	
	// Разделение файла на части.
	ИдентификаторСессии = Новый УникальныйИдентификатор;
	
	РазмерЧастиВБайтах = РазмерЧастиКБ * 1024;
	ИменаФайлов = РазделитьФайл(ИмяНеразделенногоФайла, РазмерЧастиВБайтах);
	
	КоличествоЧастей = ИменаФайлов.Количество();
	Для НомерЧасти = 1 По КоличествоЧастей Цикл
		
		ИмяФайлаЧасти = ИменаФайлов[НомерЧасти - 1];
		ДанныеФайла = Новый ДвоичныеДанные(ИмяФайлаЧасти);
		ПоместитьЧастьФайла(Прокси, ИдентификаторСессии, НомерЧасти, ДанныеФайла, ОбластьДанных);
		
	КонецЦикла;
	
	Попытка
		УдалитьФайлы(КаталогФайлов);
	Исключение
		ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУдалениеВременногоФайла(),
			УровеньЖурналаРегистрации.Ошибка,,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
	КонецПопытки;
	
	СобратьФайлИзЧастей(Прокси, ИдентификаторСессии, КоличествоЧастей, ИдентификаторФайла, ОбластьДанных);
	
	Возврат ИдентификаторФайла;
	
КонецФункции

Функция ПолучитьWSПроксиПоПараметрамПодключения(
					СтруктураНастроек,
					СтрокаСообщенияОбОшибке = "",
					СообщениеПользователю = "",
					ДелатьКонтрольныйВызов = Ложь) Экспорт
	
	Попытка
		ПроверитьКорректностьФорматаАдресаWSПрокси(СтруктураНастроек.WSURLВебСервиса);
	Исключение
		СообщениеПользователю = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		СтрокаСообщенияОбОшибке = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису(), УровеньЖурналаРегистрации.Ошибка,,, СтрокаСообщенияОбОшибке);
		Возврат Неопределено;
	КонецПопытки;

	Попытка
		ПроверитьНедопустимыеСимволыВИмениПользователяWSПрокси(СтруктураНастроек.WSИмяПользователя);
	Исключение
		СообщениеПользователю = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		СтрокаСообщенияОбОшибке = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису(), УровеньЖурналаРегистрации.Ошибка,,, СтрокаСообщенияОбОшибке);
		Возврат Неопределено;
	КонецПопытки;
	
	МестоположениеWSDL = "[URLВебСервиса]/ws/[ИмяСервиса]?wsdl";
	МестоположениеWSDL = СтрЗаменить(МестоположениеWSDL, "[URLВебСервиса]", СтруктураНастроек.WSURLВебСервиса);
	МестоположениеWSDL = СтрЗаменить(МестоположениеWSDL, "[ИмяСервиса]",    СтруктураНастроек.WSИмяСервиса);
	
	ПараметрыПодключения = ОбщегоНазначения.ПараметрыПодключенияWSПрокси();
	ПараметрыПодключения.АдресWSDL = МестоположениеWSDL;
	ПараметрыПодключения.URIПространстваИмен = СтруктураНастроек.WSURLПространстваИменСервиса;
	ПараметрыПодключения.ИмяСервиса = СтруктураНастроек.WSИмяСервиса;
	ПараметрыПодключения.ИмяПользователя = СтруктураНастроек.WSИмяПользователя; 
	ПараметрыПодключения.Пароль = СтруктураНастроек.WSПароль;
	ПараметрыПодключения.Таймаут = СтруктураНастроек.WSТаймаут;
	ПараметрыПодключения.ДелатьКонтрольныйВызов = ДелатьКонтрольныйВызов;
	
	Попытка
		WSПрокси = ОбщегоНазначения.СоздатьWSПрокси(ПараметрыПодключения);
	Исключение
		СообщениеПользователю = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		СтрокаСообщенияОбОшибке = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису(), УровеньЖурналаРегистрации.Ошибка,,, СтрокаСообщенияОбОшибке);
		Возврат Неопределено;
	КонецПопытки;
	
	Возврат WSПрокси;
КонецФункции

Функция WSПрокси(ПараметрыПодключения, СообщениеОбОшибке = "", СообщениеПользователю = "") Экспорт
	
	Попытка
		ПроверитьКорректностьФорматаАдресаWSПрокси(ПараметрыПодключения.АдресВебСервиса);
	Исключение
		СообщениеПользователю = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		СообщениеОбОшибке = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису(), УровеньЖурналаРегистрации.Ошибка,,, СообщениеОбОшибке);
		Возврат Неопределено;
	КонецПопытки;

	Попытка
		ПроверитьНедопустимыеСимволыВИмениПользователяWSПрокси(ПараметрыПодключения.ИмяПользователя);
	Исключение
		СообщениеПользователю = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		СообщениеОбОшибке = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису(), УровеньЖурналаРегистрации.Ошибка,,, СообщениеОбОшибке);
		Возврат Неопределено;
	КонецПопытки;

	Попытка
		СтруктураНастроек = Новый Структура;
		СтруктураНастроек.Вставить("WSURLВебСервиса", ПараметрыПодключения.АдресВебСервиса);
		СтруктураНастроек.Вставить("WSИмяПользователя", ПараметрыПодключения.ИмяПользователя);
		СтруктураНастроек.Вставить("WSПароль", ПараметрыПодключения.Пароль);
		ВерсииКорреспондента = ОбменДаннымиПовтИсп.ВерсииКорреспондента(СтруктураНастроек);
	Исключение
		СообщениеОбОшибке = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		Возврат Неопределено;
	КонецПопытки;
		
	ВерсияИнтерфейса = МаксимальнаяОбщаяВерсияИнтерфейсаОбмена(ВерсииКорреспондента);
	
	Если ВерсияИнтерфейса = "0.0.0.0" Тогда
		ВерсияДляАдреса = "";
	Иначе
		ВерсияДляАдреса = "_" + СтрЗаменить(ВерсияИнтерфейса, ".", "_");
	КонецЕсли;
	
	ОбменДаннымиСервер.УдалитьНезначащиеСимволыВНастройкахПодключения(ПараметрыПодключения);
	
	ПараметрыПодключения.Вставить("URIПространстваИмен", "http://www.1c.ru/SSL/Exchange" + ВерсияДляАдреса);
	ПараметрыПодключения.Вставить("ИмяСервиса", "Exchange" + ВерсияДляАдреса);
	
	Если Не ПараметрыПодключения.Свойство("Таймаут") Тогда
		ПараметрыПодключения.Вставить("Таймаут", 600);
	КонецЕсли;
	
	Если Не ПараметрыПодключения.Свойство("ДелатьКонтрольныйВызов") Тогда
		ПараметрыПодключения.Вставить("ДелатьКонтрольныйВызов", Истина);
	КонецЕсли;
		
	МестоположениеWSDL = "[URLВебСервиса]/ws/[ИмяСервиса]?wsdl";
	МестоположениеWSDL = СтрЗаменить(МестоположениеWSDL, "[URLВебСервиса]", ПараметрыПодключения.АдресВебСервиса);
	МестоположениеWSDL = СтрЗаменить(МестоположениеWSDL, "[ИмяСервиса]",    ПараметрыПодключения.ИмяСервиса);
	
	ПараметрыПодключения.Вставить("АдресWSDL", МестоположениеWSDL);
	
	ПараметрыПодключения.Вставить("ИмяТочкиПодключения");
	ПараметрыПодключения.Вставить("ИспользоватьАутентификациюОС", Ложь);
	ПараметрыПодключения.Вставить("Местоположение");
	ПараметрыПодключения.Вставить("ЗащищенноеСоединение");
	
	Попытка
		WSПрокси = ОбщегоНазначения.СоздатьWSПрокси(ПараметрыПодключения);
	Исключение
		СообщениеПользователю = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		СообщениеОбОшибке = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису(), УровеньЖурналаРегистрации.Ошибка,,, СообщениеОбОшибке);
		Возврат Неопределено;
	КонецПопытки;
	
	Возврат WSПрокси;
	
КонецФункции

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

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

Процедура ВыполнитьЗагрузкуДляУзлаИнформационнойБазыИзСервисаПередачиФайлов(ПараметрыПроцедуры, АдресХранилища) Экспорт
	
	ИмяПланаОбмена            = ПараметрыПроцедуры["ИмяПланаОбмена"];
	КодУзлаИнформационнойБазы = ПараметрыПроцедуры["КодУзлаИнформационнойБазы"];
	ИдентификаторФайла        = ПараметрыПроцедуры["ИдентификаторФайла"];
	
	УстановитьПривилегированныйРежим(Истина);
	
	ИмяВременногоФайла = ОбменДаннымиСервер.ПолучитьФайлИзХранилища(ИдентификаторФайла);
	
	ПараметрыОбменаДанными = ОбменДаннымиСервер.ПараметрыОбменаДаннымиЧерезФайлИлиСтроку();
	
	ПараметрыОбменаДанными.ПолноеИмяФайлаСообщенияОбмена = ИмяВременногоФайла;
	ПараметрыОбменаДанными.ДействиеПриОбмене             = Перечисления.ДействияПриОбмене.ЗагрузкаДанных;
	ПараметрыОбменаДанными.ИмяПланаОбмена                = ИмяПланаОбмена;
	ПараметрыОбменаДанными.КодУзлаИнформационнойБазы     = КодУзлаИнформационнойБазы;
	
	Попытка
		ОбменДаннымиСервер.ВыполнитьОбменДаннымиДляУзлаИнформационнойБазыЧерезФайлИлиСтроку(ПараметрыОбменаДанными);
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		УдалитьФайлы(ИмяВременногоФайла);
		ВызватьИсключение ПредставлениеОшибки;
	КонецПопытки;
	
	УдалитьФайлы(ИмяВременногоФайла);
КонецПроцедуры

// Соответствует операции UploadData
Процедура ВыполнитьВыгрузкуДанных(Прокси, СтруктураНастроекОбмена, ПараметрыОбмена, ОбластьДанных = 0) Экспорт
	
	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Прокси.UploadData(
			СтруктураНастроекОбмена.ИмяПланаОбменаКорреспондента,
			СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
			ПараметрыОбмена.ИдентификаторФайла,
			ПараметрыОбмена.ДлительнаяОперация,
			ПараметрыОбмена.ИдентификаторОперации,
			ПараметрыОбмена.ДлительнаяОперацияРазрешена,
			ОбластьДанных);

	Иначе
					
		Прокси.UploadData(
			СтруктураНастроекОбмена.ИмяПланаОбмена,
			СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
			ПараметрыОбмена.ИдентификаторФайла,
			ПараметрыОбмена.ДлительнаяОперация,
			ПараметрыОбмена.ИдентификаторОперации,
			ПараметрыОбмена.ДлительнаяОперацияРазрешена);
			
	КонецЕсли;

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

// Соответствует операции DownloadData.
Процедура ВыполнитьЗагрузкуДанных(Прокси, СтруктураНастроекОбмена, ПараметрыОбмена, ИдентификаторФайлаСтрокой, ОбластьДанных = 0) Экспорт
	
	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Прокси.DownloadData(
			СтруктураНастроекОбмена.ИмяПланаОбменаКорреспондента,
			СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
			ИдентификаторФайлаСтрокой,
			ПараметрыОбмена.ДлительнаяОперация,
			ПараметрыОбмена.ИдентификаторОперации,
			ПараметрыОбмена.ДлительнаяОперацияРазрешена,
			ОбластьДанных);
		
	Иначе
		
		Прокси.DownloadData(
			СтруктураНастроекОбмена.ИмяПланаОбмена,
			СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
			ИдентификаторФайлаСтрокой,
			ПараметрыОбмена.ДлительнаяОперация,
			ПараметрыОбмена.ИдентификаторОперации,
			ПараметрыОбмена.ДлительнаяОперацияРазрешена);
			
	КонецЕсли;

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

// Соответствует операции GetIBParameters.

Функция ПолучитьПараметрыИБ(Прокси, ИмяПланаОбмена, КодУзла, СообщениеОбОшибке, ОбластьДанных = 0, ДополнительныеПараметры = Неопределено) Экспорт
	
	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если Версия3_0_2_2(ВерсияПрокси) Тогда
		
		Если ДополнительныеПараметры = Неопределено Тогда
			ДополнительныеПараметры = Новый Структура;
		КонецЕсли;
		
		ДополнительныеПараметрыXDTO = СериализаторXDTO.ЗаписатьXDTO(ДополнительныеПараметры);
		
		Возврат Прокси.GetIBParameters(ИмяПланаОбмена, КодУзла, СообщениеОбОшибке, ОбластьДанных, ДополнительныеПараметрыXDTO);
		
	ИначеЕсли Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Возврат Прокси.GetIBParameters(ИмяПланаОбмена, КодУзла, СообщениеОбОшибке, ОбластьДанных);
			
	Иначе
		
		Возврат Прокси.GetIBParameters(ИмяПланаОбмена, КодУзла, СообщениеОбОшибке);
		
	КонецЕсли;
	
КонецФункции 

// Соответствует операции PutMessageForDataMatching
Процедура ПоместитьСообщениеДляСопоставленияДанных(Прокси, СтруктураНастроекОбмена, ИдентификаторФайлаСтрокой, ОбластьДанных = 0) Экспорт
	
	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Прокси.PutMessageForDataMatching(СтруктураНастроекОбмена.ИмяПланаОбменаКорреспондента,
			СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
			ИдентификаторФайлаСтрокой,
			ОбластьДанных);
		
	Иначе
		
		Прокси.PutMessageForDataMatching(СтруктураНастроекОбмена.ИмяПланаОбмена,
			СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
			ИдентификаторФайлаСтрокой);
	
	КонецЕсли;
	
КонецПроцедуры

// Соответствует операции RemoveExchangeNode
Процедура УдалитьУзелОбмена(Прокси, СтруктураНастроекОбмена, ОбластьДанных = 0) Экспорт
	
	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Прокси.RemoveExchangeNode(СтруктураНастроекОбмена.ИмяПланаОбменаКорреспондента,
			СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
			ОбластьДанных);
			
	Иначе
	
		Прокси.RemoveExchangeNode(СтруктураНастроекОбмена.ИмяПланаОбмена, СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод);
		
	КонецЕсли;
	
КонецПроцедуры

// Соответствует операции CreateExchangeNode
Процедура СоздатьУзелОбмена(Прокси, ПараметрыПодключения, ОбластьДанных = 0) Экспорт
	
	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Сериализатор = Новый СериализаторXDTO(Прокси.ФабрикаXDTO);
	
	Если Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Прокси.CreateExchangeNode(Сериализатор.ЗаписатьXDTO(ПараметрыПодключения), ОбластьДанных);
		
	Иначе
		
		Прокси.CreateExchangeNode(Сериализатор.ЗаписатьXDTO(ПараметрыПодключения));
		
	КонецЕсли;
	
КонецПроцедуры

// Возвращаемое значение:
//   Строка
//
Функция СобытиеЖурналаРегистрацииУдалениеВременногоФайла() Экспорт
	
	Возврат НСтр("ru = 'Обмен данными.Удаление временного файла'", ОбщегоНазначения.КодОсновногоЯзыка());
	
КонецФункции

// Возвращаемое значение:
//   Строка
//
Функция СобытиеЖурналаРегистрацииИзменениеТранспортаНаWS() Экспорт
	
	Возврат НСтр("ru = 'Обмен данными.Изменение транспорта на WS'", ОбщегоНазначения.КодОсновногоЯзыка());
	
КонецФункции

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

// Возвращаемое значение:
//   Строка
//
Функция СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису()
	
	Возврат НСтр("ru = 'Обмен данными.Установка подключения к web-сервису'", ОбщегоНазначения.КодОсновногоЯзыка());
	
КонецФункции

Процедура ОжиданиеЗавершенияОперации(СтруктураНастроекОбмена, ПараметрыОбмена, Прокси, ДействиеПриОбменеВЭтойИБ = Неопределено) Экспорт
	
	Если ПараметрыОбмена.ИнтервалОжиданияНаСервере = 0 Тогда
		
		Если ДействиеПриОбменеВЭтойИБ <> Неопределено Тогда
			
			// В этой ИБ "Загрузка", значит в корреспонденте "Выгрузка"
			Если ДействиеПриОбменеВЭтойИБ = Перечисления.ДействияПриОбмене.ЗагрузкаДанных Тогда
				
				ДействиеВКорреспондентеСтрокой = НСтр("ru ='выгрузка'", ОбщегоНазначения.КодОсновногоЯзыка());
				
			Иначе
				
				ДействиеВКорреспондентеСтрокой = НСтр("ru ='загрузка'", ОбщегоНазначения.КодОсновногоЯзыка());
				
			КонецЕсли;
			
			ШаблонСообщения = НСтр("ru = 'Ожидание выполнения операции (%1 данных в базе-корреспонденте)...'", ОбщегоНазначения.КодОсновногоЯзыка());
			ОбменДаннымиСервер.ЗаписьЖурналаРегистрацииОбменаДанными(СтрШаблон(ШаблонСообщения, ДействиеВКорреспондентеСтрокой), СтруктураНастроекОбмена);
			
		КонецЕсли;
		
		Возврат;
		
	КонецЕсли;
	
	Пока ПараметрыОбмена.ДлительнаяОперация Цикл // Замена рекурсии
		
		ОбменДаннымиСервер.Пауза(ПараметрыОбмена.ИнтервалОжиданияНаСервере);
		
		СтрокаСообщенияОбОшибке = "";
	
		СостояниеОперации = ПолучитьСтатусДлительнойОперации(Прокси, ПараметрыОбмена, СтрокаСообщенияОбОшибке);
			
		Если СостояниеОперации = "Active" Тогда
			
			ПараметрыОбмена.ИнтервалОжиданияНаСервере = Мин(ПараметрыОбмена.ИнтервалОжиданияНаСервере + 30, 180);
			
		ИначеЕсли СостояниеОперации = "Completed" Тогда
			
			ПараметрыОбмена.ИнтервалОжиданияНаСервере = 15;
			ПараметрыОбмена.ДлительнаяОперация = Ложь; 
			ПараметрыОбмена.ИдентификаторОперации = Неопределено;
			
		Иначе
			
			ВызватьИсключение СтрШаблон(НСтр("ru = 'Ошибка в базе-корреспонденте:%1 %2'"), Символы.ПС, СтрокаСообщенияОбОшибке);
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Функция Версия3_0_2_1(ВерсияПрокси)
	
	Возврат ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияПрокси, "3.0.2.1") >= 0;
		
КонецФункции

Функция Версия3_0_2_2(ВерсияПрокси)
	
	Возврат ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияПрокси, "3.0.2.2") >= 0;
		
КонецФункции

Функция ВерсияПрокси(Прокси)

	Имя = Прокси.ТочкаПодключения.Имя;
	Версия = СтрЗаменить(Имя, "Exchange_", "");
	Версия = СтрЗаменить(Версия, "Soap", "");
	Версия = СтрЗаменить(Версия, "_", ".");
	
	Возврат Версия;
	
КонецФункции

// Соответствует операции GetContinuousOperationStatus
Функция ПолучитьСтатусДлительнойОперации(Прокси, ПараметрыОбмена, СтрокаСообщенияОбОшибке, ОбластьДанных = 0)

	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Возврат Прокси.GetContinuousOperationStatus(ПараметрыОбмена.ИдентификаторОперации,
			СтрокаСообщенияОбОшибке, 
			ОбластьДанных);
		
	Иначе
	
		Возврат Прокси.GetContinuousOperationStatus(ПараметрыОбмена.ИдентификаторОперации, СтрокаСообщенияОбОшибке);
		
	КонецЕсли;
	
КонецФункции

// Соответствует операции PrepareGetFile
Функция ПодготовитьФайлДляПолучения(Прокси, ИдентификаторФайла, РазмерЧасти, ИдентификаторСессии, КоличествоЧастей, ОбластьДанных = 0)
	
	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Возврат Прокси.PrepareGetFile(ИдентификаторФайла,
			РазмерЧасти,
			ИдентификаторСессии,
			КоличествоЧастей, 
			ОбластьДанных);
		
	Иначе
	
		Возврат Прокси.PrepareGetFile(ИдентификаторФайла, РазмерЧасти, ИдентификаторСессии, КоличествоЧастей);
	
	КонецЕсли;
	
КонецФункции

// Соответствует операции GetFilePart
Процедура ПолучитьЧастьФайла(Прокси, ИдентификаторСессии, НомерЧасти, ДанныеЧасти, ОбластьДанных = 0)
	
	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Прокси.GetFilePart(ИдентификаторСессии,
			НомерЧасти, ДанныеЧасти,
			ОбластьДанных);
			
	Иначе
	
		Прокси.GetFilePart(ИдентификаторСессии, НомерЧасти, ДанныеЧасти);
		
	КонецЕсли;
	
КонецПроцедуры

// Соответствует операции PutFilePart
Процедура ПоместитьЧастьФайла(Прокси, ИдентификаторСессии, НомерЧасти, ДанныеФайла, ОбластьДанных = 0)
	
	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Прокси.PutFilePart(ИдентификаторСессии, НомерЧасти, ДанныеФайла,
			ОбластьДанных);
		
	Иначе
	
		Прокси.PutFilePart(ИдентификаторСессии, НомерЧасти, ДанныеФайла);
		
	КонецЕсли;
	
КонецПроцедуры

// Соответствует операции SaveFileFromParts
Процедура СобратьФайлИзЧастей(Прокси, ИдентификаторСессии, КоличествоЧастей, ИдентификаторФайла, ОбластьДанных = 0)
	
	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Прокси.SaveFileFromParts(ИдентификаторСессии, КоличествоЧастей, ИдентификаторФайла, ОбластьДанных);
		
	Иначе
		
		Прокси.SaveFileFromParts(ИдентификаторСессии, КоличествоЧастей, ИдентификаторФайла);
		
	КонецЕсли; 
	
КонецПроцедуры

// Соответствует операции TestConnection
Функция ТестСоединения(Прокси, СтруктураНастроекОбмена, СообщениеОбОшибке, ОбластьДанных = 0)

	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если Версия3_0_2_1(ВерсияПрокси) Тогда
		
		Возврат Прокси.TestConnection(
			СтруктураНастроекОбмена.ИмяПланаОбменаКорреспондента, 
			СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод, 
			СообщениеОбОшибке, 
			ОбластьДанных); 
			
	Иначе
		
		Возврат Прокси.TestConnection(СтруктураНастроекОбмена.ИмяПланаОбмена,
			СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
			СообщениеОбОшибке);
		
	КонецЕсли;
	
КонецФункции

Процедура ПроверитьНедопустимыеСимволыВИмениПользователяWSПрокси(Знач ИмяПользователя)
	
	НедопустимыеСимволы = НедопустимыеСимволыВИмениПользователяWSПрокси();
	
	Если СтрокаСодержитСимвол(ИмяПользователя, НедопустимыеСимволы) Тогда
		
		СтрокаСообщения = НСтр("ru = 'В имени пользователя %1 содержатся недопустимые символы.
			|Имя пользователя не должно содержать символы %2.'");
		СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, ИмяПользователя, НедопустимыеСимволы);
		
		ВызватьИсключение СтрокаСообщения;
		
	КонецЕсли;
	
КонецПроцедуры

Функция СтрокаСодержитСимвол(Знач Строка, Знач СтрокаСимволов)
	
	Для Индекс = 1 По СтрДлина(СтрокаСимволов) Цикл
		Символ = Сред(СтрокаСимволов, Индекс, 1);
		
		Если СтрНайти(Строка, Символ) <> 0 Тогда
			Возврат Истина;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Ложь;
	
КонецФункции

Функция НедопустимыеСимволыВИмениПользователяWSПрокси()
	
	Возврат ":";
	
КонецФункции

Процедура ПроверитьКорректностьФорматаАдресаWSПрокси(Знач АдресWSПрокси)
	
	ЭтоИнтернетАдрес           = Ложь;
	ДопустимыеПрефиксыWSПрокси = ДопустимыеПрефиксыWSПрокси();
	
	Для Каждого Префикс Из ДопустимыеПрефиксыWSПрокси Цикл
		Если Лев(НРег(АдресWSПрокси), СтрДлина(Префикс)) = НРег(Префикс) Тогда
			ЭтоИнтернетАдрес = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Если Не ЭтоИнтернетАдрес Тогда
		СтрокаПрефиксов = "";
		Для Каждого Префикс Из ДопустимыеПрефиксыWSПрокси Цикл
			СтрокаПрефиксов = СтрокаПрефиксов + ?(ПустаяСтрока(СтрокаПрефиксов), """", " или """) + Префикс + """";
		КонецЦикла;
		
		СтрокаСообщения = НСтр("ru = 'Неверный формат адреса ""%1"".
			|Адрес должен начинаться с префикса Интернет протокола %2 (например: ""http://myserver.com/service"").'");
			
		СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, АдресWSПрокси, СтрокаПрефиксов);
		
		ВызватьИсключение СтрокаСообщения;
	КонецЕсли;
	
КонецПроцедуры

Функция ДопустимыеПрефиксыWSПрокси()
	
	Результат = Новый Массив();
	
	Результат.Добавить("http");
	Результат.Добавить("https");
	
	Возврат Результат;
	
КонецФункции

Функция СостояниеНастройкиСинхронизацииВКорреспонденте(Прокси, СтруктураНастроек, ОбластьДанных = 0)
	
	Результат = Новый Структура;
	Результат.Вставить("НастройкаСуществует",                     Ложь);
	
	Результат.Вставить("НастройкаСинхронизацииДанныхЗавершена",   Истина);
	Результат.Вставить("ПолученоСообщениеДляСопоставленияДанных", Ложь);
	Результат.Вставить("ПоддерживаетсяСопоставлениеДанных",       Истина);
		
	СтрокаСообщенияОбОшибке = "";
	ВерсияПрокси = ВерсияПрокси(Прокси);
	
	Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияПрокси, "2.0.1.6") >= 0 Тогда
		
		НастройкаСуществует = ТестСоединения(Прокси, СтруктураНастроек, СтрокаСообщенияОбОшибке, ОбластьДанных);
		
		Если НастройкаСуществует
			И ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияПрокси, "3.0.1.1") >= 0 Тогда
			
			ПараметрыПриемникаПрокси = ПолучитьПараметрыИБ(Прокси,
				СтруктураНастроек.ИмяПланаОбменаКорреспондента,
				СтруктураНастроек.ТекущийУзелПланаОбменаКод,
				СтрокаСообщенияОбОшибке,
				ОбластьДанных);
			
			ПараметрыПриемника = СериализаторXDTO.ПрочитатьXDTO(ПараметрыПриемникаПрокси);
			
			ЗаполнитьЗначенияСвойств(Результат, ПараметрыПриемника);
		КонецЕсли;
		
		Результат.НастройкаСуществует = НастройкаСуществует;
	Иначе
		
		ПараметрыПриемникаПрокси = ПолучитьПараметрыИБ(Прокси,
				СтруктураНастроек.ИмяПланаОбмена,
				СтруктураНастроек.ТекущийУзелПланаОбменаКод,
				СтрокаСообщенияОбОшибке,
				ОбластьДанных);
			
		ПараметрыПриемника = ЗначениеИзСтрокиВнутр(ПараметрыПриемникаПрокси);
		
		Если ПараметрыПриемника.Свойство("УзелСуществует") Тогда
			Результат.НастройкаСуществует = ПараметрыПриемника.УзелСуществует;
		Иначе
			Результат.НастройкаСуществует = Истина;
		КонецЕсли;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ВКорреспондентеУстаревшийВариантНастроекОбмена(Прокси, СостояниеНастройки, СтруктураНастроек, КодУзла, Отказ, СтрокаСообщенияОбОшибке = "")
	
	СостояниеНастройкиВарианта = Новый Структура();
	СостояниеНастройкиВарианта.Вставить("НастройкиТранспорта", СтруктураНастроек.НастройкиТранспорта);
	
	// Проверка возможности выполнения перехода.
	Для Каждого ВариантНастройки Из УстаревшиеВариантыНастроекОбмена(СтруктураНастроек.УзелИнформационнойБазы) Цикл
		
		СостояниеНастройкиВарианта.Вставить("ИмяПланаОбмена", ВариантНастройки.ИмяПланаОбмена);
		СостояниеНастройкиВарианта.Вставить("ТекущийУзелПланаОбменаКод", КодУзла);
				
		СостояниеНастройки = СостояниеНастройкиСинхронизацииВКорреспонденте(
			Прокси, СостояниеНастройкиВарианта);
		
		Если СостояниеНастройки.НастройкаСуществует Тогда
			Если СтруктураНастроек.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ВыгрузкаДанных Тогда
				СтруктураНастроек.ИмяПланаОбмена = ВариантНастройки.ИмяПланаОбмена;
				Если КодУзла <> СтруктураНастроек.ТекущийУзелПланаОбменаКод Тогда
					СтруктураНастроек.ТекущийУзелПланаОбменаКод = КодУзла;
				КонецЕсли;
			Иначе
				// В этой ИБ выполнен переход на новый план обмена, в корреспонденте еще не выполнен.
				// Получение данных необходимо отменить.
				СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'В программе ""%1"" выполняется обновление настроек синхронизации.
					|Загрузка данных отменена. Запустите синхронизацию данных повторно.'"),
					Строка(СтруктураНастроек.УзелИнформационнойБазы));
				Отказ = Истина;
			КонецЕсли;
			Возврат Истина;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Ложь;
	
КонецФункции

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

Функция МаксимальнаяОбщаяВерсияИнтерфейсаОбмена(ВесрииИнтерфейсаОбменаКорреспондента) Экспорт
	
	СтруктураПоддерживаемыхВерсий = Новый Структура;
	ОбменДаннымиСервер.ПриОпределенииПоддерживаемыхВерсийПрограммныхИнтерфейсов(СтруктураПоддерживаемыхВерсий);
	ВерсииИнтерфейсаОбмена = СтруктураПоддерживаемыхВерсий.ОбменДанными;
	
	МаксимальнаяВерсия = "0.0.0.0";
	
	Для Каждого Версия Из ВесрииИнтерфейсаОбменаКорреспондента Цикл
		
		Если ВерсииИнтерфейсаОбмена.Найти(Версия) = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(Версия, МаксимальнаяВерсия) > 0 Тогда
			МаксимальнаяВерсия = Версия;
		КонецЕсли;
		
	КонецЦикла;
	
	// Исключение
	Если МаксимальнаяВерсия = "2.1.1.7" Тогда
		МаксимальнаяВерсия = "2.0.1.6";
	КонецЕсли;
	
	Возврат МаксимальнаяВерсия;
	
КонецФункции

#КонецОбласти

