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

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

// Параметры инициализации.
// 
// Параметры:
//  ИдентификаторТранспорта - Строка - идентифкатор транспорта
// 
// Возвращаемое значение:
//  Структура:
//   * Корреспондент - ПланОбменаСсылка, Неопределено - ссылка на узел плана обмена
//   * ИмяПланаОбмена - Строка 
//   * ИмяПланаОбменаКорреспондента - Строка
//   * ИдентификаторТранспорта - Строка
//   * НастройкиТранспорта - Структура - состав повторяет реквизиты обработки транспорта
//   * ДанныеАутентификации - Структура - состав повторяет реквизиты обработки транспорта, 
//   но только данные аутентификации, например: Пароль, ИмяПользоватля
//
Функция ПараметрыИнициализации(ИдентификаторТранспорта = "") Экспорт
	
	Параметры = Новый Структура;
	Параметры.Вставить("Корреспондент", Неопределено);
	Параметры.Вставить("ИмяПланаОбмена", "");
	Параметры.Вставить("ИмяПланаОбменаКорреспондента", "");
	Параметры.Вставить("ИдентификаторТранспорта", ИдентификаторТранспорта);
	Параметры.Вставить("НастройкиТранспорта", Новый Структура);
	Параметры.Вставить("ДанныеАутентификации", Новый Структура);
	
	Возврат Параметры;
	
КонецФункции

// Инициализация обарботки транспорта.
// 
// Параметры:
//  ПараметрыИнициализации - Структура:
//   * Корреспондент - ПланОбменаСсылка - ссылка на узел плана обмена. Если значение задано, 
//   то будут заполнены настройки транспорта (реквизиты обработки).
//   * ИмяПланаОбмена - Строка 
//   * ИмяПланаОбменаКорреспондента - Строка
//   * ИдентификаторТранспорта - Строка - доступный индентфикатор транспорта.
//   Доступные идентфикаторы см. ДоступныеТипыТранспорта
//   * НастройкиТранспорта - Структура - состав повторяет реквизиты обработки транспорта,
//   * ДанныеАутентификации - Структура - состав повторяет реквизиты обработки транспорта, 
//   но только данные аутентификации, например: Пароль, ИмяПользоватля
// 
// Возвращаемое значение:
//   ОбработкаОбъект.ТранспортСообщенийОбменаCOM,
//   ОбработкаОбъект.ТранспортСообщенийОбменаEMAIL,
//   ОбработкаОбъект.ТранспортСообщенийОбменаESB1C,
//   ОбработкаОбъект.ТранспортСообщенийОбменаFILE,
//   ОбработкаОбъект.ТранспортСообщенийОбменаFTP,
//   ОбработкаОбъект.ТранспортСообщенийОбменаGoogleDrive,
//   ОбработкаОбъект.ТранспортСообщенийОбменаHTTP,
//   ОбработкаОбъект.ТранспортСообщенийОбменаSM,
//   ОбработкаОбъект.ТранспортСообщенийОбменаWS,
//   ОбработкаОбъект.ТранспортСообщенийОбменаПассивныйРежим,
//   ОбработкаОбъект.ТранспортСообщенийОбменаЯндексДиск - обработка заданного типа транспорта с заполненными параметрами.
//    При инициализации создатся ВременныйКаталог, задается временное имя файла СообщениеОбмена, 
//    а так же шаблоны имен файлов (ШаблоныИменДляПолученияСообщения) для получения
//  
Функция Инициализация(ПараметрыИнициализации) Экспорт
	
	Параметры = ПараметрыИнициализации();
	ЗаполнитьЗначенияСвойств(Параметры, ПараметрыИнициализации);
	
	Если ЗначениеЗаполнено(Параметры.ИдентификаторТранспорта) Тогда
		ИдентификаторТранспорта = Параметры.ИдентификаторТранспорта;
	ИначеЕсли ЗначениеЗаполнено(Параметры.Корреспондент) Тогда
		ИдентификаторТранспорта = ТранспортПоУмолчанию(Параметры.Корреспондент);
	КонецЕсли;
	
	Менеджер = МенеджерТранспортаПоИдентификатору(ИдентификаторТранспорта);
	Транспорт = Менеджер.Создать();
	
	Если ЗначениеЗаполнено(Параметры.Корреспондент) Тогда
		Транспорт.Корреспондент = Параметры.Корреспондент;
	ИначеЕсли ЗначениеЗаполнено(Параметры.ИмяПланаОбмена) Тогда
		Транспорт.Корреспондент = ПланыОбмена[Параметры.ИмяПланаОбмена].ПустаяСсылка();
	КонецЕсли;
		
	Если ЗначениеЗаполнено(Параметры.ИмяПланаОбмена) Тогда
		Транспорт.ИмяПланаОбмена = Параметры.ИмяПланаОбмена;
	ИначеЕсли ЗначениеЗаполнено(Параметры.Корреспондент) Тогда
		Транспорт.ИмяПланаОбмена = Параметры.Корреспондент.Метаданные().Имя;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Параметры.ИмяПланаОбменаКорреспондента) Тогда
		Транспорт.ИмяПланаОбменаКорреспондента = Параметры.ИмяПланаОбменаКорреспондента;
	ИначеЕсли ЗначениеЗаполнено(Параметры.Корреспондент) Тогда
		Транспорт.ИмяПланаОбменаКорреспондента = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбменаКорреспондента(Параметры.Корреспондент);
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(Транспорт.ИмяПланаОбменаКорреспондента) Тогда
		Транспорт.ИмяПланаОбменаКорреспондента = Транспорт.ИмяПланаОбмена;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Параметры.НастройкиТранспорта) Тогда
		НастройкиТранспорта = Параметры.НастройкиТранспорта;
	ИначеЕсли ЗначениеЗаполнено(Параметры.Корреспондент) Тогда;
		НастройкиТранспорта = НастройкиТранспорта(Параметры.Корреспондент, ИдентификаторТранспорта);
	Иначе
		НастройкиТранспорта = Новый Структура;
	КонецЕсли;
	
	ЗаполнитьЗначенияСвойств(Транспорт, НастройкиТранспорта);
	ЗаполнитьНастройкиИзБезопасногоХранилища(Транспорт);
	
	Если ЗначениеЗаполнено(Параметры.ДанныеАутентификации) Тогда
		ЗаполнитьЗначенияСвойств(Транспорт, Параметры.ДанныеАутентификации);
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Параметры.Корреспондент) Тогда 
		ЗаполнитьИменаСообщенийПоУмолчанию(Транспорт);
	КонецЕсли;
	
	Транспорт.ВременныйКаталог = ВременныйКаталогСообщенийОбмена(Транспорт);
	
	ИмяВременногоФайла = Строка(Новый УникальныйИдентификатор) + ".xml";
	
	Транспорт.СообщениеОбмена = 
		ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(Транспорт.ВременныйКаталог, ИмяВременногоФайла);
	
	Возврат Транспорт;
	
КонецФункции

// Уничтожение обработки трансорта, удаление временного каталога обмена 
// 
// Параметры:
//  Транспорт - ОбработкаОбъект.ТранспортСообщенийОбменаCOM,
//            - ОбработкаОбъект.ТранспортСообщенийОбменаEMAIL,
//            - ОбработкаОбъект.ТранспортСообщенийОбменаESB1C,
//            - ОбработкаОбъект.ТранспортСообщенийОбменаFILE,
//            - ОбработкаОбъект.ТранспортСообщенийОбменаFTP,
//            - ОбработкаОбъект.ТранспортСообщенийОбменаGoogleDrive,
//            - ОбработкаОбъект.ТранспортСообщенийОбменаHTTP,
//            - ОбработкаОбъект.ТранспортСообщенийОбменаSM,
//            - ОбработкаОбъект.ТранспортСообщенийОбменаWS,
//            - ОбработкаОбъект.ТранспортСообщенийОбменаПассивныйРежим,
//            - ОбработкаОбъект.ТранспортСообщенийОбменаЯндексДиск - обработка транспорта сообщений обмена.
//
// Возвращаемое значение:
//  Булево - Истина при удачном выполнении, Ложь - при возникновении ошибки.
//
Функция Деинициализация(Транспорт) Экспорт

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

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

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

КонецФункции

// Транспорт по умолчанию.
// 
// Параметры:
//  Корреспондент - ПланОбменаСсылка - корреспондент
// 
// Возвращаемое значение:
//  Строка - идентфикатор транспорта
//  
Функция ТранспортПоУмолчанию(Корреспондент) Экспорт
	
	Возврат Справочники.НастройкиТранспортаСообщенийОбмена.ТранспортПоУмолчанию(Корреспондент);
		
КонецФункции

// Параметры транспорта (обработки транспорта).
// 
// Параметры:
//  ИдентификаторТранспорта - Строка - идентификатор транспорта
// 
// Возвращаемое значение:
//   Неопределено, Структура - см. СтруктураПараметровТранспорта
//
Функция ПараметрыТранспорта(Знач ИдентификаторТранспорта) Экспорт
	
	Если Не ЗначениеЗаполнено(ИдентификаторТранспорта) Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Если ТипЗнч(ИдентификаторТранспорта) <> Тип("Строка") Тогда
		ИдентификаторТранспорта = ТранспортПоУмолчанию(ИдентификаторТранспорта);
	КонецЕсли;
	
	Возврат МенеджерТранспортаПоИдентификатору(ИдентификаторТранспорта).ПараметрыТранспорта();
	
КонецФункции

// Параметр транспорта (обработки транспорта).
// 
// Параметры:
//  ИдентификаторТранспорта - Строка - идентификатор транспорта
//  ИмяПараметра - Строка - имя параметра транспорта. Список параметров см. СтруктураПараметровТранспорта
// 
// Возвращаемое значение:
//  Произвольный
//
Функция ПараметрТранспорта(Знач ИдентификаторТранспорта, ИмяПараметра) Экспорт
	
	Если Не ЗначениеЗаполнено(ИдентификаторТранспорта) Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Если ТипЗнч(ИдентификаторТранспорта) <> Тип("Строка") Тогда
		ИдентификаторТранспорта = ТранспортПоУмолчанию(ИдентификаторТранспорта);
	КонецЕсли;
	
	Параметры = ПараметрыТранспорта(ИдентификаторТранспорта);
	Возврат Параметры[ИмяПараметра];
	
КонецФункции

// Возвращает обработку транспорта по ее идентификатору.
// 
// Параметры:
//  ИдентификаторТранспорта - Строка - идентификатор транспорта
// 
// Возвращаемое значение:
//  Произвольный - менеджер обработки транспорта
//
Функция МенеджерТранспортаПоИдентификатору(ИдентификаторТранспорта) Экспорт
	
	Менеджеры = МенеджерыТранспортаПоИдентификаторам();
	
	Возврат Менеджеры.Получить(ИдентификаторТранспорта); 
	
КонецФункции

// Возвращает менеджер обработки транспорта FILE.
// 
// Возвращаемое значение:
//  ОбработкаМенеджер.ТранспортСообщенийОбменаFILE
//
Функция МенеджерТранспортаFILE() Экспорт
	
	Возврат Обработки.ТранспортСообщенийОбменаFILE;
	
КонецФункции

// Возвращает менеджер обработки транспорта COM.
// 
// Возвращаемое значение:
//  ОбработкаМенеджер.ТранспортСообщенийОбменаCOM
//
Функция МенеджерТранспортаCOM() Экспорт
	
	Возврат Обработки.ТранспортСообщенийОбменаCOM;
	
