Как разрешить определенным пользователям проводить документы в 1С, используя собственный список доступа?

Программист 1С v8.3 (Управляемые формы)
← На главную

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

Реализация доступа на проведение через собственный регистр сведений

Изначальный вопрос автора темы заключался в том, как дать доступ на проведение документов пользователям, перечисленным в специальном регистре сведений СписокПользователейДляРедактированияПроведенных. Давайте разберем по шагам, как это можно сделать.

  1. Создание регистра сведений.

    Прежде всего, убедимся, что ваш регистр сведений СписокПользователейДляРедактированияПроведенных (или другой подобный) настроен правильно. Он должен содержать измерение типа СправочникСсылка.Пользователи (или аналогичное, в зависимости от вашей системы учета пользователей, например СправочникСсылка.ФизическиеЛица с дополнительными проверками). Например, регистр может быть непериодическим, независимым, без подчинения регистратору, с одним измерением "Пользователь". Это измерение будет хранить ссылку на элемент справочника пользователей, которому мы хотим предоставить особые права.

  2. Создание функции проверки в общем модуле.

    Чтобы не дублировать код в каждом документе, создадим общую функцию, которая будет проверять, имеет ли текущий пользователь право на проведение, исходя из данных нашего регистра. Эту функцию разместим в общем модуле, например, ПЛ_Портал (как у автора) или в другом подходящем общем модуле с установленными флагами "Сервер" и "Вызов сервера" для работы в управляемых формах на сервере, а также, возможно, "Клиент (обычное приложение)", если у вас смешанный интерфейс.

    Рассмотрим пример такой функции:

    
    Функция ОпределитьПравоПользователяНаПроведениеДокументов() Экспорт
    
        // Получаем текущего пользователя сеанса. 
        // ПараметрыСеанса.ТекущийПользователь обычно хранит ссылку на элемент справочника "Пользователи".
        ТекущийПользователь = ПараметрыСеанса.ТекущийПользователь;
    
        // Создаем запрос для проверки наличия текущего пользователя в нашем регистре.
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ ПЕРВЫЕ 1
            |    СписокПользователейДляРедактированияПроведенных.Пользователь
            |ИЗ
            |    РегистрСведений.СписокПользователейДляРедактированияПроведенных КАК СписокПользователейДляРедактированияПроведенных
            |ГДЕ
            |    СписокПользователейДляРедактированияПроведенных.Пользователь = &ТекущийПользователь";
    
        // Устанавливаем параметр запроса - текущего пользователя
        Запрос.УстановитьПараметр("ТекущийПользователь", ТекущийПользователь);
    
        // Выполняем запрос
        РезультатЗапроса = Запрос.Выполнить();
    
        // Возвращаем Истина, если запрос вернул хотя бы одну запись (пользователь найден), иначе Ложь.
        Возврат Не РезультатЗапроса.Пустой();
    
    КонецФункции
    

    Эта функция возвращает Истина, если текущий пользователь найден в регистре, то есть ему разрешено проводить документы, и Ложь в противном случае. Для обеспечения корректной работы функции, если регистр сведений может быть недоступен текущему пользователю из-за прав доступа, следует использовать УстановитьПривилегированныйРежим(Истина) перед вызовом функции и УстановитьПривилегированныйРежим(Ложь) после.

  3. Интеграция проверки в процедуру ОбработкаПроведения документа.

    Теперь нам нужно использовать эту функцию в модуле объекта того документа, для которого мы хотим ограничить проведение. Наиболее подходящее место – это процедура ОбработкаПроведения. Именно эта процедура вызывается перед записью движений документа и позволяет контролировать процесс проведения.

    Проанализируем ситуацию, представленную в сообщении 4 форума, а также логику из сообщений 1, 2 и 7. Мы модифицируем код таким образом, чтобы он сначала проверял наше пользовательское право, а затем, если право есть, переходил к другим проверкам, например, на дату отгрузки.

    
    Процедура ОбработкаПроведения(Отказ, РежимПроведения)
        // ... (стандартный код проведения документа, который может быть сгенерирован платформой)
    
        // Блок для определения прав на проведение с использованием собственного регистра
        // Для доступа к данным регистра в привилегированном режиме, если права пользователя ограничены
        УстановитьПривилегированныйРежим(Истина); 
        РазрешеноПроведение = ПЛ_Портал.ОпределитьПравоПользователяНаПроведениеДокументов();
        УстановитьПривилегированныйРежим(Ложь);
    
        Если НЕ РазрешеноПроведение Тогда
            Сообщить("Вам запрещено проведение данного документа!");
            Отказ = Истина;
            Возврат; // Выходим из процедуры, если проведение запрещено
        КонецЕсли;
    
        // Если проведение разрешено, переходим к другим проверкам, например, на дату отгрузки.
        // Исходный код автора, который теперь выполняется ТОЛЬКО для разрешенных пользователей:
        // Обратите внимание, что здесь ДатаОтгрузки - Дата < 86400 * 2, где 86400 - количество секунд в сутках.
        // Это означает "менее чем через 2 дня".
        Если ЭтотОбъект.ДатаОтгрузки - ЭтотОбъект.Дата < 86400 * 2 Тогда 
            Отказ = Истина;
            Сообщение = Новый СообщениеПользователю;
            Сообщение.УстановитьДанные(ЭтотОбъект);
            Сообщение.Поле = "Объект.ДатаОтгрузки";
            Сообщение.Текст = "Дату отгрузки возможно ставить только минимум через 2 дня";
            Сообщение.Сообщить();
            Возврат; // Также выходим, если проверка по дате не пройдена
        КонецЕсли;
    
        // ... (остальной код проведения документа, формирование движений по регистрам)
    
    КонецПроцедуры
    

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

