Заявление на выпуск нового квалифицированного сертификата / Модуль менеджера

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

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

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

// Возвращает Истина, если в конфигурации используются все перечисленные подсистемы:
// 1. Подсистема Контактная информация  - для работы с российскими адресами.
// 2. Подсистема Адресный классификатор - для получения кода региона по наименованию.
// 3. Подсистема Печать - для печатной формы заявления на выпуск сертификата.
// 4. Подсистема Интернет поддержка пользователей - для подключения к сервисам 1С.
//
// Возвращаемое значение:
//   Булево
//
Функция ЗаявлениеНаВыпускСертификатаДоступно() Экспорт
	
	Возврат ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.КонтактнаяИнформация")
		И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор")
		И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Печать")
		И ОбщегоНазначения.ПодсистемаСуществует("ИнтернетПоддержкаПользователей");
	
КонецФункции

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

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

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

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

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

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

Процедура ДополнитьЗапросСпискаСертификатов(ТекстЗапроса) Экспорт
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса,
		"Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования КАК СертификатыПереопределяемый", "
		|Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования КАК СертификатыПереопределяемый
		|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗаявленияНаВыпускСертификата КАК ЗаявленияНаВыпускСертификата
		|		ПО СертификатыПереопределяемый.Ссылка = ЗаявленияНаВыпускСертификата.Сертификат");
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса,
		"&ДополнительноеУсловие",
		"(ЗаявленияНаВыпускСертификата.СостояниеЗаявления Есть NULL
		|	 ИЛИ ЗаявленияНаВыпускСертификата.СостояниеЗаявления = ЗНАЧЕНИЕ(Перечисление.СостоянияЗаявленияНаВыпускСертификата.Исполнено))");
	
КонецПроцедуры

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

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

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

// Добавить легенду.
// 
// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  ГруппаЛегенда - ГруппаФормы
//
Процедура ДобавитьЛегенду(Форма, ГруппаЛегенда) Экспорт
	
	ГруппаЗаявление = Форма.Элементы.Добавить("ГруппаЗаявление", Тип("ГруппаФормы"), ГруппаЛегенда);
	ГруппаЗаявление.Вид = ВидГруппыФормы.ОбычнаяГруппа;
	ГруппаЗаявление.Группировка = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда;
	ГруппаЗаявление.ОтображатьЗаголовок = Ложь;
	ДекорацияКартинка = Форма.Элементы.Добавить("ДекорацияКартинкаЗаявление", Тип("ДекорацияФормы"), ГруппаЗаявление);
	ДекорацияКартинка.Вид = ВидДекорацииФормы.Картинка;
	ДекорацияКартинка.Картинка = БиблиотекаКартинок.ЗаявлениеНаВыпускСертификатаКлюча;
	ДекорацияНадпись = Форма.Элементы.Добавить("ДекорацияНадписьЗаявление", Тип("ДекорацияФормы"), ГруппаЗаявление);
	ДекорацияНадпись.Вид = ВидДекорацииФормы.Надпись;
	ДекорацияНадпись.Заголовок = НСтр("ru = 'Заявление на выпуск квалифицированного сертификата'");
	
КонецПроцедуры

// Параметры:
//  НеРедактируемыеРеквизиты - Массив
//
Процедура РеквизитыНеРедактируемыеВГрупповойОбработке(НеРедактируемыеРеквизиты) Экспорт
	
	НеРедактируемыеРеквизиты.Добавить("ДатаПолученияСертификата");
	