КонецФункции

// Возвращает менеджер обработки транспорта EMAIL.
// 
// Возвращаемое значение:
//  ОбработкаМенеджер.ТранспортСообщенийОбменаEMAIL
//
Функция МенеджерТранспортаEMAIL() Экспорт
	
	Возврат Обработки.ТранспортСообщенийОбменаEMAIL;
	
КонецФункции

// Возвращает менеджер обработки транспорта FTP.
// 
// Возвращаемое значение:
//  ОбработкаМенеджер.ТранспортСообщенийОбменаFTP
//
Функция МенеджерТранспортаFTP() Экспорт
	
	Возврат Обработки.ТранспортСообщенийОбменаFTP;
	
КонецФункции

// Возвращает менеджер обработки транспорта HTTP.
// 
// Возвращаемое значение:
//  ОбработкаМенеджер.ТранспортСообщенийОбменаHTTP
//
Функция МенеджерТранспортаHTTP() Экспорт
	
	Возврат Обработки.ТранспортСообщенийОбменаHTTP;
	
КонецФункции

// Возвращает менеджер обработки транспорта WS.
// 
// Возвращаемое значение:
//  ОбработкаМенеджер.ТранспортСообщенийОбменаWS
//
Функция МенеджерТранспортаWS() Экспорт
	
	Возврат Обработки.ТранспортСообщенийОбменаWS;
	
КонецФункции

// Возвращает менеджер обработки транспорта SM.
// 
// Возвращаемое значение:
//  ОбработкаМенеджер.ТранспортСообщенийОбменаSM
//
Функция МенеджерТранспортаSM() Экспорт
	
	Возврат Обработки.ТранспортСообщенийОбменаSM;
	
КонецФункции

// Возвращает менеджер обработки транспорта ПассивныйРежим.
// 
// Возвращаемое значение:
//  ОбработкаМенеджер.ТранспортСообщенийОбменаПассивныйРежим
//
Функция МенеджерТранспортаПассивныйРежим() Экспорт
	
	Возврат Обработки.ТранспортСообщенийОбменаПассивныйРежим;
	
КонецФункции

// Возвращает менеджер обработки транспорта ESB1C.
// 
// Возвращаемое значение:
//  ОбработкаМенеджер.ТранспортСообщенийОбменаESB1C
//
Функция МенеджерТранспортаESB1C() Экспорт
	
	Возврат Обработки.ТранспортСообщенийОбменаESB1C;
	
КонецФункции

// Возвращает менеджер обработки транспорта GoogleDrive.
// 
// Возвращаемое значение:
//  ОбработкаМенеджер.ТранспортСообщенийОбменаGoogleDrive
//
Функция МенеджерТранспортаGoogleDrive() Экспорт
	
	Возврат Обработки.ТранспортСообщенийОбменаGoogleDrive;
	
КонецФункции

// Возвращает менеджер обработки транспорта ЯндексДиск.
// 
// Возвращаемое значение:
//  ОбработкаМенеджер.ТранспортСообщенийОбменаЯндексДиск
//
Функция МенеджерТранспортаЯндексДиск() Экспорт
	
	Возврат Обработки.ТранспортСообщенийОбменаЯндексДиск;
	
КонецФункции

// Удалить все настройки транспорта.
// 
// Параметры:
//  Корреспондент - ПланОбменаСсылка - удаляемый узел плана обмена
//
Процедура УдалитьВсеНастройкиТранспорта(Корреспондент) Экспорт
	
	Справочники.НастройкиТранспортаСообщенийОбмена.УдалитьВсеНастройки(Корреспондент);

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

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

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

Функция ДоступныеТипыТранспорта(Корреспондент, Знач ВариантНастройки = "") Экспорт
	
	ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(Корреспондент);
	
	Если Не Корреспондент.Пустая() Тогда
		ВариантНастройки = ОбменДаннымиСервер.СохраненныйВариантНастройкиУзлаПланаОбмена(Корреспондент);
	КонецЕсли;
	
	ОписаниеВариантаНастройки = ОбменДаннымиПовтИсп.ОписаниеВариантаНастройки(ИмяПланаОбмена,  
		ВариантНастройки, "", "");
		
	Результат = ОписаниеВариантаНастройки.ИспользуемыеТранспортыСообщенийОбмена;
	
	Если Результат.Количество() = 0 Тогда
		Результат = ВсеТипыТранспорта();
	КонецЕсли;
	
	// Для совместимости со старыми версиями
	Для Индекс = 0 По Результат.ВГраница() Цикл
		
		Транспорт = Результат[Индекс];
		
		Если Транспорт = Перечисления.ВидыТранспортаСообщенийОбмена.COM Тогда
			Результат[Индекс] = Обработки.ТранспортСообщенийОбменаCOM;
		ИначеЕсли Транспорт = Перечисления.ВидыТранспортаСообщенийОбмена.EMAIL Тогда
			Результат[Индекс] = Обработки.ТранспортСообщенийОбменаEMAIL;
		ИначеЕсли Транспорт = Перечисления.ВидыТранспортаСообщенийОбмена.FILE Тогда
			Результат[Индекс] = Обработки.ТранспортСообщенийОбменаFILE;
		ИначеЕсли Транспорт = Перечисления.ВидыТранспортаСообщенийОбмена.FTP Тогда
			Результат[Индекс] = Обработки.ТранспортСообщенийОбменаFTP;
		ИначеЕсли Транспорт = Перечисления.ВидыТранспортаСообщенийОбмена.WS Тогда
			Результат[Индекс] = Обработки.ТранспортСообщенийОбменаWS;
		ИначеЕсли Транспорт = Перечисления.ВидыТранспортаСообщенийОбмена.WSПассивныйРежим Тогда
			Результат[Индекс] = Обработки.ТранспортСообщенийОбменаПассивныйРежим;	
		КонецЕсли;
		
	КонецЦикла;
		
	// Обмен через COM-соединение не поддерживается:
	//  - для базовых версий конфигураций;
	//  - для РИБ;
	//  - для стандартного обмена (без использования правил конвертации);
	//  - если сервер 1С запущен на ОС Linux.
	//
	Если СтандартныеПодсистемыСервер.ЭтоБазоваяВерсияКонфигурации()
		Или ОбменДаннымиПовтИсп.ЭтоПланОбменаРаспределеннойИнформационнойБазы(ИмяПланаОбмена)
		Или ОбменДаннымиПовтИсп.ЭтоУзелСтандартногоОбменаДанными(ИмяПланаОбмена)
		Или ОбщегоНазначения.ЭтоLinuxСервер() Тогда
		
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаCOM);
	
	КонецЕсли;

	// Обмен через 1С:Шина не поддерживается:
	//  - для базовых версий конфигураций;
	//  - для РИБ;
	//  - для стандартного обмена (без использования правил конвертации);
	//
	Если СтандартныеПодсистемыСервер.ЭтоБазоваяВерсияКонфигурации()
		Или ОбменДаннымиПовтИсп.ЭтоПланОбменаРаспределеннойИнформационнойБазы(ИмяПланаОбмена)
		Или ОбменДаннымиПовтИсп.ЭтоУзелСтандартногоОбменаДанными(ИмяПланаОбмена) Тогда
		
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаESB1C);
	
	КонецЕсли;
			
	// Обмен через WS-соединение не поддерживается:
	//  - для РИБ, не являющихся АРМ.
	//
	Если ОбменДаннымиПовтИсп.ЭтоПланОбменаРаспределеннойИнформационнойБазы(ИмяПланаОбмена)
		И Не ОбменДаннымиПовтИсп.ЭтоУзелАвтономногоРабочегоМеста(Корреспондент) Тогда
		
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаWS);
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаHTTP);
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаПассивныйРежим);
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаESB1C);
		
	КонецЕсли;
		
	// Обмен через электронную почту не поддерживается:
	//  - когда недоступна подсистема работы с почтовыми сообщениями;
	//  - когда в конфигурации недоступно получение писем.
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаСПочтовымиСообщениями") Тогда
		МодульРаботаСПочтовымиСообщениямиСлужебный = ОбщегоНазначения.ОбщийМодуль("РаботаСПочтовымиСообщениямиСлужебный");
		Если Не МодульРаботаСПочтовымиСообщениямиСлужебный.ДоступноПолучениеПисем() Тогда
			ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат,
				Обработки.ТранспортСообщенийОбменаEMAIL);
		КонецЕсли;
	Иначе
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат,
			Обработки.ТранспортСообщенийОбменаEMAIL);
	КонецЕсли;
		
	Если ОбщегоНазначения.РазделениеВключено()
		И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаЯндексДиск);
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаGoogleDrive);
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаCOM);
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаEMAIL);
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаFILE);
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаFTP);	
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаESB1C);
		
	Иначе
		
		ОбщегоНазначенияКлиентСервер.УдалитьЗначениеИзМассива(Результат, Обработки.ТранспортСообщенийОбменаSM);
		
	КонецЕсли;
	
	ТранспортСообщенийОбменаПереопределяемый.ПриОпределенииДоступныхТиповТранспорта(
		Результат, Корреспондент, ВариантНастройки);
	
	Возврат Результат;
	
КонецФункции

Функция НастройкиПодключенияВXML(НастройкиПодключения) Экспорт
	
	Менеджер = МенеджерТранспортаПоИдентификатору(НастройкиПодключения.ИдентификаторТранспорта);
	Возврат Менеджер.НастройкиПодключенияВXML(НастройкиПодключения);
	
КонецФункции

Функция НастройкиПодключенияВJSON(НастройкиПодключения) Экспорт
	
	НастройкиПодключенияJSON = НастройкиПодключенияВJSONОбщее(НастройкиПодключения);
	
	Если ЗначениеЗаполнено(НастройкиПодключения.ИдентификаторТранспорта) Тогда
		
		Менеджер = МенеджерТранспортаПоИдентификатору(НастройкиПодключения.ИдентификаторТранспорта);
		НастройкиТранспорта = Менеджер.НастройкиТранспортаВJSON(НастройкиПодключения.НастройкиТранспорта);
		
	Иначе
		
		НастройкиТранспорта = Новый Структура;
		
	КонецЕсли;
	
	НастройкиПодключенияJSON.Вставить("TransportSettings", НастройкиТранспорта);
	
	Возврат ЗначениеВJSON(НастройкиПодключенияJSON);
	
КонецФункции

Функция НастройкиПодключенияИзXML(ТекстXML, ИдентификаторТранспорта = "") Экспорт
	
	Если Не ЗначениеЗаполнено(ИдентификаторТранспорта) Тогда
		
		ЧтениеXML = Новый ЧтениеXML;
		ЧтениеXML.УстановитьСтроку(ТекстXML);
		Фабрика = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
		
		Если Фабрика.Свойства().Получить("ОсновныеПараметрыОбмена") <> Неопределено Тогда
			ИдентификаторТранспорта = Фабрика.ОсновныеПараметрыОбмена.ВидТранспортаСообщенийОбмена;
		КонецЕсли;
		
	КонецЕсли;
	
	Менеджер = МенеджерТранспортаПоИдентификатору(ИдентификаторТранспорта);
	НастройкиПодключения = Менеджер.НастройкиПодключенияИзXML(ТекстXML);
	
	Возврат НастройкиПодключения;
	
