Как разрешить выбор любого склада-получателя в перемещениях при включенном RLS в УТ 11

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В типовых конфигурациях, таких как 1С:Управление торговлей 11, разработчики часто сталкиваются с дилеммой: механизм RLS (Record Level Security) жестко ограничивает видимость складов для пользователя, но бизнес-процесс требует, чтобы кладовщик мог отправить товар на любой склад компании, даже если он не имеет права видеть остатки или документы по этому складу. По умолчанию система скрывает «чужие» склады из всех списков выбора, что блокирует заполнение поля Склад-получатель в документе Перемещение товаров.

В этой статье мы подробно разберем, почему возникает эта проблема и какими способами можно программно или методически её решить, сохранив при этом целостность системы прав доступа.

Анализ проблемы: почему RLS скрывает склады-получатели

Разберем ситуацию: пользователю (кладовщику) в настройках доступа разрешены только 3 склада. Когда он создает документ перемещения, платформа 1С на уровне СУБД накладывает фильтр. Запрос на получение списка складов просто не возвращает те записи, на которые у пользователя нет прав Чтения. В результате в форме выбора склада кладовщик видит только свои 3 склада.

Проблема усугубляется тем, что если мы просто дадим пользователю право на чтение всех складов, он начнет видеть остатки по ним в отчетах, что часто недопустимо по соображениям безопасности. Поэтому нам нужно точечное решение, позволяющее выбрать склад, но не управлять им.

Решение №1: Программное переопределение выбора через привилегированный режим

Это самый эффективный технический способ. Мы можем «обмануть» RLS, сформировав список складов в программном коде, который выполняется на стороне сервера в модуле с установленным флагом Привилегированный.

Рассмотрим по шагам, как это реализовать:

  1. Создадим в общем модуле (например, РаботаСоСкладамиСервер) функцию, которая возвращает массив всех складов.
  2. В форме документа ПеремещениеТоваров создадим обработчик события НачалоВыбора для реквизита СкладПолучатель.

Пример кода для общего модуля (установите свойство «Привилегированный»):


Функция ПолучитьПолныйСписокСкладов() Экспорт
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Склады.Ссылка КАК Ссылка,
        |	Склады.Наименование КАК Наименование
        |ИЗ
        |	Справочник.Склады КАК Склады
        |ГДЕ
        |	НЕ Склады.ПометкаУдаления";
    
    Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
КонецФункции

Теперь проанализируем код для формы документа:


&НаКлиенте
Процедура СкладПолучательНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь; // Отключаем стандартное окно выбора
    
    СписокСкладов = ПолучитьПолныйСписокСкладовНаСервере();
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Истина);
    ПараметрыФормы.Вставить("МножественныйВыбор", Ложь);
    
    // Формируем фиксированный массив для фильтра в форме выбора
    ПараметрыФормы.Вставить("Отбор", Новый Структура("Ссылка", СписокСкладов));
    
    ОткрытьФорму("Справочник.Склады.ФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры

Важный нюанс: Если стандартная форма выбора все равно фильтрует данные из-за RLS, используйте метод ВыбратьИзСписка, предварительно заполнив список значений именами складов в привилегированном режиме.

Решение №2: Использование подписки на события для контроля проведения

Допустим, вы дали пользователю право на Чтение всех складов, чтобы он мог их выбирать. Но теперь возникла проблема: он может случайно создать документы по чужим складам. Чтобы это предотвратить, проанализируем подход с использованием подписок на события.

Создадим подписку на событие ПередЗаписью для документа ПеремещениеТоваров. В обработчике мы будем проверять, входит ли СкладОтправитель в список разрешенных складов пользователя. Если нет — блокируем проведение.


Процедура ПроверитьПраваНаСкладОтправительПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
    Если РежимЗаписи <> РежимЗаписиДокумента.Проведение Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем только склад-отправитель
    РазрешенныеСклады = ПолучитьСписокРазрешенныхСкладовДляТекущегоПользователя();
    
    Если РазрешенныеСклады.Найти(Источник.СкладОтправитель) = Неопределено Тогда
        Сообщить("У вас нет прав на отгрузку со склада: " + Источник.СкладОтправитель);
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

Этот метод позволяет держать справочник складов открытым для чтения (чтобы работал выбор), но жестко ограничивает возможность распоряжаться чужим товаром.

Решение №3: Текстовое поле и фоновое проведение

Если архитектура прав доступа настолько жесткая, что изменять RLS нельзя ни в каком виде, воспользуемся методом «виртуального выбора». Выясним, как это работает:

  1. На форму документа добавляется строковый реквизит «Наименование Склада Получателя».
  2. Пользователь выбирает название из списка, сформированного в привилегированном режиме.
  3. При сохранении документа ссылка на реальный склад подставляется в скрытый реквизит объекта.
  4. Проблема проведения: Система выдаст ошибку прав при попытке записать движения по регистру «Товары на складах» для склада-получателя.

Чтобы обойти ограничение при проведении, можно использовать механизм фоновых заданий. Документ записывается без проведения, а специальное регламентное задание, запущенное от имени пользователя с полными правами, проводит такие документы. Это сложный путь, но он гарантирует отсутствие конфликтов с RLS.

Методические рекомендации: Ордерная схема

Рассмотрим ситуацию со стороны учета. Если кладовщик склада А перемещает товар на склад Б, он фактически отвечает только за Расход. За Приход на складе Б должен отвечать другой материально-ответственный (МОЛ).

Использование Ордерной схемы в УТ 11 решает проблему прав доступа естественным путем:

При такой схеме пользователю склада А достаточно иметь права на чтение справочника «Склады» и на создание перемещений, а контроль остатков на складе-получателе его не касается, так как он не делает там никаких движений.

Выводы

Для решения задачи в УТ 11 мы рекомендуем комбинированный подход:

  1. Настроить RLS так, чтобы право Чтение было у всех складов, но Просмотр и Изменение — только у своих. Это позволит использовать стандартные формы выбора.
  2. Если пункт 1 недопустим, реализовать НачалоВыбора с заполнением списка в привилегированном режиме.
  3. Использовать подписку на событие ПередЗаписью для контроля того, что пользователь не пытается списать товар с чужого склада (склада-отправителя).

Таким образом, мы сохраняем безопасность данных и обеспечиваем удобство работы пользователей при оформлении межскладских перемещений.

← На главную