30.09.24

Создаем неструктурированный процесс в Camunda

15 мин · Обучающие


или – как выжить без Ad Hoc и CMMN?



CBOK определяет понятие "бизнес-процесс" как "набор функций, выполняемых в определенной последовательности для создания потребительской ценности".


"A collection of related, structured activities or tasks performed by people or equipment to achieve a specific organizational goal".


Предполагается, что модель процесса (Process definition) имеет четко определенную структуру, которой следуют все экземпляры процесса (Process instances). Такие линейные процессы можно встретить, например, в банках, страховых компаниях, ритейле и маркетплейсах. 


Но как быть, если экземпляры процесса не имеют одинаковой структуры? Как быть, когда решения в процессе выполняются ситуативно, на основе экспертного опыта, а задачи могут быть выполнены разное число раз и в любой последовательности?


Примеры неструктурированных процессов:


  • Медицина (Healthcare Case Management). Лечение пациента редко следует заранее известному процессу. В зависимости от диагноза, реакции на лечение и других факторов, процесс может изменяться. 

  • Юриспруденция (Legal Case Management). В правовых процессах многие задачи зависят от того, как будет развиваться дело, какие доказательства будут предоставлены и каков будет ответ другой стороны.

  • Обслуживание клиентов (Customer Service). В случае обработки запросов клиентов задачи могут варьироваться в зависимости от типа проблемы, её срочности и ответных действий клиента.

  • Управление проектами (Project Management). Для проектов с гибкой методикой может потребоваться корректировка в зависимости от уже достигнутых целей и результатов.


Ad Hoc и CMMN


Первое, что приходит на ум аналитику, владеющему BPMN – подпроцесс по требованию (Ad Hoc Subprocess).



Ad Hoc, он же подпроцесс по требованию

(Ad Hoc, он же подпроцесс по требованию)


Однако, в Camunda поддержка Ad Hoc отсутствует, о чем нам любезно (и очень давно) сообщает Найл на форуме Camunda, рекомендуя использовать CMMN или "иные символы BPMN".


Camunda не поддерживает Ad Hoc

(Camunda не поддерживает Ad Hoc)


При попытке загрузить процесс с Ad Hoc в камунду, система выведет ошибку, выругавшись на некорректное назначение (или источник) последовательности выполнения:


* Invalid destination 'Activity_1xvqljd' of sequence flow 'Flow_0cma5xm' 


Попробуем воспользоваться советом Найла и обратимся к CMMN (Case Management Model and Notation). Эта нотация была разработана Object Management Group для для более гибких сценариев, где задачи могут быть непредсказуемы, а их выполнение зависит от динамически меняющихся обстоятельств.


Но разочарование ждет нас и здесь. По словам основателей Camunda, CMMN не оправдала возложенных на неё ожиданий. В сравнении с BPMN, CMMN слишком сложная и запутанная, а ценность применения её в проектах оказалась слишком низкой. Подробнее почитать об этом можно в блоге Camunda.


В Camunda Modeler CMMN по-умолчанию отключена (как включить CMMN в Camunda Modeler). А Camunda 8 эту нотацию вообще не поддерживает.


Что же делать?



