I recently made my first foray into Alfresco advanced Activiti workflow. I started with this excellent tutorial by Jeff Potts and ended up extending the HelloWorldUI example from the tutorial in order to meet the goals of my workflow. There were a few areas where I had a hard time figuring out how to put the pieces together to get the results I wanted, so this blog post includes some of the lessons I learned along the way.

The goals of my workflow

The workflow I wanted to write followed the basic review-and-approve pathway with one primary addition: it needed to collect some information on the workflow start page that would be used to populate a change log data list when the document was approved. I wanted the workflow start page to include fields for the starting user to populate, and then I wanted the values of those fields to be displayed on the workflow review page so that the reviewer could see them but not edit them. After the reviewer approved the document, I wanted a change log entry to be created as a new row in a change log data list.

Getting custom fields onto the workflow start page

Getting the change log fields to show up on the workflow start page turned out to be easy. My workflow definition had a process id of myCompanyReviewAndApprove and I had created a custom model containing a custom type named xyz:myCompanyReviewAndApproveTaskcontaining the change log properties I wanted. I then used activiti:formKey=“xyz:myCompanyReviewAndApproveTask” on the startEvent in my workflow definition to give my start page access to the custom properties. In share-config-custom.xml, which governs all custom form UI including workflow pages, I created a config entry with condition=“activiti$myCompanyReviewAndApprove” to match the process id of my workflow definition. In this config entry I included the change log properties from xyz:myCompanyReviewAndApproveTask.

myCompanyReviewAndApprove.bpmn20.xml

<process id=“myCompanyReviewAndApprove" name=“My Company Review and Approve"isExecutable="true">

<startEvent id="startevent1" name="Start"activiti:formKey=“xyz:myCompanyReviewAndApproveTask"></startEvent>

share-config-custom.xml

<!-- This form defines the MyCompany Review and Approve workflow start page -->
<config evaluator="string-compare" condition=“activiti$myCompanyReviewAndApprove">
<forms>
<form>
<field-visibility>
<show id="packageItems" />
<show id="bpm:assignee" />
<show id=“xyz:changeType" />
<show id=“xyz:changeSeverity" />
<show id=“xyz:changeAffectedVersion" />
<show id=“xyz:changeComment" />
<show id="cm:categories" />
<show id="transitions" />
</field-visibility>
<appearance>
<set id="assignee" appearance="title" label-id="workflow.set.assignee" />
<set id="changelog" appearance="title" label-id="workflow.set.task.changelog"/>
<set id="items" appearance="title" label-id="workflow.set.items" />
<set id="other" appearance="title" label-id="workflow.set.other" />
<field id="packageItems" set="items" />
<field id="bpm:assignee" label-id="workflow.field.assign_to" set="assignee" />
<field id=“xyz:changeType" set="changelog" />
<field id=“xyz:changeSeverity" set="changelog" />
<field id=“xyz:changeAffectedVersion" set="changelog" />
<field id=“xyz:changeComment" set="changelog" />
<field id="cm:categories" set="changelog">
<control>
<control-param name="compactMode"> true</control-param>
</control>
</field>
</appearance>
</form>
</forms>

</config>

Getting the custom fields onto the workflow review page

I had some trouble getting the change log fields to show up on the workflow review page. For the userTask representing the review of the content, I started out usingactiviti:formKey=“wf:activitiReviewTask” based on a tutorial example I was starting from. This gave me the standard Approve and Reject buttons on the review page, as desired, but it didn’t give me the custom fields representing the change log information because there was no connection to my custom model type. Next I tried using activiti:formKey=“xyz:myCompanyReviewAndApproveTask”, just like on the startEvent for the workflow. This gave me the change log fields, but I no longer had theApprove and Reject buttons.

I tried a few things like adding a review outcome property to my custom type, but ultimately the solution was much simpler than the things I was trying; all I needed to do was give my custom type xyz:myCompanyReviewAndApproveTask a parent of wf:activitiReviewTask. Once I did this, I was able to use activiti:formKey=“xyz:myCompanyReviewAndApproveTask” and have access to my custom fields, as before, plus I also had access to thewf:reviewOutcome field from the parent type. I created a second config section in share-config-custom.xml with condition=“xyz:myCompanyReviewAndApproveTask” and made the change log fields plus the wf:reviewOutcome field visible. In addition, I made the change log fields appear as plain text values rather than controls by setting them to read-only=“true” and using the control template of /org/alfresco/components/form/controls/info.ftl.

myCompanyWorkflowModel.xml

<type name=“xyz:myCompanyReviewAndApproveTask">
<parent>wf:activitiReviewTask</parent>
<properties>
...

share-config-custom.xml

