Механизм ввода на основании позволяет ускорить создание связанных документов, однако в бизнес-логике часто требуется запретить ввод подчиненного документа при несоблюдении определенных условий (например, если документ-основание не проведен, закрыт период или не заполнены обязательные поля). Разберем, почему привычные методы из обычных форм не всегда срабатывают в управляемом интерфейсе и как правильно реализовать запрет.
Разработчики часто пытаются запретить ввод на основании, переопределяя событие ОбработкаЗаполнения в модуле объекта создаваемого документа следующим образом:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
Если Не РазрешеноСоздание(ДанныеЗаполнения) Тогда
СтандартнаяОбработка = Ложь;
Возврат;
КонецЕсли;
КонецПроцедуры
Проанализируем, к чему это приводит. В управляемых формах флаг СтандартнаяОбработка = Ложь лишь отключает платформенный алгоритм копирования реквизитов из основания. Сам процесс создания объекта и открытия его формы не прерывается: пользователь увидит открытую пустую форму нового документа. Рассмотрим корректные способы решения этой задачи.
Если требуется жестко прервать процесс создания объекта на уровне модуля объекта без создания дополнительных форм и команд, можно использовать оператор ВызватьИсключение:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
Если Не ДанныеЗаполнения.Проведен Тогда
ВызватьИсключение "Ввод на основании непроведенного заказа запрещен!";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Платформа прервет транзакцию создания объекта и покажет системное окно с ошибкой. Однако данный способ формирует системный дамп ошибки, что не всегда выглядит презентабельно для конечного пользователя.
Более мягкий и управляемый способ — перехватить открытие формы в обработчике ПриСозданииНаСервере формы создаваемого документа.
Разберем по шагам реализацию этого варианта:
ПриСозданииНаСервере проверим переданные параметры создания (Параметры.Основание или Параметры.ЗначениеЗаполнения).Отказ = Истина и выведем информационное сообщение.Посмотрим на пример кода:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Ключ.Пустая() И ЗначениеЗаполнено(Параметры.ЗначениеЗаполнения) Тогда
Основание = Параметры.ЗначениеЗаполнения;
Если ТипЗнч(Основание) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
Если Основание.СуммаДокумента <= 0 Тогда
Отказ = Истина;
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Нельзя ввести документ по заказу с нулевой суммой!");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
При таком подходе форма нового документа не откроется, а пользователь увидит аккуратное предупреждение.
Чтобы исключить попытки ввода, логичнее всего скрыть или заблокировать саму кнопку команды в документе-основании или форме списка.
В форме документа-основания в событиях ПриЧтенииНаСервере или ПослеЗаписи управляем доступностью элементов командной панели:
&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
// Отключаем команду создания подчиненного документа при определенном статусе
ЗапретитьВвод = (ТекущийОбъект.Статус = Перечисления.СтатусыЗаказов.Закрыт);
// Если команда создана вручную или параметризована
Если Элементы.Найти("ФормаДокументРеализацияТоваровУслугСоздатьНаОсновании") <> Неопределено Тогда
Элементы.ФормаДокументРеализацияТоваровУслугСоздатьНаОсновании.Доступность = Не ЗапретитьВвод;
КонецЕсли;
КонецПроцедуры
Если в конфигурации используется Библиотека стандартных подсистем (БСП), механизм ввода на основании реализуется через подключаемые команды. В модуле менеджера документа-источника в процедуре ДобавитьКомандыСозданияНаОсновании можно гибко настроить условия видимости команды или указать собственный клиентский обработчик проверки перед открытием формы.
При разработке собственной команды на клиенте перед вызовом метода ОткрытьФорму выполняется проверка состояния документа. Если проверка успешна, открывается форма подчиненного объекта с передачей структуры параметров, иначе выводится предупреждение методом ПоказатьПредупреждение без обращения к созданию формы.