Как реализовать условную видимость кнопки "Отменить бронирование" в документе "Заказ клиента" 1С:УТ 11.4 только для определенных ролей пользователей?

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

В процессе работы с информационными системами 1С:Предприятие, особенно с такими сложными конфигурациями, как "Управление Торговлей", часто возникает необходимость гибкого управления интерфейсом для различных категорий пользователей. Одной из таких задач является отображение определенных кнопок или элементов управления только для пользователей, обладающих соответствующими правами. Сегодня мы подробно разберем, как обеспечить условную видимость кнопки "Отменить бронирование" в документе "Заказ клиента" конфигурации 1С:УТ 11.4, используя стандартные механизмы платформы 1С:Предприятие 8.3, такие как функциональные опции и роли.

Представим ситуацию: в вашем бизнес-процессе предусмотрена возможность отмены бронирования товаров, оформленных в "Заказе клиента". Однако эта операция является ответственной и должна быть доступна не всем менеджерам, а только тем, кто имеет специальное разрешение, например, главный менеджер или руководитель отдела. Для решения этой задачи мы воспользуемся комбинацией проверки доступности ролей пользователя и функциональных опций. Мы рассмотрим это решение пошагово, с примерами кода и подробными объяснениями, чтобы вы могли легко применить его в своей базе.

Шаг 1: Подготовительные работы в конфигураторе

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

  1. Откроем конфигуратор и найдем документ "Заказ клиента".

    Для начала, запустим 1С в режиме "Конфигуратор". В дереве конфигурации развернем ветку "Документы" и найдем документ с именем "ЗаказКлиента". Именно в его форме мы будем изменять видимость кнопки.

  2. Создадим новую роль для управления правами.

    Роли в 1С:Предприятии являются основным инструментом для разграничения прав доступа к данным и функциональности системы. Они позволяют определить, какие действия может выполнять пользователь и к каким данным он имеет доступ. Если у вас уже есть роль, предназначенная для пользователей, которым будет разрешена отмена бронирования (например, РазрешитьОтменуБронирования), вы можете использовать ее. В противном случае, создадим новую роль:

    • В дереве конфигурации развернем ветку "Общие" -> "Роли".
    • Добавим новую роль, нажав соответствующую кнопку или через контекстное меню.
    • Дадим ей понятное имя, например, РазрешитьОтменуБронирования. Это имя будет использоваться в коде для проверки наличия прав.
    • Укажем информативный синоним, который будет виден администраторам при назначении ролей пользователям, например, "Разрешает отмену бронирования".
    • На этом этапе мы не будем настраивать подробные права для этой роли на объекты данных, так как ее основное предназначение — быть маркером для проверки доступа к функциональной опции, а не напрямую к данным.

    После создания роли, не забудьте назначить ее соответствующим пользователям в режиме "Предприятие" через справочник "Пользователи" или "Настройки пользователей".

  3. Создадим функциональную опцию для управления видимостью.

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

    • В дереве конфигурации развернем ветку "Общие" -> "ФункциональныеОпции".
    • Добавим новую функциональную опцию, нажав соответствующую кнопку.
    • Назовем ее, например, ИспользоватьОтменуБронирования. Это внутреннее имя, которое мы будем использовать в коде.
    • Укажем Синоним, который будет понятен пользователям при настройке функциональности в режиме "Предприятие", например, "Использовать возможность отмены бронирования".
    • В свойстве Видимость установим значение "Истина", если мы хотим, чтобы эта опция была видна администраторам и пользователям в пользовательском режиме (например, в окне "Настройка функций программы"), позволяя им включать или отключать ее.
    • Особенно важно свойство Привилегированный. Установим его в "Ложь". Это означает, что для проверки доступности данной функциональной опции будут учитываться права пользователя (через RLS), а не только ее значение. Таким образом, мы связываем функциональную опцию с механизмом RLS (Restriction Level Security). Если бы мы установили "Истина", то проверка выполнялась бы привилегированно, без учета ролей, что нам не подходит для нашего сценария.
    • Далее нам необходимо связать эту функциональную опцию с источником значения. Это может быть константа, параметр сеанса или реквизит, который будет хранить состояние "включено/отключено". Для простоты управления мы создадим константу для этой цели:
      • Развернем ветку "Общие" -> "Константы".
      • Добавим новую константу с именем ИспользоватьОтменуБронирования и типом "Булево".
      • Укажем понятный синоним, например, "Использовать отмену бронирования".
      • Вернемся к созданной функциональной опции ИспользоватьОтменуБронирования и в свойстве Значение укажем только что созданную константу.

    Теперь у нас есть константа, которая управляет состоянием функциональной опции. В пользовательском режиме администратор сможет установить эту константу в "Истина" или "Ложь", тем самым включая или отключая функцию отмены бронирования для всей системы. Это первый уровень контроля.

  4. Свяжем функциональную опцию с нашей ролью.

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

    • Откроем нашу роль РазрешитьОтменуБронирования в конфигураторе (которую мы создали ранее).
    • Перейдем на вкладку "Права".
    • В списке объектов (слева) найдем нашу функциональную опцию ИспользоватьОтменуБронирования.
    • Включим для нее право "Чтение" или "Просмотр" (название может незначительно отличаться в разных версиях платформы). Это позволит системе корректно проверять состояние функциональной опции для пользователей с этой ролью, когда мы будем использовать функцию ФункциональнаяОпцияДоступна().

    Таким образом, мы установили двухступенчатый контроль: сначала общая функциональность включается администратором через константу, которая связана с функциональной опцией, а затем доступ к этой функциональности для конкретного пользователя определяется наличием у него соответствующей роли. Если константа установлена в "Ложь", то никто не сможет использовать эту функцию, даже с нужной ролью. Если константа в "Истина", то доступ будет определяться наличием роли.

