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