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