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

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

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

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

	ПараметрыПроцедуры = Новый Массив;
	ПараметрыПроцедуры.Добавить(ПерваяЗадача);
	
	Ключ = ПерваяЗадача.ИдентификаторЗадачи;

	ПараметрыЗадания = Новый Структура;
	ПараметрыЗадания.Вставить("Ключ", Лев(Ключ, 120));
	ПараметрыЗадания.Вставить("ИмяМетода"    , "ОбменДаннымиВнутренняяПубликация.ВыполнитьОчередьЗадач");
	ПараметрыЗадания.Вставить("ОбластьДанных", ПараметрыСеанса.ОбластьДанныхЗначение);
	ПараметрыЗадания.Вставить("Использование", Истина);
	ПараметрыЗадания.Вставить("ЗапланированныйМоментЗапуска", ТекущаяУниверсальнаяДата());
	ПараметрыЗадания.Вставить("Параметры", ПараметрыПроцедуры);
	ПараметрыЗадания.Вставить("КоличествоПовторовПриАварийномЗавершении", 3);
	ПараметрыЗадания.Вставить("ИнтервалПовтораПриАварийномЗавершении", 900);
	
	УстановитьПривилегированныйРежим(Истина); // В разделенной ИБ, внут. публикация, не полные права
	
	МодульОчередьЗаданий = ОбщегоНазначения.ОбщийМодуль("ОчередьЗаданий");
	МодульОчередьЗаданий.ДобавитьЗадание(ПараметрыЗадания);
	
	УстановитьПривилегированныйРежим(Ложь);
	
КонецПроцедуры

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

Функция ЗадачаПоИдентификатору(ИдентификаторЗадачи) Экспорт

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

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

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

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

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

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

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

Процедура ПриОжиданииВыгрузкиДанных(ПараметрыОбмена, ПродолжитьОжидание) Экспорт
	
	Ошибка = "";
	ПродолжитьОжидание = Не ОчередьЗадачВыполнена(,ПараметрыОбмена.ИдентификаторОбмена, Ошибка);

	Если Ошибка <> "" Тогда
		ПараметрыОбмена.Отказ = Истина;
		ПараметрыОбмена.СообщениеОбОшибке = Ошибка;
	КонецЕсли;	
		
КонецПроцедуры

Процедура ФормаУзлаПриСозданииНаСервере(Форма, Отказ) Экспорт
	
	УстановитьФункциональныеОпцииДляУзла(Форма);
	НастроитьЭлементыФормыПоПереходуНаВебСервис(Форма);
	
КонецПроцедуры

#Область ЗадачиПриемника

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

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

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

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

#Область ДоступностьExchangeAdministrationManage_3_0_1_1

Функция ВСервисеДоступенExchangeAdministrationManage_3_0_1_1() Экспорт
	
	Если Не ОбщегоНазначения.РазделениеВключено() Тогда
		Возврат Ложь;
	КонецЕсли;
	
	МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
	
	ПараметрыПодключения = Новый Структура;
	УстановитьПривилегированныйРежим(Истина);
	ПараметрыПодключения.Вставить("URL", МодульРаботаВМоделиСервиса.ВнутреннийАдресМенеджераСервиса());
	ПараметрыПодключения.Вставить("UserName", МодульРаботаВМоделиСервиса.ИмяСлужебногоПользователяМенеджераСервиса());
	ПараметрыПодключения.Вставить("Password", МодульРаботаВМоделиСервиса.ПарольСлужебногоПользователяМенеджераСервиса());
	УстановитьПривилегированныйРежим(Ложь);
	
	Версии = ОбщегоНазначения.ПолучитьВерсииИнтерфейса(ПараметрыПодключения, "ExchangeAdministrationManage");
	
	Возврат Версии.Найти("3.0.1.1") <> Неопределено;
	
КонецФункции

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

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

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

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

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

#Область Задачи

