Загрузка данных


// BSLLS:MissingVariablesDescription-off
// BSLLS:UnusedLocalVariable-off
// Соответствие; для обнуления будем вызывать "Кэш = Неопределено".
Перем 
// BSLLS:ExportVariables-off
Кэш Экспорт,
// BSLLS:ExportVariables-on
_МодульАвторизацияКэш,
_СтдСтрКэш,
_СтдJSONКэш,
_СтдДиалогиКэш,
_СтдКоллекцииКэш,
_СтдОбщегоНазначенияКэш,
_СтдОСКэш,
_СтдФСКэш;
// BSLLS:UnusedLocalVariable-on
// BSLLS:MissingVariablesDescription-on

//{		СЛУЖЕБНЫЕ  

Функция ВерсияОбработки() Экспорт
	
	Результат = "";
	
	ВерсияМодуля = ЗначениеМакетаВерсияОбработки();
	
	РазделительВерсии = "+";
	
	Результат = РазделитьСтрокуЛок(ВерсияМодуля, РазделительВерсии);
	
	Возврат Результат[0];
	
КонецФункции

Функция ПолнаяВерсияОбработки() Экспорт
	
	Результат = ЗначениеМакетаВерсияОбработки();
	ПровайдерСервиса = ИдентификаторПровайдераСервиса();
	
	Если ЗначениеЗаполнено(ПровайдерСервиса) Тогда
		Результат = Результат + "/" + ПровайдерСервиса;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ЗначениеМакетаВерсияОбработки()
	
	Макет = ПолучитьМакет("VERSION_txt");
	Результат = Макет.ПолучитьТекст();
	
	Возврат Результат;
	
КонецФункции

Функция КлючРазработчика()
	
	Возврат "1C-DDPro-4-66-3-bf555235-0ae2-48c2-999c-e55814341e79";
	
КонецФункции

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

Функция ЭтоВнешняяОбработкаИзФайла()
	
	Результат = ЭтоВнешняяОбработка();
	
	Если Результат Тогда
		Результат = Найти(ЭтотОбъект.ИспользуемоеИмяФайла,".epf") > 0;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

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

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

Функция ИдентификаторПровайдераСервиса()
	
	FlgServiceProviderId = "";

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

//}		СЛУЖЕБНЫЕ                 

//**********************************************
//{		ИНТЕРФЕЙС СТД

Функция СтдСтр() Экспорт
	
	Если _СтдСтрКэш = Неопределено Тогда
		Если ЭтоВнешняяОбработка() Тогда
			Тип = "ExternalDataProcessorObject.КонтурДиадокСтдСтр";
		Иначе
			Тип = "DataProcessorObject.КонтурДиадокСтдСтр";
		КонецЕсли;	
		_СтдСтрКэш = Новый(Тип);
	КонецЕсли;

	Возврат _СтдСтрКэш;
	
КонецФункции

Функция СтдJSON() Экспорт	
	
	Если _СтдJSONКэш = Неопределено Тогда
		Если ЭтоВнешняяОбработка() Тогда
			Тип = "ExternalDataProcessorObject.КонтурДиадокСтдJSON";
		Иначе
			Тип = "DataProcessorObject.КонтурДиадокСтдJSON";
		КонецЕсли;
		_СтдJSONКэш = Новый(Тип);
	КонецЕсли;
	
	Возврат _СтдJSONКэш;
	
КонецФункции

Функция СтдДиалоги() Экспорт	
	
	Если _СтдДиалогиКэш = Неопределено Тогда
		Если ЭтоВнешняяОбработка() Тогда
			Тип = "ExternalDataProcessorObject.КонтурДиадокСтдДиалоги";
		Иначе
			Тип = "DataProcessorObject.КонтурДиадокСтдДиалоги";
		КонецЕсли;
		_СтдДиалогиКэш = Новый(Тип);
	КонецЕсли;
	
	Возврат _СтдДиалогиКэш;
	
КонецФункции

Функция СтдКоллекции() Экспорт
	
	Если _СтдКоллекцииКэш = Неопределено Тогда
		Если ЭтоВнешняяОбработка() Тогда
			Тип = "ExternalDataProcessorObject.КонтурДиадокСтдКоллекции";
		Иначе
			Тип = "DataProcessorObject.КонтурДиадокСтдКоллекции";
		КонецЕсли;
		_СтдКоллекцииКэш = Новый(Тип);
	КонецЕсли;
	
	Возврат _СтдКоллекцииКэш;
	
КонецФункции

Функция СтдОбщегоНазначения() Экспорт
	
	Если _СтдОбщегоНазначенияКэш = Неопределено Тогда
		Если ЭтоВнешняяОбработка() Тогда
			Тип = "ExternalDataProcessorObject.КонтурДиадокСтдОбщегоНазначения";
		Иначе
			Тип = "DataProcessorObject.КонтурДиадокСтдОбщегоНазначения";
		КонецЕсли;
		_СтдОбщегоНазначенияКэш = Новый(Тип);
	КонецЕсли;
	
	Возврат _СтдОбщегоНазначенияКэш;
	
КонецФункции

Функция СтдОС() Экспорт
	
	Если _СтдОСКэш = Неопределено Тогда
		Если ЭтоВнешняяОбработка() Тогда
			Тип = "ExternalDataProcessorObject.КонтурДиадокСтдОС";
		Иначе
			Тип = "DataProcessorObject.КонтурДиадокСтдОС";
		КонецЕсли;
		_СтдОСКэш = Новый(Тип);
	КонецЕсли;
	
	Возврат _СтдОСКэш;
	
КонецФункции

Функция СтдФС() Экспорт
	
	Если _СтдФСКэш = Неопределено Тогда
		Если ЭтоВнешняяОбработка() Тогда
			Тип = "ExternalDataProcessorObject.КонтурДиадокСтдФС";
		Иначе
			Тип = "DataProcessorObject.КонтурДиадокСтдФС";
		КонецЕсли;
		_СтдФСКэш = Новый(Тип);
	КонецЕсли;
	
	Возврат _СтдФСКэш;
	
КонецФункции

//**********************************************

//{		ХРАНИЛИЩЕ ОБЩИХ НАСТРОЕК 

// Сохраняет настройку в хранилище общих настроек текущего пользователя,
// по ключу объекта "НастройкиКонтурЭДО".
// 
// Параметры:
//   КлючНастроек - Строка       - ключ сохраняемых настроек.
//   Значение     - Произвольный - содержит настройки, которые нужно сохранить в хранилище. 
// 
Процедура ХранилищеОбщихНастроек_Сохранить(КлючНастроек, Значение) Экспорт
	
	ХранилищеОбщихНастроек.Сохранить("НастройкиКонтурЭДО", КлючНастроек, Значение);
	
КонецПроцедуры

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

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

//}		ХРАНИЛИЩЕ ОБЩИХ НАСТРОЕК


//{		ОЦЕНКА ФУНКЦИОНАЛЬНОСТИ МОДУЛЯ

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

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

Функция ОтзывПоРаботеСМодулем_ДатаЗавершенияСбора(СценарийМодуляДляОтзыва)
	
	СценарииМодуля = Модуль_Ядро().Перечисление_СценарииМодуляДляОтзывов();
	// BSLLS:MagicNumber-off
	Если СценарийМодуляДляОтзыва = СценарииМодуля.РаботаСКонтрагентами Тогда
		Результат = Дата(2024, 5, 1);
	ИначеЕсли СценарийМодуляДляОтзыва = СценарииМодуля.ОплатаСервиса Тогда
		ДатаЗавершенияСбораСтрокой = '20250501';
		Результат = Дата(ДатаЗавершенияСбораСтрокой);
	ИначеЕсли СценарийМодуляДляОтзыва = СценарииМодуля.ПоискДокументовНаОтправку Тогда
		Результат = Дата(2024, 11, 1);
	ИначеЕсли СценарийМодуляДляОтзыва = СценарииМодуля.СобытияЛентыКонтрагентов Тогда
		Результат = Дата(2025, 12, 1);
	ИначеЕсли СценарийМодуляДляОтзыва = СценарииМодуля.Авторизация Тогда
		Результат = Дата(2026, 06, 1);
	КонецЕсли;
	// BSLLS:MagicNumber-on
	Возврат Результат;
	
КонецФункции

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

//}		ОЦЕНКА ФУНКЦИОНАЛЬНОСТИ МОДУЛЯ


//{		ОБЩЕГО НАЗНАЧЕНИЯ

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

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

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

// Сравнивает текущую версию приложения с указанной версией.
// 
// Параметры:
//  Версия - Строка - номер версии, с которой нужно сравнить текущую версию приложения.
//
// Возвращаемое значение:
//   Булево - Истина, если текущая версия приложения старше чем версия параметра.
//            Например, 8.2 старше чем 8.3.
//
Функция ПриложениеСтаршеВерсии(Версия) Экспорт
	
	Результат = (СравнитьВерсии(ОписаниеСистемнойИнформации().ВерсияПриложения, Версия) < 0);
	
	Возврат Результат;
	
КонецФункции

// Сравнить две строки версий. Версии типа "1.0.1b" сравнивать нельзя.
//
// Параметры
//  СтрокаВерсии1 - Строка - номер версии в формате РР.{П|ПП}.ЗЗ.СС
//  СтрокаВерсии2 - Строка - второй сравниваемый номер версии
//
// Возвращаемое значение:
//   Число - больше 0, если СтрокаВерсии1 > СтрокаВерсии2; 0, если версии равны.
//
Функция СравнитьВерсии(Знач СтрокаВерсии1, Знач СтрокаВерсии2)
	
	Результат = 0;
	
	Пока НЕ ПустаяСтрока(СтрокаВерсии1) ИЛИ НЕ ПустаяСтрока(СтрокаВерсии2) Цикл
		
		Поз = Найти(СтрокаВерсии1, ".");
		Если Поз > 0 Тогда
			НомерПервойВерсии = Число(Лев(СтрокаВерсии1, Поз - 1));
			СтрокаВерсии1 = Сред(СтрокаВерсии1, Поз + 1);
		Иначе
			НомерПервойВерсии = ?(ПустаяСтрока(СтрокаВерсии1), 0, Число(СтрокаВерсии1));
			СтрокаВерсии1 = "";
		КонецЕсли;
		
		Поз = Найти(СтрокаВерсии2, ".");
		Если Поз > 0 Тогда
			НомерВторойВерсии = Число(Лев(СтрокаВерсии2, Поз - 1));
			СтрокаВерсии2 = Сред(СтрокаВерсии2, Поз + 1);
		Иначе
			НомерВторойВерсии = ?(ПустаяСтрока(СтрокаВерсии2), 0, Число(СтрокаВерсии2));
			СтрокаВерсии2 = "";
		КонецЕсли;
		
		Результат = НомерПервойВерсии - НомерВторойВерсии;
		
		Если Результат <> 0 Тогда
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

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

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

// Добавляет в имя файла, путь к каталогу текущей обработки.
//
// Параметры:
//  ИмяФайла - Строка - Имя файла в каталоге
//
// Возвращаемое значение:
//   Строка - Каталог, в котором расположен файл текущей обработки.
//            Пустая строка, если обработка создана не из файла.
//
Функция ПутьКФайлуВКаталогеТекущейОбработки(ИмяФайла)
	// BSLLS:DeprecatedFind-off
	ПрефиксПМ = "КонтурДиадокИнтеграция";
	
	ИмяМенеджераИнтеграции = "КонтурДиадокМенеджерИнтеграции";
	ЭтоМенеджерИнтеграции = (Найти(ИмяФайла, ИмяМенеджераИнтеграции) > 0);
	
	Если Найти(ИмяФайла, ПрефиксПМ) > 0 ИЛИ ЭтоМенеджерИнтеграции Тогда
		КаталогВложеннойОбработки = "include\";
	Иначе
		КаталогВложеннойОбработки = "libs\";
	КонецЕсли;
	
	Результат = ОбъединитьПути(КаталогОбработки() + КаталогВложеннойОбработки, ИмяФайла);
	
	Возврат Результат;
	// BSLLS:DeprecatedFind-on
КонецФункции

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

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

// Объединяет части пути через разделитель
//
Функция ОбъединитьПути(П1, П2, П3 = Неопределено, П4 = Неопределено) Экспорт
	
	Результат = П1;
	
	РазделительПути = РазделительПути();
	
	ЧастиПути = Новый Массив;
	ЧастиПути.Добавить(П2);
	ЧастиПути.Добавить(П3);
	ЧастиПути.Добавить(П4);
	
	Для Каждого Элемент Из ЧастиПути Цикл
		
		Если Не ЗначениеЗаполнено(Элемент) Тогда
			Прервать;
		КонецЕсли;
		
		Если Прав(Результат, 1) <> РазделительПути Тогда
			Результат = Результат + РазделительПути;
		КонецЕсли;
		
		Результат = Результат + Элемент;
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

// Возвращает разделитель пути, используемого в операционной системе
// 
// Возвращаемое значение:
//  Строка
//
Функция РазделительПути()
	
	СисИнфо = Новый СистемнаяИнформация;
	Если СравнитьВерсии(СисИнфо.ВерсияПриложения, "8.3.3") < 0 Тогда
		
		Результат = "\";
		Если Найти(СисИнфо.ТипПлатформы, "Linux") > 0 Тогда
			Результат = "/";
		КонецЕсли;
		
	Иначе
		Результат = Вычислить("ПолучитьРазделительПути()");
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

// Проверяет существование файла
//
// Параметры:
//  ИмяФайла - Строка - полное имя файла
// 
// Возвращаемое значение:
//  Булево - Истина, если файл существует
//
Функция ФайлСуществует(ИмяФайла)
	
	Файл = Новый Файл(ИмяФайла);
	
	Результат = Файл.Существует();
	
	Возврат Результат;
	
КонецФункции

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

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

// Фиксирует Данные типов Структура, Соответствие, Массив с учетом вложенности.
//
// BSLLS:TooManyReturns-off
// BSLLS:CognitiveComplexity-off
// BSLLS:CyclomaticComplexity-off
// BSLLS:IfElseIfEndsWithElse-off
// BSLLS:IfConditionComplexity-off
// BSLLS:DuplicateStringLiteral-off
//
// Параметры:
//  Данные - Структура
//         - Соответствие
//         - Массив - коллекции, значения которых являются примитивными типами,
//           хранилищем значения или не могут быть изменены. Поддерживаются типы значений:
//           Булево, Строка, Число, Дата, Неопределено, УникальныйИдентификатор, Null, Тип,
//           ХранилищеЗначения, ОбщийМодуль, ОбъектМетаданных, ТипЗначенияXDTO, ТипОбъектаXDTO,
//           ЛюбаяСсылка.
//
// Возвращаемое значение:
//  ФиксированнаяСтруктура, ФиксированноеСоответствие, ФиксированныйМассив - фиксированные данные, аналогичные
//    переданным в параметре Данные.
// 
Функция ФиксированныеДанные(Данные)
	
	Если ТипЗнч(Данные) = Тип("Массив")
		Или ТипЗнч(Данные) = Тип("ФиксированныйМассив") Тогда
		Массив = Новый Массив;
		
		Для Каждого Значение Из Данные Цикл
			
			Если ТипЗнч(Значение) = Тип("Структура")
				Или ТипЗнч(Значение) = Тип("Соответствие")
				Или ТипЗнч(Значение) = Тип("Массив")
				Или ТипЗнч(Значение) = Тип("ФиксированныйМассив") Тогда
				
				Массив.Добавить(ФиксированныеДанные(Значение));
				
			Иначе
				Массив.Добавить(Значение);
			КонецЕсли;
		КонецЦикла;
		
		Возврат Новый ФиксированныйМассив(Массив);
		
	ИначеЕсли ТипЗнч(Данные) = Тип("Структура")
		Или ТипЗнч(Данные) = Тип("Соответствие") Тогда
		
		Если ТипЗнч(Данные) = Тип("Структура") Тогда
			Коллекция = Новый Структура;
		Иначе
			Коллекция = Новый Соответствие;
		КонецЕсли;
		
		Для Каждого КлючИЗначение Из Данные Цикл
			Значение = КлючИЗначение.Значение;
			
			Если ТипЗнч(Значение) = Тип("Структура")
			 ИЛИ ТипЗнч(Значение) = Тип("Соответствие")
			 ИЛИ ТипЗнч(Значение) = Тип("Массив") Тогда
				
				Коллекция.Вставить(
					КлючИЗначение.Ключ, ФиксированныеДанные(Значение));
			Иначе
				Коллекция.Вставить(КлючИЗначение.Ключ, Значение);
			КонецЕсли;
		КонецЦикла;
		
		Если ТипЗнч(Данные) = Тип("Структура") Тогда
			Возврат Новый ФиксированнаяСтруктура(Коллекция);
		Иначе
			Возврат Новый ФиксированноеСоответствие(Коллекция);
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат Данные;
	
	// BSLLS:TooManyReturns-on
	// BSLLS:CognitiveComplexity-on
	// BSLLS:CyclomaticComplexity-on
	// BSLLS:IfElseIfEndsWithElse-on
	// BSLLS:IfConditionComplexity-on
	// BSLLS:DuplicateStringLiteral-on
	
КонецФункции // ФиксированныеДанные

// Дополняет структуру приемник из источника
//
// Параметры:
//  Приемник - Структура
//  Источник - Структура
//
Процедура ДополнитьСтруктуру(Приемник, Источник)
	
	Для Каждого КлючИЗначение Из Источник Цикл
		Приемник.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
	КонецЦикла;
	
КонецПроцедуры

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

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

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

// Добавляет в дерево подразделений строку с данными головного подразделения
//
// Параметры:
//	Дерево						- ДеревоЗначений 	- заполняемое дерево
// ДанныеГоловногоПодразделения	- Структура 		- данные добавляемого подразделения
Процедура ДобавитьГоловноеПодразделение(Дерево, ДанныеГоловногоПодразделения) Экспорт
	
	НоваяСтрока = Дерево.Строки.Добавить();
	
	ЗаполнитьЗначенияСвойств(НоваяСтрока, ДанныеГоловногоПодразделения);
		
	НоваяСтрока.Наименование = "Головное подразделение";
	НоваяСтрока.ПредставлениеИннКпп = ПредставлениеИннКппДляЭлементаСправочника(НоваяСтрока.ИНН, НоваяСтрока.КПП);
				
КонецПроцедуры

Процедура ЗаполнитьПредставлениеСвязейВДеревеПодразделений(
		СтрокиДереваПодразделений,
		ИмяСправочника,
		ID_ГоловногоПодразделения) Экспорт
	
	ИменаСправочниковДиадок = Перечисление_ИменаСправочников_Диадок();
	ДляОрганизации = (ИмяСправочника = ИменаСправочниковДиадок.Организации);
	
	Если ДляОрганизации Тогда
		ПредставлениеДля = ИменаСправочниковДиадок.ПодразделенияОрганизаций;
	Иначе
		ПредставлениеДля = ИменаСправочниковДиадок.ПодразделенияКонтрагентов;
	КонецЕсли;
	
	Для Каждого СтрокаДерева Из СтрокиДереваПодразделений Цикл
		
		Идентификаторы = Модуль_Ядро().Новый_ИдентификаторыСправочника( , СтрокаДерева.ID);
		СопоставленныеПодразделения = Модуль_Ядро().Подразделения_СопоставленныеВ1С(Идентификаторы, ДляОрганизации);
		
		ЭтоГоловноеПодразделение = (СтрокаДерева.ID = ID_ГоловногоПодразделения);
		
		Если НЕ ЭтоГоловноеПодразделение Тогда
			СтрокаДерева.ПредставлениеСвязи = ПредставлениеСвязейВСписке(СопоставленныеПодразделения, ПредставлениеДля);
		КонецЕсли;
		
		Если СтрокаДерева.Строки.Количество() > 0 Тогда
			ЗаполнитьПредставлениеСвязейВДеревеПодразделений(СтрокаДерева.Строки, ИмяСправочника, ID_ГоловногоПодразделения);
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

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

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

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

Функция ПредставлениеИннКпп_Отсутствует() Экспорт
	
	Результат = "Отсутствует";
	
	Возврат Результат;
	
КонецФункции

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

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

Функция Перечисление_ИменаСправочников_Диадок()
	
	Результат = Модуль_Ядро().Перечисление_ИменаСправочников_Диадок();
	
	Возврат Результат;
	
КонецФункции

//}		ОБЩЕГО НАЗНАЧЕНИЯ


//{		КЭШИРОВАНИЕ

Функция Кэш_Прочитать(ИмяЗначения)
	
	Результат = Неопределено;
	
	Если Кэш <> Неопределено Тогда
		Результат = Кэш.Получить(ИмяЗначения);
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Процедура Кэш_Поместить(ИмяЗначения, Значение)
	
	Если Кэш = Неопределено Тогда
		Кэш = Новый Соответствие;
	КонецЕсли;
	
	Кэш.Вставить(ИмяЗначения, Значение);
	
КонецПроцедуры

Процедура Кэш_Очистить() Экспорт
    
    Если Кэш <> Неопределено Тогда
        Кэш.Очистить();
    КонецЕсли;
    
КонецПроцедуры

//}		КЭШИРОВАНИЕ


//{		МЕТОДЫ ДЛЯ ФОРМ

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

Функция КлючНастроекПериода()
	
	Возврат "НастройкиПериода";
	
КонецФункции

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

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

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

// Возвращает текст истории версий модуля из макета CHANGELOG_md
Функция ИсторияОбновлений() Экспорт
	
	Результат = "";
	
	Макет = ПолучитьМакет("CHANGELOG_md");
	Результат = Макет.ПолучитьТекст();
	
	Возврат Результат;
	
КонецФункции

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

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

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

Функция КолонкиРежимаИсходящих()
	
	Результат =
	"
	|ОписаниеТипаДокумента
	|КартинкаПакета
	|ВидПакета
	|ВидЭлДокумента
	|НомерДокумента
	|ДатаДокумента
	|СуммаДокумента
	|Статус
	|ДополнительныйСтатус
	|СтатусМЧД
	|СтатусПКФНС
	|ВнешнийСтатус
	|СтатусТЭДО
	|ДатаОтправки
	|ПредставлениеДокументаДиадок
	|Метка
	|Пакет
	|ДокументЭДО
	|ЗаблокированныйПакет
	|BoxId
	|LetterId
	|DocumentId
	|ОбъектМаршрутизации";
	
	Возврат Результат;
	
КонецФункции

Функция КолонкиРежимаВходящих()
	
	ОтключитьАнализ = Модуль_Ядро().ОбщиеНастройки_Прочитать("ОтключитьАнализДляВходящихДокументов");

	Результат =
	"
	|ОписаниеТипаДокумента
	|КартинкаПакета
	|НомерДокумента
	|ДатаДокумента
	|СуммаДокумента
	|Статус
	|СтатусМЧД
	|СтатусПКФНС
	|ДополнительныйСтатус
	|ВнешнийСтатус
	|СтатусТЭДО
	|ДатаПолучения
	|ПредставлениеДокументаДиадок
	|Пакет
	|ДокументЭДО
	|ЗаблокированныйПакет
	|BoxId
	|LetterId
	|DocumentId
	|ОбъектМаршрутизации";
	
	Если НЕ ОтключитьАнализ
		И ОбщийКонтекстКлиентСервер.ИспользуетсяПодсистемаДиадок Тогда
		
		Результат = Результат + 	
		"
		|ТребуемоеДействие
		|АнализПроведен
		|ОшибкиПроверкиТекст";
		
	КонецЕсли;
	
	Если ОбщийКонтекстКлиентСервер.ИспользуетсяПодсистемаДиадок Тогда
		
		Результат = Результат + 	
		"
		|ТребуетсяРасшифровка
		|ДействиеВДД
		|ДействиеВ1С";
		
	КонецЕсли;
		
	Возврат Результат;
	
КонецФункции

Функция КолонкиРежимаВнутренние()
	
	Результат =
	"
	|Документ
	|Организация
	|Подразделение
	|ОписаниеТипаДокумента
	|КартинкаПакета
	|ВидПакета
	|ВидЭлДокумента
	|НомерДокумента
	|ДатаДокумента
	|СуммаДокумента
	|Статус
	|ДополнительныйСтатус
	|СтатусМЧД
	|СтатусПКФНС
	|ВнешнийСтатус
	|ДатаОтправки
	|ПредставлениеДокументаДиадок
	|Метка
	|Пакет
	|ДокументЭДО
	|ЗаблокированныйПакет
	|BoxId
	|LetterId
	|DocumentId
	|ОбъектМаршрутизации
	|ПодразделениеОтправитель
	|ПодразделениеПолучатель";
		
	Возврат Результат;
	
КонецФункции

Функция КолонкиРежимаПеревозочные()
	
	Результат =
	"
	|Документ
	|СодержимоеПакета
	|Статус
	|ДополнительныйСтатус
	|СтатусМЧД
	|ВнешнийСтатусЭПД
	|НомерДокумента
	|ДатаДокумента
	|СуммаДокумента
	|ДатаОтправки
	|Грузоотправитель
	|Перевозчик
	|Грузополучатель";
	
	Возврат Результат;
	
КонецФункции

Функция МассивНеизменныхКолонок() Экспорт
	
	Результат = Новый Массив;

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

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

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

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

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

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

Процедура УдалитьДополнительныеКнопкиУправляемаяФорма(Форма, Родитель)
	
	ПодчиненныеЭлементы = Родитель.ПодчиненныеЭлементы;
	
	КоличествоИндексовЭлементов = ПодчиненныеЭлементы.Количество() - 1;
	
	Для Счетчик = 0 По КоличествоИндексовЭлементов Цикл
		Кнопка = ПодчиненныеЭлементы[КоличествоИндексовЭлементов - Счетчик];
		
		Если Найти(Кнопка.Имя, "ДополнительнаяКнопка_") > 0 Тогда
			Форма.Элементы.Удалить(Кнопка);
		КонецЕсли;
		
	КонецЦикла;	
	
КонецПроцедуры

Функция ВозможенЗапускВВебКлиенте() Экспорт 
	
	// запуск в веб клиенте возможен на платформе не ниже 8.3.3.721
	// из-за появления свойства РежимИспользованияМодальности и необходимых методов для отказа от оператора Выполнить
	// http://its.1c.ru/docs/v8nonmodal/
	
	СистемнаяИнформация = Новый СистемнаяИнформация;
	
	Результат = (СравнитьВерсии(СистемнаяИнформация.ВерсияПриложения, "8.3.3.721") >= 0);
	
	Возврат Результат;
	
КонецФункции