<!-- This form defines the MyCompany Review and Approve workflow review page -->
<config evaluator="task-type" condition=“xyz:myCompanyReviewAndApproveTask">
<forms>
<form>
<field-visibility>
<show id="taskOwner" />
<show id=“xyz:changeType" />
<show id=“xyz:changeSeverity" />
<show id=“xyz:changeAffectedVersion" />
<show id=“xyz:changeComment" />
<show id="cm:categories" />
<show id="bpm:status" />
<show id="packageItems" />
<show id="wf:reviewOutcome" />
</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="progress" appearance="title" label-id="workflow.set.task.progress" />
<set id="changelog" appearance="title" label-id="workflow.set.task.changelog"/>
<set id="items" appearance="title" label-id="workflow.set.items" />
<set id="response" appearance="title" label-id="workflow.set.response" />
<field id="taskOwner" set="info" />
<field id=“xyz:changeType" set="changelog" read-only="true" >
<control template="/org/alfresco/components/form/controls/info.ftl" />
</field>
<field id=“xyz:changeSeverity" set="changelog" read-only="true" >
<control template="/org/alfresco/components/form/controls/info.ftl" />
</field>
<field id=“xyz:changeAffectedVersion" set="changelog" read-only="true" >
<control template="/org/alfresco/components/form/controls/info.ftl" />
</field>
<field id=“xyz:changeComment" set="changelog" read-only="true" >
<control template="/org/alfresco/components/form/controls/info.ftl" />
</field>
<field id="cm:categories" set="changelog" read-only="true">
<control>
<control-param name="compactMode"> true</control-param>
</control>
</field>
<field id="bpm:status" set="progress" />
<field id="packageItems" set="items" />

<field id="wf:reviewOutcome" label-id="workflow.field.outcome" set="response">
<controltemplate="/org/alfresco/components/form/controls/workflow/activiti-transitions.ftl" />
</field>
</appearance>
</form>
</forms>
</config>

Creating a data list entry within a workflow serviceTask

Once the reviewer of my workflow approved the document, I needed to create a new datalist item to represent my change log entry. To do this, I needed to give my serviceTask an activiti:class value of “org.alfresco.repo.workflow.activiti.script.AlfrescoScriptDelegate” so that I could run Javascript within an activiti:string extension element.

Before my Javascript to create the datalist would work, I needed two more things. First, I needed to run this Javascript as an administrator. That’s because I needed to create the change log entry even if the Alfresco user who performed the review didn’t have write access to data lists within that site. To do this, I needed to add a runAs activiti:field extension element to the task with a value of admin.

The second thing I needed was access to the value of the review outcome, so that I could create the data list entry only if the reviewer approved the document and do nothing if the document was rejected. To gain access to that value, I needed to add anactiviti:taskListener extension element on the complete event to set the review outcome as a variable.

myCompanyReviewAndApprove.bpmn20.xml - userTask

<activiti:taskListener event="complete"class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
execution.setVariable('wf_reviewOutcome', task.getVariable('wf_reviewOutcome'));
</activiti:string>
</activiti:field>

</activiti:taskListener>

myCompanyReviewAndApprove.bpmn20.xml - serviceTask

<serviceTask id="alfrescoScripttask1" name="Alfresco Script Task"activiti:class="org.alfresco.repo.workflow.activiti.script.AlfrescoScriptDelegate">
<extensionElements>
<activiti:field name="runAs"><activiti:string> admin</activiti:string></activiti:field>
<activiti:field name="script">
<activiti:string>
logger.log("The outcome of the review task is: " + wf_reviewOutcome + "\n");
logger.log("changeType value is: " + xyz_changeType);
logger.log("changeSeverity value is: " + xyz_changeSeverity);
logger.log("changeAffectedVersion: " + xyz_changeAffectedVersion);

….

Once I had those two things in place, I was able to check whether the value of wf_reviewOutcome was “Approve”, and if so, I was able to use the Alfresco Javascript API to create a data list of the correct type if one didn’t already exist, and then create a new entry in the data list.

Getting the correct task title in the My Tasks dashlet, instead of (No Message)

After I had everything working as designed for my workflow, I ran into one last problem. In the My Tasks dashlet, the task title showed up as (No Message). Back when I had been using activiti:formKey=“wf:activitiReviewTask” on my userTask, the task title in the dashlet had been the value of the name property on my workflow process. After I changed to using activiti:formKey=“xyz:myCompanyReviewAndApproveTask” in order to get my custom change log fields to appear on the review page, the task title started showing up as (No Message). This was not good!

The solution to this problem was to set the bpm_workflowDescription variable in an extensionElement on my userTask. The value of this variable then appeared as the task title in the My Tasks dashlet, and the name property of the userTask appeared as the subtitle:

<userTask id="alfrescoUsertask1" name="Review Document and Approve or Reject"activiti:assignee="${bpm_assignee.properties.userName}"activiti:formKey=“xyz:myCompanyReviewAndApproveTask">
<extensionElements>
<activiti:taskListener event="create"class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
task.setVariable("bpm_workflowDescription", “My Company Content Review");
</activiti:string>
</activiti:field>

</activiti:taskListener>

Once I solved the problem with the task title, my workflow looked and functioned exactly the way I wanted it to. Hopefully if you've run into any of these problems, you've been able to find a quick solution here.


Loading Conversation