Процедура УдалитьУстаревшиеЗадачи(Сценарий = Неопределено, РучнойОбмен = Ложь)
	
	НачатьТранзакцию();
	
	Попытка
		
		// Удаление записей с битыми ссылками
		Запрос = Новый Запрос;
		Запрос.Текст = 
			"ВЫБРАТЬ РАЗРЕШЕННЫЕ
			|	Задачи.ДатаСоздания КАК ДатаСоздания,
			|	Задачи.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
			|	Задачи.НомерЗадачи КАК НомерЗадачи,
			|	Задачи.ИдентификаторОбмена КАК ИдентификаторОбмена,
			|	Задачи.ИдентификаторЗадачи КАК ИдентификаторЗадачи
			|ИЗ
			|	РегистрСведений.ЗадачиОбменаДаннымиВнутренняяПубликация КАК Задачи
			|ГДЕ
			|	Задачи.УзелИнформационнойБазы.Код ЕСТЬ NULL";
		
		Выборка = Запрос.Выполнить().Выбрать();
		
		Пока Выборка.Следующий() Цикл 
			
			Блокировка = Новый БлокировкаДанных;
			ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ЗадачиОбменаДаннымиВнутренняяПубликация");
			ЭлементБлокировки.УстановитьЗначение("ДатаСоздания", Выборка.ДатаСоздания);
			ЭлементБлокировки.УстановитьЗначение("УзелИнформационнойБазы", Выборка.УзелИнформационнойБазы);
			ЭлементБлокировки.УстановитьЗначение("НомерЗадачи", Выборка.НомерЗадачи);
			ЭлементБлокировки.УстановитьЗначение("ИдентификаторОбмена", Выборка.ИдентификаторОбмена);
			ЭлементБлокировки.УстановитьЗначение("ИдентификаторЗадачи", Выборка.ИдентификаторЗадачи);
			ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
			Блокировка.Заблокировать();
			
			Запись = РегистрыСведений.ЗадачиОбменаДаннымиВнутренняяПубликация.СоздатьМенеджерЗаписи();
			ЗаполнитьЗначенияСвойств(Запись, Выборка);
			Запись.Прочитать();
			
			Если Запись.Выбран() Тогда
				Запись.Удалить();
			КонецЕсли;
			
		КонецЦикла;
			
		// Оставляем N последних записей
		Запрос = Новый Запрос;
		Запрос.Текст = 
			"ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 5
			|	Задачи.ИдентификаторОбмена КАК ИдентификаторОбмена
			|ПОМЕСТИТЬ втПоследниеСинхронизации
			|ИЗ
			|	РегистрСведений.ЗадачиОбменаДаннымиВнутренняяПубликация КАК Задачи
			|ГДЕ
			|	Задачи.Сценарий = &Сценарий
			|;
			|
			|////////////////////////////////////////////////////////////////////////////////
			|ВЫБРАТЬ
			|	Задачи.ДатаСоздания КАК ДатаСоздания,
			|	Задачи.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
			|	Задачи.НомерЗадачи КАК НомерЗадачи,
			|	Задачи.ИдентификаторОбмена КАК ИдентификаторОбмена,
			|	Задачи.ИдентификаторЗадачи КАК ИдентификаторЗадачи
			|ИЗ
			|	РегистрСведений.ЗадачиОбменаДаннымиВнутренняяПубликация КАК Задачи
			|		ПОЛНОЕ СОЕДИНЕНИЕ втПоследниеСинхронизации КАК втПоследниеСинхронизации
			|		ПО Задачи.ИдентификаторОбмена = втПоследниеСинхронизации.ИдентификаторОбмена
			|ГДЕ
			|	втПоследниеСинхронизации.ИдентификаторОбмена ЕСТЬ NULL
			|	И Задачи.Сценарий = &Сценарий
			|
			|УПОРЯДОЧИТЬ ПО
			|	ДатаСоздания";
		
		Если ЗначениеЗаполнено(Сценарий) Тогда
			Запрос.УстановитьПараметр("Сценарий", Сценарий);
		Иначе
			Запрос.УстановитьПараметр("Сценарий", Справочники.СценарииОбменовДанными.ПустаяСсылка());	
		КонецЕсли;
		
		Выборка = Запрос.Выполнить().Выбрать();
		
		Пока Выборка.Следующий() Цикл
			
			Блокировка = Новый БлокировкаДанных;
			ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ЗадачиОбменаДаннымиВнутренняяПубликация");
			ЭлементБлокировки.УстановитьЗначение("ДатаСоздания", Выборка.ДатаСоздания);
			ЭлементБлокировки.УстановитьЗначение("УзелИнформационнойБазы", Выборка.УзелИнформационнойБазы);
			ЭлементБлокировки.УстановитьЗначение("НомерЗадачи", Выборка.НомерЗадачи);
			ЭлементБлокировки.УстановитьЗначение("ИдентификаторОбмена", Выборка.ИдентификаторОбмена);
			ЭлементБлокировки.УстановитьЗначение("ИдентификаторЗадачи", Выборка.ИдентификаторЗадачи);
			ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
			Блокировка.Заблокировать();
			
			Запись = РегистрыСведений.ЗадачиОбменаДаннымиВнутренняяПубликация.СоздатьМенеджерЗаписи();
			ЗаполнитьЗначенияСвойств(Запись, Выборка);
			Запись.Прочитать();
			
			Если Запись.Выбран() Тогда
				Запись.Удалить();
			КонецЕсли;
			
		КонецЦикла;
		
		ЗафиксироватьТранзакцию();
	
	Исключение
				
		ОтменитьТранзакцию();
		
		СообщениеОбОшибке = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		
		Событие = НСтр("ru = 'Обмен данными.Удаление записей регистра задач'", ОбщегоНазначения.КодОсновногоЯзыка());
		
		ЗаписьЖурналаРегистрации(Событие, УровеньЖурналаРегистрации.Ошибка, , , СообщениеОбОшибке);
	
	КонецПопытки;
	