Функция СформироватьИнформациюОПакете(Пакет) Экспорт
	
	Результат = Новый ТабличныйДокумент;
	
	Область = Результат.ПолучитьОбласть("R1");
	Область.Область("R1C1").Текст = ("Информация о пакете");
	Результат.Вывести(Область);
	
	К = 1;
	
	Результат.НачатьГруппуСтрок("Информация пакете", Ложь);
	
	Для Каждого ЭлементПакета Из Пакет Цикл
		
		Если ТипЗнч(ЭлементПакета.Значение) = Тип("Массив") Тогда
			
			Для Каждого Элемент Из ЭлементПакета.Значение Цикл
				
				Если ТипЗнч(Элемент) <> Тип("Структура") Тогда
					
					Результат.Область("R" + XMLСтрока(К + 1) + "C1").Текст = Элемент.Ключ;
					Результат.Область("R" + XMLСтрока(К + 1) + "C2").Текст = Элемент.Значение;
					
					К = К + 1;
					
				Иначе
					
					Результат.Область("R" + XMLСтрока(К + 1) + "C1").Текст = Элемент.ДокументУчета;
					
					К = К + 1;
					
					Результат.НачатьГруппуСтрок(Элемент, Ложь);
					
					Для Каждого ЭлементСтруктуры Из Элемент Цикл
						
						Если ТипЗнч(ЭлементСтруктуры.Значение) <> Тип("Структура")
							И ТипЗнч(ЭлементСтруктуры.Значение) <> Тип("Массив") Тогда
							
							Результат.Область("R" + XMLСтрока(К + 1) + "C2").Текст = ЭлементСтруктуры.Ключ;
							Результат.Область("R" + XMLСтрока(К + 1) + "C3").Текст = ЭлементСтруктуры.Значение;
							
							К = К + 1;
							
						Иначе
							
							Результат.Область("R" + XMLСтрока(К + 1) + "C2").Текст = ЭлементСтруктуры.Ключ;
							
							К = К + 1;
							
							Результат.НачатьГруппуСтрок(Элемент.Ключ, Ложь);
							
							Для Каждого ЭлементМассива Из ЭлементСтруктуры.Значение Цикл
								
								Результат.Область("R" + XMLСтрока(К + 1) + "C3").Текст = ЭлементМассива.Ключ;
								Результат.Область("R" + XMLСтрока(К + 1) + "C4").Текст = ЭлементМассива.Значение;
								
								К = К + 1;
								
							КонецЦикла;
							
							Результат.ЗакончитьГруппуСтрок();
							
						КонецЕсли;
						
					КонецЦикла;
					
					Результат.ЗакончитьГруппуСтрок();
					
				КонецЕсли;
				
			КонецЦикла;
			
		Иначе
			
			
			Если ТипЗнч(ЭлементПакета.Значение) <> Тип("Структура") Тогда
				
				Результат.Область("R" + XMLСтрока(К + 1) + "C1").Текст = ЭлементПакета.Ключ;
				Результат.Область("R" + XMLСтрока(К + 1) + "C2").Текст = ЭлементПакета.Значение;
				
				К = К + 1;
				
			Иначе
				
				Результат.Область("R" + XMLСтрока(К + 1) + "C1").Текст = ЭлементПакета.Ключ;
				
				К = К + 1;
				
				Результат.НачатьГруппуСтрок(ЭлементПакета.Ключ, Ложь);
				
				Для Каждого ЭлементСтруктуры Из ЭлементПакета.Значение Цикл
					
					Если ТипЗнч(ЭлементСтруктуры.Значение) <> Тип("Структура")
						И ТипЗнч(ЭлементСтруктуры.Значение) <> Тип("Массив") Тогда
						
						Результат.Область("R" + XMLСтрока(К + 1) + "C2").Текст = ЭлементСтруктуры.Ключ;
						Результат.Область("R" + XMLСтрока(К + 1) + "C3").Текст = ЭлементСтруктуры.Значение;
						
						К = К + 1;
						
					Иначе
						
						Результат.Область("R" + XMLСтрока(К + 1) + "C2").Текст = ЭлементСтруктуры.Ключ;
						
						К = К + 1;
						
						Результат.НачатьГруппуСтрок(ЭлементПакета.Ключ, Ложь);
						
						Для Каждого ЭлементМассива Из ЭлементСтруктуры.Значение Цикл
							
							Если ТипЗнч(ЭлементМассива.Значение) <> Тип("Структура") Тогда
								
								Результат.Область("R" + XMLСтрока(К + 1) + "C3").Текст = ЭлементМассива.Ключ;
								Результат.Область("R" + XMLСтрока(К + 1) + "C4").Текст = ЭлементМассива.Значение;
								
								К = К + 1;
								
							Иначе
								
								Результат.Область("R" + XMLСтрока(К + 1) + "C3").Текст = ЭлементМассива.Ключ;
								
								К = К + 1;
								
								Результат.НачатьГруппуСтрок(ЭлементМассива.Ключ, Ложь);
								
								Для Каждого ЭлементВложеннойСтруктуры Из ЭлементМассива.Значение Цикл
									
									Результат.Область("R" + XMLСтрока(К + 1) + "C4").Текст = ЭлементВложеннойСтруктуры.Ключ;
									Результат.Область("R" + XMLСтрока(К + 1) + "C5").Текст = ЭлементВложеннойСтруктуры.Значение;
									
									К = К + 1;
									
								КонецЦикла;
								
								Результат.ЗакончитьГруппуСтрок();
								
							КонецЕсли;
							
						КонецЦикла;
						
						Результат.ЗакончитьГруппуСтрок();
						
					КонецЕсли;
					
				КонецЦикла;
				
				Результат.ЗакончитьГруппуСтрок();
				
			КонецЕсли;
			
			
		КонецЕсли;
		
	КонецЦикла;
	
	Для Кол = 1 По Результат.ШиринаТаблицы Цикл
		ШиринаКолонки = 0;
		Для Стр = 1 По Результат.ВысотаТаблицы Цикл
			Область = Результат.Область("R" + XMLСтрока(Стр) + "C" + XMLСтрока(Кол));
			ШиринаОбласти = Область.Отступ + СтрДлина(СокрЛП(Область.Текст));
			ШиринаКолонки = Макс(ШиринаКолонки, ШиринаОбласти + 3);
			Если ШиринаКолонки > 40 Тогда
				Область.ШиринаКолонки = 40;
			Иначе
				Область.ШиринаКолонки = ШиринаКолонки;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
	Результат.ЗакончитьГруппуСтрок();
	
	Возврат Результат;
	
КонецФункции

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

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

Функция ОписаниеТипаПоляОрганизации() Экспорт
	
	ПустаяОрганизация = Модуль_Ядро().ХранениеДанных_ПустаяСсылкаОрганизации();
	
	МассивТипов = Новый Массив;
	МассивТипов.Добавить(ТипЗнч(ПустаяОрганизация));
	
	Результат = Новый ОписаниеТипов(МассивТипов);
	
	Возврат Результат;
	
КонецФункции

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

Функция ПредставлениеСвязейПоУмолчанию() Экспорт
	
	Результат = НСтр("ru='Не выбран'");
	
	Возврат Результат;
	
КонецФункции

Функция ПредставлениеСвязейВСпискеОрганизацииКонтрагенты(СвязанныеСправочники)
	
	Результат = "";
	
	КоличествоСвязанных = СвязанныеСправочники.Количество();
	
	Если КоличествоСвязанных > 1 Тогда
		
		ШаблонПредставления = НСтр("ru='Сопоставлено: %1'");
		
		Ядро = Модуль_Ядро();
		Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
			ШаблонПредставления,
			КоличествоСвязанных
		);
		
	ИначеЕсли КоличествоСвязанных = 1 Тогда
		
		Результат = СвязанныеСправочники[0].Наименование;
		
	Иначе
		
		Результат = ПредставлениеСвязейПоУмолчанию();
		
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ПредставлениеСвязейВСпискеПодразделения(СвязанныеСправочники)
	
	Результат = СвязанныеСправочники.Количество();
	
	Возврат Результат;
	
КонецФункции

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

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

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

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

// Сохраняет настройку пользователя отображения онбординга для формы "Подписки и оплаты"
//
// Параметры:
//  ЗначениеНастройки - Булево - значение настройки 
//
Процедура НастройкиПользователяУстановить_НеПоказыватьПодпискиИОплатаОнбординг(ЗначениеНастройки) Экспорт
	
	КлючНастройки = КлючНастройки_НеПоказыватьПодпискиИОплатаОнбординг();
	
	ХранилищеОбщихНастроек_Сохранить(КлючНастройки, ЗначениеНастройки);
	
КонецПроцедуры

Функция КлючНастройки_НеПоказыватьПодпискиИОплатаОнбординг()

	Результат = "НеПоказыватьПодпискиИОплатаОнбординг";
	
	Возврат Результат;
	
КонецФункции

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

// Сохраняет настройку пользователя отображения онбординга для формы "События ленты контрагентов"
//
// Параметры:
//  ЗначениеНастройки - Булево - значение настройки
//
Процедура НастройкиПользователяУстановить_НеПоказыватьОнбордингЛентыКонтрагентов(ЗначениеНастройки) Экспорт
	
	КлючНастройки = КлючНастройки_НеПоказыватьСобытияЛентыКонтрагентов();
	
	ХранилищеОбщихНастроек_Сохранить(КлючНастройки, ЗначениеНастройки);
	
КонецПроцедуры

Функция КлючНастройки_НеПоказыватьСобытияЛентыКонтрагентов()
	
	Результат = "НеПоказыватьСобытияЛентыКонтрагентов";
	
	Возврат Результат;
	
КонецФункции



Процедура ПоместитьВКэшДобавленныеВВыбранныеВПакетыДокументыСДискаИОбновитьСписок(ДокументыСДиска, КлючиВыбранныхПакетов, СписокДокументов) Экспорт
	
	Модуль_Ядро = Модуль_Ядро();
	Модуль_Ядро.Пакеты_ДокументыСДискаПоместитьВКэш(ДокументыСДиска, КлючиВыбранныхПакетов);
	
	СписокДокументов_ОбновитьДокументыВыделенныхПакетов(СписокДокументов, КлючиВыбранныхПакетов);
	
КонецПроцедуры

//}		МЕТОДЫ ДЛЯ ФОРМ


//{		ОБНОВЛЕНИЕ МОДУЛЯ

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

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

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

Функция ОписаниеРасположенияМодуляВСправочнике(Местоположение)

	Результат = Неопределено;
	
	СсылкаНаМодуль = Модуль_Ядро().ОбновленияМодуля_ПодходящаяВнешняяОбработка(ВерсияОбработки());

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

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

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

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

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

//}		ОБНОВЛЕНИЕ МОДУЛЯ


//{		АВТООБНОВЛЕНИЕ МОДУЛЯ

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

Функция ОписаниеИзмененийТекущейВерсииМодуля() Экспорт
	
	СимволРазделителя = "## ";
	ДлинаРазделителя = СтрДлина(СимволРазделителя);
	
	ТекстИстории = ИсторияОбновлений();
	
	НачалоТекущейВерсии = Найти(ТекстИстории, СимволРазделителя) + ДлинаРазделителя;
	ОбрезаннаяИстория = Сред(ТекстИстории, НачалоТекущейВерсии);
	КонецТекущейВерсии = Найти(ОбрезаннаяИстория, СимволРазделителя);
	
	КоличествоСимволов = КонецТекущейВерсии - 1;
	
	ТекстИзменения = Сред(ТекстИстории, НачалоТекущейВерсии, КоличествоСимволов);
	
	Результат = СокрЛП(ТекстИзменения);
	
	Возврат Результат;
	
КонецФункции

Функция ОписаниеИзмененийТекущейВерсииМодуляHTML() Экспорт
	
	Ядро = Модуль_Ядро();
	
	ШаблонHTML = "<!DOCTYPE HTML>
				|<html>
				|    <head>
				|        <meta charset=""utf-8"">
				|        <style type=text/css>
				|            div {
				|               white-space: pre-wrap; font-size: 85%; 
				|            }
				|        </style>
				|    </head>
				|    <body><div>%1</div></body>
				|</html>";
	
	ОписаниеИзменений = ОписаниеИзмененийТекущейВерсииМодуля();
	ОписаниеИзменений = СтрЗаменить(ОписаниеИзменений, " " + Символы.ПС, "<br>");
	ОписаниеИзменений = СтрЗаменить(ОписаниеИзменений, Символы.ПС, "<br>");
	
	Результат  = Ядро.Общее_ПодставитьПараметрыВСтроку(ШаблонHTML,
			ОписаниеИзменений
		);
	
	Возврат Результат;
	
КонецФункции

// Возвращает описание обновлений модуля в виде кода HTML-страницы
// 
// Возвращаемое значение:
//  Строка - Код HTML-страницы
//
Функция ОписаниеИзмененийНовойВерсииМодуляHTML() Экспорт
	
	Ядро = Модуль_Ядро();
	
	Попытка
		
		ОписаниеОбновлений = Ядро.ОбновленияМодуля_ОписаниеОбновлений(ВерсияОбработки());
		
	Исключение
		
		ТелоПодменнойИнформации = "<A href=""https://support.kontur.ru/1s/41562-informaciya_ob_obnovleniyax_modulya_diadok_pro"">Информация об обновлениях модуля Диадок для 1С</A>";
		
		ОписаниеОбновлений = Новый Массив;
		ОписаниеОбновлений.Добавить(ТелоПодменнойИнформации);
		
	КонецПопытки;
	
	ШаблонНачало =
		"<HTML>
		|	<HEAD>
		|		<style type=text/css>
		|			body {font-family: Segoe UI}
		|		</style>
		|	</HEAD>
		|	<BODY scroll=auto>
		|";
	
	ШаблонПреамбулаОписания =
		"<H3>Информация об обновлениях модуля Диадок для 1С (Скачать обновление)</H3>";
	
	ШаблонОкончание =
		"		<BR>
		|	</BODY>
		|</HTML>";
	
	ЭлементыДокументаHTML = Новый Массив;
	ЭлементыДокументаHTML.Добавить(ШаблонНачало);
	ЭлементыДокументаHTML.Добавить(ШаблонПреамбулаОписания);
	
	Для Каждого ЭлементДанных Из ОписаниеОбновлений Цикл
		
		ЭлементыДокументаHTML.Добавить(ЭлементДанных);
		ЭлементыДокументаHTML.Добавить("<P>");
		
	КонецЦикла;
	
	ЭлементыДокументаHTML.Добавить(ШаблонОкончание);
	
	Результат = Ядро.СоединитьСтроку(ЭлементыДокументаHTML, Символы.ПС);
	
	Возврат Результат;
	
КонецФункции

//}		АВТООБНОВЛЕНИЕ МОДУЛЯ


//{		ЯДРО

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

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

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

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

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

Функция ИмяРасширенияКонфигурацииКонтурДиадок() Экспорт

	Возврат "КонтурДиадок";
	
КонецФункции

Процедура СинхронизироватьОбщийКонтекст(Ядро)
	
	Если ЗначениеЗаполнено(ОбщийКонтекстКлиентСервер) Тогда
		Ядро.УстановитьОбщийКонтекст(ОбщийКонтекстКлиентСервер);
	КонецЕсли;
	
КонецПроцедуры

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

//}		ЯДРО


//{ 	Подключение библиотеки

// Список зависимостей в порядке их подключения.
//
// Возвращаемое значение:
//  ФиксированныйМассив из Контракт_Зависимость
//
Функция Зависимости() Экспорт
	
	МакетыОбработки = Метаданные().Макеты;
	
	// BSLLS:LineLength-off
	// BSLLS:LatinAndCyrillicSymbolInWord-off
	МодульСтд = Новый_Зависимость("Стд", МакетыОбработки.КонтурДиадокСтд.Имя);
	МодульСтдДиалоги = Новый_Зависимость("СтдДиалоги", МакетыОбработки.КонтурДиадокСтдДиалоги.Имя);
	МодульСтдФС = Новый_Зависимость("СтдФС", МакетыОбработки.КонтурДиадокСтдФС.Имя);
	МодульСтдОС = Новый_Зависимость("СтдОС", МакетыОбработки.КонтурДиадокСтдОС.Имя);
	МодульСтдJSON = Новый_Зависимость("СтдJSON", МакетыОбработки.КонтурДиадокСтдJSON.Имя);
	МодульСтдОбщегоНазначения = Новый_Зависимость("СтдОбщегоНазначения", МакетыОбработки.КонтурДиадокСтдОбщегоНазначения.Имя);
	МодульСтдСтр = Новый_Зависимость("СтдСтр", МакетыОбработки.КонтурДиадокСтдСтр.Имя);
	МодульСтдКоллекции = Новый_Зависимость("СтдКоллекции", МакетыОбработки.КонтурДиадокСтдКоллекции.Имя);
	МодульСтдСтрСлужебный83 = Новый_Зависимость("СтдСтрСлужебный83", МакетыОбработки.КонтурДиадокСтдСтрСлужебный83.Имя);
	МодульСтдСтрСлужебный83.ВызыватьИсключение = Ложь;
	
	МодульКоннекторHTTP = Новый_Зависимость("КоннекторHTTP", МакетыОбработки.КонтурДиадокКоннекторHTTP.Имя);
	МодульКоннекторHTTPСлужебный83 = Новый_Зависимость("КоннекторHTTPСлужебный83", МакетыОбработки.КонтурДиадокКоннекторHTTPСлужебный83.Имя);
	МодульКоннекторHTTPСлужебный83.ВызыватьИсключение = Ложь;
	МодульКоннекторHTTPСлужебный8310 = Новый_Зависимость("КоннекторHTTPСлужебный8310", МакетыОбработки.КонтурДиадокКоннекторHTTPСлужебный8310.Имя);
	МодульКоннекторHTTPСлужебный8310.ВызыватьИсключение = Ложь;
	МодульКоннекторHTTPДвоичныеДанные82Служебный = Новый_Зависимость("КоннекторHTTPДвоичныеДанные82Служебный", МакетыОбработки.КонтурДиадокКоннекторHTTPДвоичныеДанные82Служебный.Имя);
	МодульКоннекторHTTPДвоичныеДанные82Служебный.ВызыватьИсключение = Ложь;
	МодульКоннекторHTTPХешMD5 = Новый_Зависимость("КоннекторHTTPХешMD5", МакетыОбработки.КонтурДиадокКоннекторHTTPХешMD5.Имя);
	
	МодульМетрики = Новый_Зависимость("Метрики", МакетыОбработки.КонтурДиадокМетрики.Имя);
	МодульАпдейтКлиент = Новый_Зависимость("АпдейтКлиент", МакетыОбработки.КонтурДиадокАпдейтКлиент.Имя);
	МодульШлюзАвторизации = Новый_Зависимость("ШлюзАвторизации", МакетыОбработки.КонтурДиадокШлюзАвторизации.Имя);
	МодульМенеджерКриптографии = Новый_Зависимость("МенеджерКриптографии", МакетыОбработки.КонтурДиадокМенеджерКриптографии.Имя);
	
	МодульЯдро = Новый_Зависимость("Ядро", МакетыОбработки.КонтурДиадокЯдро.Имя);
	МодульВнешниеСервисы = Новый_Зависимость("ВнешниеСервисы", МакетыОбработки.КонтурДиадокВнешниеСервисы.Имя);
	МодульВызовыПМ = Новый_Зависимость("ВызовыПМ", МакетыОбработки.КонтурДиадокВызовыПМ.Имя);
	МодульГенерацияXML = Новый_Зависимость("ГенерацияXML", МакетыОбработки.КонтурДиадокГенерацияXML.Имя);
	МодульМетодыAPI = Новый_Зависимость("МетодыAPI", МакетыОбработки.КонтурДиадокМетодыAPI.Имя);
	МодульПарсерJSON = Новый_Зависимость("ПарсерJSON", МакетыОбработки.КонтурДиадокПарсерJSON.Имя);
	МодульПечатныеФормы = Новый_Зависимость("ПечатныеФормы", МакетыОбработки.КонтурДиадокПечатныеФормы.Имя);
	МодульХранениеДанных = Новый_Зависимость("ХранениеДанных", МакетыОбработки.КонтурДиадокХранениеДанных.Имя);
	МодульПлагин1С = Новый_Зависимость("Плагин1С", МакетыОбработки.КонтурДиадокПлагин1С.Имя);
	МодульЭмуляторТабДокумента = Новый_Зависимость("ЭмуляторТабДокумента", МакетыОбработки.КонтурДиадокЭмуляторТабДокумента.Имя);
	МодульОнлайнСчета = Новый_Зависимость("ОнлайнСчета", МакетыОбработки.КонтурДиадокОнлайнСчета.Имя);
	МодульПлагины = Новый_Зависимость("Плагины", МакетыОбработки.КонтурДиадокПлагины.Имя);
	МодульЦентрПоддержки = Новый_Зависимость("ЦентрПоддержки", МакетыОбработки.КонтурДиадокЦентрПоддержки.Имя);
	МодульРаботаСМаркировкой = Новый_Зависимость("РаботаСМаркировкой", МакетыОбработки.КонтурДиадокРаботаСМаркировкой.Имя);
	МодульРаботаСЛогистикой = Новый_Зависимость("РаботаСЛогистикой", МакетыОбработки.КонтурДиадокРаботаСЛогистикой.Имя);
	МодульРаботаСЛогистикой.ВызыватьИсключение = Ложь;
	
	МодульАутентификатор = Новый_Зависимость("Аутентификатор", МакетыОбработки.КонтурДиадокАутентификатор.Имя);
	МодульАутентификаторХранилище = Новый_Зависимость("АутентификаторХранилище", МакетыОбработки.КонтурДиадокАутентификаторХранилище.Имя);
	
	МодульМенеджерПлагинов = Новый_Зависимость("МенеджерПлагинов", МакетыОбработки.КонтурДиадокМенеджерПлагинов.Имя);
	МодульМенеджерПлагиновХранилище = Новый_Зависимость("МенеджерПлагиновХранилище", МакетыОбработки.КонтурДиадокМенеджерПлагиновХранилище.Имя);
	МодульМенеджерПлагиновХранилище.ВызыватьИсключение = Ложь;
	
	МодульДлительныеОперации = Новый_Зависимость("ДлительныеОперации", МакетыОбработки.КонтурДиадокДлительныеОперации.Имя);
	
	МодульЧерновикиПакетов = Новый_Зависимость("ЧерновикиПакетов", МакетыОбработки.КонтурДиадокЧерновикиПакетов.Имя);
	МодульЧерновикиПакетовСлужебныйБП30 = Новый_Зависимость("ЧерновикиПакетовСлужебныйБП30", МакетыОбработки.КонтурДиадокЧерновикиПакетовСлужебныйБП30.Имя);
	МодульЧерновикиПакетовСлужебныйБП30.ВызыватьИсключение = Ложь;
	
	МодульМенеджерПлагиновХранилищеСХ1 = Новый_Зависимость("ХранилищеПлагиновСХ1", МакетыОбработки.КонтурДиадокХранилищеПлагиновСХ1.Имя);
	МодульМенеджерПлагиновХранилищеСХ1.ВызыватьИсключение = Ложь;
	
	МодульПеревозочныеДокументы = Новый_Зависимость("ПеревозочныеДокументы", МакетыОбработки.КонтурДиадокПеревозочныеДокументы.Имя);
	
	МодульНастройкиАвторизации = Новый_Зависимость("МодульНастройкиАвторизации", МакетыОбработки.КонтурДиадокМодульНастройкиАвторизации.Имя);
	
	Список = Новый Массив;
	Список.Добавить(МодульСтд);
	Список.Добавить(МодульСтдДиалоги);
	Список.Добавить(МодульСтдСтрСлужебный83);
	Список.Добавить(МодульСтдСтр);
	Список.Добавить(МодульСтдОС);
	Список.Добавить(МодульСтдФС);
	Список.Добавить(МодульСтдJSON);
	Список.Добавить(МодульСтдОбщегоНазначения);
	Список.Добавить(МодульСтдКоллекции);
	
	Список.Добавить(МодульКоннекторHTTPСлужебный83);
	Список.Добавить(МодульКоннекторHTTPСлужебный8310);
	Список.Добавить(МодульКоннекторHTTPДвоичныеДанные82Служебный);
	Список.Добавить(МодульКоннекторHTTPХешMD5);
	Список.Добавить(МодульКоннекторHTTP);
	
	Список.Добавить(МодульМетрики);
	Список.Добавить(МодульМенеджерКриптографии);
	
	Список.Добавить(МодульАпдейтКлиент);
	Список.Добавить(МодульШлюзАвторизации);
	
	Список.Добавить(МодульЯдро);
	Список.Добавить(МодульВнешниеСервисы);
	Список.Добавить(МодульВызовыПМ);
	Список.Добавить(МодульГенерацияXML);
	Список.Добавить(МодульМетодыAPI);
	Список.Добавить(МодульПарсерJSON);
	Список.Добавить(МодульПечатныеФормы);
	Список.Добавить(МодульХранениеДанных);
	Список.Добавить(МодульПлагин1С);
	Список.Добавить(МодульЭмуляторТабДокумента);
	Список.Добавить(МодульОнлайнСчета);
	Список.Добавить(МодульПлагины);
	Список.Добавить(МодульЦентрПоддержки);
	Список.Добавить(МодульРаботаСМаркировкой);
	Список.Добавить(МодульРаботаСЛогистикой);
	
	Список.Добавить(МодульАутентификатор);
	Список.Добавить(МодульАутентификаторХранилище);
	
	Список.Добавить(МодульМенеджерПлагинов);
	Список.Добавить(МодульМенеджерПлагиновХранилище);
	
	Список.Добавить(МодульДлительныеОперации);
	
	Список.Добавить(МодульЧерновикиПакетов);
	Список.Добавить(МодульЧерновикиПакетовСлужебныйБП30);
	Список.Добавить(МодульМенеджерПлагиновХранилищеСХ1);
	
	Список.Добавить(МодульНастройкиАвторизации);
	
	Список.Добавить(МодульПеревозочныеДокументы);
	// BSLLS:LineLength-on
	// BSLLS:LatinAndCyrillicSymbolInWord-on
	
	Результат = ФиксированныеДанные(Список);
	
	Возврат Результат;
	
КонецФункции 

// Зависимости

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

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

Функция КлючВерсииМетаданныхСеанса()
	
	Результат = "MdoVersions";
	
	Возврат Результат;
	
КонецФункции

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

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

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

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

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

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

Функция ПодключитьЗависимость(МетаданныеМодуля, Зависимость, Переподключать = Ложь)
	
	ТипОбъекта = Зависимость.Тип + "." + Зависимость.Имя;
	Если ТипОпределен(ТипОбъекта) И Переподключать = Ложь Тогда
		Возврат ТипОбъекта;
	КонецЕсли;
	
	Если Найти(Зависимость.Источник, "template://") Тогда
		Макет = ЭтотОбъект.ПолучитьМакет(СтрЗаменить(Зависимость.Источник, "template://", ""));
		Если ЭтоОбычноеПриложение() Тогда
			// BSLLS:MissingTemporaryFileDeletion-off
			Источник = ПолучитьИмяВременногоФайла(".epf");
			// BSLLS:MissingTemporaryFileDeletion-on
			Макет.Записать(Источник);
		Иначе
			Источник = Макет;
		КонецЕсли;
	ИначеЕсли Найти(Зависимость.Источник, "file://") Тогда
		Источник = СтрЗаменить(Зависимость.Источник, "file://", "");
		Если НЕ ФайлСуществует(Источник) Тогда
			ДанныеМакета = ПолучитьМакет(Зависимость.Имя);
			ДанныеМакета.Записать(Источник);
		КонецЕсли;
	Иначе
		ВызватьИсключение "Ошибка значения: схема не зарегистрирована " + Строка(Зависимость.Источник);
	КонецЕсли;
	
	Режим = РежимПодключенияЗависимости();
	
	Если ЭтоОбычноеПриложение()
		ИЛИ Найти(Зависимость.Источник, "file://") Тогда
		
		Попытка
			Тип = ПодключитьОбработкуИзФайла(МетаданныеМодуля, Источник, Режим);
		Исключение
			
			Если Зависимость.ВызыватьИсключение Тогда
				ВызватьИсключение;
			КонецЕсли;
			
			Ошибка = ИнформацияОбОшибке();
			// Ошибки подключения ОФ игнорируются из-за невозможности создать объект безопасно
			Тип = ТипОбъекта;
			
		КонецПопытки;
		
	Иначе
		
		Адрес = ПоместитьВоВременноеХранилище(Источник);
		Тип = ПодключитьОбработку(Адрес, Зависимость.Имя, Режим);
		УдалитьИзВременногоХранилища(Адрес);
		
	КонецЕсли;
	
	Возврат Тип;
	
КонецФункции

// Создает экземпляр внешней обработки и регистрирует его в списке подключенных метаданных
//
// Параметры:
//  МетаданныеМодуля - Структура - см. Контракт_ОписаниеЗависимостей.Метаданные
//  Путь - Строка - полное имя файла внешней обработки
//  Режим - Структура - см. РежимПодключенияЗависимости
// 
// Возвращаемое значение:
//  Строка - полное имя типа подключенной обработки
//
Функция ПодключитьОбработкуИзФайла(МетаданныеМодуля, Путь, Режим)
	
	Если Режим.УстановитьПривилегированныйРежим Тогда
		УстановитьПривилегированныйРежим(Истина); // BSLLS:SetPrivilegedMode-off
	КонецЕсли;
	
	Если Режим.ИспользоватьОписаниеЗащитыОтОпасныхДействий Тогда
		ЗащитаОтОпасныхДействий = ОписаниеЗащитыБезПредупреждений();
		
		// BSLLS:UsingExternalCodeTools-off
		Объект = ВнешниеОбработки.Создать(Путь, Режим.БезопасныйРежим, ЗащитаОтОпасныхДействий);
		// BSLLS:UsingExternalCodeTools-on
		
	Иначе
		
		// BSLLS:UsingExternalCodeTools-off
		Объект = ВнешниеОбработки.Создать(Путь, Режим.БезопасныйРежим);
		// BSLLS:UsingExternalCodeTools-on
		
	КонецЕсли;
	
	ИмяТипа = "ВнешняяОбработкаОбъект." + Объект.Метаданные().Имя;
	
	ДобавитьПодключенныеМетаданные(МетаданныеМодуля, ИмяТипа, Объект);
	
	Возврат ИмяТипа;
	
КонецФункции

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

