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