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