// Описание зависимости
// 
// Возвращаемое значение:
//  Структура:
//    * Имя - Строка - Полное имя модуля с учетом пространства имён (например, "КонтурДиадокАпдейтКлиент")
//    * Тип - Строка - Тип модуля ("ВнешняяОбработкаОбъект" или "ОбработкаОбъект")
//    * Источник - Строка - адрес источника в формате "template://<Имя макета>" или "file://<Путь к файлу>"
//    * ВызыватьИсключение - Булево - Ложь, чтобы пропустить исключения при подключении зависимости
//
Функция Контракт_Зависимость()
	
	Результат = Новый Структура;
	Результат.Вставить("Имя", "");
	Результат.Вставить("Тип", "");
	Результат.Вставить("Источник", "");
	Результат.Вставить("ВызыватьИсключение", Истина);
	
	Возврат Результат;
	
КонецФункции

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

// Описание зависимостей модуля
// 
// Возвращаемое значение:
//  Структура - содержит ключи:
//    * Зависимости - Массив из Контракт_Зависимость - см. Зависимости()
//    * Метаданные - Структура - описание подключенных метаданных
//       ** ПодключенныеТипы - ФиксированноеСоответствие - ключ - это имя типа, значение - экземпляр обработки
//
Функция Контракт_ОписаниеЗависимостей()
	
	ПодключенныеТипы = Новый ФиксированноеСоответствие(Новый Соответствие);
	
	Результат = Новый Структура;
	Результат.Вставить("Зависимости", Зависимости());
	Результат.Вставить("Метаданные", Новый Структура("ПодключенныеТипы", ПодключенныеТипы));
	
	Возврат Результат;
	
КонецФункции

// Формирует настройки подключения внешних метаданных
// 
// Возвращаемое значение:
//  Структура - режим подключения внешних метаданных:
//    * БезопасныйРежим - Строка, Булево - см. метод БезопасныйРежим()
//    * УстановитьПривилегированныйРежим - Булево - Истина, чтобы подключать зависимости в привилегированном режиме
//    * ИспользоватьОписаниеЗащитыОтОпасныхДействий - Булево - Истина, если используется параметр ОписаниеЗащитыОтОпасныхДействий
//
Функция РежимПодключенияЗависимости()
	
	ВерсияПлатформы = ОписаниеСистемнойИнформации().ВерсияПриложения;
	ИспользоватьЗОД = (СравнитьВерсии(ВерсияПлатформы, "8.3.11") >= 0);
	
	Режим = Новый Структура;
	Режим.Вставить("БезопасныйРежим", БезопасныйРежим_());
	Режим.Вставить("УстановитьПривилегированныйРежим", Ложь);
	Режим.Вставить("ИспользоватьОписаниеЗащитыОтОпасныхДействий", ИспользоватьЗОД);
	
	Возврат Режим;
	
КонецФункции

// Проверяет, установлен ли безопасный режим.
// 
// Возвращаемое значение:
//  Булево.
//
Функция БезопасныйРежим_()
	
	Попытка
		БезопасныйРежим = Вычислить("БезопасныйРежим()");
	Исключение
		БезопасныйРежим = Ложь;
	КонецПопытки;
	
	Результат = (БезопасныйРежим = Истина ИЛИ ТипЗнч(БезопасныйРежим) = Тип("Строка"));
	
	Возврат Результат;
	
КонецФункции

Функция ТипОпределен(ИмяТипа)
	
	Попытка
		Тип = Тип(ИмяТипа);
	Исключение
		Тип = Тип("Неопределено");
	КонецПопытки;
	
	Результат = (Тип <> Тип("Неопределено"));
	
	Возврат Результат;
	
КонецФункции

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

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

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

Функция ПодключенныеОбработки_ВозможныеИсточникиБиблиотек()

	Результат = Новый Структура;
	Результат.Вставить("Файл"		, "Файл");
	Результат.Вставить("Макет"		, "Макет");
	Результат.Вставить("Конфигурация", "Конфигурация");
	
	Возврат Результат;

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

//}      Подключение библиотеки


//{		МАКЕТЫ ДЛЯ ОБЩЕГО ИСПОЛЬЗОВАНИЯ

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

	МакетыБезОбработок = МакетыБезОбработок();
	ДополнитьСтруктуру(Результат, МакетыБезОбработок);
	
	Возврат Результат;
	
КонецФункции

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

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

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

Функция ФайлИнтеграционногоМодуля()
	
	Результат = Неопределено;
	
	Ядро = Модуль_Ядро();
	ИмяМодуля = Ядро.ИнтеграционныйМодуль_ПолучитьИмяМакета();
	
	Если ЗначениеЗаполнено(ИмяМодуля) Тогда
		Результат = ПутьКФайлуИлиДвоичныеДанныеМодуля(ИмяМодуля);
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ФайлТиповогоМодуля()
	
	Результат = Неопределено;
	
	ИмяМодуля = ИмяТиповогоМодуля();
	
	Если ЗначениеЗаполнено(ИмяМодуля) Тогда
		Результат = ПутьКФайлуИлиДвоичныеДанныеМодуля(ИмяМодуля);
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ФайлМодуляЯдра()
	
	ПодключенныеОбработки = ОписанияПодключенныхОбработок();

	ИмяБиблиотекиЯдро = "КонтурДиадокЯдро";
	
	ОписаниеБиблиотеки = ПодключенныеОбработки[ИмяБиблиотекиЯдро];
	
	Результат = Неопределено;
	
	Если ОписаниеБиблиотеки  <> Неопределено Тогда
		
		Результат = ПодключитьБиблиотекуИзУказанногоИсточника(ОписаниеБиблиотеки);
		
	КонецЕсли;
	
	Если Результат = Неопределено Тогда
		
		Результат = ПутьКФайлуИлиДвоичныеДанныеМодуля(ИмяБиблиотекиЯдро);
		
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

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

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

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

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

// Определяет имя модуля менеджер интеграции
// 
// Возвращаемое значение:
//   Строка       - имя модуля менеджер интеграции
//
Функция ИмяМодуляМенеджерИнтеграции()
	
	Ядро = Модуль_Ядро();
	
	Результат = Ядро.ИмяМодуляМенеджерИнтеграции();
	
	Возврат Результат;
	
КонецФункции

Функция ПроверитьВозможностьПодключения(ИмяМодуля, ВызыватьИсключение = Ложь) Экспорт
	
	Модуль_Ядро = Модуль_Ядро();
	
	ИмяМакета = Модуль_Ядро.ПолучитьИмяМакетаПоМаркеру(ИмяМодуля);
	
	МакетИМ = ПолучитьМакет(ИмяМакета);
	
	Результат = Модуль_Ядро.Модуль_ПроверитьВозможностьПодключения(ИмяМакета, МакетИМ, ВызыватьИсключение);
	
	Возврат Результат;
	
КонецФункции

//}		МАКЕТЫ ДЛЯ ОБЩЕГО ИСПОЛЬЗОВАНИЯ


//{		ВНЕШНИЕ ОБРАБОТКИ

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

// Создает внешнюю обработку из файла.
//
// Параметры:
//  ДвоичныеДанныеИлиИмяФайла - Строка - полное имя файла с учетом пути.
//
// Возвращаемое значение:
//   ОбработкаОбъект - объект созданной внешней обработки.
//
Функция ВнешниеОбработки_СоздатьИзФайла(ДвоичныеДанныеИлиИмяФайла)
	// BSLLS:UsingExternalCodeTools-off
	БезопасныйРежим = Ложь;
	ЗащитаОтОпасныхДействий = ОписаниеЗащитыБезПредупреждений();
	
	Если ПриложениеСтаршеВерсии("8.3.11") ИЛИ ЗащитаОтОпасныхДействий = Неопределено Тогда
		
		Результат = ВнешниеОбработки.Создать(
				ДвоичныеДанныеИлиИмяФайла,
				БезопасныйРежим);
		
	Иначе
		
		Результат = ВнешниеОбработки.Создать(
				ДвоичныеДанныеИлиИмяФайла,
				БезопасныйРежим,
				ЗащитаОтОпасныхДействий);
		
	КонецЕсли;
	
	Возврат Результат;
	// BSLLS:UsingExternalCodeTools-on
КонецФункции

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

// Помещает во временное хранилище объект обработки
//
// Параметры:
//  Обработка      - ОбработкаОбъект - объект обработки;
//  АдресОбработки - Строка          - адрес во временном хранилище;
//
Процедура ХранилищеОбработки_Поместить(Обработка, АдресОбработки)
	
	СтруктураОбработки = Новый Структура("ОбработкаОбъект", Обработка);
	
	ПоместитьВоВременноеХранилище(СтруктураОбработки, АдресОбработки);
	
КонецПроцедуры

// Возвращает объект обработки из временного хранилища
//
// Параметры:
//  АдресОбработки - Строка - адрес обработки во временном хранилище
// 
// Возвращаемое значение:
//  ОбработкаОбъект - если обект обработки все еще загружен в память
//  Неопределено    - если объект обработки уже уничтожен
//
Функция ХранилищеОбработки_Прочитать(АдресОбработки)
	
	СтруктураОбработки = ПолучитьИзВременногоХранилища(АдресОбработки);
	
	Результат = СвойствоСтруктуры(СтруктураОбработки, "ОбработкаОбъект");
	
	Возврат Результат;
	
КонецФункции

//}		ВНЕШНИЕ ОБРАБОТКИ


//{		ОБНОВЛЕНИЕ МОДУЛЯ


// Обработчик при открытии основной формы
//
Процедура УстановитьНовуюВерсиюМодуля() Экспорт
	
	ТекущаяВерсия = ВерсияОбработки();
	
	Ядро = Модуль_Ядро();
	Ядро.ОбработатьЗапускНовойВерсииМодуля(ТекущаяВерсия);
	
КонецПроцедуры

Процедура ПроверитьОбновитьТипыДокументов(ВерсияДоЗапуска) Экспорт
	
	Ядро = Модуль_Ядро();
	
	Если ЭтоЗапускНовогоРелиза(ВерсияДоЗапуска) Тогда
		Ядро.ТипыДокументовAPI_Обновить();
	Иначе
		Ядро.ТипыДокументовAPI_ПроверитьНаличие();
	КонецЕсли;
	
КонецПроцедуры

Функция ЭтоЗапускНовогоРелиза(ВерсияДоЗапуска)
	
	ТекущаяВерсия = ВерсияОбработки();
	
	Результат = Ложь;
	
	Если ВерсияДоЗапуска <> ТекущаяВерсия Тогда
		
		МинорнаяТекущаяВерсия = МинорнаяВерсияМодуля(ТекущаяВерсия);
		МинорнаяВерсияДоЗапуска = МинорнаяВерсияМодуля(ВерсияДоЗапуска);
		
		Результат = (СравнитьВерсии(МинорнаяТекущаяВерсия, МинорнаяВерсияДоЗапуска) > 0);
		
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция МинорнаяВерсияМодуля(ВерсияМодуля)
	
	Ядро = Модуль_Ядро();
	Точка = ".";
	
	ЭлементыВерсии = РазделитьСтрокуЛок(ВерсияМодуля, Точка);
	ЭлементыВерсии.Удалить(ЭлементыВерсии.ВГраница());
	
	Результат = Ядро.СоединитьСтроку(ЭлементыВерсии, Точка);
	
	Возврат Результат;
	
КонецФункции

//}		ОБНОВЛЕНИЕ МОДУЛЯ


//{		ЦЕНТР ПОДДЕРЖКИ

// Набор параметров для открытия сессии ЦП
//
// Параметры:
//  BoxId - Строка - идентификатор ящик
//  РежимОткрытияЦП - Строка, Неопределено - см. Ядро.ЦП_РежимыОткрытияЦП()
// 
// Возвращаемое значение:
//   Структура - содержит ключи:
//     * ИмяИнтеграции     - Строка - идентификатор интеграции в ЦП.
//     * ТестовоеОкружение - Булево - Истина если необходимо открывать тестовый ЦП, см. ЦП_ТестовоеОкружение()
//     * ИНН - Строка.
//     * КПП - Строка.
//     * Организация - Строка - наименование организации от которой открывается сессия.
//     * Логин - Строка - логин под которым авторизован пользователь ДД.
//     * ВложениеДвоичныеДанные - ДвоичныеДанные - двоичные данные файла вложения.
//     * ВложениеИмяФайла - Строка - имя файла вложения.
//     * ДополнительныеПараметры - Соответствие - - содержит ключи:
//        * Модуль типовой - Строка - см. ЦП_ПредставлениеСостоянияМодуля().
//        * Версия модуля - Строка.
//        * Система хранения - Строка.
//        * BoxId - Строка.
//        * UserId - Строка.
//        * Отпечаток сертификата - Строка.
//        * Отключить контроль дублирования - Строка - Да, Нет.
//
Функция ЦП_НовыйПараметрыОткрытияСессии(BoxId, РежимОткрытияЦП = Неопределено) Экспорт
	
	Модуль_Ядро = Модуль_Ядро();
	
	Если ЗначениеЗаполнено(BoxId) Тогда 
		
		КонтекстОрганизации = Модуль_Ядро.КонтекстСеанса_СтрокаКонтекста(BoxId);
		
		ИНН = КонтекстОрганизации.Ящик.Организация.ИНН;
		КПП = КонтекстОрганизации.Ящик.Организация.КПП;
		ОрганизацияНаименование = КонтекстОрганизации.Ящик.Организация.Наименование;
		Логин = КонтекстОрганизации.Сессия.Пользователь.Логин;
		Пользователь = КонтекстОрганизации.Сессия.Пользователь.Представление;
		UserId = КонтекстОрганизации.Сессия.Пользователь.Идентификатор;
		ОтпечатокСертификата = КонтекстОрганизации.ОтпечатокСертификата;
		
	КонецЕсли;
	
	Результат  = Новый Структура;
	Результат.Вставить("ИмяИнтеграции", "diadoc-1c");
	Результат.Вставить("ТестовоеОкружение", ЦП_ТестовоеОкружение());
	Результат.Вставить("ИНН", ИНН);
	Результат.Вставить("КПП", КПП);
	Результат.Вставить("Организация", ОрганизацияНаименование);
	Результат.Вставить("Логин", Логин);
	Результат.Вставить("ИмяПользователя", Пользователь);
	Результат.Вставить("ДополнительныеПараметры", Новый Соответствие);
	
	ТехИнфо = Модуль_Ядро.ТехническаяИнформацияV2(BoxId);
	Сборка = ТехИнфо.КонфигурацияМодуля.Сборка;
	Настройки = ТехИнфо.КонфигурацияМодуля.Настройки;
	Если ТехИнфо.Свойство("КонтекстСеанса") Тогда
		ПодпискаПредставление = ТехИнфо.КонтекстСеанса.Биллинг.ПодпискаПредставление;
	КонецЕсли;
	
	Результат.ДополнительныеПараметры.Вставить("Модуль типовой", ЦП_ПредставлениеСостоянияМодуля(ТехИнфо.КонфигурацияМодуля));
	Результат.ДополнительныеПараметры.Вставить("Версия модуля", Сборка.Версия);
	Результат.ДополнительныеПараметры.Вставить("Система хранения", Сборка.СистемаХранения);
	Результат.ДополнительныеПараметры.Вставить("Сервис подписки на модуль", ПодпискаПредставление);
	Результат.ДополнительныеПараметры.Вставить("BoxId", XMLСтрока(BoxId));
	Результат.ДополнительныеПараметры.Вставить("UserId", XMLСтрока(UserId));
	Результат.ДополнительныеПараметры.Вставить("Отпечаток сертификата", XMLСтрока(ОтпечатокСертификата));
	Результат.ДополнительныеПараметры.Вставить("Отключить контроль дублирования", Формат(Настройки.ОтключитьКонтрольДублированияОтправкиПакетов, "БЛ=Нет; БИ=Да"));
	
	ВложениеДвоичныеДанные = ЦП_ВложениеДляПередачиВЦентрПоддержки(BoxId);
	Результат.Вставить("ВложениеДвоичныеДанные"	, ВложениеДвоичныеДанные);
	Результат.Вставить("ВложениеИмяФайла"		, "uminfo_" + Новый УникальныйИдентификатор + "_.zip");
	
	ЦП_ДополнитьПараметрыПоРежимуОткрытияЦП(Результат, РежимОткрытияЦП);
	
	Возврат Результат;
	
КонецФункции

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

Функция ЦП_ВложениеДляПередачиВЦентрПоддержки(BoxId)
	
	Модуль_Ядро = Модуль_Ядро();
	
	ТехИнфо = Модуль_Ядро.ТехническаяИнформацияV2(BoxId);
	ТехИнфоMD = Модуль_Ядро.ТехническаяИнформацияКакТекст(ТехИнфо);
	СписокОшибок = Модуль_Ядро.СписокОшибок();
	
	КаталогВременныхФайлов = КаталогВременныхФайлов();
	УИДФайла = XMLСтрока(Новый УникальныйИдентификатор);
	
	ФайлZipАрхива = ПолучитьИмяВременногоФайла("zip");
	ЗаписьZip = Новый ЗаписьZipФайла(ФайлZipАрхива);
	
	ФайлТехническойИнформации = КаталогВременныхФайлов + "techinfo_" + УИДФайла + "_.md";
	Запись = Новый ЗаписьТекста(ФайлТехническойИнформации, КодировкаТекста.UTF8, , Истина);
	Запись.ЗаписатьСтроку(ТехИнфоMD);
	Запись.Закрыть();
	ЗаписьZip.Добавить(ФайлТехническойИнформации);
	
	СписокОшибокЗаполнен = ЗначениеЗаполнено(СписокОшибок);
	Если СписокОшибокЗаполнен Тогда
		
		ТекстСпискаОшибок = СписокОшибок_HTML(СписокОшибок);
		ФайлСпискаОшибок = КаталогВременныхФайлов + "errors_" + УИДФайла + "_.html";
		Запись = Новый ЗаписьТекста(ФайлСпискаОшибок, КодировкаТекста.UTF8, , Истина);
		Запись.ЗаписатьСтроку(ТекстСпискаОшибок);
		Запись.Закрыть();
		ЗаписьZip.Добавить(ФайлСпискаОшибок);
		
	КонецЕсли;
	
	ЗаписьZip.Записать();
	
	Результат = Новый ДвоичныеДанные(ФайлZipАрхива);;
	
	УдалитьФайлы(ФайлZipАрхива);
	УдалитьФайлы(ФайлТехническойИнформации);
	Если СписокОшибокЗаполнен Тогда
		УдалитьФайлы(ФайлСпискаОшибок);
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

// Формирует текстовое описание конфигурации модуля.
//
// Параметры:
//  КонфигурацияМодуля - ФиксированнаяСтруктура - см. Ядро.ТехническаяИнформацияV2.КонфигурацияМодуля
// 
// Возвращаемое значение:
//  Строка - строка вида "<МодульТиповой>[/ПМ][/Плагины]"
//
Функция ЦП_ПредставлениеСостоянияМодуля(КонфигурацияМодуля)
	
	Результат = КонфигурацияМодуля.Сборка.МодульТиповой;
	
	ИспользоватьПлагины = КонфигурацияМодуля.Плагины.Использовать;
	ИспользоватьПМ = КонфигурацияМодуля.ПодключаемыйМодуль.Использовать;
	ИспользоватьПМ = ИспользоватьПМ Или КонфигурацияМодуля.ПодключаемыйМодульСтандарт.Использовать;
	
	Если ИспользоватьПМ Тогда
		Результат = Результат + "/ПМ";
	КонецЕсли;
	
	Если ИспользоватьПлагины Тогда
		Результат = Результат + "/Плагины";
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

// Определяет необходимость работы с тестовым Центром Поддержки
// 
// Возвращаемое значение:
//   Булево  - Истина если необходимо открывать тестовый ЦП
//
Функция ЦП_ТестовоеОкружение()
	
	Результат = СвойствоСтруктуры(ОбщийКонтекстКлиентСервер, "ЦП_ТестовоеОкружение", Ложь);
	
	Возврат Результат;
	
КонецФункции

//}		ЦЕНТР ПОДДЕРЖКИ


//**********************************************
//{		HTML СООБЩЕНИЯ

Функция HTMLНовоеВВерсииРаботаСКонтрагентами() Экспорт
	
	Макет = ПолучитьМакет("HTML_НовоеВВерсииРаботаСКонтрагентами");
	Результат = Макет.ПолучитьТекст();
	
	Возврат Результат;
	
КонецФункции

// Готовит текст в разметке HTML для информирования пользователя о возможных
// причинах отсутвия контрагента с списке
// Возвращаемое значение:
//	Строка
Функция HTMLПредставлениеСпискаПричинОтсутствияКонтрагента() Экспорт

	Ядро = Модуль_Ядро();
	
	АдресаИнтернетРесурсов = Ядро.Перечисление_АдресаИнтернетРесурсов();
	СсылкаНеОбновленСписокКонтрагентов = АдресаИнтернетРесурсов.Инструкция_НеОбновленСписокКонтрагентов;
	СсылкаНеПолученыИзмененияИзДиадок = АдресаИнтернетРесурсов.Инструкция_НеПолученыИзмененияИзДиадок;
	СсылкаКонтрагентВИномСписке = АдресаИнтернетРесурсов.Инструкция_СсылкаКонтрагентВИномСписке;
	СсылкаНеВыбранаОрганизация = АдресаИнтернетРесурсов.Инструкция_СсылкаНеВыбранаОрганизация;
	Инструкция_ПосмотретьВсеПричиныКонтрагентов = АдресаИнтернетРесурсов.Инструкция_ПосмотретьВсеПричиныКонтрагентов;
	СсылкаОповещениеЦентрПоддержки = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения("ОбработатьНажатие_ОткрытьЦентрПоддержки");
	
	Картинки = БиблиотекаКартинок();
	КартинкаИнструкция = Картинки.КартинкаИнструкцияСиняяКруглая_Base64;
	КартинкаОбновить = Картинки.КартинкаОбновитьЧерная_Base64;
	КартинкаПоиск = Картинки.КартинкаПоиск_Base64;
	КартинкаКонтрагенты = Картинки.КартинкаКонтрагенты_Base64;
	КартинкаПолучитьИзменения = Картинки.КартинкаПолучитьИзменения_Base64;
	КартинкаЦентрПоддержки = Картинки.КартинкаОнлайнКонсультант_Base64;
	КартинкаОблако = Картинки.КартинкаОблако_Base64;
	
	Макет = ПолучитьМакет("HTML_ПричиныОтсутствияКонтрагента");
	ТелоHTML = Макет.ПолучитьТекст();
	
	ИспользоватьПодсистемуДиадока = ОбщийКонтекстКлиентСервер.ИспользуетсяПодсистемаДиадок;

	Если  ИспользоватьПодсистемуДиадока Тогда
		ПолучениеДанныхИзДиадока = "<BR>
			|	<B><LI><P class=strtext2>Не получены изменения из Диадока</P></LI></B>
			|	<P class=strtext2>Нажмите на кнопку <IMG class=support SRC=""data:image/png;base64,[КартинкаПолучитьИзменения]""> Получить изменения из Диадока. Она расположена выше поля выбора организации.</P>
			|	<P class=strtext2><A HREF=""[СсылкаНеПолученыИзмененияИзДиадок]"">Получение данных из Диадока</A></P>
			|";
	Иначе
		ПолучениеДанныхИзДиадока = "";
	КонецЕсли;
	
	ТелоHTML = СтрЗаменить(ТелоHTML, "[ПолучениеДанныхИзДиадока]" , ПолучениеДанныхИзДиадока);
	
	ТелоHTML = СтрЗаменить(ТелоHTML, "[КартинкаПолучитьИзменения]" , КартинкаПолучитьИзменения);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[КартинкаОбновить]" , КартинкаОбновить);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[КартинкаПоиск]" , КартинкаПоиск);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[КартинкаКонтрагенты]" , КартинкаКонтрагенты);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[КартинкаЦентрПоддержки]" , КартинкаЦентрПоддержки);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[КартинкаОблако]" , КартинкаОблако);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[КартинкаИнструкция]" , КартинкаИнструкция);
	
	ТелоHTML = СтрЗаменить(ТелоHTML, "[СсылкаНеПолученыИзмененияИзДиадок]" , СсылкаНеПолученыИзмененияИзДиадок);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[СсылкаНеОбновленСписокКонтрагентов]" , СсылкаНеОбновленСписокКонтрагентов);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[СсылкаКонтрагентВИномСписке]" , СсылкаКонтрагентВИномСписке);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[СсылкаПосмотретьВсеПричины]" , Инструкция_ПосмотретьВсеПричиныКонтрагентов);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[СсылкаНеВыбранаОрганизация]" , СсылкаНеВыбранаОрганизация);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[СсылкаОповещениеЦентрПоддержки]" , СсылкаОповещениеЦентрПоддержки);

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

// Готовит текст в разметке HTML для работы с контрагентами по сопоставлению
//
// Параметры:
//  КонтрагентыДляОбработки - СписокЗначений - Заполненные контракты контрагентов с принятым приглашением
//  Режим - Строка - идентификатор режима списка контрагентов
// 
// Возвращаемое значение:
//  Строка - HTML-страница представления списка контрагентов для сопоставления
//
Функция HTMLПредставлениеСопоставлениеСКонтрагентами1С(КонтрагентыДляОбработки, Режим) Экспорт
	
	Ядро = Модуль_Ядро();
	
	Макет = ПолучитьМакет("HTML_СопоставлениеСКонтрагентами1С");
	ТелоHTML = Макет.ПолучитьТекст();
	
	СтрокаШаблон =
	"<li><code style=""font-family: SegoeUI, Arial, sans-serif;"">
	|%1 ИНН-КПП %2-%3.&nbsp;<u><P class=strtext2><A HREF=""%4"">%5</A></P></u></code>&nbsp;</li>";
	
	СтрокаСписокКонтрагентов = "<BR>";
	
	Индекс = 0;
	Для Каждого Элемент Из КонтрагентыДляОбработки Цикл
		
		ДанныеКонтрагента = Элемент.Значение;
		Обработчик = "ОбработатьНажатие_ОткрытьСсылкуСопоставитьКонтрагента";
		СтатусСопоставления = "Сопоставить";
		Если ЗначениеЗаполнено(ДанныеКонтрагента.СвязанныйСправочник1) Тогда
			СтатусСопоставления = "Сопоставление выполнено";
		КонецЕсли;
		СсылкаДляСопоставленияКонтрагента = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(Обработчик, Индекс);
		СтрокаДляДобавления = СтрЗаменить(СтрокаШаблон, "%1", ДанныеКонтрагента.Наименование);
		СтрокаДляДобавления = СтрЗаменить(СтрокаДляДобавления, "%2", ДанныеКонтрагента.ИНН);
		СтрокаДляДобавления = СтрЗаменить(СтрокаДляДобавления, "%3", ДанныеКонтрагента.КПП);
		СтрокаДляДобавления = СтрЗаменить(СтрокаДляДобавления, "%4", СсылкаДляСопоставленияКонтрагента);
		СтрокаДляДобавления = СтрЗаменить(СтрокаДляДобавления, "%5", СтатусСопоставления);
		СтрокаСписокКонтрагентов = СтрокаСписокКонтрагентов + СтрокаДляДобавления;
		
		Индекс = Индекс + 1;
		
	КонецЦикла;
	
	Если Режим = "СопоставлениеСКонтрагентами1С_ВашиКонтрагенты" Тогда
		ПредставлениеРежима = "принятии приглашений";
	ИначеЕсли Режим = "СопоставлениеСКонтрагентами1С_ПоискИПриглашение" Тогда
		ПредставлениеРежима = "отправке приглашений";
	Иначе
		ПредставлениеРежима = "обработке приглашений";
	КонецЕсли;
	
	ТелоHTML = СтрЗаменить(ТелоHTML, "[Режим]", ПредставлениеРежима);
	ТелоHTML = СтрЗаменить(ТелоHTML, "[СтрокаСписокКонтрагентов]", СтрокаСписокКонтрагентов);
	
	Возврат ТелоHTML;
	
КонецФункции