Гибкое управление динамическими параметрами (например, "правило двух дней")

Сообщение 5 справедливо указывает на проблему жестко закодированных значений, таких как "2 дня" для даты отгрузки. Рассмотрим, как сделать такие параметры гибкими и настраиваемыми без изменения кода конфигурации, что является хорошей практикой разработки и значительно упрощает сопровождение системы.

  1. Использование регистра сведений для хранения параметров.

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

    Пример структуры регистра НастройкиПроведенияДокументов:

    • Измерение: "ТипПараметра" (например, можно создать перечисление ТипыПараметровПроведения со значениями "МинимальныеДниОтгрузки", "МаксимальнаяСуммаДокумента" и т.д.)
    • Измерение: "ВидДокумента" (если параметр может зависеть от конкретного типа документа, например, для "ЗаказКлиента" свои правила, для "РеализацияТоваровУслуг" – свои)
    • Ресурс: "ЗначениеЧисло" (для хранения числовых параметров, таких как количество дней)
    • Ресурс: "ЗначениеСтрока" (для строковых параметров)
    • Ресурс: "ЗначениеБулево" (для параметров "Да/Нет")
  2. Изменение кода проверки даты отгрузки.

    Теперь, вместо жестко закодированного значения 86400 * 2, мы будем получать это значение из нашего регистра. Это делает систему гораздо более адаптивной к изменениям в бизнес-процессах.

    
    // ... в процедуре ОбработкаПроведения после проверки прав пользователя на проведение
    
        МинимальноеКоличествоДнейОтгрузки = 2; // Значение по умолчанию, если в регистре ничего не найдено
    
        // Попытаемся получить значение из регистра сведений
        ЗапросПараметра = Новый Запрос;
        ЗапросПараметра.Текст = 
            "ВЫБРАТЬ ПЕРВЫЕ 1
            |    НастройкиПроведенияДокументов.ЗначениеЧисло
            |ИЗ
            |    РегистрСведений.НастройкиПроведенияДокументов КАК НастройкиПроведенияДокументов
            |ГДЕ
            |    НастройкиПроведенияДокументов.ТипПараметра = &ТипПараметра
            |    И (НастройкиПроведенияДокументов.ВидДокумента = &ВидДокумента
            |       ИЛИ НастройкиПроведенияДокументов.ВидДокумента ЕСТЬ NULL)"; // Можно добавить общие настройки
            
        // Для доступа к данным регистра в привилегированном режиме
        УстановитьПривилегированныйРежим(Истина); 
    
        ЗапросПараметра.УстановитьПараметр("ТипПараметра", Перечисления.ТипыПараметровПроведения.МинимальныеДниОтгрузки);
        // Получаем вид текущего документа из его метаданных
        ЗапросПараметра.УстановитьПараметр("ВидДокумента", Метаданные.Документы[ЭтотОбъект.Метаданные().Имя].Ссылка()); 
    
        РезультатПараметра = ЗапросПараметра.Выполнить().Выбрать();
    
        Если РезультатПараметра.Следующий() Тогда
            МинимальноеКоличествоДнейОтгрузки = РезультатПараметра.ЗначениеЧисло;
        КонецЕсли;
    
        УстановитьПривилегированныйРежим(Ложь);
    
        Если ЭтотОбъект.ДатаОтгрузки - ЭтотОбъект.Дата < 86400 * МинимальноеКоличествоДнейОтгрузки Тогда
            Отказ = Истина;
            Сообщение = Новый СообщениеПользователю;
            Сообщение.УстановитьДанные(ЭтотОбъект);
            Сообщение.Поле = "Объект.ДатаОтгрузки";
            Сообщение.Текст = "Дату отгрузки возможно ставить только минимум через " 
                               + Строка(МинимальноеКоличествоДнейОтгрузки) 
                               + " дня(ей)";
            Сообщение.Сообщить();
            Возврат;
        КонецЕсли;
    // ... (остальной код процедуры)
    

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

