Параллельные задания в регламентах. Вариант реализации

25 4

В Directum RX есть чудесный механизм, позволяющий довольно гибко настроить процесс согласования документов – регламенты. Через этапы согласования можно довольно гибко задавать исполнителей, темы, сроки и т.д., но параллельность заданий присутствует только в рамках отдельно взятого этапа. В связи с тем, что схема задачи не доступна для изменений, реализовать полноценную параллельность, где есть несколько «веток», которые могут «двигаться» с разной скоростью, не получится. В данной статье рассмотрим одну из возможностей, как можно разделить параллельные этапы, используя задачу на согласование по регламенту.

Дано

Для некоторых типов этапов есть возможность формировать задания параллельно (как правило, возможность есть везде, где есть несколько исполнителей). Но что, если вдруг возникает непреодолимое желание необходимость сделать так, чтобы задания исполнителям были созданы одновременно, но при этом имели разную тему, или разные варианты выполнения, сроки, или еще что-нибудь. Подходы к реализации могут быть разными, рассмотрим один из них.

Думаем

Общая концепция выглядит следующим образом: выделяем основной этап согласования, который будем использовать для группировки, в него добавляем коллекцию с подчинёнными этапами согласования и при формировании заданий в рамках основного этапа используем подчиненные.

Действуем

Этапы согласования

В первую очередь добавим модификации в справочник Этапы согласования. Добавим два новых свойства и вынесем их на форму (Рис. 1):

  • «Параллельные этапы» - логическое свойство для удобства работы,
  • «Этапы» - коллекция со ссылкой на этапы согласования, которые будут использоваться.

Рис. 1 Карточка Этапа согласования

Подчиненные этапы должны быть отфильтрованы по типу ведущего этапа, обязательно необходимо учесть задание и задание с доработкой. На форме записи справочника блокируем/ скрываем/ заполняем свойства исходя из желаемой логики, все зависит от фантазии. Как на примере выше, «Тема», группы «Исполнители» и «Настройки» заблокированы, так как их значения будут вычисляться из подчиненных этапов. Дополнительно, можно нужно при сохранении добавить валидацию: проверять, что типы этапов соответствуют друг другу, и нет ситуации, когда «основной» этап вложен в другой «основной».

Роли согласования

Добавим новую роль согласования «Исполнители подчиненных этапов» для определения исполнителей. Роль будет вычислять список (List<IRecipient>) по всем подчиненным этапам, используя базовую функцию

Sungero.Docflow.PublicFunctions.ApprovalStage.Remote.GetStagePerformers(task, stage)

Для примера - функция вычисления исполнителей подчиненных этапов может выглядеть следующим образом:

    /// <summary>
    /// Получить сотрудников роли "Исполнители подчиненных этапов".
    /// </summary>
    /// <param name="task">Задача.</param>
    /// <returns>Список сотрудников.</returns>
    [Public]
    public static List<IRecipient> GetSubStagePerformers(IApprovalStage stage, IApprovalTask task)
    {
      var performers = new List<IRecipient>();

      // Обращаемся к коллекции с параллельными этапами и в цикле собираем исполнителей.

      var subStages = stage.ParallelStages.Select(x => x.Stage);

      foreach (var subStage in subStages)

      {

        var subStagePerformers = Sungero.Docflow.PublicFunctions.ApprovalStage.Remote.GetStagePerformers(task, subStage);

        if (subStagePerformers.Any())
          performers.AddRange(subStagePerformers);

      }

      return performers;
    }

Схема задачи

Теперь перейдем к основному. Вся «магия» реализуется в событии блока StartAssignment. По каждому заданию получаем текущий этап, и, если он является «ведущим», то вычисляем «подчиненный» этап. Поиск осуществляем через исполнителя (исполнитель этапа = исполнитель создаваемого задания). Далее, на основе вычисленного подчиненного этапа заполняем требуемые свойства задания (тему, срок и т.д.). Таким образом, для каждого исполнителя (группы исполнителей) мы получаем специфичные настройки задания при сохранении параллельности исполнения.

Особенности и ограничения

В качестве основных сложностей данной реализации можно выделить следующее:

  • Один исполнитель в разных этапах. Может возникнуть ситуация, когда в нескольких подчиненных этапах исполнитель будет дублироваться. Так как несколько заданий одному исполнителю в рамках одного блока быть сформировано не может, то пользователю будет приходить задание только по первому найденному этапу. Дополнительно в данной ситуации можно добавить некую приоритизацию выбора этапа.
  • Вкладка «Регламент». В зависимости от изменений может потребоваться адаптация StateView, иначе данные на вкладке могут вводить в заблуждение пользователей.

Обратите внимание, что приведенный выше пример и относительная простота реализации возможна только для этапов с типом «Задание». Для этапов с другими типами подобная реализация в большинстве случаев не нужна, с точки зрения работы процессов, но при необходимости возможна. Сложность реализации при этом уже будет зависеть от конкретного типа этапа и исходных требований.

Помимо вышеуказанных особенностей, необходимо будет учесть:

  • Схлапывание этапов. В типах «Печать», «Отправка», «Регистрация», «Исполнение», «Подписание», «Рассмотрение» есть механизм схлапывания, который формирует обобщенное задание, если один сотрудник выполняет разный функционал. В данной ситуации необходимо будет полностью переопределять исполнителей в обработчике StartBlock, там же, задавать через коллекцию (e.Block.CollapsedStagesTypes* - коллекция типов схлопнутых этапов в заданиях, * заменяется на сокращенное название типа задания) нужные (или нет) этапы.
  • Этап с типом «Согласование». Для этого этапа придется учесть особенности определения исполнителей (доп. согласующие, подписи, доработка).

Итог

В данной статье был рассмотрен один из примеров того, как можно расширить возможности системы в части согласования/исполнения с помощью несложных модификаций. Надеюсь, информация окажется интересной и полезной.

Спасибо за внимание!

Анастасия Мосунова

Здравствуйте! 

Ваша статья очень полезная, спасибо! 

Однако по самой реализации у меня возник вопрос: как вы стартуете задания по дочерним этапам? Просто создаете в коде задания и отправляете их? Искала, как можно по этапу согласования начать задание, но, к сожалению, другого варианта решения не нашла. 

Андрей Моржухин

Анастасия, Добрый день!

В части формирования заданий все штатно. Мы получаем список исполнителей в StartBlock() на основе "подэтапов" через роль согласования. Соответственно, сколько исполнителей получили, столько заданий и будет. В StartAssignment() вычисляем повторно текущий этап, и подменяем его на нужный "подэтап" и уже применяем его настройки.

Анастасия Мосунова

Андрей, спасибо большое! Кажется поняла!

Сергей Королев

Вроде бы есть компромиссное решение.
Но часто параллельные задания требуют контроля. А если у каждого еще свой контролер - то беда совсем...

Авторизуйтесь, чтобы написать комментарий