// Готовит текст в разметке HTML для информирования пользователя о дальнейших действиях
// в случае, если возникли проблемы авторизации по сертификату
//
// Возвращаемое значение:
//	Строка
Функция HTMLТекст_НетНужногоСертификата() Экспорт
	
	Ядро = Модуль_Ядро();
	
	АдресаИнтернетРесурсов = Ядро.Перечисление_АдресаИнтернетРесурсов();
	
	HTMLШаблоны = HTMLШаблоны_НетНужногоСертификата();
	
	Результат = HTMLШаблоны.Начало;
	Результат = Результат + HTMLШаблоны.ТаблицаСтилей;
	Результат = Результат + HTMLШаблоны.НачалоТела;
	
	ПодстрокиТела = Новый Массив;
	
	Подстрока = "<p class=strtext>Если в окне авторизации нет нужного сертификата, попробуйте сделать следующее:</p>";
	ПодстрокиТела.Добавить(Подстрока);
	
	ПодстрокиТела.Добавить("<ul>");
	
	Подстрока = "<li><p class=strtext>Проверить срок действия сертификата. Если он истек - свяжитесь с <a href=" + АдресаИнтернетРесурсов.СтраницаСервисныйЦентр + ">сервисным центром</a>.</p></li>";
	ПодстрокиТела.Добавить(Подстрока);
	
	Подстрока = "<li><p class=strtext>Установить сертификат. Воспользуйтесь <a href=" + АдресаИнтернетРесурсов.СправкаУстановкаСертификата + ">инструкцией</a> по установке сертификата. </p></li>";
	ПодстрокиТела.Добавить(Подстрока);
	
	Подстрока = "<li><p class=strtext><a href=" + АдресаИнтернетРесурсов.СправкаСкопироватьСертификат + ">Скопировать сертификат на сервер</a>, если вы работаете в клиент-серверном режиме. </p></li>";
	ПодстрокиТела.Добавить(Подстрока);
	
	ПодстрокиТела.Добавить("</ul>");
	
	ТекстТела = Ядро.СоединитьСтроку(ПодстрокиТела, Символы.ПС);
	
	Результат = Результат + ТекстТела;
	Результат = Результат + HTMLШаблоны.КнопкиТехПоддрежки;
	Результат = Результат + HTMLШаблоны.Окончание;
	
	Возврат Результат;
	
КонецФункции 

// Коллекция шаблонов для формирования HTML
//
// Возвращаемое значение:
//	Структура
Функция HTMLШаблоны_НетНужногоСертификата()
	
	Начало = "<html><head>
	|<META content=""text/html; charset=utf-8"" http-equiv=Content-Type>";
	
	ТаблицаСтилей = "
	|<style type=text/css>
	|	body {font-family: Arial}
	|	p.head {font-SIZE: 12pt}
	|	p.strtext{font-SIZE: 12pt}
	|</style>";
	
	НачалоТела = "</head><body>";
	
	Окончание = "</body></html>";
	
	Шапка = "
	|<p class=head>[Текст]</p>";
	
	Абзац = "
	|<p class=strtext>[Текст]<a href=""[КомандаДействия]"">[ТекстКоманды]</a>.</p>";
	
	Результат = Новый Структура;
	
	Результат.Вставить("Шапка"			, Шапка);
	Результат.Вставить("Абзац"			, Абзац);
	Результат.Вставить("Начало"			, Начало);
	Результат.Вставить("Окончание"		, Окончание);
	Результат.Вставить("НачалоТела"		, НачалоТела);
	Результат.Вставить("ТаблицаСтилей"	, ТаблицаСтилей);
	
	ДобавитьHTMLШаблоныКнопокТехПоддержки(Результат);
	
	Возврат Результат;
	
КонецФункции

// Добавляет в шаблон HTML сервисные кнопки
//
// Параметры:
//	HTMLШаблоны	- Структура	- набор HTML шаблонов 
Процедура ДобавитьHTMLШаблоныКнопокТехПоддержки(HTMLШаблоны)
	
	Ядро = Модуль_Ядро();
	
	Картинки = Ядро.БиблиотекаКартинок();
	
	КартинкаEmail = Картинки.КартинкаEmail_Base64;
	КартинкаОнлайнКонсультант = Картинки.КартинкаОнлайнКонсультант_Base64;
	
	СтрокаОповещенияЧат = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения("ОбработатьНажатие_ОткрытьЦентрПоддержки");
	СтрокаОповещенияПочта = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения("ОбработатьНажатие_ОтправитьEmail");
	
	ТаблицаСтилей = Ядро.СвойствоСтруктуры(HTMLШаблоны, "ТаблицаСтилей", "");
	
	ТаблицаСтилей = ТаблицаСтилей + "
	|<style type=text/css>
	|	div.footer {position: static; bottom: 0; width: 100%; margin-bottom: 10px; font-SIZE: 11pt;}
	|	img.support {border: 0; margin-right: 3px; vertical-align: bottom}
	|	a.support {margin-right: 10px}
	|</style>";
	
	// BSLLS:LineLength-off
	КнопкиТехПоддрежки = "
	|<div class=footer>
	|	<p><a class=support href=" + СтрокаОповещенияПочта + "><nobr><img class=support src=""data:image/png;base64," + КартинкаEmail + """></nobr>Написать в поддержку</a></p>
	|	<p><a class=support href=" + СтрокаОповещенияЧат + "><nobr><img class=support src=""data:image/png;base64," + КартинкаОнлайнКонсультант + """></nobr>Нужна помощь</a> </p>
	|</div>";
	// BSLLS:LineLength-on
	
	HTMLШаблоны.Вставить("ТаблицаСтилей", ТаблицаСтилей);
	HTMLШаблоны.Вставить("КнопкиТехПоддрежки", КнопкиТехПоддрежки);
	
КонецПроцедуры

// Функция формирует html текст и встраивает туда двоичные данные.
// Если двоичные данные являются pdf файлом, то он встраивается напрямую,
// во всех остальных случаях в html текст помещается ссылка на сохраненный файл во временном каталоге
//
// Параметры:
//  ДвоичныеДанные	 - ДвоичныеДанные	- данные файла
//  ИмяФайла		 - Строка			- двоичные данные будут сохранены по следующему пути: ВременныйКаталог + ИмяФайла
// 
// Возвращаемое значение:
//  Строка - текст html документа
//
Функция HTMLПредставлениеФайла(ИмяФайла, ОтключитьПревьюНеформализованного = Ложь, ПоказатьЗаглушкуАктаСверки = Ложь) Экспорт
	
	Ядро = Модуль_Ядро();
	
	ТекстHTML = 
	"<!DOCTYPE HTML>
	|<html>
	|	<head>
	|		<style>
	|		 body { overflow:  hidden; }
	|		 a { padding-bottom:  10px; }
	|		 table {
	|			width: 57%; /* Ширина таблицы */
	|		 }
	|		 td { padding: 5px; }
	|			td.col1 { background: #ffec82; color: black; font-weight:bold}
	|		</style>
	|	</head>
	|	<body>
	|		%1
	|	</body>
	|</html>";
	
	Если Прав(ИмяФайла, 4) = ".pdf" 
		И НЕ ОтключитьПревьюНеформализованного Тогда
		
		ТелоHTML = "<embed src=""%1"" width=""100%"" height=""100%"" type='application/pdf'>";
		ТелоHTML = Ядро.Общее_ПодставитьПараметрыВСтроку(ТелоHTML, ИмяФайла);
		
	Иначе
		
		КартинкаСохранитьBase64 = Картинки_КартинкаСохранить_Base64();
		СтрокаОповещения = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения("Обработчик_КопироватьФайл", ИмяФайла);
		
		ТелоHTMLШаблон = "<a href=""%1""><IMG src=""data:image/png;base64,%2"" align=top border=0 alt=""%3""> %3</a>";
		ТелоHTML = Ядро.Общее_ПодставитьПараметрыВСтроку(ТелоHTMLШаблон, СтрокаОповещения, КартинкаСохранитьBase64, "Сохранить документ на диск");
		
		КартинкаОткрытьBase64 = Картинки_КартинкаКарточкаСообщения_Base64();
		СтрокаОповещения = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения("Обработчик_ОткрытьФайл", ИмяФайла);
		
		ТелоHTMLШаблон = "<a href=""%1""><IMG src=""data:image/png;base64,%2"" align=top border=0 alt=""%3""> %3</a>";
		ТелоHTML = ТелоHTML + "<br>" + "<br>" + Ядро.Общее_ПодставитьПараметрыВСтроку(ТелоHTMLШаблон, СтрокаОповещения, КартинкаОткрытьBase64, "Открыть файл документа");
		
		Если ПоказатьЗаглушкуАктаСверки Тогда
			
			ТелоHTMLШаблон =
			"<table cellspacing=""0"">
			|<tr>
			|<td class=""col1"">%1</td>
			|</tr>
			|</table>";
		
			ТекстЗаглушки =
			"Я - технический файл, не подписывайте меня в Диадоке:)
			|<br>Автоматическая сверка доступна в сервисе Контур.Взаиморасчёты
			|<br><a href=""%1"">%2</a>";
			
			АдресаИнтернетРесурсов = Ядро.Перечисление_АдресаИнтернетРесурсов();
			
			СтраницаКонтурВзаиморасчеты = АдресаИнтернетРесурсов.СтраницаКонтурВзаиморасчеты;
			
			ТекстЗаглушки = Ядро.Общее_ПодставитьПараметрыВСтроку(ТекстЗаглушки, СтраницаКонтурВзаиморасчеты, СтраницаКонтурВзаиморасчеты);
			
			ТелоHTML = ТелоHTML + "<br>" + "<br>" + Ядро.Общее_ПодставитьПараметрыВСтроку(ТелоHTMLШаблон, ТекстЗаглушки);
			
		КонецЕсли;
		
	КонецЕсли;
	
	ТекстHTML = Ядро.Общее_ПодставитьПараметрыВСтроку(ТекстHTML, ТелоHTML);
	
	Возврат ТекстHTML;
	
КонецФункции

// Формирует представление истории документооборота в форме HTML-страницы
//
// Параметры:
//  ИсторияДО - Массив - см. Ядро.Документы_ИсторияДО
//
// Возвращаемое значение:
//  Строка - HTML-страница
//
Функция HTMLИсторияДокументооборота(ИсторияДО) Экспорт
	
	Ядро = Модуль_Ядро();
	
	ТекстHTML =
		"<!DOCTYPE HTML>
		|<html>
		|    <head>
		|        <meta charset=""utf-8"">
		|        <style type=text/css>
		|            .ingoing {
		|                color: #3e9400
		|            }
		|            .outgoing {
		|                color: #006caa
		|            }
		|            .error {
		|                color: #d0021b
		|            }
		|            .warning {
		|                color: #eab800
		|			 }
		|            .warning_mchd {
		|                color: #EF8B17
		|            }
		|            .crt {
		|                color: #00957F
		|            }
		|            .organization {
		|                font-weight: bold
		|            }
		|            .job_title_date_time {
		|                color: #adadad
		|            }
		|            .comment {
		|                background-color: #f2f2f2
		|            }
		|			 p.strtext2 {
		|				font-SIZE: 10pt;
		|				margin-top: 2px;
		|				margin-left: 25px;
		|			 }
		|			 img.support {
		|				border: 0;
		|				margin-right: 2px;
		|				vertical-align: bottom
		|			 }
		|			 .image {
		|				border: 0;
		|				margin-right: 3px;
		|				vertical-align: middle
		|			 }
		|			 .verified {
		|				vertical-align: middle
		|			 }
		|			 hr {
		|  				border: 1px solid #C5C5C5;
		|			 }
		|			img.event {border: 0; margin-right: 2px; vertical-align: top; height: 22px}
		|        </style>
		|    </head>
		|    <body>
		|%1
		|    </body>
		|</html>";
	
	ШаблонСобытияHTML =
		"
		|        <div class=""event"">
		|            <div class=""organization"">
		|                <span>%2</span>
		|                <span>%3</span>
		|            </div>
		|			 %ШаблонПодписи%
		|			 <div class=""comment"">%5</div>
		|			 %ШаблонПодвала%
		|            <div class=""job_title_date_time"">%4</div>
		|        </div>
		|        <hr>";
		
	ШаблонСобытияСКартинкойHTML =
		"
		|        <div class=""event"">
		|            <div class=""organization"">
		|                <span>%2</span>
		|                <span>%3</span>
		|            </div>
		|			%ШаблонПодписи%
		|			<div class=""comment""><img class=event src=""data:image/png;base64,%6"" alt=""%7"">%5</div>
		|			%ШаблонПодвала%
		|            <div class=""job_title_date_time"">%4</div>
		|        </div>
		|        <hr>";
		
	ШаблонДокументURL = " <a href=""%1"">документ</a>";
	ШаблонДокументШаблонURL = " на основе <a href=""%1"">шаблона</a>";
	
	ШаблонИзображение = " <a href=""%1"" class=""%4""><img src=""data:image/png;base64,%2"" align=top border=0 alt=""%3"">%3</a>";
	
	ТелоHTML = "";
	
	ИконкаСохранения = Картинки_КартинкаСкачать_Base64();
	ИконкаКонверт = Картинки_КартинкаEmail_Base64();
	
	Для Каждого Элемент Из ИсторияДО Цикл
		
		ОрганизацияПодписант = "";
		Если ЗначениеЗаполнено(Элемент.Организация) Тогда
			ОрганизацияПодписант = Элемент.Организация + ", ";
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Элемент.Подписант) Тогда
			ОрганизацияПодписант = ОрганизацияПодписант + Элемент.Подписант;
		КонецЕсли;
		
		Если Прав(ОрганизацияПодписант, 2) = ", " Тогда
			ОрганизацияПодписант = Лев(ОрганизацияПодписант, СтрДлина(ОрганизацияПодписант) - 2);
		КонецЕсли;
		
		ДатаВремя = "";
		Если ЗначениеЗаполнено(Элемент.Дата) Тогда
			ДатаВремя = Формат(Элемент.Дата, "ДЛФ=DDT");
		КонецЕсли;
		
		ДолжностьДатаВремя = Элемент.Должность + ?(ЗначениеЗаполнено(Элемент.Должность), " - ", "") + ДатаВремя;
		Описание = Элемент.Описание;
		Комментарий = ЗаменитьСсылкиНаКликабельные(Элемент.Комментарий);
		
		Если ЗначениеЗаполнено(Элемент.ДокументURL) Тогда
			Описание = Описание + Ядро.Общее_ПодставитьПараметрыВСтроку(ШаблонДокументURL, Элемент.ДокументURL);
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Элемент.ШаблонДокументаURL) Тогда
			Описание = Описание + Ядро.Общее_ПодставитьПараметрыВСтроку(ШаблонДокументШаблонURL, Элемент.ШаблонДокументаURL);
		КонецЕсли;
		
		ПодписьИМЧД = HTMLИсторияДокументооборотаПодписьИДоверенность(Элемент);
		
		Если Элемент.DocflowNamedId = Ядро.ИдентификаторВнешнегоДО_ПКФНС() Тогда
			
			СобытиеHTML = HTMLСобытиеПКФНС(Элемент, ДолжностьДатаВремя);
			
		Иначе
			
			Если Элемент.КодУС = "4002" Тогда
				
				СобытиеHTML = Ядро.Общее_ПодставитьПараметрыВСтроку(
					ШаблонСобытияСКартинкойHTML,
					Элемент.Тип,
					ОрганизацияПодписант,
					Описание,
					ДолжностьДатаВремя,
					Комментарий,
					ИконкаКонверт,
					Элемент.КодУС);
					
			ИначеЕсли Элемент.КодУС = "4003" Тогда
					
				СобытиеHTML = Ядро.Общее_ПодставитьПараметрыВСтроку(
					ШаблонСобытияHTML,
					Элемент.Тип,
					ОрганизацияПодписант,
					Описание,
					ДолжностьДатаВремя,
					"");
				
			Иначе
				
				СобытиеHTML = Ядро.Общее_ПодставитьПараметрыВСтроку(
					ШаблонСобытияHTML,
					Элемент.Тип,
					ОрганизацияПодписант,
					Описание,
					ДолжностьДатаВремя,
					Комментарий);
					
			КонецЕсли;
			
			СтрокаПодвал = "";
			
			ПараметрыСохранения = Элемент.ПараметрыСохранения;
			
			Если ЗначениеЗаполнено(ПараметрыСохранения.ИмяОбработчика) Тогда
				
				СтрокаОповещения = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
						ПараметрыСохранения.ИмяОбработчика,
						ПараметрыСохранения.ПараметрОбработчика);
				
				СтрокаПодвал = Ядро.Общее_ПодставитьПараметрыВСтроку(
						ШаблонИзображение,
						СтрокаОповещения,
						ИконкаСохранения,
						ПараметрыСохранения.ПредставлениеСсылки);
				
			КонецЕсли;
			
			Если ЗначениеЗаполнено(Элемент.ИнструкцияURL) Тогда
				
				ПараметрыСсылкиНаИнструкцию = ПараметрыСсылкиНаИнструкцию(Элемент.Тип = "error");
				
				СтрокаПодвал = СтрокаПодвал + Ядро.Общее_ПодставитьПараметрыВСтроку(
						ШаблонИзображение,
						Элемент.ИнструкцияURL,
						ПараметрыСсылкиНаИнструкцию.Иконка,
						ПараметрыСсылкиНаИнструкцию.Представление,
						Элемент.Тип);
				
			КонецЕсли;
			
			СобытиеHTML = СтрЗаменить(СобытиеHTML, "%ШаблонПодвала%", СтрокаПодвал);
			
			Если ЗначениеЗаполнено(ПодписьИМЧД) Тогда
				СобытиеHTML = СтрЗаменить(СобытиеHTML, "%ШаблонПодписи%", ПодписьИМЧД);
			Иначе
				СобытиеHTML = СтрЗаменить(СобытиеHTML, "%ШаблонПодписи%", "");
			КонецЕсли;
			
		КонецЕсли;
		
		ТелоHTML = ТелоHTML + СобытиеHTML;
		
	КонецЦикла;
	
	Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(ТекстHTML, ТелоHTML);
	
	Возврат Результат;
	
КонецФункции

Функция HTMLИсторияДокументооборотаПодписьИДоверенность(Знач Элемент)
	
	Результат = "";
	
	Если НЕ ЗначениеЗаполнено(Элемент.АдресЭлектроннаяПодписьИМЧД) Тогда
		Возврат Результат;
	КонецЕсли;
	
	Ядро = Модуль_Ядро();
	
	ШаблонПредставленияМЧДиПодписи =
		"
		|            <div class=""verified"">
		|				 <a href=""%1"">%2</a>
		|				 <span>∙</span>
		|                <a href=""%1"" class=""%3"">%4</a>
		|				 %ШаблонСсылкаНетМЧД%
		|			 </div>";
	
	ШаблонПредставленияПодписи =
		"
		|            <div>
		|				 <a href=""%1"">%2</a>
		|			 </div>";
	
	ШаблонСсылкаЧтоДелатьНетМЧД =
		"
		| 			<span>    </span>
		|			<a href=""%Инструкция_НетМЧДЧтоДелать%"" 
		|				class=""verified"">
		|				<img style=""vertical-align: auto;"" src=""data:image/png;base64,%КартинкаИнформацияСиняя%"">
		|			</a>";
		
	Перечисление_АдресаИнтернетРесурсов = Ядро.Перечисление_АдресаИнтернетРесурсов();
	Инструкция_НетМЧДЧтоДелать = Перечисление_АдресаИнтернетРесурсов.Инструкция_НетМЧДЧтоДелать;
	Картинки = Ядро.БиблиотекаКартинок();
	КартинкаИнформацияСиняя = Картинки.КартинкаИнформацияСиняя_Base64;
	ШаблонСсылкаЧтоДелатьНетМЧД = СтрЗаменить(
			ШаблонСсылкаЧтоДелатьНетМЧД, 
			"%КартинкаИнформацияСиняя%",
			КартинкаИнформацияСиняя);
	ШаблонСсылкаЧтоДелатьНетМЧД = СтрЗаменить(
			ШаблонСсылкаЧтоДелатьНетМЧД, 
			"%Инструкция_НетМЧДЧтоДелать%",
			Инструкция_НетМЧДЧтоДелать);
	// BSLLS:MissingTempStorageDeletion-off
	ДоверенностьИПодпись = ПолучитьИзВременногоХранилища(Элемент.АдресЭлектроннаяПодписьИМЧД);
	// BSLLS:MissingTempStorageDeletion-on
	ДанныеЭлектроннойПодписи = ДоверенностьИПодпись.ДанныеЭлектроннойПодписи;
	ДанныеМЧД = ДоверенностьИПодпись.ДанныеМЧД;
	
	ПредставлениеСертификата = Ядро.Документы_ИсторияДО_ПредставлениеСертификата(
			ДанныеЭлектроннойПодписи.CertificateSubjectType);
	
	Если ДанныеЭлектроннойПодписи.PowerOfAttorneyAttachmentStatus.StatusName = "PowerOfAttorneyNotRequired"
		И НЕ ЗначениеЗаполнено(ДанныеМЧД) Тогда
		
		ПредставлениеМЧД = "";
		
	ИначеЕсли НЕ ЗначениеЗаполнено(ДанныеМЧД) Тогда
		
		ПредставлениеМЧД = Ядро.Документы_ИсторияДО_ПредставлениеМЧД("");
		
	Иначе
		
		ИдентификаторСтатусаМЧД = СвойствоСтруктуры(ДанныеМЧД.СтатусПроверки.СтруктураОшибок, "ИдентификаторСтатуса");
		ПредставлениеМЧД = Ядро.Документы_ИсторияДО_ПредставлениеМЧД(ИдентификаторСтатусаМЧД);
		
	КонецЕсли;
	
	КлассРаскраскиМЧД = "crt";
	Если НЕ ПредставлениеМЧД = "МЧД прошла проверку" Тогда
		КлассРаскраскиМЧД = "warning_mchd";
	КонецЕсли;
	
	ИмяОбработчика = "ПоказатьФормуЭлектроннаяПодписьИДоверенности";
	ПараметрОбработчика = Элемент.АдресЭлектроннаяПодписьИМЧД;
	
	СтрокаОповещения = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
			ИмяОбработчика,
			ПараметрОбработчика);
	
	Если ЗначениеЗаполнено(ПредставлениеМЧД) Тогда
		
		Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
				ШаблонПредставленияМЧДиПодписи,
				СтрокаОповещения,
				ПредставлениеСертификата,
				КлассРаскраскиМЧД,
				ПредставлениеМЧД);
				
		Если НЕ ПредставлениеМЧД = "Нет МЧД" Тогда
			 ШаблонСсылкаЧтоДелатьНетМЧД = "";
		КонецЕсли;
		 
		Результат = СтрЗаменить(Результат, "%ШаблонСсылкаНетМЧД%", ШаблонСсылкаЧтоДелатьНетМЧД); 
		
	Иначе
		
		Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
				ШаблонПредставленияПодписи,
				СтрокаОповещения,
				ПредставлениеСертификата);
		
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция HTMLСобытиеПКФНС(Элемент, ДолжностьДатаВремя)
	
	Ядро = Модуль_Ядро();
	
	ШаблонСобытияПКФНСHTML =
		"
		|<div class=""event"">
		|	<div class=""organization"">
		|		<span class=""outgoing"">%2</span>
		|		<span>%3</span>
		|	</div>
		|	<div class=""job_title_date_time"">%4</div>
		|</div>";
	
	ШаблонСобытияСОшибкойПКФНСHTML =
		"
		|<div class=""event"">
		|	<div class=""organization"">
		|		<span class=""outgoing"">%1</span>
		|	</div>
		|	<p>
		|		<img style=""border: 0;	margin-right: 3px;"" src=""data:image/png;base64,%2""> 
		|   	<span>%3</span>
		|	</p>
		|	<details>
		|   	<summary class=""outgoing"">Дополнительная информация</summary>
		|    	<ul>
		|			%4
		|    	</ul>
		|    	<p class=""strtext2"">
		|			<img class=""support"" src=""data:image/png;base64,%5"">
		|			<a class=""outgoing"" href=""%6"">Что делать?</a>
		|	 	</p>
		|    </details><br>
		|	<div class=""job_title_date_time"">%7</div>
		|</div>";
	
	Картинки = Ядро.БиблиотекаКартинок();
	АдресаИнтернетРесурсов = Ядро.Перечисление_АдресаИнтернетРесурсов();
	КартинкаПрикрепитьСсылку = Картинки.КартинкаПрикрепитьСсылку_Base64;
	КартинкаВниманиеЖелтая = Картинки.КартинкаВниманиеЖелтая_Base64;
	
	КлассОшибкиCSS = НРег(Элемент.Тип);
	
	Детали = ПолучитьИзВременногоХранилища(Элемент.Детализация);
	УдалитьИзВременногоХранилища(Элемент.Детализация);
	
	ОписаниеHTML = Элемент.Описание;
	
	Если ЗначениеЗаполнено(Детали.Details) Тогда
		
		СтрокаДеталей = "";
		Для Каждого Деталь Из Детали.Details Цикл
			СтрокаДеталей = СтрокаДеталей + "<li>" + Деталь.Text + "</li>";
		КонецЦикла;
		
		Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
				ШаблонСобытияСОшибкойПКФНСHTML,
				Элемент.Организация,
				КартинкаВниманиеЖелтая,
				ОписаниеHTML,
				СтрокаДеталей,
				КартинкаПрикрепитьСсылку,
				АдресаИнтернетРесурсов.ИнструкцияПоПрослеживаемымТоварам,
				ДолжностьДатаВремя);
		
	Иначе
		
		Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
				ШаблонСобытияПКФНСHTML,
				КлассОшибкиCSS,
				Элемент.Организация,
				ОписаниеHTML,
				ДолжностьДатаВремя);
		
	КонецЕсли;
	
	Результат = Результат + "<hr>";
	
	Возврат Результат;
	
КонецФункции

Функция HTML_ЭлектроннаяПодписьИДоверенность(АдресаВременногоХранилища) Экспорт
	
	Ядро = Модуль_Ядро();
	// BSLLS:MissingTempStorageDeletion-off
	Данные = ПолучитьИзВременногоХранилища(АдресаВременногоХранилища);
	// BSLLS:MissingTempStorageDeletion-on
	ДанныеSignature = Данные.ДанныеЭлектроннойПодписи;
	ДанныеМЧД = Данные.ДанныеМЧД;
	
	ТребуетсяМЧД = ДанныеSignature.PowerOfAttorneyAttachmentStatus.StatusName = "PowerOfAttorneyRequired";
	КомментарииКМЧД = СвойствоСтруктуры(ДанныеSignature.PowerOfAttorneyAttachmentStatus, "Comment");
	
	ШаблонСтраницы = HTML_ШаблонСтраницыЭлектроннаяПодписьИДоверенность();
	
	МакетЭлектроннаяПодпись = HTML_ШаблонЭлектроннаяПодпись(
			ДанныеSignature,
			АдресаВременногоХранилища);
	
	Если ЗначениеЗаполнено(ДанныеМЧД) Тогда
		
		ПараметрыГиперссылкиСкачатьФайлыДоверенности = Ядро.Новый_ПараметрыГиперссылкиДляДействийСМЧД(
				ДанныеМЧД.BoxId,
				ДанныеМЧД.MessageId,
				ДанныеМЧД.EntityId,
				ДанныеМЧД.Идентификатор);
		
		СериализованныеПараметры = Ядро.СериализоватьПараметрыГиперссылки(ПараметрыГиперссылкиСкачатьФайлыДоверенности);
		ОповещениеСкачатьДоверенности = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
				"ОбработатьНажатие_СкачатьФайлыДоверенности",
				СериализованныеПараметры);
		
		МакетДоверенность = HTML_ШаблонДоверенность(ДанныеМЧД, ОповещениеСкачатьДоверенности);
		
		Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
				ШаблонСтраницы,
				МакетЭлектроннаяПодпись + МакетДоверенность);
		
	ИначеЕсли ТребуетсяМЧД Тогда
		
		МакетДоверенность = HTML_ШаблонДоверенностьНеПриложена();
		
		МакетДоверенность = СтрЗаменить(МакетДоверенность, "%КомментарийКМЧД%", КомментарииКМЧД);
		
		Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
				ШаблонСтраницы,
				МакетЭлектроннаяПодпись + МакетДоверенность);
		
	Иначе
		
		МакетДоверенность = HTML_ШаблонДоверенностьНеНужна();
		
		Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
				ШаблонСтраницы,
				МакетЭлектроннаяПодпись + МакетДоверенность);
		
	КонецЕсли;
	
	ДатаПроверкиПодписи = СвойствоСтруктуры(ДанныеSignature, "SignatureVerificationTime");
	Если НЕ ЗначениеЗаполнено(ДатаПроверкиПодписи) Тогда
		ДатаПроверкиПодписи = СвойствоСтруктуры(ДанныеSignature, "SigningTime");
	КонецЕсли;
	TimeStamp = ДатаПроверкиПодписи.Ticks;
	ДатаСобытия = МестноеВремя(Ядро.Ticks_2_Date(TimeStamp));
	
	Результат = СтрЗаменить(Результат, "%ТипОперацииПодписания%", ДанныеSignature.ПредставлениеСобытияПодписи);
	Результат = СтрЗаменить(Результат, "%ДатаСобытия%", ДатаСобытия);
	
	Возврат Результат;
	