КонецПроцедуры

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

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

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

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  ПроверяемыеРеквизиты - Массив
//  РеквизитыДляПроверки - СписокЗначений
//  ПолеСообщения - Строка
//  ШаблонСообщения - Строка
//
Процедура ДобавитьРеквизитыДляПроверки(Форма, ПроверяемыеРеквизиты, РеквизитыДляПроверки,
			ПолеСообщения = "", ШаблонСообщения = "%1:") Экспорт
	
	Для Каждого Реквизит Из РеквизитыДляПроверки Цикл
		
		ИмяРеквизита = Реквизит.Значение;
		
		ПараметрыРеквизитаДляПроверки = Новый Структура;
		ПараметрыРеквизитаДляПроверки.Вставить("Имя", ИмяРеквизита);
		Если ИмяРеквизита = "Телефон"
			Или ИмяРеквизита = "ЮридическийАдрес"
			Или ИмяРеквизита = "ВладелецТелефон" Тогда
			ПараметрыРеквизитаДляПроверки.Вставить("Значение", Форма[ИмяРеквизита + "XML"]);
		Иначе
			ПараметрыРеквизитаДляПроверки.Вставить("Значение", Форма[ИмяРеквизита]);
		КонецЕсли;
		ПараметрыРеквизитаДляПроверки.Вставить("ПолеСообщения",
			?(ЗначениеЗаполнено(ПолеСообщения), ПолеСообщения, ИмяРеквизита));
		
		Если Реквизит.Пометка Тогда
			ТекстНезаполненного = "";
		Иначе
			ТекстНезаполненного = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				ШаблонСообщения, Реквизит.Представление);
		КонецЕсли;
		ПараметрыРеквизитаДляПроверки.Вставить("ТекстНезаполненного", ТекстНезаполненного);
		ПараметрыРеквизитаДляПроверки.Вставить("ТекстПроверкиЗначения",
			СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонСообщения, Реквизит.Представление));
		
		ПроверяемыеРеквизиты.Добавить(ПараметрыРеквизитаДляПроверки);
		
	КонецЦикла;
	
КонецПроцедуры

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

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

Функция ТекстОшибкиПолеНеЗаполнено() Экспорт
	Возврат НСтр("ru = 'Поле не заполнено'");
КонецФункции

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

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

Функция ОшибкиПроверкиБИК(БИК)
	
	Значение = СокрЛП(БИК);
	Если НЕ СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(Значение) Тогда
		Возврат НСтр("ru = 'БИК должен состоять только из цифр.'");
	КонецЕсли;
	
	Если СтрДлина(Значение) <> 9 Тогда
		Возврат НСтр("ru = 'БИК должен состоять из 9 цифр.'");
	КонецЕсли;
	
	Возврат "";
	
КонецФункции

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

	Если СтрДлина(Значение) <> 20 Тогда
		Возврат НСтр("ru = 'Корреспондентский счет должен состоять из 20 цифр.'");
	КонецЕсли;
	
	Возврат "";
	
КонецФункции

Функция ОшибкиПроверкиТелефона(Знач ТелефонXML)
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.КонтактнаяИнформация") Тогда
		Возврат "";
	КонецЕсли;
	
	МодульУправлениеКонтактнойИнформацией = ОбщегоНазначения.ОбщийМодуль("УправлениеКонтактнойИнформацией");
	
	ТекстСообщения = Новый Массив;
	ТелефонСтруктура = МодульУправлениеКонтактнойИнформацией.СведенияОТелефоне(ТелефонXML);
	
	// Проверка, что телефон российский.
	Если СтрЗаменить(ТелефонСтруктура.КодСтраны, "+", "") <> "7" Тогда
		ТекстСообщения.Добавить(НСтр("ru = 'Код страны не российский (должен быть ""7"")'"));
	КонецЕсли;
	
	НомерТелефонаБезКодаСтраны = ТелефонСтруктура.КодГорода + ТелефонСтруктура.НомерТелефона;
	
	Если Не ЗначениеЗаполнено(НомерТелефонаБезКодаСтраны) Тогда
		ТекстСообщения.Добавить(НСтр("ru = 'Не заполнен номер телефона'"));
		Возврат СтрСоединить(ТекстСообщения, Символы.ПС);
	КонецЕсли;
	
	КодГородаТолькоЦифры = ТолькоЦифры(ТелефонСтруктура.КодГорода);
	Если СтрДлина(КодГородаТолькоЦифры) < 3 Или СтрДлина(КодГородаТолькоЦифры) > 5 Тогда
		ТекстСообщения.Добавить(НСтр("ru = 'Код города должен состоять из 3-5 цифр'"));
	КонецЕсли;
	
	Если СтрДлина(ТолькоЦифры(НомерТелефонаБезКодаСтраны)) <> 10 Тогда
		ТекстСообщения.Добавить(НСтр("ru = 'Номер телефона с кодом города должен состоять из 10-и цифр'"));
	КонецЕсли;
	
	Если СтрДлина(ТелефонСтруктура.Добавочный) > 6 Тогда
		ТекстСообщения.Добавить(НСтр("ru = 'Добавочный номер телефона не может быть длиннее 6 символов.'"));
	КонецЕсли;
	
	Если ТекстСообщения.Количество() > 0 Тогда
		Возврат СтрСоединить(ТекстСообщения, Символы.ПС);
	КонецЕсли;
	
	Возврат "";
	