КонецПроцедуры

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

Функция ОчередьЗадачВыполнена(Сценарий = Неопределено, ИдентификаторОбмена = "", Ошибка = "", НайденнаяЗадачаСинхронизации = Неопределено)
	
	// Считаем, что сценарий (или ручной обмен) завершен, если для всех задач ЗавершеноУспешно = Истина, или есть ошибка 
	Если ЗначениеЗаполнено(Сценарий) И Не ЗначениеЗаполнено(ИдентификаторОбмена) Тогда
		
		Запрос = Новый Запрос;
		Запрос.Текст = 
			"ВЫБРАТЬ ПЕРВЫЕ 1
			|	Задачи.ИдентификаторОбмена КАК ИдентификаторОбмена
			|ИЗ
			|	РегистрСведений.ЗадачиОбменаДаннымиВнутренняяПубликация КАК Задачи
			|ГДЕ
			|	Задачи.Сценарий = &Сценарий
			|
			|УПОРЯДОЧИТЬ ПО
			|	Задачи.ДатаСоздания УБЫВ";
		
		Запрос.УстановитьПараметр("Сценарий", Сценарий);
		
		Выборка = Запрос.Выполнить().Выбрать();
		
		Если Выборка.Следующий() Тогда
			ИдентификаторОбмена = Выборка.ИдентификаторОбмена;		
		Иначе	
			Возврат Истина;	
		КонецЕсли;
		
	КонецЕсли;
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	Задачи.ДатаСоздания КАК ДатаСоздания,
		|	Задачи.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
		|	Задачи.НомерЗадачи КАК НомерЗадачи,
		|	Задачи.ИдентификаторОбмена КАК ИдентификаторОбмена,
		|	Задачи.ИдентификаторЗадачи КАК ИдентификаторЗадачи,
		|	Задачи.Действие КАК Действие,
		|	Задачи.ЗавершенаУспешно КАК ЗавершенаУспешно,
		|	Задачи.ЗавершенаСОшибкой КАК ЗавершенаСОшибкой,
		|	Задачи.Ошибка КАК Ошибка,
		|	ВЫБОР
		|		КОГДА Задачи.ВремяПроверкиЗадачи = ДАТАВРЕМЯ(1, 1, 1)
		|			ТОГДА Задачи.ДатаСоздания
		|		ИНАЧЕ Задачи.ВремяПроверкиЗадачи
		|	КОНЕЦ КАК ВремяПроверкиЗадачи
		|ПОМЕСТИТЬ втЗадачи
		|ИЗ
		|	РегистрСведений.ЗадачиОбменаДаннымиВнутренняяПубликация КАК Задачи
		|ГДЕ
		|	Задачи.ИдентификаторОбмена = &ИдентификаторОбмена
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	втЗадачи.ИдентификаторЗадачи КАК ИдентификаторЗадачи,
		|	втЗадачи.Действие КАК Действие,
		|	втЗадачи.Ошибка КАК Ошибка
		|ИЗ
		|	втЗадачи КАК втЗадачи
		|ГДЕ
		|	втЗадачи.ЗавершенаСОшибкой
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ИСТИНА КАК Выполнено
		|ИЗ
		|	втЗадачи КАК втЗадачи
		|
		|ИМЕЮЩИЕ
		|	СУММА(ВЫБОР
		|			КОГДА втЗадачи.ЗавершенаУспешно
		|				ТОГДА 1
		|			ИНАЧЕ 0
		|		КОНЕЦ) = МАКСИМУМ(втЗадачи.НомерЗадачи)
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ ПЕРВЫЕ 1
		|	втЗадачи.ДатаСоздания КАК ДатаСоздания,
		|	втЗадачи.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
		|	втЗадачи.НомерЗадачи КАК НомерЗадачи,
		|	втЗадачи.ИдентификаторОбмена КАК ИдентификаторОбмена,
		|	втЗадачи.ИдентификаторЗадачи КАК ИдентификаторЗадачи,
		|	втЗадачи.Действие КАК Действие,
		|	РАЗНОСТЬДАТ(втЗадачи.ВремяПроверкиЗадачи, &ТекущаяДата, ЧАС) КАК ПоследняяПроверка
		|ИЗ
		|	втЗадачи КАК втЗадачи
		|ГДЕ
		|	НЕ втЗадачи.ЗавершенаУспешно
		|	И НЕ втЗадачи.ЗавершенаСОшибкой
		|
		|УПОРЯДОЧИТЬ ПО
		|	НомерЗадачи";
		
	Запрос.УстановитьПараметр("ИдентификаторОбмена", ИдентификаторОбмена);
	Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяУниверсальнаяДата());
	
	Результат = Запрос.ВыполнитьПакет();
	
	// Завершено с ошибкой
	Выборка = Результат[1].Выбрать();
	Если Выборка.Следующий() Тогда
		Ошибка = Выборка.Ошибка;
		Возврат Истина;
	КонецЕсли;
	
	// Все задачи завершены успешно
	Выборка = Результат[2].Выбрать();
	Если Выборка.Следующий() Тогда
		Возврат Истина;
	КонецЕсли;
	
	// Текущая задача
	Выборка = Результат[3].Выбрать();
	
	Если Выборка.Следующий() Тогда
		
		Если (Выборка.Действие = Перечисления.ДействияПриОбменеВнутренняяПубликация.ЗагрузкаДанных
			Или Выборка.Действие = Перечисления.ДействияПриОбменеВнутренняяПубликация.ВыгрузкаДанных
			Или Выборка.Действие = Перечисления.ДействияПриОбменеВнутренняяПубликация.ДополнительнаяРегистрация) Тогда
			
			НайденнаяЗадачаСинхронизации = Выборка.ИдентификаторЗадачи;
			Возврат Ложь;
			
		КонецЕсли;
		
		// Проверка очереди задач в корреспонденте
		
		Состояние = "";
		
		Если Выборка.ПоследняяПроверка >= 1 Тогда
			
			Прокси = Неопределено;
			Отказ = Ложь;
			
			СтруктураНастроекОбмена = НастройкиОбменаДляУзлаИнформационнойБазы(
				Выборка.УзелИнформационнойБазы, "ПроверкаСостоянияЗадания", Отказ);
			
			Попытка
				ИнициализацияПрокси(Прокси, СтруктураНастроекОбмена, Отказ, Ошибка);
				Состояние = Прокси.TaskStatus(Выборка.ИдентификаторЗадачи);
			Исключение
				// Возможно проблемы с доступом к корреспонденту
				Возврат Ложь;
			КонецПопытки
		Иначе
			
			Возврат Ложь;
			
		КонецЕсли;
			
		Если Состояние = "Запланировано" Или Состояние = "Выполняется" Тогда
			
			Запись = РегистрыСведений.ЗадачиОбменаДаннымиВнутренняяПубликация.СоздатьМенеджерЗаписи();
			ЗаполнитьЗначенияСвойств(Запись, Выборка);
			Запись.Прочитать();
			Запись.ВремяПроверкиЗадачи = ТекущаяУниверсальнаяДата();
			Запись.Записать();
			
			Возврат Ложь;
			
		Иначе
			
			Запись = РегистрыСведений.ЗадачиОбменаДаннымиВнутренняяПубликация.СоздатьМенеджерЗаписи();
			ЗаполнитьЗначенияСвойств(Запись, Выборка);
			Запись.Прочитать();
			
			Шаблон = НСтр("ru = 'Не обнаружено активных задач обмена в корреспонденте. 
                                |См. журнал регистрации корреспондента (%1).'", ОбщегоНазначения.КодОсновногоЯзыка());
			
			Ошибка = СтрШаблон(Шаблон, Выборка.УзелИнформационнойБазы);
				
			ОбменДаннымиСервер.ЗаписьЖурналаРегистрацииОбменаДанными(Ошибка, СтруктураНастроекОбмена, Истина);	
				
			Запись.ЗавершенаСОшибкой = Истина;
			Запись.Ошибка = Ошибка; 
			Запись.Записать();
			
			Возврат Истина;
			
		КонецЕсли;
		
	КонецЕсли;
		
	Возврат Истина;

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

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

Процедура ЗаполнитьЗадачиПоСценарию(Сценарий, ПерваяЗадача = Неопределено) 
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	НастройкиОбмена.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
		|	НастройкиОбмена.ВыполняемоеДействие КАК ВыполняемоеДействие
		|ИЗ
		|	Справочник.СценарииОбменовДанными.НастройкиОбмена КАК НастройкиОбмена
		|ГДЕ
		|	НастройкиОбмена.Ссылка = &Ссылка
		|	И НЕ НастройкиОбмена.УзелИнформационнойБазы.Код ЕСТЬ NULL
		|
		|УПОРЯДОЧИТЬ ПО
		|	НастройкиОбмена.НомерСтроки";
	
	Запрос.УстановитьПараметр("Ссылка", Сценарий);
	
	Выборка = Запрос.Выполнить().Выбрать(); // АПК:1328 - блокировка не требуется.
	
	НомерЗадачи = 1;
	
	Запись = СтруктураЗадачи();
	Запись.ДатаСоздания = ТекущаяУниверсальнаяДата();
	Запись.Сценарий = Сценарий;
	Запись.ЗавершенаУспешно = Ложь;
	Запись.ЗавершенаСОшибкой = Ложь;
	Запись.ИдентификаторОбмена = Строка(Новый УникальныйИдентификатор);
	
	Набор = РегистрыСведений.ЗадачиОбменаДаннымиВнутренняяПубликация.СоздатьНаборЗаписей();
		
	Пока Выборка.Следующий() Цикл
		
		Запись.Вставить("УзелИнформационнойБазы", Выборка.УзелИнформационнойБазы);
		
		НастройкиТранспорта = ТранспортСообщенийОбмена.НастройкиТранспорта(Выборка.УзелИнформационнойБазы, "SM");	
		
		Запись.ОбластьДанныхКорреспондента = НастройкиТранспорта.ОбластьДанныхКорреспондента;
		Запись.Режим = НСтр("ru = 'Автоматический'", ОбщегоНазначения.КодОсновногоЯзыка());
		
		Если Выборка.ВыполняемоеДействие = Перечисления.ДействияПриОбмене.ЗагрузкаДанных Тогда
			
			//
			Запись.Действие = Перечисления.ДействияПриОбменеВнутренняяПубликация.ВыгрузкаДанныхКорреспондент;
			Запись.ИдентификаторЗадачи = Строка(Новый УникальныйИдентификатор);
			Запись.НомерЗадачи = НомерЗадачи;
						
			НоваяЗапись = Набор.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяЗапись, Запись);
			
			Если ПерваяЗадача = Неопределено Тогда
				ПерваяЗадача = ОбщегоНазначения.СкопироватьРекурсивно(Запись, Ложь);
			КонецЕсли;
			
			НомерЗадачи = НомерЗадачи + 1;
			
			//
			Запись.Действие = Перечисления.ДействияПриОбменеВнутренняяПубликация.ЗагрузкаДанных;
			Запись.ИдентификаторЗадачи = Строка(Новый УникальныйИдентификатор);
			Запись.НомерЗадачи = НомерЗадачи;
			
			НоваяЗапись = Набор.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяЗапись, Запись);
			
			НомерЗадачи = НомерЗадачи + 1;
			
		Иначе
			
			//
			Запись.Действие = Перечисления.ДействияПриОбменеВнутренняяПубликация.ВыгрузкаДанных;
			Запись.ИдентификаторЗадачи = Строка(Новый УникальныйИдентификатор);
			Запись.НомерЗадачи = НомерЗадачи;
			
			НоваяЗапись = Набор.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяЗапись, Запись);
			
			Если ПерваяЗадача = Неопределено Тогда
				ПерваяЗадача = ОбщегоНазначения.СкопироватьРекурсивно(Запись, Ложь);
			КонецЕсли;
			
			НомерЗадачи = НомерЗадачи + 1;
			
			//
			Запись.Действие = Перечисления.ДействияПриОбменеВнутренняяПубликация.ЗагрузкаДанныхКорреспондент;
			Запись.ИдентификаторЗадачи = Строка(Новый УникальныйИдентификатор);
			Запись.НомерЗадачи = НомерЗадачи;
			
			НоваяЗапись = Набор.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяЗапись, Запись);
			
			НомерЗадачи = НомерЗадачи + 1;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Набор.Записать(Ложь);
	