КонецФункции

Функция HTML_ШаблонСтраницыЭлектроннаяПодписьИДоверенность()
	
	Результат =
		"<!DOCTYPE HTML>
		|<html>
		|    <head>
		|        <meta charset=""utf-8"">
		|        <style type=text/css>
		|            .ingoing {
		|                color: #3e9400
		|            }
		|            .outgoing {
		|                color: #006caa
		|            }
		|            .error {
		|                color: #d0021b
		|            }
		|            .warning {
		|                color: #eab800
		|			 }
		|            .warning_mchd {
		|                color: #EF8B17
		|            }
		|            .crt {
		|                color: #00957F
		|            }
		|			.block {
		|				margin-top: 8px;
		|				padding-left: 16px;
		|			}
		|
		|			.extend {
		|				position: relative;
		|				display: -ms-flexbox;
		|				display: flex;
		|				gap: 20px;
		|			}
		|
		|			.left {
		|				width: 170px;
		|				max-width: 170px;
		|				min-width: 170px;
		|				white-space: nowrap;
		|			}
		|
		|			.right {
		|				max-width: 400px;
		|				overflow: hidden;
		|				text-overflow: ellipsis;
		|				white-space: nowrap;
		|				padding-right: 35px;
		|			}
		|            .organization {
		|                font-weight: bold
		|            }
		|            .job_title_date_time {
		|                color: #adadad
		|            }
		|            .comment {
		|                background-color: #f2f2f2
		|            }
		|			 p.strtext2 {
		|				font-SIZE: 10pt;
		|				margin-top: 2px;
		|				margin-left: 25px;
		|			 }
		|			 img.support {
		|				border: 0;
		|				margin-right: 2px;
		|				vertical-align: bottom
		|			 }
		|			 .image {
		|				border: 0;
		|				margin-right: 3px;
		|				vertical-align: middle
		|			 }
		|			 .verified {
		|				vertical-align: middle
		|			 }
		|			 .verified_crt {
		|				color: #00957F;
		|				vertical-align: middle
		|			 }
		|			 hr {
		|  				border: 1px solid #C5C5C5;
		|			 }
		|        </style>
		|    </head>
		|    <body>
		|%1
		|    </body>
		|</html>";
	
	Возврат Результат;
	
КонецФункции

Функция HTML_ШаблонЭлектроннаяПодпись(ДанныеЭлектроннойПодписи, АдресаВременногоХранилища)
	
	Результат =
		"<div class=""section"">
		|	<div class=""organization"">
		|		<p class=""outgoing"">Электронная подпись</p>
		|	</div>
		|	<p class=""organization""> %ВладелецСертификата% </p>
		|	<p> %ТипСертификата% • Действует до %ДатаДействия%</p>
		|	<div><img class=""image"" src=""data:image/png;base64,%ИзображениеГалочка%"">
		|		<span class=""verified""> Подпись подтверждена %ДатаПодтверждения% </span>
		|	</div>
		|	<br>
		|	<details>
		|
		|		<summary class=""outgoing"">Дополнительная информация</summary>
		|		<table class=""block"">
		|			<tbody>
		|			<tr class=""extend"">
		|				<td class=""left"">Организация</td>
		|				<td class=""right"">%Организация%</td>
		|			</tr>
		|			<tr class=""extend"">
		|				<td class=""left"">Серийный номер</td>
		|				<td class=""right"">%Серийный номер%</td>
		|			</tr>
		|			<tr class=""extend"">
		|				<td class=""left"">Выдан</td>
		|				<td class=""right"">%Выдан%</td>
		|			</tr>
		|			<tr class=""extend"">
		|				<td class=""left"">Начало действия</td>
		|				<td class=""right"">%НачалоДействия%</td>
		|			</tr>
		|			<tr class=""extend"">
		|				<td class=""left"">Дата окончания</td>
		|				<td class=""right"">%ДатаОкончания%</td>
		|			</tr>
		|			<tbody>
		|		</table>
		|	</details><br>
		|	<div><img class=""image"" src=""data:image/png;base64,%ИзображениеСкачать%"">
		|		<a class=""verified_crt"" href=""%СсылкаСкачатьПодпись%"">Скачать файл электронной цифровой подписи</a>
		|	</div>
		|	<div><img class=""image"" src=""data:image/png;base64,%ИзображениеСкачать%"">
		|		<a class=""verified_crt"" href=""%СсылкаСкачатьСертификат%"">Скачать сертификат подписанта</a>
		|	</div>
		|</div><hr>";
	
	Ядро = Модуль_Ядро();
	Картинки = Ядро.БиблиотекаКартинок();
	КартинкаСкачать = Картинки.КартинкаСкачатьЗеленая_Base64;
	КартинкаГалочкаВЗеленомКруге = Картинки.КартинкаГалочкаВЗеленомКруге_Base64;
	
	ВладелецСертификата = ДанныеЭлектроннойПодписи.Surname + " " + ДанныеЭлектроннойПодписи.FirstName;
	ПредставлениеСертификата = Ядро.Документы_ИсторияДО_ПредставлениеСертификата(
			ДанныеЭлектроннойПодписи.CertificateSubjectType);
	СсылкаСкачатьПодпись = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
			"ОбработатьНажатие_СкачатьФайлЭлектроннойПодписи",
			АдресаВременногоХранилища);
	СсылкаСкачатьСертификат = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
			"ОбработатьНажатие_СкачатьФайлСертификата",
			АдресаВременногоХранилища);
	
	ДатаПроверкиПодписи = СвойствоСтруктуры(ДанныеЭлектроннойПодписи, "SignatureVerificationTime");
	Если НЕ ЗначениеЗаполнено(ДатаПроверкиПодписи) Тогда
		ДатаПроверкиПодписи = СвойствоСтруктуры(ДанныеЭлектроннойПодписи, "SigningTime");
	КонецЕсли;
	TimeStamp = ДатаПроверкиПодписи.Ticks;
	ДатаСобытия = МестноеВремя(Ядро.Ticks_2_Date(TimeStamp));
	
	ФорматТолькоДата = "ДЛФ=DD";
	
	Результат = СтрЗаменить(Результат, "%ИзображениеСкачать%", КартинкаСкачать);
	Результат = СтрЗаменить(Результат, "%ИзображениеГалочка%", КартинкаГалочкаВЗеленомКруге);
	Результат = СтрЗаменить(Результат, "%ВладелецСертификата%", ВладелецСертификата);
	Результат = СтрЗаменить(Результат, "%ТипСертификата%", ПредставлениеСертификата);
	Результат = СтрЗаменить(Результат, "%Организация%", ДанныеЭлектроннойПодписи.НаименованиеОрганизацииПодписанта);
	Результат = СтрЗаменить(Результат, "%ДатаПодтверждения%",
			Формат(ДатаСобытия, ФорматТолькоДата) + " в " + Формат(ДатаСобытия, "ДЛФ=T"));
	Результат = СтрЗаменить(Результат, "%ДатаДействия%", Формат(ДанныеЭлектроннойПодписи.EndDate, ФорматТолькоДата));
	
	Результат = СтрЗаменить(Результат, "%Серийный номер%", ДанныеЭлектроннойПодписи.SerialNumber);
	Результат = СтрЗаменить(Результат, "%Выдан%", ДанныеЭлектроннойПодписи.Issuer);
	Результат = СтрЗаменить(Результат, "%НачалоДействия%", Формат(ДанныеЭлектроннойПодписи.StartDate, ФорматТолькоДата));
	Результат = СтрЗаменить(Результат, "%ДатаОкончания%", Формат(ДанныеЭлектроннойПодписи.EndDate, ФорматТолькоДата));
	Результат = СтрЗаменить(Результат, "%СсылкаСкачатьПодпись%", СсылкаСкачатьПодпись);
	Результат = СтрЗаменить(Результат, "%СсылкаСкачатьСертификат%", СсылкаСкачатьСертификат);
	
	Возврат Результат;
	
КонецФункции

Функция HTML_ШаблонДоверенность(ДанныеДоверенности, ОповещениеСкачатьДоверенности)
	
	Результат =
		"<div class=""section"">
		|	<div class=""organization"">
		|		<p class=""outgoing"">Доверенность</p>
		|	</div>
		|	<p class=""organization""> %Организация%</p>
		|	<p class=""organization""> %ВладелецДоверенности% </p>
		|	<p> Действует до %ДатаДействия%</p>
		|	%ШаблонПроверкиМЧД%
		|	<details>
		|
		|		<summary class=""outgoing"">Дополнительная информация</summary>
		|		<table class=""block"">
		|			<tbody>
		|			<tr class=""extend"">
		|				<td class=""left"">Номер доверенности</td>
		|				<td class=""right"">%НомерДоверенности%</td>
		|			</tr>
		|			<tr class=""extend"">
		|				<td class=""left"">ИНН доверителя</td>
		|				<td class=""right"">%ИННДоверителя%</td>
		|			</tr>
		|			<tr class=""extend"">
		|				<td class=""left"">ИНН доверенного лица</td>
		|				<td class=""right"">%ИННПредставителя%</td>
		|			</tr>
		|			</tbody>
		|		</table>
		|			<div class=""block"">
		|				<a href=""%ОткрытьПолномочия%"" class=""left""> Сведения о полномочиях</a>
		|			</div>
		|		</details>
		|		<div class=""block"">
		|			%ШаблонПередоверия%
		|			<div><img class=""image"" src=""data:image/png;base64,%ИзображениеСкачать%"">
		|				<a class=""verified"" href=""%СкачатьДоверенности%""> %ПредставлениеСсылкиСкачатьДоверенность%</a>
		|			</div>
		|			<div><a class=""verified"" href=""%ГиперссылкаПросмотрМЧДФНС%""> Информация о МЧД на сайте ФНС</a>
		|				<img class=""image"" src=""data:image/png;base64,%ИзображениеПрямоугольникСтрелочка%"">
		|			</div>
		|		</div>
		|</div>
		|<p class=""job_title_date_time"">%ТипОперацииПодписания% %ДатаСобытия%</p>
		|<hr>";
	
	ШаблонДоверенностьПрошлаПроверку = "
		|	<div><img class=""image"" src=""data:image/png;base64,%ИзображениеГалочка%"">
		|		<span class=""verified""> Доверенность прошла проверку %ДатаПодтверждения% </span>
		|	</div>";
	
	ШаблонДоверенностьОшибка = "
		|	<div><img class=""image"" src=""data:image/png;base64,%ИзображениеОшибки%"">
		|		<span class=""verified""> %ОписаниеОшибки% </span>
		|	</div>";
	
	ШаблонПередоверия = "
		|			<span>⟲ МЧД в порядке передоверия </span>
		|			<div><img class=""image"" src=""data:image/png;base64,%ИзображениеКоннектор%"">
		|				<a href=""%СсылкаПоказатьЦепочкуДоверенности%"" class=""verified""> Все доверенности в цепочке передоверия</a>
		|			</div>";
	
	Ядро = Модуль_Ядро();
	Картинки = Ядро.БиблиотекаКартинок();
	ИдентификаторФормы = Ядро.ОбщийКонтекст_Прочитать("ИдентификаторФормы");
	КартинкаПрикрепитьСсылку = Картинки.КартинкаПрикрепитьСсылку_Base64;
	КартинкаСкачать = Картинки.КартинкаСкачать_Base64;
	КартинкаВниманиеЖелтая = Картинки.КартинкаВниманиеЖелтая_Base64;
	КартинкаИсправитьОшибки = Картинки.КартинкаИсправитьОшибки_Base64;
	КартинкаГалочкаВЗеленомКруге = Картинки.КартинкаГалочкаВЗеленомКруге_Base64;
	ПрямоугольникСоСтрелкойЗеленая = Картинки.ПрямоугольникСоСтрелкойЗеленая_Base64;
	СсылкаНаСтраницуПроверкиДоверенностиНаСайтеФНС = Ядро.ПодготовитьСсылкуНаСтраницуПроверкиДоверенностиНаСайтеФНС(
			ДанныеДоверенности);
	ПараметрыГиперссылки = Ядро.Новый_ПараметрыГиперссылкиПроверкиМЧД(
			СсылкаНаСтраницуПроверкиДоверенностиНаСайтеФНС,
			"",
			ДанныеДоверенности.Идентификатор);
	СериализованныеПараметрыГиперссылкиПроверкиМЧД = Ядро.СериализоватьПараметрыГиперссылки(ПараметрыГиперссылки);
	ГиперссылкаПросмотрМЧДФНС = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
			"ОбработатьНажатие_ПроверитьДоверенностьНаСайтеФНС",
			СериализованныеПараметрыГиперссылкиПроверкиМЧД);
	ВладелецСертификата = Ядро.ФамилияИО(ДанныеДоверенности.Представитель.Наименование);
	АдресВременногоХранилища = ПоместитьВоВременноеХранилище(ДанныеДоверенности, ИдентификаторФормы);
	ОткрытьПолномочия = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
			"ОбработатьНажатие_ПосмотретьПолномочияМЧД",
			АдресВременногоХранилища);
	
	Результат = СтрЗаменить(Результат, "%ВладелецДоверенности%", ВладелецСертификата);
	Результат = СтрЗаменить(Результат, "%Организация%", ДанныеДоверенности.Доверитель.Наименование);
	Результат = СтрЗаменить(Результат, "%ДатаДействия%", ДанныеДоверенности.СрокДействия);
	Результат = СтрЗаменить(Результат, "%НомерДоверенности%", ДанныеДоверенности.Идентификатор);
	Результат = СтрЗаменить(Результат, "%ИННДоверителя%", ДанныеДоверенности.Доверитель.ИНН);
	Результат = СтрЗаменить(Результат, "%ИННПредставителя%", ДанныеДоверенности.Представитель.ИНН);
	
	СтатусПроверки = ДанныеДоверенности.СтатусПроверки;
	ДатаПроверки = СтатусПроверки.ДатаПроверки;
	СтруктураОшибок = СтатусПроверки.СтруктураОшибок;
	
	ПараметрЗаменыШаблонПроверкиМЧД = "%ШаблонПроверкиМЧД%";
	
	Если НЕ ЗначениеЗаполнено(СтруктураОшибок) Тогда
		
		Результат = СтрЗаменить(Результат, ПараметрЗаменыШаблонПроверкиМЧД, "");
		
	ИначеЕсли СтруктураОшибок.СписокОшибок.Количество() = 0 Тогда
		
		Результат = СтрЗаменить(Результат, ПараметрЗаменыШаблонПроверкиМЧД, ШаблонДоверенностьПрошлаПроверку + "<br>");
		Результат = СтрЗаменить(Результат, "%ДатаПодтверждения%", Формат(ДатаПроверки, "ДЛФ=DDT"));
		
	Иначе
		
		ШаблонПроверкиМЧД = "";
		
		СписокОшибок = СтруктураОшибок.СписокОшибок;
		Для Каждого СтрокаОшибки Из СписокОшибок Цикл
			
			ШаблонПроверкиМЧД = ШаблонПроверкиМЧД + ШаблонДоверенностьОшибка;
			
			ШаблонПроверкиМЧД = СтрЗаменить(ШаблонПроверкиМЧД, "%ОписаниеОшибки%", СтрокаОшибки.Расшифровка);
			
			Если СтрокаОшибки.Тип = "Error" Тогда
				
				ШаблонПроверкиМЧД = СтрЗаменить(ШаблонПроверкиМЧД, "%ИзображениеОшибки%", "%ИзображениеИсправитьОшибки%");
				
			Иначе
				
				ШаблонПроверкиМЧД = СтрЗаменить(ШаблонПроверкиМЧД, "%ИзображениеОшибки%", "%ИзображениеВниманиеЖелтая%");
				
			КонецЕсли;
			
		КонецЦикла;
		
		Результат = СтрЗаменить(Результат, ПараметрЗаменыШаблонПроверкиМЧД, ШаблонПроверкиМЧД + "<br>");
		
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ДанныеДоверенности.ДелегированныеМЧД) Тогда
		
		СсылкаПоказатьЦепочкуДоверенности = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
				"ОбработатьНажатие_ПоказатьЦепочкуПередоверияМЧД",
				АдресВременногоХранилища);
		
		Результат = СтрЗаменить(Результат, "%ШаблонПередоверия%", ШаблонПередоверия);
		Результат = СтрЗаменить(Результат, "%СсылкаПоказатьЦепочкуДоверенности%", СсылкаПоказатьЦепочкуДоверенности);
		
	Иначе
		
		Результат = СтрЗаменить(Результат, "%ШаблонПередоверия%", "");
		
	КонецЕсли;
	
	ПредставлениеГиперссылкиДляСкачиванияДоверенности = HTML_ПредставлениеГиперссылкиДляСкачиванияДоверенности(
			ДанныеДоверенности.ДелегированныеМЧД);
	
	Результат = СтрЗаменить(Результат, "%ПредставлениеСсылкиСкачатьДоверенность%",
			ПредставлениеГиперссылкиДляСкачиванияДоверенности);
	Результат = СтрЗаменить(Результат, "%СкачатьДоверенности%", ОповещениеСкачатьДоверенности);
	Результат = СтрЗаменить(Результат, "%ГиперссылкаПросмотрМЧДФНС%", ГиперссылкаПросмотрМЧДФНС);
	Результат = СтрЗаменить(Результат, "%ИзображениеСкачать%", КартинкаСкачать);
	Результат = СтрЗаменить(Результат, "%ИзображениеПрямоугольникСтрелочка%", ПрямоугольникСоСтрелкойЗеленая);
	Результат = СтрЗаменить(Результат, "%ИзображениеКоннектор%", КартинкаПрикрепитьСсылку);
	Результат = СтрЗаменить(Результат, "%ИзображениеГалочка%", КартинкаГалочкаВЗеленомКруге);
	Результат = СтрЗаменить(Результат, "%ИзображениеИсправитьОшибки%", КартинкаИсправитьОшибки);
	Результат = СтрЗаменить(Результат, "%ИзображениеВниманиеЖелтая%", КартинкаВниманиеЖелтая);
	Результат = СтрЗаменить(Результат, "%ОткрытьПолномочия%", ОткрытьПолномочия);
	
	Возврат Результат;
	
КонецФункции 

Функция HTML_ШаблонДоверенностьПередоверие(ДанныеДоверенности)
	
	Результат =
		"<div class=""section"">
		|	<p class=""organization""> %Организация%</p>
		|	<p class=""organization""> %ВладелецДоверенности% </p>
		|	<p> Действует до %ДатаДействия%</p>
		|	%ШаблонПроверкиМЧД%
		|	<details>
		|
		|		<summary class=""outgoing"">Дополнительная информация</summary>
		|		<table class=""block"">
		|			<tbody>
		|			<tr class=""extend"">
		|				<td class=""left"">Номер доверенности</td>
		|				<td class=""right"">%НомерДоверенности%</td>
		|			</tr>
		|			<tr class=""extend"">
		|				<td class=""left"">ИНН доверителя</td>
		|				<td class=""right"">%ИННДоверителя%</td>
		|			</tr>
		|			<tr class=""extend"">
		|				<td class=""left"">ИНН доверенного лица</td>
		|				<td class=""right"">%ИННПредставителя%</td>
		|			</tr>
		|			</tbody>
		|		</table>
		|			<div class=""block"">
		|				<a href=""%ОткрытьПолномочия%"" class=""left""> Сведения о полномочиях</a>
		|			</div>
		|		</details>
		|		<div class=""block"">
		|			<div><a class=""verified"" href=""%ГиперссылкаПросмотрМЧДФНС%""> Информация о МЧД на сайте ФНС</a>
		|				<img class=""image"" src=""data:image/png;base64,%ИзображениеПрямоугольникСтрелочка%"">
		|			</div>
		|		</div>
		|</div>
		|<p class=""job_title_date_time"">%ТипОперацииПодписания% %ДатаСобытия%</p>
		|<hr>";
	
	ШаблонДоверенностьПрошлаПроверку = "
		|	<div><img class=""image"" src=""data:image/png;base64,%ИзображениеГалочка%"">
		|		<span class=""verified""> Доверенность прошла проверку %ДатаПодтверждения% </span>
		|	</div>";
	
	ШаблонДоверенностьОшибка = "
		|	<div><img class=""image"" src=""data:image/png;base64,%ИзображениеОшибки%"">
		|		<span class=""verified""> %ОписаниеОшибки% </span>
		|	</div>";
	
	Ядро = Модуль_Ядро();
	Картинки = Ядро.БиблиотекаКартинок();
	ИдентификаторФормы = Ядро.ОбщийКонтекст_Прочитать("ИдентификаторФормы");
	КартинкаПрикрепитьСсылку = Картинки.КартинкаПрикрепитьСсылку_Base64;
	КартинкаВниманиеЖелтая = Картинки.КартинкаВниманиеЖелтая_Base64;
	КартинкаИсправитьОшибки = Картинки.КартинкаИсправитьОшибки_Base64;
	КартинкаГалочкаВЗеленомКруге = Картинки.КартинкаГалочкаВЗеленомКруге_Base64;
	ПрямоугольникСоСтрелкойЗеленая = Картинки.ПрямоугольникСоСтрелкойЗеленая_Base64;
	СсылкаНаСтраницуПроверкиДоверенностиНаСайтеФНС = Ядро.ПодготовитьСсылкуНаСтраницуПроверкиДоверенностиНаСайтеФНС(
			ДанныеДоверенности);
	ПараметрыГиперссылки = Ядро.Новый_ПараметрыГиперссылкиПроверкиМЧД(
			СсылкаНаСтраницуПроверкиДоверенностиНаСайтеФНС,
			"",
			ДанныеДоверенности.Идентификатор);
	СериализованныеПараметрыГиперссылкиПроверкиМЧД = Ядро.СериализоватьПараметрыГиперссылки(ПараметрыГиперссылки);
	ГиперссылкаПросмотрМЧДФНС = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
			"ОбработатьНажатие_ПроверитьДоверенностьНаСайтеФНС",
			СериализованныеПараметрыГиперссылкиПроверкиМЧД);
	ВладелецСертификата = Ядро.ФамилияИО(ДанныеДоверенности.Представитель.Наименование);
	АдресВременногоХранилища = ПоместитьВоВременноеХранилище(ДанныеДоверенности, ИдентификаторФормы);
	ОткрытьПолномочия = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
			"ОбработатьНажатие_ПосмотретьПолномочияМЧД",
			АдресВременногоХранилища);
	
	Результат = СтрЗаменить(Результат, "%ВладелецДоверенности%", ВладелецСертификата);
	Результат = СтрЗаменить(Результат, "%Организация%", ДанныеДоверенности.Доверитель.Наименование);
	Результат = СтрЗаменить(Результат, "%ДатаДействия%", ДанныеДоверенности.СрокДействия);
	Результат = СтрЗаменить(Результат, "%НомерДоверенности%", ДанныеДоверенности.Идентификатор);
	Результат = СтрЗаменить(Результат, "%ИННДоверителя%", ДанныеДоверенности.Доверитель.ИНН);
	Результат = СтрЗаменить(Результат, "%ИННПредставителя%", ДанныеДоверенности.Представитель.ИНН);
	
	СтатусПроверки = ДанныеДоверенности.СтатусПроверки;
	ДатаПроверки = СтатусПроверки.ДатаПроверки;
	СтруктураОшибок = СтатусПроверки.СтруктураОшибок;
	
	ПараметрЗаменыШаблонПроверкиМЧД = "%ШаблонПроверкиМЧД%";
	
	Если НЕ ЗначениеЗаполнено(СтруктураОшибок) Тогда
		
		Результат = СтрЗаменить(Результат, ПараметрЗаменыШаблонПроверкиМЧД, "");
		
	ИначеЕсли СтруктураОшибок.СписокОшибок.Количество() = 0 Тогда
		
		Результат = СтрЗаменить(Результат, ПараметрЗаменыШаблонПроверкиМЧД, ШаблонДоверенностьПрошлаПроверку + "<br>");
		Результат = СтрЗаменить(Результат, "%ДатаПодтверждения%", Формат(ДатаПроверки, "ДЛФ=DDT"));
		
	Иначе
		
		ШаблонПроверкиМЧД = "";
		
		СписокОшибок = СтруктураОшибок.СписокОшибок;
		Для Каждого СтрокаОшибки Из СписокОшибок Цикл
			
			ШаблонПроверкиМЧД = ШаблонПроверкиМЧД + ШаблонДоверенностьОшибка;
			
			ШаблонПроверкиМЧД = СтрЗаменить(ШаблонПроверкиМЧД, "%ОписаниеОшибки%", СтрокаОшибки.Расшифровка);
			
			Если СтрокаОшибки.Тип = "Error" Тогда
				
				ШаблонПроверкиМЧД = СтрЗаменить(ШаблонПроверкиМЧД, "%ИзображениеОшибки%", "%ИзображениеИсправитьОшибки%");
				
			Иначе
				
				ШаблонПроверкиМЧД = СтрЗаменить(ШаблонПроверкиМЧД, "%ИзображениеОшибки%", "%ИзображениеВниманиеЖелтая%");
				
			КонецЕсли;
			
		КонецЦикла;
		
		Результат = СтрЗаменить(Результат, ПараметрЗаменыШаблонПроверкиМЧД, ШаблонПроверкиМЧД + "<br>");
		
	КонецЕсли;
		
	ПредставлениеГиперссылкиДляСкачиванияДоверенности = HTML_ПредставлениеГиперссылкиДляСкачиванияДоверенности(
			ДанныеДоверенности.ДелегированныеМЧД);
	
	Результат = СтрЗаменить(Результат, "%ПредставлениеСсылкиСкачатьДоверенность%",
			ПредставлениеГиперссылкиДляСкачиванияДоверенности);
	Результат = СтрЗаменить(Результат, "%ГиперссылкаПросмотрМЧДФНС%", ГиперссылкаПросмотрМЧДФНС);
	Результат = СтрЗаменить(Результат, "%ИзображениеПрямоугольникСтрелочка%", ПрямоугольникСоСтрелкойЗеленая);
	Результат = СтрЗаменить(Результат, "%ИзображениеКоннектор%", КартинкаПрикрепитьСсылку);
	Результат = СтрЗаменить(Результат, "%ИзображениеГалочка%", КартинкаГалочкаВЗеленомКруге);
	Результат = СтрЗаменить(Результат, "%ИзображениеИсправитьОшибки%", КартинкаИсправитьОшибки);
	Результат = СтрЗаменить(Результат, "%ИзображениеВниманиеЖелтая%", КартинкаВниманиеЖелтая);
	Результат = СтрЗаменить(Результат, "%ОткрытьПолномочия%", ОткрытьПолномочия);
	
	Возврат Результат;
	
КонецФункции

Функция HTML_ШаблонДоверенностьНеНужна()
	
	Ядро = Модуль_Ядро();
	
	Результат =
		"<div class=""section"">
		|	<div class=""organization"">
		|		<span class=""outgoing"">Доверенность</span>
		|	</div>
		|	<div><img class=""image"" src=""data:image/png;base64,%ИзображениеГалочка%"">
		|		<span class=""verified""> Доверенность не нужна </span>
		|	</div>
		|	<br>
		|</div>
		|<p class=""job_title_date_time"">%ТипОперацииПодписания% %ДатаСобытия%</p>
		|<hr>";
	
	Картинки = Ядро.БиблиотекаКартинок();
	КартинкаГалочкаВЗеленомКруге = Картинки.КартинкаГалочкаВЗеленомКруге_Base64;
	
	Результат = СтрЗаменить(Результат, "%ИзображениеГалочка%", КартинкаГалочкаВЗеленомКруге);
	
	Возврат Результат;
	
КонецФункции

Функция HTML_ШаблонДоверенностьНеПриложена()
	
	Ядро = Модуль_Ядро();
	
	Результат =
		"<div class=""section"">
		|	<div class=""organization"">
		|		<span class=""outgoing"">Доверенность</span>
		|	</div>
		|	<div><img class=""image"" src=""data:image/png;base64,%КартинкаВниманиеЖелтая%"">
		|		<span class=""verified""> Не приложена доверенность к подписи </span>
		|	</div>
		|	<p> %КомментарийКМЧД%</p>
		|</div>
		|<p class=""job_title_date_time"">%ТипОперацииПодписания% %ДатаСобытия%</p>
		|<hr>";
	
	Картинки = Ядро.БиблиотекаКартинок();
	КартинкаВниманиеЖелтая = Картинки.КартинкаВниманиеЖелтая_Base64;
	
	Результат = СтрЗаменить(Результат, "%КартинкаВниманиеЖелтая%", КартинкаВниманиеЖелтая);
	
	Возврат Результат;
	