КонецФункции

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

Функция ОшибкиПроверкиКодаПодразделения(КодПодразделения)
	
	Если ПустаяСтрока(КодПодразделения) Тогда
		Возврат "";
	КонецЕсли;
	
	СтрокаЦифр = СокрЛП(КодПодразделения);
	Если СтрДлина(СтрокаЦифр) < 6 Тогда
		Возврат НСтр("ru = 'Код подразделения задан не полностью'");
	КонецЕсли;
	
	Если Не СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(СтрокаЦифр) Тогда
		Возврат НСтр("ru = 'Код подразделения должен состоять только из цифр.'");
	КонецЕсли;
	
	Если СтрокаЦифр = "000000" Тогда
		Возврат НСтр("ru = 'Код подразделения не может быть нулевым.'");
	КонецЕсли;
	
	Возврат "";
	
КонецФункции

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

Функция ТолькоЦифры(Строка)
	
	ДлинаСтроки = СтрДлина(Строка);
	
	ОбработаннаяСтрока = "";
	Для НомерСимвола = 1 По ДлинаСтроки Цикл
		
		Символ = Сред(Строка, НомерСимвола, 1);
		Если Символ >= "0" И Символ <= "9" Тогда
			ОбработаннаяСтрока = ОбработаннаяСтрока + Символ;
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат ОбработаннаяСтрока;
	
КонецФункции

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

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

Функция СостоянияЗаявленияПустаяСсылка() Экспорт
	
	Возврат Перечисления.СостоянияЗаявленияНаВыпускСертификата.ПустаяСсылка();

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

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

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

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

Функция ВебСервисУЦ(Таймаут = Неопределено) Экспорт
	
	ЭлектроннаяПодпись.РазрешенДоступКИнтернетСервисам(Истина);
	
	ПараметрыПодключения = ОбщегоНазначения.ПараметрыПодключенияWSПрокси();
	ПараметрыПодключения.АдресWSDL = "https://regservice.1c.ru/regservice/regservice.asmx?wsdl";
	ПараметрыПодключения.URIПространстваИмен = "http://regservice.keydisk.ru/";
	ПараметрыПодключения.ИмяСервиса = "RegService";
	Если Не ЗначениеЗаполнено(Таймаут) Тогда
		Таймаут = 7;
	КонецЕсли;
	ПараметрыПодключения.Таймаут = Таймаут;
	
	Возврат ОбщегоНазначения.СоздатьWSПрокси(ПараметрыПодключения);
	
КонецФункции

