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