В процессе работы с торговыми и учетными системами 1С (такими как «1С:Комплексная автоматизация», «1С:Управление торговлей» или «1С:ERP») часто возникает необходимость ограничить права пользователей на изменение иерархии справочника Номенклатура. Типовой сценарий: рядовым сотрудникам нужно разрешить просмотр товаров и их выбор в документы, но при этом строго запретить случайно или намеренно переносить позиции из одной папки в другую.
Разберем подробнее, какими способами можно решить эту задачу — от настройки типовых прав доступа до реализации программной блокировки через подписку на событие в расширении конфигурации.
Прежде чем писать программный код, проанализируем базовые возможности системы. Если пользователям требуется только просматривать номенклатуру и подбирать ее в приходные или расходные документы, им вовсе не нужны права на изменение самого справочника Номенклатура.
В современных типовых конфигурациях выбор элемента в документ доступен даже при наличии прав только на чтение. Для этого достаточно выдать пользователю профиль групп доступа с правами на просмотр номенклатуры (например, типовую роль «Только чтение») и стандартные права на создание документов. Если же сотрудникам все-таки необходимо создавать новые карточки товаров или редактировать их свойства, но запрещено менять их иерархическое расположение, потребуется добавить программный контроль.
Наиболее надежный способ запретить перенос элемента в другую группу — перехватить событие записи объекта на сервере. Для этого создадим подписку на событие ПередЗаписью для справочника Номенклатура. Чтобы не снимать основную конфигурацию с поддержки, всю доработку рекомендуется выполнять в Расширении конфигурации.
Рассмотри по шагам алгоритм создания такой подписки:
МойОбщийМодульСервер) и установим для него свойство «Сервер».СправочникОбъект.Номенклатура, в поле «Событие» — ПередЗаписью, а в качестве обработчика укажем процедуру из общего модуля.Разберем пример программного кода для процедуры-обработчика подписки:
Процедура ОбработкаЗаписиСправочникаНоменклатура(Источник, Отказ) Экспорт
// Исключаем проверки при фоновом обмене данными
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Проверяем изменение группы только для уже существующих элементов
Если Не Источник.ЭтоНовый() И (Источник.Родитель <> Источник.Ссылка.Родитель) Тогда
// Оцениваем права текущего пользователя (например, проверяем отсутствие специальной роли)
НельзяМенятьРодителя = Не РолиДоступны("РазрешеноИзменениеИерархииНоменклатуры");
Если НельзяМенятьРодителя Тогда
Отказ = Истина;
// Выводим сообщение пользователю с привязкой к реквизиту
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "У вас нет прав на изменение группы номенклатуры!";
Сообщение.Поле = "Родитель";
Сообщение.УстановитьДанные(Источник);
Сообщение.Сообщить();
Возврат;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Выясним важные детали работы этого кода:
Источник.ОбменДанными.Загрузка защищает автоматические процессы синхронизации и загрузки данных из внешних систем от ошибочной блокировки.Источник.Родитель <> Источник.Ссылка.Родитель сравнивает текущего выбранного родителя в объекте с родителем, записанным в базе данных по ссылке. Если они различаются, значит пользователь попытался перенести элемент в другую папку.Не Источник.ЭтоНовый() гарантирует, что проверка сработает только при переносе уже существующего элемента. Для новых элементов Источник.Ссылка.Родитель вернет пустую ссылку.Рассмотрим дополнительные нюансы, которые следует учитывать при внедрении этой логики:
1. Контроль создания новых элементов: если пользователю разрешено создавать новые элементы, но запрещено добавлять их в определенные закрытые группы, условие ЭтоНовый() не поможет. В этом случае необходимо отдельно анализировать целевого родителя Источник.Родитель даже при создании нового объекта.
2. Блокировка на уровне интерфейса (Drag-and-Drop): подписка на событие надежно блокирует запись на сервере, однако пользователь все равно может попытаться перетащить элемент мышью в форме списка. Чтобы повысить удобство работы и предотвратить лишние ошибки, на форме списка номенклатуры можно отключить свойство таблицы РазрешитьПеретаскивание или обработать событие ПроверкаПеретаскивания.
3. Почему нельзя использовать только RLS: механизм прав на уровне записей (RLS) в Библиотеке Стандартных Подсистем (БСП) работает по группам доступа номенклатуры, а не по иерархии папок. Кроме того, RLS разграничивает доступ к записи целиком (чтение, изменение, удаление) и не позволяет заблокировать изменение лишь одного конкретного реквизита Родитель. Поэтому использование подписки на событие остается наиболее правильным и универсальным решением.