КонецПроцедуры

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

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

Процедура ОтветныйВызов(ИмяПланаОбмена, КодУзлаИнформационнойБазы, ИдентификаторЗадачи, Ошибка = "")
	
	Узел = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(КодУзлаИнформационнойБазы);
	
	НастройкиТранспорта = ТранспортСообщенийОбмена.НастройкиТранспорта(Узел, "SM");
	
	МодульНастройкиТранспортаОбменаСообщениями = ОбщегоНазначения.ОбщийМодуль("РегистрыСведений.НастройкиТранспортаОбменаСообщениями");
	НастройкиТранспортаWS = МодульНастройкиТранспортаОбменаСообщениями.НастройкиТранспортаWS(НастройкиТранспорта.КонечнаяТочкаКорреспондента);

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

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

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

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

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

Процедура ВыполнитьЗадачуЗагрузкаДанных(Задача, Прокси, ПараметрыОбмена, СтруктураНастроекОбмена, ОбластьДанных, Отказ, Ошибка)
	
	Если Отказ Тогда
		Возврат;
	КонецЕсли;

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

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

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

Процедура ВыполнитьЗадачуВыгрузкаДанных(Задача, Прокси, СтруктураНастроекОбмена, ОбластьДанных, Отказ, Ошибка)

	Если Отказ Тогда
		Возврат;
	КонецЕсли;

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