Комплексные методы управления правами на проведение документов в 1С

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

  1. Использование стандартных ролей и прав доступа.

    Это наиболее фундаментальный и часто используемый способ. В конфигураторе 1С вы можете создать новую роль или изменить существующую, а затем снять флажок "Проведение" для определенных типов документов (объектов метаданных) для этой роли. Пользователи, которым назначена эта роль, не смогут проводить документы. Например, роль "Оператор" может иметь право на создание и редактирование документов, но право на их проведение будет только у роли "Менеджер" или "Бухгалтер". Это базовый уровень контроля, который должен быть настроен в первую очередь.

  2. Механизм RLS (Record Level Security).

    RLS позволяет ограничивать доступ к данным на уровне отдельных записей, а не только к объекту в целом. Хотя чаще он используется для ограничения видимости данных (например, менеджер видит только свои заказы), RLS также может контролировать проведение. Настраивается в конфигураторе в разделе "Роли", на вкладке "Шаблоны ограничений". С помощью RLS можно задать условие, при котором пользователь может проводить документ, например, только если он является автором документа или относится к определенной группе по ответственному подразделению. Это позволяет реализовывать очень тонкие настройки доступа, исходя из содержимого самого документа.

  3. Настройка даты запрета изменения данных.

    Этот механизм незаменим для закрытия учетных периодов и предотвращения несанкционированных изменений в прошлом. Он позволяет запретить любые изменения (включая проведение, редактирование и распроведение) документов до определенной даты. Дата запрета может быть установлена для всех пользователей, для группы пользователей или для отдельного пользователя. Настройка осуществляется в пользовательском режиме (например, через раздел "Администрирование" - "Настройки пользователей и прав" - "Даты запрета изменений"). Этот способ часто используется бухгалтерами и администраторами для закрытия учетных периодов, чтобы избежать ошибок и несоответствий.

  4. Функциональные опции.

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

Комбинирование этих подходов позволяет создать надежную и гибкую систему управления правами на проведение документов в 1С, соответствующую самым разнообразным бизнес-требованиям. Всегда стремитесь к максимальной гибкости и настраиваемости, чтобы избежать частых изменений конфигурации и упростить поддержку системы в будущем.

← На главную