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