КонецФункции

Функция НастройкиПодключенияИзJSON(ТекстJSON, ИдентификаторТранспорта = "") Экспорт

	НастройкиПодключенияИзФайла = JSONВЗначение(ТекстJSON, Ложь);
	
	НастройкиПодключения = Новый Структура;
	ИдентификаторТранспорта = "";
	
	Если НастройкиПодключенияИзФайла.Свойство("MainExchangeParameters") Тогда
		
		ОсновныеПараметры = НастройкиПодключенияИзФайла.MainExchangeParameters;
		
		НастройкиПодключения.Вставить("ВерсияФормата", ОсновныеПараметры.FormatVersion);
		НастройкиПодключения.Вставить("ПрефиксИнформационнойБазыИсточника", ОсновныеПараметры.DestinationInfobasePrefix);
		НастройкиПодключения.Вставить("ПрефиксИнформационнойБазыПриемника", ОсновныеПараметры.SourceInfobasePrefix);
		НастройкиПодключения.Вставить("КодУзла", ОсновныеПараметры.CorrespondentNodeCode);
		НастройкиПодключения.Вставить("КодУзлаКорреспондента", ОсновныеПараметры.NodeCode);
		
		НастройкиПодключения.Вставить("КодПредопределенногоУзла", ОсновныеПараметры.CorrespondentNodeCode);
		НастройкиПодключения.Вставить("КодНовогоУзлаВторойБазы", ОсновныеПараметры.NodeCode);
		
		НастройкиПодключения.Вставить("ИмяПланаОбмена", ОсновныеПараметры.CorrespondentExchangePlanName);
		НастройкиПодключения.Вставить("ИмяПланаОбменаКорреспондента", ОсновныеПараметры.ExchangePlanName);
		
		НастройкиПодключения.Вставить("НаименованиеВторойБазы", ОсновныеПараметры.ThisInfobaseDescription);
		НастройкиПодключения.Вставить("НаименованиеЭтойБазы", ОсновныеПараметры.SecondInfobaseDescription);
		НастройкиПодключения.Вставить("ИдентификаторТранспорта", ОсновныеПараметры.TransportID);
		НастройкиПодключения.Вставить("ВариантНастройкиОбмена", ОсновныеПараметры.ExchangeSetupOption);
		НастройкиПодключения.Вставить("НомерОтправленного", ОсновныеПараметры.SentNo);
		НастройкиПодключения.Вставить("НомерПринятого", ОсновныеПараметры.ReceivedNo);
		
		ИдентификаторТранспорта = ОсновныеПараметры.TransportID;
		
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ИдентификаторТранспорта)
		И НастройкиПодключенияИзФайла.Свойство("TransportSettings") Тогда
				
		Менеджер = МенеджерТранспортаПоИдентификатору(ИдентификаторТранспорта);
		НастройкиТранспорта = Менеджер.НастройкиТранспортаИзJSON(НастройкиПодключенияИзФайла.TransportSettings);
		
	Иначе
		
		НастройкиТранспорта = Новый Структура;
		
	КонецЕсли;
	
	НастройкиПодключения.Вставить("НастройкиТранспорта", НастройкиТранспорта);
	
	// ПараметрыОбменаXDTO
	Если НастройкиПодключенияИзФайла.Свойство("XDTOExchangeParameters") Тогда
		ПараметрыОбменаXDTO = НастройкиПодключенияИзФайла.XDTOExchangeParameters; 
		НастройкиПодключения.Вставить("ФорматОбмена", ПараметрыОбменаXDTO.ExchangeFormat);
	КонецЕсли;
	
	Если НастройкиПодключенияИзФайла.Свойство("SupportedObjectsInFormat") Тогда
		
		ОбъектыФормата = ТаблицаИзМассива_ПоддерживаемыеОбъектыФормата(
			НастройкиПодключенияИзФайла.SupportedObjectsInFormat,
			ОсновныеПараметры.ExchangeFormatVersions);
		
		Хранилище = Новый ХранилищеЗначения(ОбъектыФормата);
		НастройкиПодключения.Вставить("ПоддерживаемыеОбъектыФормата", Хранилище);
		
	КонецЕсли;
	
	Возврат НастройкиПодключения;

КонецФункции

Функция ИмяКаталогаСохраненияНастроек(НастройкиПодключения) Экспорт

	Менеджер = МенеджерТранспортаПоИдентификатору(НастройкиПодключения.ИдентификаторТранспорта);
	Возврат Менеджер.ИмяКаталогаСохраненияНастроек(НастройкиПодключения);
	
КонецФункции

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

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

Функция НастроенныеТипыТранспорта(Корреспондент) Экспорт
	
	Возврат Справочники.НастройкиТранспортаСообщенийОбмена.НастроенныеТипыТранспорта(Корреспондент);
	
КонецФункции

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

Процедура СохранитьНастройкиТранспорта(Корреспондент, ИдентификаторТранспорта, НастройкиТранспорта, НастройкаПоУмолчанию = Неопределено) Экспорт
	
	СтруктураЗаписи = Новый Структура();
	СтруктураЗаписи.Вставить("Корреспондент", Корреспондент);
	СтруктураЗаписи.Вставить("ИдентификаторТранспорта", ИдентификаторТранспорта);
	СтруктураЗаписи.Вставить("Настройки", НастройкиТранспорта);
	
	Если НастройкаПоУмолчанию <> Неопределено Тогда
		СтруктураЗаписи.Вставить("НастройкаПоУмолчанию", НастройкаПоУмолчанию);
	КонецЕсли;
	
	Справочники.НастройкиТранспортаСообщенийОбмена.ОбновитьНастройки(СтруктураЗаписи);
	
КонецПроцедуры

Функция ПарольСинхронизацииДанных(Знач УзелИнформационнойБазы) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	ПаролиСинхронизацииДанных = ПараметрыСеанса.ПаролиСинхронизацииДанных.Получить();
	
	Возврат ПаролиСинхронизацииДанных.Получить(УзелИнформационнойБазы);

КонецФункции

Функция ПарольСинхронизацииДанныхЗадан(Знач УзелИнформационнойБазы) Экспорт
	
	Возврат ПарольСинхронизацииДанных(УзелИнформационнойБазы) <> Неопределено;
	
КонецФункции

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

Функция ПолноеИмяФормыНастройки(ИдентификаторТранспорта) Экспорт

	Менеджер = МенеджерТранспортаПоИдентификатору(ИдентификаторТранспорта);
	ИмяОбработки = Менеджер.Создать().Метаданные().ПолноеИмя();
	ИмяФормыНастройки = ПараметрТранспорта(ИдентификаторТранспорта, "ИмяФормыНастройки");
	
	Возврат ИмяОбработки + ".Форма." + ИмяФормыНастройки;
		
КонецФункции

Функция ПолноеИмяФормыПервойНастройки(ИдентификаторТранспорта) Экспорт

	Менеджер = МенеджерТранспортаПоИдентификатору(ИдентификаторТранспорта);
	ИмяОбработки = Менеджер.Создать().Метаданные().ПолноеИмя();
	ИмяФормыПервойНастройки = ПараметрТранспорта(ИдентификаторТранспорта, "ИмяФормыПервойНастройки");
	
	Возврат ИмяОбработки + ".Форма." + ИмяФормыПервойНастройки;
		
КонецФункции

#Область РаботаСОбъектомFTPСоединение

// Определяет, существует ли каталог на FTP-сервере.
//
// Параметры:
//  Путь - Строка - путь к каталогу.
//  ИмяКаталога - Строка - имя каталога.
//  FTPСоединение - FTPСоединение - FTPСоединение, используемое для подключения к FTP-серверу.
// 
// Возвращаемое значение:
//  Булево - если Истина, то каталог существует; Ложь - нет.
//
Функция FTPКаталогСуществует(Знач Путь, Знач ИмяКаталога, Знач FTPСоединение) Экспорт
	
	Для Каждого FTPФайл Из FTPСоединение.НайтиФайлы(Путь) Цикл
		
		Если FTPФайл.ЭтоКаталог() И FTPФайл.Имя = ИмяКаталога Тогда
			
			Возврат Истина;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Ложь;
КонецФункции

Функция FTPСоединение(Знач Настройки) Экспорт
	
	Возврат Новый FTPСоединение(
		Настройки.Сервер,
		Настройки.Порт,
		Настройки.ИмяПользователя,
		Настройки.ПарольПользователя,
		НастройкиПроксиСервера(Настройки.ЗащищенноеСоединение),
		Настройки.ПассивноеСоединение,
		Настройки.Таймаут,
		Настройки.ЗащищенноеСоединение);
	
КонецФункции

Функция FTPНастройкиСоединения(Знач Таймаут = 180) Экспорт
	
	Результат = Новый Структура;
	Результат.Вставить("Сервер", "");
	Результат.Вставить("Порт", 21);
	Результат.Вставить("ИмяПользователя", "");
	Результат.Вставить("ПарольПользователя", "");
	Результат.Вставить("ПассивноеСоединение", Ложь);
	Результат.Вставить("Таймаут", Таймаут);
	Результат.Вставить("ЗащищенноеСоединение", Неопределено);
	
	Возврат Результат;
КонецФункции

// Возвращает имя сервера и путь на сервере FTP, полученные из строки подключения к FTP-ресурсу.
//
// Параметры:
//  СтрокаПодключения - Строка - строка подключения к FTP-ресурсу.
// 
// Возвращаемое значение:
//  Структура - настройки подключения к FTP-ресурсу. Поля структуры:
//              Сервер - Строка - имя сервера.
//              Путь   - Строка - путь на сервере.
//
//  Пример (1):
// Результат = FTPИмяСервераИПуть("ftp://server");
// Результат.Сервер = "server";
// Результат.Путь = "/";
//
//  Пример (2):
// Результат = FTPИмяСервераИПуть("ftp://server/saas/obmen");
// Результат.Сервер = "server";
// Результат.Путь = "/saas/obmen/";
//
Функция FTPИмяСервераИПуть(Знач СтрокаПодключения) Экспорт
	
	Результат = Новый Структура("Сервер, Путь");
	СтрокаПодключения = СокрЛП(СтрокаПодключения);
	
	Если (ВРег(Лев(СтрокаПодключения, 6)) <> "FTP://"
		И ВРег(Лев(СтрокаПодключения, 7)) <> "FTPS://")
		ИЛИ СтрНайти(СтрокаПодключения, "@") <> 0 Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Строка подключения к FTP-ресурсу не соответствует формату: ""%1""'"), СтрокаПодключения);
	КонецЕсли;
	
	ПараметрыПодключения = СтрРазделить(СтрокаПодключения, "/");
	
	Если ПараметрыПодключения.Количество() < 3 Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'В строке подключения к FTP-ресурсу не указано имя сервера: ""%1""'"), СтрокаПодключения);
	КонецЕсли;
	
	Результат.Сервер = ПараметрыПодключения[2];
	
	ПараметрыПодключения.Удалить(0);
	ПараметрыПодключения.Удалить(0);
	ПараметрыПодключения.Удалить(0);
	
	ПараметрыПодключения.Вставить(0, "@");
	
	Если Не ПустаяСтрока(ПараметрыПодключения.Получить(ПараметрыПодключения.ВГраница())) Тогда
		
		ПараметрыПодключения.Добавить("@");
		
	КонецЕсли;
	
	Результат.Путь = СтрСоединить(ПараметрыПодключения, "/");
	Результат.Путь = СтрЗаменить(Результат.Путь, "@", "");
	
	Возврат Результат;
