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