Шаг 2: Модификация формы документа "Заказ клиента"

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

  1. Откроем форму документа "Заказ клиента".

    В конфигураторе развернем ветку "Документы" -> "ЗаказКлиента" -> "Формы". Найдем основную форму документа (обычно "ФормаДокумента") и откроем ее для редактирования. Если форма не является основной, убедитесь, что вы выбрали ту, которую используют пользователи.

  2. Создадим или найдем кнопку "Отменить бронирование".

    Если кнопка "Отменить бронирование" уже существует на форме, найдем ее в элементах формы и определим ее программное имя. Если кнопки нет, добавим новую кнопку на командную панель или в нужную группу элементов формы:

    • В редакторе формы (вкладка "Элементы") щелкнем правой кнопкой мыши по командной панели или группе, где хотим разместить кнопку, и выберем "Добавить элемент".
    • Создадим кнопку, назовем ее, например, КнопкаОтменитьБронирование. Это имя мы будем использовать в коде для обращения к кнопке.
    • Укажем заголовок для кнопки: "Отменить бронирование". Это текст, который увидят пользователи.
    • Создадим обработчик события "Нажатие" для этой кнопки. Для этого в свойствах кнопки найдем событие "Нажатие" и нажмем кнопку с лупой для создания обработчика. Назовем процедуру обработчика, например, КнопкаОтменитьБронированиеНажатие. Эта процедура будет содержать логику, которая выполняется при клике на кнопку.
  3. Настроим видимость кнопки программно.

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

    Мы будем использовать обработчик ПриСозданииНаСервере или ПриОткрытии. Важно понимать разницу и выбрать наиболее подходящий для вашей задачи:

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

    Рассмотрим пример кода, который необходимо добавить в один из этих обработчиков. Мы будем ориентироваться на то, что кнопка должна быть невидима по умолчанию и становиться видимой только при выполнении двух условий: у текущего пользователя есть роль РазрешитьОтменуБронирования и функциональная опция ИспользоватьОтменуБронирования включена.

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

    В этом примере мы используем свойство Видимость элемента формы, которое полностью скрывает элемент, если установлено в "Ложь". Вы также можете использовать свойство Доступность, которое делает элемент неактивным (серым), но видимым. Выбор зависит от конкретных требований к интерфейсу и удобству пользователя.

    Важно: убедитесь, что программное имя вашей кнопки (в нашем примере КнопкаОтменитьБронирование) соответствует имени, указанному в коде. Его можно найти в свойствах элемента формы.

  4. Реализуем логику отмены бронирования.

    После того как кнопка станет видимой и доступной, необходимо реализовать функционал, который будет выполняться при ее нажатии. Эта логика должна быть выполнена на сервере, так как она, скорее всего, будет изменять данные в базе. Мы разделим клиентскую часть (взаимодействие с пользователем) и серверную часть (изменение данных).

    
    &НаКлиенте
    Процедура КнопкаОтменитьБронированиеНажатие(Команда)
        // Шаг 1: Перед выполнением важной операции, которая изменяет данные,
        // всегда рекомендуется запросить подтверждение у пользователя.
        Если Вопрос("Вы уверены, что хотите отменить бронирование?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет) = КодВозвратаДиалога.Да Тогда
            // Шаг 2: Если пользователь подтвердил действие, вызываем серверную процедуру
            // для выполнения основных операций по отмене бронирования.
            ОтменитьБронированиеНаСервере();
        КонецЕсли;
    КонецПроцедуры
    
    &НаСервере
    Процедура ОтменитьБронированиеНаСервере()
        // Шаг 3: Здесь, на сервере, реализуем основную логику отмены бронирования.
        // Нам нужен объект документа "Заказ клиента", чтобы внести в него изменения.
        // Получаем объект документа из реквизитов формы.
        // Функция РеквизитФормыВЗначение() возвращает объект данных, соответствующий реквизиту формы.
        ДокументОбъект = РеквизитФормыВЗначение("Объект");
    
        // Шаг 4: Выполняем действия по отмене бронирования.
        // Предположим, что в модуле объекта документа "Заказ клиента" уже есть или будет создан
        // метод ОтменитьБронирование(), который инкапсулирует всю необходимую логику:
        // изменение статусов, корректировку регистров накопления (например, "ТоварыВРезервеНаСкладах").
        // Если такого метода нет, его нужно будет реализовать в модуле объекта документа.
        // Пример вызова метода объекта:
        ДокументОбъект.ОтменитьБронирование();
    
        // Шаг 5: После изменения объекта необходимо его записать в базу данных.
        // Это сохранит все изменения, сделанные методом ОтменитьБронирование().
        ДокументОбъект.Записать();
    
        // Шаг 6 (Необязательно): Если требуется обновить данные на форме после записи,
        // чтобы пользователь увидел актуальное состояние документа,
        // можно вызвать метод формы Прочитать().
        // Прочитать();
    КонецПроцедуры
    

    Важные моменты при реализации логики:

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

Шаг 3: Дополнительные возможности — управление видимостью на основе пользовательских настроек

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

  1. Создадим или используем существующий регистр сведений для настроек пользователя.

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

    • В дереве конфигурации развернем ветку "РегистрыСведений".
    • Добавим новый регистр сведений, например, НастройкиОтменыБронированияПользователей.
    • Добавим измерение Пользователь с типом "СправочникСсылка.Пользователи". Это измерение будет хранить ссылку на пользователя, для которого создается настройка.
    • Добавим ресурс ИспользоватьОтменуБронирования с типом "Булево". Этот ресурс будет хранить значение "Истина" или "Ложь", указывающее на личное предпочтение пользователя.
    • Установим периодичность "Непериодический". Нам не нужно хранить историю изменений этой настройки, только ее текущее значение.
    • Режим записи: "Независимый". Это позволит записывать настройки напрямую, без привязки к регистраторам.

    После создания регистра, необходимо будет предоставить пользователям интерфейс для управления этой настройкой (например, через форму общих настроек, дополнительную обработку или путем доработки стандартного справочника "Пользователи").

  2. Изменим код проверки видимости кнопки.

    Теперь в модуле формы документа, вместо использования стандартной функции ФункциональнаяОпцияДоступна() (которая проверяет константу), мы будем обращаться к нашему регистру сведений. Логика проверки будет следующей: кнопка видна, если у пользователя есть роль РазрешитьОтменуБронирования И в его личных настройках (из регистра сведений) установлено разрешение на отмену бронирования.

    
    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
        // ... Ваш существующий код ...
    
        // Инициализируем переменную, которая будет хранить окончательное решение о видимости кнопки.
        // По умолчанию кнопка невидима.
        ПеременнаяВидимостиКнопки = Ложь;
    
        // Шаг 1: Сначала проверяем основное условие - наличие роли.
        // Без этой роли кнопка в любом случае не должна быть видна.
        Если РольДоступна("РазрешитьОтменуБронирования") Тогда
            // Шаг 2: Если роль есть, переходим к проверке пользовательской настройки.
            // Получаем текущего пользователя системы.
            ТекущийПользователь = Пользователи.ТекущийПользователь();
    
            // Создаем структуру с ключом для поиска записи в регистре сведений.
            // В нашем случае это измерение "Пользователь".
            СтруктураОтбора = Новый Структура("Пользователь", ТекущийПользователь);
    
            // Шаг 3: Пытаемся получить запись из регистра сведений для текущего пользователя.
            // Используем метод Получить(), который возвращает Структуру или Неопределено.
            НастройкиПользователя = РегистрыСведений.НастройкиОтменыБронированияПользователей.Получить(СтруктураОтбора);
    
            // Шаг 4: Проверяем, найдена ли настройка для пользователя
            // и установлено ли в ней разрешение на использование функции отмены бронирования.
            Если НастройкиПользователя <> Неопределено И НастройкиПользователя.ИспользоватьОтменуБронирования Тогда
                // Если настройка найдена и она разрешает, устанавливаем переменную видимости в Истина.
                ПеременнаяВидимостиКнопки = Истина;
            КонецЕсли;
        КонецЕсли;
    
        // Шаг 5: Применяем полученное значение к свойству видимости кнопки.
        Элементы.КнопкаОтменитьБронирование.Видимость = ПеременнаяВидимостиКнопки;
    
        // ... Остальной код обработчика ...
    КонецПроцедуры
    

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

Заключение

Мы подробно рассмотрели, как можно реализовать условную видимость кнопки в документе "Заказ клиента" 1С:УТ 11.4, используя комплексный подход, включающий в себя создание ролей, функциональных опций и программное управление свойствами формы. Вы также узнали, как расширить эту функциональность, добавив возможность индивидуальной настройки видимости для каждого пользователя через регистр сведений.

Используя методы РольДоступна() и ФункциональнаяОпцияДоступна(), а также управляя свойствами Видимость и Доступность элементов формы в обработчиках ПриСозданииНаСервере или ПриОткрытии, мы достигаем высокой гибкости и безопасности в управлении интерфейсом. Вся эта работа ведется в управляемых формах платформы 1С:Предприятие 8.3, что позволяет создавать современные и удобные интерфейсы.

Помните, что каждый шаг требует внимательности и тестирования. Перед внесением изменений в рабочую базу, обязательно проверьте все на тестовой копии. Успехов в разработке на 1С!

← На главную