// Обновить состояние заявления.
// 
// Параметры:
//  Сертификат - СправочникСсылка.СертификатыКлючейЭлектроннойПодписиИШифрования
// 
// Возвращаемое значение:
//  Неопределено, Булево - булево, Неопределено
//
Функция ОбновитьСостояниеЗаявления(Сертификат) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	ДанныеЗаявления = РегистрыСведений.ЗаявленияНаВыпускСертификата.СоздатьМенеджерЗаписи();
	ДанныеЗаявления.Сертификат = Сертификат;
	ДанныеЗаявления.Прочитать();
	
	Если Не ДанныеЗаявления.Выбран() Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ПервоначальноеСостояниеЗаявления = ДанныеЗаявления.СостояниеЗаявления;
	
	ШаблонОписанияОшибки =
		НСтр("ru = 'Не удалось обновить состояние по причине: %1'");
	
	// Запрос состояния обработки заявления.
	
	Попытка
		ВебСервис = ВебСервисУЦ(20);
		Ответ = ВебСервис.ReceivePacket(ДанныеЗаявления.ИдентификаторДокументооборота);
	Исключение
		ИнформацияОбОшибке = ИнформацияОбОшибке();
		ДанныеЗаявления.ДатаОбновленияСостояния = ТекущаяДатаСеанса();
		ДанныеЗаявления.СостояниеОбработкиЗаявления = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонОписанияОшибки,
			ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
		ДанныеЗаявления.Записать();	
		Возврат Неопределено;
	КонецПопытки;
	
	ДанныеЗаявления.ДатаОбновленияСостояния = ТекущаяДатаСеанса();
	
	Если Не ЗначениеЗаполнено(Ответ) Тогда
		ДанныеЗаявления.СостояниеОбработкиЗаявления = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонОписанияОшибки,
			СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Метод %1 сервиса 1С:Подпись вернул пустой ответ.'"), "ReceivePacket"));
		ДанныеЗаявления.Записать();
		Возврат Неопределено;
	КонецЕсли;
	
	ОписаниеОшибки = "";
	ЧтениеXML = Новый ЧтениеXML;
	ЧтениеXML.УстановитьСтроку(Ответ);
	ПостроительDOM = Новый ПостроительDOM();
	ПостроительDOM = ПостроительDOM.Прочитать(ЧтениеXML);
	ЧтениеXML.Закрыть();
	
	УзелDOM = ПостроительDOM.ПолучитьЭлементыПоИмени("code");
	КодРезультата = УзелDOM[0].ТекстовоеСодержимое;
	
	ИмяФайлаПакетОтвета = "";
	Если КодРезультата = "0" Тогда
		УзелDOM = ПостроительDOM.ПолучитьЭлементыПоИмени("packet");
		
		Если УзелDOM.Количество() > 0 Тогда
			
			СодержимоеОтвета = УзелDOM[0].ТекстовоеСодержимое;
			
		Иначе
			ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонОписанияОшибки,
				СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Метод %1 сервиса 1С:Подпись вернул пустые данные.'"), "ReceivePacket"));
		КонецЕсли;
		
	ИначеЕсли КодРезультата = "1" Тогда
		ОписаниеОшибки = НСтр("ru = 'Заявление еще не обработано, попробуйте позже.'");
	Иначе
		УзелDOM = ПостроительDOM.ПолучитьЭлементыПоИмени("errorMessage");
		Если УзелDOM.Количество() > 0 Тогда
			ОписаниеОшибки = УзелDOM[0].ТекстовоеСодержимое;
		Иначе
			ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Метод %1 сервиса 1С:Подпись вернул код ошибки: %2'"),
				"ReceivePacket", Строка(КодРезультата));
		КонецЕсли;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ОписаниеОшибки) Тогда
		ДанныеЗаявления.СостояниеОбработкиЗаявления = ОписаниеОшибки;
		ДанныеЗаявления.Записать();
		Возврат Неопределено;
	КонецЕсли;
		
	ДвоичныеДанные = Base64Значение(СодержимоеОтвета);
	ИмяФайлаПакетОтвета = ПолучитьИмяВременногоФайла(".zip");
	ДвоичныеДанные.Записать(ИмяФайлаПакетОтвета);
	ВременныйКаталог = ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути(
	ПолучитьИмяВременногоФайла("package"));
	
	СоздатьКаталог(ВременныйКаталог);
	
	ФайлНайден = Ложь;
	Попытка
		Архив1 = Новый ЧтениеZipФайла(ИмяФайлаПакетОтвета);
		
		Для Счетчик = 0 По Архив1.Элементы.Количество() - 1 Цикл
			
			Если Архив1.Элементы[Счетчик].Расширение = "bin" Тогда
				ФайлНайден = Истина;
				
				Архив1.Извлечь(Архив1.Элементы[Счетчик], ВременныйКаталог);
				Архив2 = Новый ЧтениеZipФайла(ВременныйКаталог + Архив1.Элементы[Счетчик].Имя);
				Архив2.ИзвлечьВсе(ВременныйКаталог);
				
				ЧтениеXML = Новый ЧтениеXML;
				ЧтениеXML.ОткрытьФайл(ВременныйКаталог + "file");
				ПостроительDOM = Новый ПостроительDOM;
				ДокументDOM  = ПостроительDOM.Прочитать(ЧтениеXML);
				ЧтениеXML.Закрыть();
				
				РегистрацияУспешна = Булево(ЗначениеУзлаXML(ДокументDOM, "РегистрацияУспешна"));
				ДанныеЗаявления.СостояниеОбработкиЗаявления = ЗначениеУзлаXML(ДокументDOM, "Результат");
				
				Если РегистрацияУспешна Тогда
					ДанныеЗаявления.ИдентификаторАбонента = ЗначениеУзлаXML(ДокументDOM, "ИдентификаторАбонента");
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
		
		Если Не ФайлНайден Тогда
			ВызватьИсключение НСтр("ru = 'Архив не содержит файл данных.'");
		КонецЕсли;
	Исключение
		ИнформацияОбОшибке = ИнформацияОбОшибке();
		ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не удалось разобрать результат выполнения метода %1 сервиса 1С:Подпись по причине: %2'"),
			"ReceivePacket",
			ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
	КонецПопытки;
	
	ФайловаяСистема.УдалитьВременныйФайл(ИмяФайлаПакетОтвета);
	ФайловаяСистема.УдалитьВременныйКаталог(ВременныйКаталог);
	
	Если ЗначениеЗаполнено(ОписаниеОшибки) Тогда
		ДанныеЗаявления.СостояниеОбработкиЗаявления = ОписаниеОшибки;
		ДанныеЗаявления.Записать();
		Возврат Неопределено;
	КонецЕсли;
	
	Если Не РегистрацияУспешна Тогда
		
		НачатьТранзакцию();
		Попытка
			БлокировкаДанных = Новый БлокировкаДанных;
			ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрСведений.ЗаявленияНаВыпускСертификата");
			ЭлементБлокировки.УстановитьЗначение("Сертификат", Сертификат);
			ЭлементБлокировки = БлокировкаДанных.Добавить("Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования");
			ЭлементБлокировки.УстановитьЗначение("Ссылка", Сертификат);
			БлокировкаДанных.Заблокировать();
			
			ДанныеЗаявления.СостояниеЗаявления = Перечисления.СостоянияЗаявленияНаВыпускСертификата.Отклонено;
			ДанныеЗаявления.Записать();
			
			Объект = Сертификат.ПолучитьОбъект();
			Наименование = СокрП(Объект.Фамилия + " " + Объект.Имя + " " + Объект.Отчество) + " (" + НСтр("ru = 'Заявление отклонено'") + ")";
			
			ИзменитьТекстНапоминанийПользователя(Сертификат, 
				"АвтоматическоеНапоминаниеОбИзмененииСостоянияЗаявления",
				СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru='Заявление отклонено: ""%1""'"), Наименование));
				
			Объект.Наименование = Наименование;
			Объект.ДатаПолученияСертификата = Дата(1,1,1);
			Объект.Записать();
			
			ЗафиксироватьТранзакцию();
		Исключение
			ОтменитьТранзакцию();
			ВызватьИсключение;
		КонецПопытки;
		
		Возврат Ложь;
	КонецЕсли;
	
	// Запрос сертификата.
	
	Ответ = ВебСервис.ReceiveUpdatedPacket(Строка(ДанныеЗаявления.ИдентификаторАбонента), Дата('00010101'));
	
	ОписаниеОшибки = "";
	ЧтениеXML = Новый ЧтениеXML;
	ЧтениеXML.УстановитьСтроку(Ответ);
	ПостроительDOM = Новый ПостроительDOM();
	ПостроительDOM = ПостроительDOM.Прочитать(ЧтениеXML);
	ЧтениеXML.Закрыть();
	
	УзелDOM = ПостроительDOM.ПолучитьЭлементыПоИмени("code");
	КодРезультата = УзелDOM[0].ТекстовоеСодержимое;
	
	ИмяФайлаПакетОтвета = "";
	Если КодРезультата = "0" Тогда
		УзелDOM = ПостроительDOM.ПолучитьЭлементыПоИмени("packet");
		
		Если УзелDOM.Количество() > 0 Тогда
			
			СодержимоеОтвета = УзелDOM[0].ТекстовоеСодержимое;
			
		Иначе
			ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонОписанияОшибки,
				СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Метод %1 сервиса 1С:Подпись вернул пустые данные.'"), "ReceiveUpdatedPacket"));
		КонецЕсли;
	Иначе
		УзелDOM = ПостроительDOM.ПолучитьЭлементыПоИмени("errorMessage");
		Если УзелDOM.Количество() > 0 Тогда
			ОписаниеОшибки = УзелDOM[0].ТекстовоеСодержимое;
		Иначе
			ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Метод %1 сервиса 1С:Подпись вернул код ошибки: %2'"),
				"ReceiveUpdatedPacket", Строка(КодРезультата));
		КонецЕсли;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ОписаниеОшибки) Тогда
		ДанныеЗаявления.СостояниеОбработкиЗаявления = ОписаниеОшибки;
		ДанныеЗаявления.Записать();
		Возврат Неопределено;
	КонецЕсли;
	
	ДвоичныеДанные = Base64Значение(СодержимоеОтвета);
	ИмяФайлаПакетОтвета = ПолучитьИмяВременногоФайла(".zip");
	ДвоичныеДанные.Записать(ИмяФайлаПакетОтвета);
	
	ВременныйКаталог = ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути(
		ПолучитьИмяВременногоФайла("package"));
	
	СоздатьКаталог(ВременныйКаталог);
	
	ФайлНайден = Ложь;
	
	Попытка
		Архив = Новый ЧтениеZipФайла(ИмяФайлаПакетОтвета);
		
		Для Счетчик = 0 По Архив.Элементы.Количество() - 1 Цикл
			
			Если Архив.Элементы[Счетчик].Расширение = "xml" Тогда
				ФайлНайден = Истина;
				
				Архив.Извлечь(Архив.Элементы[Счетчик], ВременныйКаталог);
				
				ЧтениеXML = Новый ЧтениеXML;
				ЧтениеXML.ОткрытьФайл(ВременныйКаталог + Архив.Элементы[Счетчик].Имя); 
				ПостроительDOM = Новый ПостроительDOM;
				ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);
				ЧтениеXML.Закрыть();
				
				УзелDOM = ДокументDOM.ПолучитьЭлементыПоИмени("Сертификат");
				
				СертификатСтрокой = "";
				КорневойСертификатСтрокой = "";
				
				Для Каждого Узел Из УзелDOM Цикл
					Хранилище = Узел.Атрибуты.ПолучитьИменованныйЭлемент("Хранилище").ТекстовоеСодержимое;
					Если Хранилище = "MY" Тогда
						СертификатСтрокой = Узел.ТекстовоеСодержимое;
					КонецЕсли;
					Если Хранилище = "ROOT" Тогда
						КорневойСертификатСтрокой = Узел.ТекстовоеСодержимое;
					КонецЕсли;
				КонецЦикла;
				
				Если Не ЗначениеЗаполнено(СертификатСтрокой) Тогда
					ВызватьИсключение НСтр("ru = 'Ответ не содержит сведений о выпущенном сертификате.'");
				ИначеЕсли Не ЗначениеЗаполнено(КорневойСертификатСтрокой) Тогда
					ВызватьИсключение НСтр("ru = 'Ответ не содержит сведений о корневом сертификате.'");
				КонецЕсли;
				
				ДанныеСертификата          = Base64Значение(СертификатСтрокой);
				ДанныеКорневогоСертификата = Base64Значение(КорневойСертификатСтрокой);
				
				СертификатКриптографии         = Новый СертификатКриптографии(ДанныеСертификата);
				КорневойСертификат = Новый СертификатКриптографии(ДанныеКорневогоСертификата);
				
			КонецЕсли;
		КонецЦикла;
		
		Если Не ФайлНайден Тогда
			ВызватьИсключение НСтр("ru = 'Архив не содержит файл данных.'");
		КонецЕсли;
	Исключение
		ИнформацияОбОшибке = ИнформацияОбОшибке();
		ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не удалось разобрать результат выполнения метода %1 сервиса 1С:Подпись по причине: %2'"),
			"ReceiveUpdatedPacket", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
	КонецПопытки;
	
	ФайловаяСистема.УдалитьВременныйФайл(ИмяФайлаПакетОтвета);
	ФайловаяСистема.УдалитьВременныйКаталог(ВременныйКаталог);
	
	Если ЗначениеЗаполнено(ОписаниеОшибки) Тогда
		ДанныеЗаявления.СостояниеОбработкиЗаявления = ОписаниеОшибки;
		ДанныеЗаявления.Записать();
		Возврат Неопределено;
	КонецЕсли;
	
	СвойстваСертификата = ЭлектроннаяПодпись.СвойстваСертификата(СертификатКриптографии);
	СвойстваСубъекта    = ЭлектроннаяПодпись.СвойстваСубъектаСертификата(СертификатКриптографии);
	
	НачатьТранзакцию();
	Попытка
		БлокировкаДанных = Новый БлокировкаДанных;
		ЭлементБлокировки = БлокировкаДанных.Добавить("РегистрСведений.ЗаявленияНаВыпускСертификата");
		ЭлементБлокировки.УстановитьЗначение("Сертификат", Сертификат);
		ЭлементБлокировки = БлокировкаДанных.Добавить("Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования");
		ЭлементБлокировки.УстановитьЗначение("Ссылка", Сертификат);
		БлокировкаДанных.Заблокировать();
		Объект = Сертификат.ПолучитьОбъект(); 
		
		// Важно заполнить отпечаток, чтобы не было возможности добавить дубль сертификата.
		Объект.Наименование = СвойстваСертификата.Представление;
		
		Объект.Подписание     = СвойстваСертификата.Подписание;
		Объект.Шифрование     = СвойстваСертификата.Шифрование;
		Объект.Отпечаток      = СвойстваСертификата.Отпечаток;
		Объект.КомуВыдан      = СвойстваСертификата.КомуВыдан;
		Объект.КемВыдан       = СвойстваСертификата.КемВыдан;
		Объект.ДействителенДо = СвойстваСертификата.ДатаОкончания;
		
		Объект.Фамилия   = СвойстваСубъекта.Фамилия;
		Объект.Имя       = СвойстваСубъекта.Имя;
		Объект.Отчество  = СвойстваСубъекта.Отчество;
		Объект.Должность = СвойстваСубъекта.Должность;
		Объект.Фирма     = СвойстваСубъекта.Организация;
		Объект.ДатаПолученияСертификата = ТекущаяДатаСеанса();
		
		Если Объект.ДанныеСертификата.Получить() <> ДанныеСертификата Тогда
			Объект.ДанныеСертификата = Новый ХранилищеЗначения(ДанныеСертификата, Новый СжатиеДанных(9));
		КонецЕсли;
		
		Содержание = ДанныеЗаявления.СодержаниеЗаявления.Получить();
		Содержание.Вставить("ОтпечатокКорневогоСертификата", Base64Строка(КорневойСертификат.Отпечаток));
		Содержание.Вставить("Сертификат", ДанныеСертификата);
		Содержание.Вставить("КорневойСертификат", ДанныеКорневогоСертификата);
		
		ДанныеЗаявления.СодержаниеЗаявления = Новый ХранилищеЗначения(Содержание, Новый СжатиеДанных(9));
		
		Если ПервоначальноеСостояниеЗаявления = Перечисления.СостоянияЗаявленияНаВыпускСертификата.ИсполненоСертификатНеУстановлен
			ИЛИ ПервоначальноеСостояниеЗаявления = Перечисления.СостоянияЗаявленияНаВыпускСертификата.Исполнено Тогда
				ДанныеЗаявления.СостояниеЗаявления = ПервоначальноеСостояниеЗаявления; 
		Иначе
			ДанныеЗаявления.СостояниеЗаявления = Перечисления.СостоянияЗаявленияНаВыпускСертификата.ИсполненоРаспискаНеОтправлена;
		КонецЕсли;
		ДанныеЗаявления.Записать();
		
		Если ЗначениеЗаполнено(ДанныеЗаявления.СертификатОснование) Тогда
			НовыйТекстНапоминания = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='Сертификат перевыпущен: ""%1"" -> ""%2""'"), 
				ДанныеЗаявления.СертификатОснование,
				Объект.Наименование); 
			
			ИзменитьТекстНапоминанийПользователя(ДанныеЗаявления.СертификатОснование, 
				"АвтоматическоеНапоминаниеОПродленииСертификата",
				НовыйТекстНапоминания);
		КонецЕсли;
	
		Объект.Записать();
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;

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

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