Процедура ВыполнитьЗадачуЗагрузкаДанныхКорреспондент(Задача, Прокси, ПараметрыОбмена, СтруктураНастроекОбмена, ОбластьДанных, Отказ, Ошибка)
	
	Если Отказ Тогда
		Возврат;
	КонецЕсли;

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

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

Процедура ВыполнитьЗадачуДополнительнаяРегистрация(Задача, Отказ, Ошибка)
	
	Если Отказ Тогда
		Возврат;
	КонецЕсли;

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

Процедура ПроверитьБлокировкуЗадачи(Задача, Отказ)
	Перем ИдентификаторЗадачи, ДатаСоздания, УзелИнформационнойБазы, НомерЗадачи, ИдентификаторОбмена, Сценарий;
	
	Если ТипЗнч(Задача) <> Тип("Структура") Тогда
		
		Возврат;
		
	КонецЕсли;
	
	Попытка
		
		КлючРегистра = РегистрыСведений.ЗадачиОбменаДаннымиВнутренняяПубликация.СоздатьКлючЗаписи(Задача);
		ЗаблокироватьДанныеДляРедактирования(КлючРегистра);
		
	Исключение
		
		Отказ = Истина;
		ШаблонТекста = НСтр("ru = 'Задача с идентификатором [%1] заблокирована.
			|Вероятно она находится в состоянии выполнения.
			|	Дата создания: %2
			|	Узел ИБ: %3
			|	Номер: %4
			|	Идентификатор Обмена: %5
			|	Сценарий: %6'", ОбщегоНазначения.КодОсновногоЯзыка());
		
		Задача.Свойство("ИдентификаторЗадачи", ИдентификаторЗадачи);
		Задача.Свойство("ДатаСоздания", ДатаСоздания);
		Задача.Свойство("УзелИнформационнойБазы", УзелИнформационнойБазы);
		Задача.Свойство("НомерЗадачи", НомерЗадачи);
		Задача.Свойство("ИдентификаторОбмена", ИдентификаторОбмена);
		Задача.Свойство("Сценарий", Сценарий);
		
		Комментарий = СтрШаблон(ШаблонТекста, ИдентификаторЗадачи, ДатаСоздания,
			УзелИнформационнойБазы, НомерЗадачи, ИдентификаторОбмена, Сценарий);
			
		ИмяСобытия = ОбменДаннымиВМоделиСервиса.СобытиеЖурналаРегистрацииСинхронизацииДанных();
		ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Информация, , , Комментарий);
		
	КонецПопытки;
	
