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

#Область ОписаниеПеременных

&НаКлиенте
Перем ПользователиПродолжитьДобавление, ВыбранныйПользователь, ВыбранныйСпособУказанияДатыЗапрета;

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

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	УстановитьУсловноеОформление();
	
	СвойстваРазделов = ДатыЗапретаИзмененияСлужебный.СвойстваРазделов();
	
	// Проверка прав доступа.
	// АПК:515-выкл - №737.4 проверка по ролям, так как право есть всегда.
	ЕстьПравоПросмотраЗапретаИзмененияДанных =
		Пользователи.РолиДоступны("ЧтениеДатЗапретаИзменения, ДобавлениеИзменениеДатЗапретаИзменения",, Ложь);
	
	ЕстьПравоРедактированияЗапретаИзмененияДанных = ЕстьПравоПросмотраЗапретаИзмененияДанных
		И Пользователи.РолиДоступны("ДобавлениеИзменениеДатЗапретаИзменения",, Ложь);
	
	ЕстьПравоПросмотраЗапретаЗагрузкиДанных =
		  СвойстваРазделов.ДатыЗапретаЗагрузкиВнедрены
		И Пользователи.РолиДоступны("ЧтениеДатЗапретаЗагрузки, ДобавлениеИзменениеДатЗапретаЗагрузки",, Ложь);
	
	ЕстьПравоРедактированияЗапретаЗагрузкиДанных = ЕстьПравоПросмотраЗапретаЗагрузкиДанных
		И Пользователи.РолиДоступны("ДобавлениеИзменениеДатЗапретаЗагрузки",, Ложь);
	// АПК:515-вкл
	Если Параметры.ДатыЗапретаЗагрузкиДанных Тогда
		Если Не СвойстваРазделов.ДатыЗапретаЗагрузкиВнедрены Тогда
			ВызватьИсключение ДатыЗапретаИзмененияСлужебный.ТекстОшибкиДатыЗапретаЗагрузкиНеВнедрены();
		КонецЕсли;
		Если Не ЕстьПравоПросмотраЗапретаЗагрузкиДанных Тогда
			ВызватьИсключение(НСтр("ru = 'Недостаточно прав для просмотра дат запрета загрузки данных прошлых периодов из других приложений.'"),
				КатегорияОшибки.НарушениеПравДоступа);
		КонецЕсли;
	ИначеЕсли Не ЕстьПравоПросмотраЗапретаИзмененияДанных Тогда
		ВызватьИсключение(НСтр("ru = 'Недостаточно прав для просмотра дат запрета ввода и редактирования данных прошлых периодов.'"),
			КатегорияОшибки.НарушениеПравДоступа);
	КонецЕсли;
	
	Если Не Параметры.ДатыЗапретаЗагрузкиДанных
	   И Не ЕстьПравоРедактированияЗапретаИзмененияДанных
	 Или Параметры.ДатыЗапретаЗагрузкиДанных
	   И Не ЕстьПравоРедактированияЗапретаЗагрузкиДанных Тогда
		
		Элементы.УстановкаДатыЗапрета.Доступность = Ложь;
		Элементы.Пользователи.ТолькоПросмотр = Истина;
		Элементы.ПользователиПодобрать.Доступность = Ложь;
		Элементы.ДатыЗапрета.ТолькоПросмотр = Истина;
		Элементы.ДатыЗапретаОписаниеДатыЗапретаПредставление.ГиперссылкаЯчейки = Ложь;
		Элементы.СпособУказанияОбщаяДата.ТолькоПросмотр = Истина;
		Элементы.ГруппаРасширенныеВозможности.ТолькоПросмотр = Истина;
	КонецЕсли;
	
	// Кэширование текущей даты на сервере.
	НачалоДня = НачалоДня(ТекущаяДатаСеанса());
	
	// Заполнение свойств разделов.
	ЗаполнитьЗначенияСвойств(ЭтотОбъект, СвойстваРазделов);
	Таблица = Новый ТаблицаЗначений;
	Таблица.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.РазделыДатЗапретаИзменения"));
	Таблица.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(150)));
	Таблица.Колонки.Добавить("ЭтоОбщаяДата",  Новый ОписаниеТипов("Булево"));
	Для Каждого Раздел Из Разделы Цикл
		Если ТипЗнч(Раздел.Ключ) = Тип("Строка") Тогда
			Продолжить;
		КонецЕсли;
		НоваяСтрока = Таблица.Добавить();
		СвойстваРаздела = Раздел.Значение; // Структура
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СвойстваРаздела);
		Если Не ЗначениеЗаполнено(СвойстваРаздела.Ссылка) Тогда
			НоваяСтрока.Представление = ТекстПредставленияОбщейДаты();
			НоваяСтрока.ЭтоОбщаяДата  = Истина;
		КонецЕсли;
	КонецЦикла;
	АдресТаблицыРазделов = ПоместитьВоВременноеХранилище(Таблица, УникальныйИдентификатор);
	
	// Подготовка таблицы для установки/снятия объектных блокировок формы.
	Измерения = Метаданные.РегистрыСведений.ДатыЗапретаИзменения.Измерения;
	Таблица = Новый ТаблицаЗначений;
	Таблица.Колонки.Добавить("Раздел",       Измерения.Раздел.Тип);
	Таблица.Колонки.Добавить("Объект",       Измерения.Объект.Тип);
	Таблица.Колонки.Добавить("Пользователь", Измерения.Пользователь.Тип);
	Блокировки = Новый Структура;
	Блокировки.Вставить("ИдентификаторФормы",   УникальныйИдентификатор);
	Блокировки.Вставить("Состав",               Таблица);
	Блокировки.Вставить("НачалоДня",            НачалоДня);
	Блокировки.Вставить("БезРазделовИОбъектов", БезРазделовИОбъектов);
	Блокировки.Вставить("РазделПустаяСсылка",   РазделПустаяСсылка);
	
	АдресУстановленныхБлокировок = ПоместитьВоВременноеХранилище(Блокировки, УникальныйИдентификатор);
	
	// Настройка полей формы
	Если Параметры.ДатыЗапретаЗагрузкиДанных Тогда
		Элементы.ИспользованиеДатЗапретаВыключеноНадпись.Заголовок =
			НСтр("ru = 'Даты запрета загрузки данных прошлых периодов из других приложений отключены в настройках.'");
		
		Заголовок = НСтр("ru = 'Даты запрета загрузки данных'");
		Элементы.УстановкаДатыЗапрета.СписокВыбора.НайтиПоЗначению("ДляВсехПользователей").Представление =
			НСтр("ru = 'Для всех информационных баз'");
		Элементы.УстановкаДатыЗапрета.СписокВыбора.НайтиПоЗначению("ПоПользователям").Представление =
			НСтр("ru = 'По информационным базам'");
		
		Элементы.ПользователиПолноеПредставление.Заголовок =
			НСтр("ru = 'Приложение: информационная база'");
		
		Элементы.ПользователиКомментарий.Подсказка =
			НСтр("ru = 'Описывает причину отдельного запрета для информационной базы или приложения'");
		
		ЗначениеДляВсехПользователей = Перечисления.ВидыНазначенияДатЗапрета.ДляВсехИнформационныхБаз;
		
		ТипыПользователя =
			Метаданные.РегистрыСведений.ДатыЗапретаИзменения.Измерения.Пользователь.Тип.Типы();
		
		Для Каждого ТипПользователя Из ТипыПользователя Цикл
			ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипПользователя);
			Если Не Метаданные.ПланыОбмена.Содержит(ОбъектМетаданных) Тогда
				Продолжить;
			КонецЕсли;
			ПустаяСсылкаУзлаПланаОбмена = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(
				ОбъектМетаданных.ПолноеИмя()).ПустаяСсылка();
			
			СписокТиповПользователей.Добавить(
				ПустаяСсылкаУзлаПланаОбмена, ОбъектМетаданных.Представление());
		КонецЦикла;
		Элементы.Пользователи.КартинкаСтрок = БиблиотекаКартинок.ПиктограммыПланОбменаУзел;
		НавигационнаяСсылка = "e1cib/command/РегистрСведений.ДатыЗапретаИзменения.Команда.ДатыЗапретаЗагрузкиДанных";
		
		Если ПолучитьФункциональнуюОпцию("ИспользоватьДатыЗапретаИзменения") Тогда
			Если ЕстьПравоРедактированияЗапретаИзмененияДанных Тогда
				ПереходКДругимДатамЗапрета = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Также можно настроить <a href=""%1"">даты запрета ввода и редактирования данных</a> прошлых периодов.'"),
					"e1cib/command/РегистрСведений.ДатыЗапретаИзменения.Команда.ДатыЗапретаИзмененияДанных");
					
			ИначеЕсли ЕстьПравоПросмотраЗапретаИзмененияДанных Тогда
				ПереходКДругимДатамЗапрета = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Также можно посмотреть <a href=""%1"">даты запрета ввода и редактирования данных</a> прошлых периодов.'"),
					"e1cib/command/РегистрСведений.ДатыЗапретаИзменения.Команда.ДатыЗапретаИзмененияДанных");
			КонецЕсли;
		КонецЕсли;
	Иначе
		Элементы.ИспользованиеДатЗапретаВыключеноНадпись.Заголовок =
			НСтр("ru = 'Даты запрета ввода и редактирования данных прошлых периодов отключены в настройках приложения.'");
		Элементы.ПользователиПолноеПредставление.Заголовок = 
			?(ПолучитьФункциональнуюОпцию("ИспользоватьГруппыПользователей"),
			НСтр("ru = 'Пользователь, группа пользователей'"), НСтр("ru = 'Пользователь'"));
		Элементы.ПользователиКомментарий.Подсказка =
			НСтр("ru = '1. Определяет порядок групп пользователей при расчете дат запрета
			           |2. Описывает причину отдельного запрета для пользователя или группы пользователей'");
		ЗначениеДляВсехПользователей = Перечисления.ВидыНазначенияДатЗапрета.ДляВсехПользователей;
		СписокТиповПользователей.Добавить(
			Тип("СправочникСсылка.Пользователи"),        НСтр("ru = 'Пользователь'"));
		СписокТиповПользователей.Добавить(
			Тип("СправочникСсылка.ВнешниеПользователи"), НСтр("ru = 'Внешний пользователь'"));
		
		НавигационнаяСсылка = "e1cib/command/РегистрСведений.ДатыЗапретаИзменения.Команда.ДатыЗапретаИзмененияДанных";
		
		Если ПолучитьФункциональнуюОпцию("ИспользоватьДатыЗапретаЗагрузки") Тогда
			Если ЕстьПравоРедактированияЗапретаЗагрузкиДанных Тогда
				ПереходКДругимДатамЗапрета = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Также можно настроить <a href=""%1"">даты запрета загрузки данных</a> из других приложений.'"),
					"e1cib/command/РегистрСведений.ДатыЗапретаИзменения.Команда.ДатыЗапретаЗагрузкиДанных");
					
			ИначеЕсли ЕстьПравоПросмотраЗапретаЗагрузкиДанных Тогда
				ПереходКДругимДатамЗапрета = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Также можно посмотреть <a href=""%1"">даты запрета загрузки данных</a> из других приложений.'"),
					"e1cib/command/РегистрСведений.ДатыЗапретаИзменения.Команда.ДатыЗапретаЗагрузкиДанных");
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Список = Элементы.СпособУказанияДатыЗапрета.СписокВыбора;
	
	Если БезРазделовИОбъектов Тогда
		Элементы.СпособУказанияДатыЗапрета.Видимость =
			ЗначениеЗаполнено(ТекущийСпособУказанияДатыЗапрета(
				"*", ЕдинственныйРаздел, ЗначениеДляВсехПользователей, НачалоДня));
		
		Список.Удалить(Список.НайтиПоЗначению("ПоРазделамИОбъектам"));
		Список.Удалить(Список.НайтиПоЗначению("ПоРазделам"));
		Список.Удалить(Список.НайтиПоЗначению("ПоОбъектам"));
		
	ИначеЕсли Не ПоказыватьРазделы Тогда
		Список.Удалить(Список.НайтиПоЗначению("ПоРазделамИОбъектам"));
		Список.Удалить(Список.НайтиПоЗначению("ПоРазделам"));
	ИначеЕсли ВсеРазделыБезОбъектов Тогда
		Список.Удалить(Список.НайтиПоЗначению("ПоРазделамИОбъектам"));
		Список.Удалить(Список.НайтиПоЗначению("ПоОбъектам"));
	Иначе
		Список.Удалить(Список.НайтиПоЗначению("ПоОбъектам"));
	КонецЕсли;
	
	ИспользоватьВнешнихПользователей = ВнешниеПользователи.ИспользоватьВнешнихПользователей();
	СправочникВнешниеПользователиДоступен = ПравоДоступа("Просмотр", Метаданные.Справочники.ВнешниеПользователи);
	
	ОбновитьНаСервере();
	