#Область РегламентноеЗадание

// См. РегламентныеЗаданияПереопределяемый.ПриОпределенииНастроекРегламентныхЗаданий
Процедура ПриОпределенииНастроекРегламентныхЗаданий(Настройки) Экспорт

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

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

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

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

	Запрос.УстановитьПараметр("Ссылка", Сертификат);
	Возврат Запрос.Выполнить();
КонецФункции

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

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

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

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

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

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

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

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

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

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

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

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

		СодержаниеЗаявления.Свойство("Сотрудник", СертификатОбъект.ФизическоеЛицо);

		Если СодержаниеЗаявления.Свойство("ДатаОбновленияСостояния") Тогда
			Если (СертификатОбъект.УдалитьСостояниеЗаявления = Перечисления.СостоянияЗаявленияНаВыпускСертификата.Исполнено
				Или СертификатОбъект.УдалитьСостояниеЗаявления = Перечисления.СостоянияЗаявленияНаВыпускСертификата.ИсполненоРаспискаНеОтправлена
				Или СертификатОбъект.УдалитьСостояниеЗаявления
				= Перечисления.СостоянияЗаявленияНаВыпускСертификата.ИсполненоСертификатНеУстановлен) Тогда

				ДатаПолученияСертификата = СодержаниеЗаявления.ДатаОбновленияСостояния;

			ИначеЕсли СертификатОбъект.УдалитьСостояниеЗаявления
				= Перечисления.СостоянияЗаявленияНаВыпускСертификата.Отклонено Тогда

				ДатаПолученияСертификата = Дата(1, 1, 1);

			КонецЕсли;
		КонецЕсли;

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

	КонецЕсли;
	СертификатОбъект.ДатаПолученияСертификата = ДатаПолученияСертификата;
	СертификатОбъект.УдалитьСостояниеЗаявления = Неопределено;
	ЗаписатьОбъект = Истина;
		
КонецПроцедуры


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

#КонецЕсли

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