Как запретить изменение проведенных документов и снятие пометки удаления в УТ 11.4 через расширение?

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

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

Почему проверка в модуле формы — это ошибка

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

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

Шаг 1. Создание расширения и добавление модуля объекта

Для начала нам необходимо создать новое расширение (или использовать существующее). Главная задача — добавить в него модуль объекта нужного нам документа (например, РеализацияТоваровУслуг). Выясним, как это сделать: в дереве конфигурации расширения находим нужный документ, нажимаем правую кнопку мыши и выбираем пункт «Добавить в расширение». Важно убедиться, что в расширение попал именно объект, а не только его форма.

Теперь откроем модуль объекта в расширении. Здесь мы будем использовать аннотацию &Перед, чтобы вклиниться в стандартный процесс записи документа.

Шаг 2. Реализация проверки прав в модуле объекта

Рассмотрим структуру процедуры ПередЗаписью. В отличие от формы, здесь нам доступны параметры РежимЗаписи и РежимПроведения. Это позволяет нам точно определить, что именно делает пользователь: просто записывает данные, проводит документ или отменяет проведение.

Посмотрим на пример кода, который блокирует изменения для определенных пользователей:


&Перед("ПередЗаписью")
Процедура Расш1_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Если запись инициирована обменом данными, проверки обычно пропускаются
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Проверяем, входит ли пользователь в наш список ограниченных прав
    // (Здесь можно использовать проверку роли или реквизит справочника)
    НайденП = Справочники.Расш1_ПользователиЗапретПроведения.НайтиПоРеквизиту("Пользователь", Пользователи.ТекущийПользователь());
    
    Если ЗначениеЗаполнено(НайденП) Тогда
        
        // 1. Запрет отмены проведения
        Если РежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения Тогда
            Сообщить("Вам запрещено отменять проведение документов!");
            Отказ = Истина;
            Возврат;
        КонецЕсли;

        // 2. Запрет изменения уже проведенного документа
        Если ЭтотОбъект.Проведен И РежимЗаписи = РежимЗаписиДокумента.Запись Тогда
            Сообщить("Нельзя изменять или перепроводить уже проведенный документ!");
            Отказ = Истина;
            Возврат;
        КонецЕсли;
        
    КонецЕсли;
КонецПроцедуры

Шаг 3. Запрет снятия пометки удаления

Теперь разберем более сложный момент, который интересовал автора темы: как запретить именно снятие пометки удаления? В обработчике ПередЗаписью мы видим текущее состояние объекта, но нам нужно сравнить его с тем, что сейчас записано в базе данных.

Проанализируем алгоритм: если в текущем объекте ПометкаУдаления установлена в Ложь, а в базе данных (по ссылке) она еще Истина — значит, пользователь пытается восстановить документ из удаленных. Посмотрим, как это реализовать:


&Перед("ПередЗаписью")
Процедура Расш1_ЗапретВосстановления(Отказ, РежимЗаписи, РежимПроведения)
    
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Ссылка.ПометкаУдаления — это значение в базе данных до записи
    // ЭтотОбъект.ПометкаУдаления — это то, что пытается записать пользователь
    Если Не ЭтотОбъект.ЭтоНовый() Тогда
        СтараяПометка = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ЭтотОбъект.Ссылка, "ПометкаУдаления");
        
        Если СтараяПометка = Истина И ЭтотОбъект.ПометкаУдаления = Ложь Тогда
            Сообщить("Снятие пометки удаления запрещено для вашей роли!");
            Отказ = Истина;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Важные нюансы при использовании расширений

При реализации подобных запретов необходимо учитывать несколько технических аспектов, чтобы не нарушить работу системы:

  1. Свойство ОбменДанными.Загрузка: Всегда добавляйте проверку этого флага в начале процедур модуля объекта. Если этого не сделать, ваши запреты могут заблокировать синхронизацию данных с другими базами (например, выгрузку из Бухгалтерии), что приведет к критическим ошибкам в учете.
  2. Метод получения данных из базы: Использование Ссылка.ПолучитьОбъект() внутри ПередЗаписью — плохая практика, так как это создает лишнюю нагрузку и может привести к блокировкам. Рекомендуется использовать функцию ОбщегоНазначения.ЗначениеРеквизитаОбъекта() или легкий запрос к таблице документа.
  3. Ролевая модель: Вместо создания отдельного справочника «Пользователи с запретом», лучше создать в расширении специальную Роль (например, Расш1_ЗапретРедактированияПроведенных). Проверить наличие роли у текущего пользователя можно программно через функцию РольДоступна().

Альтернативные способы решения

Выясним, можно ли решить задачу без написания кода. В типовых конфигурациях на базе БСП (включая УТ 11.4) существует механизм Даты запрета изменения данных. Вы можете установить дату запрета «сегодняшним числом» для определенных групп пользователей. В этом случае система автоматически заблокирует любые попытки изменения документов ранее этой даты.

Также стоит рассмотреть настройку Профилей групп доступа. В типовой конфигурации можно настроить роли так, чтобы у пользователя отсутствовало право «Интерактивная отмена проведения» или «Интерактивное снятие пометки удаления». Это более «чистый» способ с точки зрения архитектуры 1С, так как кнопки на форме станут недоступными автоматически на уровне платформы.

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

← На главную