В практике автоматизации торговых предприятий часто возникает задача разделения зон ответственности менеджеров. Классический пример: один менеджер работает только с товарами из Китая, другой — с товарами из США. При этом товары в справочнике Номенклатура разложены по соответствующим папкам (группам). Возникает вопрос: как технически реализовать ограничение видимости, чтобы "китайский" менеджер не видел "американские" товары, и как это повлияет на работу с документами и отчетами?
Давайте подробно разберем возможные варианты решения этой задачи, проанализируем их плюсы, минусы и технические особенности реализации в среде 1С:Предприятие 8.3 (на примере конфигурации УНФ, хотя принципы универсальны).
Многие опытные разработчики рекомендуют начинать именно с этого способа. Если задача состоит в том, чтобы просто не "захламлять" список товаров лишними позициями и упростить подбор, то использование жесткого RLS (Record Level Security) может быть избыточным и ресурсоемким. Для реализации этой задачи можно использовать настройку доступности элементов формы у пользователей или специализированное расширение для настройки видимости объектов в списках, которое позволит скрыть ненужные группы без сложного программирования.
Суть метода заключается в программной установке отборов в формах списков и документах.
Как это работает:
Пользователи), где указываем, какие папки номенклатуры доступны конкретному пользователю.Номенклатура или формы выбора мы перехватываем событие создания формы и устанавливаем фиксированный отбор.Рассмотрим пример алгоритма, который можно применить в модуле формы списка:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем список доступных групп для текущего пользователя
ДоступныеГруппы = ПолучитьДоступныеГруппыПользователя(ПараметрыСеанса.ТекущийПользователь);
// Если список не пустой и не стоит признак "Все", устанавливаем отбор
Если ДоступныеГруппы.Количество() > 0 Тогда
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Родитель");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
ЭлементОтбора.ПравоеЗначение = ДоступныеГруппы;
ЭлементОтбора.Использование = Истина;
// Делаем отбор недоступным для изменения пользователем
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
КонецЕсли;
КонецПроцедуры
Преимущества подхода:
Недостатки:
Если требования безопасности строгие (менеджер ни при каких обстоятельствах не должен видеть себестоимость или сам факт наличия товаров конкурентного отдела), необходимо использовать механизм RLS (Record Level Security). Перед внедрением этого механизма рекомендуется провести анализ существующих прав и ролей, а также выполнить быструю проверку прав доступа на объект, чтобы убедиться в корректности будущих ограничений.
Давайте проанализируем, как правильно написать запрос ограничения доступа.
Самый очевидный, но опасный с точки зрения производительности вариант запроса выглядит так:
ГДЕ Родитель В ИЕРАРХИИ (&СписокДоступныхГрупп)
Почему это плохо? Оператор В ИЕРАРХИИ заставляет SQL-сервер выполнять рекурсивные запросы или строить сложные планы выполнения каждый раз, когда система отображает список товаров. На больших объемах данных (тысячи позиций номенклатуры) это приведет к существенным "тормозам" интерфейса.
Правильный подход к RLS:
Для оптимизации рекомендуется использовать плоские списки или специальные регистры, где иерархия уже развернута. В типовых конфигурациях (БСП) для этого используются регистры сведений типа НаборыЗначенийДоступа.
Если мы пишем свой RLS, лучше использовать Параметры Сеанса. Рассмотрим создание параметра сеанса ДоступныеВидыНоменклатуры или ДоступныеГруппыПлоскийСписок.
В модуле сеанса при старте мы заполняем этот параметр:
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
Если ТребуемыеПараметры = Неопределено
Или ТребуемыеПараметры.Найти("ДоступныеГруппы") <> Неопределено Тогда
// Здесь логика получения массива ссылок всех вложенных папок
МассивГрупп = ПолучитьВсеВложенныеГруппыДляПользователя();
ПараметрыСеанса.ДоступныеГруппы = Новый ФиксированныйМассив(МассивГрупп);
КонецЕсли;
КонецПроцедуры
Тогда запрос RLS в роли для справочника Номенклатура на чтение будет выглядеть так:
ГДЕ Родитель В (&ДоступныеГруппы)
// Обратите внимание: просто "В", без "ИЕРАРХИИ"
Такой запрос работает на порядки быстрее, так как сравнение идет по фиксированному списку ссылок.
При внедрении RLS возникает серьезная логическая проблема, о которой часто забывают на этапе постановки задачи. Что произойдет с документом (например, ПриходнаяНакладная или ЗаказПокупателя), если в его табличной части окажутся товары из разных групп доступа?
Представим ситуацию:
Сценарий 1: RLS настроен только на справочник Номенклатура.
Платформа 1С при чтении документа пытается считать и представления ссылок (наименования товаров). Поскольку у пользователя нет прав на чтение "Товара США", в поле Номенклатура он увидит надпись <Объект не найден> или, что чаще, платформа выдаст ошибку доступа ко всей строке или документу, если используются жесткие шаблоны ограничений.
Сценарий 2: Попытка редактирования/проведения.
Если "Менеджер Китай" попытается провести такой документ, система не сможет прочитать данные "Товара США" для формирования движений по регистрам. Результат — ошибка права доступа и невозможность проведения документа.
Решение проблемы смешанных документов:
В обсуждении были предложены следующие выходы:
ПередЗаписью или использовать готовое расширение для блокировки записи объекта по условию, которое обеспечит соблюдение бизнес-правил.ВЫБРАТЬ РАЗРЕШЕННЫЕ. Это позволит не видеть строки с запрещенной номенклатурой, но исказит итоговые суммы документа (сумма по строкам не сойдется с итогом документа).Отдельное внимание стоит уделить отчетам. Если мы используем схему без RLS (Вариант 1), то отчеты "из коробки" покажут все продажи. Нам придется дорабатывать каждый отчет.
Для доработки отчетов на Системе Компоновки Данных (СКД) можно использовать следующий подход:
СписокДоступнойНоменклатуры.Если же используется RLS (Вариант 2), то отчеты автоматически отфильтруют данные, при условии, что в запросах отчетов используется слово РАЗРЕШЕННЫЕ. В типовых конфигурациях, таких как УНФ, это, как правило, уже предусмотрено разработчиками фирмы 1С.
Подводя итог анализу задачи, сформулируем алгоритм действий для специалиста:
В ИЕРАРХИИ в RLS. Если RLS необходим, используйте плоские списки в параметрах сеанса или вспомогательных регистрах.