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

#Область ОбработчикиСобытийФормы

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

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	Если БлокировкаУзлаУстановлена Тогда
		
		Шаг = 2;
		
	Иначе
		
		Шаг = 1;
		
	КонецЕсли;
	
	УстановитьПорядковыйНомерПерехода(Шаг);
	
КонецПроцедуры

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

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

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура ПерейтиВЖурналРегистрации(Команда)
	
	ПараметрыФормы = ДанныеОтбораЖурналаРегистрации(УзелИнформационнойБазы);
	ОткрытьФорму("Обработка.ЖурналРегистрации.Форма", ПараметрыФормы, ЭтотОбъект);
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьОбновление(Команда)
	
	ОбменДаннымиКлиент.УстановитьОбновлениеКонфигурации(ЗавершениеРаботыСистемы);
	
КонецПроцедуры

&НаКлиенте
Процедура ПерезапуститьПрограмму(Команда)

	ЗавершитьРаботуСистемы(Ложь, Истина);

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

&НаКлиенте
Процедура ВыполнитьОбмен(Команда)
	
	ВыполнитьПереходДалее();
	
КонецПроцедуры

&НаКлиенте
Процедура ПродолжитьСинхронизацию(Команда)
	
	ПорядковыйНомерПерехода = ПорядковыйНомерПерехода - 1;
	УстановитьПорядковыйНомерПерехода(ПорядковыйНомерПерехода + 1);
	
КонецПроцедуры

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

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

////////////////////////////////////////////////////////////////////////////////
// ПОСТАВЛЯЕМАЯ ЧАСТЬ
////////////////////////////////////////////////////////////////////////////////

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

&НаКлиенте
Процедура ВыполнитьПереходДалее()
	
	ИзменитьПорядковыйНомерПерехода(+1);
	
КонецПроцедуры

&НаКлиенте
Процедура ИзменитьПорядковыйНомерПерехода(Итератор)
	
	ОчиститьСообщения();
	УстановитьПорядковыйНомерПерехода(ПорядковыйНомерПерехода + Итератор);
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьПорядковыйНомерПерехода(Знач Значение)
	
	ЭтоПереходДалее = (Значение > ПорядковыйНомерПерехода);
	
	ПорядковыйНомерПерехода = Значение;
	
	Если ПорядковыйНомерПерехода < 0 Тогда
		ПорядковыйНомерПерехода = 0;
	КонецЕсли;
	
	ПорядковыйНомерПереходаПриИзменении(ЭтоПереходДалее);
	
КонецПроцедуры

&НаКлиенте
Процедура ПорядковыйНомерПереходаПриИзменении(Знач ЭтоПереходДалее)
	
	// Выполняем обработчики событий перехода.
	ВыполнитьОбработчикиСобытийПерехода(ЭтоПереходДалее);
	
	// Устанавливаем отображение страниц.
	СтрокиПереходаТекущие = ТаблицаПереходов.НайтиСтроки(Новый Структура("ПорядковыйНомерПерехода", ПорядковыйНомерПерехода));
	
	Если СтрокиПереходаТекущие.Количество() = 0 Тогда
		ВызватьИсключение НСтр("ru = 'Не определена страница для отображения.'");
	КонецЕсли;
	
	СтрокаПереходаТекущая = СтрокиПереходаТекущие[0];
	
	Элементы.ВыполнениеОбменаДанными.ТекущаяСтраница = Элементы[СтрокаПереходаТекущая.ИмяОсновнойСтраницы];
	
	Если ЭтоПереходДалее И СтрокаПереходаТекущая.ДлительнаяОперация Тогда
		ПодключитьОбработчикОжидания("ВыполнитьОбработчикДлительнойОперации", 0.1, Истина);
	КонецЕсли;
	
КонецПроцедуры

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

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

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

////////////////////////////////////////////////////////////////////////////////
// ПЕРЕОПРЕДЕЛЯЕМАЯ ЧАСТЬ
////////////////////////////////////////////////////////////////////////////////

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

