Несмотря на то, что в 4.5.1 нет как такого инструментария для исправления и возобновления задач, в самом DIRECTUM все спроектировано так, что задача которая прекратилась на блоке (Вычисление
или др. блоке) видимо почти не отличается от задачи которая ожидает своей очереди на обработку службой Workflow. Возобновить прекращенную задачу можно задав ей признак
в работе(State=W) и разместив её в очередь в таблицу SBWorkflowProcessing.
Сделать это можно так (сценарий Возобновление упавшей задачи (л)):
UPDATE SBTask SET State='W' WHERE XRecID =%s
INSERT INTO SBWorkflowProcessing VALUES( %s, 0, null, 0, null, 0 )
Смело возобновляйте задачи, если они прекратились из-за ошибки не связанной с разработкой маршрута т.е. в том случае если ошибка связана с платформой. К таким случаям относятся ошибки вида «истекло время для обработки…» или, когда произошла нехватка памяти
на сервере, возникли перебои в работе SQL сервера или произошла ошибка в пакете .bpl платформы, такое случается очень редко, но на ранних версиях DIRECTUM это особенно неприятно т.к. нет явной возможности возобновить.
В тех случаях, когда задача прекратилась из-за ошибки, которая была допущена в разработке маршрута, нужно править непосредственно схему маршрута задачи.
В 4.5.1 отсутствуют инструменты для редактирования схемы запущенной задачи, но здесь у нас есть два варианта:
1-й вариант: мы можем воспользоваться инструментами более поздних версий DIRECTUM. Например, можно экспортировать схему маршрута из задачи 4.5.1 в задачу 4.9, поправить её там, вернуть в 4.5.1 и все скорее всего заработает. Workflow в лог
*proc.log «выругается» не незнакомые строковые константы, но задачу обработает.
2-й вариант: можно внести изменения непосредственно в XML схему маршрута используя текстовый редактор(желательно с подсветкой). Т.к. код вычислений хранится в кодировке mime/base64, предварительно такие участки нужно декодировать, а изменив
вычисления, закодировать схему маршрута обратно в mime/base64
Рассмотрим подробнее 1-й вариант:
Выгрузить текстовое описание схемы маршрута задачи можно следующим образом ( сценарий Выгрузить схему задачи (л) ):
задача = Tasks.GetObjectByID( <номер задачи> )
description = задача.WorkflowDescription
EditText( description )
Загрузить в задачу DIRECTUM, где уже разработаны инструменты ( сценарий Загрузить схему задачи (л) )
Task = Tasks.GetObjectByID( <номер задачи> )
task.WorkflowDescription = схема
task.Save
При выгрузке нужно указать номер задачи для редактирования, при загрузке укажите номер задачи, в которой будет выполняться редактирование. Текст переписки задачи не измениться, а вот схема будет присвоенная. Задача в которой будет
выполняться редактирование желательно должна быть по типовому маршруту, т.к. кнопка «Схема маршрута» будет отсутствовать для задачи не по маршруту. В той системе, в которой будет выполняться редактирование, придется завести все роли и всех пользователей, которые
были задействованы в ходе выполнения «подсаживаемой» задачи.
Показалось удобным работать через буфер обмена, поэтому 1-я обработка покажет схему в редакторе, копируйте в буфер, вставляйте в окно второй обработки, выполните редактирование нужных блоков и обработок и выгрузите/загрузите обратно из 4.x в 4.5.1. Воспользуйтесь
обработкой для возобновления задачи в 4.5. В логи sbworkflowproc.log служба вероятно выдаст ошибки вида,
31.01.2013 14:52:00 1244 UVKDIR ISBuilderSystem ESBLocalizationError Localization Error! There is no string with code "TASK_ACCESS_TYPE_ALL" (Group "SYSRES_SYSCOMP", language "Russian"). <- ...
но задача будет работать дальше.
Рассмотрим 2-й вариант, когда редактирование будет выполняться непосредственно в 4.5.1
Здесь будет непосредственно корректироваться текстовое описание маршрута задачи. Чтобы иметь возможно исправить вычисления или события блоков, эти участки схемы нужно предварительно декодировать из mime/base64.
Участки схемы, которые содержат вычисления выглядят примерно так
[CDATA[{5314B05F-CF9F-4F66-99EC-24992A5FB114}Ly/R7+jx7uog7+7r8/fg8uXr5ekg7/Dg4gpBbGxSb2xlcyA9IEFycmF5T2YoIAoizeD34Ov87ejqz93OIjsKIsTo8OXq8u
Для обработки данной кодировки нам понадобятся функции MimeEncodeString и MimeDecodeString, которые по сути появились в 4.6. В 4.5.1 они не работают, возвращают пустой результат.
MimeEncodeString для 4.5.1 можно описать примерно так
oXML = CreateObject("Msxml2.DOMDocument.3.0")
oNode = oXML.CreateElement("base64")
oNode.dataType = "bin.base64"
adTypeText = 2
adTypeBinary = 1
BinaryStream = CreateObject("ADODB.Stream")
BinaryStream.Type = adTypeText
BinaryStream.CharSet = "windows-1251"
BinaryStream.Open
BinaryStream.WriteText( строка )
BinaryStream.Position = 0
BinaryStream.Type = adTypeBinary
BinaryStream.Position = 0
oNode.nodeTypedValue = BinaryStream.Read
result = oNode.text
MimeDecodeString так
oXML = CreateObject("Msxml2.DOMDocument.3.0")
oNode = oXML.CreateElement("base64")
oNode.dataType = "bin.base64"
oNode.text = строка_mime
Binary = oNode.nodeTypedValue
adTypeText = 2
adTypeBinary = 1
BinaryStream = CreateObject("ADODB.Stream")
BinaryStream.Type = adTypeBinary
BinaryStream.Open
BinaryStream.Write( Binary )
BinaryStream.Position = 0
BinaryStream.Type = adTypeText
BinaryStream.CharSet = "windows-1251"
result = BinaryStream.ReadText
Получить схему маршрута можно следующим образом
task = Tasks.GetObjectByID( ид_задачи )
схема = task.WorkflowDescription
Раскодировать схему можно следующим образом: в качестве парсера XML используется стандартный COM объект IXMLDomDocument. Через XPath запрос, отбираем все узлы, которые содержат код обработок(вычисления, события). Узлы которые
содержат код вычислений, начинаются с указания GUID { XXXXXX-XXXXX-XXXXX }, далее следует текст обработки в кодировке mime/base64, это значение декодируется, а в конце XML документу выставляется
кодировка в windows-1251.
XMLDoc = CreateObject("MSXml.DomDocument")
XMLDoc.LoadXML( схема )
xmlDoc.setProperty("SelectionLanguage"; "XPath")
выбрать_все_коды = "//*[count(*)=0 and contains(.,'{')]"
все_узлы = xmlDoc.selectNodes( выбрать_все_коды ) //IXMLDomSelection
количество_узлов = все_узлы.length
все_узлы.reset
i = 0
while i < количество_узлов
узел_с_кодом = все_узлы.nextNode // IXMLDOMElement
текст_узла = узел_с_кодом.Text
guid = Copy( текст_узла; 1; 38 )
mime_text = Copy( текст_узла; 39; length( текст_узла ) - 38 )
if Assigned( mime_text )
mime_text = loc_MimeDecodeString( mime_text )
result_text = guid & mime_text
if узел_с_кодом.hasChildNodes
cdata = узел_с_кодом.childNodes.item(0)
if cdata.nodeType = 4
cdata.data = result_text
endif
endif
endif
i = i + 1
endwhile
результат_схема = xmlDoc.XML
правильная_кодировка = 'version="1.0" encoding="windows-1251" standalone="yes"'
неправильная_кодировка = 'version="1.0" standalone="yes"'
результат_схема = Replace( результат_схема; неправильная_кодировка; правильная_кодировка )
result = результат_схема
xmlDoc = nil
Кодирование происходит таким же образом, только вместо MimeDecodeString используется MimeEncodeString.
В прикрепленной разработке вы найдете сценарии и функции для того чтобы выполнить оба описанных варианта корректировки схемы задачи.
Используйте сценарии как инструменты:
* Сценарий Править схему задачи (л) используйте для того чтобы выполнить правку текстового описания задачи непосредственно в базе. Перед этим обязательно выполните резервирование оригинала схемы маршрута задачи при помощи сценария Выгрузить
схему задачи (л). Вы сможете восстановиться из копии используя обработку Загрузить схему задачи (л)
* Используйте сценарии Выгрузить схему задачи (л) и Загрузить схему задачи (л) соответственно в двух поставках DIRECTUM 4.5.1 и более старших DIRECTUM 4.x
Как распространить изменения
Самым простым способом распространить изменения в вычислениях событий, наверно, будет замена вычислений уже в закодированном виде.
Сценарий Распространить изменения маршрута (л) можно посмотреть как пример подобной пакетной правки.
Если будете исправлять вычисления задачи, имейте введу, что текущий исполняемый блок схемы дополнительно дублируется между тегами в конце схемы. Т.е. вычисления надо править два раза.
Описание функций
лЗадача_Возобновить( значение_номер_задачи ) — возобновляет прекращенную задачу. Для этого задаче выставляется состояние В работе, затем задача помещается в очередь на обработку Workflow службой.
лСхема_РаскодироватьОбработки( <текстовое описание схемы как есть в базе данных> ) — возвращает строку, раскодированный вариант схемы приведя вычисления схемы к понятному виду.
лСхема_ЗакодироватьОбработки( <текстовое описание схемы с раскодированными обработками> ) — возвращает строку, закодированную схему приведя все вычисления схемы к тому виду, в котором они хранятся в базе данных
Загрузки
Набор инструментов Возобновление задач 4.5.1.zip (11,05 Кб)
Ссылки
MimeStringEncode/Decode алгоритм взят отсюда http://stackoverflow.com/questions/496751/base64-encode-string-in-vbscript
Ссылки на доп. инструменты
Для приведения XML схемы задачи в иерархичный вид, можно использовать
онлайн инструмент
Для тестирования XPath запросов можно использовать
онлайн инструмент
P.S. Будьте предельно внимательны корректируя XML схему задачи
Я не знаю насколько эти инструменты совместимы с 4.5, 4.4. Если у вас есть возможность протестировать, пожалуйста, отпишитесь о результатах.
Другие материалы на тему работы со схемой
Экспорт/Импорт схемы задач из системы DIRECTUM средствами ISBL Дмитрия Тарасова
Экспорт/Импорт схемы задач из системы DIRECTUM Антона Калашникова
Атрибут реквизита |
Значение |
Имя |
WorkflowDescription |
Заголовок |
Описание процесса |
Имя поля |
WorkflowDescription |
Раздел |
Главный |
Сохраняемый |
Да |
Обязательный |
Нет |
Заполнять при копировании |
Да |
Тип |
Текст |
© 2011, Компания DIRECTUM Отправить комментарий к этому разделу на support@directum.ru |
Данную заметку, по-хорошему, следовало написать после того, как был бы подготовлен материал про создание потоков операций применительно к функциональности SAP Processes and Forms. Но что-то пошло не так. В этой заметке я хочу написать про распространенную ошибку, возникающую при настройке workflow в разрезе ASR процессов.
Вступление
Рассматриваем ситуацию, когда вы настроили поток операций, и приготовились к его первому запуску. Первый запуск выполнен без ошибок, о чем свидетельствуют и статус потока операций, и появившаяся задача в рабочем листе пользователя, который стал обработчиком этой задачи. Но после открытия задачи из рабочего списка, пользователь получаете сообщение об ошибке вида No step object GUID is assigned to the work item ID …
Стоит обратить внимание на то, что задача в рабочем списке пользователя, который назначен ее обработчиком, может выглядеть приблизительно следующим образом
Если описанные выше признаки схожи — значит что-то пошло не так. Обычно, такая ошибка свидетельствует о том что, в вашем потоке не заполнен обязательный элемент контейнера (или несколько элементов). В данном конкретном случае — это элемент STEP_OBJECT. Возможно, еще какой-то параметр пропущен. Об этом речь пойдет ниже.
Program Exit для задачи утверждения процесса
Работая с потоками операций в функциональности SAP Processes and Forms, вы будете использовать какие-либо из стандартных задач обработки/утверждения вашего процесса (либо их копии).
См. Task Group TG17900002: Interactive Components
Так, для демонстрации в этой заметке, при условии, что используются FPM формуляры, я задействовал в потоке операций задачу TS33700022
С помощью транзакции SWDD откройте ваш поток операций
Выберите задачу, с помощью которой пользователь должен согласовать заявку/процесс и перейдите на закладку Program Exits
Первая ошибка заключается в том, что в этой задаче не указан класс CL_HRASR00_POBJ_WF_EXIT
Process Control
If you use this task, you must also do the following tasks in the relevant workflow step:
Data flow of task container
Rule for agent determination with respective data flow to rule container
Programming exit CL_HRASR00_POBJ_WF_EXITСм. Standard Task TS33700022: Approve Form (Web Dynpro)
Настройка Binding для контейнера потока операций
В контейнере задачи, используемой для утверждения заявки, присутствует два обязательных элемента:
- Form
- Form_Scenario_Stage
Для элемента Form необходимо передать значение сценария, которое вы определили, создавая свой процесс. Посмотреть это наименование можно в транзакции HRASR_DT
Для элемента Form_Scenario_Stage необходимо определить значение шага процесса, которое также настраивается в транзакции HRASR_DT, применительно к вашему процессу
Выполните необходимые присвоения (binding) для указанных элементов.
N.B. Обратите внимание на то, что значение шага процесса в потоке операций необходимо прописать в одинарных кавычках.
На рисунке выше не указано значение для элемента Form, так как оно определяется при первоначальной настройке потока операций (то есть константа), и передается из задачи в задачу в течение всей жизни потока операций.
После выполнения описанных выше действий, активируйте поток операций и запустите заново. В рабочем списке пользователя (UWL), который по-прежнему является обработчиком вашего процесса, задача должна выглядеть следующим образом
Элементы STEP_OBJECT и Form_Scenario_Stage Step должны быть заполнены
Сама же заявка откроется без проблем (ну по крайней мере у меня так получилось)
PS
Чтобы не терять нить рассуждений по этой теме, а также соблюсти какую-то логичность публикуемого материала, я постараюсь в ближайшее время опубликовать заметку по первоначальной настройке потоков операций для FPM процесса. Спасибо за внимание.
Опубликовано fufler, 7 Фев 2011
В прошлый раз был рассмотрен пример создания простого бизнес-процесса. В этой статье хочу рассмотреть несколько модифицированный вариант: во-первых, предлагаю добавить отправку уведомлений по почте по мере прохождения статьи по пути согласования; во-вторых, создать интерфейс для работы с бизнес-процессом в Alfresco Share
Для начала нужно определиться, что конкретно потребуется сделать для реализации заявленного функционала. Нам понадобится новое свойство, в котором будем хранить хранить ответ пользователя на вопрос «Присылать уведомления?». Это свойство мы добавим к start-task:
<!-- Свойства --> <properties> <!-- Присылать письма --> <property name="tcwf:notifyMe"> <type>d:boolean</type> <default>false</default> </property> </properties>
Также дадим возможность редактору и корректоу писать комментарии к статье по ходу рассмотрения, для этого добавим новый аспект к CorrectTask, EditTask и ReviseTask(чтобы и пользователь мог прочитать эти комментарии):
<!-- Комментарий --> <aspect>tcwf:commentAspect</aspect>
Ну и добавим описание нового аспекта:
<aspect name="tcwf:commentAspect"> <title>TrashCo commentable aspect</title> <properties> <property name="tcwf:comments"> <type>d:text</type> <mandatory>false</mandatory> <multiple>false</multiple> </property> </properties> </aspect>
Таким образом, модель данных теперь выглядит вот так (extension/tcWorkflowModel.xml):
<?xml version="1.0" encoding="UTF-8"?> <!-- Описание модели бизнес-процесса --> <model name="tcwf:workflowmodel" xmlns="http://www.alfresco.org/model/dictionary/1.0"> <!-- Необязательные метаданные модели --> <description>TrashCo Workflow Model</description> <author>lx</author> <version>0.0</version> <!-- Импорт необходимых описаний --> <imports> <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" /> <import uri="http://www.alfresco.org/model/bpm/1.0" prefix="bpm" /> </imports> <!-- Описываем пространство имен для нашего процесса --> <namespaces> <namespace uri="http://www.trashco.com/model/workflow/1.0" prefix="tcwf" /> </namespaces> <types> <!-- Подача статьи --> <type name="tcwf:submitTask"> <!-- Наследуем от bpm:startTask --> <parent>bpm:startTask</parent> <!-- Свойства --> <properties> <!-- Присылать письма --> <property name="tcwf:notifyMe"> <type>d:boolean</type> <default>false</default> </property> </properties> <!-- Указываем обязательные аспекты --> <mandatory-aspects> <!-- Редактор --> <aspect>bpm:assignee</aspect> <!-- Статья может быть опубликована online --> <aspect>tcwf:webable</aspect> </mandatory-aspects> </type> <!-- Корректирование статьи --> <type name="tcwf:correctTask"> <!-- Наследуем от bpm:workflowTask --> <parent>bpm:workflowTask</parent> <!-- Документ может быть отредактирован --> <overrides> <property name="bpm:packageItemActionGroup"> <default>edit_package_item_actions</default> </property> </overrides> <mandatory-aspects> <!-- Статья может быть опубликована online --> <aspect>tcwf:webable</aspect> <!-- Комментарий --> <aspect>tcwf:commentAspect</aspect> </mandatory-aspects> </type> <!-- Техническое редактирование статьи --> <type name="tcwf:editTask"> <!-- Наследуем от bpm:workflowTask --> <parent>bpm:workflowTask</parent> <!-- Документ может быть отредактирован --> <overrides> <property name="bpm:packageItemActionGroup"> <default>edit_package_item_actions</default> </property> </overrides> <mandatory-aspects> <!-- Статья может быть опубликована online --> <aspect>tcwf:webable</aspect> <!-- Комментарий --> <aspect>tcwf:commentAspect</aspect> </mandatory-aspects> </type> <!-- Доработка статьи --> <type name="tcwf:reviseTask"> <!-- Наследуем от bpm:workflowTask --> <parent>bpm:workflowTask</parent> <!-- Документ может быть отредактирован --> <overrides> <property name="bpm:packageItemActionGroup"> <default>edit_package_item_actions</default> </property> </overrides> <mandatory-aspects> <!-- Статья может быть опубликована online --> <aspect>tcwf:webable</aspect> <!-- Комментарий --> <aspect>tcwf:commentAspect</aspect> </mandatory-aspects> </type> <!-- Публикация статьи --> <type name="tcwf:publishTask"> <!-- Наследуем от bpm:workflowTask --> <parent>bpm:workflowTask</parent> <!-- Документ может быть только просмотрен --> <overrides> <property name="bpm:packageItemActionGroup"> <default>read_package_item_actions</default> </property> </overrides> <mandatory-aspects> <!-- Статья может быть опубликована online --> <aspect>tcwf:webable</aspect> </mandatory-aspects> </type> </types> <!-- Описываем аспекты, которые будем использовать --> <aspects> <!-- Статью можно опубликовать online --> <aspect name="tcwf:webable"> <title>TrashCo webable aspect</title> <properties> <property name="tcwf:publishOnline"> <type>d:boolean</type> <mandatory>true</mandatory> <multiple>false</multiple> </property> </properties> </aspect> <aspect name="tcwf:commentAspect"> <title>TrashCo commentable aspect</title> <properties> <property name="tcwf:comments"> <type>d:text</type> <mandatory>false</mandatory> <multiple>false</multiple> </property> </properties> </aspect> </aspects> </model>
Теперь добавим в бизнес-процесс код, отвечающий за отправку уведомлений. Внутри javascript-кода переменные, объявленные в модели доступны в виде <префикс>_<имя> (к примеру, tcwf:notifyMe доступна как tcwf_notifyMe). Для отправки писем (как и для многих других вещей) в Alfresco используется механизм действий (actions). Вот таким образом нужно изменить CorrectTask, чтобы инициатор стал получать письма:
<task-node name="CorrectTask"> <!-- Задача для корректора --> <task name="tcwf:correctTask" swimlane="corrector" /> <!-- Одобрить статью --> <transition name="approve" to="EditTask"> <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> <!-- Отправляем уведомление --> <script> <![CDATA[ logger.log("PublishPaperProcess: Approved"); if (tcwf_notifyMe) { var mail = actions.create("mail"); mail.parameters.to = initiator.properties["cm:email"]; mail.parameters.subject = "Публикация статьи"; mail.parameters.text = "Добрый день.nnВаша статья прошла проверку редактора и отправлена техническому редактору на рассмотрение."; mail.execute(bpm_package); } ]]> </script> </action> </transition> <!-- Отклонить статью --> <transition name="reject" to="ReviseTask"> <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> <!-- Отправляем уведомление --> <script> <![CDATA[ logger.log("PublishPaperProcess: Rejected"); if (tcwf_notifyMe) { var mail = actions.create("mail"); mail.parameters.to = initiator.properties["cm:email"]; mail.parameters.subject = "Публикация статьи"; mail.parameters.text = "Добрый день.nnВаша статья не прошла проверку редактора и нуждается в доработке. nnКомментарии:n"+ tcwf_comments; mail.execute(bpm_package); } ]]> </script> </action> </transition> </task-node>
Как видно из кода, делается это достаточно просто. Внутрь <transition> добавляется скрипт, который срабатывает при соответствующем переходе. Внутри скрипта мы проверяем, нужно ли отправлять письмо: если да, то заполняем соответствующие поля письма и отправляем его. Всё просто, но не совсем Есть один неприятный момент: Alfresco отправляет письма от имени того пользователя, который инициировал переход (на багзилле это значится как «expected behaviour, not a bug»). Таким образом, отсылать письма с отправителем вида noreply@somehost.zz становится затруднительно. Могу предложить такие методы решение:
- использовать хорошо настроенный локальный почтовый сервер, который при отправке изменяет соответствующие поля
- использовать внешний сервер (gmail.com, например), но в таком случае отправитель будет @gmail.com ,что тоже не очень хорошо
- прописать всем пользователям системы одинаковый адрес email
- написать свой класс для отправки почты
Таким образом, файл (extension/workflows/PublishPaperProcess.xml) с описанием бизнес-процесса теперь выглядит вот так:
<?xml version="1.0" encoding="UTF-8"?> <!-- Начало описания процесса --> <process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="tcwf:publishpaper"> <!-- Исполнитель "инициатор" --> <swimlane name="initiator" /> <!-- Исполнитель "корректор", выбирается из группы correctors --> <swimlane name="corrector"> <assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment"> <pooledactors>#{people.getGroup('GROUP_correctors')}</pooledactors> </assignment> </swimlane> <!-- Исполнитель "редактор", выбирается при создании процесса --> <swimlane name="editor"> <assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment"> <actor>#{bpm_assignee}</actor> </assignment> </swimlane> <!-- Исполнитель "издатель", выбирается из группы publishers --> <swimlane name="publisher"> <assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment"> <pooledactors>#{people.getGroup('GROUP_publishers')}</pooledactors> </assignment> </swimlane> <!-- Начальный узел процесса --> <start-state name="Start"> <!-- Задание для инициатора --> <task name="tcwf:submitTask" swimlane="initiator" /> <!-- Подать статью на рассмотрение --> <transition name="" to="Submit" /> </start-state> <!-- Подача статьи на рассмотрение --> <node name="Submit"> <!-- Передать корректору --> <transition name="" to="CorrectTask"/> </node> <!-- Корректирование статьи --> <task-node name="CorrectTask"> <!-- Задача для корректора --> <task name="tcwf:correctTask" swimlane="corrector" /> <!-- Одобрить статью --> <transition name="approve" to="EditTask"> <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> <!-- Отправляем уведомление --> <script> <![CDATA[ logger.log("PublishPaperProcess: Approved"); if (tcwf_notifyMe) { var mail = actions.create("mail"); mail.parameters.to = initiator.properties["cm:email"]; mail.parameters.subject = "Публикация статьи"; mail.parameters.text = "Добрый день.nnВаша статья прошла проверку редактора и отправлена техническому редактору на рассмотрение."; mail.execute(bpm_package); } ]]> </script> </action> </transition> <!-- Отклонить статью --> <transition name="reject" to="ReviseTask"> <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> <!-- Отправляем уведомление --> <script> <![CDATA[ logger.log("PublishPaperProcess: Rejected"); if (tcwf_notifyMe) { var mail = actions.create("mail"); mail.parameters.to = initiator.properties["cm:email"]; mail.parameters.subject = "Публикация статьи"; mail.parameters.text = "Добрый день.nnВаша статья не прошла проверку редактора и нуждается в доработке. nnКомментарии:n"+ tcwf_comments; mail.execute(bpm_package); } ]]> </script> </action> </transition> </task-node> <!-- Техническое редактирование статьи --> <task-node name="EditTask"> <!-- Задача для редактора --> <task name="tcwf:editTask" swimlane="editor" /> <!-- Одобрить статью --> <transition name="approve" to="PublishTask"> <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> <!-- Отправляем уведомление --> <script> <![CDATA[ logger.log("PublishPaperProcess: Approved2"); if (tcwf_notifyMe) { var mail = actions.create("mail"); mail.parameters.to = initiator.properties["cm:email"]; mail.parameters.subject = "Публикация статьи"; mail.parameters.text = "Добрый день.nnВаша статья прошла проверку технического редактора и отправлена на публикацию."; mail.execute(bpm_package); } ]]> </script> </action> </transition> <!-- Отклонить статью --> <transition name="reject" to="ReviseTask"> <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> <!-- Отправляем уведомление --> <script> <![CDATA[ logger.log("PublishPaperProcess: Rejected2"); if (tcwf_notifyMe) { var mail = actions.create("mail"); mail.parameters.to = initiator.properties["cm:email"]; mail.parameters.subject = "Публикация статьи"; mail.parameters.text = "Добрый день.nnВаша статья не прошла проверку технического редактора и нуждается в доработке. nnКомментарии:n"+ tcwf_comments; mail.execute(bpm_package); } ]]> </script> </action> </transition> </task-node> <!-- Доработка статьи --> <task-node name="ReviseTask"> <!-- Задача для инициатора --> <task name="tcwf:reviseTask" swimlane="initiator" /> <!-- Подать статьи повторно --> <transition name="resubmit" to="Submit" /> <!-- Отменить процесс публикации статьи --> <transition name="cancel" to="End" /> </task-node> <!-- Публикация статьи --> <task-node name="PublishTask"> <!-- Задача для издателя --> <task name="tcwf:publishTask" swimlane="publisher" /> <!-- Конец процесса --> <transition name="done" to="End"> <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> <!-- Отправляем уведомление --> <script> <![CDATA[ logger.log("PublishPaperProcess: Published"); if (tcwf_notifyMe) { var mail = actions.create("mail"); mail.parameters.to = initiator.properties["cm:email"]; mail.parameters.subject = "Публикация статьи"; mail.parameters.text = "Добрый день.nnВаша статья опубликована."; mail.execute(bpm_package); } ]]> </script> </action> </transition> </task-node> <!-- Последний узел --> <end-state name="End"/> </process-definition> <!-- Конец описания процесса -->
Если для отправки почты мы используем действия, то нужно настроить соответствующим образом Alfresco ( alfresco-global.properties и extension/custom-email-context.xml):
mail.host=localhost #mail.username= #mail.password= mail.port=25 mail.protocol=smtp mail.smtps.starttls.enable=false mail.smtps.auth=false
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'> <beans> <!-- Указываем, откуда брать параметры почтового сервера --> <bean id="mailService" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="host"> <value>${mail.host}</value> </property> <property name="port"> <value>${mail.port}</value> </property> <property name="protocol"> <value>${mail.protocol}</value> </property> <property name="username"> <value>${mail.username}</value> </property> <property name="password"> <value>${mail.password}</value> </property> <property name="defaultEncoding"> <value>${mail.encoding}</value> </property> <property name="javaMailProperties"> <props> <prop key="mail.smtps.auth">${mail.smtps.auth}</prop> <prop key="mail.smtps.starttls.enable">${mail.smtps.starttls.enable}</prop> </props> </property> </bean> </beans>
После того, как код отправки уведомлений написан, нужно настроить пользовательский интерфейс. Ниже я привел конфигурационный файл web-extension/share-custom-config.xml, отвечающий за то, как этот бизнес-процесс будет выглядеть в Alfresco Share. В файле присутствуют минимальные комментарии, которых, как мне кажется, вполне достаточно для осознания происходящего
<!-- Настройки интерфейса --> <alfresco-config> <!-- Отображение информации при просмотре бизнес-процесса --> <config evaluator="string-compare" condition="jbpm$tcwf:publishpaper"> <forms> <form> <!-- Список видимых полей --> <field-visibility> <show id="bpm:workflowDescription" /> <show id="bpm:assignee"/> <show id="packageItems" /> <show id="tcwf:publishOnline" /> <show id="tcwf:notifyMe" /> </field-visibility> <appearance> <!-- Блоки --> <set id="" appearance="title" label-id="workflow.set.general" /> <set id="assignee" appearance="title" label-id="tcwf_assignee" /> <set id="items" appearance="title" label-id="tcwf_items" /> <!-- Отображение полей --> <field id="bpm:workflowDescription" label-id="tcwf_description"> <control template="/org/alfresco/components/form/controls/textarea.ftl"> <control-param name="style">width: 95%</control-param> </control> </field> <field id="tcwf:publishOnline" label-id="tcwf_publish_online" /> <field id="tcwf:notifyMe" label-id="tcwf_notify_me" /> <field id="bpm:assignee" label-id="tcwf_assign_to" set="assignee" /> <field id="packageItems" set="items" label="" /> </appearance> </form> </forms> </config> <!-- Подача статьи на рассмотрение --> <config evaluator="task-type" condition="tcwf:submitTask"> <forms> <form id="workflow-details"> <!-- Список видимых полей --> <field-visibility> <show id="tcwf:publishOnline" /> <show id="packageItems" /> </field-visibility> <appearance> <!-- Блоки --> <set id="" appearance="title" label-id="workflow.set.workflow.more_info" /> <set id="items" appearance="title" label-id="tcwf_items" /> <!-- Отображение полей --> <field id="tcwf:publishOnline" label-id="tcwf_publish_online"/> <field id="packageItems" set="items" label="tcwf_items_list"/> </appearance> </form> </forms> </config> <!-- Корректирование статьи --> <config evaluator="task-type" condition="tcwf:correctTask"> <forms> <form> <!-- Список видимых полей --> <field-visibility> <show id="bpm:taskId" /> <show id="bpm:status" /> <show id="packageItems" /> <show id="transitions" /> <show id="tcwf:publishOnline"/> <show id="tcwf:comments"/> </field-visibility> <appearance> <!-- Блоки --> <set id="" appearance="title" label-id="workflow.set.task.info" /> <set id="info" appearance="" template="/org/alfresco/components/form/3-column-set.ftl" /> <set id="items" appearance="title" label-id="tcwf_items" /> <set id="progress" appearance="title" label="" /> <set id="response" appearance="title" label-id="workflow.set.response" /> <!-- Отображение полей --> <field id="bpm:taskId" set="info" label-id="tcwf_task_id"> <control template="/org/alfresco/components/form/controls/info.ftl" /> </field> <field id="tcwf:comments" label-id="tcwf_comments" set="items"/> <field id="bpm:status" set="progress" label-id="tcwf_status"/> <field id="packageItems" set="items" label-id="tcwf_items_list"/> <field id="tcwf:publishOnline" label-id="tcwf_publish_online" set="items" read-only="true"/> <field id="transitions" set="response" /> </appearance> </form> </forms> </config> <!-- Техническое редактирование статьи --> <config evaluator="task-type" condition="tcwf:editTask"> <forms> <form> <!-- Список видимых полей --> <field-visibility> <show id="bpm:taskId" /> <show id="bpm:status" /> <show id="packageItems" /> <show id="transitions" /> <show id="tcwf:publishOnline"/> <show id="tcwf:comments"/> </field-visibility> <appearance> <!-- Блоки --> <set id="" appearance="title" label-id="workflow.set.task.info" /> <set id="info" appearance="" template="/org/alfresco/components/form/3-column-set.ftl" /> <set id="items" appearance="title" label-id="tcwf_items" /> <set id="progress" appearance="title" label="" /> <set id="response" appearance="title" label-id="workflow.set.response" /> <!-- Отображение полей --> <field id="bpm:taskId" set="info" label-id="tcwf_task_id"> <control template="/org/alfresco/components/form/controls/info.ftl" /> </field> <field id="tcwf:publishOnline" label-id="tcwf_publish_online" set="items"/> <field id="tcwf:comments" label-id="tcwf_comments" set="items"/> <field id="bpm:status" set="progress" label-id="tcwf_status"/> <field id="packageItems" set="items" label-id="tcwf_items_list"/> <field id="transitions" set="response" /> </appearance> </form> </forms> </config> <!-- Публикация статьи --> <config evaluator="task-type" condition="tcwf:publishTask"> <forms> <form> <!-- Список видимых полей --> <field-visibility> <show id="bpm:taskId" /> <show id="bpm:status" /> <show id="packageItems" /> <show id="transitions" /> <show id="tcwf:publishOnline"/> </field-visibility> <appearance> <!-- Блоки --> <set id="" appearance="title" label-id="workflow.set.task.info" /> <set id="info" appearance="" template="/org/alfresco/components/form/3-column-set.ftl" /> <set id="items" appearance="title" label-id="tcwf_items" /> <set id="progress" appearance="title" label="" /> <set id="response" appearance="title" label-id="workflow.set.response" /> <!-- Отображение полей --> <field id="bpm:taskId" set="info" label-id="tcwf_task_id"> <control template="/org/alfresco/components/form/controls/info.ftl" /> </field> <field id="tcwf:publishOnline" label-id="tcwf_publish_online" set="items" read-only="true"/> <field id="bpm:status" set="progress" label-id="tcwf_status"/> <field id="packageItems" set="items" label-id="tcwf_items_list"/> <field id="transitions" set="response" /> </appearance> </form> </forms> </config> <!-- Доработка статьи --> <config evaluator="task-type" condition="tcwf:reviseTask"> <forms> <form> <!-- Список видимых полей --> <field-visibility> <show id="bpm:taskId" /> <show id="bpm:status" /> <show id="packageItems" /> <show id="transitions" /> <show id="tcwf:publishOnline"/> <show id="tcwf:comments" /> </field-visibility> <appearance> <!-- Блоки --> <set id="" appearance="title" label-id="workflow.set.task.info" /> <set id="info" appearance="" template="/org/alfresco/components/form/3-column-set.ftl" /> <set id="items" appearance="title" label-id="tcwf_items" /> <set id="progress" appearance="title" label="" /> <set id="response" appearance="title" label-id="workflow.set.response" /> <!-- Отображение полей --> <field id="bpm:taskId" set="info" label-id="tcwf_task_id"> <control template="/org/alfresco/components/form/controls/info.ftl" /> </field> <field id="tcwf:publishOnline" label-id="tcwf_publish_online" set="items"/> <field id="bpm:status" set="progress" label-id="tcwf_status"/> <field id="packageItems" set="items" label-id="tcwf_items_list"/> <field id="tcwf:comments" label-id="tcwf_comments" set="items"/> <field id="transitions" set="response" /> </appearance> </form> </forms> </config> </alfresco-config>
Вот так теперь выглядит бизнес процесс публикации статьи:
Прикрепленные файлы | Размер |
---|---|
publish_paper_pt2.zip | 10.75 кб |
- Alfresco
- javascript
- workflow
- документооборот
- Для технарей
- fufler’s блог
Cправка — Профиль компании в Google
Войти
Справка Google
- Справочный центр
- Сообщество
- Профиль компании в Google
- Политика конфиденциальности
- Условия предоставления услуг
- Отправить отзыв
Тема отзыва
Информация в текущем разделе Справочного центра
Общие впечатления о Справочном центре Google
- Справочный центр
- Сообщество
Профиль компании в Google