КонецФункции

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

#Область COM

// Основная функция для использования внешнего соединения при обмене.
//
// Параметры: 
//  СтруктураНастроек - структура настроек транспорта COM обмена.
//
// Возвращаемое значение:
//  Структура:
//    * Соединение                  - COMОбъект
//                                  - Неопределено - указатель на COM-объект соединения или Неопределено в
//                                    случае ошибки;
//    * КраткоеОписаниеОшибки       - Строка - краткое описание ошибки;
//    * ПодробноеОписаниеОшибки     - Строка - подробное описание ошибки;
//    * ОшибкаПодключенияКомпоненты - Булево - флаг ошибки подключения COM.
//
Функция УстановитьВнешнееСоединениеСБазой(СтруктураНастроек) Экспорт
	
	Результат = ОбщегоНазначения.УстановитьВнешнееСоединениеСБазой(СтруктураНастроек);
	
	ВнешнееСоединение = Результат.Соединение;
	Если ВнешнееСоединение = Неопределено Тогда
		// Ошибка установки соединения.
		Возврат Результат;
	КонецЕсли;
	
	// Для конфигураций с разными вариантами встроенного языка COM соединение не работает
	
	ВариантВстроенногоЯзыкаКорреспондента = "";
	ВариантыВстроенногоЯзыкаОтличаются = Ложь;
	Если Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский
		И ВнешнееСоединение.Метаданные.ВариантВстроенногоЯзыка <> ВнешнееСоединение.Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда
		ВариантВстроенногоЯзыкаКорреспондента = НСтр("ru = 'Английский'");
		ВариантыВстроенногоЯзыкаОтличаются = Истина;
	КонецЕсли;
	
	Если Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский
		И ВнешнееСоединение.Метаданные.ВариантВстроенногоЯзыка <> ВнешнееСоединение.Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский Тогда
		ВариантВстроенногоЯзыкаКорреспондента = НСтр("ru = 'Русский'");
		ВариантыВстроенногоЯзыкаОтличаются = Истина;
	КонецЕсли;
	
	Если ВариантыВстроенногоЯзыкаОтличаются Тогда
		
		ПодробноеОписаниеОшибки = НСтр("ru = 'В подключаемой программе отличается вариант встроенного языка (%1). Подключение невозможно.'");
		ПодробноеОписаниеОшибки = СтрШаблон(ПодробноеОписаниеОшибки, ВариантВстроенногоЯзыкаКорреспондента); 
		
		Результат.ПодробноеОписаниеОшибки = ПодробноеОписаниеОшибки;
		Результат.КраткоеОписаниеОшибки   = ПодробноеОписаниеОшибки;
		Результат.Соединение = Неопределено;
		
		Возврат Результат;
		
	КонецЕсли;
		
	// Дополнительно проверяем возможность работы с внешней базой.
	
	Попытка
		НетПолныхПрав = Не ВнешнееСоединение.ОбменДаннымиВнешнееСоединение.РольДоступнаПолныеПрава();
	Исключение
		НетПолныхПрав = Истина;
	КонецПопытки;
	
	Если НетПолныхПрав Тогда
		Результат.ПодробноеОписаниеОшибки = НСтр("ru = 'Пользователю, указанному для подключения к другой программе, должны быть назначены роли ""Администратор системы"" и ""Полные права""'");
		Результат.КраткоеОписаниеОшибки   = Результат.ПодробноеОписаниеОшибки;
		Результат.Соединение = Неопределено;
	Иначе
		Попытка 
			СостояниеНеДопустимо = ВнешнееСоединение.ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы();
		Исключение
			СостояниеНеДопустимо = Ложь
		КонецПопытки;
		
		Если СостояниеНеДопустимо Тогда
			Результат.ПодробноеОписаниеОшибки = НСтр("ru = 'Другая программа находится в состоянии обновления.'");
			Результат.КраткоеОписаниеОшибки   = Результат.ПодробноеОписаниеОшибки;
			Результат.Соединение = Неопределено;
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

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

КонецФункции

// Возвращает массив номеров версий, поддерживаемых интерфейсом корреспондента для подсистемы ОбменДанными.
// 
// Параметры:
//   ВнешнееСоединение - COMОбъект - COM-соединение, которое используется для работы с корреспондентом.
//
// Возвращаемое значение:
//   Массив из Строка - номера версий, поддерживаемых интерфейсом корреспондента.
//
Функция ВерсииИнтерфейсаЧерезВнешнееСоединение(ВнешнееСоединение) Экспорт
	
	Возврат ОбщегоНазначения.ПолучитьВерсииИнтерфейсаЧерезВнешнееСоединение(ВнешнееСоединение, "ОбменДанными");
	
КонецФункции

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

// Выполняет проверку подключения обработки транспорта по заданным настройкам.
Процедура ПроверитьПодключениеОбработкиТранспортаСообщенийОбмена(Отказ,
	СтруктураНастроек, ВидТранспорта, СообщениеОбОшибке = "", НовыеПароли = Неопределено) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	Корреспондент = Неопределено;
	ЕстьКорреспондент = СтруктураНастроек.Свойство("Корреспондент", Корреспондент)
		Или СтруктураНастроек.Свойство("КонечнаяТочкаКорреспондента", Корреспондент);
		
	СтрокаПараметров = "COMПарольПользователя, FTPСоединениеПароль, WSПароль, ПарольАрхиваСообщенияОбмена,
		|FTPСоединениеПарольОбластейДанных, ПарольАрхиваСообщенияОбменаОбластейДанных";
	
	Если ЕстьКорреспондент И НовыеПароли = Неопределено Тогда
		Пароли = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(Корреспондент, СтрокаПараметров, Истина);
	КонецЕсли;
	
	Если ВидТранспорта = Перечисления.ВидыТранспортаСообщенийОбмена.FILE Тогда
		
		Транспорт = Обработки.ТранспортСообщенийОбменаFILE.Создать();
		Транспорт.КаталогОбменаИнформацией = СтруктураНастроек.FILEКаталогОбменаИнформацией;
		
	ИначеЕсли ВидТранспорта = Перечисления.ВидыТранспортаСообщенийОбмена.FTP Тогда 
		
		Транспорт = Обработки.ТранспортСообщенийОбменаFTP.Создать();
		Транспорт.ПассивноеСоединение = СтруктураНастроек.FTPСоединениеПассивноеСоединение;
		Транспорт.Пользователь = СтруктураНастроек.FTPСоединениеПользователь;
		Транспорт.Порт = СтруктураНастроек.FTPСоединениеПорт;
		Транспорт.Путь = СтруктураНастроек.FTPСоединениеПуть;
		
		Если СтруктураНастроек.Свойство("FTPСоединениеПароль") Тогда
			Транспорт.Пароль = СтруктураНастроек.FTPСоединениеПароль;
		ИначеЕсли НовыеПароли = Неопределено Тогда
			Транспорт.Пароль = Пароли.FTPСоединениеПароль;
		Иначе
			Транспорт.Пароль = НовыеПароли.FTPСоединениеПароль;
		КонецЕсли;
		
	КонецЕсли;
	
	Если Не Транспорт.ПодключениеУстановлено() Тогда
		
		Отказ = Истина;
		
		СообщениеОбОшибке = Транспорт.СообщениеОбОшибке
			+ Символы.ПС + НСтр("ru = 'Техническую информацию об ошибке см. в журнале регистрации.'");
				
	КонецЕсли;
	
КонецПроцедуры

Функция ЗначениеВJSON(Значение) Экспорт
	
	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку();
	ЗаписатьJSON(ЗаписьJSON, Значение);
	
	Возврат ЗаписьJSON.Закрыть();
	
КонецФункции

Функция JSONВЗначение(Строка, ПрочитатьВСоответствие = Истина, ИменаСвойствСоЗначениямиДата = Неопределено) Экспорт
	
	ЧтениеJSON = Новый ЧтениеJSON;
	ЧтениеJSON.УстановитьСтроку(Строка);
	
	Возврат ПрочитатьJSON(ЧтениеJSON, ПрочитатьВСоответствие, ИменаСвойствСоЗначениямиДата);

КонецФункции

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

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

Функция ВсеТипыТранспорта()
	
	ТипыТранспорта = Новый Массив;
	
	ТипыТранспорта.Добавить(Обработки.ТранспортСообщенийОбменаSM);
	ТипыТранспорта.Добавить(Обработки.ТранспортСообщенийОбменаCOM);
	ТипыТранспорта.Добавить(Обработки.ТранспортСообщенийОбменаFILE);
	ТипыТранспорта.Добавить(Обработки.ТранспортСообщенийОбменаFTP);
	ТипыТранспорта.Добавить(Обработки.ТранспортСообщенийОбменаEMAIL);
	ТипыТранспорта.Добавить(Обработки.ТранспортСообщенийОбменаЯндексДиск);
	ТипыТранспорта.Добавить(Обработки.ТранспортСообщенийОбменаGoogleDrive);
	ТипыТранспорта.Добавить(Обработки.ТранспортСообщенийОбменаWS);
	ТипыТранспорта.Добавить(Обработки.ТранспортСообщенийОбменаHTTP);
	ТипыТранспорта.Добавить(Обработки.ТранспортСообщенийОбменаПассивныйРежим);
	ТипыТранспорта.Добавить(Обработки.ТранспортСообщенийОбменаESB1C);
	
	ТранспортСообщенийОбменаПереопределяемый.ПриОпределенииТиповТранспорта(ТипыТранспорта);
		
	Возврат ТипыТранспорта;
	
КонецФункции

