Как предоставить секретарю ограниченный доступ к редактированию номера и даты документа "Командировка" в 1С:ЗУП?

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

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

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

Подход 1: Использование расширений конфигурации

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

1. Модификация формы документа "Командировка"

Прежде всего, нам потребуется изменить форму документа "Командировка", чтобы поля "Номер" и "Дата" были доступны для редактирования секретарю. Для этого:

  1. Мы создаем новое расширение конфигурации.
  2. Добавляем в расширение объект "Документ.Командировка" и его основную форму.
  3. На форме документа "Командировка" мы находим элементы управления, связанные с реквизитами Номер и Дата.
  4. Для этих элементов мы устанавливаем свойство ТолькоПросмотр = Ложь или просто убеждаемся, что они интерактивно доступны для редактирования. Остальные поля документа останутся недоступными для изменения, согласно стандартным правам секретаря.
  5. Для выполнения привилегированных операций, мы можем добавить на форму команду, например, "ЗаписатьНомерИДату", которая будет вызывать серверный код.

2. Обработка записи в привилегированном режиме

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

Мы можем использовать событие формы документа, например, "ПриЗаписиНаСервере" или создать отдельную команду на форме, которая будет выполнять запись. Рассмотрим пример серверной процедуры:


// В модуле формы документа "Командировка" расширения,
// например, в обработчике команды "ЗаписатьНомерИДату" или "ПередЗаписьюНаСервере"

&НаСервере
Процедура ЗаписатьНомерИДатуДокументаНаСервере(Знач НовыйНомер, Знач НоваяДата)

    // Получаем объект документа из ссылки
    ДокументОбъект = Объект.ПолучитьОбъект();

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

    // Включаем привилегированный режим.
    // Это позволит выполнить запись документа, даже если у текущего пользователя
    // нет полных прав на объект.
    УстановитьПривилегированныйРежим(Истина);

    Попытка
        // Изменяем только разрешенные реквизиты
        ДокументОбъект.Номер = НовыйНомер;
        ДокументОбъект.Дата = НоваяДата;

        // Выполняем запись документа
        ДокументОбъект.Записать();
        Сообщить("Номер и дата документа успешно изменены.");
    Исключение
        Сообщить("Ошибка при изменении номера и даты: " + ОписаниеОшибки(), СтатусСообщения.Важное);
    КонецПопытки;

    // Обязательно отключаем привилегированный режим после выполнения операции
    УстановитьПривилегированныйРежим(Ложь);

КонецПроцедуры

В клиентском коде мы могли бы вызывать эту серверную процедуру, передавая новые значения номера и даты, введенные секретарем.

3. Назначение прав через профили и роли

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

  1. Интерактивное редактирование полей Номер и Дата на форме документа, модифицированной расширением.
  2. Выполнение серверных процедур расширения, работающих в привилегированном режиме (т.е. иметь право на вызов конкретных команд или доступ к общему модулю, содержащему привилегированный код).

Важно также убедиться, что для расширения отключен безопасный режим (если он был включен), иначе привилегированный режим может быть ограничен.

Подход 2: Использование внешней обработки данных

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

1. Логика работы обработки

Внешняя обработка может представлять собой форму со списком документов "Командировка", где секретарь сможет выбрать нужный документ. Затем в этой же обработке или в отдельном диалоговом окне будет предоставлена упрощенная форма, позволяющая изменить только номер и дату выбранного документа. Это дает нам полный контроль над интерфейсом и доступными действиями.

2. Привилегированный режим в обработке

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

Рассмотрим пример кода из внешней обработки:


// В модуле формы внешней обработки

&НаКлиенте
Процедура ИзменитьИЗаписать(Команда)
    // Предполагаем, что у нас есть поля формы:
    // ПолеВводаСсылкаНаДокумент - для выбора командировки
    // ПолеВводаНовыйНомер - для ввода нового номера
    // ПолеВводаНоваяДата - для ввода новой даты

    Если ЗначениеЗаполнено(ПолеВводаСсылкаНаДокумент) Тогда
        Если Не ЗначениеЗаполнено(ПолеВводаНовыйНомер) Тогда
            Сообщить("Поле 'Новый номер' должно быть заполнено!");
            Возврат;
        КонецЕсли;

        Если ТипЗнч(ПолеВводаНоваяДата) <> Тип("Дата") Или Не ЗначениеЗаполнено(ПолеВводаНоваяДата) Тогда
            Сообщить("Поле 'Новая дата' должно быть заполнено корректной датой!");
            Возврат;
        КонецЕсли;

        // Вызываем серверную процедуру для выполнения изменений
        ИзменитьИЗаписатьНаСервере(ПолеВводаСсылкаНаДокумент, ПолеВводаНовыйНомер, ПолеВводаНоваяДата);

    Иначе
        Сообщить("Выберите документ 'Командировка'.");
    КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ИзменитьИЗаписатьНаСервере(СсылкаНаДокумент, НовыйНомер, НоваяДата)
    // Получаем объект документа по ссылке
    Попытка
        ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
    Исключение
        Сообщить("Не удалось получить объект документа: " + ОписаниеОшибки(), СтатусСообщения.Важное);
        Возврат;
    КонецПопытки;

    // Включаем привилегированный режим для записи
    УстановитьПривилегированныйРежим(Истина);

    Попытка
        ДокументОбъект.Номер = НовыйНомер;
        ДокументОбъект.Дата = НоваяДата;

        // Если нужно провести документ после изменения
        // Допустим, на форме обработки есть флажок "ПровестиДокумент"
        Если ЭтотОбъект.ПровестиДокумент Тогда
            ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
            Сообщить("Документ " + ДокументОбъект.Номер + " успешно изменен и проведен.");
        Иначе
            ДокументОбъект.Записать();
            Сообщить("Документ " + ДокументОбъект.Номер + " успешно изменен.");
        КонецЕсли;

    Исключение
        Сообщить("Ошибка при изменении/проведении документа: " + ОписаниеОшибки(), СтатусСообщения.Важное);
    КонецПопытки;

    // Обязательно отключаем привилегированный режим
    УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры

3. Контроль и валидация

Во внешней обработке мы можем реализовать дополнительные проверки, например, на уникальность вводимого номера документа, чтобы избежать дублирования, а также контроль корректности даты. Эти проверки желательно выполнять до включения привилегированного режима.

Детали и меры предосторожности при работе с Привилегированным режимом

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

  1. Как использовать: Привилегированный режим можно включить, установив свойство "Привилегированный" для общего модуля (тогда весь код этого модуля будет выполняться в привилегированном режиме) или явно вызвав функцию УстановитьПривилегированныйРежим(Истина) в коде.
  2. Область действия: Мы должны включать привилегированный режим только на минимально необходимый участок кода, который требует повышенных прав. После выполнения операции его следует немедленно отключать с помощью УстановитьПривилегированныйРежим(Ложь). Это минимизирует потенциальные риски безопасности.
  3. Когда применять: Мы применяем привилегированный режим тогда, когда это логически оправдано (как в нашем случае, для предоставления ограниченных прав) и не нарушает общую логику программы, а также не приводит к нежелательным проводкам или утечке данных.

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

Проведение документа после изменения

В запросе пользователя также упоминается "проведение этого документа". После изменения номера или даты документ, скорее всего, потребуется перепровести, чтобы изменения отразились в регистрах и повлияли на связанные расчеты (например, расчет среднего заработка). Мы должны учесть это в нашей разработке.

  1. Проведение в привилегированном режиме: Если у секретаря нет прав на проведение документа "Командировка", то операцию проведения также необходимо будет выполнять в привилегированном режиме, либо через расширение, либо через внешнюю обработку. Мы видели примеры этого в коде выше, используя ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение) внутри блока привилегированного режима.
  2. Влияние на расчеты: Мы должны помнить, что изменение даты документа может повлиять на расчеты, связанные с командировкой (например, расчет среднего заработка), особенно если зарплата за соответствующий период уже начислена. Перед проведением мы можем предупредить пользователя о возможных последствиях или реализовать дополнительные проверки.

Учет "Даты запрета изменения данных"

В 1С:ЗУП, как и в других типовых конфигурациях, существует механизм "Даты запрета изменения данных". Этот механизм устанавливается администратором для предотвращения редактирования документов за прошедшие периоды, например, после сдачи отчетности.

  1. Даже при наличии доработок и привилегированного режима, если установлена дата запрета изменения, изменить документ, дата которого раньше этой даты, будет невозможно. Привилегированный режим обходит *права пользователя*, но не обходит *дату запрета изменения данных*.
  2. Мы должны убедиться, что дата редактируемого документа не попадает под глобальный запрет изменения. Если это происходит, то для внесения изменений потребуется либо временно снять запрет (что крайне не рекомендуется для обычных пользователей), либо обратиться к администратору. Это важный аспект, который мы должны учитывать при проектировании решения.

Итоговый подход: Рекомендации

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

  1. Минимизировать вмешательство: Мы избегаем изменения типовой конфигурации, что существенно упрощает процесс обновления информационной базы.
  2. Модифицировать интерфейс: Мы можем изменить форму документа "Командировка", делая поля Номер и Дата доступными для редактирования секретарю, сохраняя при этом остальные поля в режиме только для просмотра или недоступными.
  3. Централизованно управлять логикой: Мы реализуем обработчик события "ПередЗаписью" или "ПриЗаписи" документа, который будет сохранять изменения номера и даты, вызывая серверные процедуры в привилегированном режиме. Это позволяет нам централизованно управлять логикой записи.
  4. Обеспечить проведение документа: При необходимости мы можем обеспечить проведение документа после изменения номера и даты, также используя привилегированный режим.
  5. Детально настроить права: Мы можем создать новую роль с минимально необходимыми правами для секретаря, которая будет давать доступ к измененной форме и разрешать выполнение кода расширения.

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

← На главную