КонецФункции

Функция HTML_ПредставлениеГиперссылкиДляСкачиванияДоверенности(ДелегированныеМЧД)
	
	Если ЗначениеЗаполнено(ДелегированныеМЧД) Тогда
		Результат = "Скачать цепочку доверенностей (xml  и подписи к ним)";
	Иначе
		Результат = "Скачать доверенность (xml  и подпись к ней)";
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция HTML_ПередовериеМЧД(ДанныеМЧД) Экспорт
	
	Ядро = Модуль_Ядро();
	Картинки = Ядро.БиблиотекаКартинок();
	КартинкаСтрелочкаВправо = Картинки.КартинкаСтрелочкаВправо_Base64;
	ШаблонСтраницы = HTML_ШаблонСтраницыЭлектроннаяПодписьИДоверенность();
	
	ШаблонКартинкиЦепочки = "
		| <span style=""margin: 0 4px;""><img class=""image"" src=""data:image/png;base64,%КартинкаСтрелочкаВправо%""></span>";
	
	ШаблонКартинкиЦепочки = СтрЗаменить(
			ШаблонКартинкиЦепочки,
			"%КартинкаСтрелочкаВправо%",
			КартинкаСтрелочкаВправо);
	
	ШаблонСтрокиЦепочки = "
		| <span>%ЦепочкаПередоверия%</span>";
	
	ПодстрокаЗаменыЦепочки = "%ЦепочкаПередоверия%";
	
	ФиоДоверенного = Ядро.ФамилияИО(ДанныеМЧД.Представитель.Наименование);
	
	МассивЦепочки = Новый Массив;
	
	НовыйЭлементЦепочки = СтрЗаменить(
			ШаблонСтрокиЦепочки,
			ПодстрокаЗаменыЦепочки,
			ДанныеМЧД.Доверитель.Наименование);
	МассивЦепочки.Добавить(НовыйЭлементЦепочки);
	
	НовыйЭлементЦепочки = СтрЗаменить(
			ШаблонСтрокиЦепочки,
			ПодстрокаЗаменыЦепочки,
			ФиоДоверенного);
	МассивЦепочки.Добавить(НовыйЭлементЦепочки);
	
	Для Каждого Элемент Из ДанныеМЧД.ДелегированныеМЧД Цикл
		
		НовыйЭлементЦепочки = СтрЗаменить(
				ШаблонСтрокиЦепочки,
				ПодстрокаЗаменыЦепочки,
				Элемент.Доверитель.Наименование);
		МассивЦепочки.Вставить(0, НовыйЭлементЦепочки);
		
	КонецЦикла;
	
	Цепочка = Ядро.СоединитьСтроку(МассивЦепочки, ШаблонКартинкиЦепочки);
	Цепочка = Цепочка + "<hr>";
	ДобавлятьЦепочкуПередоверия = Ложь;
	 
	МакетДоверенность = HTML_ШаблонДоверенностьПередоверие(ДанныеМЧД);
			
	МакетДоверенность = СтрЗаменить(
			МакетДоверенность, 
			"%ТипОперацииПодписания%", 
			"Целевая доверенность");
			
	ПолныйМакет = Цепочка + МакетДоверенность;
	
	Для Каждого ЭлементМЧД Из ДанныеМЧД.ДелегированныеМЧД Цикл
		
		МакетДоверенность = HTML_ШаблонДоверенностьПередоверие(ЭлементМЧД);
		
		ПолныйМакет = ПолныйМакет + МакетДоверенность;
		
	КонецЦикла;
	
	Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
			ШаблонСтраницы,
			ПолныйМакет);
	
	Результат = СтрЗаменить(Результат, "%ТипОперацииПодписания%", "");
	Результат = СтрЗаменить(Результат, "%ДатаСобытия%", "");
	
	Возврат Результат;
	
КонецФункции

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

Функция HTMLСтраница_Рекомендации(РезультатыПроверки)
	
	Ядро = Модуль_Ядро();
	
	ШаблонТаблицы =
	"<table style='table-layout: fixed; width: 100%; border: 0;'>
	|	<col width=""2%"">
	|	<col width=""70%"">
	|	<col width=""28%"">
	|	%1
	|</table>";
	
	СтрокиHTMLТаблицы = "";
	
	Для Каждого РезультатПроверки Из РезультатыПроверки Цикл
		
		КодПроверки = РезультатПроверки.Представление;
		
		Если КодПроверки = КодПроверки_ОрганизацияНеСопоставлена() Тогда
			
			НоваяСтрока = HTMLСтраница_Рекомендация_ОрганизацияНеСопоставлена();
			
		ИначеЕсли КодПроверки = КодПроверки_КонтрагентаНетВДиадоке() Тогда
			
			НоваяСтрока = HTMLСтраница_Рекомендация_КонтрагентаНетВДиадоке();
			
		ИначеЕсли КодПроверки = КодПроверки_ПроверкаСтатусаКонтрагента() Тогда
			
			НоваяСтрока = HTMLСтраница_Рекомендация_ПроверкаСтатусаКонтрагента(РезультатПроверки.Значение);
			
		ИначеЕсли КодПроверки = КодПроверки_ДокументНеПроведен() Тогда
			
			НоваяСтрока = HTMLСтраница_Рекомендация_ДокументНеПроведен();
			
		ИначеЕсли КодПроверки = КодПроверки_ДокументОтправлен() Тогда
			
			НоваяСтрока = HTMLСтраница_Рекомендация_ДокументОтправлен();
			
		ИначеЕсли КодПроверки = КодПроверки_ИспользуютсяРасширенныеФильтры() Тогда
			
			НоваяСтрока = HTMLСтраница_Рекомендация_ИспользуютсяРасширенныеФильтры();
			
		ИначеЕсли КодПроверки = КодПроверки_ДокументБезСфСНДС() Тогда
			
			НоваяСтрока = HTMLСтраница_Рекомендация_ДокументБезСФСНДС();
			
		Иначе
			
			ШаблонОшибки = НСтр("ru='Неожиданный код результата проверки: %1'");
			ТекстОшибки = Ядро.Общее_ПодставитьПараметрыВСтроку(
				ШаблонОшибки,
				КодПроверки
			);
			
			ВызватьИсключение ТекстОшибки;
			
		КонецЕсли;
		
		СтрокиHTMLТаблицы = СтрокиHTMLТаблицы + НоваяСтрока;
		
	КонецЦикла;
	
	Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
		ШаблонТаблицы,
		СтрокиHTMLТаблицы
	);
	
	Возврат Результат;
	
КонецФункции

Функция HTMLСтраница_Рекомендации_ШаблонСтрокиHTMLТаблицы()
	
	Результат =
	"<tr style='vertical-align: top;'>
	|	<td>
	|		<li>
	|	</td>
	|	<td style='padding-bottom: 1em'>
	|		%1
	|	</td>
	|	<td style='text-align: center'>
	|		%2
	|	</td>
	|</tr>";
	
	Возврат Результат;
	
КонецФункции

Функция HTMLСтраница_Рекомендации_ШаблонЯчейкиСсылка()
	
	Результат =
	"<a href=""%1"">%2</a>";
	
	Возврат Результат;
	
КонецФункции


Функция HTMLСтраница_Рекомендация_ОрганизацияНеСопоставлена()
	
	Ядро = Модуль_Ядро();
	
	СсылкаОповещениеСопоставитьОрганизацию = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения("ОбработатьНажатие_СопоставитьОрганизацию");
	
	Действие = Ядро.Общее_ПодставитьПараметрыВСтроку(
		HTMLСтраница_Рекомендации_ШаблонЯчейкиСсылка(),
		СсылкаОповещениеСопоставитьОрганизацию,
		НСтр("ru='Сопоставить организацию'")
	);
	
	Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
		HTMLСтраница_Рекомендации_ШаблонСтрокиHTMLТаблицы(),
		НСтр("ru='Организация не сопоставлена.'"),
		Действие
	);
	
	Возврат Результат;
	
КонецФункции

Функция HTMLСтраница_Рекомендация_КонтрагентаНетВДиадоке()
	
	Ядро = Модуль_Ядро();
	
	АдресаИнтернетРесурсов = Ядро.Перечисление_АдресаИнтернетРесурсов();
	
	Действие = "";
	
	ТекстРекомендации = Ядро.Общее_ПодставитьПараметрыВСтроку(
		НСтр("ru='Мы не нашли, что контрагент работает в Диадоке. Если контрагент работает через другого оператора, отправьте заявку на настройку <a href=""%1"">роуминга</a>.'"),
		АдресаИнтернетРесурсов.ЗаявкаНаНастройкуРоуминга
	);
	
	Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
		HTMLСтраница_Рекомендации_ШаблонСтрокиHTMLТаблицы(),
		ТекстРекомендации,
		Действие
	);
	
	Возврат Результат;
	
КонецФункции

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

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

Функция HTMLСтраница_Рекомендация_ДокументОтправлен()
	
	Ядро = Модуль_Ядро();
	
	Действие = "";
	
	Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
		HTMLСтраница_Рекомендации_ШаблонСтрокиHTMLТаблицы(),
		НСтр("ru='Проверьте список исходящих. В нем есть документ, созданный на основании выбранного.'"),
		Действие
	);
	
	Возврат Результат;
	
КонецФункции

Функция HTMLСтраница_Рекомендация_ИспользуютсяРасширенныеФильтры()
	
	Ядро = Модуль_Ядро();
	
	Действие = "";
	КартинкаКнопкаРасширенныеФильтры = Ядро.БиблиотекаКартинок().КартинкаКнопкаРасширенныеФильтры_Base64;
	
	КартинкаФильтров = "<img src=""data:image/png;base64," + КартинкаКнопкаРасширенныеФильтры + """>";
	
	ШаблонТекстаРекомендации = НСтр("ru=' На вкладке ""Для отправки"" используются фильтры. Проверьте правильность выставленных значений в расширенных фильтрах %1 и фильтрах на форме.'");
	
	ТекстРекомендации = Ядро.Общее_ПодставитьПараметрыВСтроку(
		ШаблонТекстаРекомендации,
		КартинкаФильтров
	);
	
	Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
		HTMLСтраница_Рекомендации_ШаблонСтрокиHTMLТаблицы(),
		ТекстРекомендации,
		Действие
	);
	
	Возврат Результат;
	
КонецФункции

Функция HTMLСтраница_Рекомендация_ДокументБезСФСНДС()
	
	Ядро = Модуль_Ядро();
	
	СсылкаОповещениеОткрытьДокументУчета =
		Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения("ОбработатьНажатие_ОткрытьДокументУчета");
	
	Действие = Ядро.Общее_ПодставитьПараметрыВСтроку(
		HTMLСтраница_Рекомендации_ШаблонЯчейкиСсылка(),
		СсылкаОповещениеОткрытьДокументУчета,
		НСтр("ru='Открыть документ учета'")
	);
	
	ТекстРекомендации = НСтр(
		"ru='В документе есть НДС, чтобы отправить документ с НДС, создайте на его основании Счет- фактура выданный.
		|<BR>
		| Если требуется отправить электронный документ без НДС - установите в документе 1С ставку ""Без НДС"". '");
	
	Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
		HTMLСтраница_Рекомендации_ШаблонСтрокиHTMLТаблицы(),
		ТекстРекомендации,
		Действие
	);
	
	Возврат Результат;
	
КонецФункции

Функция HTMLСтраница_УниверсальнаяОшибка()
	
	Ядро = Модуль_Ядро();
	
	АдресаИнтернетРесурсов = Ядро.Перечисление_АдресаИнтернетРесурсов();
	
	ШаблонУниверсальнойОшибки = НСтр(
		"ru='Автоматическая проверка не выявила проблем. Обновите список и проверьте документ на вкладке ""Для отправки"".
		|<BR>
		|Если документа нет, выполните более детальную проверку вручную согласно <a href=""%1"">инструкции</a>'"
	);
	
	СсылкаОповещениеОткрытьИнструкцию = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
		"ОбработатьНажатие_ОткрытьИнструкцию",
		АдресаИнтернетРесурсов.Инструкция_ПосмотретьВсеПричины
	);
	
	Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(
		ШаблонУниверсальнойОшибки,
		СсылкаОповещениеОткрытьИнструкцию
	);
	
	Возврат Результат;
	
КонецФункции


Функция КодПроверки_ОрганизацияНеСопоставлена()
	Возврат "ОрганизацияНеСопоставлена";
КонецФункции

Функция КодПроверки_КонтрагентНеСопоставлен()
	Возврат "КонтрагентНеСопоставлен";
КонецФункции

Функция КодПроверки_КонтрагентаНетВДиадоке()
	Возврат "КонтрагентаНетВДиадоке";
КонецФункции

Функция КодПроверки_ПроверкаСтатусаКонтрагента()
	Возврат "СтатусКонтрагентаНеподходящий";
КонецФункции

Функция КодПроверки_ДокументНеПроведен()
	Возврат "ДокументНеПроведен";
КонецФункции

Функция КодПроверки_ДокументОтправлен()
	Возврат "ДокументОтправлен";
КонецФункции

Функция КодПроверки_ИспользуютсяРасширенныеФильтры()
	Возврат "ИспользуютсяРасширенныеФильтры";
КонецФункции

Функция КодПроверки_ДокументБезСфСНДС()
	Возврат "ДокументБезСфСНДС";
КонецФункции

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

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


Функция Картинки_КартинкаСохранить_Base64()
	
	ВсеКартинки = БиблиотекаКартинок();
	Результат = ВсеКартинки["КартинкаСохранить_Base64"];
	
	Возврат Результат;
	
КонецФункции

Функция Картинки_КартинкаКарточкаСообщения_Base64()
	
	ВсеКартинки = БиблиотекаКартинок();
	Результат = ВсеКартинки["КартинкаКарточкаСообщения_Base64"];
	
	Возврат Результат;
	
КонецФункции

Функция Картинки_КартинкаСкачать_Base64()
	
	ВсеКартинки = БиблиотекаКартинок();
	Результат = ВсеКартинки["КартинкаСкачать_Base64"];
	
	Возврат Результат;
	
КонецФункции

Функция Картинки_КартинкаEmail_Base64()
	
	ВсеКартинки = БиблиотекаКартинок();
	Результат = ВсеКартинки["КартинкаEmail_Base64"];
	
	Возврат Результат;
	
КонецФункции

Функция БиблиотекаКартинок() Экспорт
	
	Результат = Новый Структура;
	
	Макет = ПолучитьМакет("БиблиотекаКартинок");
	
	Для Каждого Рисунок Из Макет.Рисунки Цикл
		
		ИмяКартинки = Рисунок.Имя;
		ИмяКартинкиBase64 = ИмяКартинки + "_Base64";
		
		Картинка = Рисунок.Картинка;
		СтрокаBase64 = Base64Строка(Картинка.ПолучитьДвоичныеДанные());
		
		Результат.Вставить(ИмяКартинки, Картинка);
		Результат.Вставить(ИмяКартинкиBase64, СтрокаBase64);
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

Функция ЗаменитьСсылкиНаКликабельные(ИсходнаяСтрока)
	
	Результат = ИсходнаяСтрока;
	
	ЕстьСсылкиВОписании = Найти(ИсходнаяСтрока, "https://") > 0;
	
	Если ЕстьСсылкиВОписании Тогда
		
		Ядро = Модуль_Ядро();
		
		ШаблонСсылкаURL = "<a href=""%1"">%2</a>";
		
		МассивСлов = РазделитьСтрокуЛок(ИсходнаяСтрока, " ", Ложь);
		
		МассивСловСвернутый = Ядро.Общее_СвернутьМассив(МассивСлов);
		
		Для каждого Слово Из МассивСловСвернутый Цикл
			
			ЭтоСсылка = Найти(Слово, "https://") > 0;
			
			Если ЭтоСсылка Тогда
				
				СтрокаДляЗамены = Ядро.Общее_ПодставитьПараметрыВСтроку(ШаблонСсылкаURL, Слово, Слово);
				
				Результат = СтрЗаменить(Результат, Слово, СтрокаДляЗамены);
			
			КонецЕсли;
			
		КонецЦикла;
		
	КонецЕсли;
	
	Возврат Результат;

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

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

Функция СтатусКонтрагента_Ликвидирован()
	Возврат "Ликвидирован";
КонецФункции

Функция СписокОшибок_HTML(СписокОшибок) Экспорт
	
	Шаблоны		 = СписокОшибок_HTMLШаблоны();
	ТелоСписка	 = СписокОшибок_HTMLТело(СписокОшибок);
	Результат	 = Шаблоны.Начало + ТелоСписка + Шаблоны.Окончание;
	
	СписокОшибок_HTMLЗаполнитьКартинки(Результат);
	
	Возврат Результат;
	
КонецФункции

Функция СписокОшибок_HTMLШаблоны()
	
	Ядро = Модуль_Ядро();
	
	ИмяОбработчика = "ОбработчикОповещения_ОчиститьСписокОшибок";
	РезультатОповещения = Неопределено;
	ЗакрыватьФормуСообщения = Истина;
	ОбработчикОчиститьСписокОшибок = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
		ИмяОбработчика,
		РезультатОповещения,
		ЗакрыватьФормуСообщения
	);
	
	Начало =
	"<HTML><HEAD>
	|<style type=text/css>
	|	h6 {
	|		padding-bottom: 0em;
	|	}
	|	div {
	|		padding: 1 4 3 4;
	|		border-style: solid;
	|		border-width: 0;
	|		border-color: #DADAC4;
	|	}
	|	a {
	|		padding-left: 5px;
	|		padding-top: 0em;
	|		padding-bottom: 0.2em;
	|	}
	|	body {
	|		font-family: ""MS Sans Serif"";
	|		margin-right: 0em;
	|		scrollbar-face-color: #FFFBF0;
	|		scrollbar-darkshadow-color: #fff;
	|		scrollbar-highlight-color: #DADAC4;
	|		scrollbar-arrow-color: #708090;
	|		scrollbar-3dlight-color: #fff;
	|		scrollbar-track-color: #FFFBF0;
	|	}
	|	ul {
	|		margin-top: 0em;
	|		margin-bottom: 0.2em;
	|		margin-left: 1.5em;
	|		margin-right: 1.5em;
	|		white-space: pre-wrap;
	|	}
	|	ul.none {
	|		display:none
	|	}
	|	ul.block {
	|		display:block
	|	}
	|	li {
	|		margin: 5px;
	|		padding: 0;
	|	}
	|	li.error {
	|		background: url(data:image/png;base64,[КартинкаОшибка]) no-repeat;
	|		padding-left: 5px;
	|		width: 100%;
	|	}
	|	li.info {
	|		background: url(data:image/png;base64,[КартинкаИнформация]) no-repeat;
	|		padding-left: 5px;
	|		width: 100%;
	|	}
	|	li.warning {
	|		background: url(data:image/png;base64,[КартинкаВажнаяИнформация]) no-repeat;
	|		padding-left: 5px;
	|		width: 100%;
	|	}
	|	li.suberror {
	|		background: url(data:image/png;base64,[КартинкаОшибка]) no-repeat;
	|		margin-left: -10px;
	|		padding-left: 15px;
	|	}
	|	li.subinfo {
	|		background: url(data:image/png;base64,[КартинкаИнформация]) no-repeat;
	|		margin-left: -10px;
	|		padding-left: 15px;
	|	}
	|	li.subinfotable {
	|		margin-left: -10px;
	|		padding-left: 15px;
	|	}
	|	li.subwarning {
	|		background: url(data:image/png;base64,[КартинкаВажнаяИнформация]) no-repeat;
	|		margin-left: -10px;
	|		padding-left: 15px;
	|	}
	|	img {
	|		margin-top: 3px
	|	}
	|	table {
	|		border-width: 1px;
	|		border-spacing: 5px;
	|		border-style: solid;
	|		font-family: ""MS Sans Serif"";
	|		margin-right: 0em;
	|		border-color: #A0A0A4;
	|	}
	|	td {
	|		border-width: 1px;
	|		border-style: solid;
	|		font-size:12;
	|	}
	|	th {
	|		border-width: 1px;
	|		border-style: solid;
	|		background-color: #F0F0F0;
	|		width:60px;
	|		font-size: 12;
	|	}
	|</style>
	|</HEAD>
	|<BODY scroll=auto><FONT face=""MS Sans Serif"" size=1>
	|<a href=""" + ОбработчикОчиститьСписокОшибок + """>Очистить и закрыть</a>
	|";
	
	КнопкиТехПоддержки = Ядро.ЦП_ШаблонHTMLКнопкаТехПоддержки();
	
	Начало = Начало + КнопкиТехПоддержки;
	
	Окончание =
	"</FONT>
	|</BODY>
	|</HTML>";
	
	Результат = Новый Структура;
	Результат.Вставить("Начало",	Начало);
	Результат.Вставить("Окончание",	Окончание);
	
	Возврат Результат;
	
КонецФункции

Функция СписокОшибок_HTMLТело(СписокОшибок, Родитель = Неопределено, КодРодителя = "")
	
	Результат = "";
	Разделитель = Символы.ПС;
	
	Ядро = Модуль_Ядро();
	
	ВидыСообщений = Ядро.СписокОшибок_Перечисление_ВидыСообщенийСпискаОшибок();
	
	Для ИндексСтроки = 0 По СписокОшибок.ВГраница() Цикл
		
		Строка = СписокОшибок[ИндексСтроки];
		ТекстСообщения = Строка.ТекстСообщения;
		
		Если Строка.Количество > 1 Тогда
			ТекстСообщения = ТекстСообщения + " (" + Строка.Количество + ")";
		КонецЕсли;
		
		КодСтроки = КодРодителя + ?(ЗначениеЗаполнено(КодРодителя), "/", "") + Формат(ИндексСтроки, "ЧН=; ЧГ=0");
		
		Если ЗначениеЗаполнено(Строка.Расшифровка) Тогда
			ДобавитьРасшифровкуОшибкиHTML(ТекстСообщения, Строка, КодСтроки);
		КонецЕсли;
		
		Если Строка.ВидСообщения = ВидыСообщений.Раздел Тогда
			
			Результат = Результат + Разделитель + "<h6>" + ТекстСообщения + "</h6>";
			
		Иначе
			
			Если ЗначениеЗаполнено(Родитель) И Родитель.ВидСообщения = ВидыСообщений.Раздел Тогда
					
				Если Строка.ВидСообщения = ВидыСообщений.Информация Тогда
					
					Результат = Результат + Разделитель + "<li class=""info""><div>";
					
				ИначеЕсли Строка.ВидСообщения = ВидыСообщений.ВажнаяИнформация Тогда
					
					Результат = Результат + Разделитель + "<li class=""warning""><div>";
					
				ИначеЕсли Строка.ВидСообщения = ВидыСообщений.Ошибка Тогда
					
					Результат = Результат + Разделитель + "<li class=""error""><div>";
					
				КонецЕсли;
				
			Иначе
				
				Если Строка.ВидСообщения = ВидыСообщений.Информация Тогда
					
					Результат = Результат + Разделитель + "<li class=""subinfo""><div>";
					
				ИначеЕсли Строка.ВидСообщения = ВидыСообщений.ВажнаяИнформация Тогда
					
					Результат = Результат + Разделитель + "<li class=""subwarning""><div>";
					
				ИначеЕсли Строка.ВидСообщения = ВидыСообщений.Ошибка Тогда
					
					Результат = Результат + Разделитель + "<li class=""suberror""><div>";
					
				КонецЕсли;
				
			КонецЕсли;
			
			Результат = Результат + " " + ТекстСообщения + "</div>";
			
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Строка.Строки) Тогда
			
			Результат = Результат + Разделитель + "<ul class=""block"">";
			
			ВложенныйБлок = СписокОшибок_HTMLТело(Строка.Строки, Строка, КодСтроки);
			
			Результат = Результат + ВложенныйБлок + "</ul></li>";
			
		Иначе
			
			Результат = Результат + "</li>";
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

Процедура ДобавитьРасшифровкуОшибкиHTML(ТекстСообщения, Строка, КодСтроки)
	
	Ядро = Модуль_Ядро();
	
	Для ИндексРасшифровки = 0 По Строка.Расшифровка.ВГраница() Цикл
		
		СтрокаРасшифровки = Строка.Расшифровка[ИндексРасшифровки];
		УказательНаРасшифровку = КодСтроки + "/" + Формат(ИндексРасшифровки, "ЧН=; ЧГ=0");
		
		СтрокаОповещения = Ядро.ПараметрыОповещенияВСтрокуHTMLСообщения(
			"ОбработчикОповещения_ПоказатьРасшифровкуСпискаОшибок",
			УказательНаРасшифровку
		);
		
		ШаблонСообщения = НСтр("ru='%1<a href=""%2"">%3</a>'");
		
		ТекстСообщения = Ядро.Общее_ПодставитьПараметрыВСтроку(
			ШаблонСообщения,
			ТекстСообщения,
			СтрокаОповещения,
			СтрокаРасшифровки.Представление
		);
		
	КонецЦикла;
	
КонецПроцедуры

Процедура СписокОшибок_HTMLЗаполнитьКартинки(ТекстСписка)
	
	Картинки = БиблиотекаКартинок();
	КартинкаИнформация = Картинки.КартинкаИнформацияВСпискеОшибок_Base64;
	КартинкаВажнаяИнформация = Картинки.КартинкаВажнаяИнформация_Base64;
	КартинкаОшибка = Картинки.КартинкаОшибка_Base64;
	
	ТекстСписка = СтрЗаменить(ТекстСписка, "[КартинкаОшибка]", КартинкаОшибка);
	ТекстСписка = СтрЗаменить(ТекстСписка, "[КартинкаИнформация]", КартинкаИнформация);
	ТекстСписка = СтрЗаменить(ТекстСписка, "[КартинкаВажнаяИнформация]", КартинкаВажнаяИнформация);
	
КонецПроцедуры

// Возвращает текст HTML с предупреждением об отсутствии прав на формирование УС
//
// Параметры:
//  ЯщикиБезПраваНаФормированиеУС	 - Массив	 - Идентификаторы ящиков, для которых требуются права
// 
// Возвращаемое значение:
//   - Строка
//
Функция HTML_ПредупреждениеОбОтсутствииПравНаФормированиеУС(ЯщикиБезПраваНаФормированиеУС) Экспорт
	
	Ядро = Модуль_Ядро();
	
	ПользователиБезПравНаФормированиеУС = Новый Соответствие;
	
	СтрокиКонтекста = Ядро.КонтекстСеанса_СтрокиКонтекста();
	
	Для Каждого КлючЗначение Из СтрокиКонтекста Цикл
		
		СтрокаКонтекста = КлючЗначение.Значение;
		
		Если ЯщикиБезПраваНаФормированиеУС.Найти(СтрокаКонтекста.Ящик.Идентификатор) = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		ФИО = СтрокаКонтекста.ОписаниеПользователя.ФИО;
		НаименованиеОрганизации = СтрокаКонтекста.Ящик.Организация.Наименование;
		
		Организации = ПользователиБезПравНаФормированиеУС.Получить(ФИО);
		
		Если Организации = Неопределено Тогда
			
			Организации = Ядро.ЗначениеВМассив(НаименованиеОрганизации);
			ПользователиБезПравНаФормированиеУС.Вставить(ФИО, Организации);
			
		Иначе
			Организации.Добавить(НаименованиеОрганизации);
		КонецЕсли;
		
	КонецЦикла;
	
	КоллекцияСообщений = Новый Массив;
	
	ШаблонСтроки = 
	"<p>У пользователя %1 недостаточно прав в %2 %3 для совершения дополнительных действий с документами.</p>";
	
	Для Каждого ПользовательБезПравНаФормированиеУС Из ПользователиБезПравНаФормированиеУС Цикл
		
		ФИО = ПользовательБезПравНаФормированиеУС.Ключ;
		Организации = ПользовательБезПравНаФормированиеУС.Значение;
		
		ОрганизацииСтрокой = Ядро.СоединитьСтроку(Организации, ", ");
		
		Если Организации.Количество() > 1 Тогда
			СклонениеОрганизации = "организациях";
		Иначе
			СклонениеОрганизации = "организации";
		КонецЕсли;
		
		ТекстСообщения = Ядро.Общее_ПодставитьПараметрыВСтроку(ШаблонСтроки, ФИО, СклонениеОрганизации, ОрганизацииСтрокой);
		КоллекцияСообщений.Добавить(ТекстСообщения);
		
	КонецЦикла;
	
	ШаблонГиперссылки = "<a href=""%1"">Инструкция по настройке прав</a>";
	
	АдресаИнтернетРесурсов = Ядро.Перечисление_АдресаИнтернетРесурсов();
	АдресИнтернетРесурса = АдресаИнтернетРесурсов.Инструкция_НастройкаПравСотрудника;
	
	ТекстГиперссылки = Ядро.Общее_ПодставитьПараметрыВСтроку(ШаблонГиперссылки, АдресИнтернетРесурса);
	КоллекцияСообщений.Добавить(ТекстГиперссылки);
	
	ШаблонHTML = HTMLШаблоны_СтандартныйШаблон();
	ТекстТела = Ядро.СоединитьСтроку(КоллекцияСообщений, Символы.ПС);
	
	Результат = Ядро.Общее_ПодставитьПараметрыВСтроку(ШаблонHTML, ТекстТела);
	
	Возврат Результат;
	
КонецФункции

Функция HTMLШаблоны_СтандартныйШаблон()

	Результат = 
		"<html>
		|<head>
		|    <meta content=""text/html; charset=utf-8"" http-equiv=Content-Type>
		|    <style>body {font-family: Arial; font-size: 12pt;}</style>
		|</head>
		|<body>
		|%1
		|</body>
		|</html>";
		
	Возврат Результат;
	
КонецФункции

//}		HTML СООБЩЕНИЯ

//{		ПРЕДУПРЕЖДЕНИЯ ДОКУМЕНТА

Процедура Предупреждения_ДополнитьТекстHTMLОписаниемПредупреждений(ТекстHTML, ЭлементыHTMLТекста)
	
	Ядро = Модуль_Ядро();
	
	Если ТекстHTML = Неопределено Тогда
		
		HTMLШаблоны = Ядро.Документы_ОшибкиВалидации_HTMLШаблоны();
		
		ЭлементыДокументаHTML = Новый Массив;
		ЭлементыДокументаHTML.Добавить(HTMLШаблоны.Начало);
		ЭлементыДокументаHTML.Добавить(HTMLШаблоны.ТаблицаСтилей);
		ЭлементыДокументаHTML.Добавить(HTMLШаблоны.НачалоТела);
		ЭлементыДокументаHTML.Добавить(HTMLШаблоны.Окончание);
		
		ТекстHTML = Ядро.СоединитьСтроку(ЭлементыДокументаHTML);
		
	КонецЕсли;
	
	ПолныйHTMLТекстОшибки = Ядро.СоединитьСтроку(ЭлементыHTMLТекста);
	
	ТегКонецТела = "</body>";
	ТекстHTML = СтрЗаменить(ТекстHTML, ТегКонецТела, ПолныйHTMLТекстОшибки + ТегКонецТела);
	
КонецПроцедуры

Функция Предупреждения_ТекстЗаголовкаРазделаПредупрежденийHTML()
	
	Картинки = БиблиотекаКартинок();
	КартинкаВнимание = Картинки.КартинкаВниманиеЖелтая_Base64;
	
	Результат =
	"<h4 style=""margin-top:30;""><img class=support src=""data:image/png;base64,"
	+ КартинкаВнимание
	+ """ align=""texttop""><b style=""margin-left:10px;"">ПРЕДУПРЕЖДЕНИЕ!</b></h4>";
	
	Возврат Результат;
	
