Документооборот с контролирующими органами / Управление ошибками обмена / Модуль формы

файл
&НаКлиенте
Перем КонтекстЭДО Экспорт;

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

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

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	КонтекстЭДО = ВладелецФормы.КонтекстЭДО;
	ПодключитьОбработчикОжидания("Подключаемый_ПоискатьСертификаты", 0.1, Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаНавигационнойСсылки(НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка) Экспорт
	
	Если СтрНайти(НавигационнаяСсылкаФорматированнойСтроки, "#view_certificate_msg") > 0 Тогда 
		СтандартнаяОбработка = Ложь;
		ЭлементыСтроки = СтрРазделить(НавигационнаяСсылкаФорматированнойСтроки, "?");
		Если ЭлементыСтроки.Количество() > 1 Тогда 
			Подробнее(Неопределено, Истина);
		КонецЕсли;
		
	ИначеЕсли СтрНайти(НавигационнаяСсылкаФорматированнойСтроки, "#view_certificate") > 0 Тогда 
		СтандартнаяОбработка = Ложь;
		ЭлементыСтроки = СтрРазделить(НавигационнаяСсылкаФорматированнойСтроки, "?");
		Если ЭлементыСтроки.Количество() > 1 Тогда 
			Отпечаток = ЭлементыСтроки[1];
			
			ДанныеСертификата = Новый Структура("Отпечаток", Отпечаток);
			КриптографияЭДКОКлиентСервер.КонтекстМоделиХраненияКлюча(Истина, ДанныеСертификата);
			КриптографияЭДКОКлиент.ПоказатьСертификат(ДанныеСертификата);
		КонецЕсли;
		
	ИначеЕсли СтрНайти(НавигационнаяСсылкаФорматированнойСтроки, "#action") > 0 Тогда 
		СтандартнаяОбработка = Ложь;
		// #action?ignore_cert=serial
		// #action?ignore_all_tc
		ЭлементыСтроки = СтрРазделить(НавигационнаяСсылкаФорматированнойСтроки, "?");
		Если ЭлементыСтроки.Количество() > 1 Тогда 
			// ignore_cert=serial
			// ignore_all_tc
			КомандаСПараметром = ЭлементыСтроки[1];			
			Если КомандаСПараметром = "adjusting" Тогда 
				
				ДополнительныеПараметры = Новый Структура();
				ДополнительныеПараметры.Вставить("ЭтоТолькоНастройка", Истина);
				
				ОткрытьФорму("Обработка.НачалоРаботыОблачной1СО.Форма.БыстрыйСтарт", ДополнительныеПараметры);
				
			ИначеЕсли КомандаСПараметром = "close_window" Тогда 
				ЭтотОбъект.Закрыть();			
			ИначеЕсли КомандаСПараметром = "show_master" Тогда 
				
				ФлагиВМастер = Новый Структура("ПродлитьСертификат", Истина);
				ФлагиВМастер.Вставить("ИзменитьРеквизитыПодключенияК1СОтчетности", Ложь);
				ФлагиВМастер.Вставить("ПродлитьЛицензиюНа1СОтчетность", Ложь);
								
				АктивироватьФлагиМастера = Новый Структура("ФлагиВМастер", ФлагиВМастер);
				
				ПараметрыОткрытияМастера = Новый Структура;
				ПараметрыОткрытияМастера.Вставить("АктивироватьФлагиМастера", АктивироватьФлагиМастера);
				ВидЗаявления = ПредопределенноеЗначение("Перечисление.ТипыЗаявленияАбонентаСпецоператораСвязи.Изменение");
				ЭлектронныйДокументооборотСКонтролирующимиОрганамиКлиент.ОткрытьФормуМастераЗаявленияНаПодключение(
					Организация, 
					ЭтотОбъект,,
					ВидЗаявления,
					ПараметрыОткрытияМастера
				);
			ИначеЕсли КомандаСПараметром = "configure_certificates" Тогда 
				
				Ключ = "ОбщаяФормаНастройкиНерасшифровываемых";
				
				ПараметрыОткрытияФормы = Новый Структура();	
				ПараметрыОткрытияФормы.Вставить("АктивироватьСтраницу", "СтрСертификаты");				
				Если ЗначениеЗаполнено(Организация) Тогда 
					ПараметрыОткрытияФормы.Вставить("Организация", Организация);
				КонецЕсли;
				
				ФормаРезультат = ПолучитьФорму(КонтекстЭДО.ПутьКОбъекту + ".Форма.Нерасшифровываемые_УправлениеОшибкамиОбмена", ПараметрыОткрытияФормы, ЭтотОбъект, Ключ);
				ФормаРезультат.Открыть();
				
			ИначеЕсли КомандаСПараметром = "configure_documents" Тогда 
				
				Ключ = "ОбщаяФормаНастройкиНерасшифровываемых";
				
				ПараметрыОткрытияФормы = Новый Структура();	
				ПараметрыОткрытияФормы.Вставить("АктивироватьСтраницу", "СтрДокументы");				
				Если ЗначениеЗаполнено(Организация) Тогда 
					ПараметрыОткрытияФормы.Вставить("Организация", Организация);
				КонецЕсли;
				
				ФормаРезультат = ПолучитьФорму(КонтекстЭДО.ПутьКОбъекту + ".Форма.Нерасшифровываемые_УправлениеОшибкамиОбмена", ПараметрыОткрытияФормы, ЭтотОбъект, Ключ);
				ФормаРезультат.Открыть();
				
			ИначеЕсли КомандаСПараметром = "ignore_all_tc" Тогда 
				
				Элементы.Сообщения.ВыделенныеСтроки.Очистить();
				Для Ст = 0 по Сообщения.Количество()-1 Цикл 
					Элементы.Сообщения.ВыделенныеСтроки.Добавить(Ст);
				КонецЦикла;
				ПереключениеРасшифровкиПоСообщениям(, Истина);
				
			ИначеЕсли СтрНайти(КомандаСПараметром, "ignore_cert") > 0 Тогда 
				ЭлементыСтроки = СтрРазделить(НавигационнаяСсылкаФорматированнойСтроки, "=");
				Если ЭлементыСтроки.Количество() > 1 Тогда 
					СерийныйНомерСтрокой = ЭлементыСтроки[1];
					
					Ст = 0;
					Элементы.Сертификаты.ВыделенныеСтроки.Очистить();
					Для Каждого Серт Из Сертификаты Цикл 
						Если Серт.Свойства.СерийныйНомерСтрокой = СерийныйНомерСтрокой Тогда 
							Элементы.Сертификаты.ВыделенныеСтроки.Добавить(Ст);
							ПереключениеРасшифровкиПоСертификату();
							Прервать;
						КонецЕсли;
						Ст = Ст + 1;
					КонецЦикла;
					
				КонецЕсли;
				
			ИначеЕсли СтрНайти(КомандаСПараметром, "user_list") > 0 Тогда
				ТекущийПользователь = ПользователиКлиент.ТекущийПользователь();
				ТекущийПользовательВСписке = СписокПользователей.НайтиПоЗначению(ТекущийПользователь);
				Если ТекущийПользовательВСписке <> Неопределено Тогда
					СписокПользователей.Удалить(ТекущийПользовательВСписке);
				КонецЕсли;
				КонтекстЭДО.ОткрытьФормуСпискаПользователей(, СписокПользователей, Истина);
			КонецЕсли;
		КонецЕсли;
	
	КонецЕсли;	
	
КонецПроцедуры

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

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура ОрганизацияПриИзменении(Элемент)
	
	ОрганизацияПриИзмененииСервер();
	
КонецПроцедуры

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

#Область ОбработчикиСобытийЭлементовТаблицыФормы

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

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

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

&НаКлиенте
Процедура НеРасшифровыватьПоСертификату(Команда)
	
	Если Элементы.Сертификаты.ТекущиеДанные <> Неопределено Тогда
		ПереключениеРасшифровкиПоСертификату();
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура РасшифровыватьПоСертификату(Команда)
	
	Если Элементы.Сертификаты.ТекущиеДанные <> Неопределено Тогда
		ПереключениеРасшифровкиПоСертификату();
	КонецЕсли;
	
КонецПроцедуры

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

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

&НаКлиенте
Процедура РасшифровыватьСообщение(Команда)
	
	Если Элементы.Сообщения.ТекущиеДанные <> Неопределено Тогда
		ПереключениеРасшифровкиПоСообщениям(, Ложь);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура НеРасшифровыватьСообщение(Команда)
	
	Если Элементы.Сообщения.ТекущиеДанные <> Неопределено Тогда
		ПереключениеРасшифровкиПоСообщениям(, Истина);
	КонецЕсли;
	
КонецПроцедуры

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

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

#Область Бесконтекстные_вызовы

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

&НаКлиентеНаСервереБезКонтекста
Функция ИзвлечьCNИздателя(РеквизитыИздателя) Экспорт
	
	ПоставщикCN = "";
	Если Не РеквизитыИздателя.Свойство("CN", ПоставщикCN) Тогда 
		Если Не РеквизитыИздателя.Свойство("OID2_5_4_3", ПоставщикCN) Тогда // 	CN, AKA 2.5.4.3
			Если Не РеквизитыИздателя.Свойство("OID2_5_4_10", ПоставщикCN) Тогда 
				ПоставщикCN = "";
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Возврат ПоставщикCN;
	
КонецФункции

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

	Если ВсеСвойстваСертификата.Свойство("Наименование") Тогда 
		ВсеСвойстваСертификата.Вставить("Описание", 
			СтрШаблон("%1 %2 - %3", 
				ВсеСвойстваСертификата.Наименование,
				Формат(ВсеСвойстваСертификата.ДатаНачала, "ДФ='dd.MM.yyyy HH:mm'"),
				Формат(ВсеСвойстваСертификата.ДатаОкончания, "ДФ='dd.MM.yyyy HH:mm'")
			)
		);
		
		Ссылка = СтрШаблон("#view_certificate?%1", ВсеСвойстваСертификата.ОтпечатокСтрокой);		
		
		ВсеСвойстваСертификата.Вставить("ПодробноеОписание", 
		
			Новый ФорматированнаяСтрока(СтрШаблон("%1, действителен с %2 по %3", 
				ВсеСвойстваСертификата.Наименование,
				Формат(ВсеСвойстваСертификата.ДатаНачала, "ДФ='dd.MM.yyyy HH:mm'"),
				Формат(ВсеСвойстваСертификата.ДатаОкончания, "ДФ='dd.MM.yyyy HH:mm'")
			)," (", Новый ФорматированнаяСтрока("подробнее",,,, Ссылка), ")")
		);
	Иначе
		ВсеСвойстваСертификата.Вставить("Описание", 
			СтрШаблон("%1 %2", 
				"Неизвестный",
				ВсеСвойстваСертификата.СерийныйНомерСтрокой)
		);
		
		ВсеСвойстваСертификата.Вставить("ПодробноеОписание", 
			СтрШаблон("%1 %2, издан %3", 
				"Неизвестный",
				ВсеСвойстваСертификата.СерийныйНомерСтрокой,
				ВсеСвойстваСертификата.ИздательСтрокой)
		);
	КонецЕсли;
			
	Возврат ВсеСвойстваСертификата;
КонецФункции

&НаСервереБезКонтекста
Функция ИнформацияДляРасшифровкиСообщения(ТранспортноеСообщение, ОбщиеПараметры)
	
	ОбработкаЭДО = ОбщиеПараметры.ОбработкаЭДО;
	
	Результат = Новый Структура;
	Результат.Вставить("ТранспортноеСообщение", ТранспортноеСообщение);
	Результат.Вставить("Получатели", 			Новый Массив);
	Результат.Вставить("Ошибка", 				"");
	Результат.Вставить("Пользователи", 			"");
	Результат.Вставить("МассивПользователей", 	Новый Массив);
	
	Результат.МассивПользователей = Мультирежим.ВладельцыТранспортногоСообщения(ТранспортноеСообщение);
	
	Если ТранспортноеСообщение.СертификатыПолучателей.Количество() > 0 Тогда 
		Для Каждого Получатель Из ТранспортноеСообщение.СертификатыПолучателей Цикл 
			ПолучательСтр = Новый Структура("СерийныйНомер,ПоставщикCN,Отпечаток,Сторонний");
			ЗаполнитьЗначенияСвойств(ПолучательСтр, Получатель);
			Результат.Получатели.Добавить(СвойстваСертификата(ПолучательСтр, ОбщиеПараметры));
		КонецЦикла;
		Возврат Результат;
	КонецЕсли;
	
	Контейнеры = ОбработкаЭДО.ПолучитьТранспортныйКонтейнер(ТранспортноеСообщение, Истина);
	Если Контейнеры.Количество() < 1 Тогда 
		Результат.Ошибка = "Отсутствует транспортный контейнер";
		Возврат Результат;
	КонецЕсли;
	
	Контейнер = Контейнеры[0];
	Попытка
		ДанныеКонтейнера = Контейнер.Данные.Получить();
		Если НЕ ЗначениеЗаполнено(ДанныеКонтейнера) ИЛИ ДанныеКонтейнера.Размер() = 0 Тогда
			Результат.Ошибка = "Транспортный контейнер пуст или поврежден";
			Возврат Результат;
		КонецЕсли;
	Исключение
		Результат.Ошибка = "Транспортный контейнер поврежден";
		Возврат Результат;
	КонецПопытки;
	
	ЗашифрованныйИзКонтейнера = Неопределено;
	
	ВременныйКаталог = ПолучитьИмяВременногоФайла("cat");
	Разделитель = ПолучитьРазделительПути();
	Если Прав(ВременныйКаталог, 1) <> Разделитель Тогда 
		ВременныйКаталог = ВременныйКаталог + Разделитель;
	КонецЕсли;	
	СоздатьКаталог(ВременныйКаталог);
	
	Чтение = Неопределено;
	ЧтениеZip = Неопределено;
	Попытка
		ФорматДокументооборота = Неопределено;
		ИмяФайлаОписания = "packageDescription.xml";
		Чтение = Новый ЧтениеДанных(ДанныеКонтейнера);
		ЧтениеZip = Новый ЧтениеZipФайла(Чтение.ИсходныйПоток());
		ФайлАрхива = ЧтениеZip.Элементы.Найти(ИмяФайлаОписания);
		Если ФайлАрхива = Неопределено Тогда
			РеквизитыЦиклаОбмена = ?(ЗначениеЗаполнено(ТранспортноеСообщение.ЦиклОбмена),
				ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ТранспортноеСообщение.ЦиклОбмена, "Вид, ФорматДокументооборота"),
				Новый Структура("Вид, ФорматДокументооборота", Неопределено, Неопределено));
			Если РеквизитыЦиклаОбмена.Вид = Перечисления.ТипыКонтролирующихОрганов.ПФР
			И (НЕ ЗначениеЗаполнено(РеквизитыЦиклаОбмена.ФорматДокументооборота) ИЛИ
			РеквизитыЦиклаОбмена.ФорматДокументооборота = Перечисления.ФорматыДокументооборотаСПФР.ЭДОК)
			ИЛИ ТранспортноеСообщение.Тип = Перечисления.ТипыТранспортныхСообщений.ПервичноеСообщениеСодержащееОтчетностьПФР
			ИЛИ ТранспортноеСообщение.Тип = Перечисления.ТипыТранспортныхСообщений.ПодтверждениеПолученияОтчетностиПФР
			ИЛИ ТранспортноеСообщение.Тип = Перечисления.ТипыТранспортныхСообщений.ПротоколПФР
			ИЛИ ТранспортноеСообщение.Тип = Перечисления.ТипыТранспортныхСообщений.ПротоколКвитанцияПФР
			ИЛИ ТранспортноеСообщение.Тип = Перечисления.ТипыТранспортныхСообщений.ПисьмоИсходящееКвитанцияПФР
			ИЛИ ТранспортноеСообщение.Тип = Перечисления.ТипыТранспортныхСообщений.УведомлениеОбОшибкеПФР
			ИЛИ ТранспортноеСообщение.Тип = Перечисления.ТипыТранспортныхСообщений.ПодтверждениеПолученияЗапросаПФР
			ИЛИ ТранспортноеСообщение.Тип = Перечисления.ТипыТранспортныхСообщений.ОтветНаЗапросПФР Тогда
				// обход ошибки платформы для архива zip с кодировкой имен файлов cp866, сформированного в Linux
				
				Попытка
					ЧтениеZip.Закрыть();
					ЧтениеZip = Неопределено;
					Чтение.Закрыть();
					Чтение = Неопределено;
					МассивОписанийИДанных = ОбщегоНазначенияЭДКО.МассивОписанийИДанныхZipФайла(ДанныеКонтейнера);
					Если МассивОписанийИДанных <> Неопределено Тогда
						ПотокДанныхКонтейнера = Новый ПотокВПамяти;
						ОбщегоНазначенияЭДКО.СформироватьZip(МассивОписанийИДанных, ПотокДанныхКонтейнера);
						ДанныеКонтейнера = ПотокДанныхКонтейнера.ЗакрытьИПолучитьДвоичныеДанные();
					КонецЕсли;
					Чтение = Новый ЧтениеДанных(ДанныеКонтейнера);
					ЧтениеZip = Новый ЧтениеZipФайла(Чтение.ИсходныйПоток());
				Исключение
					ЧтениеZip = Неопределено;
					Результат.Ошибка = "Транспортный контейнер поврежден, отсутствует описание";
					Чтение.Закрыть();
					Чтение = Неопределено;
					ОперацииСФайламиЭДКО.УдалитьВременныйФайл(ВременныйКаталог);
					Возврат Результат;
				КонецПопытки;
				
				Если ЧтениеZip <> Неопределено Тогда
					Для каждого ЭлементКонтейнера Из ЧтениеZip.Элементы Цикл
						ИмяФайлаВРег = СокрЛП(ЭлементКонтейнера.ИмяБезРасширения);
						ИмяФайлаВРег = ВРег(ИмяФайлаВРег);
						РасширениеФайла = СокрЛП(ЭлементКонтейнера.Расширение);
						
						Если (Лев(ИмяФайлаВРег, 4) = "ПФР_" ИЛИ Лев(ИмяФайлаВРег, 4) = "СФР_")
							И СтрНайти(ИмяФайлаВРег, "_ОСП_") > 0 И нрег(РасширениеФайла) = "xml" Тогда
							
							ИмяФайлаОписания = ЭлементКонтейнера.Имя;
							ФайлАрхива = ЭлементКонтейнера;
							ФорматДокументооборота = Перечисления.ФорматыДокументооборотаСПФР.ЭДОК;
							Прервать;
						КонецЕсли;
					КонецЦикла;
				КонецЕсли;
			КонецЕсли;
			
			Если ФайлАрхива = Неопределено Тогда
				Результат.Ошибка = "Транспортный контейнер поврежден, отсутствует описание";
				ЧтениеZip.Закрыть();
				ЧтениеZip = Неопределено;
				Чтение.Закрыть();
				Чтение = Неопределено;
				ОперацииСФайламиЭДКО.УдалитьВременныйФайл(ВременныйКаталог);
				Возврат Результат;
			КонецЕсли;
		КонецЕсли;
		
		Если ФайлАрхива <> Неопределено Тогда
			ЧтениеZip.Извлечь(ФайлАрхива, ВременныйКаталог, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
			
			ЧтениеXML = Новый ЧтениеXML;
			ЧтениеXML.ОткрытьФайл(ВременныйКаталог + ИмяФайлаОписания);
			ЧтениеXML.ПерейтиКСодержимому();
			ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
			ЧтениеXML.Закрыть();
			
			ПервыйЗашифрованный = Неопределено;
			
			Если ФорматДокументооборота = Перечисления.ФорматыДокументооборотаСПФР.ЭДОК Тогда
				ДеревоОписанияСведений = ОбработкаЭДО.ЗагрузитьXMLВДеревоЗначений(ВременныйКаталог + ИмяФайлаОписания);
				Если ДеревоОписанияСведений = Неопределено Тогда
					Результат.Ошибка = НСтр("ru = 'Транспортный контейнер поврежден, некорректный формат описания'");
					ЧтениеZip.Закрыть();
					ЧтениеZip = Неопределено;
					Чтение.Закрыть();
					Чтение = Неопределено;
					ОперацииСФайламиЭДКО.УдалитьВременныйФайл(ВременныйКаталог);
					Возврат Результат;
				КонецЕсли;
				
				УзелОСП = ОбработкаЭДО.НайтиСтрокиДереваЗначений(ДеревоОписанияСведений,,, "ОСП", "Э");
				Если НЕ ЗначениеЗаполнено(УзелОСП) Тогда
					Результат.Ошибка = НСтр("ru = 'Транспортный контейнер поврежден, отсутствует узел ""ОСП""'");
					ЧтениеZip.Закрыть();
					ЧтениеZip = Неопределено;
					Чтение.Закрыть();
					Чтение = Неопределено;
					ОперацииСФайламиЭДКО.УдалитьВременныйФайл(ВременныйКаталог);
					Возврат Результат;
				КонецЕсли;
				
				УзелЗашифровано = ОбработкаЭДО.НайтиСтрокиДереваЗначений(УзелОСП,,, "Зашифровано", "Э", Ложь);
				ДокументыЗашифрованы = ?(ЗначениеЗаполнено(УзелЗашифровано),
					ОбработкаЭДО.БулевоПоСтроке(УзелЗашифровано.Значение), Неопределено);
				
				УзлыДокумент = Новый Массив;
				ОбработкаЭДО.НайтиСтрокиДереваЗначений(УзелОСП,, УзлыДокумент, "Документ", "Э", Ложь);
				УзелДополнительныеДокументы = ОбработкаЭДО.НайтиСтрокиДереваЗначений(УзелОСП,,,
					"ДополнительныеДокументы", "Э", Ложь);
				УзлыДополнительныйДокумент = Неопределено;
				Если ЗначениеЗаполнено(УзелДополнительныеДокументы) Тогда
					УзлыДополнительныйДокумент = Новый Массив;
					ОбработкаЭДО.НайтиСтрокиДереваЗначений(УзелДополнительныеДокументы,,
						УзлыДополнительныйДокумент, "Документ", "Э", Ложь);
				КонецЕсли;
				
				Для НомерУзловДокументов = 1 По ?(УзлыДополнительныйДокумент = Неопределено, 1, 2) Цикл
					ЭтоДополнительныйДокумент = (НомерУзловДокументов = 2);
					Если ЭтоДополнительныйДокумент Тогда
						УзлыДокумент = УзлыДополнительныйДокумент;
					КонецЕсли;
					
					Для каждого УзелДокумент Из УзлыДокумент Цикл
						УзелКод = ОбработкаЭДО.НайтиСтрокиДереваЗначений(УзелДокумент,,, "Код", "Э", Ложь);
						КодДокумента = ?(ЗначениеЗаполнено(УзелКод), СокрЛП(УзелКод.Значение), "");
						
						УзелФайл = ОбработкаЭДО.НайтиСтрокиДереваЗначений(УзелДокумент,,, "Файл", "Э", Ложь);
						ИмяФайлаДокумента = ?(ЗначениеЗаполнено(УзелФайл), СокрЛП(УзелФайл.Значение), "");
						Если (ВРег(КодДокумента) = "УОД" ИЛИ ВРег(КодДокумента) = "УОПП" ИЛИ ВРег(КодДокумента) = "УОНД")
							И НЕ ЗначениеЗаполнено(УзелЗашифровано) И (нрег(Прав(ИмяФайлаДокумента, 4)) = ".enc") Тогда // Обход ошибки ПФР
							ИмяФайлаДокумента = Лев(ИмяФайлаДокумента, СтрДлина(ИмяФайлаДокумента) - 4);
						КонецЕсли;
						
						Если ДокументыЗашифрованы <> Неопределено Тогда
							ДокументЗашифрован = ДокументыЗашифрованы;
						Иначе
							РасширениеДокументаНРег = ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла(ИмяФайлаДокумента).Расширение;
							РасширениеДокументаНРег = нрег(РасширениеДокументаНРег);
							ДокументЗашифрован = (РасширениеДокументаНРег = ".enc"
								ИЛИ (РасширениеДокументаНРег <> ".gz" И РасширениеДокументаНРег <> ".der"
								И ОбработкаЭДО.ТипСодержимогоПоИмениФайла(ИмяФайлаДокумента) =
								Перечисления.ТипыСодержимогоФайлов.Неизвестный));
						КонецЕсли;
						
						Если ДокументЗашифрован Тогда
							ПервыйЗашифрованный = ИмяФайлаДокумента;
							Прервать;
						КонецЕсли;
					КонецЦикла;
				КонецЦикла;
				
				Если НЕ ЗначениеЗаполнено(ПервыйЗашифрованный) Тогда
					ЧтениеZip.Закрыть();
					ЧтениеZip = Неопределено;
					Чтение.Закрыть();
					Чтение = Неопределено;
					ОперацииСФайламиЭДКО.УдалитьВременныйФайл(ВременныйКаталог);
					Возврат Результат; //  "Транспортный контейнер не содержит зашифрованные документы"
				КонецЕсли;
				
			Иначе
				Попытка
					// Исходный xpath "/документ[@зашифрован=""true""][1]/содержимое/@имяФайла"
					ПервыйЗашифрованный = ОбъектXDTO.Получить("./документ[зашифрован=true]/содержимое/имяФайла");
				Исключение
					ЧтениеZip.Закрыть();
					ЧтениеZip = Неопределено;
					Чтение.Закрыть();
					Чтение = Неопределено;
					ОперацииСФайламиЭДКО.УдалитьВременныйФайл(ВременныйКаталог);
					Возврат Результат; //  "Транспортный контейнер не содержит зашифрованные документы"
				КонецПопытки;
			КонецЕсли;
			
			ФайлАрхива = ЧтениеZip.Элементы.Найти(ПервыйЗашифрованный);
			Если ФайлАрхива = Неопределено Тогда
				Результат.Ошибка = "Транспортный контейнер поврежден, отсутствует зашифрованный файл из описания";
				ЧтениеZip.Закрыть();
				ЧтениеZip = Неопределено;
				Чтение.Закрыть();
				Чтение = Неопределено;
				ОперацииСФайламиЭДКО.УдалитьВременныйФайл(ВременныйКаталог);
				Возврат Результат;
			Иначе
				ЧтениеZip.Извлечь(ФайлАрхива, ВременныйКаталог, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
				ЗашифрованныйИзКонтейнера = Новый ДвоичныеДанные(ВременныйКаталог + ПервыйЗашифрованный);
			КонецЕсли;
		КонецЕсли;
		ЧтениеZip.Закрыть();
		ЧтениеZip = Неопределено;
		Чтение.Закрыть();
		Чтение = Неопределено;
		ОперацииСФайламиЭДКО.УдалитьВременныйФайл(ВременныйКаталог);
	Исключение
		Если ЧтениеZip <> Неопределено Тогда
			ЧтениеZip.Закрыть();
		КонецЕсли;
		Если Чтение <> Неопределено Тогда
			Чтение.Закрыть();
		КонецЕсли;
		ОперацииСФайламиЭДКО.УдалитьВременныйФайл(ВременныйКаталог);
		
		ТекстИсключения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		Результат.Ошибка = СтрШаблон("Ошибка чтения транспортного контейнера: %1", ТекстИсключения);
		Возврат Результат;
	КонецПопытки;
	
	Свойства = КриптографияЭДКОСлужебныйВызовСервера.ПолучитьСвойстваКриптосообщения(ЗашифрованныйИзКонтейнера);
	Если Не Свойства.Свойство("Получатели") Тогда 
		Результат.Ошибка = "Не удалось извлечь получателей из криптосообщения";
		Возврат Результат;
	КонецЕсли;
	
	Для Каждого Получатель Из Свойства.Получатели Цикл 
		
		ПоставщикCN = ОбработкаЭДО.ИзвлечьCNИздателя(Получатель.Издатель);
		
		ПолучательСтр = Новый Структура("СерийныйНомер,ПоставщикCN,Отпечаток,Сторонний");		
		ПолучательСтр.ПоставщикCN = ПоставщикCN;
		ПолучательСтр.СерийныйНомер = НРег(ПолучитьHexСтрокуИзДвоичныхДанных(Получатель.СерийныйНомер));
		ПолучательСтр.Отпечаток = "";
		ПолучательСтр.Сторонний = ОбработкаЭДО.СертификатЯвляетсяСторонним(ПоставщикCN, ОбщиеПараметры);
		
		Результат.Получатели.Добавить(СвойстваСертификата(ПолучательСтр, ОбщиеПараметры));
		
	КонецЦикла;
	
	Возврат Результат;

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

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

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

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

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

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

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

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

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

#Область ОбработчикиПодключаемые

&НаКлиенте
Процедура Подключаемый_ПоискатьСертификаты() Экспорт

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

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

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

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

#Область События_формы

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

	Если ВхКонтекст = Неопределено Или (ТипЗнч(ВхКонтекст) = Тип("Массив") и  ВхКонтекст.Количество() = 0) Тогда 
		Контекст = Нерасшифрованные(Организация, ОбщиеПараметры);
	Иначе
		Если ТипЗнч(ВхКонтекст) <> Тип("Массив") Тогда 
			Док = ВхКонтекст;
			ВхКонтекст = Новый Массив;
			ВхКонтекст.Добавить(Док);
		КонецЕсли;
		Контекст = Новый Массив;
		МассивПользователей = Новый Массив;
		Для Каждого ТранспортноеСообщение Из ВхКонтекст Цикл
			Сведения = ИнформацияДляРасшифровкиСообщения(ТранспортноеСообщение, ОбщиеПараметры);
			Если Сведения.Получатели.Количество() = 0 И Сведения.Ошибка = "" Тогда
				Продолжить;
			КонецЕсли;
			Если Сведения.Ошибка <> "" Тогда
				СводнаяИнформация.ОшибокОбработкиКонтейнера = СводнаяИнформация.ОшибокОбработкиКонтейнера + 1;
			КонецЕсли;
			Сведения.Вставить("ПоследняяРасшифровка", ТекущаяДатаСеанса());
			Контекст.Добавить(Сведения);
			ОбщегоНазначенияКлиентСервер.ДополнитьМассив(МассивПользователей, Сведения.МассивПользователей, Истина);
		КонецЦикла;
		СписокПользователей = Новый СписокЗначений;
		СписокПользователей.ЗагрузитьЗначения(МассивПользователей);
		ВхКонтекст.Очистить();
	КонецЕсли;
	
	ТекущийПользователь = Пользователи.ТекущийПользователь();
	МассивПользователей = СписокПользователей.ВыгрузитьЗначения();
	ФизическиеЛицаПользователей = ОбщегоНазначения.ЗначениеРеквизитаОбъектов(
		МассивПользователей, "ФизическоеЛицо", Истина);
	Для каждого ПользовательРасшифровки Из СписокПользователей Цикл
		СтрокаПользователя = Новый Структура;
		СтрокаПользователя.Вставить("Пользователь", ПользовательРасшифровки.Значение);
		СтрокаПользователя.Вставить("ФизическоеЛицо", ФизическиеЛицаПользователей[ПользовательРасшифровки.Значение]);
		ПользовательРасшифровки.Представление = Мультирежим.ПредставлениеПользователей(ЭтаФорма, СтрокаПользователя);
		Если ПользовательРасшифровки.Значение = ТекущийПользователь Тогда
			ПользовательРасшифровки.Картинка = БиблиотекаКартинок.Пользователь;
		КонецЕсли;
	КонецЦикла;
	
	СобранныеСертификаты = Новый Массив;
	Уникальные = Новый Соответствие;
	
	СортированныеСообщения = РеквизитФормыВЗначение("Сообщения", Тип("ТаблицаЗначений"));
	СортированныеСообщения.Очистить();
	
	Для Каждого СведенияОТранспортномСообщении Из Контекст Цикл
		
		ЗаписьСообщение = СортированныеСообщения.Добавить();
		ЗаписьСообщение.ТранспортноеСообщение = СведенияОТранспортномСообщении.ТранспортноеСообщение;
		
		МассивПользователей = СведенияОТранспортномСообщении.МассивПользователей;
		ПользователиСообщения = "";
		СписокПользователейСообщения = Неопределено;
		Если МассивПользователей.Количество() <> 0 Тогда
			Если МассивПользователей.Найти(ТекущийПользователь) = Неопределено Тогда
				СтрокаПользователя = Новый Структура;
				СтрокаПользователя.Вставить("Пользователь", МассивПользователей[0]);
				СтрокаПользователя.Вставить("ФизическоеЛицо", ФизическиеЛицаПользователей[МассивПользователей[0]]);
				ПользователиСообщения = Мультирежим.ПредставлениеПользователей(ЭтаФорма, СтрокаПользователя);
				
			Иначе
				ПользователиСообщения = НСтр("ru = 'Вы'");
			КонецЕсли;
			
			Если МассивПользователей.Количество() > 1 Тогда
				КоличествоПользователей = МассивПользователей.Количество();
				КоличествоОстальныхПользователейСтрокой = Формат(КоличествоПользователей - 1, "ЧДЦ=; ЧН=; ЧГ=");
				ПользователиСообщения = ПользователиСообщения + " " + СтрШаблон(
					НСтр("ru = 'и еще %1'"),
					КоличествоОстальныхПользователейСтрокой);
			КонецЕсли;
			
			СписокПользователейСообщения = Новый СписокЗначений;
			СписокПользователейСообщения.ЗагрузитьЗначения(МассивПользователей);
			Для каждого ПользовательСообщения Из СписокПользователейСообщения Цикл
				СтрокаПользователя = Новый Структура;
				СтрокаПользователя.Вставить("Пользователь", ПользовательСообщения.Значение);
				СтрокаПользователя.Вставить("ФизическоеЛицо", ФизическиеЛицаПользователей[ПользовательСообщения.Значение]);
				ПользовательСообщения.Представление = Мультирежим.ПредставлениеПользователей(ЭтаФорма, СтрокаПользователя);
				Если ПользовательСообщения.Значение = ТекущийПользователь Тогда
					ПользовательСообщения.Картинка = БиблиотекаКартинок.Пользователь;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
		ЗаписьСообщение.Пользователи = ПользователиСообщения;
		ЗаписьСообщение.СписокПользователей = СписокПользователейСообщения;
		
		СводнаяИнформация.ВсегоНерасшифрованных = СводнаяИнформация.ВсегоНерасшифрованных + 1;
		
		СвойстваТС = СвойстваТранспортногоСообщения(ЗаписьСообщение.ТранспортноеСообщение);
		СвойстваТС.Вставить("ПоследняяРасшифровка", СведенияОТранспортномСообщении.ПоследняяРасшифровка);
		СвойстваТС.Вставить("ДатаБлокировки", Неопределено);
		СвойстваТС.Вставить("ИнициаторБлокировки", Неопределено);
		
		ЗаполнитьЗначенияСвойств(ЗаписьСообщение, СвойстваТС);
		ЗаписьСообщение.Свойства = СвойстваТС;
		
		Для Каждого Получатель Из СведенияОТранспортномСообщении.Получатели Цикл
			// Не показываем однозначно идентифицированные сертификаты контролирующих органов
			Если Получатель.Сторонний Тогда
				Продолжить;
			КонецЕсли;
			КлючСертификата = СокрЛП(Получатель.СерийныйНомерСтрокой) + "." + СокрЛП(НРег(Получатель.ИздательСтрокой));
			ЗаписьСообщение.Сертификаты.Добавить(Получатель, КлючСертификата);
			
			Если Уникальные.Получить(КлючСертификата) = Неопределено Тогда 
				СобранныеСертификаты.Добавить(Получатель);
				Уникальные.Вставить(КлючСертификата, Новый Массив);
			КонецЕсли;
		КонецЦикла;
		
		ЗаписьСообщение.Игнорировать = Ложь;
		
	КонецЦикла;
	
	СортированныеСообщения.Сортировать("Игнорировать, ПоследняяРасшифровка");
	ЗначениеВРеквизитФормы(СортированныеСообщения, "Сообщения");
	
	Исключенные = ИсключенныеИзОбработки();
	
	ТабСобранныеСертификаты = Новый ТаблицаЗначений;
	ТабСобранныеСертификаты.Колонки.Добавить("Сертификат");
	ТабСобранныеСертификаты.Колонки.Добавить("Игнорировать");
	ТабСобранныеСертификаты.Колонки.Добавить("ОтпечатокСтрокой");
	ТабСобранныеСертификаты.Колонки.Добавить("Описание");
	
	Отбор = Новый Структура;
	Для Каждого Сертификат Из СобранныеСертификаты Цикл
		
		Сертификат.Вставить("Игнорировать", Ложь);
		
		Сертификат.Вставить("ПричинаБлокировки", Неопределено);
		Сертификат.Вставить("ДатаБлокировки", Неопределено);
		Сертификат.Вставить("ИнициаторБлокировки", Неопределено);
						
		Отбор.Вставить("СерийныйНомер", Сертификат.СерийныйНомерСтрокой);
		Строки = Исключенные.Сертификаты.НайтиСтроки(Отбор);
		Для Каждого ИсключенныйСерт Из Строки Цикл 
			Если ИсключенныйСерт.ПоставщикCN = Сертификат.ИздательСтрокой Тогда 				
				Сертификат.Игнорировать = Истина;
				Сертификат.ПричинаБлокировки = ИсключенныйСерт.Причина;
				Сертификат.ДатаБлокировки = ИсключенныйСерт.ВремяСобытия;
				Сертификат.ИнициаторБлокировки = ИсключенныйСерт.Инициатор;
				Прервать;
			КонецЕсли;
		КонецЦикла;	
		
		Новая = ТабСобранныеСертификаты.Добавить();
		Новая.Сертификат = Сертификат;
		Новая.Игнорировать = Сертификат.Игнорировать;
		Новая.Описание = Сертификат.Описание;
		Новая.ОтпечатокСтрокой = Сертификат.ОтпечатокСтрокой;
				
		Если Сертификат.Игнорировать Тогда 
			СводнаяИнформация.СертификатовИсключено = СводнаяИнформация.СертификатовИсключено + 1;
		Иначе
			СводнаяИнформация.СертификатовНезаблокированных = СводнаяИнформация.СертификатовНезаблокированных + 1;
		КонецЕсли;
		
		Если Сертификат.Текущий Тогда 
			СводнаяИнформация.ЗашифрованоНаТекущем = СводнаяИнформация.ЗашифрованоНаТекущем + 1;
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Сертификат.Криптопровайдер) Тогда 
			Если Сертификат.Криптопровайдер =  Перечисления.ТипыКриптоПровайдеров.CryptoPro Тогда 
				СводнаяИнформация.СертификатовКриптоПро = СводнаяИнформация.СертификатовКриптоПро + 1;
			ИначеЕсли Сертификат.Криптопровайдер =  Перечисления.ТипыКриптоПровайдеров.CryptoProHSM Тогда 
				СводнаяИнформация.СертификатовКриптоПроHSM = СводнаяИнформация.СертификатовКриптоПроHSM + 1;
			ИначеЕсли Сертификат.Криптопровайдер =  Перечисления.ТипыКриптоПровайдеров.VipNet Тогда 
				СводнаяИнформация.СертификатовВипнет = СводнаяИнформация.СертификатовВипнет + 1;
			КонецЕсли;
		Иначе
			СводнаяИнформация.СертификатовНеизвестных = СводнаяИнформация.СертификатовНеизвестных + 1;
		КонецЕсли;
		
	КонецЦикла;	
	
	ТабСобранныеСертификаты.Сортировать("Игнорировать Возр, ОтпечатокСтрокой Убыв, Описание Возр",);
	СобранныеСертификаты = ТабСобранныеСертификаты.ВыгрузитьКолонку("Сертификат");
				
	Номер = 0;
	Для Каждого Сообщение Из Сообщения Цикл 
		
		Стр = Исключенные.Сообщения.Найти(Сообщение.ТранспортноеСообщение, "ТранспортноеСообщение");
		Если Стр <> Неопределено Тогда
			Сообщение.Свойства.ДатаБлокировки = Стр.ВремяСобытия;
			Сообщение.Свойства.ИнициаторБлокировки = Стр.Инициатор;
			
			Сообщение.Игнорировать = Истина;
		КонецЕсли;
		
		Для Каждого Получатель Из Сообщение.Сертификаты Цикл 
			КлючСертификата = СокрЛП(Получатель.Значение.СерийныйНомерСтрокой) + "." + СокрЛП(НРег(Получатель.Значение.ИздательСтрокой));
			Уникальные.Получить(КлючСертификата).Добавить(Номер);
		КонецЦикла;
		Номер = Номер + 1;
	КонецЦикла;
	
	Для Каждого Получатель Из СобранныеСертификаты Цикл
		ЗаписьСертификат = Сертификаты.Добавить();
		ЗаписьСертификат.Свойства = Получатель;
		ЗаписьСертификат.Игнорировать = Получатель.Игнорировать;
		ЗаполнитьЗначенияСвойств(ЗаписьСертификат, ЗаписьСертификат.Свойства);
		
		КлючСертификата = СокрЛП(Получатель.СерийныйНомерСтрокой) + "." + СокрЛП(НРег(Получатель.ИздательСтрокой));
		ЗаписьСертификат.Сообщения.ЗагрузитьЗначения(Уникальные.Получить(КлючСертификата));
						
	КонецЦикла;
	
	Возврат СводнаяИнформация;
				
КонецФункции

&НаСервере
Процедура ЗаполнитьРекомендации(ОписаниеОшибки, СводнаяИнформация)
	SaaSРежим = КриптографияЭДКОСлужебныйВызовСервера.ИспользованиеКриптосервисаВозможно();		
	
	ПояснениеОшибки = Новый Массив;
	ПояснениеОшибки.Добавить(ОписаниеОшибки);
	ПояснениеОшибки.Добавить(Символы.ПС);
	
	Рекомендации = Новый Массив;
	
	СимволТочкиИПробел = Символ(9679) + " ";
	Если СводнаяИнформация.СертификатовНезаблокированных = 0 И СводнаяИнформация.ОшибокОбработкиКонтейнера = 0 Тогда
		
		// после обработки ошибок форма была переоткрыта
		
		СтатичныйТекст = СимволТочкиИПробел + НСтр("ru = 'Ошибки обработаны и никаких действий не требуется, просто'") + " ";
		Рекомендации.Добавить(СтатичныйТекст);
		Рекомендации.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'закройте'"),,,, "#action?close_window"));
		Рекомендации.Добавить(" " + НСтр("ru = 'это окно'") + ".");
		
	ИначеЕсли СводнаяИнформация.СертификатовНезаблокированных = 0 И СводнаяИнформация.ОшибокОбработкиКонтейнера > 0 Тогда
		
		// нет никаких сертификатов, но есть ошибки извлечения контейнера
		
		ПояснениеОшибки.Добавить(НСтр("ru = 'Транспортный контейнер был записан с ошибкой.'"));
		Рекомендации.Добавить(СимволТочкиИПробел + НСтр("ru = 'При необходимости, исключите из расшифровки конкретные сообщения.'") + " ");
		Рекомендации.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'Перейти к настройке'"),,,, "#action?configure_documents"));
		Рекомендации.Добавить(".");
		
	ИначеЕсли СтрНайти(ОписаниеОшибки, "Ошибка сохранения во временный файл") > 0
		ИЛИ СтрНайти(ОписаниеОшибки, "Пустое содержимое транспортного контейнера") > 0
		ИЛИ СтрНайти(ОписаниеОшибки, "Повреждено содержимое транспортного контейнера сообщения") > 0 Тогда
		
		// отсутствуют данные транспортного контейнера
		
		ПояснениеОшибки.Добавить(НСтр("ru = 'Транспортный контейнер был записан с ошибкой.'"));
		Рекомендации.Добавить(СимволТочкиИПробел + НСтр("ru = 'При необходимости, исключите из расшифровки конкретные сообщения.'") + " ");
		Рекомендации.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'Перейти к настройке'"),,,, "#action?configure_documents"));
		Рекомендации.Добавить(".");
		
	ИначеЕсли СтрНайти(ОписаниеОшибки, "Ошибка при чтении присоединенного файла транспортного контейнера") > 0 Тогда
		
		// отсутствуют данные транспортного контейнера в присоединенных файлах
		
		Рекомендации.Добавить(СимволТочкиИПробел + НСтр("ru = 'При необходимости, исключите из расшифровки конкретные сообщения.'") + " ");
		Рекомендации.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'Перейти к настройке'"),,,, "#action?configure_documents"));
		Рекомендации.Добавить(".");
		
	ИначеЕсли СтрНайти(ОписаниеОшибки, "Ошибка расшифровки файла документа при распаковке пакета") > 0 Тогда 
		
		// разнообразные причины возникновения
		
		ПояснениеОшибки.Добавить(НСтр("ru = 'Сообщение зашифровано сертификатом недоступного ключа.'"));
		
		Если СводнаяИнформация.СертификатовНеизвестных = 0
				И СводнаяИнформация.СертификатовКриптоПро = 0
				И СводнаяИнформация.СертификатовВипнет = 0 Тогда
				
			// Однозначно облачный сертификат
			
			СтатичныйТекст = СимволТочкиИПробел + НСтр("ru = 'Попробуйте повторить обновление позже, при этом убедитесь, что пароль введен правильно.'");
			Рекомендации.Добавить(СтатичныйТекст);
			Рекомендации.Добавить(Символы.ПС);
			
		Иначе
			
			// Локальный или другой нераспознанный сертификат
			
			Если ПараметрыПоказа <> Неопределено И ПараметрыПоказа.ПоказДляДругихПользователей Тогда
				Рекомендации.Добавить(СимволТочкиИПробел + НСтр("ru = 'Попробуйте расшифровать сообщения с компьютеров'") + " ");
				Рекомендации.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'других пользователей'"),,,,"#action?user_list"));
				Рекомендации.Добавить(", " + НСтр("ru = 'на которых есть доступ к закрытому ключу'") + ".");
				Рекомендации.Добавить(Символы.ПС);
				
			Иначе
				СтатичныйТекст = СимволТочкиИПробел + НСтр("ru = 'Вставьте токен (флешку) в USB-порт или удостоверьтесь, что есть доступ к закрытому ключу, и повторите обновление.'");
				Рекомендации.Добавить(СтатичныйТекст);
				Рекомендации.Добавить(Символы.ПС);
				
				Рекомендации.Добавить(СимволТочкиИПробел + НСтр("ru = 'Выполните настройку рабочего места.'") + " ");
				Рекомендации.Добавить(Новый ФорматированнаяСтрока("Перейти к настройке",,,, "#action?adjusting"));
				Рекомендации.Добавить(".");
				Рекомендации.Добавить(Символы.ПС);
				
				Если СводнаяИнформация.СертификатовНеизвестных = 0 Тогда
					СтатичныйТекст = СимволТочкиИПробел + НСтр("ru = 'При использовании 1С-Отчетности на нескольких компьютерах повторите обновление на том, где настроен'") + " ";
					Рекомендации.Добавить(СтатичныйТекст);
					Если СводнаяИнформация.СертификатовНеизвестных = 0
							И СводнаяИнформация.СертификатовКриптоПро > 0
							И СводнаяИнформация.СертификатовВипнет = 0 Тогда // однозначно КриптоПро
						Рекомендации.Добавить(НСтр("ru = 'КриптоПро'"));
					ИначеЕсли СводнаяИнформация.СертификатовНеизвестных = 0
							И СводнаяИнформация.СертификатовКриптоПро = 0
							И СводнаяИнформация.СертификатовВипнет > 0 Тогда // однозначно Випнет
						Рекомендации.Добавить(НСтр("ru = 'ViPNet'"));
					КонецЕсли;
					Рекомендации.Добавить(" CSP.");
					Рекомендации.Добавить(Символы.ПС);
				КонецЕсли;
			КонецЕсли;
			
			Если ПараметрыПоказа <> Неопределено И ПараметрыПоказа.ПоказДляДругихПользователей Тогда
				СтатичныйТекст = СимволТочкиИПробел + НСтр("ru = 'Перенесите закрытый ключ с компьютера другого пользователя.'") + " ";
			Иначе
				СтатичныйТекст = СимволТочкиИПробел + НСтр("ru = 'Перенесите закрытый ключ с другого компьютера.'") + " ";
			КонецЕсли;
			Рекомендации.Добавить(СтатичныйТекст);
			Если СводнаяИнформация.СертификатовНеизвестных > 0 Тогда // нераспознанный сертификат
				Рекомендации.Добавить(НСтр("ru = 'Инструкция по переносу для'") + " ");
				Рекомендации.Добавить(Новый ФорматированнаяСтрока("ViPNet CSP",,,, "https://its.1c.ru/bmk/elreps/key_trans_vipnet"));
				Рекомендации.Добавить(" " + НСтр("ru = 'и'") + " ");
				Рекомендации.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'КриптоПро CSP'"),,,, "https://its.1c.ru/bmk/elreps/key_trans_cryptopro"));
			ИначеЕсли СводнаяИнформация.СертификатовНеизвестных = 0 
					И СводнаяИнформация.СертификатовКриптоПро > 0
					И СводнаяИнформация.СертификатовВипнет = 0 Тогда // однозначно КриптоПро
				Рекомендации.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'Инструкция по переносу'"),,,, "https://its.1c.ru/bmk/elreps/key_trans_cryptopro"));
			ИначеЕсли СводнаяИнформация.СертификатовНеизвестных = 0 
					И СводнаяИнформация.СертификатовКриптоПро = 0
					И СводнаяИнформация.СертификатовВипнет > 0 Тогда // однозначно Випнет
				Рекомендации.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'Инструкция по переносу'"),,,, "https://its.1c.ru/bmk/elreps/key_trans_vipnet"));
			КонецЕсли;
			Рекомендации.Добавить(".");
			Рекомендации.Добавить(Символы.ПС);
			
			Если ПараметрыПоказа <> Неопределено И ПараметрыПоказа.ПоказДляДругихПользователей Тогда
				СтатичныйТекст = СимволТочкиИПробел + НСтр("ru = 'Вставьте токен (флешку) в USB-порт или удостоверьтесь, что есть доступ к закрытому ключу, и повторите расшифровку. Ее вызов доступен для организации по гиперссылке ""Настройки обмена с контролирующими органами"" в разделе ""Настройки"" формы ""1С-Отчетность"".'");
				Рекомендации.Добавить(СтатичныйТекст);
				Рекомендации.Добавить(Символы.ПС);
			КонецЕсли;
		КонецЕсли;
		
		Если СводнаяИнформация.ЗашифрованоНаТекущем > 0 Тогда
			Рекомендации.Добавить(СимволТочкиИПробел);
			Если ПараметрыПоказа = Неопределено ИЛИ НЕ ПараметрыПоказа.ПоказДляДругихПользователей Тогда
				Рекомендации.Добавить(НСтр("ru = 'Некоторые сообщения зашифрованы действующим сертификатом.'") + " ");
			КонецЕсли;
			Рекомендации.Добавить(НСтр("ru = 'Если сертификат утерян'") + ", ");
			Рекомендации.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'отправьте заявление'"),,,, "#action?show_master"));
			Рекомендации.Добавить(" " + НСтр("ru = 'на перевыпуск'") + ".");
			Рекомендации.Добавить(Символы.ПС);
		КонецЕсли;
		
		Если СводнаяИнформация.СертификатовНезаблокированных > 0 Тогда
			Рекомендации.Добавить(СимволТочкиИПробел + НСтр("ru = 'Настройте исключения расшифровки по сертификатам, которые более недоступны.'") + " ");
			Рекомендации.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'Перейти к настройке'"),,,, "#action?configure_certificates"));
			Рекомендации.Добавить(".");
			Рекомендации.Добавить(Символы.ПС);
		КонецЕсли;
		
		Рекомендации.Добавить(СимволТочкиИПробел + НСтр("ru = 'При необходимости, исключите из расшифровки конкретные сообщения.'") + " ");
		Рекомендации.Добавить(Новый ФорматированнаяСтрока(НСтр("ru = 'Перейти к настройке'"),,,, "#action?configure_documents"));
		Рекомендации.Добавить(".");
		
	ИначеЕсли СтрНайти(ОписаниеОшибки, "не найден файл описания пакета") > 0 Тогда 
		
		// в контейнере отсутствует packageDescription.xml
		
		СтатичныйТекст = НСтр("ru = 'Транспортный контейнер входящего сообщения содержит ошибки, его содержимое не может быть корректно извлечено и прочитано.'");
		ПояснениеОшибки.Добавить(СтатичныйТекст);
		
		Рекомендации.Добавить(СимволТочкиИПробел + НСтр("ru = 'Описание контейнера отсутствует.'") + " ");
		Рекомендации.Добавить(НСтр("ru = 'Запросите повторную отправку сообщения в контролирующем органе по эл. почте или телефону.'"));
		
	ИначеЕсли СтрНайти(ОписаниеОшибки, "некорректная структура файла описания пакета") > 0 Тогда 
		
		// контролирующий орган изменил схему обмена либо мы не успели её реализовать/исправить
		
		СтатичныйТекст = НСтр("ru = 'Транспортный контейнер входящего сообщения содержит ошибки, его содержимое не может быть правильно извлечено и прочитано.'");
		ПояснениеОшибки.Добавить(СтатичныйТекст);
		
		Рекомендации.Добавить(СимволТочкиИПробел + НСтр("ru = 'Расшифровка транспортного сообщения невозможна.'") + " ");
		Рекомендации.Добавить(НСтр("ru = 'Запросите повторную отправку сообщения в контролирующем органе по эл. почте или телефону.'"));
		
	ИначеЕсли СтрНайти(ОписаниеОшибки, "не определен файл подписи под документом") > 0 Тогда
		
		// в packageDescription.xml отсутствует ожидаемая подпись под документом
		
		СтатичныйТекст = НСтр("ru = 'Транспортный контейнер входящего сообщения сформирован некорректно, его содержимое частично отсутствует.'");
		ПояснениеОшибки.Добавить(СтатичныйТекст);		
		
		Рекомендации.Добавить(СимволТочкиИПробел + НСтр("ru = 'Проверка содержимого транспортного сообщения завершилась с ошибкой.'") + " ");
		Рекомендации.Добавить(НСтр("ru = 'Некоторые файлы в контейнере отсутствуют.'") + " ");
		Рекомендации.Добавить(НСтр("ru = 'Запросите повторную отправку сообщения в контролирующем органе по эл. почте или телефону.'"));
		
	ИначеЕсли СтрНайти(ОписаниеОшибки, "не удалось проверить подпись") > 0 Тогда 
		
		// в packageDescription.xml присутствует подпись под документом которого нет в информационной базе
		
		СтатичныйТекст = НСтр("ru = 'Возникла проблема проверки подписи одного из файлов транспортного сообщения.'");
		ПояснениеОшибки.Добавить(СтатичныйТекст);
		
		Рекомендации.Добавить(СимволТочкиИПробел + НСтр("ru = 'Проверка содержимого транспортного сообщения завершилась с ошибкой.'") + " ");
		Рекомендации.Добавить(НСтр("ru = 'Но на расшифровку сообщения она не влияет.'"));
		
	КонецЕсли;
	
	Элементы.ДекорацияКонтекста.Заголовок = Новый ФорматированнаяСтрока(ПояснениеОшибки);
	Элементы.ДекорацияРекомендации.Заголовок = Новый ФорматированнаяСтрока(Рекомендации);
	
КонецПроцедуры

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

&НаСервере
Процедура ОрганизацияПриИзмененииСервер()
	
	ЗаполнитьСообщенияИСертификаты();
	ИзменитьВидимостьЭлементовФормы();
	
КонецПроцедуры

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

#Область Служебные_обработчики

&НаКлиенте
Процедура ОбновитьНадписьВСтрокеСообщенийКлиент(Запись)
	
	Запись.Действие = ?(Запись.Игнорировать, "Не расшифровывать", "Расшифровывать");
	
КонецПроцедуры

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

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

&НаСервере
Процедура ОбновитьНадписьВСтрокеСообщений(Запись)
	
	Запись.Действие = ?(Запись.Игнорировать, "Не расшифровывать", "Расшифровывать");
	
КонецПроцедуры

&НаСервере
Процедура ОбновитьНадписиВТаблицах()
	
	Для Каждого Запись Из Сертификаты Цикл 
		ОбновитьНадписьВСтрокеСертификатов(Запись);
	КонецЦикла;
	
	Для Каждого Запись Из Сообщения Цикл 
		ОбновитьНадписьВСтрокеСообщений(Запись);
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура СертификатыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	Подробнее(Неопределено);
	
КонецПроцедуры

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

#Область Команды

&НаКлиенте
Процедура ПоказатьФормуЗапросаБлокировки(ОповещениеОЗакрытии, ФормаИнициатор = Неопределено)
	
	НомерСтр = ОповещениеОЗакрытии.ДополнительныеПараметры.СтрокаТаблицыСертификатов;
	СообщенийСертификата = ОповещениеОЗакрытии.ДополнительныеПараметры.КоличествоСообщений;
	СвойствоСертификата = "";
	
	Части = Новый Массив;
	Части.Добавить(
		"Подтвердите недоступность закрытого ключа для следующего сертификата:"
	);
	
	ЖирныйШрифт = Новый Шрифт(,, Истина,);
	
	Части.Добавить(Символы.ПС + Символы.ПС);
	Части.Добавить(Новый ФорматированнаяСтрока(СтрШаблон("%1", Сертификаты[НомерСтр].Описание), ЖирныйШрифт));
	Части.Добавить(Символы.ПС + Символы.ПС);
	Если СообщенийСертификата = 0 Тогда 
		Части.Добавить("Новые получаемые сообщения, зашифрованные на этом сертификате, не будут расшифровываться.
		|");
	Иначе 
		Ссылка = СтрШаблон("#view_certificate_msg?%1", НомерСтр);		
		ФорматированнаяСсылка = Новый ФорматированнаяСтрока(Строка(СообщенийСертификата),,,, Ссылка);
	
		Части.Добавить("Хранящиеся в базе нерасшифрованные транспортные сообщения (");
		Части.Добавить(ФорматированнаяСсылка);
		Части.Добавить("), а также новые
		|получаемые сообщения, зашифрованные на этом сертификате, не будут расшифровываться.
		|");
	КонецЕсли;
	ТекстВопроса = Новый ФорматированнаяСтрока(Части);
	
	Части.Очистить();
	Части.Добавить("Обратите внимание, это действие применяется для всех пользователей и рабочих мест.");
	
	ТекстВажного = Новый ФорматированнаяСтрока(Части);
	
	ПараметрыФормы = Новый Структура();
	ПараметрыФормы.Вставить("ТекстВопроса", ТекстВопроса);
	ПараметрыФормы.Вставить("ТекстВажного", ТекстВажного);
	ПараметрыФормы.Вставить("Заголовок", "");
	ПараметрыФормы.Вставить("ЗаголовокКнопкиОК", "Подтверждаю недоступность ключа");
	ПараметрыФормы.Вставить("ПоказатьПричину", Истина);
	
	Ключ = "РасширенныйДиалогВопросаСертификат";
	
	Если ФормаИнициатор = Неопределено Тогда 
		ВладелецДиалога = ЭтаФорма;
	Иначе
		ВладелецДиалога = ФормаИнициатор;
	КонецЕсли;
	
	ОткрытьФорму(
		КонтекстЭДО.ПутьКОбъекту + ".Форма.Нерасшифровываемые_РасширенныйДиалогВопроса", 
		ПараметрыФормы, 
		ВладелецДиалога, 
		Ключ,,, 
		ОповещениеОЗакрытии, 
		РежимОткрытияОкнаФормы.БлокироватьОкноВладельца
	);
	
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьФормуЗапросаРазблокировки(ОповещениеОЗакрытии, ФормаИнициатор = Неопределено)
	
	НомерСтр = ОповещениеОЗакрытии.ДополнительныеПараметры.СтрокаТаблицыСертификатов;
	СообщенийСертификата = ОповещениеОЗакрытии.ДополнительныеПараметры.КоличествоСообщений;
	СвойствоСертификата = "";
	
	Части = Новый Массив;
	Части.Добавить(
		"Подтвердите доступность закрытого ключа для следующего сертификата:"
	);
	
	ЖирныйШрифт = Новый Шрифт(,, Истина,);
	
	Части.Добавить(Символы.ПС + Символы.ПС);
	Части.Добавить(Новый ФорматированнаяСтрока(СтрШаблон("%1", Сертификаты[НомерСтр].Описание), ЖирныйШрифт));
	Части.Добавить(Символы.ПС + Символы.ПС);
	Если СообщенийСертификата = 0 Тогда 
		Части.Добавить("Новые получаемые сообщения, зашифрованные на этом сертификате, будут пытаться расшифроваться.
		|");
	Иначе 
		Ссылка = СтрШаблон("#view_certificate_msg?%1", НомерСтр);		
		ФорматированнаяСсылка = Новый ФорматированнаяСтрока(Строка(СообщенийСертификата),,,, Ссылка);
	
		Части.Добавить("Хранящиеся в базе нерасшифрованные транспортные сообщения (");
		Части.Добавить(ФорматированнаяСсылка);
		Части.Добавить("), а также новые
		|получаемые сообщения, зашифрованные на этом сертификате, будут пытаться расшифроваться.
		|");
	КонецЕсли;
	ТекстВопроса = Новый ФорматированнаяСтрока(Части);
	
	Части.Очистить();
	Части.Добавить("Обратите внимание, это действие применяется для всех пользователей и рабочих мест.");
	
	ТекстВажного = Новый ФорматированнаяСтрока(Части);
	
	ПараметрыФормы = Новый Структура();
	ПараметрыФормы.Вставить("ТекстВопроса", ТекстВопроса);
	ПараметрыФормы.Вставить("ТекстВажного", ТекстВажного);
	ПараметрыФормы.Вставить("Заголовок", "");
	ПараметрыФормы.Вставить("ЗаголовокКнопкиОК", "Подтверждаю доступность ключа");
	
	Ключ = "РасширенныйДиалогВопросаСертификат";
	
	Если ФормаИнициатор = Неопределено Тогда 
		ВладелецДиалога = ЭтаФорма;
	Иначе
		ВладелецДиалога = ФормаИнициатор;
	КонецЕсли;
	
	ОткрытьФорму(
		КонтекстЭДО.ПутьКОбъекту + ".Форма.Нерасшифровываемые_РасширенныйДиалогВопроса", 
		ПараметрыФормы, 
		ВладелецДиалога, 
		Ключ,,, 
		ОповещениеОЗакрытии, 
		РежимОткрытияОкнаФормы.БлокироватьОкноВладельца
	);
	

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

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

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

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

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

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

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

&НаКлиенте
Процедура УстановитьРасшифровкуСообщения(Режим, НомерСтр) Экспорт
	
	Сообщения[НомерСтр].Игнорировать = Режим;
	ОбновитьНадписьВСтрокеСообщенийКлиент(Сообщения[НомерСтр]);

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

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

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

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

Связанные материалы