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