// Структура параметров транспорта.
// 
// Возвращаемое значение:
//  Структура - структура параметров транспорта:
//   * Псевдоним - Строка - краткое представление транспорта
//   * ИдентификаторТранспорта - Строка
//   * Описание - Строка - подробное описание транспорта
//   * ИмяФормыНастройки - Строка - имя формы, для настроенного транспорта
//   * ИмяФормыПервойНастройки - Строка - имя формы, которая используется при первой настройке синхронизации.
//   * ИмяФормыАутентификации - Строка - имя формы, которая используется при ввода данных аутентификации
//   * РеквизитыДляБезопасногоХранилища - Массив из Строка - список реквизитов,
//   которые помещаются в безопасное хранилище при сохранение настроек транспорта
//   * ЗапускОбменаИзКорреспондента - Булево - признак того, что синхронизацию можно запустить в базе корреспонденте
//   * ИспользоватьПрогресс - Булево - будет ли использован прогресс бар при выгрузке загрузке данных.
//   Истина - для оффлайн обменов, Ложь для онлайн
//   * СохранитьПараметрыПодключенияВФайл - Булево
//   * РежимРаботыПриложения - Число - влияет только на картинку в списке формы НастройкиСинхронизацииДанных.
//   Доступно 0 и 1. 0 - Обмен через обычные каналы связи (FILE, FTP и т.д.), 1 - с приложением в сервисе.
//   * Картинка - Картинка - картинка, которая будет отображаться для транспорта в списках выбора
//   * ПрямоеПодключение - Булево - Истина - с базой корреспондентом есть прямая связь (COM, WS, HTTP)
//   * ПассивныйРежим - Булево - Истина Транспорт является "заглушкой",
//   при использовании транспорта с этим параметром нельзя инициализировать синхронизацию данных.
//   Используется в связке с WS и HTTP
//   * НастройкаУзлаВКорреспонденте - Булево - 
//   Истина, если есть необходимость донастроить транспорт в базе корреспонденте при создании новой синхронизации.
//   Ложь - Необходимости нет
//
Функция СтруктураПараметровТранспорта() Экспорт
	
	Параметры = Новый Структура;
	
	Параметры.Вставить("Псевдоним", "");
	Параметры.Вставить("ИдентификаторТранспорта", "");
	Параметры.Вставить("Описание", "");
	Параметры.Вставить("ИмяФормыНастройки", "ФормаНастройки");
	Параметры.Вставить("ИмяФормыПервойНастройки", "ФормаНастройки");
	Параметры.Вставить("ИмяФормыАутентификации", "ФормаАутентификации");
	Параметры.Вставить("РеквизитыДляБезопасногоХранилища", Новый Массив);
	Параметры.Вставить("ЗапускОбменаИзКорреспондента", Истина);
	Параметры.Вставить("ИспользоватьПрогресс", Истина);
	Параметры.Вставить("СохранитьПараметрыПодключенияВФайл", Истина);
	Параметры.Вставить("РежимРаботыПриложения", 0); 
	Параметры.Вставить("Картинка", БиблиотекаКартинок.ТранспортПередачаДанных);
	
	// Для онлайн обмена
	Параметры.Вставить("ПрямоеПодключение", Ложь);
	Параметры.Вставить("ПассивныйРежим", Ложь);
	
	Параметры.Вставить("НастройкаУзлаВКорреспонденте", Ложь);
	
	Возврат Параметры;
	
КонецФункции

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

	// Контроль дублирования настроек синхронизации (синхронизация уже настроена)
	Результат.Вставить("ЭтотУзелЕстьВКорреспонденте", Ложь);
	Результат.Вставить("УзелКорреспондентаЕстьВЭтойБазе", Ложь);
	Результат.Вставить("УзелДляУдаления", Неопределено);
	
	Возврат Результат;
	
КонецФункции

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

Функция ПрефиксДляРеквизитаИдентификатора()
	
	Возврат "Идентификатор_";
	
КонецФункции

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

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

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

Процедура ЗаполнитьНастройкиИзБезопасногоХранилища(Объект) Экспорт
	
	ИмяОбработкиТранспорта = Объект.Метаданные().Имя;
	ПараметрыТранспорта = Обработки[ИмяОбработкиТранспорта].ПараметрыТранспорта();
	
	УстановитьПривилегированныйРежим(Истина);
	
	Для Каждого Реквизит Из ПараметрыТранспорта.РеквизитыДляБезопасногоХранилища Цикл
		
		Если ЗначениеЗаполнено(Объект[Реквизит]) Тогда
			Объект[Реквизит] = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(Объект[Реквизит]);
		КонецЕсли;
	
	КонецЦикла;
	
	УстановитьПривилегированныйРежим(Ложь);
	
КонецПроцедуры

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

Процедура ИнформацияОбОшибкеВСообщения(Транспорт, ИнформацияОбОшибке, ДополнитьСообщениеОбОшибке = Ложь) Экспорт

	КраткоеПредставлениеОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
	ПодробноеПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
	
	Если ДополнитьСообщениеОбОшибке Тогда
		
		Транспорт.СообщениеОбОшибке = Транспорт.СообщениеОбОшибке + Символы.ПС + КраткоеПредставлениеОшибки;
		Транспорт.СообщениеОбОшибкеЖР = Транспорт.СообщениеОбОшибкеЖР + Символы.ПС + ПодробноеПредставлениеОшибки;
		
	Иначе
		
		Транспорт.СообщениеОбОшибке = КраткоеПредставлениеОшибки;
		Транспорт.СообщениеОбОшибкеЖР = ПодробноеПредставлениеОшибки;
	
	КонецЕсли;
	
КонецПроцедуры

Процедура ЗаписатьСообщениеВЖурналРегистрации(Транспорт, ДействиеПриОбмене = Неопределено, СообщениеОбОшибке = "", ЭтоОшибка = Истина) Экспорт
	
	Если ЗначениеЗаполнено(СообщениеОбОшибке) Тогда
		СообщениеОбОшибкеЖР = СообщениеОбОшибке;
	ИначеЕсли ЗначениеЗаполнено(Транспорт.СообщениеОбОшибкеЖР) Тогда
		СообщениеОбОшибкеЖР = Транспорт.СообщениеОбОшибкеЖР;
	ИначеЕсли ЗначениеЗаполнено(Транспорт.СообщениеОбОшибке) Тогда
		СообщениеОбОшибкеЖР = Транспорт.СообщениеОбОшибке;
	Иначе
		СообщениеОбОшибкеЖР = НСтр("ru = 'Внутренняя ошибка'");
	КонецЕсли;
	
	ИмяТранспорта = НСтр("ru = 'Обработка: %1'");
	ИмяТранспорта = СтрШаблон(ИмяТранспорта, Транспорт.Метаданные().Имя);
	
	СообщениеОбОшибкеЖР = ИмяТранспорта + Символы.ПС + СообщениеОбОшибкеЖР;
	
	Если ТипЗнч(ДействиеПриОбмене) = Тип("Строка") Тогда
		ДействиеПриОбмене = Перечисления.ДействияПриОбмене[ДействиеПриОбмене];
	КонецЕсли;
		
	Корреспондент = Транспорт.Корреспондент;
	
	Если Не ЗначениеЗаполнено(ДействиеПриОбмене) Или Не ЗначениеЗаполнено(Корреспондент) Тогда
		КлючСообщенияЖурналаРегистрации = НСтр("ru = 'Транспорт сообщений обмена'");
	Иначе
		КлючСообщенияЖурналаРегистрации = ОбменДаннымиСервер.КлючСообщенияЖурналаРегистрации(
			Транспорт.Корреспондент, ДействиеПриОбмене);
	КонецЕсли;
		
	Уровень = ?(ЭтоОшибка, УровеньЖурналаРегистрации.Ошибка, УровеньЖурналаРегистрации.Информация);
	
	Если ЗначениеЗаполнено(Корреспондент) Тогда
		
		ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, 
			Уровень,
			Корреспондент.Метаданные(),
			Корреспондент,
			СообщениеОбОшибкеЖР);
			
	Иначе
		ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, Уровень,,, СообщениеОбОшибкеЖР);
	КонецЕсли;
	
КонецПроцедуры

Функция ТребуетсяАутентификация(ПараметрыАутентификации, ИмяФормы = "") Экспорт
	
	Если Не ЗначениеЗаполнено(ПараметрыАутентификации.ИдентификаторТранспорта) Тогда
		Возврат Ложь;
	КонецЕсли;
	
	ПрямоеПодключение = ПараметрТранспорта(ПараметрыАутентификации.ИдентификаторТранспорта, "ПрямоеПодключение");
	
	Если Не ПрямоеПодключение Тогда
		Возврат Ложь;
	КонецЕсли;
	
	ПарольСинхронизацииДанныхЗадан = ПарольСинхронизацииДанныхЗадан(ПараметрыАутентификации.Корреспондент);
	
	Если ПарольСинхронизацииДанныхЗадан Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Транспорт = Инициализация(ПараметрыАутентификации);
	
	ИмяОбработки = Транспорт.Метаданные().ПолноеИмя();
	ИмяФормыАутентификации = ПараметрТранспорта(ПараметрыАутентификации.ИдентификаторТранспорта, "ИмяФормыАутентификации");
	ИмяФормы = ИмяОбработки + ".Форма." + ИмяФормыАутентификации;
	
	Возврат Транспорт.ТребуетсяАутентификация();
	
КонецФункции

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

Процедура ЗаполнитьИменаСообщенийПоУмолчанию(Транспорт)
	
	// Шаблоны для получения
	Шаблоны = Новый Массив;
	Корреспондент = Транспорт.Корреспондент;
	
	ЭтотУзел = ОбменДаннымиПовтИсп.ПолучитьЭтотУзелПланаОбмена(Транспорт.ИмяПланаОбмена);
	Транслитерация = Транспорт.Метаданные().Реквизиты.Найти("Транслитерация") <> Неопределено
		И Транспорт.Транслитерация;
	
	ПервыйШаблон = ШаблонИмениФайлаСообщения(ЭтотУзел, Корреспондент, Ложь, Транслитерация);
	ПервыйШаблон = СтрЗаменить(ПервыйШаблон, "Message", "Message*") + ".*";
	
	Шаблоны.Добавить(ПервыйШаблон);
	
	ВторойШаблон = ШаблонИмениФайлаСообщения(ЭтотУзел, Корреспондент, Ложь, Транслитерация, Истина);
	ВторойШаблон = СтрЗаменить(ВторойШаблон, "Message", "Message*") + ".*";
	
	Если ПервыйШаблон <> ВторойШаблон Тогда
		Шаблоны.Добавить(ВторойШаблон);
	КонецЕсли;
	
	Транспорт.ШаблоныИменДляПолученияСообщения = Шаблоны;
	
	// Имя сообщения для отправки
	Транспорт.ИмяСообщенияДляОтправки = ШаблонИмениФайлаСообщения(ЭтотУзел, Корреспондент, Истина, Транслитерация) + ".xml";
	
КонецПроцедуры

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

// Возвращает имя файла сообщения обмена данными по данным узла-отправителя и узла-получателя.
//
Функция ИмяФайлаСообщенияОбмена(КодУзлаОтправителя, КодУзлаПолучателя, ЭтоИсходящееСообщение)
	
	ШаблонИмени = "[Префикс]_[УзелОтправитель]_[УзелПолучатель]";
	Если СтрДлина(КодУзлаОтправителя) = 36 И ЭтоИсходящееСообщение Тогда
		ПрефиксИБИсточника = Константы.ПрефиксУзлаРаспределеннойИнформационнойБазы.Получить();
		Если ЗначениеЗаполнено(ПрефиксИБИсточника) Тогда
			ШаблонИмени = "[Префикс]_[ПрефиксИБИсточника]_[УзелОтправитель]_[УзелПолучатель]";
		КонецЕсли;
	КонецЕсли;
	ШаблонИмени = СтрЗаменить(ШаблонИмени, "[Префикс]",         "Message");
	ШаблонИмени = СтрЗаменить(ШаблонИмени, "[ПрефиксИБИсточника]",ПрефиксИБИсточника);
	ШаблонИмени = СтрЗаменить(ШаблонИмени, "[УзелОтправитель]", КодУзлаОтправителя);
	ШаблонИмени = СтрЗаменить(ШаблонИмени, "[УзелПолучатель]",  КодУзлаПолучателя);
	
	Возврат ШаблонИмени;
КонецФункции

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