КонецФункции

// ОБРАБОТКА ПРЕДУПРЕЖДЕНИЙ ДОКУМЕНТА

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

//}		ПРЕДУПРЕЖДЕНИЯ ДОКУМЕНТА

//{		ОТБОРЫ

Функция ДиадокЮрФизЛица_ПолучитьСКД(Колонки) Экспорт
		
	Результат	= ПолучитьМакет("МакетОтбора_ДиадокЮрФизЛица");
	Настройки	= Результат.НастройкиПоУмолчанию;	
	НаборДанных	= Результат.НаборыДанных.Найти("НаборДанных_ЮрФизЛица");
	ПоляНабора	= НаборДанных.Поля;
	
	ПоляНабора.Очистить();
	
	Для Каждого Колонка Из Колонки Цикл
		
		НовПоле = ПоляНабора.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
		НовПоле.Поле			= Колонка.Имя;
		НовПоле.ПутьКДанным		= Колонка.Имя;
		НовПоле.Заголовок		= Колонка.Имя;
		НовПоле.ТипЗначения		= Колонка.ТипЗначения;
		
		// теперь особые случаи для нескольких колонок
		Если Колонка.Имя = "Связь1" Или Колонка.Имя = "Связь2" Или Колонка.Имя = "Связь3" Тогда
			
			Попытка
				НовПоле.ТипЗначения	= Модуль_Ядро().Справочники_ОписаниеТипаПоля("Контрагенты");
			Исключение
			КонецПопытки;
					
		КонецЕсли;
		
		Если Колонка.Имя = "Статус" Тогда
			
			СписокСтатусов = Новый СписокЗначений;
			
			СписокСтатусов.Добавить("Работает в Диадок");
			СписокСтатусов.Добавить("Заблокировал меня");
			СписокСтатусов.Добавить("Заблокирован мной");
			
			НовПоле.УстановитьДоступныеЗначения(СписокСтатусов);
			
		КонецЕсли;
		
	КонецЦикла;
	
	ГруппировкаСтрока = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
	ГруппировкаСтрока.Использование = Истина;
	
	ПолеСтрока = ГруппировкаСтрока.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
	ПолеСтрока.Использование = Истина;
	ПолеСтрока.Поле = Новый ПолеКомпоновкиДанных("НомерСтроки");
	
	ВыбранныеПоляДляСтроки = ГруппировкаСтрока.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
	ВыбранныеПоляДляСтроки.Использование = Истина;
	
	ПорядокДляСтроки = ГруппировкаСтрока.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
	ПорядокДляСтроки.Использование = Истина;
		
	Возврат Результат;
	
КонецФункции

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

Процедура ТаблицаОтборов_УстановитьЗначенияКолонок(Колонки, ПоляНабора)
	
	Ядро = Модуль_Ядро();
	
	Для Каждого Колонка Из Колонки Цикл
		
		Если Найти(Колонка.Имя, "ДопРеквизит") > 0 Тогда
			Продолжить;
		КонецЕсли;
		
		НовПоле = ПоляНабора.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
		НовПоле.Поле 			= Колонка.Имя;
		НовПоле.ПутьКДанным 	= Колонка.Имя;
		НовПоле.Заголовок 		= Колонка.Синоним;
		НовПоле.ТипЗначения		= Колонка.Тип;
		
		// теперь особые случаи для нескольких колонок
		Если Колонка.Имя = "Контрагент" Тогда
			
			Попытка
				НовПоле.ТипЗначения	= Ядро.Справочники_ОписаниеТипаПоля("Контрагенты");
			Исключение
				
				Ошибка = ИнформацияОбОшибке();
				ТекстОшибки = ПодробноеПредставлениеОшибки(Ошибка);
				ВидОперации = "ДобавитьФильтрКонтрагент";
				
				ЖурналРегистрации_ЗаписатьПредупреждение(
					Видоперации,
					ТекстОшибки
				);
				
			КонецПопытки;
			
		ИначеЕсли Колонка.Имя = "КонтрагентТипОрганизации" Тогда
			
			Список = Ядро.ТипыОрганизацийКакСписок();
			НовПоле.УстановитьДоступныеЗначения(Список);
			
		ИначеЕсли Колонка.Имя = "Организация" Тогда
			
			Попытка
				НовПоле.ТипЗначения	= Ядро.Справочники_ОписаниеТипаПоля("Организации");
			Исключение
				
				Ошибка = ИнформацияОбОшибке();
				ТекстОшибки = ПодробноеПредставлениеОшибки(Ошибка);
				ВидОперации = "ДобавитьФильтрОрганизация";
				
				ЖурналРегистрации_ЗаписатьПредупреждение(
					ВидОперации,
					ТекстОшибки
				);
				
			КонецПопытки;
			
		ИначеЕсли Колонка.Имя = "ТипДокумента" Тогда
			
			Список = Новый СписокЗначений;
			
			ТипыДокументовAPI = Ядро.ПредопределенныеСписки_ТипыДокументовAPI();
			
			Для Каждого Эл Из ТипыДокументовAPI Цикл
				
				Если ЗначениеЗаполнено(Эл.TypeNamedId)
					И Список.НайтиПоЗначению(Эл.TypeNamedId) = Неопределено Тогда
					
					Список.Добавить(Эл.TypeNamedId, Эл.Title + " (" + Эл.TypeNamedId + ")");
					
				КонецЕсли;
				
			КонецЦикла;
			
			Список.СортироватьПоПредставлению();
			НовПоле.УстановитьДоступныеЗначения(Список);
			
		ИначеЕсли Колонка.Имя = "ВидПакета" Тогда
			
			Список = Новый СписокЗначений;
			
			МассивВидовПакетов = Ядро.МассивВидовПакетов();
			
			Для Каждого Эл Из МассивВидовПакетов Цикл
				Список.Добавить(Эл.Наименование, Эл.Наименование);
			КонецЦикла;
			
			НовПоле.УстановитьДоступныеЗначения(Список);
			
		ИначеЕсли Колонка.Имя = "ВидПакетаID" Тогда
			
			Список = Новый СписокЗначений;
			
			МассивВидовПакетов = Ядро.МассивВидовПакетов();
			
			Для Каждого Эл Из МассивВидовПакетов Цикл
				Список.Добавить(Эл.Идентификатор, Эл.Идентификатор);
			КонецЦикла;
			
			НовПоле.УстановитьДоступныеЗначения(Список);
			
		ИначеЕсли Колонка.Имя = "Статус" Тогда
			
			СтруктураСтатусовДокументов = Ядро.Перечисление_СтатусыДокументов();
			
			Список = СписокЗначенийПоЗначениямСтруктуры(СтруктураСтатусовДокументов);
			
			НовПоле.УстановитьДоступныеЗначения(Список);
			
		ИначеЕсли Колонка.Имя = "ДополнительныйСтатус" Тогда
			
			ДопСтатусыДокументов = Ядро.Перечисление_ДополнительныеСтатусыДокументов();
			
			Список = СписокЗначенийПоЗначениямСтруктуры(ДопСтатусыДокументов);
			
			НовПоле.УстановитьДоступныеЗначения(Список);
			
		ИначеЕсли Колонка.Имя = "ВнешнийСтатус" Тогда
			
			ВнешниеСтатусы = Ядро.Перечисление_СтатусыГИСМТ_Представление();
			
			Список = СписокЗначенийПоЗначениямСтруктуры(ВнешниеСтатусы);
			Список.СортироватьПоЗначению();
			
			НовПоле.УстановитьДоступныеЗначения(Список);
			
		ИначеЕсли Колонка.Имя = "СтатусМЧД" Тогда
			
			ВнешниеСтатусы = Ядро.Перечисление_СтатусыМЧД_Представление();
			
			Список = СписокЗначенийПоЗначениямСтруктуры(ВнешниеСтатусы);
			Список.СортироватьПоЗначению();
			
			НовПоле.УстановитьДоступныеЗначения(Список);
			
		ИначеЕсли Колонка.Имя = "СтатусТЭДО" Тогда
			
			ВнешниеСтатусы = Ядро.Перечисление_СтатусыДТС_Представление();
			
			Список = СписокЗначенийПоЗначениямСтруктуры(ВнешниеСтатусы);
			Список.СортироватьПоЗначению();
			
			НовПоле.УстановитьДоступныеЗначения(Список);
			
		ИначеЕсли Колонка.Имя = "Подразделение" Тогда
			
			Список = Новый СписокЗначений;
			
			СписокОрганизацийПоКонтексту = Ядро.Организации_СписокОрганизацийПоКонтексту();
			
			Для Каждого ДанныеОрганизации Из СписокОрганизацийПоКонтексту Цикл
				
				СписокПодразделений	= Ядро.Подразделения_СписокПодразделений(ДанныеОрганизации);
				
				Для Каждого ДанныеПодразделения Из СписокПодразделений Цикл
					
					Если ОбщийКонтекстКлиентСервер.ИспользуетсяПодсистемаДиадок Тогда
						Список.Добавить(ДанныеПодразделения.Ссылка);
					Иначе
						Список.Добавить(ДанныеПодразделения.Наименование);
					КонецЕсли;
					
				КонецЦикла;
				
			КонецЦикла;
			
			НовПоле.УстановитьДоступныеЗначения(Список);
			
		КонецЕсли;
		
	КонецЦикла;

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

Процедура ТаблицаОтборов_Фильтры_ДопКолонки(КолонкиСписка, ПоляНабора, Режим, МакетОтбора_Документы)
	
	Ядро = Модуль_Ядро();
	
	НастройкиДопКолонок = Ядро.ПодключаемыйМодуль_ОбработатьСобытие(
		"ПолучитьНастройкиДополнительныхКолонокСпискаДокументов",
		Новый Структура("Режим", Режим)
	);
	
	Для Сч = 0 По 4 Цикл
		
		КолонкаСКД = КолонкиСписка["ДопРеквизит" + Формат(Сч + 1, "ЧГ=0")];
		
		НовПоле = ПоляНабора.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
		НовПоле.Поле 			= КолонкаСКД.Имя;
		НовПоле.ПутьКДанным 	= КолонкаСКД.Имя;
		
		Если НастройкиДопКолонок <> Неопределено
			И НастройкиДопКолонок.Количество() > Сч Тогда
			
			НовПоле.Заголовок		= НастройкиДопКолонок[Сч].Заголовок;
			
			Если НастройкиДопКолонок[Сч].Тип <> Неопределено Тогда
				НовПоле.ТипЗначения		= НастройкиДопКолонок[Сч].Тип;
			КонецЕсли;	
			
			Если НастройкиДопКолонок[Сч].ДопустимыеЗначения <> Неопределено Тогда
				НовПоле.УстановитьДоступныеЗначения(НастройкиДопКолонок[Сч].ДопустимыеЗначения);
			КонецЕсли;
			
			// Сразу добавим в интерфейс:
			НовЭлементОтбора = МакетОтбора_Документы.НастройкиПоУмолчанию.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
			НовЭлементОтбора.ВидСравнения	= ВидСравненияКомпоновкиДанных.Равно;
			НовЭлементОтбора.ЛевоеЗначение	= Новый ПолеКомпоновкиДанных(КолонкаСКД.Имя);
			НовЭлементОтбора.Использование	= Ложь;
			
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

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

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

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

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

Процедура ТаблицаОтборов_ПодготовитьТаблицуДляОтбора(ИсходнаяТаблица)
	
	НомерСтроки = 1;
	
	Для Каждого СтрокаТЗ Из ИсходнаяТаблица Цикл
		
		СтрокаТЗ.Видимость = Ложь;
		СтрокаТЗ.НомерСтроки = НомерСтроки;
		
		НомерСтроки = НомерСтроки + 1;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ТаблицаОтборов_УстановитьВидимостьСтрок(ИсходнаяТаблица, ТаблицаПослеОтбора)
	
	Для Каждого СтрокаТЗ Из ТаблицаПослеОтбора Цикл
		ИсходнаяТаблица[СтрокаТЗ.НомерСтроки - 1].Видимость = Истина;
	КонецЦикла;

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

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

Процедура УстановитьДляСпискаДокументовИндексИконкиПакета(КэшСпискаДокументов)
	
	КэшСпискаДокументов.ЗаполнитьЗначения(0, "ИндексИконкиПакета");
	
	ОтборСтрок = Новый Структура("Видимость", Истина);
	ВидимыеСтрокиСписка = КэшСпискаДокументов.НайтиСтроки(ОтборСтрок);
	
	ТекущийПакет = Неопределено;
	ИндексПервойСтрокиПакета = Неопределено;
	ИндексПоследнейСтрокиПакета = Неопределено;
	
	Для Индекс = 0 По ВидимыеСтрокиСписка.ВГраница() Цикл
		
		СтрокаСписка = ВидимыеСтрокиСписка[Индекс]; 
		
		Если ЗначениеЗаполнено(СтрокаСписка.Пакет) Тогда
			ИдентификаторПакета = СтрокаСписка.Пакет;
		Иначе
			ИдентификаторПакета = СтрокаСписка.LetterId;
		КонецЕсли;
		
		Если ТекущийПакет <> ИдентификаторПакета Тогда
			
			Если ИндексПервойСтрокиПакета <> ИндексПоследнейСтрокиПакета Тогда
				
				ВидимыеСтрокиСписка[ИндексПервойСтрокиПакета].ИндексИконкиПакета = 1;
				ВидимыеСтрокиСписка[ИндексПоследнейСтрокиПакета].ИндексИконкиПакета = 3;
				
			КонецЕсли;
			
			ТекущийПакет = ИдентификаторПакета;
			
			ИндексПервойСтрокиПакета = Индекс;
			ИндексПоследнейСтрокиПакета = ИндексПервойСтрокиПакета;
			
		Иначе
			
			ИндексПоследнейСтрокиПакета = Индекс;
			СтрокаСписка.ИндексИконкиПакета = 2;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Если ИндексПервойСтрокиПакета <> ИндексПоследнейСтрокиПакета Тогда
		
		ВидимыеСтрокиСписка[ИндексПервойСтрокиПакета].ИндексИконкиПакета = 1;
		ВидимыеСтрокиСписка[ИндексПоследнейСтрокиПакета].ИндексИконкиПакета = 3;
		
	КонецЕсли;
	
КонецПроцедуры

Процедура УстановитьДляСпискаДокументовИндексИконкиСтроки(КэшСпискаДокументов)
	
	КэшСпискаДокументов.ЗаполнитьЗначения(0, "ИндексИконкиСтроки");
	
	ОтборСтрок = Новый Структура("Видимость", Истина);
	ВидимыеСтрокиСписка = КэшСпискаДокументов.НайтиСтроки(ОтборСтрок);
	
	Для Индекс = 0 По ВидимыеСтрокиСписка.ВГраница() Цикл
		
		СтрокаСписка = ВидимыеСтрокиСписка[Индекс];
		Если СтрокаСписка.ЭтоЧерновик Тогда
			СтрокаСписка.ИндексИконкиСтроки = 1;
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

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

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

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

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

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

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


//{		СПИСОК ДОКУМЕНТОВ

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

// Возвращает список для выбора количества строк,
// которое должно быть отображено на странице в табличной части "СписокДокументов".
//
// Возвращаемое значение: 
//   СписокЗначений - содержит числа с количеством строк.
//
Функция СписокДокументов_СписокВыбораРазмераСтраницы() Экспорт 
	
	Результат = Новый СписокЗначений;
	
	Результат.Добавить(100	, Строка(100)	+ " строк");
	Результат.Добавить(200	, Строка(200)	+ " строк");
	Результат.Добавить(500	, Строка(500)	+ " строк");
	Результат.Добавить(1000	, Строка(1000)	+ " строк");
	Результат.Добавить(10000, Строка(10000)	+ " строк");
	
	Возврат Результат;
	
КонецФункции

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

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

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

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

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

Процедура СписокДокументов_ОбновитьСтроки(ТаблицаСпискаДокументов, КэшСпискаДокументов, ОтборПоПакету, РежимОтображения)
	
	ИдентификаторПакета	 = СвойствоСтруктуры(ОтборПоПакету, "ИдентификаторПакета");
	
	Если НЕ ЗначениеЗаполнено(ИдентификаторПакета) Тогда
		Возврат;
	КонецЕсли;
	
	КлючСтроки	 = XMLСтрока(ИдентификаторПакета);
	DocumentID	 = ОтборПоПакету.DocumentID;
	
	ПоискПоДокументу = РежимОтображения <> РежимыОтображения().ДляОтправки И ЗначениеЗаполнено(DocumentID);
	
	ОтборНовогоСписка = Новый Структура;
	Если ПоискПоДокументу Тогда
		ОтборНовогоСписка.Вставить("DocumentID", DocumentID);
	Иначе
		ОтборНовогоСписка.Вставить("LetterId", КлючСтроки);
	КонецЕсли; 
	
	ОтборТекущегоСписка = Новый Структура;
	Если ПоискПоДокументу Тогда
		ОтборТекущегоСписка.Вставить("DocumentID", DocumentID);
	Иначе
		ОтборТекущегоСписка.Вставить("Ключ"	, КлючСтроки);
	КонецЕсли; 
	
	СтрокиНовогоСписка = КэшСпискаДокументов.НайтиСтроки(ОтборНовогоСписка);
	Если СтрокиНовогоСписка.Количество() > 0 Тогда
		СтрокаИзНовогоСписка = СтрокиНовогоСписка[0];
	КонецЕсли;
	
	СтрокиТекущегоСписка = ТаблицаСпискаДокументов.НайтиСтроки(ОтборТекущегоСписка);
	Если СтрокиТекущегоСписка.Количество() > 0 Тогда
		
		СтрокаИзТекущегоСписка = СтрокиТекущегоСписка[0];
		
		Если СтрокаИзНовогоСписка = Неопределено Тогда
			
			ИндексСтроки = ТаблицаСпискаДокументов.Индекс(СтрокаИзТекущегоСписка);
			ТаблицаСпискаДокументов.Удалить(ИндексСтроки);
			
		Иначе
			
			ЗаполнитьЗначенияСвойств(СтрокаИзТекущегоСписка, СтрокаИзНовогоСписка, , "НомерСтроки");
			
		КонецЕсли;
		
	ИначеЕсли СтрокаИзНовогоСписка <> Неопределено Тогда
		
		НоваяСтрока = ТаблицаСпискаДокументов.Вставить(0);
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИзНовогоСписка);
		
		Если ТипЗнч(ТаблицаСпискаДокументов) = Тип("ТаблицаЗначений") Тогда
			Для каждого СтрокаСписка Из ТаблицаСпискаДокументов Цикл
				СтрокаСписка.НомерСтроки = ТаблицаСпискаДокументов.Индекс(СтрокаСписка) + 1;
			КонецЦикла;
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

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

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

		Модуль_Ядро().СписокДокументов_ДобавитьДокументыВПакетыНаОтправку(СтрокаСпискаДокументов);
		
	КонецЦикла;
	
КонецПроцедуры

//}		СПИСОК ДОКУМЕНТОВ

//{		ДОКУМЕНТЫ

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

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

Функция HTMLСобытияМЧД_СформироватьHTMLСтраницуПоСобытиямМЧД(СобытияМЧД) Экспорт
	
	ОболочкаДокументаHTML = ЭтотОбъект.ПолучитьМакет("HTML_СобытияМЧД");
	ДокументHTML = ОболочкаДокументаHTML.ПолучитьДокументHTML();
	
	Для ИндексСтроки = 0 По СобытияМЧД.Количество()-1 Цикл
		
		СтрокаСобытия = СобытияМЧД.Получить(ИндексСтроки);
		
		СтрокаТаблицыHTML = HTMLСобытияМЧД_ПолучитьСтрокуТаблицыHTML(ДокументHTML, СтрокаСобытия, ИндексСтроки);
		
		HTMLСобытияМЧД_ЗаполнитьСведенияОСобытииВСтрокеТаблицыHTML(СтрокаТаблицыHTML, СтрокаСобытия);
		
		HTMLСобытияМЧД_ЗаполнитьСсылкиВСтрокеТаблицыHTML(СтрокаТаблицыHTML, СтрокаСобытия, ИндексСтроки);
		
	КонецЦикла;
	
	HTMLСобытияМЧД_УдалитьШаблоныСтрокТаблицыHTML(ДокументHTML);
	
	Результат = ДокументHTMLвТекстHTML(ДокументHTML);
	
	Возврат Результат;	
	
КонецФункции

Функция HTMLСобытияМЧД_ПолучитьСтрокуТаблицыHTML(ДокументHTML, СтрокаСобытия, ИндексСтрокиСобытия)
	
	ТаблицаHTML = ДокументHTML.ПолучитьЭлементПоИдентификатору("table");
	
	Если СтрокаСобытия.ЕстьОшибкаПроверкиМЧД Тогда
		СтрокаТаблицыHTML = ДокументHTML.ПолучитьЭлементПоИдентификатору("raw_table_error");
	Иначе
		СтрокаТаблицыHTML = ДокументHTML.ПолучитьЭлементПоИдентификатору("raw_table");	
	КонецЕсли;
	
	НоваяСтрокаТаблицыHTML = СтрокаТаблицыHTML.КлонироватьУзел(Истина);
	HTMLСобытияМЧД_УстановитьИдентификаторСтрокиТаблицыHTML(НоваяСтрокаТаблицыHTML, ИндексСтрокиСобытия);
	
	ТаблицаHTML.ДобавитьДочерний(НоваяСтрокаТаблицыHTML);
	
	Возврат НоваяСтрокаТаблицыHTML;
	
КонецФункции

Процедура HTMLСобытияМЧД_ЗаполнитьСведенияОСобытииВСтрокеТаблицыHTML(СтрокаТаблицыHTML, СтрокаСобытия)
	
	ЭлементыHTMLСтроки = СтрокаТаблицыHTML.ПолучитьЭлементыПоИмени("p");
	Для Каждого ЭлементHTML Из ЭлементыHTMLСтроки Цикл
		
		Если ЭлементHTML.Заголовок = "Доверенность" Тогда
			ЭлементHTML.ТекстовоеСодержимое = HTMLСобытияМЧД_СформироватьПредставлениеДоверенности(СтрокаСобытия.ИнформацияОДоверенности);
		ИначеЕсли ЭлементHTML.Заголовок = "Срок действия" Тогда
			ЭлементHTML.ТекстовоеСодержимое = Формат(СтрокаСобытия.ИнформацияОДоверенности.СрокДействия, "ДФ='''До'' dd.MM.yyyy'; ДП=");
		ИначеЕсли ЭлементHTML.Заголовок = "Событие" Тогда
			ЭлементHTML.ТекстовоеСодержимое = HTMLСобытияМЧД_СформироватьПредставлениеСобытия(СтрокаСобытия.Описание, СтрокаСобытия.Дата);
		КонецЕсли;
		
	КонецЦикла;
	
	HTMLСобытияМЧД_ЗаполнитьСтатусПроверкиМЧДСтрокиТаблицыHTML(
		СтрокаТаблицыHTML,
		СтрокаСобытия.ОписанияПроверокМЧД,
		СтрокаСобытия.ЕстьОшибкаПроверкиМЧД);
	
КонецПроцедуры

Процедура HTMLСобытияМЧД_ЗаполнитьСсылкиВСтрокеТаблицыHTML(СтрокаТаблицыHTML, СтрокаСобытия, ИндексСтрокиСобытия)
	
	Модуль_Ядро = Модуль_Ядро();
	
	ИндексСтроки = Формат(ИндексСтрокиСобытия, "ЧН=0; ЧГ=0");
	
	ЭлементыHTML = СтрокаТаблицыHTML.ПолучитьЭлементыПоИмени("a");
	Для Каждого ЭлементHTML Из ЭлементыHTML Цикл
		
		Если ЭлементHTML.Идентификатор = "СкачатьДоверенность" Тогда
			
			ВидимостьСсылки = (СтрокаСобытия.МЧДПереданаФайлом И НЕ СтрокаСобытия.ЕстьДелегированныеМЧД);	
			
		ИначеЕсли ЭлементHTML.Идентификатор = "ПосмотретьДоверенностьВЦепочкеПередоверия" Тогда
			
			ВидимостьСсылки = СтрокаСобытия.ЕстьДелегированныеМЧД;
			
		ИначеЕсли ЭлементHTML.Идентификатор = "СкачатьЦепочкуДоверенностей" Тогда
			
			ВидимостьСсылки = (СтрокаСобытия.МЧДПереданаФайлом И СтрокаСобытия.ЕстьДелегированныеМЧД);	
			
		Иначе
			ВидимостьСсылки = Истина;	
		КонецЕсли;
		
		Если НЕ ВидимостьСсылки Тогда
			HTMLСобытияМЧД_СкрытьЭлементHTML(ЭлементHTML)
		КонецЕсли;
		
		ЗначениеСсылки = ЭлементHTML.ПолучитьАтрибут("href");
		ДобавитьПараметрВСсылкуHTML(ЗначениеСсылки, "raw_id", ИндексСтроки);
		ЭлементHTML.УстановитьАтрибут("href", ЗначениеСсылки);
		
	КонецЦикла;
	
КонецПроцедуры