КонецПроцедуры

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

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

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

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
	
	Если ЗавершениеРаботы Тогда
		Возврат;
	КонецЕсли;
	РазблокироватьВсеЗаписиНаСервере(АдресУстановленныхБлокировок);
	
КонецПроцедуры

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

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

&НаКлиенте
Процедура ПриИзмененииИспользованияДатЗапрета()
	
	ПриИзмененииИспользованияДатЗапретаНаСервере();
	
КонецПроцедуры

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

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

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

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

#Область ОдинаковыеОбработчикиСобытийФормДатыЗапретаИзмененияИРедактированиеДатыЗапрета

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

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

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

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

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

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

&НаКлиенте
Процедура БольшеВозможностейНажатие(Элемент)
	
	ВыбранРасширенныйРежим = Истина;
	Элементы.РасширенныйРежим.Видимость = Истина;
	Элементы.ГруппаРежимыРаботы.ТекущаяСтраница = Элементы.РасширенныйРежим;
	
КонецПроцедуры

&НаКлиенте
Процедура МеньшеВозможностейНажатие(Элемент)
	
	ВыбранРасширенныйРежим = Ложь;
	Элементы.РасширенныйРежим.Видимость = Ложь;
	Элементы.ГруппаРежимыРаботы.ТекущаяСтраница = Элементы.ПростойРежим;
	