&НаКлиенте
Процедура ЗапуститьПереходДалее()
	
	ПерейтиДалее      = Истина;
	ВыполнитьПереходДалее();
	
КонецПроцедуры

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

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

&НаСервере
Процедура ПроверкаНеобходимостиПереходаНаНовыйОбмен()
	
	МассивСообщений = ПолучитьСообщенияПользователю(Истина);
	
	Если МассивСообщений = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Количество = МассивСообщений.Количество();
	Если Количество = 0 Тогда
		Возврат;
	КонецЕсли;
	
	Сообщение      = МассивСообщений[Количество-1];
	ТекстСообщения = Сообщение.Текст;
	
	// При необходимости из сообщения удаляется идентификатор подсистемы.
	Если СтрНачинаетсяС(ТекстСообщения, "{ВыполненПереходНаНовыйОбмен}") Тогда
		
		ДанныеСообщения = ОбщегоНазначения.ЗначениеИзСтрокиXML(ТекстСообщения);
		
		Если ДанныеСообщения <> Неопределено
			И ТипЗнч(ДанныеСообщения) = Тип("Структура") Тогда
			
			ИмяПланаОбмена                    = ДанныеСообщения.ИмяПланаОбменаДляПереходаНаНовыйОбмен;
			КодУзлаПланаОбмена                = ДанныеСообщения.Код;
			НоваяНастройкаСинхронизацииДанных = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(КодУзлаПланаОбмена);
			
			ФоновоеЗаданиеРезультатВыполнения.ДополнительныеДанныеРезультата.Вставить("ПараметрыПовторногоОткрытияФормы",
				Новый Структура("НоваяНастройкаСинхронизацииДанных", НоваяНастройкаСинхронизацииДанных));
				
			ФоновоеЗаданиеРезультатВыполнения.ДополнительныеДанныеРезультата.Вставить("ЗакрытьФормуБезусловно", Истина);
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

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

&НаСервереБезКонтекста
Процедура ЗавершитьВыполнениеДлительнойОперации(ИдентификаторЗадания)
	ДлительныеОперации.ОтменитьВыполнениеЗадания(ИдентификаторЗадания);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ТребуетсяУстановкаОбновления()
	
	Возврат ОбменДаннымиСервер.ТребуетсяУстановкаОбновления();
	
КонецФункции

&НаСервереБезКонтекста
Функция ТребуетсяПерезагрузка()
	
	Возврат Справочники.ВерсииРасширений.РасширенияИзмененыДинамически();
	
КонецФункции

&НаСервереБезКонтекста
Процедура ПроверитьВозможностьЗапускаОбмена(УзелОбмена, БлокировкаУстановлена)
	
	Отказ = Ложь;
	ОбменДаннымиСервер.ПроверитьВозможностьЗапускаОбмена(УзелОбмена, Отказ);
	
	БлокировкаУстановлена = Не Отказ;
	
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьВозможностьЗапускаОбменаОбработкаОжидания()
	
	ПроверитьВозможностьЗапускаОбмена(УзелИнформационнойБазы, БлокировкаУзлаУстановлена);
	
	Если БлокировкаУзлаУстановлена Тогда
		ИзменитьПорядковыйНомерПерехода(+1);
	Иначе
		ПодключитьОбработчикОжидания("ПроверитьВозможностьЗапускаОбменаОбработкаОжидания", 15, Истина);
	КонецЕсли;
	