КонецПроцедуры

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

#Область НастройкаФормыУзла

Процедура УстановитьФункциональныеОпцииДляУзла(Форма)

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

Процедура НастроитьЭлементыФормыПоПереходуНаВебСервис(Форма)

	УстановитьПривилегированныйРежим(Истина);
	
	Элементы = Форма.Элементы;
	Узел = Форма.Объект.Ссылка;
	
	ИдентификаторТранспорта = Неопределено;
	НастройкиТранспорта = ТранспортСообщенийОбмена.НастройкиТранспортаПоУмолчанию(Узел, ИдентификаторТранспорта);
	
	ЭтоОбменЧерезВнутреннююПубликацию = ИдентификаторТранспорта = "SM" И НастройкиТранспорта.ВнутренняяПубликация;
	ДоступенExchangeAdministrationManage_3_0_1_1 = ДляУзлаДоступенExchangeAdministrationManage_3_0_1_1(Узел) = Истина;
		
	Если Не Пользователи.ЭтоПолноправныйПользователь()
		Или Узел.Пустая()
		Или	ЭтоОбменЧерезВнутреннююПубликацию
		Или Не ДоступенExchangeAdministrationManage_3_0_1_1
		Или Не ОбменДаннымиПовтИсп.ЭтоПланОбменаXDTO(Узел)
		Или Не ОбменДаннымиСервер.НастройкаСинхронизацииЗавершена(Узел) Тогда
		
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
			Форма.Элементы,
			"ФормаОбщаяКомандаПомощникПереходаНаИнтернетВнутренняяПубликация",
			"Видимость",
			Ложь);
			
		Возврат; 
				 
	КонецЕсли;
	
	Элементы = Форма.Элементы;
	
	ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
		Форма.Элементы,
		"ФормаОбщаяКомандаПомощникПереходаНаИнтернетВнутренняяПубликация",
		"ПоложениеВКоманднойПанели",
		ПоложениеКнопкиВКоманднойПанели.ВДополнительномПодменю);
		
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	Настройки.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
		|	Настройки.ПереходНаWS_Этап КАК ПереходНаWS_Этап
		|ИЗ
		|	РегистрСведений.ОбщиеНастройкиУзловИнформационныхБаз КАК Настройки
		|ГДЕ
		|	Настройки.УзелИнформационнойБазы = &Узел";
	
	Запрос.УстановитьПараметр("Узел", Узел);
		
	Выборка = Запрос.Выполнить().Выбрать();
								
	НеЗаконченПереходНаВебСервис = Выборка.Следующий() И Выборка.ПереходНаWS_Этап > 0;
	НеПредлагатьПерейтиНаВебСервис = ОбменДаннымиВнутренняяПубликацияВызовСервера.ФлагНастройкиНеПредлагатьПерейтиНаВебСервис(Узел);
	ТекстПанели = "";
	
	Если НеЗаконченПереходНаВебСервис Тогда
		
		ТекстПанели = 
			НСтр("ru = '<br>Не завершен переход на обмен через Интернет (веб-сервис). 
                  |<br> 
                  |<br>Воспользуйтесь <a href=ФормаПомощникПереходаНаИнтернетВнутренняяПубликация>помощником</a> для завершения перехода.'"); 
			
	ИначеЕсли Не НеПредлагатьПерейтиНаВебСервис Тогда
												
		ТекстПанели = 
			НСтр("ru = 'Для данной синхронизации есть возможность настроить обмен через Интернет (веб-сервис). 
                  |<br>Это позволит ускорить обмен и более гибко настроить график синхронизации. 
                  |<br>Для перехода на обмен посредством веб-сервиса, воспользуйтесь <a href=ФормаПомощникПереходаНаИнтернетВнутренняяПубликация>помощником перехода</a>.
                  |<br><br>
                  |<a href=НеПредлагатьПерейтиНаВебСервис>Больше не предлагать перейти на веб-сервис</a>. (Вызвать помощник перехода можно через меню <b>Еще<b>)'");
									
	КонецЕсли;
	
	Если Не ПустаяСтрока(ТекстПанели) Тогда
		
		ИмяЭлемента = "ИнформацияОПереходеНаВебСервис"; 
		
		Группа = Элементы.Вставить(ИмяЭлемента, Тип("ГруппаФормы"), Форма, Элементы.ФормаКоманднаяПанель);
		Группа.Вид 			= ВидГруппыФормы.ОбычнаяГруппа;
		Группа.Группировка 	= ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда;
		Группа.ЦветФона 	= WebЦвета.БледноЗеленый;
		Группа.ОтображатьЗаголовок = Ложь;
		
		ДекорацияОтступ = Элементы.Добавить("Отступ" + ИмяЭлемента, Тип("ДекорацияФормы"), Группа);
		ДекорацияОтступ.Вид = ВидДекорацииФормы.Надпись;
		
		ДекорацияКартинка = Элементы.Добавить("Картинка" + ИмяЭлемента, Тип("ДекорацияФормы"), Группа);
		ДекорацияКартинка.Вид 		= ВидДекорацииФормы.Картинка;
		ДекорацияКартинка.Картинка 	= БиблиотекаКартинок.Информация;
		ДекорацияКартинка.Высота 	= 3;
		ДекорацияКартинка.Ширина 	= 5;
		ДекорацияКартинка.РазмерКартинки = РазмерКартинки.Пропорционально;
		
		ФДок = Новый ФорматированныйДокумент;
		ФДок.УстановитьHTML("<html>" + ТекстПанели + "</html>", Новый Структура);
		
		ДекорацияНадпись = Элементы.Добавить("Надпись" + ИмяЭлемента, Тип("ДекорацияФормы"), Группа);
		ДекорацияНадпись.Вид 						= ВидДекорацииФормы.Надпись;
		ДекорацияНадпись.АвтоМаксимальнаяШирина 	= Ложь;
		ДекорацияНадпись.РастягиватьПоГоризонтали 	= Истина;
		ДекорацияНадпись.Заголовок 					= ФДок.ПолучитьФорматированнуюСтроку();
		ДекорацияНадпись.УстановитьДействие("ОбработкаНавигационнойСсылки", "Подключаемый_ОбработкаНавигационнойСсылки");
	
	КонецЕсли;
		
КонецПроцедуры

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

#Область Прочее

Функция ДляУзлаДоступенExchangeAdministrationManage_3_0_1_1(Узел)
	
	Доступен = РегистрыСведений.НастройкиОбменаДаннымиXDTO.ЗначениеНастройкиКорреспондента(Узел, "ДоступенExchangeAdministrationManage_3_0_1_1");
	
	Возврат Доступен = Истина;
		
КонецФункции

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

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

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

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

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

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

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