Как ограничить работу пользователей с конкретным складом в 1С:Управление торговлей 10.3?

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

В конфигурации 1С:Управление торговлей 10.3 часто возникает прикладная задача: разрешить одним пользователям работать с определенным складом (оформлять поступления, реализации, списания, перемещения), а для других сотрудников полностью заблокировать возможность проведения документов по этому объекту. Проанализируем возможности типового функционала и разберем практические способы реализации такого ограничения.

Штатные механизмы конфигурации и их ограничения

Прежде всего выясним, почему в типовой конфигурации не удается настроить этот запрет в пару кликов без доработки:

  1. Отсутствие готового RLS по складам «из коробки». Типовой механизм ограничения прав на уровне записей (RLS) в УТ 10.3 реализован исключительно для организаций и групп доступа к контрагентам. В перечислении ВидыОбъектовДоступа и регистре сведений НастройкиПравДоступаПользователей складов нет.
  2. Назначение справочника «Группы доступности складов». Этот справочник присутствует в типовой конфигурации и задается в настройках пользователя, однако он предназначен исключительно для алгоритмов автоматического подбора складов при резервировании и размещении номенклатуры в документе ЗаказПокупателя. Он не запрещает пользователю выбрать любой склад вручную и провести документ.

Таким образом, для строгого запрета требуется программное вмешательство. Рассмотрим наиболее эффективные пути решения.

Способ 1. Контроль проведения через подписку на события (рекомендуемый вариант)

Наиболее надежный, простой и минимально инвазивный способ решения — создание нештатной подписки на события. При таком подходе мы не трогаем формы и логику проведения каждого отдельного типового документа, а проверяем права централизованно.

Разберем по шагам, как устроена эта логика:

  1. Хранение соответствий. Создадим собственный регистр сведений или используем типовой справочник ГруппыДоступностиСкладов, связав его с пользователями через персональные настройки, чтобы список разрешенных складов задавался в режиме «1С:Предприятие» без необходимости изменения программного кода при добавлении новых сотрудников.
  2. Создание подписки на событие. В дереве метаданных конфигуратора добавим объект ПодпискаНаСобытие:
    • Источник: составной тип из нужных документов товародвижения (ДокументОбъект.РеализацияТоваровУслуг, ДокументОбъект.ПоступлениеТоваровУслуг, ДокументОбъект.ПеремещениеТоваров, ДокументОбъект.ТребованиеНакладная и др.).
    • Событие: ПередЗаписью или ОбработкаПроведения. Оптимально использовать ПередЗаписью, чтобы блокировать сохранение документа еще до старта транзакции проведения.
  3. Проверка складов в шапке и табличной части. Важно помнить, что в УТ 10.3 склад может храниться не только в реквизитах шапки (Склад, СкладОтправитель, СкладПолучатель), но и построчно в табличной части Товары, если включена настройка указания складов в табличной части. Алгоритм должен обязательно анализировать обе структуры данных.

Посмотрим на пример обработчика в общем модуле, который вызывается из подписки на событие:


Процедура ПроверитьДоступностьСкладаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт

    // Исключаем проверку при программной загрузке данных
    Если Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Пользователям с полными правами контроль можно отключить
    Если РольДоступна("ПолныеПрава") Тогда
        Возврат;
    КонецЕсли;

    ТекущийПользователь = глЗначениеПеременной("глТекущийПользователь");

    // Получаем массив складов, задействованных в документе
    СкладыДокумента = Новый Массив;

    МетаданныеДокумента = Источник.Метаданные();

    // 1. Проверяем реквизиты шапки
    Если МетаданныеДокумента.Реквизиты.Найти("Склад") <> Неопределено И ЗначениеЗаполнено(Источник.Склад) Тогда
        СкладыДокумента.Добавить(Источник.Склад);
    КонецЕсли;

    Если МетаданныеДокумента.Реквизиты.Найти("СкладОтправитель") <> Неопределено И ЗначениеЗаполнено(Источник.СкладОтправитель) Тогда
        СкладыДокумента.Добавить(Источник.СкладОтправитель);
    КонецЕсли;

    Если МетаданныеДокумента.Реквизиты.Найти("СкладПолучатель") <> Неопределено И ЗначениеЗаполнено(Источник.СкладПолучатель) Тогда
        СкладыДокумента.Добавить(Источник.СкладПолучатель);
    КонецЕсли;

    // 2. Проверяем табличную часть, если склад указывается в строках
    Если МетаданныеДокумента.ТабличныеЧасти.Найти("Товары") <> Неопределено Тогда
        Если МетаданныеДокумента.ТабличныеЧасти.Товары.Реквизиты.Найти("Склад") <> Неопределено Тогда
            Для Каждого СтрокаТЧ Из Источник.Товары Цикл
                Если ЗначениеЗаполнено(СтрокаТЧ.Склад) И СкладыДокумента.Найти(СтрокаТЧ.Склад) = Неопределено Тогда
                    СкладыДокумента.Добавить(СтрокаТЧ.Склад);
                КонецЕсли;
            КонецЦикла;
        КонецЕсли;
    КонецЕсли;

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

КонецПроцедуры

Функция СкладДоступенПользователю может обращаться к регистру сведений разрешенных складов либо к справочнику групп доступности. Главное преимущество этого способа — надежность: ни один документ с запрещенным складом не запишется и не проведется в информационной базе независимо от того, как он был создан (вручную, копированием или внешней обработкой).

Способ 2. Интерфейсное ограничение на формах

Подписка на события гарантирует целостность данных, но пользователю неудобно выбирать склад из полного списка и получать ошибку только в момент записи. В качестве дополнения к серверному контролю настроим визуальный отбор в интерфейсе:

  1. В формах документов или в событии НачалоВыбора поля ввода склада программно накладываем нередактируемый отбор по списку разрешенных значений:
    
    ФормаВыбора = Справочники.Склады.ПолучитьФормуВыбора(, Элемент);
    ФормаВыбора.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке;
    ФормаВыбора.Отбор.Ссылка.Значение = СписокДоступныхСкладов;
    ФормаВыбора.Отбор.Ссылка.Использование = Истина;
    ФормаВыбора.Открыть();
    СтандартнаяОбработка = Ложь;
    
  2. Ограничение подхода: визуальный отбор сам по себе не является защитой. Пользователь может ввести запрещенный склад путем копирования старого документа или перетаскивания данных. Поэтому интерфейсные ограничения всегда должны работать в связке с подпиской на событие.

Способ 3. Полноценная доработка механизма RLS

Если стоит жесткое требование не просто блокировать проведение, а полностью спрятать определенные склады, движения по ним и документы из списков, потребуется расширить типовой механизм RLS:

  1. Добавить значение «Склады» в перечисление ВидыОбъектовДоступа.
  2. Добавить тип СправочникСсылка.Склады в состав измерений ОбъектДоступа и ВладелецПравДоступа регистра сведений НастройкиПравДоступаПользователей.
  3. Доработать форму обработки НастройкаПравДоступа, предоставив администраторам возможность назначать права на склады аналогично организациям и контрагентам.
  4. Прописать шаблоны ограничений RLS в ролях пользователей на уровне справочника Склады, целевых документов и складских регистров накопления (ТоварыНаСкладах, ТоварыВРезервеНаСкладах, ТоварыКПередачеСоСкладов и др.).

Важное предупреждение о рисках RLS: полноценное внедрение RLS на склады существенно усложняет текст запросов к СУБД, что неминуемо приведет к падению производительности при формировании тяжелых отчетов («Ведомость по товарам на складах», отчеты по партиям). Кроме того, если не настроить доступ ко всем связанным регистрам, пользователи начнут сталкиваться с ошибками нарушения прав доступа или пустыми ссылками вида «<Объект не найден>» в интерфейсе. Именно поэтому реализация через подписку на событие остается наиболее стабильным и безопасным решением для УТ 10.3.

← На главную