// Устанавливает элементу HTML признак скрытого. На старых платформах
// через назначение имени класса CSS, т.к. атрибут hidden там не работает
//
Процедура HTMLСобытияМЧД_СкрытьЭлементHTML(ЭлементHTML)
	
	Если ПриложениеСтаршеВерсии("8.3.14") Тогда
		ЭлементHTML.ИмяКласса = "hidden";
	Иначе
		ЭлементHTML.УстановитьАтрибут("hidden", "True");
	КонецЕсли;
	
КонецПроцедуры

Процедура HTMLСобытияМЧД_УстановитьИдентификаторСтрокиТаблицыHTML(СтрокаТаблицыHTML, ИндексСтрокиСобытия)
	
	СтрокаТаблицыHTML.Идентификатор = "raw_" + Формат(ИндексСтрокиСобытия, "ЧН=0; ЧГ=0");
	
КонецПроцедуры

Функция HTMLСобытияМЧД_СформироватьПредставлениеДоверенности(ИнформацияОДоверенности)

	Модуль_Ядро = Модуль_Ядро();
	
	Идентификатор = ИнформацияОДоверенности.Идентификатор;
	Представитель = ИнформацияОДоверенности.Представитель.Наименование;
	Доверитель = ИнформацияОДоверенности.Доверитель.Наименование;
	ПредставительИНН = СвойствоСтруктуры(ИнформацияОДоверенности.Представитель, "ИНН", """");
	ДоверительИНН = СвойствоСтруктуры(ИнформацияОДоверенности.Доверитель, "ИНН", """");

	Если ЗначениеЗаполнено(ПредставительИНН) Тогда
		ШаблонСтроки = "%1 (%2)";
		Представитель = Модуль_Ядро.Общее_ПодставитьПараметрыВСтроку(ШаблонСтроки, Представитель, ПредставительИНН);
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ДоверительИНН) Тогда
		ШаблонСтроки = "%1 (%2)";
		Доверитель = Модуль_Ядро.Общее_ПодставитьПараметрыВСтроку(ШаблонСтроки, Доверитель, ДоверительИНН);
	КонецЕсли;
	
	Результат = Модуль_Ядро.Общее_ПодставитьПараметрыВСтроку(
		"Доверенность %1, %2, %3",
		Идентификатор,
		Представитель,
		Доверитель);
		
	Возврат Результат;

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

Функция HTMLСобытияМЧД_СформироватьПредставлениеСобытия(Описание, ДатаСобытия)

	Результат = Описание;
	
	Если ЗначениеЗаполнено(Результат) И ЗначениеЗаполнено(ДатаСобытия) Тогда
		СтрокаПредставленияДаты = Формат(ДатаСобытия, "ДФ='dd.MM.yy ""в"" ЧЧ:мм'");
		Результат = Результат + " "+ СтрокаПредставленияДаты;
	КонецЕсли;
	
	Возврат Результат;

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

Процедура HTMLСобытияМЧД_ЗаполнитьСтатусПроверкиМЧДСтрокиТаблицыHTML(СтрокаТаблицыHTML, ОписанияПроверокМЧД, ЕстьОшибкаПроверкиМЧД)
	
	ЭлементыHTMLСписки = СтрокаТаблицыHTML.ПолучитьЭлементыПоИмени("ul");
	
	СписокHTMLРезультатыПроверкиМЧД = ЭлементыHTMLСписки[0]; 
	СписокHTMLРезультатыПроверкиМЧД.ПервыйДочерний.ТекстовоеСодержимое = "";
	
	МаркерСписка = ?(ОписанияПроверокМЧД.Количество() > 1, "- ", "");
	
	Для ИндексСтроки = 0 По ОписанияПроверокМЧД.ВГраница() Цикл
		
		Если ИндексСтроки = 0 Тогда
			НовыйЭлементСпискаHTML = СписокHTMLРезультатыПроверкиМЧД.ПервыйДочерний;
		Иначе
			НовыйЭлементСпискаHTML = СписокHTMLРезультатыПроверкиМЧД.ПервыйДочерний.КлонироватьУзел(Истина);
			СписокHTMLРезультатыПроверкиМЧД.ДобавитьДочерний(НовыйЭлементСпискаHTML);
		КонецЕсли;
		
		НовыйЭлементСпискаHTML.ТекстовоеСодержимое = МаркерСписка + ОписанияПроверокМЧД[ИндексСтроки].Расшифровка;
		
		Если ЕстьОшибкаПроверкиМЧД Тогда
			НовыйЭлементСпискаHTML.ИмяКласса = "validations_error_list"	
		КонецЕсли;
		
	КонецЦикла;	
	
КонецПроцедуры

Процедура HTMLСобытияМЧД_УдалитьШаблоныСтрокТаблицыHTML(ДокументHTML)

	ТаблицаHTML = ДокументHTML.ПолучитьЭлементПоИдентификатору("table");
	ТаблицаHTML.УдалитьСтроку(0);
	ТаблицаHTML.УдалитьСтроку(0);
	
КонецПроцедуры

Функция ДокументHTMLвТекстHTML(ДокументHTML)
	
	ЗапиcьHTML = Новый ЗаписьHTML;
	ЗапиcьHTML.УстановитьСтроку();
	
	ЗаписьDOM = Новый ЗаписьDOM;
	ЗаписьDOM.Записать(ДокументHTML, ЗапиcьHTML);
	
	Результат = ЗапиcьHTML.Закрыть();

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

Процедура ДобавитьПараметрВСсылкуHTML(Ссылка, ИмяПараметра, Значение)
	
	Если Найти(Ссылка, "?") > 0 Тогда
		РазделительПараметров = "&";
	Иначе
		РазделительПараметров = "?";
	КонецЕсли;
	
	Ссылка = Ссылка + РазделительПараметров + ИмяПараметра + "=" + Значение;
	
КонецПроцедуры

//}		ДОКУМЕНТЫ

//{ ПОДПИСКИ И ОПЛАТА

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

		HTMLПодпискиИОплата_УдалитьИнформациюОбОтсутствииПредложенийHTML(ДокументHTML);
			
	КонецЕсли;
	
	КоличествоШаблоновМакетаHTML = 14;
	HTMLПодпискиИОплата_УдалитьШаблоныСтрокТаблицыHTML(ДокументHTML, КоличествоШаблоновМакетаHTML);
	
	Результат = ДокументHTMLвТекстHTML(ДокументHTML);
	
	Возврат Результат;	
	
КонецФункции

Функция HTMLПодпискиИОплата_ПолучитьСтрокуЗаголовкаОрганизацииТаблицыHTML(ДокументHTML, ДанныеПредложенияПодписки)
	
	ТаблицаHTML = ДокументHTML.ПолучитьЭлементПоИдентификатору("table");
	
	СтрокаТаблицыHTML = ДокументHTML.ПолучитьЭлементПоИдентификатору("raw_box");
	
	НоваяСтрокаТаблицыHTML = СтрокаТаблицыHTML.КлонироватьУзел(Истина);
	НоваяСтрокаТаблицыHTML.Идентификатор = "raw_" + ДанныеПредложенияПодписки.BoxId;
	
	ТаблицаHTML.ДобавитьДочерний(НоваяСтрокаТаблицыHTML);
	
	Возврат НоваяСтрокаТаблицыHTML;
	
КонецФункции

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

Функция HTMLПодпискиИОплата_СтрокаТаблицыHTML(ДокументHTML, ДанныеПредложенияПодписки, ИндексПредложения)
	
	ТаблицаHTML = ДокументHTML.ПолучитьЭлементПоИдентификатору("table");
	
	СтрокаТаблицыHTML = HTMLПодпискиИОплата_ШаблонСтрокиТаблицыHTML(ДокументHTML, ДанныеПредложенияПодписки);
	
	НоваяСтрокаТаблицыHTML = СтрокаТаблицыHTML.КлонироватьУзел(Истина);
	НоваяСтрокаТаблицыHTML.Идентификатор = "raw_" + Формат(ИндексПредложения, "ЧН=0; ЧГ=0");
	
	ТаблицаHTML.ДобавитьДочерний(НоваяСтрокаТаблицыHTML);
	
	Возврат НоваяСтрокаТаблицыHTML;
	
КонецФункции

Функция HTMLПодпискиИОплата_ШаблонСтрокиТаблицыHTML(ДокументHTML, ДанныеПредложенияПодписки)
	
	Если ДанныеПредложенияПодписки.ЭтоПредложение Тогда
		
		СценарийПредложения = ДанныеПредложенияПодписки.СценарийПредложения;
		
		Если ЗначениеЗаполнено(СценарийПредложения) Тогда
			
			Результат = ДокументHTML.ПолучитьЭлементПоИдентификатору(СценарийПредложения);
			
			Если Результат <> Неопределено Тогда
				Возврат Результат;
			КонецЕсли;
			
		КонецЕсли;
		
		Если ДанныеПредложенияПодписки.ЭтоПредложениеВажное Тогда
			
			ИдентификаторШаблонаHTML = "raw_offer_critical";
			
		ИначеЕсли ЗначениеЗаполнено(ДанныеПредложенияПодписки.Описание) Тогда
			
			ИдентификаторШаблонаHTML = "raw_offer_warning";
			
		Иначе
			
			ИдентификаторШаблонаHTML = "raw_offer";
			
		КонецЕсли;
		
	Иначе
		
		ИдентификаторШаблонаHTML = "raw_subscription";
		
		Если ЗначениеЗаполнено(ДанныеПредложенияПодписки.РазметкаГруппировки) Тогда
			 ИдентификаторШаблонаHTML = ИдентификаторШаблонаHTML + ДанныеПредложенияПодписки.РазметкаГруппировки;
		КонецЕсли;
		
	КонецЕсли;
	
	Результат = ДокументHTML.ПолучитьЭлементПоИдентификатору(ИдентификаторШаблонаHTML);
	
	Возврат Результат;
	
КонецФункции

Процедура HTMLПодпискиИОплата_ЗаполнитьПредложениеВСтрокеТаблицыHTML(СтрокаТаблицыHTML, ДанныеПредложенияПодписки)
	
	ЭлементыHTMLСтроки = СтрокаТаблицыHTML.ПолучитьЭлементыПоИмени("p");
	
	Для Каждого ЭлементHTML Из ЭлементыHTMLСтроки Цикл
		
		Если ЭлементHTML.Заголовок = "Представление" Тогда
			
			ЭлементHTML.ТекстовоеСодержимое = ДанныеПредложенияПодписки.Представление;
			
		ИначеЕсли ЭлементHTML.Заголовок = "Описание" Тогда
			
			ЭлементHTML.ТекстовоеСодержимое = ДанныеПредложенияПодписки.Описание;
			
		ИначеЕсли ЭлементHTML.Заголовок = "СрокДействия" Тогда
			
			ДатаОкончания = ДанныеПредложенияПодписки.ДатаОкончания;
			
			Если ЗначениеЗаполнено(ДатаОкончания) Тогда
				ЭлементHTML.ТекстовоеСодержимое = "До" + Символы.НПП + Формат(ДатаОкончания, "ДФ=dd.MM.yyyy");
			Иначе
				ЭлементHTML.ТекстовоеСодержимое = "";
			КонецЕсли;
			
		Иначе	
			Продолжить;
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура HTMLПодпискиИОплата_ЗаполнитьСсылкиВСтрокеТаблицыHTML(СтрокаТаблицыHTML, ДанныеПредложенияПодписки, Индекс)
	
	ИндексСтроки = Формат(Индекс, "ЧН=0; ЧГ=0");
	
	ЭлементыHTML = СтрокаТаблицыHTML.ПолучитьЭлементыПоИмени("a");
	
	Для Каждого ЭлементHTML Из ЭлементыHTML Цикл
		
		Если ЭлементHTML.Идентификатор = "buy" Тогда
			ЭлементHTML.ТекстовоеСодержимое = ДанныеПредложенияПодписки.Действие;
		КонецЕсли;
		
		ЗначениеСсылки = ЭлементHTML.ПолучитьАтрибут("href");
		ДобавитьПараметрВСсылкуHTML(ЗначениеСсылки, "raw_id", Индекс);
		ЭлементHTML.УстановитьАтрибут("href", ЗначениеСсылки);
		
	КонецЦикла;
	
КонецПроцедуры

Процедура HTMLПодпискиИОплата_УдалитьИнформациюОбОтсутствииПредложенийHTML(ДокументHTML)

	ИнформацияПоДругимПредложениям = ДокументHTML.ПолучитьЭлементПоИдентификатору("no_offers");
	ИнформацияПоДругимПредложениям.ТекстовоеСодержимое = "";
	
КонецПроцедуры

Процедура HTMLПодпискиИОплата_УдалитьШаблоныСтрокТаблицыHTML(ДокументHTML, КоличествоШаблонов)

	ТаблицаHTML = ДокументHTML.ПолучитьЭлементПоИдентификатору("table");
	
	Для й = 1 По КоличествоШаблонов Цикл
		ТаблицаHTML.УдалитьСтроку(0);
	КонецЦикла;

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

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

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

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

Функция ПредложенияДляПокупки_КлючНастроекРекомендацияПокупкиПлагинов()
	
	Результат = "БаннерРекомендации_ПокупкаПлагинов_Закрыт";
	
	Возврат Результат;
	
КонецФункции

// Записывает дату закрытия пользователем баннера рекомендации покупки пакета документов
//
Процедура ПредложенияДляПокупки_ЗаписатьДатуЗакрытияРекомендацииПокупкиПакетаДокументов() Экспорт
	
	КлючНастроек = ПредложенияДляПокупки_КлючНастроекРекомендацияПокупкиПакетаДокументов();
	
	ЗначениеНастройки = ТекущаяДатаСеанса();
	
	ХранилищеОбщихНастроек_Сохранить(КлючНастроек, ЗначениеНастройки);
	
КонецПроцедуры

Функция ПредложенияДляПокупки_КлючНастроекРекомендацияПокупкиПакетаДокументов()
	
	Результат = "БаннерРекомендации_ПокупкаПакетаДокументов_Закрыт";
	
	Возврат Результат;
	
КонецФункции

//} ПОДПИСКИ И ОПЛАТА

//{ ПОДКЛЮЧЕНИЕ ВО ВНЕШНИЕ ОБРАБОТКИ

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

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

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

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

Процедура ДополнитьПараметрыРегистрацииРазрешениямиВнешнейОбработки(ПараметрыРегистрации)

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

Процедура ЖурналРегистрации_ЗаписатьПредупреждение(ВидОперации, Комментарий)
	
	СобытиеЖР = "Диадок." + ВидОперации;
	
	ЖурналРегистрации_ЗаписатьСобытие(СобытиеЖР, УровеньЖурналаРегистрации.Предупреждение, Комментарий);
	
КонецПроцедуры

Процедура ЖурналРегистрации_ЗаписатьОшибку(ВидОперации, Комментарий)
	
	СобытиеЖР = "Диадок." + ВидОперации;
	
	ЖурналРегистрации_ЗаписатьСобытие(СобытиеЖР, УровеньЖурналаРегистрации.Ошибка, Комментарий);
	
КонецПроцедуры

Процедура ЖурналРегистрации_ЗаписатьСобытие(СобытиеЖР, УровеньСобытия, Комментарий)
	
	ЗаписьЖурналаРегистрации(
		СобытиеЖР,
		УровеньСобытия,
		Неопределено,
		Неопределено,
		Комментарий
	);
	
КонецПроцедуры

//} ПОДКЛЮЧЕНИЕ ВО ВНЕШНИЕ ОБРАБОТКИ


// { ВЫГРУЗКА ВЛОЖЕННЫХ ОБРАБОТОК ДЛЯ ОТЛАДКИ

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

Функция КаталогиВложенныхОбработокДляОтладки()
	
	Результат = Новый Соответствие;
	
	Для Каждого Макет Из Метаданные().Макеты Цикл
		
		ИмяМакета = Макет.Имя;
		
		Если Лев(ИмяМакета, 12) = "КонтурДиадок" Тогда
			
			ИмяФайла = ИмяМакета + ".epf";
			ПутьКФайлу = ПутьКФайлуВКаталогеТекущейОбработки(ИмяФайла);
			
			Результат.Вставить(ИмяМакета, ПутьКФайлу);
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

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

// } ВЫГРУЗКА ВЛОЖЕННЫХ ОБРАБОТОК ДЛЯ ОТЛАДКИ


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

Процедура ВыполнитьРегламентныеДействия(ПараметрыВыполненияКоманды)
	
	ИнициализироватьОбщийКонтекст();
	
	Модуль_Ядро = Модуль_Ядро();

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

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

// { МЧД

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

// Сохраняет настройку пользователя отображения предупреждения по МЧД
//
// Параметры:
//  ЗначениеНастройки - Булево - значение настройки
//
Процедура НастройкиПользователяУстановить_НеПоказыватьПредупрежденияПоМЧД(ЗначениеНастройки) Экспорт
	
	КлючНастройки = "НастройкаДоверенности_БольшеНеПоказывать";
	ХранилищеОбщихНастроек_Сохранить(КлючНастройки, ЗначениеНастройки);
	
КонецПроцедуры

// BSLLS:CognitiveComplexity-off
// BSLLS:MissingReturnedValueDescription-off
// BSLLS:MissingParameterDescription-off
Функция МЧД_ПредставлениеСведенийОДоверенности_HTML(КонтрактМЧД) Экспорт
	// BSLLS:MissingReturnedValueDescription-on
	// BSLLS:MissingParameterDescription-on
	Модуль_Ядро = Модуль_Ядро();
	
	ТабДокумент = Новый ТабличныйДокумент;
	
	Макет = ПолучитьМакет("СведенияОбМЧД_mxl");
	
	ОбластьРеквизиты = Макет.ПолучитьОбласть("Реквизиты");
	
	ПараметрыОбласти = ОбластьРеквизиты.Параметры;
	
	ПараметрыОбласти.РегистрационныйНомер = КонтрактМЧД.Идентификатор;
	ПараметрыОбласти.ДоверительНаименование = КонтрактМЧД.Доверитель.Наименование;
	ПараметрыОбласти.ДоверительИННКПП = ПредставлениеИННКПП(КонтрактМЧД.Доверитель);
	ПараметрыОбласти.ПредставительНаименование = КонтрактМЧД.Представитель.Наименование;
	ПараметрыОбласти.ДатаВыдачи = КонтрактМЧД.ДатаНачалаДействия;
	ПараметрыОбласти.СрокДействия = КонтрактМЧД.СрокДействия;
	
	ТипыПредставителя = Модуль_Ядро.Перечисление_ТипыПредставителяМЧД();
	
	Если КонтрактМЧД.Представитель.Тип = ТипыПредставителя.ИП
		Или КонтрактМЧД.Представитель.Тип = ТипыПредставителя.ФЛ Тогда
		
		ПредставительНаименованиеЗаголовок = "ФИО";
		ПредставительИННЗаголовок = "ИНН";
		ПредставительИННТекст = КонтрактМЧД.Представитель.ИНН;
		
	Иначе
		
		ПредставительНаименованиеЗаголовок = "Наименование";
		ПредставительИННЗаголовок = "ИНН-КПП";
		
		ПредставительИННТекст = КонтрактМЧД.Представитель.ИНН;
		Если ЗначениеЗаполнено(КонтрактМЧД.Представитель.КПП) Тогда
			ПредставительИННТекст = ПредставительИННТекст + " - " + КонтрактМЧД.Представитель.КПП;
		КонецЕсли;
		
	КонецЕсли;
	
	ПараметрыОбласти.ПредставительНаименованиеЗаголовок = ПредставительНаименованиеЗаголовок;
	ПараметрыОбласти.ПредставительИННЗаголовок = ПредставительИННЗаголовок;
	ПараметрыОбласти.ПредставительИНН = ПредставительИННТекст;
	
	ТабДокумент.Вывести(ОбластьРеквизиты);
	
	СведенияОПолномочиях = КонтрактМЧД.СведенияОПолномочиях;
	Полномочия = СведенияОПолномочиях.Полномочия;
	
	Если Полномочия.Количество() Тогда
		
		ОбластьЗаголовкаПолномочий = Макет.ПолучитьОбласть("ЗаголовокОбластиПолномочий");
		ТабДокумент.Вывести(ОбластьЗаголовкаПолномочий);
		
		ОбластьПередоверия = Макет.ПолучитьОбласть("СведенияОПередоверии");
		
		Если СведенияОПолномочиях.УтратаПолномочийПриПередоверии = Ложь Тогда
			ОбластьПередоверия.Параметры.Передоверие = "Полномочия не утрачиваются при передоверии";
		ИначеЕсли СведенияОПолномочиях.УтратаПолномочийПриПередоверии = Истина Тогда
			ОбластьПередоверия.Параметры.Передоверие = "Полномочия утрачиваются при передоверии";
		Иначе
			ОбластьПередоверия.Параметры.Передоверие = "";
		КонецЕсли;
		
		ТабДокумент.Вывести(ОбластьПередоверия);
		
		Если СведенияОПолномочиях.СовместныеПолномочия Тогда
			ОбластьСовместныеПолномочия = Макет.ПолучитьОбласть("ОбластьСовместныеПолномочия");
			ТабДокумент.Вывести(ОбластьСовместныеПолномочия);
		КонецЕсли;
		
		Для Каждого Полномочие Из Полномочия Цикл
			
			Если Полномочие.МашиночитаемоеПолномочие Тогда
				МашиночитаемоеОписание = Полномочие.МашиночитаемоеОписание;
				ОбластьОписанияПолномочий = МЧД_МашиночитаемоеПредставлениеСведенийОбДоверенности(МашиночитаемоеОписание, Макет);
			Иначе
				ОбластьОписанияПолномочий = Макет.ПолучитьОбласть("ТекстовоеОписаниеПолномочия");
				ОбластьОписанияПолномочий.Параметры.ОписаниеПолномочия = Полномочие.ТекстовоеОписание;
			КонецЕсли;
			
			ТабДокумент.Вывести(ОбластьОписанияПолномочий);
			
		КонецЦикла;
		
	КонецЕсли;
	
	СтруктураОшибок = КонтрактМЧД.СтатусПроверки.СтруктураОшибок;
	
	Если ЗначениеЗаполнено(СтруктураОшибок) Тогда
		
		СведенияОПроверке = Макет.ПолучитьОбласть("СведенияОПроверке");
		
		КоллекцияОшибок = Новый Массив;
		Для Каждого ОписаниеОшибки Из СтруктураОшибок.СписокОшибок Цикл
			РасшифровкаОшибки = "- " + ОписаниеОшибки.Расшифровка;
			КоллекцияОшибок.Добавить(РасшифровкаОшибки);
		КонецЦикла;
		
		Если ЗначениеЗаполнено(КоллекцияОшибок) Тогда
			
			СписокОшибокСтрокой = Модуль_Ядро.СоединитьСтроку(КоллекцияОшибок, Символы.ПС);
			
			СведенияОПроверке.Параметры.СведенияОПроверке = СписокОшибокСтрокой;
			
			ТабДокумент.Вывести(СведенияОПроверке);
			
		КонецЕсли;
		
	КонецЕсли;
	
	ВремФайл = ПолучитьИмяВременногоФайла();
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	
	ТабДокумент.Записать(ВремФайл, ТипФайлаТабличногоДокумента.HTML);
	ТекстовыйДокумент.Прочитать(ВремФайл);
	ТекстHTML = ТекстовыйДокумент.ПолучитьТекст();
	
	ТабДокумент.Записать(ВремФайл, ТипФайлаТабличногоДокумента.TXT);
	ТекстовыйДокумент.Прочитать(ВремФайл);
	Текст = ТекстовыйДокумент.ПолучитьТекст();
	
	Результат = Новый Структура;
	Результат.Вставить("ТекстHTML", ТекстHTML);
	Результат.Вставить("Текст", Текст);
	
	УдалитьФайлы(ВремФайл);
	
	Возврат Результат;
	
КонецФункции
// BSLLS:CognitiveComplexity-on

Функция МЧД_МашиночитаемоеПредставлениеСведенийОбДоверенности(ОписаниеПолномочия, Макет)

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

// BSLLS:CognitiveComplexity-off
// BSLLS:MissingReturnedValueDescription-off
// BSLLS:MissingParameterDescription-off
Функция МЧД_ПредставлениеПолномочий_HTML(КонтрактМЧД) Экспорт
	// BSLLS:MissingReturnedValueDescription-on
	// BSLLS:MissingParameterDescription-on
	ТабДокумент = Новый ТабличныйДокумент;
	Макет = ПолучитьМакет("ПолномочияМЧД_mxl");
	СведенияОПолномочиях = КонтрактМЧД.СведенияОПолномочиях;
	Полномочия = СведенияОПолномочиях.Полномочия;
	
	ОбластьРеквизиты = Макет.ПолучитьОбласть("Реквизиты");
	
	ПараметрыОбласти = ОбластьРеквизиты.Параметры;
	ПараметрыОбласти.ПредставлениеОрганизацииИДоверенного =
		КонтрактМЧД.Доверитель.Наименование + ", " + КонтрактМЧД.Представитель.Наименование;
	
	ТабДокумент.Вывести(ОбластьРеквизиты);
	
	ОбластьПередоверия = Макет.ПолучитьОбласть("СведенияОПередоверии");
	
	Если СведенияОПолномочиях.УтратаПолномочийПриПередоверии = Ложь Тогда
		ОбластьПередоверия.Параметры.Передоверие = "Полномочия не утрачиваются при передоверии";
	ИначеЕсли СведенияОПолномочиях.УтратаПолномочийПриПередоверии = Истина Тогда
		ОбластьПередоверия.Параметры.Передоверие = "Полномочия утрачиваются при передоверии";
	Иначе
		ОбластьПередоверия.Параметры.Передоверие = "";
	КонецЕсли;
	
	ТабДокумент.Вывести(ОбластьПередоверия);
	
	Если Полномочия.Количество() Тогда
		
		ОбластьЗаголовкаПолномочий = Макет.ПолучитьОбласть("ЗаголовокОбластиПолномочий");
		ТабДокумент.Вывести(ОбластьЗаголовкаПолномочий);
		
		Если СведенияОПолномочиях.СовместныеПолномочия Тогда
			ОбластьСовместныеПолномочия = Макет.ПолучитьОбласть("ОбластьСовместныеПолномочия");
			ТабДокумент.Вывести(ОбластьСовместныеПолномочия);
		КонецЕсли;
		
		Для Каждого Полномочие Из Полномочия Цикл
			
			Если Полномочие.МашиночитаемоеПолномочие Тогда
				МашиночитаемоеОписание = Полномочие.МашиночитаемоеОписание;
				ОбластьОписанияПолномочий = МЧД_МашиночитаемоеПредставлениеСведенийОбДоверенности(МашиночитаемоеОписание, Макет);
			Иначе
				ОбластьОписанияПолномочий = Макет.ПолучитьОбласть("ТекстовоеОписаниеПолномочия");
				ОбластьОписанияПолномочий.Параметры.ОписаниеПолномочия = Полномочие.ТекстовоеОписание;
			КонецЕсли;
			
			ТабДокумент.Вывести(ОбластьОписанияПолномочий);
			
		КонецЦикла;
		
	КонецЕсли;
	
	ВремФайл = ПолучитьИмяВременногоФайла();
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	
	ТабДокумент.Записать(ВремФайл, ТипФайлаТабличногоДокумента.HTML);
	ТекстовыйДокумент.Прочитать(ВремФайл);
	ТекстHTML = ТекстовыйДокумент.ПолучитьТекст();
	
	ТабДокумент.Записать(ВремФайл, ТипФайлаТабличногоДокумента.TXT);
	ТекстовыйДокумент.Прочитать(ВремФайл);
	Текст = ТекстовыйДокумент.ПолучитьТекст();
	
	Результат = Новый Структура;
	Результат.Вставить("ТекстHTML", ТекстHTML);
	Результат.Вставить("Текст", Текст);
	
	УдалитьФайлы(ВремФайл);
	
	Возврат Результат;
	
КонецФункции
// BSLLS:CognitiveComplexity-on

Функция МЧД_ПредставлениеОграниченийДоверенности(ОписаниеОграничений, Макет)

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

// } МЧД

// { СЛУЖЕБНЫЕ МЕТОДЫ

Функция ПредставлениеИННКПП(Данные)

	МассивСлов = Новый Массив;
	МассивСлов.Добавить(Данные.ИНН);
	МассивСлов.Добавить(Данные.КПП);
	
	Результат = Модуль_Ядро().СоединитьСтроку(МассивСлов, "-");
    Возврат Результат;
	
КонецФункции

// } СЛУЖЕБНЫЕ МЕТОДЫ