Files
SSL/SSL/src/Catalogs/ГруппыДоступа/ManagerModule.bsl
T
2024-06-17 10:24:00 +03:00

2980 lines
210 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область ПрограммныйИнтерфейс
#Область ДляВызоваИзДругихПодсистем
// СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов
// Возвращает реквизиты объекта, которые не рекомендуется редактировать
// с помощью обработки группового изменения реквизитов.
//
// Возвращаемое значение:
// Массив из Строка
//
Функция РеквизитыНеРедактируемыеВГрупповойОбработке() Экспорт
НеРедактируемыеРеквизиты = Новый Массив;
НеРедактируемыеРеквизиты.Добавить("ТипПользователей");
НеРедактируемыеРеквизиты.Добавить("Пользователь");
НеРедактируемыеРеквизиты.Добавить("ОсновнаяГруппаДоступаПоставляемогоПрофиля");
НеРедактируемыеРеквизиты.Добавить("ВидыДоступа.*");
НеРедактируемыеРеквизиты.Добавить("ЗначенияДоступа.*");
Возврат НеРедактируемыеРеквизиты;
КонецФункции
// Конец СтандартныеПодсистемы.ГрупповоеИзменениеОбъектов
// СтандартныеПодсистемы.УправлениеДоступом
// Параметры:
// Ограничение - см. УправлениеДоступомПереопределяемый.ПриЗаполненииОграниченияДоступа.Ограничение.
//
Процедура ПриЗаполненииОграниченияДоступа(Ограничение) Экспорт
Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
| ЭтоГруппа
| ИЛИ Профиль <> Значение(Справочник.ПрофилиГруппДоступа.Администратор)
| И ЭтоАвторизованныйПользователь(Ответственный)";
КонецПроцедуры
// Конец СтандартныеПодсистемы.УправлениеДоступом
// ТехнологияСервиса.ВыгрузкаЗагрузкаДанных
// Подключается в ВыгрузкаЗагрузкаДанныхПереопределяемый.ПриРегистрацииОбработчиковВыгрузкиДанных.
//
// Параметры:
// Контейнер - ОбработкаОбъект.ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера
// МенеджерВыгрузкиОбъекта - ОбработкаОбъект.ВыгрузкаЗагрузкаДанныхМенеджерВыгрузкиДанныхИнформационнойБазы
// Сериализатор - СериализаторXDTO
// Объект - КонстантаМенеджерЗначения
// - СправочникОбъект
// - ДокументОбъект
// - БизнесПроцессОбъект
// - ЗадачаОбъект
// - ПланСчетовОбъект
// - ПланОбменаОбъект
// - ПланВидовХарактеристикОбъект
// - ПланВидовРасчетаОбъект
// - РегистрСведенийНаборЗаписей
// - РегистрНакопленияНаборЗаписей
// - РегистрБухгалтерииНаборЗаписей
// - РегистрРасчетаНаборЗаписей
// - ПоследовательностьНаборЗаписей
// - ПерерасчетНаборЗаписей
// Артефакты - Массив из ОбъектXDTO
// Отказ - Булево
//
Процедура ПередВыгрузкойОбъекта(Контейнер, МенеджерВыгрузкиОбъекта, Сериализатор, Объект, Артефакты, Отказ) Экспорт
УправлениеДоступомСлужебный.ПередВыгрузкойОбъекта(Контейнер, МенеджерВыгрузкиОбъекта, Сериализатор, Объект, Артефакты, Отказ);
КонецПроцедуры
// Конец ТехнологияСервиса.ВыгрузкаЗагрузкаДанных
#КонецОбласти
#КонецОбласти
#КонецЕсли
#Область ОбработчикиСобытий
Процедура ОбработкаПолученияПолейПредставления(Поля, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Поля.Добавить("Наименование");
Поля.Добавить("Пользователь");
КонецПроцедуры
Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
Если Не ЗначениеЗаполнено(Данные.Пользователь) Тогда
Возврат;
КонецЕсли;
СтандартнаяОбработка = Ложь;
Представление = УправлениеДоступомСлужебныйКлиентСервер.ПредставлениеГруппыДоступа(Данные);
КонецПроцедуры
#КонецОбласти
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область СлужебныйПрограммныйИнтерфейс
Процедура ИсключитьПросроченныхУчастников() Экспорт
НачалоДняТекущейДатыСеанса = НачалоДня(ТекущаяДатаСеанса());
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ПустаяДата", '00010101');
Запрос.УстановитьПараметр("НачалоДняТекущейДатыСеанса", НачалоДняТекущейДатыСеанса);
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ГруппыДоступаПользователи.Ссылка КАК Ссылка
|ИЗ
| Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
|ГДЕ
| ГруппыДоступаПользователи.СрокДействия <> &ПустаяДата
| И ГруппыДоступаПользователи.СрокДействия <= &НачалоДняТекущейДатыСеанса";
Выборка = Запрос.Выполнить().Выбрать();
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Справочник.ГруппыДоступа");
Пока Выборка.Следующий() Цикл
ЭлементБлокировки.УстановитьЗначение("Ссылка", Выборка.Ссылка);
НачатьТранзакцию();
Попытка
Блокировка.Заблокировать();
ГруппаДоступаОбъект = Выборка.Ссылка.ПолучитьОбъект();
Если ГруппаДоступаОбъект <> Неопределено Тогда
ЕстьИзменения = Ложь;
Индекс = ГруппаДоступаОбъект.Пользователи.Количество() - 1;
Пока Индекс >= 0 Цикл
СтрокаТЧ = ГруппаДоступаОбъект.Пользователи[Индекс];
Если ЗначениеЗаполнено(СтрокаТЧ.СрокДействия)
И СтрокаТЧ.СрокДействия <= НачалоДняТекущейДатыСеанса Тогда
ГруппаДоступаОбъект.Пользователи.Удалить(Индекс);
ЕстьИзменения = Истина;
КонецЕсли;
Индекс = Индекс - 1;
КонецЦикла;
Если ЕстьИзменения Тогда
ГруппаДоступаОбъект.Записать();
КонецЕсли;
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецЦикла;
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
// См. УправлениеДоступом.ГруппаДоступаАдминистраторы
Функция ГруппаДоступаАдминистраторы(ПрофильАдминистратор = Неопределено) Экспорт
УстановитьОтключениеБезопасногоРежима(Истина);
УстановитьПривилегированныйРежим(Истина);
Если Не ЗначениеЗаполнено(ПрофильАдминистратор) Тогда
ПрофильАдминистратор = УправлениеДоступом.ПрофильАдминистратор();
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК Ссылка
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| ГруппыДоступа.Профиль = &ПрофильАдминистратор
|
|УПОРЯДОЧИТЬ ПО
| Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК Ссылка
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| ГруппыДоступа.ИмяПредопределенныхДанных = &ИмяПредопределенныхДанных
|
|УПОРЯДОЧИТЬ ПО
| Ссылка";
Запрос.УстановитьПараметр("ПрофильАдминистратор", ПрофильАдминистратор);
Запрос.УстановитьПараметр("ИмяПредопределенныхДанных", "Администраторы");
РезультатыЗапроса = Запрос.ВыполнитьПакет();
ВыборкаПоПрофилю = РезультатыЗапроса[0].Выбрать();
ВыборкаПоПредопределенному = РезультатыЗапроса[1].Выбрать();
Если ВыборкаПоПрофилю.Следующий()
И ВыборкаПоПредопределенному.Следующий()
И ВыборкаПоПрофилю.Количество() = 1
И ВыборкаПоПредопределенному.Количество() = 1
И ВыборкаПоПрофилю.Ссылка = ВыборкаПоПредопределенному.Ссылка Тогда
Возврат ВыборкаПоПрофилю.Ссылка;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
Блокировка.Добавить("Справочник.ГруппыДоступа");
НачатьТранзакцию();
Попытка
Блокировка.Заблокировать();
РезультатыЗапроса = Запрос.ВыполнитьПакет();
ВыборкаПоПрофилю = РезультатыЗапроса[0].Выбрать();
ВыборкаПоПредопределенному = РезультатыЗапроса[1].Выбрать();
Если ВыборкаПоПрофилю.Следующий() Тогда
ГруппаДоступаОбъект = ВыборкаПоПрофилю.Ссылка.ПолучитьОбъект();
Если ГруппаДоступаОбъект.ИмяПредопределенныхДанных <> "Администраторы" Тогда
ГруппаДоступаОбъект.ИмяПредопределенныхДанных = "Администраторы";
КонецЕсли;
ИначеЕсли ВыборкаПоПредопределенному.Следующий() Тогда
ГруппаДоступаОбъект = ВыборкаПоПредопределенному.Ссылка.ПолучитьОбъект();
ГруппаДоступаОбъект.Профиль = ПрофильАдминистратор;
Иначе
ГруппаДоступаПоНаименованию = ГруппаДоступаПоНаименованию(
НСтр("ru = 'Администраторы'", ОбщегоНазначения.КодОсновногоЯзыка()));
Если ЗначениеЗаполнено(ГруппаДоступаПоНаименованию) Тогда
ГруппаДоступаОбъект = ГруппаДоступаПоНаименованию.ПолучитьОбъект();
Иначе
ГруппаДоступаОбъект = СоздатьЭлемент();
КонецЕсли;
ГруппаДоступаОбъект.Профиль = ПрофильАдминистратор;
ГруппаДоступаОбъект.ИмяПредопределенныхДанных = "Администраторы";
КонецЕсли;
Если ГруппаДоступаОбъект.Модифицированность() Тогда
ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаДоступаОбъект, Ложь, Ложь);
КонецЕсли;
ОбъектыДляОтвязки = Новый Соответствие;
Пока ВыборкаПоПрофилю.Следующий() Цикл
Если ВыборкаПоПрофилю.Ссылка <> ГруппаДоступаОбъект.Ссылка Тогда
ОбъектыДляОтвязки.Вставить(ВыборкаПоПрофилю.Ссылка);
КонецЕсли;
КонецЦикла;
Пока ВыборкаПоПредопределенному.Следующий() Цикл
Если ВыборкаПоПредопределенному.Ссылка <> ГруппаДоступаОбъект.Ссылка Тогда
ОбъектыДляОтвязки.Вставить(ВыборкаПоПредопределенному.Ссылка);
КонецЕсли;
КонецЦикла;
Для Каждого КлючИЗначение Из ОбъектыДляОтвязки Цикл
ТекущийГруппаДоступаОбъект = КлючИЗначение.Ключ.ПолучитьОбъект();
ТекущийГруппаДоступаОбъект.Профиль = Неопределено;
ТекущийГруппаДоступаОбъект.ИмяПредопределенныхДанных = "";
ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ТекущийГруппаДоступаОбъект, Ложь, Ложь);
КонецЦикла;
Для Каждого КлючИЗначение Из ОбъектыДляОтвязки Цикл
ТекущийГруппаДоступаОбъект = КлючИЗначение.Ключ.ПолучитьОбъект();
ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ТекущийГруппаДоступаОбъект);
КонецЦикла;
ГруппаДоступаОбъект.Наименование = НСтр("ru = 'Администраторы'",
ОбщегоНазначения.КодОсновногоЯзыка());
ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаДоступаОбъект);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
Возврат ГруппаДоступаОбъект.Ссылка;
КонецФункции
// Для функции ГруппаДоступаАдминистраторы.
Функция ГруппаДоступаПоНаименованию(Наименование)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Наименование", Наименование);
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ГруппыДоступа.Ссылка КАК Ссылка
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| ГруппыДоступа.Наименование = &Наименование
|
|УПОРЯДОЧИТЬ ПО
| Ссылка";
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Ссылка;
КонецЕсли;
Возврат Неопределено;
КонецФункции
// Устанавливает пометку удаления группам доступа, если установлена
// пометка удаления у профиля группы доступа. Требуется, например,
// при удалении предопределенных профилей групп доступа,
// т.к. платформа не вызывает обработчики объектов при
// установке пометки удаления бывшим предопределенным
// элементам в процессе обновления конфигурации базы данных.
//
// Параметры:
// ЕстьИзменения - Булево - возвращаемое значение. Если производилась запись,
// устанавливается Истина, иначе не изменяется.
//
Процедура ПометитьНаУдалениеГруппыДоступаПомеченныхПрофилей(ЕстьИзменения = Неопределено) Экспорт
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ПрофильАдминистратор", УправлениеДоступом.ПрофильАдминистратор());
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК Ссылка
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| ГруппыДоступа.Профиль <> &ПрофильАдминистратор
| И ГруппыДоступа.Профиль.ПометкаУдаления
| И НЕ ГруппыДоступа.ПометкаУдаления
| И НЕ ГруппыДоступа.Предопределенный";
Выборка = Запрос.Выполнить().Выбрать();
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Справочник.ГруппыДоступа");
Пока Выборка.Следующий() Цикл
ЭлементБлокировки.УстановитьЗначение("Ссылка", Выборка.Ссылка);
НачатьТранзакцию();
Попытка
Блокировка.Заблокировать();
ГруппаДоступаОбъект = Выборка.Ссылка.ПолучитьОбъект();
ГруппаДоступаОбъект.ПометкаУдаления = Истина;
ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаДоступаОбъект);
РегистрыСведений.ТаблицыГруппДоступа.ОбновитьДанныеРегистра(Выборка.Ссылка);
РегистрыСведений.ЗначенияГруппДоступа.ОбновитьДанныеРегистра(Выборка.Ссылка);
// @skip-check query-in-loop - Порционная обработка данных в транзакции
ПользователиДляОбновления = ПользователиДляОбновленияРолей(Неопределено, ГруппаДоступаОбъект);
УправлениеДоступом.ОбновитьРолиПользователей(ПользователиДляОбновления);
ЕстьИзменения = Истина;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецЦикла;
КонецПроцедуры
// Выполняет обновление видов доступа групп доступа указанного профиля.
// При этом возможно не удалять виды доступа из группы доступа,
// которые удалены в профиле этой группы доступа, в случае
// когда в группе доступа назначены значения доступа по
// удаляемому виду доступа.
//
// Параметры:
// Профиль - СправочникСсылка.ПрофилиГруппДоступа - профиль групп доступа.
//
// ОбновлятьГруппыДоступаСУстаревшимиНастройками - Булево - обновлять группы доступа.
//
// Возвращаемое значение:
// Булево - когда Истина, группа доступа была изменена,
// когда Ложь никаких изменений не было выполнено.
//
Функция ОбновитьГруппыДоступаПрофиля(Профиль, ОбновлятьГруппыДоступаСУстаревшимиНастройками = Ложь) Экспорт
ГруппаДоступаОбновлена = Ложь;
ВидыДоступаПрофиля = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Профиль, "ВидыДоступа").Выгрузить();
Индекс = ВидыДоступаПрофиля.Количество() - 1;
Пока Индекс >= 0 Цикл
Строка = ВидыДоступаПрофиля[Индекс];
СвойстваВидаДоступа = УправлениеДоступомСлужебный.СвойстваВидаДоступа(Строка.ВидДоступа);
Если СвойстваВидаДоступа = Неопределено Тогда
ВидыДоступаПрофиля.Удалить(Строка);
КонецЕсли;
Индекс = Индекс - 1;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ПрофильАдминистратор", УправлениеДоступом.ПрофильАдминистратор());
Запрос.УстановитьПараметр("ГруппаДоступаАдминистраторы", УправлениеДоступом.ГруппаДоступаАдминистраторы());
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК Ссылка
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| НЕ(ГруппыДоступа.Профиль <> &Профиль
| И НЕ(&Профиль = &ПрофильАдминистратор
| И ГруппыДоступа.Ссылка = &ГруппаДоступаАдминистраторы))";
Запрос.УстановитьПараметр("Профиль", Профиль);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Проверка необходимости/возможности обновления группы доступа.
ГруппаДоступа = Выборка.Ссылка.ПолучитьОбъект();
Если ГруппаДоступа.Ссылка = УправлениеДоступом.ГруппаДоступаАдминистраторы()
И ГруппаДоступа.Профиль <> УправлениеДоступом.ПрофильАдминистратор() Тогда
// Установка профиля Администратор, если не задан.
ГруппаДоступа.Профиль = УправлениеДоступом.ПрофильАдминистратор();
КонецЕсли;
// Проверка состава видов доступа.
СоставВидовДоступаИзменен = Ложь;
ЕстьУдаляемыеВидыДоступаСЗаданнымиЗначениямиДоступа = Ложь;
Если ГруппаДоступа.ВидыДоступа.Количество() <> ВидыДоступаПрофиля.НайтиСтроки(Новый Структура("Предустановленный", Ложь)).Количество() Тогда
СоставВидовДоступаИзменен = Истина;
Иначе
Для каждого СтрокаВидаДоступа Из ГруппаДоступа.ВидыДоступа Цикл
Если ВидыДоступаПрофиля.НайтиСтроки(Новый Структура("ВидДоступа, Предустановленный", СтрокаВидаДоступа.ВидДоступа, Ложь)).Количество() = 0 Тогда
СоставВидовДоступаИзменен = Истина;
Если ГруппаДоступа.ЗначенияДоступа.Найти(СтрокаВидаДоступа.ВидДоступа, "ВидДоступа") <> Неопределено Тогда
ЕстьУдаляемыеВидыДоступаСЗаданнымиЗначениямиДоступа = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если СоставВидовДоступаИзменен
И ( ОбновлятьГруппыДоступаСУстаревшимиНастройками
ИЛИ НЕ ЕстьУдаляемыеВидыДоступаСЗаданнымиЗначениямиДоступа ) Тогда
// Обновление группы доступа.
// 1. Удаление лишних видов доступа и значений доступа (если есть).
ТекущийНомерСтроки = ГруппаДоступа.ВидыДоступа.Количество()-1;
Пока ТекущийНомерСтроки >= 0 Цикл
ТекущийВидДоступа = ГруппаДоступа.ВидыДоступа[ТекущийНомерСтроки].ВидДоступа;
Если ВидыДоступаПрофиля.НайтиСтроки(Новый Структура("ВидДоступа, Предустановленный", ТекущийВидДоступа, Ложь)).Количество() = 0 Тогда
СтрокиЗначенийВидаДоступа = ГруппаДоступа.ЗначенияДоступа.НайтиСтроки(Новый Структура("ВидДоступа", ТекущийВидДоступа));
Для каждого СтрокаЗначения Из СтрокиЗначенийВидаДоступа Цикл
ГруппаДоступа.ЗначенияДоступа.Удалить(СтрокаЗначения);
КонецЦикла;
ГруппаДоступа.ВидыДоступа.Удалить(ТекущийНомерСтроки);
КонецЕсли;
ТекущийНомерСтроки = ТекущийНомерСтроки - 1;
КонецЦикла;
// 2. Добавление новых видов доступа (если есть).
Для каждого СтрокаВидаДоступа Из ВидыДоступаПрофиля Цикл
Если НЕ СтрокаВидаДоступа.Предустановленный
И ГруппаДоступа.ВидыДоступа.Найти(СтрокаВидаДоступа.ВидДоступа, "ВидДоступа") = Неопределено Тогда
НоваяСтрока = ГруппаДоступа.ВидыДоступа.Добавить();
НоваяСтрока.ВидДоступа = СтрокаВидаДоступа.ВидДоступа;
НоваяСтрока.ВсеРазрешены = СтрокаВидаДоступа.ВсеРазрешены;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ГруппаДоступа.Модифицированность() Тогда
Если Не ОбновлениеИнформационнойБазы.ВыполняетсяОбновлениеИнформационнойБазы()
И Не ОбновлениеИнформационнойБазы.ЭтоВызовИзОбработчикаОбновления() Тогда
ЗаблокироватьДанныеДляРедактирования(ГруппаДоступа.Ссылка, ГруппаДоступа.ВерсияДанных);
КонецЕсли;
Если Не Справочники.ВерсииРасширений.ВсеРасширенияПодключены() Тогда
СтарыеЗначения = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ГруппаДоступа.Ссылка, "ВидыДоступа, ЗначенияДоступа");
Справочники.ПрофилиГруппДоступа.ВосстановитьНесуществующиеВидыИЗначенияДоступа(СтарыеЗначения, ГруппаДоступа);
КонецЕсли;
ГруппаДоступа.ДополнительныеСвойства.Вставить("НеОбновлятьРолиПользователей");
ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаДоступа);
ГруппаДоступаОбновлена = Истина;
Если Не ОбновлениеИнформационнойБазы.ВыполняетсяОбновлениеИнформационнойБазы()
И Не ОбновлениеИнформационнойБазы.ЭтоВызовИзОбработчикаОбновления() Тогда
РазблокироватьДанныеДляРедактирования(ГруппаДоступа.Ссылка);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат ГруппаДоступаОбновлена;
КонецФункции
// Возвращает ссылку на группу-родителя персональных групп доступа.
// Если родитель не найден он будет создан.
//
// Параметры:
// НеСоздавать - Булево - если задан Истина, родитель не будет автоматически создан,
// а функция вернет Неопределено, если родитель не найден.
//
// НаименованиеГруппыЭлементов - Строка
//
// Возвращаемое значение:
// СправочникСсылка.ГруппыДоступа - ссылка на группу-родителя.
//
Функция РодительПерсональныхГруппДоступа(Знач НеСоздавать = Ложь, НаименованиеГруппыЭлементов = "") Экспорт
УстановитьПривилегированныйРежим(Истина);
НаименованиеГруппыЭлементов = НСтр("ru = 'Персональные группы доступа'");
Запрос = Новый Запрос(
"ВЫБРАТЬ
| ГруппыДоступа.Ссылка
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| ГруппыДоступа.Наименование ПОДОБНО &НаименованиеГруппыЭлементов СПЕЦСИМВОЛ ""~""
| И ГруппыДоступа.ЭтоГруппа");
Запрос.УстановитьПараметр("НаименованиеГруппыЭлементов",
ОбщегоНазначения.СформироватьСтрокуДляПоискаВЗапросе(НаименованиеГруппыЭлементов));
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ГруппаЭлементов = Выборка.Ссылка;
ИначеЕсли НеСоздавать Тогда
ГруппаЭлементов = Неопределено;
Иначе
ГруппаЭлементовОбъект = СоздатьГруппу();
ГруппаЭлементовОбъект.Наименование = НаименованиеГруппыЭлементов;
ГруппаЭлементовОбъект.Записать();
ГруппаЭлементов = ГруппаЭлементовОбъект.Ссылка;
КонецЕсли;
Возврат ГруппаЭлементов;
КонецФункции
Функция ИзменилисьВидыИлиЗначенияДоступа(СтарыеЗначения, ТекущийОбъект) Экспорт
Если СтарыеЗначения.Ссылка <> ТекущийОбъект.Ссылка Тогда
Возврат Истина;
КонецЕсли;
ВидыДоступа = СтарыеЗначения.ВидыДоступа.Выгрузить();
ЗначенияДоступа = СтарыеЗначения.ЗначенияДоступа.Выгрузить();
Если ВидыДоступа.Количество() <> ТекущийОбъект.ВидыДоступа.Количество()
Или ЗначенияДоступа.Количество() <> ТекущийОбъект.ЗначенияДоступа.Количество() Тогда
Возврат Истина;
КонецЕсли;
Отбор = Новый Структура("ВидДоступа, ВсеРазрешены");
Для Каждого Строка Из ТекущийОбъект.ВидыДоступа Цикл
ЗаполнитьЗначенияСвойств(Отбор, Строка);
Если ВидыДоступа.НайтиСтроки(Отбор).Количество() = 0 Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Отбор = Новый Структура("ВидДоступа, ЗначениеДоступа, ВключаяНижестоящие");
Для Каждого Строка Из ТекущийОбъект.ЗначенияДоступа Цикл
ЗаполнитьЗначенияСвойств(Отбор, Строка);
Если ЗначенияДоступа.НайтиСтроки(Отбор).Количество() = 0 Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
Функция ПользователиДляОбновленияРолей(СтарыеЗначения, ЭлементДанных) Экспорт
Если СтарыеЗначения = Неопределено Тогда
СтарыеЗначения = Новый Структура("Ссылка, Профиль, ПометкаУдаления")
КонецЕсли;
// Обновление ролей для добавленных, оставшихся и удаленных пользователей.
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("НовыеУчастники", ?(ТипЗнч(ЭлементДанных) <> Тип("УдалениеОбъекта"),
ЭлементДанных.Пользователи.ВыгрузитьКолонку("Пользователь"), Новый Массив));
Запрос.УстановитьПараметр("СтарыеУчастники", ?(ЭлементДанных.Ссылка = СтарыеЗначения.Ссылка,
СтарыеЗначения.Пользователи.Выгрузить().ВыгрузитьКолонку("Пользователь"), Новый Массив));
Если ТипЗнч(ЭлементДанных) = Тип("УдалениеОбъекта")
Или ЭлементДанных.Профиль <> СтарыеЗначения.Профиль
Или ЭлементДанных.ПометкаУдаления <> СтарыеЗначения.ПометкаУдаления Тогда
// Выбор всех новых и старых участников группы доступа.
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| СоставыГруппПользователей.Пользователь КАК Пользователь
|ИЗ
| РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
|ГДЕ
| (СоставыГруппПользователей.ГруппаПользователей В (&СтарыеУчастники)
| ИЛИ СоставыГруппПользователей.ГруппаПользователей В (&НовыеУчастники))";
Иначе
// Выбор изменений участников группы доступа.
Запрос.Текст =
"ВЫБРАТЬ
| Данные.Пользователь КАК Пользователь
|ИЗ
| (ВЫБРАТЬ РАЗЛИЧНЫЕ
| СоставыГруппПользователей.Пользователь КАК Пользователь,
| -1 КАК ВидИзмененияСтроки
| ИЗ
| РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
| ГДЕ
| СоставыГруппПользователей.ГруппаПользователей В(&СтарыеУчастники)
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ РАЗЛИЧНЫЕ
| СоставыГруппПользователей.Пользователь,
| 1
| ИЗ
| РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
| ГДЕ
| СоставыГруппПользователей.ГруппаПользователей В(&НовыеУчастники)) КАК Данные
|
|СГРУППИРОВАТЬ ПО
| Данные.Пользователь
|
|ИМЕЮЩИЕ
| СУММА(Данные.ВидИзмененияСтроки) <> 0";
КонецЕсли;
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Пользователь");
КонецФункции
Функция ПользователиДляОбновленияРолейПоПрофилю(Профили) Экспорт
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Профили", Профили);
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| СоставыГруппПользователей.Пользователь КАК Пользователь
|ИЗ
| РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
| ПО СоставыГруппПользователей.ГруппаПользователей = ГруппыДоступаПользователи.Пользователь
| И (ГруппыДоступаПользователи.Ссылка.Профиль В (&Профили))";
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Пользователь");
КонецФункции
Функция РолиДляОбновленияПрав(СтарыеЗначения, ЭлементДанных) Экспорт
Если СтарыеЗначения = Неопределено Тогда
СтарыеЗначения = Новый Структура("Ссылка, Профиль, ПометкаУдаления")
КонецЕсли;
// Обновление ролей для добавленных, оставшихся и удаленных пользователей.
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("НовыйПрофиль",
?(ТипЗнч(ЭлементДанных) <> Тип("УдалениеОбъекта") И Не ЭлементДанных.ПометкаУдаления,
ЭлементДанных.Профиль, Справочники.ПрофилиГруппДоступа.ПустаяСсылка()));
Запрос.УстановитьПараметр("СтарыйПрофиль",
?(ЭлементДанных.Ссылка = СтарыеЗначения.Ссылка И Не СтарыеЗначения.ПометкаУдаления,
СтарыеЗначения.Профиль, Справочники.ПрофилиГруппДоступа.ПустаяСсылка()));
Если ТипЗнч(ЭлементДанных) = Тип("УдалениеОбъекта")
Или ЭлементДанных.ПометкаУдаления <> СтарыеЗначения.ПометкаУдаления Тогда
// Выбор всех ролей старого или нового профилей группы доступа.
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| РолиПрофилей.Роль КАК Роль
|ИЗ
| Справочник.ПрофилиГруппДоступа.Роли КАК РолиПрофилей
|ГДЕ
| РолиПрофилей.Ссылка В (&СтарыйПрофиль, &НовыйПрофиль)";
Иначе
// Выбор изменений состава ролей группы доступа.
Запрос.Текст =
"ВЫБРАТЬ
| Данные.Роль КАК Роль
|ИЗ
| (ВЫБРАТЬ РАЗЛИЧНЫЕ
| РолиПрофилей.Роль КАК Роль,
| -1 КАК ВидИзмененияСтроки
| ИЗ
| Справочник.ПрофилиГруппДоступа.Роли КАК РолиПрофилей
| ГДЕ
| РолиПрофилей.Ссылка = &СтарыйПрофиль
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ РАЗЛИЧНЫЕ
| РолиПрофилей.Роль,
| 1
| ИЗ
| Справочник.ПрофилиГруппДоступа.Роли КАК РолиПрофилей
| ГДЕ
| РолиПрофилей.Ссылка = &НовыйПрофиль) КАК Данные
|
|СГРУППИРОВАТЬ ПО
| Данные.Роль
|
|ИМЕЮЩИЕ
| СУММА(Данные.ВидИзмененияСтроки) <> 0";
КонецЕсли;
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Роль");
КонецФункции
Функция ГруппыДоступаПрофиля(Профили) Экспорт
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Профили", Профили);
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК Ссылка
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| ГруппыДоступа.Профиль В(&Профили)
| И НЕ ГруппыДоступа.ЭтоГруппа";
РезультатЗапроса = Запрос.Выполнить();
Возврат РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Ссылка");
КонецФункции
// Только для внутреннего использования.
//
// Параметры:
// Объект - СправочникОбъект.ПрофилиГруппДоступа
// СтарыеЗначения - Структура
//
Функция УстановленаПометкаУдаленияПрофиля(Объект, СтарыеЗначения) Экспорт
Возврат Объект.ПометкаУдаления И СтарыеЗначения.ПометкаУдаления = Ложь;
КонецФункции
// Только для внутреннего использования.
//
// Параметры:
// Объект - СправочникОбъект.ГруппыДоступа
// - СправочникОбъект.ПрофилиГруппДоступа
// СтарыеЗначения - Структура
//
Процедура ЗарегистрироватьИзменениеУчастниковГруппДоступа(Объект, СтарыеЗначения) Экспорт
Данные = Новый Структура;
Данные.Вставить("ВерсияСтруктурыДанных", 1);
Данные.Вставить("ИзмененияУчастников", Новый Массив);
Данные.Вставить("ПредставлениеГруппДоступа", Новый Массив);
Данные.Вставить("СоставыГруппПользователей", Новый Массив);
Если ТипЗнч(Объект) = Тип("СправочникОбъект.ГруппыДоступа") Тогда
Если Объект.ДополнительныеСвойства.Свойство("УстановкаПометкиУдаленияГруппыДоступаПриУстановкеПометкиУдаленияПрофиля") Тогда
Если Не ПривилегированныйРежим() Тогда
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Свойство %1 допустимо использовать только в привилегированном режиме'"),
"УстановкаПометкиУдаленияГруппыДоступаПриУстановкеПометкиУдаленияПрофиля");
ВызватьИсключение ТекстОшибки;
КонецЕсли;
Возврат;
КонецЕсли;
ПометкаУдаленияПрофиля = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Объект.Профиль, "ПометкаУдаления");
ПометкаУдаленияПрофиля = ?(ТипЗнч(ПометкаУдаленияПрофиля) = Тип("Булево"), ПометкаУдаленияПрофиля, Ложь);
АктивностьГруппыДоступаИзменена = Объект.ПометкаУдаления <> СтарыеЗначения.ПометкаУдаления
Или Объект.Профиль <> СтарыеЗначения.Профиль
Или ПометкаУдаленияПрофиля <> СтарыеЗначения.ПометкаУдаленияПрофиля;
ИзмененияУчастников = Объект.Пользователи.Выгрузить();
ИзмененияУчастников.Индексы.Добавить("Пользователь");
ИзмененияУчастников.Свернуть("Пользователь, СрокДействия");
ИзмененияУчастников.Колонки.Добавить("ВидИзменения", Новый ОписаниеТипов("Строка"));
ИзмененияУчастников.ЗаполнитьЗначения("Добавлено", "ВидИзменения");
ИзмененияУчастников.Колонки.Добавить("СтарыйСрокДействия", Новый ОписаниеТипов("Дата"));
Если СтарыеЗначения.Пользователи <> Неопределено Тогда
Выборка = СтарыеЗначения.Пользователи.Выбрать();
Пока Выборка.Следующий() Цикл
НайденнаяСтрока = ИзмененияУчастников.Найти(Выборка.Пользователь, "Пользователь");
Если НайденнаяСтрока = Неопределено Тогда
НоваяСтрока = ИзмененияУчастников.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
НоваяСтрока.ВидИзменения = "Удалено";
ИначеЕсли НайденнаяСтрока.СрокДействия <> Выборка.СрокДействия Тогда
НайденнаяСтрока.СтарыйСрокДействия = Выборка.СрокДействия;
НайденнаяСтрока.ВидИзменения = "Изменено";
ИначеЕсли АктивностьГруппыДоступаИзменена Тогда
НайденнаяСтрока.СтарыйСрокДействия = НайденнаяСтрока.СрокДействия;
НайденнаяСтрока.ВидИзменения = "Изменено";
Иначе
ИзмененияУчастников.Удалить(НайденнаяСтрока);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Не АктивностьГруппыДоступаИзменена
И Не ЗначениеЗаполнено(ИзмененияУчастников) Тогда
Возврат;
КонецЕсли;
АктивныеУчастники = АктивныеУчастники(ИзмененияУчастников);
ИзмененияУчастников.Колонки.Добавить("ГруппаДоступа");
ИзмененияУчастников.ЗаполнитьЗначения(Объект.Ссылка, "ГруппаДоступа");
Свойства = Новый Структура;
Свойства.Вставить("ГруппаДоступа", СериализованнаяСсылка(Объект.Ссылка));
Свойства.Вставить("Представление", ПредставлениеСсылки(Объект.Ссылка));
Свойства.Вставить("ПометкаУдаления", Объект.ПометкаУдаления);
Свойства.Вставить("Профиль", СериализованнаяСсылка(Объект.Профиль));
Свойства.Вставить("ПредставлениеПрофиля", ПредставлениеСсылки(Объект.Профиль));
Свойства.Вставить("ПометкаУдаленияПрофиля", ПометкаУдаленияПрофиля);
Свойства.Вставить("СтарыеЗначенияСвойств", Новый Структура);
Если Объект.ПометкаУдаления <> СтарыеЗначения.ПометкаУдаления Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("ПометкаУдаления", СтарыеЗначения.ПометкаУдаления);
КонецЕсли;
Если Объект.Профиль <> СтарыеЗначения.Профиль Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("Профиль", СериализованнаяСсылка(СтарыеЗначения.Профиль));
СтароеПредставлениеПрофиля = ПредставлениеСсылки(СтарыеЗначения.Профиль);
Если Свойства.ПредставлениеПрофиля <> СтароеПредставлениеПрофиля Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("ПредставлениеПрофиля", СтароеПредставлениеПрофиля);
КонецЕсли;
КонецЕсли;
Если ПометкаУдаленияПрофиля <> СтарыеЗначения.ПометкаУдаленияПрофиля Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("ПометкаУдаленияПрофиля", СтарыеЗначения.ПометкаУдаленияПрофиля);
КонецЕсли;
Данные.ПредставлениеГруппДоступа.Добавить(Свойства);
Иначе
Если Объект.ПометкаУдаления = СтарыеЗначения.ПометкаУдаления Тогда
Возврат;
КонецЕсли;
ИсключаемаяГруппаДоступа = Справочники.ГруппыДоступа.ПустаяСсылка();
Если Объект.ДополнительныеСвойства.Свойство("СнятиеПометкиУдаленияПрофиляПриСнятииПометкиУдаленияГруппыДоступа") Тогда
Если Не ПривилегированныйРежим() Тогда
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Свойство %1 допустимо использовать только в привилегированном режиме'"),
"СнятиеПометкиУдаленияПрофиляПриСнятииПометкиУдаленияГруппыДоступа");
ВызватьИсключение ТекстОшибки;
КонецЕсли;
ИсключаемаяГруппаДоступа =
Объект.ДополнительныеСвойства.СнятиеПометкиУдаленияПрофиляПриСнятииПометкиУдаленияГруппыДоступа;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ИсключаемаяГруппаДоступа", ИсключаемаяГруппаДоступа);
Запрос.УстановитьПараметр("Профиль", Объект.Ссылка);
Запрос.УстановитьПараметр("НоваяПометкаУдаления", УстановленаПометкаУдаленияПрофиля(Объект, СтарыеЗначения));
// АПК:1377-выкл - №654.2.1 Требуются все четыре типа при обращении "через точку".
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК Ссылка,
| &НоваяПометкаУдаления КАК ПометкаУдаления
|ПОМЕСТИТЬ ГруппыДоступа
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| ГруппыДоступа.Профиль = &Профиль
| И ГруппыДоступа.Ссылка <> &ИсключаемаяГруппаДоступа
| И НЕ ГруппыДоступа.ПометкаУдаления
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК Ссылка,
| ГруппыДоступа.ПометкаУдаления КАК ПометкаУдаления
|ИЗ
| ГруппыДоступа КАК ГруппыДоступа
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| УчастникиГруппДоступа.Ссылка КАК ГруппаДоступа,
| УчастникиГруппДоступа.Пользователь КАК Пользователь,
| НЕ ЕСТЬNULL(УчастникиГруппДоступа.Пользователь.ПометкаУдаления, ИСТИНА)
| И НЕ ЕСТЬNULL(УчастникиГруппДоступа.Пользователь.Недействителен, ЛОЖЬ) КАК Используется,
| УчастникиГруппДоступа.СрокДействия КАК СрокДействия,
| УчастникиГруппДоступа.СрокДействия КАК СтарыйСрокДействия
|ИЗ
| ГруппыДоступа КАК ГруппыДоступа
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа.Пользователи КАК УчастникиГруппДоступа
| ПО (УчастникиГруппДоступа.Ссылка = ГруппыДоступа.Ссылка)";
// АПК:1377-вкл.
РезультатыЗапроса = Запрос.ВыполнитьПакет();
Если РезультатыЗапроса[1].Пустой() Тогда
Возврат;
КонецЕсли;
ИзмененияУчастников = РезультатыЗапроса[2].Выгрузить();
ИзмененияУчастников.Колонки.Добавить("ВидИзменения", Новый ОписаниеТипов("Строка"));
ИзмененияУчастников.ЗаполнитьЗначения("Изменено", "ВидИзменения");
АктивныеУчастники = Неопределено;
Выборка = РезультатыЗапроса[1].Выбрать();
Пока Выборка.Следующий() Цикл
Свойства = Новый Структура;
Свойства.Вставить("ГруппаДоступа", СериализованнаяСсылка(Выборка.Ссылка));
Свойства.Вставить("Представление", ПредставлениеСсылки(Выборка.Ссылка));
Свойства.Вставить("ПометкаУдаления", Выборка.ПометкаУдаления);
Свойства.Вставить("Профиль", СериализованнаяСсылка(Объект.Ссылка));
Свойства.Вставить("ПредставлениеПрофиля", ПредставлениеСсылки(Объект.Ссылка));
Свойства.Вставить("ПометкаУдаленияПрофиля", Объект.ПометкаУдаления);
Свойства.Вставить("СтарыеЗначенияСвойств", Новый Структура);
Если Объект.Ссылка <> СтарыеЗначения.Ссылка Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("Профиль", СериализованнаяСсылка(СтарыеЗначения.Ссылка));
СтароеПредставлениеПрофиля = ПредставлениеСсылки(СтарыеЗначения.Ссылка);
Если Свойства.ПредставлениеПрофиля <> СтароеПредставлениеПрофиля Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("ПредставлениеПрофиля", СтароеПредставлениеПрофиля);
КонецЕсли;
КонецЕсли;
Если Объект.ПометкаУдаления <> СтарыеЗначения.ПометкаУдаления Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("ПометкаУдаленияПрофиля",
?(ТипЗнч(СтарыеЗначения.ПометкаУдаления) = Тип("Булево"),
СтарыеЗначения.ПометкаУдаления, Ложь));
КонецЕсли;
Данные.ПредставлениеГруппДоступа.Добавить(Свойства);
КонецЦикла;
КонецЕсли;
ДобавленныеГруппыПользователей = Новый Соответствие;
ГруппыПользователей = Новый Массив;
ОписаниеТиповГрупп = Новый ОписаниеТипов("СправочникСсылка.ГруппыПользователей,
|СправочникСсылка.ГруппыВнешнихПользователей");
Для Каждого Строка Из ИзмененияУчастников Цикл
Если Не ЗначениеЗаполнено(Строка.Пользователь) Тогда
Продолжить;
КонецЕсли;
Если ОписаниеТиповГрупп.СодержитТип(ТипЗнч(Строка.Пользователь))
И ДобавленныеГруппыПользователей.Получить(Строка.Пользователь) = Неопределено Тогда
ГруппыПользователей.Добавить(Строка.Пользователь);
КонецЕсли;
Свойства = Новый Структура;
Свойства.Вставить("ГруппаДоступа", СериализованнаяСсылка(Строка.ГруппаДоступа));
Свойства.Вставить("Участник", СериализованнаяСсылка(Строка.Пользователь));
Свойства.Вставить("УчастникИспользуется", ?(АктивныеУчастники = Неопределено, Строка.Используется,
АктивныеУчастники.Найти(Строка.Пользователь, "Пользователь") <> Неопределено));
Свойства.Вставить("ПредставлениеУчастника", ПредставлениеСсылки(Строка.Пользователь));
Свойства.Вставить("СрокДействия", Строка.СрокДействия);
Свойства.Вставить("СтарыеЗначенияСвойств", Новый Структура);
Если Строка.ВидИзменения = "Изменено"
И Строка.СрокДействия <> Строка.СтарыйСрокДействия Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("СрокДействия", Строка.СтарыйСрокДействия);
КонецЕсли;
Свойства.Вставить("ВидИзменения", Строка.ВидИзменения);
Данные.ИзмененияУчастников.Добавить(Свойства);
КонецЦикла;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ГруппыПользователей", ГруппыПользователей);
Запрос.УстановитьПараметр("ГруппаВсеПользователи", Пользователи.ГруппаВсеПользователи());
Запрос.УстановитьПараметр("ГруппаВсеВнешниеПользователи", ВнешниеПользователи.ГруппаВсеВнешниеПользователи());
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| СоставыГруппПользователей.ГруппаПользователей КАК ГруппаПользователей,
| СоставыГруппПользователей.Пользователь КАК Пользователь,
| СоставыГруппПользователей.Используется КАК Используется,
| ПРЕДСТАВЛЕНИЕ(СоставыГруппПользователей.Пользователь) КАК ПредставлениеПользователя,
| НЕ ГруппыПользователейСостав.Пользователь ЕСТЬ NULL
| ИЛИ НЕ ГруппыВнешнихПользователейСостав.ВнешнийПользователь ЕСТЬ NULL
| ИЛИ СоставыГруппПользователей.ГруппаПользователей = &ГруппаВсеПользователи
| ИЛИ СоставыГруппПользователей.ГруппаПользователей = &ГруппаВсеВнешниеПользователи КАК ПользовательВГруппе
|ИЗ
| РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ГруппыПользователей.Состав КАК ГруппыПользователейСостав
| ПО (ГруппыПользователейСостав.Ссылка = СоставыГруппПользователей.ГруппаПользователей)
| И (ГруппыПользователейСостав.Пользователь = СоставыГруппПользователей.Пользователь)
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ГруппыВнешнихПользователей.Состав КАК ГруппыВнешнихПользователейСостав
| ПО (ГруппыВнешнихПользователейСостав.Ссылка = СоставыГруппПользователей.ГруппаПользователей)
| И (ГруппыВнешнихПользователейСостав.ВнешнийПользователь = СоставыГруппПользователей.Пользователь)
|ГДЕ
| СоставыГруппПользователей.ГруппаПользователей В(&ГруппыПользователей)";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Свойства = Новый Структура;
Свойства.Вставить("ГруппаПользователей", СериализованнаяСсылка(Выборка.ГруппаПользователей));
Свойства.Вставить("Пользователь", СериализованнаяСсылка(Выборка.Пользователь));
Свойства.Вставить("ИзНижестоящейГруппы", Не Выборка.ПользовательВГруппе);
Свойства.Вставить("Используется", Выборка.Используется);
Свойства.Вставить("ПредставлениеПользователя", Выборка.ПредставлениеПользователя);
Данные.СоставыГруппПользователей.Добавить(Свойства);
КонецЦикла;
ИмяСобытия = УправлениеДоступомСлужебный.ИмяСобытияИзменениеУчастниковГруппДоступаДляЖурналаРегистрации();
ЗаписьЖурналаРегистрации(ИмяСобытия,
УровеньЖурналаРегистрации.Информация,
Объект.Метаданные(),
ОбщегоНазначения.ЗначениеВСтрокуXML(Данные),
,
РежимТранзакцииЗаписиЖурналаРегистрации.Транзакционная);
КонецПроцедуры
// Для процедуры ЗарегистрироватьИзменениеУчастниковГруппДоступа.
Функция АктивныеУчастники(ИзмененияУчастников)
Участники = ИзмененияУчастников.Скопировать(, "Пользователь");
Участники.Свернуть("Пользователь");
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Участники", Участники);
Запрос.Текст =
"ВЫБРАТЬ
| Участники.Пользователь КАК Пользователь
|ПОМЕСТИТЬ Участники
|ИЗ
| &Участники КАК Участники
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Участники.Пользователь КАК Пользователь
|ИЗ
| Участники КАК Участники
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Пользователи КАК Пользователи
| ПО (Пользователи.Ссылка = Участники.Пользователь)
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВнешниеПользователи КАК ВнешниеПользователи
| ПО (ВнешниеПользователи.Ссылка = Участники.Пользователь)
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ГруппыПользователей КАК ГруппыПользователей
| ПО (ГруппыПользователей.Ссылка = Участники.Пользователь)
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ГруппыВнешнихПользователей КАК ГруппыВнешнихПользователей
| ПО (ГруппыВнешнихПользователей.Ссылка = Участники.Пользователь)
|ГДЕ
| ВЫБОР
| КОГДА НЕ Пользователи.Ссылка ЕСТЬ NULL
| ТОГДА НЕ Пользователи.ПометкаУдаления
| И НЕ Пользователи.Недействителен
| КОГДА НЕ ВнешниеПользователи.Ссылка ЕСТЬ NULL
| ТОГДА НЕ ВнешниеПользователи.ПометкаУдаления
| И НЕ ВнешниеПользователи.Недействителен
| КОГДА НЕ ГруппыПользователей.Ссылка ЕСТЬ NULL
| ТОГДА НЕ ГруппыПользователей.ПометкаУдаления
| КОГДА НЕ ГруппыВнешнихПользователей.Ссылка ЕСТЬ NULL
| ТОГДА НЕ ГруппыВнешнихПользователей.ПометкаУдаления
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ";
Результат = Запрос.Выполнить().Выгрузить();
Результат.Индексы.Добавить("Пользователь");
Возврат Результат;
КонецФункции
// См. ПользователиСлужебный.СериализованнаяСсылка
Функция СериализованнаяСсылка(Ссылка)
Возврат ПользователиСлужебный.СериализованнаяСсылка(Ссылка);
КонецФункции
// См. ПользователиСлужебный.ПредставлениеСсылки
Функция ПредставлениеСсылки(Ссылка)
Возврат ПользователиСлужебный.ПредставлениеСсылки(Ссылка);
КонецФункции
// Только для внутреннего использования.
//
// Параметры:
// Объект - СправочникОбъект.ГруппыДоступа
// - СправочникОбъект.ПрофилиГруппДоступа
// - ОпределяемыйТип.ЗначениеДоступаОбъект - для регистрации изменений использования групп значений доступа
// и состава иерархии родителя, если значение доступа используется с нижестоящими значениями.
// - Структура:
// * ИзменениеВидовДоступа - ТаблицаЗначений:
// ** ВидДоступа - ОпределяемыйТип.ЗначениеДоступа
// ** Использование - Булево - новое использование вида доступа после изменения
// в регистре сведений ИспользуемыеВидыДоступа.
// ** ВидИзменения - Строка - одна из строк "Добавлено", "Удалено", "Изменено".
// * ИзменениеСоставовГруппПользователей - см. ПользователиСлужебный.НовоеИзменениеСоставовГруппДляРегистрации
//
// СтарыеЗначения - Структура - старые значения свойств, когда объект не типа структура.
// - Неопределено - когда объект типа структура.
//
Процедура ЗарегистрироватьИзменениеРазрешенныхЗначений(Объект, СтарыеЗначения) Экспорт
Если ТипЗнч(Объект) = Тип("Структура") Тогда
Источник = Новый Массив;
ПредставлениеИсточника = Неопределено;
Если Объект.Свойство("ИзменениеВидовДоступа") Тогда
НавигационнаяСсылкаИсточника = "e1cib/list/РегистрСведений.ИспользуемыеВидыДоступа";
МетаданныеОбъекта = Метаданные.РегистрыСведений.ИспользуемыеВидыДоступа;
Иначе
НавигационнаяСсылкаИсточника = "e1cib/list/РегистрСведений.СоставыГруппПользователей";
МетаданныеОбъекта = Метаданные.РегистрыСведений.СоставыГруппПользователей;
КонецЕсли;
Иначе
Источник = СериализованнаяСсылка(Объект.Ссылка);
ПредставлениеИсточника = ПредставлениеСсылки(Объект.Ссылка);
НавигационнаяСсылкаИсточника = ПолучитьНавигационнуюСсылку(Объект.Ссылка);
МетаданныеОбъекта = Объект.Метаданные();
КонецЕсли;
Данные = Новый Структура;
Данные.Вставить("ВерсияСтруктурыДанных", 1);
Данные.Вставить("Источник", Источник);
Данные.Вставить("НавигационнаяСсылкаИсточника", НавигационнаяСсылкаИсточника);
Данные.Вставить("ПредставлениеИсточника", ПредставлениеИсточника);
Данные.Вставить("ИзменениеВидовДоступа", Новый Массив);
Данные.Вставить("ПредставлениеВидовДоступа", Новый Массив);
Данные.Вставить("ИзменениеЗначенийДоступа", Новый Массив);
Данные.Вставить("ИзменениеГруппЗначенийДоступа", Новый Массив);
Данные.Вставить("ПредставлениеГруппДоступа", Новый Массив);
Данные.Вставить("ПредставлениеЗначенийДоступа", Новый Массив);
СвойстваВидовДоступа = УправлениеДоступомСлужебный.СвойстваВидовДоступа();
Если ТипЗнч(Объект) = Тип("СправочникОбъект.ГруппыДоступа") Тогда
// Добавление изменений состава видов доступа и флажка ВсеРазрешены.
СтарыеЗначения.Вставить("ВидыДоступаПрофиля", Неопределено);
СвойстваПрофиля = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Объект.Профиль,
"ПометкаУдаления, ВидыДоступа, ЗначенияДоступа");
Если СтарыеЗначения.Профиль = Объект.Профиль Тогда
СтарыеЗначения.ВидыДоступаПрофиля = СвойстваПрофиля.ВидыДоступа;
ИначеЕсли ЗначениеЗаполнено(СтарыеЗначения.Профиль) Тогда
СтарыеЗначения.ВидыДоступаПрофиля = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(
СтарыеЗначения.Профиль, "ВидыДоступа");
КонецЕсли;
ПредустановленныеВидыДоступаПрофиля = ?(ЗначениеЗаполнено(СтарыеЗначения.Ссылка),
Неопределено, Новый Соответствие);
НовыеВидыДоступа = ВидыДоступаБезПовторений(Объект.ВидыДоступа.Выгрузить(),,
СвойстваПрофиля.ВидыДоступа, ПредустановленныеВидыДоступаПрофиля);
ИзменениеВидовДоступа = ИзменениеСоставаВидовДоступа(НовыеВидыДоступа, СтарыеЗначения);
// Добавление изменений состава значений и групп значений доступа, флажка ВключаяНижестоящие,
// а также значений доступа, у которых вид доступа добавлен / удален / изменен флажок ВсеРазрешены.
ИзменениеЗначенийДоступа = ИзменениеСоставаЗначенийДоступа(Объект,
СтарыеЗначения, ИзменениеВидовДоступа, СвойстваВидовДоступа);
Если Не ЗначениеЗаполнено(ИзменениеВидовДоступа)
И Не ЗначениеЗаполнено(ИзменениеЗначенийДоступа) Тогда
Возврат;
КонецЕсли;
// Добавление неизмененных видов доступа, для которых изменились значения доступа.
ДобавитьВидыДоступаДляКоторыхИзменилисьЗначенияДоступа(ИзменениеЗначенийДоступа,
ИзменениеВидовДоступа, НовыеВидыДоступа);
ИзменениеВидовДоступа.ЗаполнитьЗначения(Объект.Ссылка, "ГруппаДоступаИлиПрофиль");
ИзменениеЗначенийДоступа.ЗаполнитьЗначения(Объект.Ссылка, "ГруппаДоступаИлиПрофиль");
// Добавление предустановленных видов доступа профиля и их значений при создании группы доступа.
ДобавитьПредустановленныеВидыДоступаСоЗначениями(ИзменениеВидовДоступа, ИзменениеЗначенийДоступа,
Объект.Профиль, ПредустановленныеВидыДоступаПрофиля, СвойстваПрофиля.ЗначенияДоступа, СвойстваВидовДоступа);
// Заполнение состава измененных групп значений доступа.
// Заполнение нижестоящих значений доступа с флажком ВключаяНижестоящие и при изменении флажка.
ИзменениеГруппЗначенийДоступа = ЗначенияГруппЗначений(ИзменениеЗначенийДоступа, СвойстваВидовДоступа);
УдалитьЛишниеНеизмененныеЗначенияИГруппы(ИзменениеЗначенийДоступа, ИзменениеГруппЗначенийДоступа);
// Добавление представления группы доступа.
ПометкаУдаленияПрофиля = ?(ТипЗнч(СвойстваПрофиля.ПометкаУдаления) = Тип("Булево"),
СвойстваПрофиля.ПометкаУдаления, Ложь);
Свойства = Новый Структура;
Свойства.Вставить("ГруппаДоступа", СериализованнаяСсылка(Объект.Ссылка));
Свойства.Вставить("Представление", ПредставлениеСсылки(Объект.Ссылка));
Свойства.Вставить("ПометкаУдаления", Объект.ПометкаУдаления);
Свойства.Вставить("Профиль", СериализованнаяСсылка(Объект.Профиль));
Свойства.Вставить("ПредставлениеПрофиля", ПредставлениеСсылки(Объект.Профиль));
Свойства.Вставить("ПометкаУдаленияПрофиля", ПометкаУдаленияПрофиля);
Свойства.Вставить("СтарыеЗначенияСвойств", Новый Структура);
Если Объект.ПометкаУдаления <> СтарыеЗначения.ПометкаУдаления Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("ПометкаУдаления", СтарыеЗначения.ПометкаУдаления);
КонецЕсли;
Если Объект.Профиль <> СтарыеЗначения.Профиль Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("Профиль", СериализованнаяСсылка(СтарыеЗначения.Профиль));
СтароеПредставлениеПрофиля = ПредставлениеСсылки(СтарыеЗначения.Профиль);
Если Свойства.ПредставлениеПрофиля <> СтароеПредставлениеПрофиля Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("ПредставлениеПрофиля", СтароеПредставлениеПрофиля);
КонецЕсли;
КонецЕсли;
Если ПометкаУдаленияПрофиля <> СтарыеЗначения.ПометкаУдаленияПрофиля Тогда
Свойства.СтарыеЗначенияСвойств.Вставить("ПометкаУдаленияПрофиля", СтарыеЗначения.ПометкаУдаленияПрофиля);
КонецЕсли;
Данные.ПредставлениеГруппДоступа.Добавить(Свойства);
ИначеЕсли ТипЗнч(Объект) = Тип("СправочникОбъект.ПрофилиГруппДоступа") Тогда
// Добавление изменений состава видов доступа и флажков ВсеРазрешены, Предустановленный.
ВидыДоступаСИзменениемПредустановки = Новый Массив;
НовыеВидыДоступа = ВидыДоступаБезПовторений(Объект.ВидыДоступа.Выгрузить(), Истина);
ИзменениеВидовДоступа = ИзменениеСоставаВидовДоступа(НовыеВидыДоступа,
СтарыеЗначения, Истина, ВидыДоступаСИзменениемПредустановки);
// Добавление изменений состава значений и групп значений доступа, флажка ВключаяНижестоящие,
// а также значений доступа, у которых вид доступа добавлен / удален / изменен флажок ВсеРазрешены.
ИзменениеЗначенийДоступа = ИзменениеСоставаЗначенийДоступа(Объект, СтарыеЗначения,
ИзменениеВидовДоступа, СвойстваВидовДоступа);
Если Не ЗначениеЗаполнено(ИзменениеВидовДоступа)
И Не ЗначениеЗаполнено(ИзменениеЗначенийДоступа) Тогда
Возврат;
КонецЕсли;
// Добавление неизмененных видов доступа, для которых изменились значения доступа.
ДобавитьВидыДоступаДляКоторыхИзменилисьЗначенияДоступа(ИзменениеЗначенийДоступа,
ИзменениеВидовДоступа, НовыеВидыДоступа);
ИзменениеВидовДоступа.ЗаполнитьЗначения(Объект.Ссылка, "ГруппаДоступаИлиПрофиль");
ИзменениеЗначенийДоступа.ЗаполнитьЗначения(Объект.Ссылка, "ГруппаДоступаИлиПрофиль");
// Добавление видов и значений доступа групп доступа профиля,
// для видов доступа профиля с измененным признаком Предустановленный.
СвойстваГруппДоступа = СвойстваГруппДоступаПрофиля(Объект.Ссылка, ВидыДоступаСИзменениемПредустановки);
ЗаполнитьВидыИЗначенияДоступа(ИзменениеВидовДоступа,
ИзменениеЗначенийДоступа, СвойстваГруппДоступа, СвойстваВидовДоступа);
// Заполнение состава измененных групп значений доступа.
// Заполнение нижестоящих значений доступа с флажком ВключаяНижестоящие и при изменении флажка.
ИзменениеГруппЗначенийДоступа = ЗначенияГруппЗначений(ИзменениеЗначенийДоступа, СвойстваВидовДоступа);
УдалитьЛишниеНеизмененныеЗначенияИГруппы(ИзменениеЗначенийДоступа, ИзменениеГруппЗначенийДоступа);
// Добавление представлений групп доступа профиля.
СериализованнаяСсылкаПрофиля = СериализованнаяСсылка(Объект.Ссылка);
ПредставлениеПрофиля = ПредставлениеСсылки(Объект.Ссылка);
СтарыеЗначенияСвойств = Новый Структура;
Если Объект.ПометкаУдаления <> СтарыеЗначения.ПометкаУдаления Тогда
СтарыеЗначенияСвойств.Вставить("ПометкаУдаленияПрофиля",
?(ТипЗнч(СтарыеЗначения.ПометкаУдаления) = Тип("Булево"),
СтарыеЗначения.ПометкаУдаления, Ложь));
КонецЕсли;
СтароеПредставлениеПрофиля = ПредставлениеСсылки(СтарыеЗначения.Ссылка);
Если ПредставлениеПрофиля <> СтароеПредставлениеПрофиля Тогда
СтарыеЗначенияСвойств.Вставить("ПредставлениеПрофиля", СтароеПредставлениеПрофиля);
КонецЕсли;
Если Не ЗначениеЗаполнено(СвойстваГруппДоступа.ГруппыДоступа) Тогда
НоваяСтрока = СвойстваГруппДоступа.ГруппыДоступа.Добавить();
НоваяСтрока.ГруппаДоступа = Справочники.ГруппыДоступа.ПустаяСсылка();
НоваяСтрока.Представление = "<" + НСтр("ru = 'Нет группы доступа'",
ОбщегоНазначения.КодОсновногоЯзыка()) + ">";
КонецЕсли;
Для Каждого ОписаниеГруппыДоступа Из СвойстваГруппДоступа.ГруппыДоступа Цикл
Свойства = Новый Структура;
Свойства.Вставить("ГруппаДоступа", СериализованнаяСсылка(ОписаниеГруппыДоступа.ГруппаДоступа));
Свойства.Вставить("Представление", ОписаниеГруппыДоступа.Представление);
Свойства.Вставить("ПометкаУдаления", ОписаниеГруппыДоступа.ПометкаУдаления);
Свойства.Вставить("Профиль", СериализованнаяСсылкаПрофиля);
Свойства.Вставить("ПредставлениеПрофиля", ПредставлениеПрофиля);
Свойства.Вставить("ПометкаУдаленияПрофиля", Объект.ПометкаУдаления);
Свойства.Вставить("СтарыеЗначенияСвойств", СтарыеЗначенияСвойств);
Данные.ПредставлениеГруппДоступа.Добавить(Свойства);
КонецЦикла;
ИначеЕсли ТипЗнч(Объект) <> Тип("Структура")
Или Объект.Свойство("ИзменениеСоставовГруппПользователей") Тогда
ИзменениеВидовДоступа = НовоеИзменениеВидовДоступа();
ИзменениеЗначенийДоступа = НовоеИзменениеЗначенийДоступа();
ИзменениеГруппЗначенийДоступа = Неопределено;
Если ТипЗнч(Объект) = Тип("Структура") Тогда
ИзменениеГруппЗначенийДоступа = Объект.ИзменениеСоставовГруппПользователей.Скопировать(,
"ГруппаПользователей, Пользователь, ВидИзменения");
ИзменениеГруппЗначенийДоступа.Колонки.ГруппаПользователей.Имя = "ГруппаЗначений";
ИзменениеГруппЗначенийДоступа.Колонки.Пользователь.Имя = "ЗначениеДоступа";
Отбор = Новый Структура("ВидИзменения", "Изменено");
НайденныеСтроки = ИзменениеГруппЗначенийДоступа.НайтиСтроки(Отбор);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ИзменениеГруппЗначенийДоступа.Удалить(НайденнаяСтрока);
КонецЦикла;
СвойстваПрофилейИГруппДоступа = СвойстваПрофилейИГруппДоступаИзмененийГруппЗначений(
ИзменениеГруппЗначенийДоступа);
ИначеЕсли СтарыеЗначения.Свойство("ГруппаДоступа")
Или СтарыеЗначения.Свойство("ГруппыДоступа") Тогда
Свойства = СвойстваВидовДоступа.ЗначенияДоступаСГруппами.ПоТипамДляОбновления.Получить(ТипЗнч(Объект));
Если Свойства = Неопределено
Или Свойства.ТипГруппЗначений <> Тип("Неопределено") Тогда
Возврат;
КонецЕсли;
ИзменениеГруппЗначенийДоступа = ИзменениеГруппЗначенийДоступа(Объект,
СтарыеЗначения, Свойства.НесколькоГруппЗначений);
СвойстваПрофилейИГруппДоступа = СвойстваПрофилейИГруппДоступаИзмененийГруппЗначений(
ИзменениеГруппЗначенийДоступа);
ИначеЕсли СтарыеЗначения.Свойство("Родитель") Тогда
Свойства = СвойстваВидовДоступа.ПоТипамЗначенийСИерархией.Получить(ТипЗнч(Объект));
Если Свойства = Неопределено Тогда
Возврат;
КонецЕсли;
ИзменениеГруппЗначенийДоступа = ИзменениеЗначенийДоступаРодителей(Объект, СтарыеЗначения);
СвойстваПрофилейИГруппДоступа = СвойстваПрофилейИГруппДоступаИзмененийГруппЗначений(
ИзменениеГруппЗначенийДоступа, Истина);
КонецЕсли;
ЗаполнитьВидыИЗначенияДоступа(ИзменениеВидовДоступа,
ИзменениеЗначенийДоступа, СвойстваПрофилейИГруппДоступа, СвойстваВидовДоступа);
УдалитьЛишниеНеизмененныеЗначенияИГруппы(ИзменениеЗначенийДоступа, ИзменениеГруппЗначенийДоступа);
// Добавление представлений групп доступа профилей.
ЗаполнитьПредставлениеГруппДоступаПрофилей(Данные, СвойстваПрофилейИГруппДоступа.ГруппыДоступа);
Иначе
// Добавление изменения использования видов доступа.
Для Каждого Строка Из Объект.ИзменениеВидовДоступа Цикл
Свойства = Новый Структура;
Свойства.Вставить("ВидДоступа", СериализованнаяСсылка(Строка.ВидДоступа));
Свойства.Вставить("Используется", Строка.Используется);
Свойства.Вставить("ВидИзменения", Строка.ВидИзменения);
Данные.Источник.Добавить(Свойства);
КонецЦикла;
ИзменениеВидовДоступа = НовоеИзменениеВидовДоступа();
ИзменениеЗначенийДоступа = НовоеИзменениеЗначенийДоступа();
СвойстваПрофилейИГруппДоступа = СвойстваПрофилейИГруппДоступаИзмененийВидовДоступа(Объект.ИзменениеВидовДоступа);
ЗаполнитьВидыИЗначенияДоступа(ИзменениеВидовДоступа,
ИзменениеЗначенийДоступа, СвойстваПрофилейИГруппДоступа, СвойстваВидовДоступа);
// Заполнение состава измененных групп значений доступа.
// Заполнение нижестоящих значений доступа с флажком ВключаяНижестоящие.
ИзменениеГруппЗначенийДоступа = ЗначенияГруппЗначений(ИзменениеЗначенийДоступа, СвойстваВидовДоступа);
// Добавление представлений групп доступа профилей.
ЗаполнитьПредставлениеГруппДоступаПрофилей(Данные, СвойстваПрофилейИГруппДоступа.ГруппыДоступа);
КонецЕсли;
Если Не ЗначениеЗаполнено(ИзменениеВидовДоступа)
И Не ЗначениеЗаполнено(ИзменениеЗначенийДоступа) Тогда
Возврат;
КонецЕсли;
// Заполнение изменений видов доступа.
Для Каждого Строка Из ИзменениеВидовДоступа Цикл
Свойства = Новый Структура;
Свойства.Вставить("ГруппаДоступаИлиПрофиль", СериализованнаяСсылка(Строка.ГруппаДоступаИлиПрофиль));
Свойства.Вставить("ВидДоступа", СериализованнаяСсылка(Строка.ВидДоступа));
Свойства.Вставить("ВсеРазрешены", Строка.ВсеРазрешены);
Свойства.Вставить("Предустановленный", Строка.Предустановленный);
Свойства.Вставить("ВидИзменения", Строка.ВидИзменения);
Свойства.Вставить("СтарыеЗначенияСвойств", Строка.СтарыеЗначенияСвойств);
Данные.ИзменениеВидовДоступа.Добавить(Свойства);
КонецЦикла;
// Заполнение представлений видов доступа.
РегистрируемыеВидыДоступа = ИзменениеВидовДоступа.Скопировать(, "ВидДоступа");
РегистрируемыеВидыДоступа.Свернуть("ВидДоступа");
СвойстваВидовДоступаПоТипам = СвойстваВидовДоступа.ПоТипамГруппИЗначений;
ИспользуемыеВидыДоступа = УправлениеДоступомСлужебный.ИспользуемыеВидыДоступа(Истина);
ПредставлениеВидовДоступа = УправлениеДоступомСлужебный.ПредставлениеВидовДоступа();
Для Каждого Строка Из РегистрируемыеВидыДоступа Цикл
ТипЗначенияВидаДоступа = ТипЗнч(Строка.ВидДоступа);
Свойства = Новый Структура;
Свойства.Вставить("ВидДоступа", СериализованнаяСсылка(Строка.ВидДоступа));
Свойства.Вставить("Используется", ИспользуемыеВидыДоступа.Получить(Строка.ВидДоступа) <> Неопределено);
Свойства.Вставить("Имя", "");
Свойства.Вставить("Представление", "");
СвойстваВидаДоступа = СвойстваВидовДоступаПоТипам.Получить(ТипЗначенияВидаДоступа);
Если СвойстваВидаДоступа = Неопределено Тогда
Свойства.Представление = "? " + Строка(ТипЗначенияВидаДоступа);
Иначе
Свойства.Имя = СвойстваВидаДоступа.Имя;
Свойства.Представление = ПредставлениеВидовДоступа.Получить(ТипЗначенияВидаДоступа);
КонецЕсли;
Данные.ПредставлениеВидовДоступа.Добавить(Свойства);
КонецЦикла;
// Заполнение изменений значений доступа.
Для Каждого Строка Из ИзменениеЗначенийДоступа Цикл
Свойства = Новый Структура;
Свойства.Вставить("ГруппаДоступаИлиПрофиль", СериализованнаяСсылка(Строка.ГруппаДоступаИлиПрофиль));
Свойства.Вставить("ВидДоступа", СериализованнаяСсылка(Строка.ВидДоступа));
Свойства.Вставить("ЗначениеДоступа", СериализованнаяСсылка(Строка.ЗначениеДоступа));
Свойства.Вставить("ЭтоГруппаЗначений", Строка.ЭтоГруппаЗначений);
Свойства.Вставить("ВключаяНижестоящие", Строка.ВключаяНижестоящие);
Свойства.Вставить("ВидИзменения", Строка.ВидИзменения);
Свойства.Вставить("СтарыеЗначенияСвойств", Строка.СтарыеЗначенияСвойств);
Данные.ИзменениеЗначенийДоступа.Добавить(Свойства);
КонецЦикла;
РегистрируемыеЗначения = ИзменениеЗначенийДоступа.Скопировать(, "ЗначениеДоступа");
// Заполнение изменений групп значений доступа.
Если ЗначениеЗаполнено(ИзменениеГруппЗначенийДоступа) Тогда
Для Каждого Строка Из ИзменениеГруппЗначенийДоступа Цикл
Свойства = Новый Структура;
Свойства.Вставить("ГруппаЗначений", СериализованнаяСсылка(Строка.ГруппаЗначений));
Свойства.Вставить("ЗначениеДоступа", СериализованнаяСсылка(Строка.ЗначениеДоступа));
Свойства.Вставить("ВидИзменения", Строка.ВидИзменения);
Данные.ИзменениеГруппЗначенийДоступа.Добавить(Свойства);
РегистрируемыеЗначения.Добавить().ЗначениеДоступа = Строка.ГруппаЗначений;
РегистрируемыеЗначения.Добавить().ЗначениеДоступа = Строка.ЗначениеДоступа;
КонецЦикла;
КонецЕсли;
// Заполнение представлений значений и групп значений доступа.
РегистрируемыеЗначения.Свернуть("ЗначениеДоступа");
КодыПеречислений = УправлениеДоступомСлужебныйПовтИсп.КодыПеречислений();
ПеречисленияТипВсеСсылки = Перечисления.ТипВсеСсылки();
Для Каждого Строка Из РегистрируемыеЗначения Цикл
Свойства = Новый Структура;
Свойства.Вставить("Значение", СериализованнаяСсылка(Строка.ЗначениеДоступа));
Свойства.Вставить("Представление", ПредставлениеСсылки(Строка.ЗначениеДоступа));
Свойства.Вставить("НавигационнаяСсылка", "");
Если СтрНачинаетсяС(Свойства.Значение, "{") Тогда
Если ПеречисленияТипВсеСсылки.СодержитТип(ТипЗнч(Строка.ЗначениеДоступа)) Тогда
Свойства.НавигационнаяСсылка = СтрШаблон("e1cib/list/%1?name=%2",
Строка.ЗначениеДоступа.Метаданные().ПолноеИмя(), КодыПеречислений.Получить(Строка.ЗначениеДоступа));
Иначе
Свойства.НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(Строка.ЗначениеДоступа);
КонецЕсли;
КонецЕсли;
Данные.ПредставлениеЗначенийДоступа.Добавить(Свойства);
КонецЦикла;
ИмяСобытия = УправлениеДоступомСлужебный.ИмяСобытияИзменениеРазрешенныхЗначенийДляЖурналаРегистрации();
ЗаписьЖурналаРегистрации(ИмяСобытия,
УровеньЖурналаРегистрации.Информация,
МетаданныеОбъекта,
ОбщегоНазначения.ЗначениеВСтрокуXML(Данные),
,
РежимТранзакцииЗаписиЖурналаРегистрации.Транзакционная);
КонецПроцедуры
Функция НовоеИзменениеВидовДоступа(НовыеВидыДоступа = Неопределено)
Если НовыеВидыДоступа = Неопределено Тогда
ШаблонПрофиля = Справочники.ПрофилиГруппДоступа.СоздатьЭлемент();
ИзменениеВидовДоступа = ШаблонПрофиля.ВидыДоступа.Выгрузить(Новый Массив);
Иначе
ИзменениеВидовДоступа = НовыеВидыДоступа;
КонецЕсли;
ИзменениеВидовДоступа.Колонки.Добавить("ГруппаДоступаИлиПрофиль");
ИзменениеВидовДоступа.Колонки.Добавить("ВидИзменения", Новый ОписаниеТипов("Строка"));
ИзменениеВидовДоступа.Колонки.Добавить("СтарыеЗначенияСвойств", Новый ОписаниеТипов("Структура"));
Возврат ИзменениеВидовДоступа;
КонецФункции
Функция ИзменениеСоставаВидовДоступа(НовыеВидыДоступа, СтарыеЗначения, ЭтоПрофиль = Ложь,
ВидыДоступаСИзменениемПредустановки = Неопределено)
ИзменениеВидовДоступа = НовоеИзменениеВидовДоступа(НовыеВидыДоступа.Скопировать());
ИзменениеВидовДоступа.ЗаполнитьЗначения("Добавлено", "ВидИзменения");
Если СтарыеЗначения.ВидыДоступа = Неопределено Тогда
Возврат ИзменениеВидовДоступа;
КонецЕсли;
СтарыеВидыДоступа = ВидыДоступаБезПовторений(СтарыеЗначения.ВидыДоступа.Выгрузить(),
ЭтоПрофиль, ?(ЭтоПрофиль, Неопределено, СтарыеЗначения.ВидыДоступаПрофиля));
Для Каждого СтараяСтрока Из СтарыеВидыДоступа Цикл
НоваяСтрока = ИзменениеВидовДоступа.Найти(СтараяСтрока.ВидДоступа, "ВидДоступа");
Если НоваяСтрока = Неопределено Тогда
НоваяСтрока = ИзменениеВидовДоступа.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтараяСтрока);
НоваяСтрока.ВидИзменения = "Удалено";
ИначеЕсли НоваяСтрока.ВсеРазрешены <> СтараяСтрока.ВсеРазрешены
Или НоваяСтрока.Предустановленный <> СтараяСтрока.Предустановленный Тогда
НоваяСтрока.ВидИзменения = "Изменено";
Если НоваяСтрока.ВсеРазрешены <> СтараяСтрока.ВсеРазрешены Тогда
НоваяСтрока.СтарыеЗначенияСвойств.Вставить("ВсеРазрешены", СтараяСтрока.ВсеРазрешены);
КонецЕсли;
Если НоваяСтрока.Предустановленный <> СтараяСтрока.Предустановленный Тогда
НоваяСтрока.СтарыеЗначенияСвойств.Вставить("Предустановленный", СтараяСтрока.Предустановленный);
ВидыДоступаСИзменениемПредустановки.Добавить(НоваяСтрока.ВидДоступа);
КонецЕсли;
Иначе
ИзменениеВидовДоступа.Удалить(НоваяСтрока);
КонецЕсли;
КонецЦикла;
Возврат ИзменениеВидовДоступа;
КонецФункции
Функция НовоеИзменениеЗначенийДоступа(НовыеЗначенияДоступа = Неопределено)
Если НовыеЗначенияДоступа = Неопределено Тогда
ШаблонПрофиля = Справочники.ПрофилиГруппДоступа.СоздатьЭлемент();
ИзменениеЗначенийДоступа = ШаблонПрофиля.ЗначенияДоступа.Выгрузить(Новый Массив);
ИзменениеЗначенийДоступа.Колонки.Добавить("ЭтоГруппаЗначений", Новый ОписаниеТипов("Булево"));
Иначе
ИзменениеЗначенийДоступа = НовыеЗначенияДоступа;
КонецЕсли;
ИзменениеЗначенийДоступа.Колонки.Добавить("ГруппаДоступаИлиПрофиль");
ИзменениеЗначенийДоступа.Колонки.Добавить("ВидИзменения", Новый ОписаниеТипов("Строка"));
ИзменениеЗначенийДоступа.Колонки.Добавить("СтарыеЗначенияСвойств", Новый ОписаниеТипов("Структура"));
ИзменениеЗначенийДоступа.Колонки.Добавить("СтароеЗначениеВключаяНижестоящие", Новый ОписаниеТипов("Булево"));
Возврат ИзменениеЗначенийДоступа;
КонецФункции
Функция ИзменениеСоставаЗначенийДоступа(Объект, СтарыеЗначения, ИзменениеВидовДоступа, СвойстваВидовДоступа)
НовыеЗначенияДоступа = ЗначенияДоступаБезПовторений(Объект.ЗначенияДоступа.Выгрузить(),
СвойстваВидовДоступа);
ИзменениеЗначенийДоступа = НовоеИзменениеЗначенийДоступа(НовыеЗначенияДоступа);
ИзменениеЗначенийДоступа.ЗаполнитьЗначения("Добавлено", "ВидИзменения");
Если СтарыеЗначения.ЗначенияДоступа <> Неопределено Тогда
СтарыеЗначенияДоступа = ЗначенияДоступаБезПовторений(СтарыеЗначения.ЗначенияДоступа.Выгрузить(),
СвойстваВидовДоступа);
Для Каждого СтараяСтрока Из СтарыеЗначенияДоступа Цикл
Отбор = Новый Структура("ВидДоступа, ЗначениеДоступа");
ЗаполнитьЗначенияСвойств(Отбор, СтараяСтрока);
НайденныеСтроки = ИзменениеЗначенийДоступа.НайтиСтроки(Отбор);
НоваяСтрока = ?(ЗначениеЗаполнено(НайденныеСтроки), НайденныеСтроки[0], Неопределено);
Если НоваяСтрока = Неопределено Тогда
НоваяСтрока = ИзменениеЗначенийДоступа.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтараяСтрока);
НоваяСтрока.ВидИзменения = "Удалено";
ИначеЕсли НоваяСтрока.ВключаяНижестоящие <> СтараяСтрока.ВключаяНижестоящие Тогда
НоваяСтрока.ВидИзменения = "Изменено";
НоваяСтрока.СтарыеЗначенияСвойств.Вставить("ВключаяНижестоящие", СтараяСтрока.ВключаяНижестоящие);
НоваяСтрока.СтароеЗначениеВключаяНижестоящие = СтараяСтрока.ВключаяНижестоящие;
ИначеЕсли ИзменениеВидовДоступа.Найти(СтараяСтрока.ВидДоступа, "ВидДоступа") <> Неопределено Тогда
НоваяСтрока.ВидИзменения = "Изменено";
Иначе
НоваяСтрока.ВидИзменения = "";
КонецЕсли;
КонецЦикла;
ИзменениеВидовДоступаПоЗначениям = ИзменениеЗначенийДоступа.Скопировать(, "ВидДоступа, ВидИзменения");
ИзменениеВидовДоступаПоЗначениям.Свернуть("ВидДоступа, ВидИзменения");
ВидыДоступа = ИзменениеВидовДоступаПоЗначениям.Скопировать(, "ВидДоступа");
ВидыДоступа.Свернуть("ВидДоступа");
Для Каждого ОписаниеВидаДоступа Из ВидыДоступа Цикл
Отбор = Новый Структура("ВидДоступа", ОписаниеВидаДоступа.ВидДоступа);
НайденныеСтроки = ИзменениеВидовДоступаПоЗначениям.НайтиСтроки(Отбор);
Если НайденныеСтроки.Количество() <> 1 Или НайденныеСтроки[0].ВидИзменения <> "" Тогда
Продолжить;
КонецЕсли;
НайденныеСтроки = ИзменениеЗначенийДоступа.НайтиСтроки(Отбор);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ИзменениеЗначенийДоступа.Удалить(НайденнаяСтрока);
КонецЦикла;
КонецЦикла;
КонецЕсли;
Возврат ИзменениеЗначенийДоступа;
КонецФункции
Функция ВидыДоступаБезПовторений(Таблица, ЭтоПрофиль = Ложь, ВидыДоступаПрофиля = Неопределено,
ПредустановленныеВидыДоступаПрофиля = Неопределено)
Если Не ЭтоПрофиль Тогда
ПредустановленныеВидыДоступа = Новый Соответствие;
Если ТипЗнч(ВидыДоступаПрофиля) = Тип("РезультатЗапроса") Тогда
Выгрузка = ВидыДоступаПрофиля.Выгрузить();
Для Каждого СтрокаТЧ Из Выгрузка Цикл
ПредустановленныеВидыДоступа.Вставить(СтрокаТЧ.ВидДоступа, СтрокаТЧ);
КонецЦикла;
КонецЕсли;
Если ПредустановленныеВидыДоступаПрофиля <> Неопределено Тогда
ПредустановленныеВидыДоступаПрофиля = ПредустановленныеВидыДоступа;
КонецЕсли;
КонецЕсли;
Результат = Таблица.Скопировать(, "ВидДоступа");
Результат.Свернуть("ВидДоступа");
Результат.Колонки.Добавить("ВсеРазрешены", Новый ОписаниеТипов("Булево"));
Результат.Колонки.Добавить("Предустановленный");
Отбор = Новый Структура("ВидДоступа");
Для Каждого Строка Из Результат Цикл
Отбор.ВидДоступа = Строка.ВидДоступа;
НайденныеСтроки = Таблица.НайтиСтроки(Отбор);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
Строка.ВсеРазрешены = Строка.ВсеРазрешены Или НайденнаяСтрока.ВсеРазрешены;
Если ЭтоПрофиль Тогда
Строка.Предустановленный = НайденнаяСтрока.Предустановленный
Или ?(Строка.Предустановленный = Неопределено, Ложь, Строка.Предустановленный);
КонецЕсли;
КонецЦикла;
Если Не ЭтоПрофиль Тогда
// Когда вида доступа нет в профиле группы доступа или он предустановленный,
// то настройки группы доступа игнорируются.
СтрокаТЧ = ПредустановленныеВидыДоступа.Получить(Строка.ВидДоступа);
Если СтрокаТЧ <> Неопределено Тогда
Строка.Предустановленный = СтрокаТЧ.Предустановленный;
Если Не СтрокаТЧ.Предустановленный Тогда
ПредустановленныеВидыДоступа.Удалить(Строка.ВидДоступа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ЗначенияДоступаБезПовторений(Таблица, СвойстваВидовДоступа)
Результат = Таблица.Скопировать(, "ВидДоступа, ЗначениеДоступа");
Результат.Свернуть("ВидДоступа, ЗначениеДоступа");
Результат.Колонки.Добавить("ВключаяНижестоящие", Новый ОписаниеТипов("Булево"));
Результат.Колонки.Добавить("ЭтоГруппаЗначений", Новый ОписаниеТипов("Булево"));
Отбор = Новый Структура("ВидДоступа, ЗначениеДоступа");
СвойстваПоТипамЗначений = СвойстваВидовДоступа.ПоТипамЗначений;
СвойстваПоТипамГруппИЗначений = СвойстваВидовДоступа.ПоТипамГруппИЗначений;
Для Каждого Строка Из Результат Цикл
ЗаполнитьЗначенияСвойств(Отбор, Строка);
НайденныеСтроки = Таблица.НайтиСтроки(Отбор);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
Строка.ВключаяНижестоящие = Строка.ВключаяНижестоящие Или НайденнаяСтрока.ВключаяНижестоящие;
КонецЦикла;
ТипЗначения = ТипЗнч(Строка.ЗначениеДоступа);
Строка.ЭтоГруппаЗначений = СвойстваПоТипамЗначений.Получить(ТипЗначения) = Неопределено
И СвойстваПоТипамГруппИЗначений.Получить(ТипЗначения) <> Неопределено;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ДобавитьВидыДоступаДляКоторыхИзменилисьЗначенияДоступа(ИзменениеЗначенийДоступа, ИзменениеВидовДоступа,
НовыеВидыДоступа)
ВидыДоступаСИзменениемЗначений = ИзменениеЗначенийДоступа.Скопировать(, "ВидДоступа");
ВидыДоступаСИзменениемЗначений.Свернуть("ВидДоступа");
Для Каждого Строка Из ВидыДоступаСИзменениемЗначений Цикл
НайденнаяСтрока = ИзменениеВидовДоступа.Найти(Строка.ВидДоступа, "ВидДоступа");
Если НайденнаяСтрока <> Неопределено Тогда
Продолжить;
КонецЕсли;
НоваяСтрока = ИзменениеВидовДоступа.Добавить();
НоваяСтрока.ВидИзменения = "Изменено";
НайденнаяСтрока = НовыеВидыДоступа.Найти(Строка.ВидДоступа, "ВидДоступа");
Если НайденнаяСтрока <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(НоваяСтрока, НайденнаяСтрока);
Иначе
НоваяСтрока.ВидДоступа = Строка.ВидДоступа;
НоваяСтрока.ВсеРазрешены = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ДобавитьПредустановленныеВидыДоступаСоЗначениями(ИзменениеВидовДоступа, ИзменениеЗначенийДоступа,
Профиль, ПредустановленныеВидыДоступаПрофиля, СвойстваПрофиляЗначенияДоступа, СвойстваВидовДоступа);
Если Не ЗначениеЗаполнено(ПредустановленныеВидыДоступаПрофиля) Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(СвойстваПрофиляЗначенияДоступа) = Тип("РезультатЗапроса") Тогда
ЗначенияДоступаПрофиля = ЗначенияДоступаБезПовторений(СвойстваПрофиляЗначенияДоступа.Выгрузить(),
СвойстваВидовДоступа);
Иначе
ЗначенияДоступаПрофиля = Неопределено;
КонецЕсли;
Для Каждого ОписаниеВидаДоступа Из ПредустановленныеВидыДоступаПрофиля Цикл
НоваяСтрока = ИзменениеВидовДоступа.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ОписаниеВидаДоступа.Значение);
НоваяСтрока.ГруппаДоступаИлиПрофиль = Профиль;
НоваяСтрока.ВидИзменения = "Изменено";
Если ЗначенияДоступаПрофиля = Неопределено Тогда
Продолжить;
КонецЕсли;
Отбор = Новый Структура("ВидДоступа", НоваяСтрока.ВидДоступа);
НайденныеСтроки = ЗначенияДоступаПрофиля.НайтиСтроки(Отбор);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
НоваяСтрока = ИзменениеЗначенийДоступа.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, НайденнаяСтрока);
НоваяСтрока.ГруппаДоступаИлиПрофиль = Профиль;
НоваяСтрока.ВидИзменения = "Изменено";
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ЗначенияГруппЗначений(ИзменениеЗначенийДоступа, СвойстваВидовДоступа)
Запрос = Новый Запрос;
ЧастиЗапроса = Новый Массив;
ДобавитьЗапросыЗначенийГруппЗначений(Запрос, ЧастиЗапроса, ИзменениеЗначенийДоступа, СвойстваВидовДоступа);
ДобавитьЗапросыНижестоящихЗначений(Запрос, ЧастиЗапроса, ИзменениеЗначенийДоступа);
Если Не ЗначениеЗаполнено(ЧастиЗапроса) Тогда
Возврат Неопределено;
КонецЕсли;
Запрос.Текст = Запрос.Текст + СтрСоединить(ЧастиЗапроса, ОбщегоНазначения.ТекстОбъединитьВсе());
Результат = Запрос.Выполнить().Выгрузить();
Результат.Колонки.Добавить("ВидИзменения");
Результат.ЗаполнитьЗначения("Изменено", "ВидИзменения");
Возврат Результат;
КонецФункции
// Для функции ИзменениеГруппЗначенийДоступа.
Процедура ДобавитьЗапросыЗначенийГруппЗначений(Запрос, ЧастиЗапроса, ИзменениеЗначенийДоступа, СвойстваВидовДоступа)
Отбор = Новый Структура("ЭтоГруппаЗначений", Истина);
НайденныеСтроки = ИзменениеЗначенийДоступа.НайтиСтроки(Отбор);
Если Не ЗначениеЗаполнено(НайденныеСтроки) Тогда
Возврат;
КонецЕсли;
ТекстЗапросаВременнойТаблицы =
"ВЫБРАТЬ
| ГруппыЗначений.ЗначениеДоступа КАК ГруппаЗначенийДоступа
|ПОМЕСТИТЬ ТекущиеГруппыЗначений
|ИЗ
| &ГруппыЗначений КАК ГруппыЗначений";
ШаблонЧастиЗапроса =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ТекущаяТаблица.ГруппаДоступа КАК ГруппаЗначений,
| ТекущаяТаблица.Ссылка КАК ЗначениеДоступа
|ИЗ
| ТаблицаЗначенийДоступа КАК ТекущаяТаблица
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТекущиеГруппыЗначений КАК ТекущиеГруппыЗначений
| ПО ТекущаяТаблица.ГруппаДоступа = ТекущиеГруппыЗначений.ГруппаЗначенийДоступа";
ШаблонЧастиЗапросаПользователей =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ТекущаяТаблица.ГруппаПользователей КАК ГруппаЗначений,
| ТекущаяТаблица.Пользователь КАК ЗначениеДоступа
|ИЗ
| РегистрСведений.СоставыГруппПользователей КАК ТекущаяТаблица
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТекущиеГруппыЗначений КАК ТекущиеГруппыЗначений
| ПО ТекущаяТаблица.ГруппаПользователей = ТекущиеГруппыЗначений.ГруппаЗначенийДоступа";
СвойстваВидовДоступаПоСсылкам = СвойстваВидовДоступа.ПоСсылкам;
ВидыДоступа = ИзменениеЗначенийДоступа.Скопировать(НайденныеСтроки, "ВидДоступа");
ВидыДоступа.Свернуть("ВидДоступа");
ШаблонЧастиЗапросаПользователейДобавлен = Ложь;
Для Каждого Строка Из ВидыДоступа Цикл
Свойства = СвойстваВидовДоступаПоСсылкам.Получить(Строка.ВидДоступа);
Если Свойства = Неопределено Тогда
Продолжить;
КонецЕсли;
Если Свойства.Имя = "Пользователи" Или Свойства.Имя = "ВнешниеПользователи" Тогда
Если Не ШаблонЧастиЗапросаПользователейДобавлен Тогда
ЧастиЗапроса.Добавить(ШаблонЧастиЗапросаПользователей);
ШаблонЧастиЗапросаПользователейДобавлен = Истина;
КонецЕсли;
Продолжить;
КонецЕсли;
ДобавитьЧастьЗапроса(Свойства, ЧастиЗапроса, ШаблонЧастиЗапроса);
Для Каждого ТекущиеСвойства Из Свойства.ДополнительныеТипы Цикл
ДобавитьЧастьЗапроса(ТекущиеСвойства, ЧастиЗапроса, ШаблонЧастиЗапроса);
КонецЦикла;
КонецЦикла;
Если Не ЗначениеЗаполнено(ЧастиЗапроса) Тогда
Возврат;
КонецЕсли;
ГруппыЗначений = ИзменениеЗначенийДоступа.Скопировать(НайденныеСтроки, "ЗначениеДоступа");
ГруппыЗначений.Свернуть("ЗначениеДоступа");
Запрос.УстановитьПараметр("ГруппыЗначений", ГруппыЗначений);
Запрос.Текст = ТекстЗапросаВременнойТаблицы + ОбщегоНазначения.РазделительПакетаЗапросов();
КонецПроцедуры
// Для процедуры ДобавитьЗапросыЗначенийГруппЗначений.
Процедура ДобавитьЧастьЗапроса(Свойства, ЧастиЗапроса, ШаблонЧастиЗапроса)
Если Свойства.ТипГруппЗначений = Тип("Неопределено") Тогда
Возврат;
КонецЕсли;
ОбъектМетаданных = Метаданные.НайтиПоТипу(Свойства.ТипЗначений);
Если ОбъектМетаданных = Неопределено Тогда
Возврат;
КонецЕсли;
ПолноеИмяТаблицы = ОбъектМетаданных.ПолноеИмя();
Если Свойства.НесколькоГруппЗначений Тогда
ПолноеИмяТаблицы = ПолноеИмяТаблицы + "." + ОбъектМетаданных.ТабличныеЧасти.ГруппыДоступа.Имя;
КонецЕсли;
ЧастиЗапроса.Добавить(СтрЗаменить(ШаблонЧастиЗапроса, "ТаблицаЗначенийДоступа", ПолноеИмяТаблицы));
КонецПроцедуры
// Для функции ИзменениеГруппЗначенийДоступа.
Процедура ДобавитьЗапросыНижестоящихЗначений(Запрос, ЧастиЗапроса, ИзменениеЗначенийДоступа)
Отбор = Новый Структура("ВключаяНижестоящие", Истина);
НайденныеСтроки = ИзменениеЗначенийДоступа.НайтиСтроки(Отбор);
ЗначенияДоступа = ИзменениеЗначенийДоступа.Скопировать(НайденныеСтроки, "ЗначениеДоступа");
Отбор = Новый Структура("ВключаяНижестоящие, СтароеЗначениеВключаяНижестоящие", Ложь, Истина);
НайденныеСтроки = ИзменениеЗначенийДоступа.НайтиСтроки(Отбор);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ЗначенияДоступа.Добавить(), НайденнаяСтрока);
КонецЦикла;
ЗначенияДоступа.Свернуть("ЗначениеДоступа");
ЗначенияДоступаСИзменениемНижестоящих = Новый Соответствие;
Для Каждого ОписаниеЗначения Из ЗначенияДоступа Цикл
ТипЗначения = ТипЗнч(ОписаниеЗначения.ЗначениеДоступа);
ЗначенияПоТипу = ЗначенияДоступаСИзменениемНижестоящих.Получить(ТипЗначения);
Если ЗначенияПоТипу = Неопределено Тогда
ЗначенияПоТипу = Новый Соответствие;
ЗначенияДоступаСИзменениемНижестоящих.Вставить(ТипЗначения, ЗначенияПоТипу);
КонецЕсли;
ЗначенияПоТипу.Вставить(ОписаниеЗначения.ЗначениеДоступа);
КонецЦикла;
ШаблонЗапроса =
"ВЫБРАТЬ
| &ЗначениеДоступа КАК ГруппаЗначений,
| Таблица.Ссылка КАК ЗначениеДоступа
|ИЗ
| &Таблица КАК Таблица
|ГДЕ
| Таблица.Ссылка В ИЕРАРХИИ(&ЗначениеДоступа)";
Индекс = 0;
Для Каждого ЗначенияПоТипу Из ЗначенияДоступаСИзменениемНижестоящих Цикл
ОбъектМетаданных = Метаданные.НайтиПоТипу(ЗначенияПоТипу.Ключ);
Если ОбъектМетаданных = Неопределено Тогда
Продолжить;
КонецЕсли;
ТекстЗапроса = СтрЗаменить(ШаблонЗапроса, "&Таблица", ОбъектМетаданных.ПолноеИмя());
Для Каждого ОписаниеЗначения Из ЗначенияПоТипу.Значение Цикл
Индекс = Индекс + 1;
ИмяПараметра = "ЗначениеДоступа" + XMLСтрока(Индекс);
Запрос.УстановитьПараметр(ИмяПараметра, ОписаниеЗначения.Ключ);
ЧастиЗапроса.Добавить(СтрЗаменить(ТекстЗапроса, "&ЗначениеДоступа", "&" + ИмяПараметра));
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура УдалитьЛишниеНеизмененныеЗначенияИГруппы(ИзменениеЗначенийДоступа, ИзменениеГруппЗначенийДоступа)
Если ИзменениеГруппЗначенийДоступа <> Неопределено Тогда
ИзменениеГруппЗначенийДоступа.Индексы.Добавить("ГруппаЗначений");
ИзменениеГруппЗначенийДоступа.Индексы.Добавить("ЗначениеДоступа");
КонецЕсли;
// Удаление лишних неизмененных значений и групп значений.
ИзменениеЗначенийДоступа.Индексы.Добавить("ГруппаДоступаИлиПрофиль, ВидДоступа");
Отбор = Новый Структура("ВидИзменения", "");
НайденныеСтроки = ИзменениеЗначенийДоступа.НайтиСтроки(Отбор);
ОписаниеОтборов = ИзменениеЗначенийДоступа.Скопировать(НайденныеСтроки, "ГруппаДоступаИлиПрофиль, ВидДоступа");
ОписаниеОтборов.Свернуть("ГруппаДоступаИлиПрофиль, ВидДоступа");
ОтборЗначений = Новый Структура("ГруппаДоступаИлиПрофиль, ВидДоступа");
Для Каждого ОписаниеОтбора Из ОписаниеОтборов Цикл
ЗаполнитьЗначенияСвойств(ОтборЗначений, ОписаниеОтбора);
Значения = ИзменениеЗначенийДоступа.НайтиСтроки(ОтборЗначений);
ЗначенияБезИзменения = Новый Массив;
ЗначенияСИзменением = Новый Соответствие;
Для Каждого СтрокаТЗ Из Значения Цикл
Если СтрокаТЗ.ВидИзменения = "" Тогда
ЗначенияБезИзменения.Добавить(СтрокаТЗ);
Иначе
ЗначенияСИзменением.Вставить(СтрокаТЗ.ЗначениеДоступа, Истина);
КонецЕсли;
КонецЦикла;
Для Каждого ОписаниеЗначения Из ЗначенияБезИзменения Цикл
ЕстьПересечение = Ложь;
Если ИзменениеГруппЗначенийДоступа <> Неопределено
И (ОписаниеЗначения.ЭтоГруппаЗначений Или ОписаниеЗначения.ВключаяНижестоящие) Тогда
Отбор = Новый Структура("ГруппаЗначений", ОписаниеЗначения.ЗначениеДоступа);
ЗначенияГруппы = ИзменениеГруппЗначенийДоступа.НайтиСтроки(Отбор);
Для Каждого ЗначениеГруппы Из ЗначенияГруппы Цикл
ЕстьПересечение = ЗначениеВСоставеИзмененных(ЗначениеГруппы.ЗначениеДоступа,
ЗначенияСИзменением, ИзменениеГруппЗначенийДоступа);
Если ЕстьПересечение Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЕстьПересечение Тогда
Продолжить;
КонецЕсли;
Если Не ОписаниеЗначения.ЭтоГруппаЗначений Или ОписаниеЗначения.ВключаяНижестоящие Тогда
ЕстьПересечение = ЗначениеВСоставеИзмененных(ОписаниеЗначения.ЗначениеДоступа,
ЗначенияСИзменением, ИзменениеГруппЗначенийДоступа);
КонецЕсли;
Если ЕстьПересечение Тогда
Продолжить;
КонецЕсли;
ИзменениеЗначенийДоступа.Удалить(ОписаниеЗначения);
КонецЦикла;
КонецЦикла;
// Удаление лишних групп значений со значениями.
Если ИзменениеГруппЗначенийДоступа = Неопределено Тогда
Возврат;
КонецЕсли;
ГруппыЗначений = ИзменениеГруппЗначенийДоступа.Скопировать(, "ГруппаЗначений");
ГруппыЗначений.Свернуть("ГруппаЗначений");
ИзменениеЗначенийДоступа.Индексы.Добавить("ЗначениеДоступа");
Для Каждого ОписаниеГруппыЗначений Из ГруппыЗначений Цикл
Отбор = Новый Структура("ЗначениеДоступа", ОписаниеГруппыЗначений.ГруппаЗначений);
Если ИзменениеЗначенийДоступа.Найти(ОписаниеГруппыЗначений.ГруппаЗначений, "ЗначениеДоступа") <> Неопределено Тогда
Продолжить;
КонецЕсли;
Отбор = Новый Структура("ГруппаЗначений", ОписаниеГруппыЗначений.ГруппаЗначений);
НайденныеСтроки = ИзменениеГруппЗначенийДоступа.НайтиСтроки(Отбор);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ИзменениеГруппЗначенийДоступа.Удалить(НайденнаяСтрока);
КонецЦикла;
КонецЦикла;
КонецПроцедуры
// Для процедуры УдалитьЛишниеНеизмененныеЗначенияИГруппы.
Функция ЗначениеВСоставеИзмененных(ЗначениеБезИзменения, ЗначенияИГруппыСИзменением, ГруппыЗначений)
Если ЗначенияИГруппыСИзменением.Получить(ЗначениеБезИзменения) <> Неопределено Тогда
Возврат Истина;
КонецЕсли;
Если ГруппыЗначений = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Отбор = Новый Структура("ЗначениеДоступа", ЗначениеБезИзменения);
Группы = ГруппыЗначений.НайтиСтроки(Отбор);
Для Каждого ОписаниеГруппы Из Группы Цикл
Если ЗначенияИГруппыСИзменением.Получить(ОписаниеГруппы.ГруппаЗначений) <> Неопределено Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
Функция СвойстваГруппДоступаПрофиля(Профиль, ВидыДоступаСИзменениемПредустановки)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Профиль", Профиль);
Запрос.УстановитьПараметр("ВидыДоступаСИзменениемПредустановки", ВидыДоступаСИзменениемПредустановки);
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК Ссылка,
| ГруппыДоступа.ПометкаУдаления КАК ПометкаУдаления,
| ПРЕДСТАВЛЕНИЕ(ГруппыДоступа.Ссылка) КАК Представление
|ПОМЕСТИТЬ ГруппыДоступа
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| ГруппыДоступа.Профиль = &Профиль
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК ГруппаДоступа,
| ГруппыДоступа.ПометкаУдаления КАК ПометкаУдаления,
| ГруппыДоступа.Представление КАК Представление
|ИЗ
| ГруппыДоступа КАК ГруппыДоступа
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВидыДоступаГруппДоступа.Ссылка КАК ГруппаДоступаИлиПрофиль,
| ВидыДоступаГруппДоступа.ВидДоступа КАК ВидДоступа,
| ВидыДоступаГруппДоступа.ВсеРазрешены КАК ВсеРазрешены
|ИЗ
| ГруппыДоступа КАК ГруппыДоступа
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа.ВидыДоступа КАК ВидыДоступаГруппДоступа
| ПО (ВидыДоступаГруппДоступа.Ссылка = ГруппыДоступа.Ссылка)
| И (ВидыДоступаГруппДоступа.ВидДоступа В (&ВидыДоступаСИзменениемПредустановки))
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ЗначенияДоступаГруппДоступа.Ссылка КАК ГруппаДоступаИлиПрофиль,
| ЗначенияДоступаГруппДоступа.ВидДоступа КАК ВидДоступа,
| ЗначенияДоступаГруппДоступа.ЗначениеДоступа КАК ЗначениеДоступа,
| ЗначенияДоступаГруппДоступа.ВключаяНижестоящие КАК ВключаяНижестоящие
|ИЗ
| ГруппыДоступа КАК ГруппыДоступа
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа.ЗначенияДоступа КАК ЗначенияДоступаГруппДоступа
| ПО (ЗначенияДоступаГруппДоступа.Ссылка = ГруппыДоступа.Ссылка)
| И (ЗначенияДоступаГруппДоступа.ВидДоступа В (&ВидыДоступаСИзменениемПредустановки))";
РезультатыЗапроса = Запрос.ВыполнитьПакет();
Результат = Новый Структура;
Результат.Вставить("ГруппыДоступа", РезультатыЗапроса[1].Выгрузить());
Результат.Вставить("ВидыДоступа", РезультатыЗапроса[2].Выгрузить());
Результат.Вставить("ЗначенияДоступа", РезультатыЗапроса[3].Выгрузить());
Возврат Результат;
КонецФункции
Функция СвойстваПрофилейИГруппДоступаИзмененийВидовДоступа(ИзменениеВидовДоступа)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ИзмененныеВидыДоступа",
ИзменениеВидовДоступа.ВыгрузитьКолонку("ВидДоступа"));
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК ГруппаДоступа,
| ГруппыДоступа.ПометкаУдаления КАК ПометкаУдаления,
| ПРЕДСТАВЛЕНИЕ(ГруппыДоступа.Ссылка) КАК Представление,
| ГруппыДоступа.Профиль КАК Профиль,
| ЕСТЬNULL(ГруппыДоступа.Профиль.ПометкаУдаления, ЛОЖЬ) КАК ПометкаУдаленияПрофиля,
| ПРЕДСТАВЛЕНИЕ(ГруппыДоступа.Профиль) КАК ПредставлениеПрофиля
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| ВЫБОР
| КОГДА ГруппыДоступа.Профиль В
| (ВЫБРАТЬ
| ВидыДоступаПрофилей.Ссылка
| ИЗ
| Справочник.ПрофилиГруппДоступа.ВидыДоступа КАК ВидыДоступаПрофилей
| ГДЕ
| ВидыДоступаПрофилей.ВидДоступа В (&ИзмененныеВидыДоступа)
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| ЗначенияДоступаПрофилей.Ссылка
| ИЗ
| Справочник.ПрофилиГруппДоступа.ЗначенияДоступа КАК ЗначенияДоступаПрофилей
| ГДЕ
| ЗначенияДоступаПрофилей.ВидДоступа В (&ИзмененныеВидыДоступа))
| ТОГДА ИСТИНА
| КОГДА ГруппыДоступа.Ссылка В
| (ВЫБРАТЬ
| ВидыДоступаГруппДоступа.Ссылка
| ИЗ
| Справочник.ГруппыДоступа.ВидыДоступа КАК ВидыДоступаГруппДоступа
| ГДЕ
| ВидыДоступаГруппДоступа.ВидДоступа В (&ИзмененныеВидыДоступа)
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| ЗначенияДоступаГруппДоступа.Ссылка
| ИЗ
| Справочник.ГруппыДоступа.ЗначенияДоступа КАК ЗначенияДоступаГруппДоступа
| ГДЕ
| ЗначенияДоступаГруппДоступа.ВидДоступа В (&ИзмененныеВидыДоступа))
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВидыДоступаПрофилей.Ссылка КАК ГруппаДоступаИлиПрофиль,
| ВидыДоступаПрофилей.ВидДоступа КАК ВидДоступа,
| ВидыДоступаПрофилей.Предустановленный КАК Предустановленный,
| ВидыДоступаПрофилей.ВсеРазрешены КАК ВсеРазрешены
|ИЗ
| Справочник.ПрофилиГруппДоступа.ВидыДоступа КАК ВидыДоступаПрофилей
|ГДЕ
| ВидыДоступаПрофилей.ВидДоступа В(&ИзмененныеВидыДоступа)
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ВидыДоступаГруппДоступа.Ссылка,
| ВидыДоступаГруппДоступа.ВидДоступа,
| ЕСТЬNULL(ВидыДоступаПрофилей.Предустановленный, НЕОПРЕДЕЛЕНО),
| ВидыДоступаГруппДоступа.ВсеРазрешены
|ИЗ
| Справочник.ГруппыДоступа.ВидыДоступа КАК ВидыДоступаГруппДоступа
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа КАК ГруппыДоступа
| ПО (ВидыДоступаГруппДоступа.ВидДоступа В (&ИзмененныеВидыДоступа))
| И (ГруппыДоступа.Ссылка = ВидыДоступаГруппДоступа.Ссылка)
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПрофилиГруппДоступа.ВидыДоступа КАК ВидыДоступаПрофилей
| ПО (ВидыДоступаПрофилей.Ссылка = ГруппыДоступа.Профиль)
| И (ВидыДоступаПрофилей.ВидДоступа = ВидыДоступаГруппДоступа.ВидДоступа)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ЗначенияДоступаПрофилей.Ссылка КАК ГруппаДоступаИлиПрофиль,
| ЗначенияДоступаПрофилей.ВидДоступа КАК ВидДоступа,
| ЗначенияДоступаПрофилей.ЗначениеДоступа КАК ЗначениеДоступа,
| ЗначенияДоступаПрофилей.ВключаяНижестоящие КАК ВключаяНижестоящие
|ИЗ
| Справочник.ПрофилиГруппДоступа.ЗначенияДоступа КАК ЗначенияДоступаПрофилей
|ГДЕ
| ЗначенияДоступаПрофилей.ВидДоступа В(&ИзмененныеВидыДоступа)
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ЗначенияДоступаГруппДоступа.Ссылка,
| ЗначенияДоступаГруппДоступа.ВидДоступа,
| ЗначенияДоступаГруппДоступа.ЗначениеДоступа,
| ЗначенияДоступаГруппДоступа.ВключаяНижестоящие
|ИЗ
| Справочник.ГруппыДоступа.ЗначенияДоступа КАК ЗначенияДоступаГруппДоступа
|ГДЕ
| ЗначенияДоступаГруппДоступа.ВидДоступа В(&ИзмененныеВидыДоступа)";
РезультатыЗапроса = Запрос.ВыполнитьПакет();
Результат = Новый Структура;
Результат.Вставить("ГруппыДоступа", РезультатыЗапроса[0].Выгрузить());
Результат.Вставить("ВидыДоступа", РезультатыЗапроса[1].Выгрузить());
Результат.Вставить("ЗначенияДоступа", РезультатыЗапроса[2].Выгрузить());
Возврат Результат;
КонецФункции
Функция СвойстваПрофилейИГруппДоступаИзмененийГруппЗначений(ИзменениеГруппЗначенийДоступа, ИерархическиеЗначения = Ложь)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ИзмененныеГруппыЗначений",
ИзменениеГруппЗначенийДоступа.ВыгрузитьКолонку("ГруппаЗначений"));
Запрос.УстановитьПараметр("ВидИзмененияИзменено", "Изменено");
Запрос.УстановитьПараметр("ВидИзмененияПусто", "");
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК ГруппаДоступа,
| ГруппыДоступа.ПометкаУдаления КАК ПометкаУдаления,
| ПРЕДСТАВЛЕНИЕ(ГруппыДоступа.Ссылка) КАК Представление,
| ГруппыДоступа.Профиль КАК Профиль,
| ЕСТЬNULL(ГруппыДоступа.Профиль.ПометкаУдаления, ЛОЖЬ) КАК ПометкаУдаленияПрофиля,
| ПРЕДСТАВЛЕНИЕ(ГруппыДоступа.Профиль) КАК ПредставлениеПрофиля
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| ВЫБОР
| КОГДА ГруппыДоступа.Профиль В
| (ВЫБРАТЬ
| ЗначенияДоступаПрофилей.Ссылка
| ИЗ
| Справочник.ПрофилиГруппДоступа.ЗначенияДоступа КАК ЗначенияДоступаПрофилей
| ГДЕ
| ЗначенияДоступаПрофилей.ЗначениеДоступа В (&ИзмененныеГруппыЗначений)
| И &ЗначенияДоступаПрофилейВключаяНижестоящие)
| ТОГДА ИСТИНА
| КОГДА ГруппыДоступа.Ссылка В
| (ВЫБРАТЬ
| ЗначенияДоступаГруппДоступа.Ссылка
| ИЗ
| Справочник.ГруппыДоступа.ЗначенияДоступа КАК ЗначенияДоступаГруппДоступа
| ГДЕ
| ЗначенияДоступаГруппДоступа.ЗначениеДоступа В (&ИзмененныеГруппыЗначений)
| И &ЗначенияДоступаГруппДоступаВключаяНижестоящие)
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| ВидыДоступаПрофилей.Ссылка КАК ГруппаДоступаИлиПрофиль,
| ВидыДоступаПрофилей.ВидДоступа КАК ВидДоступа,
| ВидыДоступаПрофилей.Предустановленный КАК Предустановленный,
| ВидыДоступаПрофилей.ВсеРазрешены КАК ВсеРазрешены
|ИЗ
| Справочник.ПрофилиГруппДоступа.ЗначенияДоступа КАК ЗначенияДоступаПрофилей
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПрофилиГруппДоступа.ВидыДоступа КАК ВидыДоступаПрофилей
| ПО (ЗначенияДоступаПрофилей.ЗначениеДоступа В (&ИзмененныеГруппыЗначений))
| И (&ЗначенияДоступаПрофилейВключаяНижестоящие)
| И (ВидыДоступаПрофилей.Ссылка = ЗначенияДоступаПрофилей.Ссылка)
| И (ВидыДоступаПрофилей.ВидДоступа = ЗначенияДоступаПрофилей.ВидДоступа)
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| ВидыДоступаГруппДоступа.Ссылка,
| ВидыДоступаГруппДоступа.ВидДоступа,
| ЕСТЬNULL(ВидыДоступаПрофилей.Предустановленный, НЕОПРЕДЕЛЕНО),
| ВидыДоступаГруппДоступа.ВсеРазрешены
|ИЗ
| Справочник.ГруппыДоступа.ЗначенияДоступа КАК ЗначенияДоступаГруппДоступа
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа.ВидыДоступа КАК ВидыДоступаГруппДоступа
| ПО (ЗначенияДоступаГруппДоступа.ЗначениеДоступа В (&ИзмененныеГруппыЗначений))
| И (&ЗначенияДоступаГруппДоступаВключаяНижестоящие)
| И (ВидыДоступаГруппДоступа.Ссылка = ЗначенияДоступаГруппДоступа.Ссылка)
| И (ВидыДоступаГруппДоступа.ВидДоступа = ЗначенияДоступаГруппДоступа.ВидДоступа)
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа КАК ГруппыДоступа
| ПО (ГруппыДоступа.Ссылка = ЗначенияДоступаГруппДоступа.Ссылка)
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПрофилиГруппДоступа.ВидыДоступа КАК ВидыДоступаПрофилей
| ПО (ВидыДоступаПрофилей.Ссылка = ГруппыДоступа.Профиль)
| И (ВидыДоступаПрофилей.ВидДоступа = ВидыДоступаГруппДоступа.ВидДоступа)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| ЗначенияДоступаПрофилей.Ссылка КАК Ссылка,
| ЗначенияДоступаПрофилей.ВидДоступа КАК ВидДоступа
|ПОМЕСТИТЬ ВидыДоступаЗначенийПрофилей
|ИЗ
| Справочник.ПрофилиГруппДоступа.ЗначенияДоступа КАК ЗначенияДоступаПрофилей
|ГДЕ
| ЗначенияДоступаПрофилей.ЗначениеДоступа В(&ИзмененныеГруппыЗначений)
| И &ЗначенияДоступаПрофилейВключаяНижестоящие
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| ЗначенияДоступаГруппДоступа.Ссылка КАК Ссылка,
| ЗначенияДоступаГруппДоступа.ВидДоступа КАК ВидДоступа
|ПОМЕСТИТЬ ВидыДоступаЗначенийГруппДоступа
|ИЗ
| Справочник.ГруппыДоступа.ЗначенияДоступа КАК ЗначенияДоступаГруппДоступа
|ГДЕ
| ЗначенияДоступаГруппДоступа.ЗначениеДоступа В(&ИзмененныеГруппыЗначений)
| И &ЗначенияДоступаГруппДоступаВключаяНижестоящие
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ЗначенияДоступаПрофилей.Ссылка КАК ГруппаДоступаИлиПрофиль,
| ЗначенияДоступаПрофилей.ВидДоступа КАК ВидДоступа,
| ЗначенияДоступаПрофилей.ЗначениеДоступа КАК ЗначениеДоступа,
| ЗначенияДоступаПрофилей.ВключаяНижестоящие КАК ВключаяНижестоящие,
| ВЫБОР
| КОГДА ЗначенияДоступаПрофилей.ЗначениеДоступа В (&ИзмененныеГруппыЗначений)
| И &ЗначенияДоступаПрофилейВключаяНижестоящие
| ТОГДА &ВидИзмененияИзменено
| ИНАЧЕ &ВидИзмененияПусто
| КОНЕЦ КАК ВидИзменения
|ИЗ
| ВидыДоступаЗначенийПрофилей КАК ВидыДоступаЗначенийПрофилей
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПрофилиГруппДоступа.ЗначенияДоступа КАК ЗначенияДоступаПрофилей
| ПО (ЗначенияДоступаПрофилей.Ссылка = ВидыДоступаЗначенийПрофилей.Ссылка)
| И (ЗначенияДоступаПрофилей.ВидДоступа = ВидыДоступаЗначенийПрофилей.ВидДоступа)
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ЗначенияДоступаГруппДоступа.Ссылка,
| ЗначенияДоступаГруппДоступа.ВидДоступа,
| ЗначенияДоступаГруппДоступа.ЗначениеДоступа,
| ЗначенияДоступаГруппДоступа.ВключаяНижестоящие,
| ВЫБОР
| КОГДА ЗначенияДоступаГруппДоступа.ЗначениеДоступа В (&ИзмененныеГруппыЗначений)
| И &ЗначенияДоступаГруппДоступаВключаяНижестоящие
| ТОГДА &ВидИзмененияИзменено
| ИНАЧЕ &ВидИзмененияПусто
| КОНЕЦ
|ИЗ
| ВидыДоступаЗначенийГруппДоступа КАК ВидыДоступаЗначенийГруппДоступа
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа.ЗначенияДоступа КАК ЗначенияДоступаГруппДоступа
| ПО (ЗначенияДоступаГруппДоступа.Ссылка = ВидыДоступаЗначенийГруппДоступа.Ссылка)
| И (ЗначенияДоступаГруппДоступа.ВидДоступа = ВидыДоступаЗначенийГруппДоступа.ВидДоступа)";
Запрос.Текст = СтрЗаменить(Запрос.Текст,
"&ЗначенияДоступаПрофилейВключаяНижестоящие",
?(ИерархическиеЗначения, "ЗначенияДоступаПрофилей.ВключаяНижестоящие", "ИСТИНА"));
Запрос.Текст = СтрЗаменить(Запрос.Текст,
"&ЗначенияДоступаГруппДоступаВключаяНижестоящие",
?(ИерархическиеЗначения, "ЗначенияДоступаГруппДоступа.ВключаяНижестоящие", "ИСТИНА"));
РезультатыЗапроса = Запрос.ВыполнитьПакет();
Результат = Новый Структура;
Результат.Вставить("ГруппыДоступа", РезультатыЗапроса[0].Выгрузить());
Результат.Вставить("ВидыДоступа", РезультатыЗапроса[1].Выгрузить());
Результат.Вставить("ЗначенияДоступа", РезультатыЗапроса[4].Выгрузить());
Возврат Результат;
КонецФункции
Процедура ЗаполнитьВидыИЗначенияДоступа(ИзменениеВидовДоступа, ИзменениеЗначенийДоступа,
СвойстваГруппДоступа, СвойстваВидовДоступа)
Отбор = Новый Структура("ГруппаДоступаИлиПрофиль, ВидДоступа");
ЕстьВидИзменения = СвойстваГруппДоступа.ЗначенияДоступа.Колонки.Найти("ВидИзменения") <> Неопределено;
СвойстваПоТипамЗначений = СвойстваВидовДоступа.ПоТипамЗначений;
СвойстваПоТипамГруппИЗначений = СвойстваВидовДоступа.ПоТипамГруппИЗначений;
Для Каждого Строка Из СвойстваГруппДоступа.ЗначенияДоступа Цикл
НоваяСтрока = ИзменениеЗначенийДоступа.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
Если Не ЕстьВидИзменения Тогда
НоваяСтрока.ВидИзменения = "Изменено";
КонецЕсли;
ТипЗначения = ТипЗнч(НоваяСтрока.ЗначениеДоступа);
НоваяСтрока.ЭтоГруппаЗначений = СвойстваПоТипамЗначений.Получить(ТипЗначения) = Неопределено
И СвойстваПоТипамГруппИЗначений.Получить(ТипЗначения) <> Неопределено;
ЗаполнитьЗначенияСвойств(Отбор, Строка);
Если СвойстваГруппДоступа.ВидыДоступа.НайтиСтроки(Отбор).Количество() = 0 Тогда
НоваяСтрока = СвойстваГруппДоступа.ВидыДоступа.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
НоваяСтрока.ВсеРазрешены = Истина;
НоваяСтрока.Предустановленный = Неопределено;
КонецЕсли;
КонецЦикла;
СвойстваГруппДоступа.ВидыДоступа.Индексы.Добавить("ГруппаДоступаИлиПрофиль, ВидДоступа");
Для Каждого Строка Из СвойстваГруппДоступа.ВидыДоступа Цикл
НоваяСтрока = ИзменениеВидовДоступа.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
НоваяСтрока.ВидИзменения = "Изменено";
КонецЦикла;
КонецПроцедуры
Функция ИзменениеГруппЗначенийДоступа(Объект, СтарыеЗначения, НесколькоГруппЗначений)
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("ГруппаЗначений", Метаданные.ОпределяемыеТипы.ЗначениеДоступа);
Результат.Колонки.Добавить("ЗначениеДоступа", Метаданные.ОпределяемыеТипы.ЗначениеДоступа);
Результат.Колонки.Добавить("ВидИзменения");
Если НесколькоГруппЗначений Тогда
Если ТипЗнч(СтарыеЗначения.ГруппыДоступа) = Тип("РезультатЗапроса") Тогда
СтарыеГруппы = СтарыеЗначения.ГруппыДоступа.Выгрузить();
Для Каждого СтрокаТЗ Из СтарыеГруппы Цикл
Если СтрокаТЗ.ГруппаДоступа = Неопределено
Или Объект.ГруппыДоступа.Найти(СтрокаТЗ.ГруппаДоступа, "ГруппаДоступа") <> Неопределено Тогда
Продолжить;
КонецЕсли;
НоваяСтрока = Результат.Добавить();
НоваяСтрока.ГруппаЗначений = СтрокаТЗ.ГруппаДоступа;
НоваяСтрока.ЗначениеДоступа = Объект.Ссылка;
НоваяСтрока.ВидИзменения = "Удалено";
КонецЦикла;
КонецЕсли;
Для Каждого СтрокаТЧ Из Объект.ГруппыДоступа Цикл
Если СтрокаТЧ.ГруппаДоступа = Неопределено
Или СтарыеГруппы.Найти(СтрокаТЧ.ГруппаДоступа, "ГруппаДоступа") <> Неопределено Тогда
Продолжить;
КонецЕсли;
НоваяСтрока = Результат.Добавить();
НоваяСтрока.ГруппаЗначений = СтрокаТЗ.ГруппаДоступа;
НоваяСтрока.ЗначениеДоступа = Объект.Ссылка;
НоваяСтрока.ВидИзменения = "Добавлено";
КонецЦикла;
Иначе
Если Объект.ГруппаДоступа <> Неопределено Тогда
НоваяСтрока = Результат.Добавить();
НоваяСтрока.ГруппаЗначений = Объект.ГруппаДоступа;
НоваяСтрока.ЗначениеДоступа = Объект.Ссылка;
НоваяСтрока.ВидИзменения = "Добавлено";
КонецЕсли;
Если СтарыеЗначения.ГруппаДоступа <> Неопределено Тогда
НоваяСтрока = Результат.Добавить();
НоваяСтрока.ГруппаЗначений = СтарыеЗначения.ГруппаДоступа;
НоваяСтрока.ЗначениеДоступа = Объект.Ссылка;
НоваяСтрока.ВидИзменения = "Удалено";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ЗаполнитьПредставлениеГруппДоступаПрофилей(Данные, ГруппыДоступа)
Для Каждого ОписаниеГруппыДоступа Из ГруппыДоступа Цикл
Свойства = Новый Структура;
Свойства.Вставить("ГруппаДоступа", СериализованнаяСсылка(ОписаниеГруппыДоступа.ГруппаДоступа));
Свойства.Вставить("Представление", ОписаниеГруппыДоступа.Представление);
Свойства.Вставить("ПометкаУдаления", ОписаниеГруппыДоступа.ПометкаУдаления);
Свойства.Вставить("Профиль", СериализованнаяСсылка(ОписаниеГруппыДоступа.Профиль));
Свойства.Вставить("ПредставлениеПрофиля", ОписаниеГруппыДоступа.ПредставлениеПрофиля);
Свойства.Вставить("ПометкаУдаленияПрофиля", ОписаниеГруппыДоступа.ПометкаУдаленияПрофиля);
Свойства.Вставить("СтарыеЗначенияСвойств", Новый Структура);
Данные.ПредставлениеГруппДоступа.Добавить(Свойства);
КонецЦикла;
КонецПроцедуры
Функция ИзменениеЗначенийДоступаРодителей(Объект, СтарыеЗначения)
СтарыеРодители = ЗначениеСРодителями(СтарыеЗначения.Родитель);
НовыеРодители = ЗначениеСРодителями(Объект.Родитель);
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("ГруппаЗначений", Метаданные.ОпределяемыеТипы.ЗначениеДоступа.Тип);
Результат.Колонки.Добавить("ЗначениеДоступа", Метаданные.ОпределяемыеТипы.ЗначениеДоступа.Тип);
Результат.Колонки.Добавить("ВидИзменения");
Для Каждого СтарыйРодитель Из СтарыеРодители Цикл
Если НовыеРодители.Найти(СтарыйРодитель) <> Неопределено Тогда
Продолжить;
КонецЕсли;
НоваяСтрока = Результат.Добавить();
НоваяСтрока.ГруппаЗначений = СтарыйРодитель;
НоваяСтрока.ЗначениеДоступа = Объект.Ссылка;
НоваяСтрока.ВидИзменения = "Удалено";
КонецЦикла;
Для Каждого НовыйРодитель Из НовыеРодители Цикл
Если СтарыеРодители.Найти(НовыйРодитель) <> Неопределено Тогда
Продолжить;
КонецЕсли;
НоваяСтрока = Результат.Добавить();
НоваяСтрока.ГруппаЗначений = НовыйРодитель;
НоваяСтрока.ЗначениеДоступа = Объект.Ссылка;
НоваяСтрока.ВидИзменения = "Добавлено";
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ЗначениеСРодителями(Родитель)
Результат = Новый Массив;
МетаданныеТаблицы = Метаданные.НайтиПоТипу(ТипЗнч(Родитель));
Если МетаданныеТаблицы = Неопределено Тогда
Возврат Результат;
КонецЕсли;
Свойства = Новый Структура("Иерархический", Ложь);
ЗаполнитьЗначенияСвойств(Свойства, МетаданныеТаблицы);
Если Не Свойства.Иерархический Тогда
Возврат Результат;
КонецЕсли;
Результат.Добавить(Родитель);
Если Не ЗначениеЗаполнено(Родитель) Тогда
Возврат Результат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Ссылка", Родитель);
Запрос.Текст =
"ВЫБРАТЬ
| ТекущаяТаблица.Родитель КАК Родитель1,
| ТекущаяТаблица.Родитель.Родитель КАК Родитель2,
| ТекущаяТаблица.Родитель.Родитель.Родитель КАК Родитель3,
| ТекущаяТаблица.Родитель.Родитель.Родитель.Родитель КАК Родитель4,
| ТекущаяТаблица.Родитель.Родитель.Родитель.Родитель.Родитель КАК Родитель5
|ИЗ
| &ТекущаяТаблица КАК ТекущаяТаблица
|ГДЕ
| ТекущаяТаблица.Ссылка = &Ссылка";
Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ТекущаяТаблица", МетаданныеТаблицы.ПолноеИмя());
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Результат.Добавить(Выборка.Родитель1);
Если ЗначениеЗаполнено(Выборка.Родитель1) Тогда
Результат.Добавить(Выборка.Родитель2);
Если ЗначениеЗаполнено(Выборка.Родитель2) Тогда
Результат.Добавить(Выборка.Родитель3);
Если ЗначениеЗаполнено(Выборка.Родитель3) Тогда
Результат.Добавить(Выборка.Родитель4);
Если ЗначениеЗаполнено(Выборка.Родитель4) Тогда
ДополнительныйРезультат = ЗначениеСРодителями(Выборка.Родитель5);
Для Каждого Значение Из ДополнительныйРезультат Цикл
Результат.Добавить(Значение);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// Процедуры и функции для поддержки обмена данными в РИБ.
// Только для внутреннего использования.
//
// Параметры:
// ЭлементДанных - СправочникОбъект.ГруппыДоступа
//
Процедура ВосстановитьСоставУчастниковГруппыДоступаАдминистраторы(ЭлементДанных) Экспорт
ГруппаДоступаАдминистраторы = УправлениеДоступом.ГруппаДоступаАдминистраторы();
Если ЭлементДанных.Ссылка <> ГруппаДоступаАдминистраторы Тогда
Возврат;
КонецЕсли;
ЭлементДанных.Пользователи.Очистить();
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ГруппаДоступаАдминистраторы", ГруппаДоступаАдминистраторы);
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ГруппыДоступаПользователи.Пользователь
|ИЗ
| Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
|ГДЕ
| ГруппыДоступаПользователи.Ссылка = &ГруппаДоступаАдминистраторы";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если ЭлементДанных.Пользователи.Найти(Выборка.Пользователь, "Пользователь") = Неопределено Тогда
ЭлементДанных.Пользователи.Добавить().Пользователь = Выборка.Пользователь;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Только для внутреннего использования.
Процедура УдалитьУчастниковГруппыДоступаАдминистраторыБезПользователяИБ() Экспорт
ГруппаДоступаАдминистраторы = УправлениеДоступом.ГруппаДоступаАдминистраторы();
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Справочник.ГруппыДоступа");
ЭлементБлокировки.УстановитьЗначение("Ссылка", ГруппаДоступаАдминистраторы);
НачатьТранзакцию();
Попытка
Блокировка.Заблокировать();
ГруппаДоступаАдминистраторы = ГруппаДоступаАдминистраторы.ПолучитьОбъект();
Индекс = ГруппаДоступаАдминистраторы.Пользователи.Количество() - 1;
Пока Индекс >= 0 Цикл
ТекущийПользователь = ГруппаДоступаАдминистраторы.Пользователи[Индекс].Пользователь;
Если ТипЗнч(ТекущийПользователь) = Тип("СправочникСсылка.Пользователи") Тогда
ИдентификаторПользователяИБ = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ТекущийПользователь,
"ИдентификаторПользователяИБ");
Иначе
ИдентификаторПользователяИБ = Неопределено;
КонецЕсли;
Если ТипЗнч(ИдентификаторПользователяИБ) = Тип("УникальныйИдентификатор") Тогда
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору(
ИдентификаторПользователяИБ);
Иначе
ПользовательИБ = Неопределено;
КонецЕсли;
Если ПользовательИБ = Неопределено Тогда
ГруппаДоступаАдминистраторы.Пользователи.Удалить(Индекс);
КонецЕсли;
Индекс = Индекс - 1;
КонецЦикла;
Если ГруппаДоступаАдминистраторы.Модифицированность() Тогда
ГруппаДоступаАдминистраторы.Записать();
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
// Только для внутреннего использования.
//
// Параметры:
// ЭлементДанных - СправочникОбъект.ГруппыДоступа
// - УдалениеОбъекта
//
Процедура ЗарегистрироватьИзменениеПриПолученииДанных(ЭлементДанных) Экспорт
СтарыеЗначения = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ЭлементДанных.Ссылка,
"Ссылка, Профиль, ПометкаУдаления, Пользователи, ВидыДоступа, ЗначенияДоступа");
ТребуетсяРегистрация = Ложь;
ГруппаДоступа = ЭлементДанных.Ссылка;
Если ТипЗнч(ЭлементДанных) = Тип("УдалениеОбъекта") Тогда
Если СтарыеЗначения.Ссылка = Неопределено Тогда
Возврат;
КонецЕсли;
ТребуетсяРегистрация = Истина;
ИначеЕсли СтарыеЗначения.Ссылка <> ЭлементДанных.Ссылка Тогда
ТребуетсяРегистрация = Истина;
ГруппаДоступа = ПользователиСлужебный.СсылкаОбъекта(ЭлементДанных);
ИначеЕсли ЭлементДанных.ПометкаУдаления <> СтарыеЗначения.ПометкаУдаления
Или ЭлементДанных.Профиль <> СтарыеЗначения.Профиль Тогда
ТребуетсяРегистрация = Истина;
Иначе
НаличиеУчастников = ЭлементДанных.Пользователи.Количество() <> 0;
СтароеНаличиеУчастников = Не СтарыеЗначения.Пользователи.Пустой();
Если НаличиеУчастников <> СтароеНаличиеУчастников
Или ИзменилисьВидыИлиЗначенияДоступа(СтарыеЗначения, ЭлементДанных) Тогда
ТребуетсяРегистрация = Истина;
КонецЕсли;
КонецЕсли;
УстановитьПривилегированныйРежим(Истина);
Если ТребуетсяРегистрация Тогда
ПользователиСлужебный.ЗарегистрироватьСсылки("ГруппыДоступа", ГруппаДоступа);
КонецЕсли;
ПользователиСлужебный.ЗарегистрироватьСсылки("ГруппыДоступаПользователи",
ПользователиДляОбновленияРолей(СтарыеЗначения, ЭлементДанных));
Если УправлениеДоступомСлужебный.ОграничиватьДоступНаУровнеЗаписейУниверсально() Тогда
РолиДляОбновления = РолиДляОбновленияПрав(СтарыеЗначения, ЭлементДанных);
ПользователиСлужебный.ЗарегистрироватьСсылки("ГруппыДоступаРоли", РолиДляОбновления);
КонецЕсли;
КонецПроцедуры
// Только для внутреннего использования.
Процедура ОбработатьИзменениеЗарегистрированноеПриПолученииДанных() Экспорт
Если ОбщегоНазначения.РазделениеВключено() Тогда
// Изменения групп доступа в АРМ заблокированы и не загружаются в область данных.
Возврат;
КонецЕсли;
ОчисткаРегистрации = Новый Массив;
ОбработатьЗарегистрированноеИзменениеГруппДоступа("ГруппыДоступа", ОчисткаРегистрации);
ОбработатьЗарегистрированноеИзменениеРолей("ГруппыДоступаРоли", ОчисткаРегистрации);
ОбработатьЗарегистрированноеИзменениеУчастников("ГруппыДоступаПользователи", ОчисткаРегистрации);
Для Каждого ИмяВидаСсылок Из ОчисткаРегистрации Цикл
ПользователиСлужебный.ЗарегистрироватьСсылки(ИмяВидаСсылок, Null);
КонецЦикла;
КонецПроцедуры
// Для процедуры ОбработатьИзменениеЗарегистрированноеПриПолученииДанных.
Процедура ОбработатьЗарегистрированноеИзменениеГруппДоступа(ИмяВидаСсылок, ОчисткаРегистрации)
ИзмененныеГруппыДоступа = ПользователиСлужебный.ЗарегистрированныеСсылки(ИмяВидаСсылок);
Если ИзмененныеГруппыДоступа.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Если ИзмененныеГруппыДоступа.Количество() = 1
И ИзмененныеГруппыДоступа[0] = Неопределено Тогда
ИзмененныеГруппыДоступа = Неопределено;
КонецЕсли;
РегистрыСведений.ТаблицыГруппДоступа.ОбновитьДанныеРегистра(ИзмененныеГруппыДоступа);
РегистрыСведений.ЗначенияГруппДоступа.ОбновитьДанныеРегистра(ИзмененныеГруппыДоступа);
Если УправлениеДоступомСлужебный.ОграничиватьДоступНаУровнеЗаписейУниверсально() Тогда
Описание = "ОбновитьВспомогательныеДанныеГруппДоступаИзмененныхПриЗагрузке";
УправлениеДоступомСлужебный.ЗапланироватьОбновлениеНаборовГруппДоступа(Описание);
ТипыИзмененныхУчастников = Новый Структура("Пользователи, ВнешниеПользователи", Истина, Истина);
УправлениеДоступомСлужебный.ЗапланироватьОбновлениеДоступаПриИзмененииУчастниковГруппыДоступа(
ИзмененныеГруппыДоступа, ТипыИзмененныхУчастников, Истина);
УправлениеДоступомСлужебный.ОбновитьГруппыДоступаРазрешенногоКлючаДоступа(ИзмененныеГруппыДоступа);
КонецЕсли;
ОчисткаРегистрации.Добавить(ИмяВидаСсылок);
КонецПроцедуры
// Для процедуры ОбработатьИзменениеЗарегистрированноеПриПолученииДанных.
Процедура ОбработатьЗарегистрированноеИзменениеРолей(ИмяВидаСсылок, ОчисткаРегистрации)
Если Не УправлениеДоступомСлужебный.ОграничиватьДоступНаУровнеЗаписейУниверсально() Тогда
Возврат;
КонецЕсли;
СоставИзмененийРолей = ПользователиСлужебный.ЗарегистрированныеСсылки(ИмяВидаСсылок);
Если СоставИзмененийРолей.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Если СоставИзмененийРолей.Количество() = 1
И СоставИзмененийРолей[0] = Неопределено Тогда
СоставИзмененийРолей = Неопределено;
КонецЕсли;
Описание = "ОбновитьВспомогательныеДанныеГруппДоступаИзмененныхПриЗагрузке";
УправлениеДоступомСлужебный.ЗапланироватьОбновлениеДоступаПриИзмененииПрофиляГруппыДоступа(Описание,
СоставИзмененийРолей, Истина);
ОчисткаРегистрации.Добавить(ИмяВидаСсылок);
КонецПроцедуры
// Для процедуры ОбработатьИзменениеЗарегистрированноеПриПолученииДанных.
Процедура ОбработатьЗарегистрированноеИзменениеУчастников(ИмяВидаСсылок, ОчисткаРегистрации)
Состав = ПользователиСлужебный.ЗарегистрированныеСсылки(ИмяВидаСсылок);
Если Состав.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Если Состав.Количество() = 1 И Состав[0] = Неопределено Тогда
Состав = Неопределено;
КонецЕсли;
УправлениеДоступом.ОбновитьРолиПользователей(Состав);
ОчисткаРегистрации.Добавить(ИмяВидаСсылок);
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Начальное заполнение
// Смотри также ОбновлениеИнформационнойБазыПереопределяемый.ПриНастройкеНачальногоЗаполненияЭлементов
//
// Параметры:
// Настройки - см. ОбновлениеИнформационнойБазыПереопределяемый.ПриНастройкеНачальногоЗаполненияЭлементов.Настройки
//
Процедура ПриНастройкеНачальногоЗаполненияЭлементов(Настройки) Экспорт
Настройки.ПриНачальномЗаполненииЭлемента = Ложь;
КонецПроцедуры
// Смотри также ОбновлениеИнформационнойБазыПереопределяемый.ПриНачальномЗаполненииЭлементов
//
// Параметры:
// КодыЯзыков - см. ОбновлениеИнформационнойБазыПереопределяемый.ПриНачальномЗаполненииЭлементов.КодыЯзыков
// Элементы - см. ОбновлениеИнформационнойБазыПереопределяемый.ПриНачальномЗаполненииЭлементов.Элементы
// ТабличныеЧасти - см. ОбновлениеИнформационнойБазыПереопределяемый.ПриНачальномЗаполненииЭлементов.ТабличныеЧасти
//
Процедура ПриНачальномЗаполненииЭлементов(КодыЯзыков, Элементы, ТабличныеЧасти) Экспорт
Элемент = Элементы.Добавить();
Элемент.ИмяПредопределенныхДанных = "Администраторы";
Элемент.Наименование = НСтр("ru = 'Администраторы'", ОбщегоНазначения.КодОсновногоЯзыка());
Элемент.Профиль = УправлениеДоступом.ПрофильАдминистратор();
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Обновление информационной базы.
Процедура ЗаполнитьПрофильГруппыДоступаАдминистраторы() Экспорт
Объект = УправлениеДоступом.ГруппаДоступаАдминистраторы().ПолучитьОбъект();
Если Объект.Профиль <> УправлениеДоступом.ПрофильАдминистратор() Тогда
Объект.Профиль = УправлениеДоступом.ПрофильАдминистратор();
ОбновлениеИнформационнойБазы.ЗаписатьДанные(Объект);
КонецЕсли;
КонецПроцедуры
Процедура ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию(Параметры) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ГруппыДоступа.Ссылка КАК Ссылка
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа";
ОбновлениеИнформационнойБазы.ОтметитьКОбработке(Параметры,
Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"));
КонецПроцедуры
Процедура ОбработатьДанныеДляПереходаНаНовуюВерсию(Параметры) Экспорт
ОбработкаЗавершена = Истина;
ПараметрыОбновления = Новый Структура;
Если Параметры.Свойство("ГруппыДоступа") Тогда
ГруппыДоступа = Параметры.ГруппыДоступа;
ПараметрыОбновления.Вставить("ВызыватьИсключение");
Иначе
Выборка = ОбновлениеИнформационнойБазы.ВыбратьСсылкиДляОбработки(Параметры.Очередь, "Справочник.ГруппыДоступа");
ГруппыДоступа = Новый Массив;
Пока Выборка.Следующий() Цикл
ГруппыДоступа.Добавить(Выборка.Ссылка);
КонецЦикла;
КонецЕсли;
ПараметрыОбновления.Вставить("ГруппыДоступа", ГруппыДоступа);
Если Справочники.ВерсииРасширений.РасширенияИзмененыДинамически()
И (Не ОбщегоНазначения.ИнформационнаяБазаФайловая()
Или ТекущийРежимЗапуска() <> Неопределено) Тогда
АдресРезультата = ПоместитьВоВременноеХранилище(Неопределено);
ПараметрыОбновления.Вставить("АдресРезультата", АдресРезультата);
НаименованиеЗадания =
НСтр("ru = 'Обновление вспомогательных данных групп доступа'",
ОбщегоНазначения.КодОсновногоЯзыка());
ФоновоеЗадание = РасширенияКонфигурации.ВыполнитьФоновоеЗаданиеСРасширениямиБазыДанных(
"УправлениеДоступомСлужебный.ОбновитьВспомогательныеДанныеГруппДоступа",
ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(ПараметрыОбновления),,
НаименованиеЗадания);
ФоновоеЗадание = ФоновоеЗадание.ОжидатьЗавершенияВыполнения();
Если ФоновоеЗадание.Состояние <> СостояниеФоновогоЗадания.Завершено Тогда
Если ФоновоеЗадание.ИнформацияОбОшибке <> Неопределено Тогда
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Фоновое задание ""%1"" завершилось с ошибкой:
|%2'"),
НаименованиеЗадания,
ОбработкаОшибок.ПодробноеПредставлениеОшибки(ФоновоеЗадание.ИнформацияОбОшибке));
Иначе
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Фоновое задание ""%1"" не завершилось.'"), НаименованиеЗадания);
КонецЕсли;
ВызватьИсключение ТекстОшибки;
КонецЕсли;
Результат = ПолучитьИзВременногоХранилища(АдресРезультата);
Если ТипЗнч(Результат) <> Тип("Структура") Тогда
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Фоновое задание ""%1"" не вернуло результат.'"), НаименованиеЗадания);
ВызватьИсключение ТекстОшибки;
КонецЕсли;
Иначе
ОбновитьВспомогательныеДанныеГруппДоступа(ПараметрыОбновления);
Результат = ПараметрыОбновления.Результат;
КонецЕсли;
Для Каждого ГруппаДоступа Из Результат.ОбработанныеГруппыДоступа Цикл
ОбновлениеИнформационнойБазы.ОтметитьВыполнениеОбработки(ГруппаДоступа);
КонецЦикла;
ОбъектовОбработано = Результат.ОбработанныеГруппыДоступа.Количество();
ПроблемныхОбъектов = Результат.ПроблемныхОбъектов;
Если Параметры.Свойство("ГруппыДоступа") Тогда
Возврат;
КонецЕсли;
Если Не ОбновлениеИнформационнойБазы.ОбработкаДанныхЗавершена(Параметры.Очередь, "Справочник.ГруппыДоступа") Тогда
ОбработкаЗавершена = Ложь;
КонецЕсли;
Если ОбъектовОбработано = 0 И ПроблемныхОбъектов <> 0 Тогда
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось обработать некоторые группы доступа (пропущены): %1'"),
ПроблемныхОбъектов);
ВызватьИсключение ТекстСообщения;
Иначе
ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(),
УровеньЖурналаРегистрации.Информация,
Метаданные.Справочники.ГруппыДоступа,,
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Обработана очередная порция групп доступа: %1'"),
ОбъектовОбработано));
КонецЕсли;
Параметры.ОбработкаЗавершена = ОбработкаЗавершена;
КонецПроцедуры
Процедура ОбновитьВспомогательныеДанныеГруппДоступа(Параметры) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Пользователи.Ссылка КАК Ссылка
|ИЗ
| Справочник.Пользователи КАК Пользователи
|ГДЕ
| Пользователи.Служебный";
Выборка = Запрос.Выполнить().Выбрать();
СлужебныеПользователи = Новый Соответствие;
Пока Выборка.Следующий() Цикл
СлужебныеПользователи.Вставить(Выборка.Ссылка, Истина);
КонецЦикла;
ШаблонОшибкиОбработкиГруппыДоступа =
НСтр("ru = 'Не удалось обработать группу доступа ""%1"" по причине:
|%2'");
ШаблонОшибкиОбновленияТаблицГруппДоступа =
НСтр("ru = 'Не удалось обновить таблицы группы доступа ""%1"" по причине:
|%2'");
ШаблонОшибкиОбновленияЗначенийГруппДоступа =
НСтр("ru = 'Не удалось обновить значения доступа группы доступа ""%1"" по причине:
|%2'");
ПроблемныхОбъектов = 0;
ОбработанныеГруппыДоступа = Новый Массив;
Для Каждого ГруппаДоступа Из Параметры.ГруппыДоступа Цикл
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Справочник.ГруппыДоступа");
ЭлементБлокировки.УстановитьЗначение("Ссылка", ГруппаДоступа);
ПредставлениеСсылки = Строка(ГруппаДоступа);
НачатьТранзакцию();
Попытка
ШаблонОшибки = ШаблонОшибкиОбработкиГруппыДоступа;
Блокировка.Заблокировать();
ГруппаДоступаОбъект = ГруппаДоступа.ПолучитьОбъект(); // СправочникОбъект.ГруппыДоступа
Индекс = ГруппаДоступаОбъект.Пользователи.Количество();
Пока Индекс > 0 Цикл
Индекс = Индекс - 1;
СтрокаТЧ = ГруппаДоступаОбъект.Пользователи.Получить(Индекс);
Если СлужебныеПользователи.Получить(СтрокаТЧ.Пользователь) <> Неопределено Тогда
ГруппаДоступаОбъект.Пользователи.Удалить(Индекс);
КонецЕсли;
КонецЦикла;
Если ГруппаДоступаОбъект.Модифицированность() Тогда
ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ГруппаДоступаОбъект, Ложь);
УправлениеДоступомСлужебный.ЗапланироватьОбновлениеНаборовГруппДоступа(
"ОбновитьВспомогательныеДанныеГруппДоступа", Истина, Ложь);
КонецЕсли;
ШаблонОшибки = ШаблонОшибкиОбновленияТаблицГруппДоступа;
РегистрыСведений.ТаблицыГруппДоступа.ОбновитьДанныеРегистра(ГруппаДоступа);
ШаблонОшибки = ШаблонОшибкиОбновленияЗначенийГруппДоступа;
РегистрыСведений.ЗначенияГруппДоступа.ОбновитьДанныеРегистра(ГруппаДоступа);
ШаблонОшибки = ШаблонОшибкиОбработкиГруппыДоступа;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ПроблемныхОбъектов = ПроблемныхОбъектов + 1;
ИнформацияОбОшибке = ИнформацияОбОшибке();
Если Параметры.Свойство("ВызыватьИсключение") Тогда
ВызватьИсключение;
КонецЕсли;
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонОшибки,
ПредставлениеСсылки,
ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(),
УровеньЖурналаРегистрации.Предупреждение, , , ТекстСообщения);
Продолжить;
КонецПопытки;
ОбработанныеГруппыДоступа.Добавить(ГруппаДоступа);
КонецЦикла;
Результат = Новый Структура;
Результат.Вставить("ПроблемныхОбъектов", ПроблемныхОбъектов);
Результат.Вставить("ОбработанныеГруппыДоступа", ОбработанныеГруппыДоступа);
Если Параметры.Свойство("АдресРезультата") Тогда
ПоместитьВоВременноеХранилище(Результат, Параметры.АдресРезультата);
Иначе
Параметры.Вставить("Результат", Результат);
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#КонецЕсли