15 мая 2013 г.

WorkFlow и рассылка сообщений

В SAP есть такой интересный механизм, как WorkFlow. Ну очень интересный, с большим количеством ну очень интересных подводных камней.
Начинаем серию публикаций об этих самых камнях. Предполагается, что возможности самого WF вам известны.
Возможно некоторые проблемы с WF возникают у нас из-за того, что мы неправильно его готовим и есть штатные способы их решить. Но так как я этих способов не знаю - для меня эти проблемы реальны.

Первая тем - отправка сообщений из WF о ходе его продвижения.

В WF есть готовы шаг по рассылки почтового сообщения на SAP-почту. Там довольно легко в мастере мышкой можно набрать что-то вроде "эй, мистер ZZZ, для заказа N XXX нужно бы цены пониже, согласуй?!".
Сразу подсказка: если создать почтовую задачу, а потом добавить в WF её же, но в качестве обычной задачи, то можно отправлять письмо на внешнюю почту.

Но есть у этого способа целый ряд существенных недостатков:
1. Весь WF вываливается в логическую ошибку если получатель не нашёлся, или даже нашёлся, но заблокирован. Возможно это как-то можно обойти, но я такого способа не знаю.
2. Если нужно подробное письмо с кучей данных о заказе (дебитор, сумма заказа и тд) - эти данные надо сначала получить в контейнер WF. А это ещё одна задача в потоке. Тоже касается получателей, если это не инициатор, а кто-то другой, его тоже надо выяснить специальной задачей.
3. Иногда отправлять надо только если выполняется какое-то условие, либо текст/получатель зависит от какого-то условия. Придётся добавлять ещё и шаги ветвления по этому условию. Возможно и задачу отправки придётся дублировать.
4. Иногда надо отправить сообщение разными способами (сап-почта, email, sms). Соответственно и задач будет несколько.
5. Иногда надо отправить задачи нескольким разным получателям с разным текстом. Ещё дополнительные шаги.
6. Эти шаги могут повторяться с небольшими отклонениями в нескольких различных WF. Копипаста логики.
7. Выходит, что этот замечательный мастер создания письма надо проходить множество раз, а он не такой уж и элементарный. Плюс когда что-то меняется надо не забыть поменять везде одинаково.
8. WF становится очень громоздким - на один шаг-действие приходится целая пачка вспомогательных шагов. Да и в контейнере потока чёрт ногу сломит.
9. Вся эта информация о работе WF, куча лишних шагов и переменных, это всё хранится в бд, что не лучшим способом сказывается на быстродействии.
10. Много кода по получению доп. данных, который надо сопровождать. Актуально только для тех переменных, которые получаются только для письме, но не влияют на сам бизнес-процесс.
11. Если вам понадобится какая-то более сложная структура письма, типа список строк заказа с несколькими параметрами, или письмо в формате HTML с красивыми табличками, картинками и сложным форматированием, или вообще приложенный PDF - у вас это всё скорее всего не выйдет или выйдет очень сложно.

Для борьбы с этим был придуман такой приём.
- Для всего WF (или даже группы родственных WF) для отправки сообщений создаётся один ФМ (ну или метод класса) и оборачивающая её задача WF.
- В задачу эту прокидывается минимально необходимый объём данных из контейнера (в нашем случае это только номер сбытового заказа).
- Ещё одним параметром будет "код события". То есть что только что случилось и о чём надо сообщить всех заинтересованных лиц.
- В самом ВФ везде, где надо что-то отправить, вставляется шаг с этой задачей с уникальным текстом в "код события". Такие шаги можно добавлять очень быстро, а поддержки больше не требуют.
- При желании в некоторых случаях можно встраивать вызов этого ФМ в сам код задачи-действия, а шаг в WF не делать. Тогда WF будет ещё менее громоздким.
Вся же умная логика, по отправке сосредоточена в одном ФМ/классе. А уже там вы можете делать что угодно, насколько гибко/просто/наглядно как вы хотите.
В моём случае это:
- в зависимости от события, вида заказа, различных условий вычисляемых по номеру заказа, выбираются типы получателей (например, "автор заказа", "менеджер дебитора", "логист по закупу материала", "транспортный менеджер", прочие роли в процессе) и способы отправки (сап-почта, email, sms).
- по заказу и типу получателя находятся адреса (имя получателя сап-почты, email, телефон)
- по заказу ищутся все необходимые данные для текста и делаются все необходимые проверки.
- по заказу и типу сообщения формируется текст сообщения. причём возможности тут гораздо богаче, чем в мастере.
- при желании можно приаттачить что угодно, например, выходную печатную форму документа.
- планируется добавить логирование всех этих данных, чтобы можно было посмотреть что кому когда уходило. в журнале WF всё не так наглядно.
И вся логика работы в пределах нескольких методов одного класса. Очень наглядно. Очень удобно сопровождать.
И WF выглядит гораздо понятнее. Что тоже очень большой плюс.
Подробнее...