Как изменить реквизит проведенного документа в 1С без прав на отражение в регламентированном учете?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

В конфигурациях 1С на платформе «1С:Предприятие 8» (в частности, в «Управление производственным предприятием, ред. 1.3») часто возникает задача: дать пользователю с ограниченными правами (например, менеджеру по продажам или закупкам) возможность менять отдельные текстовые поля — такие как Комментарий — в уже проведенных документах или документах из закрытого периода.

При этом у пользователя отсутствует роль Отражение в регламентированном учете. Простая попытка записать документ программно даже с использованием привилегированного режима завершается ошибкой прав доступа. Разберем причинно-следственные связи этой проблемы и проанализируем решения.

Почему стандартный код с привилегированным режимом выдает ошибку?

Многие разработчики пытаются решить задачу «в лоб», вызывая запись документа в модуле с установленным привилегированным режимом и отключением проверок через ОбменДанными.Загрузка = Истина. Рассмотрим следующий пример кода:


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

При выполнении этого кода для проведенного документа («Реализация товаров и услуг» или «Поступление товаров и услуг») пользователь получает исключение: «Недостаточно прав для отражения в регламентированном учете. Изменения не могут быть записаны...».

Выясним причину такого поведения платформы и конфигурации:

  1. Метод УстановитьПривилегированныйРежим() отключает ограничения на уровне базы данных (RLS — Record Level Security). Однако он не отменяет программные проверки, прописанные разработчиками в модулях объектов и подписках на события (например, вызовы функций РольДоступна() или проверку дополнительных прав).
  2. Свойство ОбменДанными.Загрузка = Истина отключает бизнес-логику и проверки только в тех обработчиках события ПередЗаписью или подписках, где разработчики явно добавили проверку Если ОбменДанными.Загрузка Тогда Возврат; КонецЕсли;. В типовой конфигурации УПП 1.3 подписки на события, проверяющие право на отражение в регламентированном учете, выполняются независимо от флага загрузки.
  3. При попытке записи проведенного документа система в любом случае контролирует права текущего пользователя на работу с регл. учетом и закрытый период.

Варианты решения проблемы

Рассмотрим несколько проверенных способов решения задачи без нарушения прав доступа и риска повреждения учетных данных.

Вариант 1. Использование механизма «Дополнительных сведений» (Рекомендуется)

Вместо изменения штатного реквизита Комментарий непосредственно в документе, используем встроенный механизм дополнительных сведений. Дополнительные сведения хранятся в отдельном регистре сведений ЗначенияСвойствОбъектов и не меняют сам документ.

  1. Зайдем в систему под администратором и создадим новое Дополнительное сведение для нужного типа документов (например, «Комментарий менеджера»).
  2. Пользователю достаточно иметь права на запись в регистр сведений дополнительных реквизитов, при этом документ перезаписывать не требуется.
  3. При необходимости эти сведения легко выводятся в списки документов, динамические списки и любые отчеты.

Вариант 2. Использование независимого регистра сведений

Если штатный механизм дополнительных сведений по каким-то причинам не подходит, создадим собственный независимый регистр сведений, например ЗаметкиКДокументам.

Структура регистра:

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

Вариант 3. Асинхронная запись через фоновое задание

Если бизнес-требования жестко заставляют менять именно реквизит Комментарий самого документа, запись можно выполнить в контексте фонового задания на сервере.


// В обработчике нажатия кнопки на клиенте/сервере
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(СсылкаНаДокумент);
МассивПараметров.Добавить(НовыйТекстКомментария);

ФоновыеЗадания.Выполнить("МойОбщийМодульСервер.ОбновитьКомментарийДокумента", МассивПараметров);

Код процедура в серверном модуле МойОбщийМодульСервер:


Процедура ОбновитьКомментарийДокумента(СсылкаНаДокумент, НовыйКомментарий) Экспорт
    УстановитьПривилегированныйРежим(Истина);
    
    ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
    ДокОбъект.Комментарий = НовыйКомментарий;
    ДокОбъект.ОбменДанными.Загрузка = Истина;
    ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
КонецПроцедуры

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

Вариант 4. Корректировка подписок на события в конфигураторе

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

В начало процедур-обработчиков таких подписок добавляется условие:


Если Источник.ОбменДанными.Загрузка Тогда
    Возврат;
КонецЕсли;

После этого доработка связки ОбменДанными.Загрузка = Истина совместно с УстановитьПривилегированныйРежим(Истина) позволит успешно перезаписывать проведенные документы без выполнения проверок регламентированного учета.

Резюме

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

← На главную