Документооборот с контролирующими органами / Формирование пакета по ЕГРЮЛ / Модуль формы

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

&НаКлиенте
Перем МенеджерыКриптографии;

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

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

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

	ПодключитьОбработчикОжидания("Подключаемый_НачатьПолучениеКонтекста", 1, Истина);
	
КонецПроцедуры

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

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

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

&НаКлиенте
Процедура ОчиститьСертификатНажатие(Элемент)
	
	ВыбранныеСертификаты = Новый ФиксированныйМассив(Новый Массив());
	ИзменитьОформлениеСертификатов();
	
КонецПроцедуры

&НаКлиенте
Процедура КоличествоУчредителейПриИзменении(Элемент)
	КоличествоУчредителейПриИзмененииНаСервере();
КонецПроцедуры

&НаКлиенте
Процедура ПредставлениеСертификатовОбработкаНавигационнойСсылки(Элемент, Ссылка, СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;
	
	Количество = ВыбранныеСертификаты.Количество();

	Если Количество = 0 ИЛИ НесколькоУчредителей Тогда
		
		Если Количество = 0 Тогда  
			Сертификат = Неопределено;
		Иначе
			Сертификат = ВыбранныеСертификаты[Количество - 1];
		КонецЕсли;
		
		ОписаниеОповещения = Новый ОписаниеОповещения(
			"СертификатНачалоВыбора_ПослеВыбораСертификата", 
			ЭтотОбъект);
			
		ДопПараметры = ПараметрыВыбораСертификата(Сертификат);

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

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

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

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

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

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

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

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

#Область ОбъединениеСканыВТиф

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

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

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

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

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

#Область Подписание

&НаКлиенте
Процедура ПодписатьДанные_ПослеПолученияСвойствСертификата(Результат, ВходящийКонтекст) Экспорт
	
	ТекущийФайл = 0;
	ПодписатьСледующийФайл(, ВходящийКонтекст);
	
КонецПроцедуры

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

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

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

&НаКлиенте
Процедура ВыполнитьДействиеПослеПодписанияОдного(ВходящийКонтекст) Экспорт
	
	ТекущийФайл = ТекущийФайл + 1;
	ПодписатьСледующийФайл(, ВходящийКонтекст);
	
КонецПроцедуры

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

&НаКлиенте
Процедура ДобавитьПодписьВОписание(АдресПодписи)
	
	ТекущееОписание = ОписаниеФайлов[ТекущийФайл];
	
	Если НЕ ТекущееОписание.Свойство("Подписи") Тогда
		ТекущееОписание.Вставить("Подписи", Новый Массив);
	КонецЕсли;      
	
	Сертификат = ВыбранныеСертификаты[НомерСертификата];
	
	Подпись = Новый Структура();
	Подпись.Вставить("АдресПодписи",    АдресПодписи);
	Подпись.Вставить("ИмяФайлаПодписи", ТекущееОписание.ИмяФайла + ПостфиксПодписи(НомерСертификата + 1));
	
	ТекущееОписание.Подписи.Добавить(Подпись);
	
КонецПроцедуры

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

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

#Область Сертификат

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

&НаКлиенте
Процедура ОбработатьОшибкуПоискаСертификата(ДополнительныеПараметры, ТекстОшибки)
	
	ПоказатьОшибкуПоискаСертификата(ТекстОшибки);
	ПроверитьВыводСообщений();

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

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

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

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

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

&НаКлиенте
Процедура ПолучитьСертификаты_ПослеЗаполненияСведенийВыбранногоСертификата(Результат, ДополнительныеПараметры) Экспорт
	
	ПоказатьСтраницуВыбораСертификата();
	
КонецПроцедуры

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

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

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

	// Организация
	Если ВладелецСтруктура.Свойство("O") Тогда
		Организация = ВладелецСтруктура["O"];
	Иначе
		Организация = "";
	КонецЕсли;
	
	СвойстваРезультат.Вставить("Организация", Организация);
	
	// Подразделение
	Если ВладелецСтруктура.Свойство("OU") Тогда
		Подразделение = ВладелецСтруктура["OU"];
	Иначе
		Подразделение = "";
	КонецЕсли;
	
	СвойстваРезультат.Вставить("Подразделение", Подразделение);
	
	// ЭлектроннаяПочта
	Если ВладелецСтруктура.Свойство("E") Тогда
		ЭлектроннаяПочта = ВладелецСтруктура["E"];
	Иначе
		ЭлектроннаяПочта = "";
	КонецЕсли;
	
	СвойстваРезультат.Вставить("ЭлектроннаяПочта", ЭлектроннаяПочта);	

	// Должность
	Если ВладелецСтруктура.Свойство("T") Тогда
		Должность = ВладелецСтруктура["T"];
	Иначе
		Должность = "";
	КонецЕсли;
	
	СвойстваРезультат.Вставить("Должность", Должность);
	
	// ИНН
	ИНН = ДокументооборотСКОКлиентСервер.ИННИзСертификата(ВладелецСтруктура, Ложь);
	СвойстваРезультат.Вставить("ИНН", ИНН);
	
	// СНИЛС
	Если ВладелецСтруктура.Свойство("SNILS") Тогда
		СНИЛС = ВладелецСтруктура["SNILS"];
	Иначе
		СНИЛС = "";
	КонецЕсли;
	
	СвойстваРезультат.Вставить("СНИЛС", СНИЛС);

	Возврат СвойстваРезультат;

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

&НаКлиентеНаСервереБезКонтекста
Функция ЗначениеПоля(СтрЗначениеПоля)
	
	Возврат ?(НЕ ЗначениеЗаполнено(СтрЗначениеПоля) ИЛИ СокрЛП(СтрЗначениеПоля) = "0", "", СтрЗначениеПоля);
	
КонецФункции

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

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

&НаКлиенте
Процедура ЗаполнитьДанныеВладельца(Сертификат, НовыйСертификат)
	
	Если Сертификат.Свойство("ВладелецСтруктура") Тогда
		
		ВладелецСтруктура = Сертификат.ВладелецСтруктура;
		
		Если ВладелецСтруктура.Свойство("SN")
			И ВладелецСтруктура.Свойство("GN") Тогда
			
			НовыйСертификат.Вставить("Фамилия", ВладелецСтруктура.SN);
			
			ИмяОтчество = ВладелецСтруктура.GN;
			ИмяОтчествоМассив = СтрРазделить(ИмяОтчество, " ");
			
			НовыйСертификат.Вставить("Имя", ИмяОтчествоМассив[0]);
			Отчество = "";
			Если ИмяОтчествоМассив.Количество() > 1 Тогда
				Отчество = ИмяОтчествоМассив[1];
			Иначе
				Отчество = "";
			КонецЕсли;
			НовыйСертификат.Вставить("Отчество", Отчество);
			
		КонецЕсли;
		
		Если ВладелецСтруктура.Свойство("INN") Тогда
			ИНН = ВладелецСтруктура.INN;
			Если НЕ Лев(ИНН, 2) = "00" Тогда
				НовыйСертификат.Вставить("ИНН", ИНН)
			КонецЕсли;
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

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

&НаКлиенте
Процедура РасчитатьСведенияВыбранногоСертификата(ВыполяемоеОповещение)
	
	ДопПараметры = Новый Структура();
	ДопПараметры.Вставить("ВыполяемоеОповещение", ВыполяемоеОповещение);
	
	ОписаниеОповещения = Новый ОписаниеОповещения(
		"СертификатНачалоВыбора_ПослеПолученияДвДанныхВыбранногоСертификата", 
		ЭтотОбъект, 
		ДопПараметры);
		
	Сертификат = ВыбранныеСертификаты[НомерСертификата];
	
	КриптографияЭДКОКлиент.ЭкспортироватьСертификатВBase64(ОписаниеОповещения, Сертификат, Ложь);
	
КонецПроцедуры

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

	Возврат ДопПараметры;
		
КонецФункции

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

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

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

			КонецЕсли;
			
		КонецЕсли;
		
	Иначе
		
		Если Результат.CryptoProCSPУстановлен Тогда
			CryptoPro = ПредопределенноеЗначение("Перечисление.ТипыКриптоПровайдеров.CryptoPro");
			ДополнительныеПараметры.Вставить("Криптопровайдер", CryptoPro);
		ИначеЕсли Результат.ViPNetCSPУстановлен Тогда
			VipNet = ПредопределенноеЗначение("Перечисление.ТипыКриптоПровайдеров.VipNet");
			ДополнительныеПараметры.Вставить("Криптопровайдер", VipNet);
		КонецЕсли;
		
	КонецЕсли;

	СертификатНачалоВыбора_ПослеПроверкиКриптопровайдера(ДополнительныеПараметры);
	
КонецПроцедуры

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

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

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

	КонецЕсли;
	
КонецПроцедуры

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

#Область ИзменениеОформленияФормы

&НаСервере
Процедура ПоказатьСтраницуВыбораСертификата()
	
	Заголовок = НСтр("ru = 'Выбор сертификата'");
	АктивизироватьСтраницу(ЭтотОбъект, Элементы.СертификатИПароль);
	ИзменитьОформлениеСертификатов();
	
КонецПроцедуры

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

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

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

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

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

&НаКлиентеНаСервереБезКонтекста
Процедура АктивизироватьСтраницу(Форма, ТекущаяСтраница)
	
	ДокументооборотСКОКлиентСервер.АктивизироватьСтраницу(Форма.Элементы.Этапы, ТекущаяСтраница);
	
КонецПроцедуры

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

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

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

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

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

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

&НаСервере
Функция РазрешеноНесколькоСертификатов()
	
	Возврат Истина;
	
КонецФункции

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

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

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

&НаКлиенте
Процедура ОтменитьОперациюКлиент()
	
	РезультатВернули = Истина;
	Закрыть();
	
КонецПроцедуры

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

#Область Пакет

#Область Общие

&НаКлиенте
Процедура Подключаемый_СформироватьПакет()
	
	ПодготовитьОписаниеФайлов();
	
	// Опись готовим до подписания, потому что ее надо подписывать
	// packageDescription готовим после подписания, потому что его подписывать НЕ надо
	ПодготовитьОпись();
	
	НомерСертификата = 0;
	ПодписатьДанныеСледующейПодписью();
	
КонецПроцедуры

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

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

	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПодписатьДанныеСледующейПодписью_ПослеПодписания(Результат, ВходящийКонтекст) Экспорт

	// Чтобы не было ошибки передачи на сервер
	ТекущийСертификат = ВыбранныеСертификаты[НомерСертификата];
	МенеджерыКриптографии.Вставить(НомерСертификата, ТекущийСертификат.МенеджерКриптографии);
	
	ТекущийСертификат = ВыбранныеСертификаты[НомерСертификата];
	ТекущийСертификат.МенеджерКриптографии   = Неопределено;
	ТекущийСертификат.СертификатКриптографии = Неопределено;
	
	НомерСертификата = НомерСертификата + 1;
	ПодписатьДанныеСледующейПодписью();
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ПостфиксПодписи(Номер)
	
	Возврат ".zayav_" + Формат(Номер, "ЧГ=0") + ".p7s";

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

&НаСервере
Функция ПостфиксПоЛатински()
	
	Если ЭтоЮрЛицо Тогда 
		Возврат "UL";
	Иначе
		Возврат "IP";
	КонецЕсли;
	
КонецФункции

&НаСервере
Функция ПостфиксПоРусски()
	
	Если ЭтоЮрЛицо Тогда 
		Возврат "ЮЛ";
	Иначе
		Возврат "ИП";
	КонецЕсли;
	
КонецФункции

&НаСервере
Функция УникальныйИдентификаторБезТире()
	
	Возврат СтрЗаменить(Новый УникальныйИдентификатор(), "-", "");
	
КонецФункции

&НаСервере
Процедура ПодготовитьОписаниеФайлов()
	
	ОписаниеФайлов = ОбщегоНазначения.СкопироватьРекурсивно(ОписаниеФайловИсходное);
	UUIDы = UUIDы();

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

&НаСервере
Функция UUIDы()
	
	ВидыДокументов = Новый Соответствие;
	Для каждого ОписаниеФайла Из ОписаниеФайловИсходное Цикл
		ВидыДокументов.Вставить(ОписаниеФайла.ВидДокумента, УникальныйИдентификаторБезТире());
	КонецЦикла;
	
	Возврат ВидыДокументов;
	
КонецФункции

&НаСервере
Процедура ПодготовитьОпись()
	
	Опись = Опись();
	ДобавитьОписьВОписание(Опись);
	
КонецПроцедуры

&НаКлиенте
Процедура СформироватьПакетПослеПодписания()
	
	ПодготовитьpackageDescription();
	СформироватьРезультат();
	
КонецПроцедуры

&НаСервере
Функция ИНН()
	
	Если ЗначениеЗаполнено(ИНН_ФЛ) Тогда
		ИНН = ИНН_ФЛ;
	Иначе
		ИНН = "000000000000";
	КонецЕсли;
	
	Возврат ИНН;
	
КонецФункции

&НаСервере
Функция ИмяПакета()
	
	Подстроки = Новый Массив;
	Подстроки.Добавить("FNS");
	Подстроки.Добавить(ИНН()); // идентификатор отправителя
	Подстроки.Добавить(КодНО); // идентификатор получателя
	Подстроки.Добавить(Строка(Новый УникальныйИдентификатор())); // UUID
	Подстроки.Добавить(ПостфиксПоРусски()); // код типа документооборота
	Подстроки.Добавить("01"); // код типа транзакции
	Подстроки.Добавить("01"); // код типа документа
	
	Имя = СтрСоединить(Подстроки, "_");
	Имя = Имя + ".zip";
	
	Возврат Имя;

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

&НаСервере
Функция АдресПакета()
	
	ПолноеИмяФайлаПакета = ПолучитьИмяВременногоФайла();
	
	// создаем архив
	ЗаписьZIP = Новый ЗаписьZipФайла(ПолноеИмяФайлаПакета);

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

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

&НаСервере
Процедура ЗаписатьФИО(ОбъектЗапись, Сертификат)

	ОбъектЗапись.ЗаписатьНачалоЭлемента("ФИО");
		
	ОбъектЗапись.ЗаписатьАтрибут("Фамилия", Сертификат.Фамилия);
	ОбъектЗапись.ЗаписатьАтрибут("Имя",     Сертификат.Имя);
	Если ЗначениеЗаполнено(СведенияЗаявителя(Сертификат, "Отчество")) Тогда
		ОбъектЗапись.ЗаписатьАтрибут("Отчество", СведенияЗаявителя(Сертификат, "Отчество"));
	КонецЕсли;
	
	ОбъектЗапись.ЗаписатьКонецЭлемента(); // ФИО
	
КонецПроцедуры

&НаСервере
Функция СведенияИзЗаявления(Свойство)

	Возврат ЗначениеИзСтруктуры(СведенияИзЗаявления, Свойство);

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

&НаСервере
Функция СведенияЗаявителя(Заявитель, Свойство)

	Возврат ЗначениеИзСтруктуры(Заявитель, Свойство);

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

&НаСервере
Функция ЗначениеИзСтруктуры(Структура, Свойство)

	Если Структура.Свойство(Свойство) Тогда
		Значение = Структура[Свойство];
		Если Значение = Неопределено Тогда
			Возврат "";
		Иначе
			Возврат Структура[Свойство];
		КонецЕсли;
	Иначе
		Возврат "";
	КонецЕсли;

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

&НаКлиентеНаСервереБезКонтекста
Функция ЭтоXML(Данные)
	
	ЭтоXML =  Данные.Свойство("ТипыСодержимогоЗаявления") 
		И Данные.ТипыСодержимогоЗаявления = ПредопределенноеЗначение("Перечисление.ТипыСодержимогоФайлов.xml");
		
	Возврат ЭтоXML;
	
КонецФункции

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

&НаСервере
Функция СвойстваДокумента(ОписаниеФайла) 
	
	ВидДокумента = ЗначениеИзСтруктуры(ОписаниеФайла, "ВидДокумента");
	Виды = ВидыДокументовДляЭлГосРегистрации();
	
	Отбор = Новый Структура();
	Отбор.Вставить("Значение", ВидДокумента);
	
	НайденныеСтроки = Виды.НайтиСтроки(Отбор);
	
	Свойства = ОбщегоНазначения.СтрокаТаблицыЗначенийВСтруктуру(НайденныеСтроки[0]);
	
	Если ЭтоXML(ОписаниеФайла) Тогда
		
		Свойства.Вставить("типСодержимого", "xml");
		Свойства.Вставить("Расширение", "xml");
		Свойства.Вставить("кодТипаДокумента", Свойства.кодТипаДокументаXML);
		Свойства.ТипДокумента = Свойства.ТипДокумента + "формат";
		Свойства.ПрефиксФайла = Свойства.ПрефиксФайла + "xml";
		
	ИначеЕсли ЭтоPDF(ОписаниеФайла) Тогда
		
		Свойства.Вставить("кодТипаДокумента", Свойства.кодТипаДокументаНеXML);
		Свойства.Вставить("типСодержимого", "pdf");
		Свойства.Вставить("Расширение", "pdf");
		
	Иначе
		
		Свойства.Вставить("кодТипаДокумента", Свойства.кодТипаДокументаНеXML);
		Свойства.Вставить("типСодержимого", "tiff");
		Свойства.Вставить("Расширение", "tif");
		
	КонецЕсли;
	
	Возврат Свойства;

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

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

	Закрыть(ДополнительныеПараметры);
	
КонецПроцедуры

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

#Область Опись

&НаСервере
Процедура Опись_ЗаписатьЭлементПодпись(ОбъектЗапись, ОписаниеФайла)

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

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

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

&НаСервере
Процедура Опись_ЗаписатьЭлементСвЗаявит(ОбъектЗапись)
	
	Если ЭтоЮрЛицо Тогда
		
		Для каждого Сертификат Из ВыбранныеСертификаты Цикл
			
			ОбъектЗапись.ЗаписатьНачалоЭлемента("СвЗаявит");
			Если ЗначениеЗаполнено(ЭлПочтаЗаявителя) Тогда
				ОбъектЗапись.ЗаписатьАтрибут("E-mail", ЭлПочтаЗаявителя);
			КонецЕсли;
			ЗаписатьФИО(ОбъектЗапись, Сертификат);
			ОбъектЗапись.ЗаписатьКонецЭлемента(); // СвЗаявит
		КонецЦикла;
		
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура Опись_ЗаписатьЭлементСвЮЛ(ОбъектЗапись)
	
	ОбъектЗапись.ЗаписатьНачалоЭлемента("СвЮЛ");
	
	НаимЮЛПолн = СведенияИзЗаявления("НаимЮЛПолн");
	Если ЗначениеЗаполнено(НаимЮЛПолн) Тогда
		ОбъектЗапись.ЗаписатьАтрибут("НаимЮЛПолн", НаимЮЛПолн);
	КонецЕсли;
	
	ОГРН = СведенияИзЗаявления("ОГРН");
	Если ЗначениеЗаполнено(ОГРН) Тогда
		ОбъектЗапись.ЗаписатьАтрибут("ОГРН", ОГРН);
	КонецЕсли;
	
	ОбъектЗапись.ЗаписатьКонецЭлемента(); // СвЮЛ
	
КонецПроцедуры

&НаСервере
Процедура Опись_ЗаписатьЭлементСвИП(ОбъектЗапись)
	
	ОбъектЗапись.ЗаписатьНачалоЭлемента("СвИП");
	
	Если ЗначениеЗаполнено(СведенияИзЗаявления("ИНН")) Тогда
		ОбъектЗапись.ЗаписатьАтрибут("ИННФЛ", СведенияИзЗаявления("ИНН"));
	КонецЕсли;
	Если ЗначениеЗаполнено(СведенияИзЗаявления("ОГРНИП")) Тогда
		ОбъектЗапись.ЗаписатьАтрибут("ОГРНИП", СведенияИзЗаявления("ОГРНИП"));
	КонецЕсли;
	Если ЗначениеЗаполнено(ЭлПочтаЗаявителя) Тогда
		ОбъектЗапись.ЗаписатьАтрибут("E-mail", ЭлПочтаЗаявителя);
	КонецЕсли;
	
	Сертификат = ВыбранныеСертификаты[0];
	ЗаписатьФИО(ОбъектЗапись, Сертификат);
	
	ОбъектЗапись.ЗаписатьКонецЭлемента(); // СвИП
	
КонецПроцедуры

&НаСервере
Процедура Опись_ЗаписатьЭлементФайл(ОбъектЗапись, ИдФайл)
	
	ОбъектЗапись.ЗаписатьНачалоЭлемента("Файл");
	ОбъектЗапись.ЗаписатьАтрибут("ИдФайл", ИдФайл);
	
	Если ЭтоЮрЛицо Тогда
		ОбъектЗапись.ЗаписатьАтрибут("ВерсФорм", "9.04");
	Иначе
		ОбъектЗапись.ЗаписатьАтрибут("ВерсФорм", "9.05");
	КонецЕсли;
	
	ОбъектЗапись.ЗаписатьАтрибут("ВерсПрог", РегламентированнаяОтчетность.НазваниеИВерсияПрограммы());
	ОбъектЗапись.ЗаписатьАтрибут("КодСФРД",  СведенияИзЗаявления("КодЗаявления"));
	ОбъектЗапись.ЗаписатьАтрибут("КодНО",    КодНО);
	
	ПрВысБум = СпособыПредоставленияОтвета.Получить(СпособПредоставленияОтвета); 
	Если ПрВысБум <> "0" И ЗначениеЗаполнено(ПрВысБум) Тогда
		ОбъектЗапись.ЗаписатьАтрибут("ПрВысБум", ПрВысБум);
	КонецЕсли;
	
	Если ЭтоЮрЛицо Тогда
		Опись_ЗаписатьЭлементСвЮЛ(ОбъектЗапись);
	Иначе
		Опись_ЗаписатьЭлементСвИП(ОбъектЗапись);
	КонецЕсли;
	
	Опись_ЗаписатьЭлементСвЗаявит(ОбъектЗапись);
	
	Для каждого ОписаниеФайла Из ОписаниеФайлов Цикл
		Опись_ЗаписатьЭлементДокумент(ОбъектЗапись, ОписаниеФайла);
	КонецЦикла;
	
	ОбъектЗапись.ЗаписатьКонецЭлемента(); // Файл
	
КонецПроцедуры

&НаСервере
Функция Опись()
	
	УникальныйИдентификаторОписи = УникальныйИдентификаторБезТире();
	
	Шаблон = "OP_REG%1_%2_%3";
	ИдФайл = СтрШаблон(
		Шаблон,
		ПостфиксПоЛатински(),
		Формат(ТекДата, "ДФ=yyyyMMdd"),
		Строка(УникальныйИдентификаторОписи));
		
	ИдФайл = ВРег(ИдФайл);
	
	КороткоеИмяФайла = ИдФайл + ".xml";
	ПолноеИмяФайла = КаталогВременныхФайлов() + КороткоеИмяФайла;

	ОбъектЗапись = Новый ЗаписьXML;
	ОбъектЗапись.ОткрытьФайл(ПолноеИмяФайла, "windows-1251");
	ОбъектЗапись.ЗаписатьОбъявлениеXML();

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

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

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

#Область packageDescription

&НаСервере
Процедура packageDescription_отправитель(ОбъектЗапись)
	
	ОбъектЗапись.ЗаписатьНачалоЭлемента("отправитель");
	ОбъектЗапись.ЗаписатьАтрибут("идентификаторСубъекта", ИНН());
	ОбъектЗапись.ЗаписатьАтрибут("типСубъекта", "заявитель");
	ОбъектЗапись.ЗаписатьКонецЭлемента(); // отправитель

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

&НаСервере
Процедура packageDescription_получатель(ОбъектЗапись)
	
	ОбъектЗапись.ЗаписатьНачалоЭлемента("получатель");
	ОбъектЗапись.ЗаписатьАтрибут("идентификаторСубъекта", КодНО);
	ОбъектЗапись.ЗаписатьАтрибут("типСубъекта", "налоговыйОрган");
	ОбъектЗапись.ЗаписатьКонецЭлемента(); // получатель

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

&НаСервере
Процедура packageDescription_документ(ОбъектЗапись, ОписаниеФайла)
	
	ЭтоОпись = ОписаниеФайла.Свойство("ЭтоОпись") И ОписаниеФайла.ЭтоОпись;
	
	ОбъектЗапись.ЗаписатьНачалоЭлемента("документ");
	
	Если ЭтоОпись Тогда
		кодТипаДокумента = "07";
		типДокумента     = "ОписьДокументов" + ПостфиксПоРусски();
		типСодержимого   = "xml";
	Иначе
		Свойства         = СвойстваДокумента(ОписаниеФайла);
		кодТипаДокумента = Свойства.кодТипаДокумента;
		типДокумента     = Свойства.типДокумента;
		типСодержимого   = Свойства.типСодержимого;
	КонецЕсли;
	
	ОбъектЗапись.ЗаписатьАтрибут("кодТипаДокумента", кодТипаДокумента);
	ОбъектЗапись.ЗаписатьАтрибут("типДокумента", типДокумента);
	ОбъектЗапись.ЗаписатьАтрибут("типСодержимого", типСодержимого);
	ОбъектЗапись.ЗаписатьАтрибут("сжат", XMLСтрока(Ложь));
	ОбъектЗапись.ЗаписатьАтрибут("зашифрован", XMLСтрока(Ложь));
	ОбъектЗапись.ЗаписатьАтрибут("идентификаторДокумента", XMLСтрока(ОписаниеФайла.ИдДок));
	ОбъектЗапись.ЗаписатьАтрибут("исходноеИмяФайла", ОписаниеФайла.ИсхИмяФайла);
	
	ОбъектЗапись.ЗаписатьНачалоЭлемента("содержимое");
	ОбъектЗапись.ЗаписатьАтрибут("имяФайла", ОписаниеФайла.ИмяФайла);
	ОбъектЗапись.ЗаписатьКонецЭлемента(); // содержимое
	
	Для каждого Подпись Из ОписаниеФайла.Подписи Цикл
		ОбъектЗапись.ЗаписатьНачалоЭлемента("подпись");
		ОбъектЗапись.ЗаписатьАтрибут("имяФайла", Подпись.ИмяФайлаПодписи);
		ОбъектЗапись.ЗаписатьАтрибут("роль", "заявитель");
		ОбъектЗапись.ЗаписатьКонецЭлемента(); // подпись
	КонецЦикла;
	
	ОбъектЗапись.ЗаписатьКонецЭлемента(); // документ

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

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

	ОбъектЗапись.ЗаписатьКонецЭлемента(); // ТрансИнф
	
КонецПроцедуры

&НаСервере
Процедура ПодготовитьpackageDescription()
	
	КороткоеИмяФайла = "packageDescription.xml";
	ПолноеИмяФайла = КаталогВременныхФайлов() + КороткоеИмяФайла;
	
	ОбъектЗапись = Новый ЗаписьXML;
	ОбъектЗапись.ОткрытьФайл(ПолноеИмяФайла, "windows-1251");
	ОбъектЗапись.ЗаписатьОбъявлениеXML();
	
	packageDescription_ТрансИнф(ОбъектЗапись);
	
	ОбъектЗапись.Закрыть();
	
	ДвДанные = Новый ДвоичныеДанные(ПолноеИмяФайла);
	АдресФайла = ПоместитьВоВременноеХранилище(ДвДанные, УникальныйИдентификатор);
	
	packageDescription_ДобавитьВОписание(АдресФайла, КороткоеИмяФайла);

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

&НаСервере
Процедура packageDescription_ДобавитьВОписание(АдресФайла, КороткоеИмяФайла)
	
	АдресаФайлов = Новый Массив;
	АдресаФайлов.Добавить(АдресФайла);
	
	ДополнительныеПараметры = Новый Структура();
	ДополнительныеПараметры.Вставить("ЭтоpackageDescription",     Истина);
	ДополнительныеПараметры.Вставить("ИмяФайла",     КороткоеИмяФайла);
	ДополнительныеПараметры.Вставить("ИсхИмяФайла",  КороткоеИмяФайла);
	ДополнительныеПараметры.Вставить("АдресаФайлов", АдресаФайлов);
	ДополнительныеПараметры.Вставить("АдресИтоговогоФайла", АдресФайла);
	
	ОписаниеФайловМассив = Новый Массив(ОписаниеФайлов);
	ОписаниеФайловМассив.Добавить(ДополнительныеПараметры);
	ОписаниеФайлов = Новый ФиксированныйМассив(ОписаниеФайловМассив);
	
КонецПроцедуры

&НаСервере
Процедура КоличествоУчредителейПриИзмененииНаСервере()
	
    НесколькоУчредителей = КоличествоУчредителей = НСтр("ru = 'Несколько'");
	
	Количество = ВыбранныеСертификаты.Количество();
	Если НЕ НесколькоУчредителей И ВыбранныеСертификаты.Количество() > 1 Тогда
		
		Сертификат = ВыбранныеСертификаты[Количество - 1];
		
		ВыбранныеСертификатыМассив = Новый Массив;
		ВыбранныеСертификатыМассив.Добавить(Сертификат);
		
		ВыбранныеСертификаты = Новый ФиксированныйМассив(ВыбранныеСертификатыМассив);
		
	КонецЕсли;
	
	ИзменитьОформлениеСертификатов();
	
КонецПроцедуры

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

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

#Область ОтправкаПакета

&НаКлиенте
Процедура ОтправитьДокументыПосле()
	
	Если ВыбранныеСертификаты.Количество() = 0 Тогда
		ОбщегоНазначенияКлиент.СообщитьПользователю(НСтр("ru = 'Выберите сертификат'"));
		Возврат;  
	КонецЕсли;
	
	ОтправитьДокументы = Истина;
	ОбъединитьВTIFСканы();
	
КонецПроцедуры

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

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

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

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

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

&НаКлиенте
Процедура ТекстОшибкиОбработкаНавигационнойСсылки(Элемент, Ссылка, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;

	Если Ссылка = "CryptoPro" Тогда
		
		Оповещение = Новый ОписаниеОповещения("СкачатьCryptoProПослеУстановки", ЭтотОбъект);
		ОбщегоНазначенияЭДКОКлиент.УстановитьCryptoProCSP(Оповещение, ЭтаФорма);
	
	ИначеЕсли Ссылка = "ViPNet" Тогда

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

&НаКлиенте
Процедура СкачатьViPNetПослеУстановки(Результат, ВходящийКонтекст) Экспорт
	
	Если НЕ Результат.Выполнено Тогда
		ОбщегоНазначенияКлиент.СообщитьПользователю(НСтр("ru = 'Не удалось установить ViPNet CSP.'"));
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура СкачатьCryptoProПослеУстановки(Результат, ВходящийКонтекст) Экспорт
	
	Если НЕ Результат.Выполнено Тогда
		ОбщегоНазначенияКлиент.СообщитьПользователю(НСтр("ru = 'Не удалось установить CryptoPro CSP.'"));
	КонецЕсли;
	
КонецПроцедуры

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

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

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