TMTOWTDI (There's More Than One Way To Do It)


К счастью, многое из того, что позволяют сделать Ad Hoc или CMMN, может быть реализовано при помощи комбинации DMN + BPMN.


Наглядный пример из жизни – документарное сопровождение проектной деятельности.


Каждый проект автоматизации процессов по-своему уникален. У каждого заказчика свои условия контрактования и оплаты. Одни могут авансировать работы, другие – нет. Кто-то готов подписать акты и до фактического их завершения, а кто-то – строго после завершения всех доработок. С одними заказчиками мы обмениваемся документами через ЭДО, а другие – хотят иметь бумажные оригиналы.


Соответственно, набор задач и последовательность их выполнения в таком процессе отличаются от заказчика к заказчику, от проекта к проекту. 


Задачи в процессе сопровождения контракта

(типичный набор задач в процессе сопровождения проекта)


Неизменно только одно – для завершения процесса должны быть завершены следующие его этапы:


  • Получена оплата,

  • Получены подписанные оригиналы документов,

  • Завершены работы.



Для того, чтобы реализовать такую неструктурированную магию, нам понадобится 3 ингредиента: 


  • DMN (Business Rule Task);

  • Activity (Task, Call Activity, Subprocess) с маркером Multi-instance;

  • Язык выражений (FEEL – для Camunda 7 и 8, FEEL + JUEL для Camunda 7).


Магический процесс

(магический процесс)


Здесь и далее, в целях наглядности, задачи процесса будут представлены как User Tasks, а процесс смоделирован для Camunda 7.


DMN и Business Rule Task


Создадим таблицу решений contract, входом которой будет переменная процесса contract, представляющая собой объект, содержащий параметры контракта.


{
    "contract":
    {
        "value":
        {
            "edi": true,
            "prepayment": false
        }
    }
}

Атрибут edi будет определять необходимость отправки документов через ЭДО, а prepayment – признак того, что контракт с предоплатой.

На выходе таблицы будет переменная tasks – массив или коллекция строк (List<String>), представляющая собой список наименований пользовательских задач.


В качестве Hit Policy подойдет Collect или (если важен порядок выполнения активностей) – Rule Order.


DMN, которая будет управлять структурой процесса

(DMN, которая будет управлять структурой процесса)


Не забудьте указать наименование выходной переменной процесса и метод сбора данных – CollectEntries (в Camunda 8 указывать тип не нужно, там все в JSON).


Выходная переменная DMN

(выходная переменная)



Настройки задачи (Activity Properties)


Перейдем к настройкам задачи. Важное преимущество Camunda – возможность использования языка выражений (Expression Language). В Camunda 7 это JUEL (Java Unified Expression Language), а в Camunda 8 – FEEL (Friendly Enough Expression Language).


С помощью выражения вы можете определить:


  • Имя задачи (Activity Name);

  • Топик (Topic) для External Task;

  • Вызываемый элемент (Called Element) для Call Activity.



Таким, образом, DMN таблица определяет набор и порядок выполнения активностей, а язык выражений, путем подстановки значения, обеспечивает выбор нужной реализации.


Зададим маркер активности задачи. Если задачи могут быть выполнены в любом порядке, подойдет Parallel multi-instance. Если важен порядок выполнения задач – необходимо выбрать Sequential multi-instance (в этом случае не забываем также использовать Hit Policy Rule Order в DMN-таблице).


Маркер активности

(маркер активности)


Число экземпляров активности = числу элементов в массиве tasks. Его необходимо указать в поле Collection. Содержимое элемента, который будет подставляться в имя задачи, поместим в локальную переменную с именем task. Её же укажем в качестве имени задачи при помощи языка выражений: ${task}.


Настройки задачи

(настройки задачи)



Развернем полученные артефакты в Camunda и запустим процесс, подав на вход переменную contract:


Входные данные процесса

(входные данные)


Найдя в Cockpit экземпляр процесса, мы видим следующую картину:



Задачи выполняются параллельно

(параллельно выполняемые задачи)



Появилось семь экземпляров задач, получивших нужные наименования, которые пользователь может увидеть в списке задач (Tasklist):



Список полученных задач

(список задач)


Поскольку задачи выполняются параллельно, они могут быть выполнены в любом порядке.


Приведенный выше пример является упрощенным. Однако, эти же принципы могут быть применены и при проектировании более сложных процессов, где часть этапов может выполнятся последовательно, а часть – параллельно. Пользовательские задачи могут быть заменены на сервисные (External Task). Сложная логика может быть вынесена в вызываемые активности (Call Activity). А дополнительной "событийности" могут добавить подпроцессы по событию (Event Subprocess).


Доводилось ли вам решать похожие задачи? Предлагаю обсудить концепцию на нашем форуме.