Функция РаспаковатьСообщениеОбменаИзZipФайла(Транспорт, ИмяФайлаАрхива, Пароль) Экспорт

	Результат = Истина;
	
	Архив = Новый ЧтениеZipФайла(ИмяФайлаАрхива, Пароль);
	ФайлВАрхиве = Архив[0];
		
	Попытка
		
		Архив.Извлечь(ФайлВАрхиве, Транспорт.ВременныйКаталог);
		
		Транспорт.СообщениеОбмена = 
			ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(Транспорт.ВременныйКаталог, ФайлВАрхиве.Имя);
		
	Исключение
		
		Результат = Ложь;
		
		СообщениеОбОшибке = НСтр("ru = 'Ошибка при распаковке сжатого файла сообщения.
                                  |%1'");
		СообщениеОбОшибке = СтрШаблон(СообщениеОбОшибке, ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); 
		
		Транспорт.СообщениеОбОшибке = СообщениеОбОшибке;
		
		ЗаписатьСообщениеВЖурналРегистрации(Транспорт, Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
		
	КонецПопытки;
	
	Возврат Результат
	
КонецФункции

Функция НастройкиПодключенияВXML_1_2(НастройкиПодключения) Экспорт
	
	ИдентификаторТранспорта = НастройкиПодключения.ИдентификаторТранспорта;
	
	РеквизитыУзла = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(
		НастройкиПодключения.УзелИнформационнойБазы, "Код,НомерПринятого,НомерОтправленного");
	
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку("UTF-8");
	ЗаписьXML.ЗаписатьОбъявлениеXML();
	
	ЗаписьXML.ЗаписатьНачалоЭлемента("ПараметрыНастройки"); // @Non-NLS
	ЗаписьXML.ЗаписатьАтрибут("ВерсияФормата", ВерсияФорматаНастроекОбменаДаннымиXML()); // @Non-NLS 
	
	ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsd", "http://www.w3.org/2001/XMLSchema");
	ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
	ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("v8",  "http://v8.1c.ru/data");
	
	// Параметры подключения
	ЗаписьXML.ЗаписатьНачалоЭлемента("ОсновныеПараметрыОбмена"); // @Non-NLS

	ИмяПланаОбмена = ОбменДаннымиТрансляцияФорматаПовтИсп.ТранслироватьИмя(НастройкиПодключения.ИмяПланаОбмена, "ru");

	ДобавитьЗаписьXML(ЗаписьXML, ИмяПланаОбмена, "ИмяПланаОбмена"); // @Non-NLS
	ДобавитьЗаписьXML(ЗаписьXML, НастройкиПодключения.НаименованиеЭтойБазы,   "НаименованиеВторойБазы"); // @Non-NLS
	ДобавитьЗаписьXML(ЗаписьXML, НастройкиПодключения.НаименованиеВторойБазы, "НаименованиеЭтойБазы"); // @Non-NLS
	ДобавитьЗаписьXML(ЗаписьXML, НастройкиПодключения.КодУзла, "КодНовогоУзлаВторойБазы"); // @Non-NLS
	ДобавитьЗаписьXML(ЗаписьXML, НастройкиПодключения.ПрефиксИнформационнойБазыПриемника, "ПрефиксИнформационнойБазыИсточника"); // @Non-NLS
	
	// Настройки транспорта сообщений обмена
	ЗаписьXML.ЗаписатьНачалоЭлемента("ВидТранспортаСообщенийОбмена"); // @Non-NLS
	ЗаписьXML.ЗаписатьАтрибут("xmlns", "");
	ЗаписьXML.ЗаписатьАтрибут("xsi:type", "EnumRef.ВидыТранспортаСообщенийОбмена"); // @Non-NLS-2
	ЗаписьXML.ЗаписатьТекст(?(ИдентификаторТранспорта = "WS", "", ИдентификаторТранспорта));
	ЗаписьXML.ЗаписатьКонецЭлемента();
	
	НастройкиТранспорта = НастройкиПодключения.НастройкиТранспорта;
		
	Если ИдентификаторТранспорта = "FILE" Тогда
		
		ПарольАрхиваСообщенияОбмена = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(НастройкиТранспорта.ПарольАрхиваСообщенияОбмена);
	
		ДобавитьЗаписьXML(ЗаписьXML, ПарольАрхиваСообщенияОбмена, "ПарольАрхиваСообщенияОбмена"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.Транслитерация, "ТранслитерацияИмениФайловСообщенийОбмена"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.КаталогОбменаИнформацией, "FILEКаталогОбменаИнформацией"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.СжиматьФайлИсходящегоСообщения, "FILEСжиматьФайлИсходящегоСообщения"); // @Non-NLS
		
	ИначеЕсли ИдентификаторТранспорта = "COM" Тогда
		
		ДобавитьЗаписьXML(ЗаписьXML, "", "ПарольАрхиваСообщенияОбмена"); // @Non-NLS-2
		ДобавитьЗаписьXML(ЗаписьXML, Ложь, "ТранслитерацияИмениФайловСообщенийОбмена"); // @Non-NLS
		
		ПараметрыПодключенияИБ = ОбщегоНазначенияКлиентСервер.ПолучитьПараметрыПодключенияИзСтрокиСоединенияИнформационнойБазы(
		СтрокаСоединенияИнформационнойБазы());
		
		ВариантРаботыИнформационнойБазы             = ПараметрыПодключенияИБ.ВариантРаботыИнформационнойБазы;
		ИмяИнформационнойБазыНаСервере1СПредприятия = ПараметрыПодключенияИБ.ИмяИнформационнойБазыНаСервере1СПредприятия;
		ИмяСервера1СПредприятия                     = ПараметрыПодключенияИБ.ИмяСервера1СПредприятия;
		КаталогИнформационнойБазы                   = ПараметрыПодключенияИБ.КаталогИнформационнойБазы;

		ПользовательИБ   = ПользователиИнформационнойБазы.ТекущийПользователь();
		АутентификацияОС = ПользовательИБ.АутентификацияОС;
		ИмяПользователя  = ПользовательИБ.Имя;

		ДобавитьЗаписьXML(ЗаписьXML, ВариантРаботыИнформационнойБазы, "COMВариантРаботыИнформационнойБазы"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, ИмяИнформационнойБазыНаСервере1СПредприятия, "COMИмяИнформационнойБазыНаСервере1СПредприятия"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, ИмяСервера1СПредприятия, "COMИмяСервера1СПредприятия"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, КаталогИнформационнойБазы, "COMКаталогИнформационнойБазы"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, АутентификацияОС, "COMАутентификацияОперационнойСистемы"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, ИмяПользователя, "COMИмяПользователя"); // @Non-NLS
		
	ИначеЕсли ИдентификаторТранспорта = "FTP" Тогда
		
		ПарольАрхиваСообщенияОбмена = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(НастройкиТранспорта.ПарольАрхиваСообщенияОбмена);
		Пароль = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(НастройкиТранспорта.Пароль);
		
		ДобавитьЗаписьXML(ЗаписьXML, ПарольАрхиваСообщенияОбмена, "ПарольАрхиваСообщенияОбмена"); // @Non-NLS	//	
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.Транслитерация, "ТранслитерацияИмениФайловСообщенийОбмена"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.СжиматьФайлИсходящегоСообщения, "FTPСжиматьФайлИсходящегоСообщения"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.МаксимальныйДопустимыйРазмерСообщения, "FTPСоединениеМаксимальныйДопустимыйРазмерСообщения"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, Пароль, "FTPСоединениеПароль"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.ПассивноеСоединение, "FTPСоединениеПассивноеСоединение"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.Пользователь, "FTPСоединениеПользователь"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.Порт, "FTPСоединениеПорт"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.Путь, "FTPСоединениеПуть"); // @Non-NLS
		
	ИначеЕсли ИдентификаторТранспорта = "WS" Тогда
			
		// Действий не требуется
		
	ИначеЕсли ИдентификаторТранспорта = "EMAIL" Тогда 
		
		ПарольАрхиваСообщенияОбмена = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(НастройкиТранспорта.ПарольАрхиваСообщенияОбмена);
	
		ДобавитьЗаписьXML(ЗаписьXML, ПарольАрхиваСообщенияОбмена, "ПарольАрхиваСообщенияОбмена"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.Транслитерация, "ТранслитерацияИмениФайловСообщенийОбмена"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.МаксимальныйДопустимыйРазмерСообщения, "EMAILМаксимальныйДопустимыйРазмерСообщения"); // @Non-NLS
		ДобавитьЗаписьXML(ЗаписьXML, НастройкиТранспорта.СжиматьФайлИсходящегоСообщения,        "EMAILСжиматьФайлИсходящегоСообщения"); // @Non-NLS
		
		// Учтеная запись
		ЗаписьXML.ЗаписатьНачалоЭлемента("EMAILУчетнаяЗапись"); // @Non-NLS
		ЗаписьXML.ЗаписатьАтрибут("xmlns", "");
		ЗаписьXML.ЗаписатьАтрибут("xsi:type", "CatalogRef.УчетныеЗаписиЭлектроннойПочты"); // @Non-NLS-2
		ЗаписьXML.ЗаписатьТекст(Строка(НастройкиТранспорта.УчетнаяЗапись.УникальныйИдентификатор()));
		ЗаписьXML.ЗаписатьКонецЭлемента();
		
	КонецЕсли;
	
	ДобавитьЗаписьXML(ЗаписьXML, ИдентификаторТранспорта = "EMAIL", "ИспользоватьПараметрыТранспортаEMAIL"); // @Non-NLS-2
	ДобавитьЗаписьXML(ЗаписьXML, ИдентификаторТранспорта = "FILE", "ИспользоватьПараметрыТранспортаFILE"); // @Non-NLS-2
	ДобавитьЗаписьXML(ЗаписьXML, ИдентификаторТранспорта = "FTP", "ИспользоватьПараметрыТранспортаFTP"); // @Non-NLS-2
	
	// Поддержка файла настроек обмена формата версии 1.0.
	ДобавитьЗаписьXML(ЗаписьXML, НастройкиПодключения.НаименованиеЭтойБазы, "НаименованиеНастройкиВыполненияОбмена"); // @Non-NLS
	
	ДобавитьЗаписьXML(ЗаписьXML, НастройкиПодключения.КодУзла, "КодНовогоУзла"); // @Non-NLS
	ДобавитьЗаписьXML(ЗаписьXML, РеквизитыУзла.Код, "КодПредопределенногоУзла"); // @Non-NLS
	ДобавитьЗаписьXML(ЗаписьXML, РеквизитыУзла.НомерОтправленного, "НомерОтправленного"); // @Non-NLS
	ДобавитьЗаписьXML(ЗаписьXML, РеквизитыУзла.НомерПринятого, "НомерПринятого"); // @Non-NLS
	
	ЗаписьXML.ЗаписатьКонецЭлемента(); // ОсновныеПараметрыОбмена
	
	Если ИдентификаторТранспорта = "EMAIL" Тогда
		
		// УчетнаяЗаписьЭлектроннойПочты
		УчетнаяЗапись = Неопределено;
		Если ЗначениеЗаполнено(НастройкиТранспорта.УчетнаяЗапись) Тогда
			УчетнаяЗапись = НастройкиТранспорта.УчетнаяЗапись.ПолучитьОбъект();
		КонецЕсли;
		
		ЗаписьXML.ЗаписатьНачалоЭлемента("УчетнаяЗаписьЭлектроннойПочты"); // @Non-NLS
		ЗаписатьXML(ЗаписьXML, УчетнаяЗапись);
		ЗаписьXML.ЗаписатьКонецЭлемента(); 
		// УчетнаяЗаписьЭлектроннойПочты
		
	КонецЕсли;
	
	Если ОбменДаннымиПовтИсп.ЭтоПланОбменаXDTO(НастройкиПодключения.ИмяПланаОбмена) Тогда
		ЗаписатьПараметрыОбменаXDTO(ЗаписьXML, НастройкиПодключения.ИмяПланаОбмена);
	КонецЕсли;
	
	ЗаписьXML.ЗаписатьКонецЭлемента(); // ПараметрыНастройки
	
	Возврат ЗаписьXML.Закрыть();

КонецФункции

Функция НастройкиПодключенияИзXML_1_2(ТекстXML, ИдентификаторТранспорта) Экспорт
	
	Настройки = Новый Структура;

	ЧтениеXML = Новый ЧтениеXML;
	ЧтениеXML.УстановитьСтроку(ТекстXML);

	Фабрика = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
		
	Если Фабрика.Свойства().Получить("ОсновныеПараметрыОбмена") <> Неопределено Тогда // @Non-NLS
		
		ОсновныеПараметры = Новый Структура;
		ОсновныеПараметрыXDTO = Фабрика["ОсновныеПараметрыОбмена"]; // @Non-NLS
		Для Каждого Свойство Из ОсновныеПараметрыXDTO.Свойства() Цикл
			ОсновныеПараметры.Вставить(Свойство.Имя, ОсновныеПараметрыXDTO[Свойство.Имя]); 
		КонецЦикла;
		
		Настройки.Вставить("ИмяПланаОбмена", ОсновныеПараметры["ИмяПланаОбмена"]); // @Non-NLS-2
		Настройки.Вставить("НаименованиеВторойБазы", ОсновныеПараметры["НаименованиеВторойБазы"]); // @Non-NLS-2
		Настройки.Вставить("НаименованиеЭтойБазы", ОсновныеПараметры["НаименованиеЭтойБазы"]); // @Non-NLS-2
		Настройки.Вставить("КодНовогоУзлаВторойБазы", ОсновныеПараметры["КодНовогоУзлаВторойБазы"]); // @Non-NLS-2
		Настройки.Вставить("ПрефиксИнформационнойБазыИсточника", ОсновныеПараметры["ПрефиксИнформационнойБазыИсточника"]); // @Non-NLS-2
		
		Настройки.Вставить("НаименованиеНастройкиВыполненияОбмена", ОсновныеПараметры["НаименованиеНастройкиВыполненияОбмена"]); // @Non-NLS-2
		Настройки.Вставить("КодНовогоУзла", ОсновныеПараметры["КодНовогоУзла"]); // @Non-NLS-2
		Настройки.Вставить("КодПредопределенногоУзла", ОсновныеПараметры["КодПредопределенногоУзла"]); // @Non-NLS-2
		Настройки.Вставить("ИдентификаторТранспорта", ИдентификаторТранспорта);
			
		СкопироватьЗначениеСтруктуры(ОсновныеПараметры, "НомерОтправленного", Настройки, "НомерОтправленного"); // @Non-NLS-1
		СкопироватьЗначениеСтруктуры(ОсновныеПараметры, "НомерПринятого", Настройки, "НомерПринятого"); // @Non-NLS-1
	
		НастройкиТранспорта = Новый Структура;
		
		Если ИдентификаторТранспорта = "FILE" Тогда
		
			НастройкиТранспорта.Вставить("КаталогОбменаИнформацией", ОсновныеПараметры["FILEКаталогОбменаИнформацией"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("СжиматьФайлИсходящегоСообщения", ОсновныеПараметры["FILEСжиматьФайлИсходящегоСообщения"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("ПарольАрхиваСообщенияОбмена", ОсновныеПараметры["ПарольАрхиваСообщенияОбмена"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("Транслитерация", Ложь);
		
		ИначеЕсли ИдентификаторТранспорта = "FTP" Тогда
			
			НастройкиТранспорта.Вставить("МаксимальныйДопустимыйРазмерСообщения", ОсновныеПараметры["FTPСоединениеМаксимальныйДопустимыйРазмерСообщения"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("Пароль", ОсновныеПараметры["FTPСоединениеПароль"]);
			НастройкиТранспорта.Вставить("ПарольАрхиваСообщенияОбмена", ОсновныеПараметры["ПарольАрхиваСообщенияОбмена"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("ПассивноеСоединение", ОсновныеПараметры["FTPСоединениеПассивноеСоединение"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("Пользователь", ОсновныеПараметры["FTPСоединениеПользователь"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("Порт", ОсновныеПараметры["FTPСоединениеПорт"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("Путь", ОсновныеПараметры["FTPСоединениеПуть"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("СжиматьФайлИсходящегоСообщения", ОсновныеПараметры["FTPСжиматьФайлИсходящегоСообщения"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("Транслитерация", Ложь);
		
		ИначеЕсли ИдентификаторТранспорта = "EMAIL" Тогда
			
			НастройкиТранспорта.Вставить("МаксимальныйДопустимыйРазмерСообщения", ОсновныеПараметры["EMAILМаксимальныйДопустимыйРазмерСообщения"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("СжиматьФайлИсходящегоСообщения", ОсновныеПараметры["EMAILСжиматьФайлИсходящегоСообщения"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("ПарольАрхиваСообщенияОбмена", ОсновныеПараметры["ПарольАрхиваСообщенияОбмена"]); // @Non-NLS-2
			
		ИначеЕсли ИдентификаторТранспорта = "COM" Тогда
			
			НастройкиТранспорта.Вставить("ВариантРаботыИнформационнойБазы", ОсновныеПараметры["COMВариантРаботыИнформационнойБазы"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("ИмяИнформационнойБазыНаСервере1СПредприятия", ОсновныеПараметры["COMИмяИнформационнойБазыНаСервере1СПредприятия"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("ИмяСервера1СПредприятия", ОсновныеПараметры["COMИмяСервера1СПредприятия"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("КаталогИнформационнойБазы", ОсновныеПараметры["COMКаталогИнформационнойБазы"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("АутентификацияОперационнойСистемы", ОсновныеПараметры["COMАутентификацияОперационнойСистемы"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("ИмяПользователя", ОсновныеПараметры["COMИмяПользователя"]); // @Non-NLS-2
			НастройкиТранспорта.Вставить("ПарольПользователя");
			НастройкиТранспорта.Вставить("ПродолжениеНастройки", Истина);
		
		ИначеЕсли ИдентификаторТранспорта = "WS" Тогда
			
			Настройки.Вставить("ИдентификаторТранспорта", "ПассивныйРежим");
				
		КонецЕсли;
		
	КонецЕсли;
	
	Если Фабрика.Свойства().Получить("ПараметрыОбменаXDTO") <> Неопределено Тогда
		
		ПараметрыОбмена = Новый Структура;
		ПараметрыОбменаXDTO = Фабрика["ПараметрыОбменаXDTO"];
		Для Каждого Свойство Из ПараметрыОбменаXDTO.Свойства() Цикл
			ПараметрыОбмена.Вставить(Свойство.Имя, ПараметрыОбменаXDTO[Свойство.Имя]); 
		КонецЦикла;
		
		Настройки.Вставить("ФорматОбмена", ПараметрыОбменаXDTO["ФорматОбмена"]); // @Non-NLS-2
		
	КонецЕсли;
	
	Если Фабрика.Свойства().Получить("УчетнаяЗаписьЭлектроннойПочты") <> Неопределено Тогда // @Non-NLS
		
		СтандартныеРеквизиты = Новый Структура;
		СтандартныеРеквизиты.Вставить("Description","Наименование");
		СтандартныеРеквизиты.Вставить("PredefinedDataName","ИмяПредопределенныхДанных");
		
		СтруктураУчетнойЗаписи = Новый Структура;
		
		ИмяСвойства = Фабрика["УчетнаяЗаписьЭлектроннойПочты"].Свойства()[0].Имя; // @Non-NLS
		УчетнаяЗаписьXDTO = Фабрика["УчетнаяЗаписьЭлектроннойПочты"][ИмяСвойства]; // @Non-NLS
		
		Словарь = СловарьДляУчетнойЗаписи("en");
		
		Для Каждого Свойство Из УчетнаяЗаписьXDTO.Свойства() Цикл
			
			Ключ = Свойство.Имя;
			
			Если СтандартныеРеквизиты.Свойство(Ключ) Тогда
				Ключ = СтандартныеРеквизиты[Ключ];
			КонецЕсли;
			
			Если Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский Тогда
				Если Словарь.Получить(Ключ) <> Неопределено Тогда
					Ключ = Словарь.Получить(Ключ);
				Иначе
					Продолжить;
				КонецЕсли;
			КонецЕсли;
			
			СтруктураУчетнойЗаписи.Вставить(Ключ, УчетнаяЗаписьXDTO[Свойство.Имя]);
			
		КонецЦикла;
		
		ИмяСправочника = "УчетныеЗаписиЭлектроннойПочты";
		Менеджер = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени("Справочник." + ИмяСправочника);
		УчетнаяЗаписьЭлектроннойПочты = Менеджер.СоздатьЭлемент();
		УчетнаяЗаписьЭлектроннойПочты.Наименование = СтруктураУчетнойЗаписи.Наименование;
		Если СтруктураУчетнойЗаписи.Свойство("ИмяПредопределенныхДанных") Тогда
			УчетнаяЗаписьЭлектроннойПочты.ИмяПредопределенныхДанных = СтруктураУчетнойЗаписи.ИмяПредопределенныхДанных;
		КонецЕсли;
		
		Для Каждого Реквизит Из Метаданные.Справочники[ИмяСправочника].Реквизиты Цикл
			
			Если Не СтруктураУчетнойЗаписи.Свойство(Реквизит.Имя) Тогда
				Продолжить;
			КонецЕсли;
			
			УчетнаяЗаписьЭлектроннойПочты[Реквизит.Имя] = СтруктураУчетнойЗаписи[Реквизит.Имя];
			
		КонецЦикла;

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

Функция СловарьДляУчетнойЗаписи(НаправлениеПеревода = "en")
	
	Словарь = Новый Соответствие;
	
	Словарь.Вставить("АдресЭлектроннойПочты", "Email");
	Словарь.Вставить("ВремяОжидания", "Timeout");
	Словарь.Вставить("ИмяПользователя", "UserName");
	Словарь.Вставить("ИспользоватьДляОтправки", "UseForSending");
	Словарь.Вставить("ИспользоватьДляПолучения", "UseForReceiving");
	Словарь.Вставить("ИспользоватьЗащищенноеСоединениеДляВходящейПочты", "UseSecureConnectionForIncomingMail");
	Словарь.Вставить("ИспользоватьЗащищенноеСоединениеДляИсходящейПочты", "UseSecureConnectionForOutgoingMail");
	Словарь.Вставить("ОставлятьКопииСообщенийНаСервере", "KeepMessageCopiesAtServer");
	Словарь.Вставить("ПериодХраненияСообщенийНаСервере", "KeepMailAtServerPeriod");
	Словарь.Вставить("Пользователь", "User");
	Словарь.Вставить("ПользовательSMTP", "SMTPUser");
	Словарь.Вставить("ПортСервераВходящейПочты", "IncomingMailServerPort");
	Словарь.Вставить("ПортСервераИсходящейПочты", "OutgoingMailServerPort");
	Словарь.Вставить("ПротоколВходящейПочты", "ProtocolForIncomingMail");
	Словарь.Вставить("СерверВходящейПочты", "IncomingMailServer");
	Словарь.Вставить("СерверИсходящейПочты", "OutgoingMailServer");
	Словарь.Вставить("ТребуетсяВходНаСерверПередОтправкой", "SignInBeforeSendingRequired");
	Словарь.Вставить("ОтправлятьСкрытыеКопииПисемНаЭтотАдрес", "SendBCCToThisAddress");
	Словарь.Вставить("ВладелецУчетнойЗаписи", "AccountOwner");
	Словарь.Вставить("ПриОтправкеПисемТребуетсяАвторизация", "AuthorizationRequiredOnSendEmails");
	Словарь.Вставить("АвторизацияСПомощьюПочтовогоСервиса", "EmailServiceAuthorization");
	Словарь.Вставить("ИмяПочтовогоСервиса", "EmailServiceName");
	
	Если НаправлениеПеревода = "en" Тогда
		
		Возврат Словарь;
		
	ИначеЕсли НаправлениеПеревода = "ru" Тогда
		
		НовыйСловарь = Новый Соответствие;
		Для Каждого КлючИЗначение Из Словарь Цикл
			НовыйСловарь.Вставить(КлючИЗначение.Значение, КлючИЗначение.Ключ);
		КонецЦикла;
		
		Возврат НовыйСловарь;
		
	КонецЕсли;
	
КонецФункции

Функция НастройкиПодключенияВJSONОбщее(НастройкиПодключения)

	Результат = Новый Структура;
	
	// Основыне параметры обмена
	ОсновныеПараметры = Новый Структура;
	
	РеквизитыУзла = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(
		НастройкиПодключения.УзелИнформационнойБазы, "Код,НомерПринятого,НомерОтправленного");
		
	ИмяПланаОбмена = ОбменДаннымиТрансляцияФорматаПовтИсп.ТранслироватьИмя(НастройкиПодключения.ИмяПланаОбмена, "en");
	ИмяПланаОбменаКорреспондента = ОбменДаннымиТрансляцияФорматаПовтИсп.ТранслироватьИмя(
		НастройкиПодключения.ИмяПланаОбменаКорреспондента, "en");
	
	ОсновныеПараметры.Вставить("FormatVersion", ВерсияФорматаНастроекОбменаДаннымиJSON());
	ОсновныеПараметры.Вставить("SourceInfobasePrefix", НастройкиПодключения.ПрефиксИнформационнойБазыИсточника);
	ОсновныеПараметры.Вставить("DestinationInfobasePrefix", НастройкиПодключения.ПрефиксИнформационнойБазыПриемника);
	ОсновныеПараметры.Вставить("NodeCode", НастройкиПодключения.КодУзла);
	ОсновныеПараметры.Вставить("CorrespondentNodeCode", НастройкиПодключения.КодУзлаКорреспондента);
	ОсновныеПараметры.Вставить("ExchangePlanName", ИмяПланаОбмена);
	ОсновныеПараметры.Вставить("CorrespondentExchangePlanName", ИмяПланаОбменаКорреспондента);
	ОсновныеПараметры.Вставить("ThisInfobaseDescription", НастройкиПодключения.НаименованиеЭтойБазы);
	ОсновныеПараметры.Вставить("SecondInfobaseDescription", НастройкиПодключения.НаименованиеВторойБазы);
	ОсновныеПараметры.Вставить("ExchangeSetupOption", НастройкиПодключения.ВариантНастройкиОбмена);
	ОсновныеПараметры.Вставить("TransportID", НастройкиПодключения.ИдентификаторТранспорта);
	ОсновныеПараметры.Вставить("SentNo", РеквизитыУзла.НомерОтправленного);
	ОсновныеПараметры.Вставить("ReceivedNo", РеквизитыУзла.НомерПринятого);
		
	Результат.Вставить("MainExchangeParameters", ОсновныеПараметры);
	
	// ПараметрыОбменаXDTO
	Если ОбменДаннымиПовтИсп.ЭтоПланОбменаXDTO(НастройкиПодключения.ИмяПланаОбмена) Тогда
		
		ВерсииФорматаОбмена = ОбменДаннымиСервер.ЗначениеНастройкиПланаОбмена(НастройкиПодключения.ИмяПланаОбмена, "ВерсииФорматаОбмена");
		ВерсииФорматаОбмена = ОбщегоНазначения.ВыгрузитьКолонку(ВерсииФорматаОбмена, "Ключ", Истина);
		
		ОсновныеПараметры.Вставить("ExchangeFormatVersions", ВерсииФорматаОбмена);
		
		ПараметрыОбменаXDTO = Новый Структура;
		ПараметрыОбменаXDTO.Вставить("ExchangeFormat", НастройкиПодключения.ФорматОбмена);
		
		Результат.Вставить("XDTOExchangeParameters", ПараметрыОбменаXDTO);

		Если НастройкиПодключения.ПоддерживаемыеОбъектыФормата <> Неопределено Тогда 
			
			Массив = МассивИзТаблицы_ПоддерживаемыеОбъектыФормата(
				НастройкиПодключения.ПоддерживаемыеОбъектыФормата.Получить(), 
				ВерсииФорматаОбмена);
			
			Результат.Вставить("SupportedObjectsInFormat", Массив);
			
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат Результат; 
	
КонецФункции

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

Функция ТаблицаИзМассива_ПоддерживаемыеОбъектыФормата(Массив, ВерсииФорматаОбмена) Экспорт

	Результат = Новый ТаблицаЗначений;
	Результат.Колонки.Добавить("Версия");
	Результат.Колонки.Добавить("Объект");
	Результат.Колонки.Добавить("Отправка");
	Результат.Колонки.Добавить("Получение");
	
	Для Каждого ЭлМассива Из Массив Цикл
		
		Объект = ЭлМассива["Object"];
		
		ОтправкаВерсии = ЭлМассива["Send"];
		Если ОтправкаВерсии = "*" Тогда
			ОтправкаВерсии = ВерсииФорматаОбмена;
		КонецЕсли;
		
		Для Каждого Версия Из ОтправкаВерсии Цикл
			
			НоваяСтрока = Результат.Добавить();
			НоваяСтрока.Версия = Версия;
			НоваяСтрока.Объект = Объект;
			НоваяСтрока.Отправка = Истина;
			НоваяСтрока.Получение = Ложь;
			
		КонецЦикла;
		
		ПолучениеВерсии = ЭлМассива["Receive"];
		Если ПолучениеВерсии = "*" Тогда
			ПолучениеВерсии = ВерсииФорматаОбмена;
		КонецЕсли;
		
		Для Каждого Версия Из ПолучениеВерсии Цикл
			
			Отбор = Новый Структура("Объект, Версия", Объект, Версия);
			РезультатПоиска = Результат.НайтиСтроки(Отбор);
			
			Если РезультатПоиска.Количество() = 0 Тогда
				
				НоваяСтрока = Результат.Добавить();
				НоваяСтрока.Версия = Версия;
				НоваяСтрока.Объект = Объект;
				НоваяСтрока.Отправка = Ложь;
				НоваяСтрока.Получение = Истина;
				
			Иначе
				
				РезультатПоиска[0].Получение = Истина;
				
			КонецЕсли;
			
		КонецЦикла;
		
	КонецЦикла;

	Возврат Результат;
	
КонецФункции

Процедура ДобавитьЗаписьXML(ЗаписьXML, Значение, ПолноеИмя) Экспорт
	
	ЗаписатьXML(ЗаписьXML, Значение, ПолноеИмя, НазначениеТипаXML.Явное);
	
КонецПроцедуры

Процедура СкопироватьЗначениеСтруктуры(Источник, КлючИсточник, Приемник, КлючПриемник = Неопределено) Экспорт
	
	Если КлючПриемник = Неопределено Тогда
		КлючПриемник = КлючИсточник;
	КонецЕсли;
	
	Если Источник.Свойство(КлючИсточник) Тогда
		Значение = Источник[КлючИсточник];
	Иначе
		Значение = Неопределено;
	КонецЕсли;
	
	Приемник.Вставить(КлючПриемник, Значение);
	
КонецПроцедуры

Функция ВерсияФорматаНастроекОбменаДаннымиXML() Экспорт
	
	Возврат "1.2";
	
КонецФункции

Функция ВерсияФорматаНастроекОбменаДаннымиJSON()
	
	Возврат "2.0";
	
КонецФункции

Процедура ЗаписатьПараметрыОбменаXDTO(ЗаписьXML, ИмяПланаОбмена) Экспорт
	
	ЗаписьXML.ЗаписатьНачалоЭлемента("ПараметрыОбменаXDTO"); // @Non-NLS
	
	ФорматОбмена = ОбменДаннымиСервер.ЗначениеНастройкиПланаОбмена(ИмяПланаОбмена, "ФорматОбмена");
	
	ЗаписатьXML(ЗаписьXML, ФорматОбмена, "ФорматОбмена", НазначениеТипаXML.Явное); // @Non-NLS
	
	ЗаписьXML.ЗаписатьКонецЭлемента(); // ПараметрыОбменаXDTO
	
КонецПроцедуры

#Область ПриПодключенииККорреспонденту

Процедура ПриПодключенииККорреспонденту(Отказ, ИмяПланаОбмена, Знач ВерсияКорреспондента, СообщениеОбОшибке = "") Экспорт
	
	Если Не ЗначениеЗаполнено(ВерсияКорреспондента) Тогда
		ВерсияКорреспондента = "0.0.0.0";
	КонецЕсли;
	
	Попытка
	
		Если НЕ ОбменДаннымиСервер.ЕстьАлгоритмМенеджераПланаОбмена("ПриПодключенииККорреспонденту", ИмяПланаОбмена) Тогда
			Возврат;
		ИначеЕсли ПустаяСтрока(ВерсияКорреспондента) Тогда
			ВерсияКорреспондента = "0.0.0.0";
		КонецЕсли;
		
		ПланыОбмена[ИмяПланаОбмена].ПриПодключенииККорреспонденту(ВерсияКорреспондента);
	
	Исключение
		
		ПодробноеПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ШаблонСообщения = НСтр("ru = 'При выполнении обработчика ПриПодключенииККорреспонденту произошла ошибка:%1%2'");
		СообщениеОбОшибке = СтрШаблон(ШаблонСообщения, Символы.ПС, ПодробноеПредставлениеОшибки);
		
		ЗаписьЖурналаРегистрации(ОбменДаннымиСервер.СобытиеЖурналаРегистрацииСозданиеОбменаДанными(),
			УровеньЖурналаРегистрации.Ошибка, , , СообщениеОбОшибке);
		
		Отказ = Истина;
		
	КонецПопытки;
	
КонецПроцедуры

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

// Получает настройки прокси сервера.
//
Функция НастройкиПроксиСервера(ЗащищенноеСоединение)
	
	Прокси = Неопределено;
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПолучениеФайловИзИнтернета") Тогда
		МодульПолучениеФайловИзИнтернета = ОбщегоНазначения.ОбщийМодуль("ПолучениеФайловИзИнтернета");
		Протокол = ?(ЗащищенноеСоединение = Неопределено, "ftp", "ftps");
		Прокси = МодульПолучениеФайловИзИнтернета.ПолучитьПрокси(Протокол);
	КонецЕсли;
	
	Возврат Прокси;
	
КонецФункции

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

Функция ПроверитьАутентификацию(Корреспондент, ИдентификаторТранспорта, НастройкиТранспорта, ДанныеАутентификации) Экспорт
	
	Параметры = ПараметрыИнициализации();

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

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