КонецПроцедуры

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

		Иначе
			
			Шаблон = НСтр("ru = 'Для узла ""%1"" уже выполняется синхронизация.
                           |
                           |Нажмите Далее, чтобы прервать текущую синхронизацию
                           |и запустить ее снова'");
			ТекстСообщения = СтрШаблон(Шаблон, Строка(УзелИнформационнойБазы));

		КонецЕсли;
		
		Элементы.СтатусЗадачаВОчереди.Заголовок = ТекстСообщения;
		
	Иначе
		
		ПропуститьСтраницу = Истина;
		
	КонецЕсли;
		
	Возврат Неопределено;
	
КонецФункции

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

&НаКлиенте
Процедура ОтменитьОчередьИПродолжить(Команда)
	ОтменитьОчередьИПродолжитьНаСервере();
	ВыполнитьПереходДалее();
КонецПроцедуры

&НаКлиенте
Процедура ЗавершитьСинхронизацию(Команда)

	ЗавершитьСинхронизациюНаСервере(); 
	Закрыть();

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

&НаСервере
Процедура ЗавершитьСинхронизациюНаСервере()

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

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

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

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

&НаКлиенте
Функция Подключаемый_ВыгрузкаДанных_ПриОткрытии(Отказ, ПропуститьСтраницу, ЭтоПереходДалее)
	
	Если СинхронизацияДанныхОтключена Тогда
		ПропуститьСтраницу = Истина;
	Иначе
		ИнициализироватьПеременныеОбработки();
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

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

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

&НаКлиенте
Процедура ПриНачалеВыгрузкиДанных(Отказ)

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

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

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

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

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

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

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

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

&НаСервереБезКонтекста
Процедура ПриОжиданииВыгрузкиДанныхЧерезВнутреннююПубликациюНаСервере(ПараметрыОбмена, ПродолжитьОжидание)
	
	МодульОбменДаннымиВнутренняяПубликация = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиВнутренняяПубликация");
	МодульОбменДаннымиВнутренняяПубликация.ПриОжиданииВыгрузкиДанных(ПараметрыОбмена, ПродолжитьОжидание);
	
КонецПроцедуры

&НаКлиенте
Процедура ПриЗавершенииВыгрузкиДанныхЧерезВнутреннююПубликацию()
		
	ЕстьОшибки = ЕстьОшибки Или ПараметрыОбменаЧерезВнутреннююПубликацию.Отказ;
		
	ВыводитьОписаниеОшибкиПользователю = Истина;
	СообщениеОбОшибкеПользователю = ПараметрыОбменаЧерезВнутреннююПубликацию.СообщениеОбОшибке;
	
	ИзменитьПорядковыйНомерПерехода(+1);
	
КонецПроцедуры

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

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

#Область СтраницыОбменаЧерезВебСервис

&НаКлиенте
Процедура АвторизацияЗавершение(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = Неопределено Тогда
		Закрыть();
	КонецЕсли;
	
	// Проверка подключения?
	
	ВыполнитьПереходДалее();
	
КонецПроцедуры

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

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

#Область РазделОбработкиФоновыхЗаданий

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

&НаКлиенте
Процедура ЗавершениеФоновогоЗадания(Результат, ДополнительныеПараметры) Экспорт
	
	ФоновоеЗаданиеРезультатВыполнения = Результат;
	РезультатВыполненияФоновогоЗадания();
	
КонецПроцедуры

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

&НаКлиенте
Процедура РезультатВыполненияФоновогоЗадания()
	
	ФоновоеЗаданиеПолучитьРезультатНаСервере();
	ЗавершениеДлительнойОперации();
	
КонецПроцедуры

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

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

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

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

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

#Область ИнициализацияПереходов

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

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

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

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

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

#Область РазделОбработчиковСобытийПереходов

////////////////////////////////////////////////////////////////////////////////
// Общие страницы обмена

&НаКлиенте
Процедура СтатусНедоступностьСинхронизацииОбработкаНавигационнойСсылки(Элемент, НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	Если НавигационнаяСсылкаФорматированнойСтроки = "ОжидатьВозможностьСинхронизации" Тогда
		
		Шаг = ПорядковыйНомерПерехода + 1;
		УстановитьПорядковыйНомерПерехода(Шаг);
		
	КонецЕсли;
	
КонецПроцедуры



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

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