Как настроить выборочный запрет на изменение документов в 1С:Управление торговлей 10.3

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

В типовой конфигурации «1С:Управление торговлей 10.3» механизм Установка даты запрета изменения данных работает глобально: он проверяет дату документа относительно установленной границы запрета для конкретного пользователя или группы пользователей. Однако штатный механизм не позволяет точечно заблокировать редактирование одного или нескольких произвольных документов без привязки к хронологической дате.

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

Вариант 1. Использование единой подписки на события и регистра сведений

Наиболее гибкое и правильное решение задачи без дублирования кода — создание подписки на событие записи документа в сочетании со специальным регистром сведений. Разберем по шагам весь процесс реализации.

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

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

  2. Создание подписки на событие:

    В дереве метаданных в ветке Общие → Подписки на события добавим новую подписку, например, ЗапретИзмененияВыборочныхДокументовПередЗаписью.

    В свойстве Источник выберем тип ДокументОбъект и отметим галочками все виды документов, для которых должна действовать проверка.

    В свойстве Событие укажем событие ПередЗаписью.

  3. Программный код проверки:

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

Посмотрим на пример реализации процедуры-обработчика в общем серверном модуле:


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

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

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

Вариант 2. Ограничение прав на уровне записей (RLS)

Если требуется заблокировать возможность редактирования непосредственно на уровне интерфейса (чтобы поля формы становились недоступными сразу при открытии), проанализируем использование механизма RLS (Record Level Security).

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

При использовании RLS платформа автоматически проверяет права при обращении к данным, исключая необходимость вызова дополнительных проверок в коде подписок.

Вариант 3. Блокировка по статусной модели документа

Если запрет редактирования связан с жизненным циклом документа (например, запрещено менять документы в статусах «Закрыт», «Согласован» или «Оплачен»), создадим общий реквизит или реквизит шапки СтатусДокумента.

В подписке на событие ПередЗаписью проверим исходное состояние объекта в базе данных перед его изменением:


Процедура ПроверитьСтатусПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт

    Если Источник.ЭтоНовый() ИЛИ РольДоступна("ПолныеПрава") Тогда
        Возврат;
    КонецЕсли;

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

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

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

← На главную