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