КонецПроцедуры

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

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

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

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

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

&НаКлиенте
Процедура ПользователиВосстановитьТекущуюСтрокуПослеОтказаПриАктивизацииСтроки()
	
	Элементы.Пользователи.ТекущаяСтрока = ПользователиТекущаяСтрока;
	
КонецПроцедуры

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

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

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

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

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

&НаКлиенте
Процедура ПользователиОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	
	ПользователиОбработкаВыбораНаСервере(ВыбранноеЗначение);
	
КонецПроцедуры

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

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

&НаКлиенте
Процедура ПользователиПолноеПредставлениеПриИзменении(Элемент)
	
	ТекущиеДанные = Элементы.Пользователи.ТекущиеДанные;
	
	Если Не ЗначениеЗаполнено(ТекущиеДанные.ПолноеПредставление) Тогда
		ТекущиеДанные.ПолноеПредставление = ТекущиеДанные.Представление;
	КонецЕсли;
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

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

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

&НаКлиенте
Процедура ДатыЗапретаПриАктивизацииСтроки(Элемент)
	
	ДатыЗапретаУстановитьДоступностьКоманд(Элементы.ДатыЗапрета.ТекущиеДанные <> Неопределено);
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

&НаКлиенте
Процедура Обновить(Команда)
	
	ОбновитьНаСервере();
	ПодключитьОбработчикОжидания("РазвернутьДанныеПользователя", 0.1, Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура ПодобратьОбъекты(Команда)
	
	Если ТекущийПользователь = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ВыбратьПодобратьОбъекты(Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура ПодобратьПользователей(Команда)
	
	ВыбратьПодобратьПользователей(Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьОтчет(Команда)
	
	Если Параметры.ДатыЗапретаЗагрузкиДанных Тогда
		ИмяФормыОтчета = "Отчет.ДатыЗапретаЗагрузки.Форма";
	Иначе
		ИмяФормыОтчета = "Отчет.ДатыЗапретаИзменения.Форма";
	КонецЕсли;
	
	ОткрытьФорму(ИмяФормыОтчета);
	
КонецПроцедуры

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

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

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

&НаКлиенте
Процедура ДатыЗапретаИзменитьСтроку()
	
	Если Не Элементы.ДатыЗапрета.ТолькоПросмотр Тогда
		Элементы.ДатыЗапрета.ИзменитьСтроку();
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПользователиИзменитьСтроку()
	
	Если Не Элементы.Пользователи.ТолькоПросмотр Тогда
		Элементы.Пользователи.ИзменитьСтроку();
	КонецЕсли;
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

&НаКлиенте
Процедура ДатыЗапретаПередУдалениемЗавершение(Ответ, ВыделенныеСтроки) Экспорт
	
	Если Ответ <> КодВозвратаДиалога.Да Тогда
		Возврат;
	КонецЕсли;
	
	Для каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл
		ТекущиеДанные = ДатыЗапрета.НайтиПоИдентификатору(ВыделеннаяСтрока);
		Если ТекущиеДанные = Неопределено Тогда // уже ранее удалено
			Продолжить;
		КонецЕсли;
			
		Если ТекущиеДанные.ЭтоРаздел Тогда
			ОтключитьДатуЗапретаДляРаздела(ТекущиеДанные);
			Продолжить;
		КонецЕсли;	
		
		ТекущийРаздел = ТекущиеДанные.ПолучитьРодителя();
		// @skip-check query-in-loop - По-объектная запись данных
		УдалитьЗаписьПользователя(АдресУстановленныхБлокировок, 
			?(ТекущийРаздел <> Неопределено, ТекущийРаздел.Раздел, Неопределено), 
			ТекущиеДанные.Объект, ТекущийПользователь);
		Если ТекущийРаздел() = ТекущиеДанные.Объект Тогда
			// Удалена общая дата.
			ДатаЗапрета         = '00010101';
			ОписаниеДатыЗапрета = "";
			ЗаписьСуществует    = Ложь;
		КонецЕсли;
		
		ДатыЗапретаПриУдалении(ТекущиеДанные);
	КонецЦикла;
	
	ОповеститьОбИзменении(Тип("РегистрСведенийКлючЗаписи.ДатыЗапретаИзменения"));
	
КонецПроцедуры

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

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

&НаКлиенте
Процедура ОбновитьДанныеПользователяОбработчикОжидания()
	
	ОбновитьДанныеПользователя();
	
КонецПроцедуры

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

&НаКлиенте
Процедура ОбновитьОтображениеДатыЗапретаПриИзмененииОбработчикОжидания()
	
	ДатыЗапретаИзмененияСлужебныйКлиентСервер.ОбновитьОтображениеДатыЗапретаПриИзменении(ЭтотОбъект);
	
КонецПроцедуры

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

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

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

&НаСервереБезКонтекста
Процедура УдалитьЗаписьПользователя(Знач АдресУстановленныхБлокировок, Знач Раздел, Знач Объект, Знач Пользователь)
	
	МенеджерЗаписи = РегистрыСведений.ДатыЗапретаИзменения.СоздатьМенеджерЗаписи();
	
	Если ТипЗнч(Объект) = Тип("Массив") Тогда
		Объекты = Объект;
	Иначе
		Объекты = Новый Массив;
		Объекты.Добавить(Объект);
	КонецЕсли;
	
	Для Каждого ТекущийОбъект Из Объекты Цикл
		// @skip-check query-in-loop - В этом вызове ветка с запросом не выполняется
		ЗаблокироватьЗаписьПользователяНаСервере(АдресУстановленныхБлокировок,
			Раздел, ТекущийОбъект, Пользователь);
	КонецЦикла;
	
	Для Каждого ТекущийОбъект Из Объекты Цикл
		МенеджерЗаписи.Раздел = Раздел;
		МенеджерЗаписи.Объект = ТекущийОбъект;
		МенеджерЗаписи.Пользователь = Пользователь;
		МенеджерЗаписи.Прочитать();
		Если МенеджерЗаписи.Выбран() Тогда
			МенеджерЗаписи.Удалить();
		КонецЕсли;
	КонецЦикла;
	
	РазблокироватьВсеЗаписиНаСервере(АдресУстановленныхБлокировок);
	
КонецПроцедуры

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

&НаКлиенте
Процедура ПользователиПриНачалеРедактированияОбработчикОжидания()
	
	ВыбратьПодобратьПользователей();
	
КонецПроцедуры

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

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

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

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

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

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

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

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

&НаКлиенте
Процедура ОбработчикОжиданияВыбратьОбъекты()
	
	ВыбратьПодобратьОбъекты();
	
КонецПроцедуры

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

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

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

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

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

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

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

&НаСервере
Процедура ИзменитьВидимость(Элемент, Видимость)
	
	Если Элемент.Видимость <> Видимость Тогда
		Элемент.Видимость = Видимость;
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ИзменитьУстановкуДатыЗапрета(Знач ВыбранноеЗначение, Знач УдалитьЛишнее)
	
	Если УдалитьЛишнее Тогда
		
		НачатьТранзакцию();
		Попытка
			Запрос = Новый Запрос;
			Запрос.УстановитьПараметр("ДатыЗапретаЗагрузкиДанных",
				Параметры.ДатыЗапретаЗагрузкиДанных);
			
			Если ВыбранноеЗначение = "ДляВсехПользователей" Тогда
				Запрос.УстановитьПараметр("ОставитьДляВсехПользователей", Истина);
			Иначе
				Запрос.УстановитьПараметр("ДатыЗапретаЗагрузкиДанных", Неопределено);
			КонецЕсли;
			
			Запрос.Текст =
			"ВЫБРАТЬ
			|	ДатыЗапретаИзменения.Раздел,
			|	ДатыЗапретаИзменения.Объект,
			|	ДатыЗапретаИзменения.Пользователь
			|ИЗ
			|	РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапретаИзменения
			|ГДЕ
			|	(ДатыЗапретаИзменения.Пользователь = НЕОПРЕДЕЛЕНО
			|			ИЛИ ВЫБОР
			|				КОГДА ТИПЗНАЧЕНИЯ(ДатыЗапретаИзменения.Пользователь) = ТИП(Справочник.Пользователи)
			|						ИЛИ ТИПЗНАЧЕНИЯ(ДатыЗапретаИзменения.Пользователь) = ТИП(Справочник.группыПользователей)
			|						ИЛИ ТИПЗНАЧЕНИЯ(ДатыЗапретаИзменения.Пользователь) = ТИП(Справочник.ВнешниеПользователи)
			|						ИЛИ ТИПЗНАЧЕНИЯ(ДатыЗапретаИзменения.Пользователь) = ТИП(Справочник.группыВнешнихПользователей)
			|						ИЛИ ДатыЗапретаИзменения.Пользователь = ЗНАЧЕНИЕ(Перечисление.ВидыНазначенияДатЗапрета.ДляВсехПользователей)
			|					ТОГДА &ДатыЗапретаЗагрузкиДанных = ЛОЖЬ
			|				ИНАЧЕ &ДатыЗапретаЗагрузкиДанных = ИСТИНА
			|			КОНЕЦ)
			|	И ВЫБОР
			|			КОГДА ТИПЗНАЧЕНИЯ(ДатыЗапретаИзменения.Пользователь) = ТИП(Перечисление.ВидыНазначенияДатЗапрета)
			|				ТОГДА &ОставитьДляВсехПользователей = ЛОЖЬ
			|			ИНАЧЕ ИСТИНА
			|		КОНЕЦ";
			ЗначенияКлючейЗаписей = Запрос.Выполнить().Выгрузить();
			
			// Блокировка удаляемых записей.
			Для Каждого ЗначенияКлючаЗаписи Из ЗначенияКлючейЗаписей Цикл
				// @skip-check query-in-loop - По-объектная запись данных
				ЗаблокироватьЗаписьПользователяНаСервере(АдресУстановленныхБлокировок,
					ЗначенияКлючаЗаписи.Раздел,
					ЗначенияКлючаЗаписи.Объект,
					ЗначенияКлючаЗаписи.Пользователь);
			КонецЦикла;
			
			// Удаление заблокированных записей.
			Для Каждого ЗначенияКлючаЗаписи Из ЗначенияКлючейЗаписей Цикл
				// @skip-check query-in-loop - По-объектная запись данных
				УдалитьЗаписьПользователя(АдресУстановленныхБлокировок,
					ЗначенияКлючаЗаписи.Раздел,
					ЗначенияКлючаЗаписи.Объект,
					ЗначенияКлючаЗаписи.Пользователь);
			КонецЦикла;
			
			ЗафиксироватьТранзакцию();
		Исключение
			ОтменитьТранзакцию();
			РазблокироватьВсеЗаписиНаСервере(АдресУстановленныхБлокировок);
			ВызватьИсключение;
		КонецПопытки;
		РазблокироватьВсеЗаписиНаСервере(АдресУстановленныхБлокировок);
	КонецЕсли;
	
	ПрочитатьПользователей();
	ТекстОшибки = "";
	ПрочитатьДанныеПользователя(ЭтотОбъект, ТекстОшибки);
	Если ЗначениеЗаполнено(ТекстОшибки) Тогда
		ОбщегоНазначения.СообщитьПользователю(ТекстОшибки);
	КонецЕсли;
	
	УстановитьВидимость();
	
КонецПроцедуры

&НаСервереБезКонтекста
Функция ТекущийСпособУказанияДатыЗапрета(Знач Пользователь, Знач ЕдинственныйРаздел, Знач ЗначениеДляВсехПользователей, Знач НачалоДня, Данные = Неопределено)
	
	НачатьТранзакцию();
	Попытка
		Запрос = Новый Запрос;
		Запрос.УстановитьПараметр("Пользователь",                 Пользователь);
		Запрос.УстановитьПараметр("ЕдинственныйРаздел",           ЕдинственныйРаздел);
		Запрос.УстановитьПараметр("ПустаяДата",                   '00010101');
		Запрос.УстановитьПараметр("ЗначениеДляВсехПользователей", ЗначениеДляВсехПользователей);
		Запрос.Текст =
		"ВЫБРАТЬ ПЕРВЫЕ 1
		|	ИСТИНА КАК ЗначениеИстина
		|ИЗ
		|	РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапретаИзменения
		|ГДЕ
		|	НЕ(&Пользователь <> ДатыЗапретаИзменения.Пользователь
		|				И &Пользователь <> ""*"")
		|	И НЕ(ДатыЗапретаИзменения.Раздел = ЗНАЧЕНИЕ(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка)
		|				И ДатыЗапретаИзменения.Объект = ЗНАЧЕНИЕ(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка))
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ ПЕРВЫЕ 1
		|	ИСТИНА КАК ЗначениеИстина
		|ИЗ
		|	РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапретаИзменения
		|ГДЕ
		|	НЕ(&Пользователь <> ДатыЗапретаИзменения.Пользователь
		|				И &Пользователь <> ""*"")
		|	И ДатыЗапретаИзменения.Раздел <> ЗНАЧЕНИЕ(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка)
		|	И ДатыЗапретаИзменения.Объект <> ЗНАЧЕНИЕ(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка)
		|	И ДатыЗапретаИзменения.Объект <> ДатыЗапретаИзменения.Раздел
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ ПЕРВЫЕ 1
		|	ИСТИНА КАК ЗначениеИстина
		|ИЗ
		|	РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапретаИзменения
		|ГДЕ
		|	НЕ(&Пользователь <> ДатыЗапретаИзменения.Пользователь
		|				И &Пользователь <> ""*"")
		|	И ДатыЗапретаИзменения.Раздел <> ЗНАЧЕНИЕ(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка)
		|	И ДатыЗапретаИзменения.Раздел <> &ЕдинственныйРаздел
		|
		|ОБЪЕДИНИТЬ ВСЕ
		|
		|ВЫБРАТЬ ПЕРВЫЕ 1
		|	ИСТИНА
		|ИЗ
		|	РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапретаИзменения
		|ГДЕ
		|	НЕ(&Пользователь <> ДатыЗапретаИзменения.Пользователь
		|				И &Пользователь <> ""*"")
		|	И ДатыЗапретаИзменения.Раздел <> ЗНАЧЕНИЕ(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка)
		|	И ДатыЗапретаИзменения.Раздел = ДатыЗапретаИзменения.Объект";
		
		РезультатыЗапроса = Запрос.ВыполнитьПакет();
		
		ТекущийСпособУказанияДатыЗапрета = "";
		
		Запрос.Текст =
		"ВЫБРАТЬ
		|	ДатыЗапретаИзменения.ДатаЗапрета,
		|	ДатыЗапретаИзменения.ОписаниеДатыЗапрета
		|ИЗ
		|	РегистрСведений.ДатыЗапретаИзменения КАК ДатыЗапретаИзменения
		|ГДЕ
		|	ДатыЗапретаИзменения.Пользователь = &Пользователь
		|	И ДатыЗапретаИзменения.Раздел = ЗНАЧЕНИЕ(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка)
		|	И ДатыЗапретаИзменения.Объект = ЗНАЧЕНИЕ(ПланВидовХарактеристик.РазделыДатЗапретаИзменения.ПустаяСсылка)";
		Выборка = Запрос.Выполнить().Выбрать();
		ОбщаяДатаПрочитана = Выборка.Следующий();
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
	Если Данные = Неопределено Тогда
		Данные = Новый Структура;
		Данные.Вставить("ОписаниеДатыЗапрета", "");
		Данные.Вставить("ДатаЗапрета", '00010101');
		Данные.Вставить("КоличествоДнейРазрешения", 0);
		Данные.Вставить("ЗаписьСуществует", ОбщаяДатаПрочитана);
	КонецЕсли;
	
	Если ОбщаяДатаПрочитана Тогда
		Данные.ДатаЗапрета = ДатыЗапретаИзмененияСлужебный.ДатаЗапретаПоОписанию(
			Выборка.ОписаниеДатыЗапрета, Выборка.ДатаЗапрета, НачалоДня);
		ЗаполнитьПоВнутреннемуОписаниюДатыЗапрета(Данные, Выборка.ОписаниеДатыЗапрета);
	КонецЕсли;
	
	Если РезультатыЗапроса[0].Пустой() Тогда
		// Нет по объектам и по разделам, когда пустой.
		ТекущийСпособУказанияДатыЗапрета = ?(ОбщаяДатаПрочитана, "ОбщаяДата", "");
		
	ИначеЕсли Не РезультатыЗапроса[1].Пустой() Тогда
		// Есть по объектам, когда не пустой.
		
		Если РезультатыЗапроса[2].Пустой()
		   И ЗначениеЗаполнено(ЕдинственныйРаздел) Тогда
			// Только по ЕдинственныйРаздел (без дат по разделам), когда пустой.
			ТекущийСпособУказанияДатыЗапрета = "ПоОбъектам";
		Иначе
			ТекущийСпособУказанияДатыЗапрета = "ПоРазделамИОбъектам";
		КонецЕсли;
	Иначе
		ТекущийСпособУказанияДатыЗапрета = "ПоРазделам";
	КонецЕсли;
	
	Возврат ТекущийСпособУказанияДатыЗапрета;
	
КонецФункции

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

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

&НаКлиенте
Процедура РедактироватьДатуЗапретаВФормеЗавершение(ВыделенныеСтроки) Экспорт
	
	// Блокировка записей выделенных строк.
	Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл
		ТекущиеДанные = ДатыЗапрета.НайтиПоИдентификатору(ВыделеннаяСтрока);
		// @skip-check query-in-loop - В этом вызове ветка с запросом не выполняется
		ПрочитанныеСвойства = ЗаблокироватьЗаписьПользователяНаСервере(АдресУстановленныхБлокировок,
			ТекущийРаздел(ТекущиеДанные), ТекущиеДанные.Объект, ТекущийПользователь);
		
		ОбновитьЗначенияПрочитанныхСвойств(
			ТекущиеДанные, ПрочитанныеСвойства, Элементы.Пользователи.ТекущиеДанные);
	КонецЦикла;
	
	// Изменение описания даты запрета.
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("ПользовательПредставление", "");
	ПараметрыФормы.Вставить("РазделПредставление", "");
	ПараметрыФормы.Вставить("Объект", "");
	Если УстановкаДатыЗапрета = "ПоПользователям" Тогда
		ПараметрыФормы.ПользовательПредставление = Элементы.Пользователи.ТекущиеДанные.Представление;
	Иначе
		ПараметрыФормы.ПользовательПредставление = ТекстПредставленияДляВсехПользователей(ЭтотОбъект);
	КонецЕсли;
	
	ТекущиеДанные = Элементы.ДатыЗапрета.ТекущиеДанные;
	ПараметрыФормы.Вставить("ОписаниеДатыЗапрета", ТекущиеДанные.ОписаниеДатыЗапрета);
	ПараметрыФормы.Вставить("КоличествоДнейРазрешения", ТекущиеДанные.КоличествоДнейРазрешения);
	ПараметрыФормы.Вставить("ДатаЗапрета", ТекущиеДанные.ДатаЗапрета);
	ПараметрыФормы.Вставить("ЗаписьСуществует", ТекущиеДанные.ЗаписьСуществует);
	ПараметрыФормы.Вставить("НетДатыЗапретаПредставление", НетДатыЗапретаПредставление(ТекущиеДанные));
	
	Если ВыделенныеСтроки.Количество() = 1 Тогда
		Если ТекущиеДанные.ЭтоРаздел Тогда
			ПараметрыФормы.РазделПредставление = ТекущиеДанные.Представление;
		Иначе
			ПараметрыФормы.Объект = ТекущиеДанные.Объект;
			Если СпособУказанияДатыЗапрета <> "ПоОбъектам" Тогда
				ПараметрыФормы.РазделПредставление = ТекущиеДанные.ПолучитьРодителя().Представление;
			КонецЕсли;	
		КонецЕсли;
	Иначе
		ПараметрыФормы.Объект = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Выбранные строки (%1)'"), ВыделенныеСтроки.Количество());
	КонецЕсли;
	
	ОткрытьФорму("РегистрСведений.ДатыЗапретаИзменения.Форма.РедактированиеДатыЗапрета",
		ПараметрыФормы, ЭтотОбъект);
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьВычисляемыеПоля(Знач Данные)
	
	Для каждого СтрокаДанных Из Данные Цикл
		УстановитьПредставлениеОписанияДатыЗапрета(СтрокаДанных);
		Для каждого СтрокаДанных Из СтрокаДанных.ПолучитьЭлементы() Цикл
			УстановитьПредставлениеОписанияДатыЗапрета(СтрокаДанных);
		КонецЦикла;	
	КонецЦикла;	
	
КонецПроцедуры

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

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

&НаКлиентеНаСервереБезКонтекста
Функция ВнутренняяДатаЗапрета(Данные)
	
	Если ЗначениеЗаполнено(Данные.ОписаниеДатыЗапрета)
	   И Данные.ОписаниеДатыЗапрета <> "ПроизвольнаяДата" Тогда
		
		Возврат '39990202'; // Сохраняемое значение относительной даты запрета.
	КонецЕсли;
	
	Возврат Данные.ДатаЗапрета;
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ВнутреннееОписаниеДатыЗапрета(Знач Данные)
	
	ВнутреннееОписание = "";
	Если Данные.ОписаниеДатыЗапрета <> "ПроизвольнаяДата" Тогда
		ВнутреннееОписание = СокрЛП(
			Данные.ОписаниеДатыЗапрета + Символы.ПС
				+ Формат(Данные.КоличествоДнейРазрешения, "ЧГ=0"));
	КонецЕсли;
	
	Возврат ВнутреннееОписание;
	
КонецФункции

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

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

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

&НаСервереБезКонтекста
Процедура ЗаблокироватьИЗаписатьПустыеДаты(АдресУстановленныхБлокировок, Раздел, Объект, Пользователь, Комментарий)
	
	Если ТипЗнч(Объект) = Тип("Массив") Тогда
		ОбъектыДляДобавления = Объект;
	Иначе
		ОбъектыДляДобавления = Новый Массив;
		ОбъектыДляДобавления.Добавить(Объект);
	КонецЕсли;
	
	Для Каждого ТекущийОбъект Из ОбъектыДляДобавления Цикл
		// @skip-check query-in-loop - По-объектная запись данных
		ЗаблокироватьЗаписьПользователяНаСервере(АдресУстановленныхБлокировок,
			Раздел, ТекущийОбъект, Пользователь);
	КонецЦикла;
	
	Для Каждого ТекущийОбъект Из ОбъектыДляДобавления Цикл
		ЗаписатьДатуЗапретаСОписанием(
			Раздел,
			ТекущийОбъект,
			Пользователь,
			'00010101',
			"",
			Комментарий);
	КонецЦикла;
	
	РазблокироватьВсеЗаписиНаСервере(АдресУстановленныхБлокировок);
	
КонецПроцедуры

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

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьСвойство(Свойство, Значение)
	Если Свойство <> Значение Тогда
		Свойство = Значение;
	КонецЕсли;
КонецПроцедуры

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

#Область ВспомогательныеФункцииСтрокИнтерфейсаПользователя

&НаКлиентеНаСервереБезКонтекста
Функция ТекстПредставленияДляВсехПользователей(Форма)
	
	Возврат "<" + Форма.ЗначениеДляВсехПользователей + ">";
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ТекстПредставленияПользователя(Форма, Пользователь)
	
	Если Форма.Параметры.ДатыЗапретаЗагрузкиДанных Тогда
		Для Каждого ЗначениеСписка Из Форма.СписокТиповПользователей Цикл
			Если ТипЗнч(ЗначениеСписка.Значение) = ТипЗнч(Пользователь) Тогда
				Если ЗначениеЗаполнено(Пользователь) Тогда
					Возврат ЗначениеСписка.Представление + ": " + Строка(Пользователь);
				Иначе
					Возврат ЗначениеСписка.Представление + ": " + НСтр("ru = '<Все информационные базы>'");
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Пользователь) Тогда
		Возврат Строка(Пользователь);
	КонецЕсли;
	
	Возврат Строка(ТипЗнч(Пользователь));
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ТекстПредставленияОбщейДаты()
	
	Возврат "<" + НСтр("ru = 'Общая дата для всех разделов'") + ">";
	
КонецФункции

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

&НаКлиенте
Функция ТекстСообщенияВВыбранномРазделеДатыЗапретаДляОбъектовНеУстанавливаются(Раздел)
	
	Возврат ?(Раздел <> РазделПустаяСсылка, 
		СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'В разделе ""%1"" не предусмотрена установка дат запрета для отдельных объектов.'"), Раздел),
		НСтр("ru = 'Для установки дат запрета по отдельным объектам выберите один из разделов ниже и нажмите ""Подобрать"".'"));
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ТекстЗаголовкаВыборТипаДанных()
	
	Возврат НСтр("ru = 'Выбор типа данных'");
	
КонецФункции

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

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