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