В конфигурациях 1С на платформе «1С:Предприятие 8» (в частности, в «Управление производственным предприятием, ред. 1.3») часто возникает задача: дать пользователю с ограниченными правами (например, менеджеру по продажам или закупкам) возможность менять отдельные текстовые поля — такие как Комментарий — в уже проведенных документах или документах из закрытого периода.
При этом у пользователя отсутствует роль Отражение в регламентированном учете. Простая попытка записать документ программно даже с использованием привилегированного режима завершается ошибкой прав доступа. Разберем причинно-следственные связи этой проблемы и проанализируем решения.
Многие разработчики пытаются решить задачу «в лоб», вызывая запись документа в модуле с установленным привилегированным режимом и отключением проверок через ОбменДанными.Загрузка = Истина. Рассмотрим следующий пример кода:
Попытка
УстановитьПривилегированныйРежим(Истина);
ДокОбъект = СсылкаНаОбъект.ПолучитьОбъект();
ДокОбъект.Комментарий = "Новый комментарий";
ДокОбъект.ОбменДанными.Загрузка = Истина;
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
УстановитьПривилегированныйРежим(Ложь);
Исключение
Сообщить("Не удалось записать документ: " + ОписаниеОшибки());
КонецПопытки;
При выполнении этого кода для проведенного документа («Реализация товаров и услуг» или «Поступление товаров и услуг») пользователь получает исключение: «Недостаточно прав для отражения в регламентированном учете. Изменения не могут быть записаны...».
Выясним причину такого поведения платформы и конфигурации:
УстановитьПривилегированныйРежим() отключает ограничения на уровне базы данных (RLS — Record Level Security). Однако он не отменяет программные проверки, прописанные разработчиками в модулях объектов и подписках на события (например, вызовы функций РольДоступна() или проверку дополнительных прав).ОбменДанными.Загрузка = Истина отключает бизнес-логику и проверки только в тех обработчиках события ПередЗаписью или подписках, где разработчики явно добавили проверку Если ОбменДанными.Загрузка Тогда Возврат; КонецЕсли;. В типовой конфигурации УПП 1.3 подписки на события, проверяющие право на отражение в регламентированном учете, выполняются независимо от флага загрузки.Рассмотрим несколько проверенных способов решения задачи без нарушения прав доступа и риска повреждения учетных данных.
Вместо изменения штатного реквизита Комментарий непосредственно в документе, используем встроенный механизм дополнительных сведений. Дополнительные сведения хранятся в отдельном регистре сведений ЗначенияСвойствОбъектов и не меняют сам документ.
Если штатный механизм дополнительных сведений по каким-то причинам не подходит, создадим собственный независимый регистр сведений, например ЗаметкиКДокументам.
Структура регистра:
Документ (Тип: ДокументСсылка)ТекстЗаметки (Тип: Строка)Для сохранения текстового примечания пользователь будет записывать данные напрямую в этот регистр. Проведенный документ при этом остается нетронутым, проверка прав на проведение и закрытый период не срабатывает.
Если бизнес-требования жестко заставляют менять именно реквизит Комментарий самого документа, запись можно выполнить в контексте фонового задания на сервере.
// В обработчике нажатия кнопки на клиенте/сервере
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(СсылкаНаДокумент);
МассивПараметров.Добавить(НовыйТекстКомментария);
ФоновыеЗадания.Выполнить("МойОбщийМодульСервер.ОбновитьКомментарийДокумента", МассивПараметров);
Код процедура в серверном модуле МойОбщийМодульСервер:
Процедура ОбновитьКомментарийДокумента(СсылкаНаДокумент, НовыйКомментарий) Экспорт
УстановитьПривилегированныйРежим(Истина);
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
ДокОбъект.Комментарий = НовыйКомментарий;
ДокОбъект.ОбменДанными.Загрузка = Истина;
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
КонецПроцедуры
Фоновые задания выполняются в отдельном сеансе под административными правами (или правами указанного в настройках пользователя), где интерактивные проверки текущего сеанса пользователя не блокируют запись.
Если база находится на поддержке с возможностью изменения, проанализируем подписки на события при записи документов (например, подписки, проверяющие право отражения в регламентированном учете).
В начало процедур-обработчиков таких подписок добавляется условие:
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
После этого доработка связки ОбменДанными.Загрузка = Истина совместно с УстановитьПривилегированныйРежим(Истина) позволит успешно перезаписывать проведенные документы без выполнения проверок регламентированного учета.
Для безопасной работы пользователей без лишних прав на регламентированный учет наилучшим архитектурным решением является вынос дополнительных текстовых данных в Дополнительные сведения или независимый регистр сведений. Это полностью исключает риски случайного изменения движений документа в закрытых периодах.