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

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

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

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
	
	Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда
		ЗаполнитьЗначенияСвойств(ЭтотОбъект, ДанныеЗаполнения);
	КонецЕсли;

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

	Если ЗначениеЗаполнено(Организация) Тогда
		ЗаполнитьДанныеОрганизации();
	КонецЕсли;
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

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

Процедура СформироватьДвиженияУничтоженныеПерсональныеДанные()

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

Процедура УдалитьЗаписьСрокХраненияПерсональныхДанных()

	НаборЗаписей = РегистрыСведений.СрокиХраненияПерсональныхДанных.СоздатьНаборЗаписей();
	НаборЗаписей.Отбор.Субъект.Установить(Субъект);
	НаборЗаписей.Записать();
	
КонецПроцедуры

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

#Иначе
ВызватьИсключение НСтр("ru = 'Недопустимый вызов объекта на клиенте.'");
#КонецЕсли