Based on the example kindly provided by Mr. Potts, I've developed the system of the contracts approval.
Business process in BPMN notation is presented below.
By Activiti Eclipse BPMN 2.0 Designer:
The scheme of a running business process in Alfresco:
For creating activiti diagrams I used Activiti Eclipse BPMN 2.0 Designer 5.18. Here is a description of the process that was generated by this plug-in:
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="contractsApproval" name="Contracts Approval" isExecutable="true">
<startEvent id="startevent1" name="Start" activiti:formKey="scwf:submitReviewTask"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="Approval of the first group" activiti:candidateGroups="GROUP_First" activiti:formKey="scwf:activitiFirstReview">
<extensionElements>
<activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string><![CDATA[if(task.getVariableLocal('scwf_approveRejectOutcome') == 'Approve') {
var newApprovedCount = scwf_approveCount + 1;
execution.setVariable('scwf_approveCount', newApprovedCount);
}]]></activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
</userTask>
<userTask id="usertask3" name="Revise" activiti:assignee="${initiator.properties.userName}" activiti:formKey="scwf:activitiRevise">
<extensionElements>
<activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string><![CDATA[if(task.getVariableLocal('scwf_reviseOutcome') == 'Re-submit') {
execution.setVariable('scwf_resubmit', true);
} else {
execution.setVariable('scwf_resubmit', false);
}]]></activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
</userTask>
<userTask id="usertask4" name="Approval of the second group" activiti:candidateGroups="GROUP_Second" activiti:formKey="scwf:activitiSecondReview">
<extensionElements>
<activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string><![CDATA[if(task.getVariableLocal('scwf_approveRejectOutcome') == 'Approve') {
var newApprovedCount = scwf_approveCount + 1;
execution.setVariable('scwf_approveCount', newApprovedCount);
}
]]></activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
</userTask>
<serviceTask id="scripttask1" name="Send a document for approval" activiti:class="org.alfresco.repo.workflow.activiti.script.AlfrescoScriptDelegate">
<extensionElements>
<activiti:field name="runAs">
<activiti:string><![CDATA[admin]]></activiti:string>
</activiti:field>
<activiti:field name="script">
<activiti:string><![CDATA[execution.setVariable('scwf_approveCount', 0);
execution.setVariable('scwf_tpApproved', false);]]></activiti:string>
</activiti:field>
</extensionElements>
</serviceTask>
<parallelGateway id="parallelgateway1" name="Parallel Gateway"></parallelGateway>
<parallelGateway id="parallelgateway2" name="Parallel Gateway"></parallelGateway>
<exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="scripttask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="scripttask1" targetRef="parallelgateway1"></sequenceFlow>
<sequenceFlow id="flow3" sourceRef="parallelgateway1" targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow4" sourceRef="parallelgateway1" targetRef="usertask4"></sequenceFlow>
<sequenceFlow id="flow5" sourceRef="usertask1" targetRef="parallelgateway2"></sequenceFlow>
<sequenceFlow id="flow6" sourceRef="usertask4" targetRef="parallelgateway2"></sequenceFlow>
<sequenceFlow id="flow7" sourceRef="parallelgateway2" targetRef="exclusivegateway1"></sequenceFlow>
<sequenceFlow id="flow9" sourceRef="exclusivegateway1" targetRef="usertask3">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${scwf_approveCount < 2}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow13" sourceRef="usertask3" targetRef="scripttask1">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${scwf_resubmit == true}]]></conditionExpression>
</sequenceFlow>
<userTask id="usertask5" name="Approved Notification" activiti:assignee="${initiator.properties.userName}" activiti:formKey="scwf:activitiApprovedNotification">
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string><![CDATA[var setWebFlagAction = actions.create("set-web-flag");
setWebFlagAction.parameters["active"] = true;
for (var i = 0; i < bpm_package.children.length; i++) {
logger.log("Approving node:" + bpm_package.children[i].nodeRef);
setWebFlagAction.execute(bpm_package.children[i]);
}]]></activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
</userTask>
<sequenceFlow id="flow15" sourceRef="usertask5" targetRef="endevent1"></sequenceFlow>
<sequenceFlow id="flow16" sourceRef="usertask3" targetRef="endevent1">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${scwf_resubmit == false}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow17" sourceRef="exclusivegateway1" targetRef="usertask5"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_contractsApproval">
<bpmndi:BPMNPlane bpmnElement="contractsApproval" id="BPMNPlane_contractsApproval">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="0.0" y="163.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="790.0" y="164.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="75.0" width="105.0" x="330.0" y="96.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
<omgdc:Bounds height="55.0" width="105.0" x="310.0" y="360.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask4" id="BPMNShape_usertask4">
<omgdc:Bounds height="78.0" width="105.0" x="330.0" y="193.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="scripttask1" id="BPMNShape_scripttask1">
<omgdc:Bounds height="89.0" width="121.0" x="60.0" y="136.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="parallelgateway1" id="BPMNShape_parallelgateway1">
<omgdc:Bounds height="40.0" width="40.0" x="230.0" y="162.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="parallelgateway2" id="BPMNShape_parallelgateway2">
<omgdc:Bounds height="40.0" width="40.0" x="480.0" y="160.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
<omgdc:Bounds height="40.0" width="40.0" x="568.0" y="160.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask5" id="BPMNShape_usertask5">
<omgdc:Bounds height="68.0" width="105.0" x="640.0" y="147.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="35.0" y="180.0"></omgdi:waypoint>
<omgdi:waypoint x="60.0" y="180.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="181.0" y="180.0"></omgdi:waypoint>
<omgdi:waypoint x="230.0" y="182.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="250.0" y="162.0"></omgdi:waypoint>
<omgdi:waypoint x="250.0" y="137.0"></omgdi:waypoint>
<omgdi:waypoint x="330.0" y="133.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="250.0" y="202.0"></omgdi:waypoint>
<omgdi:waypoint x="250.0" y="233.0"></omgdi:waypoint>
<omgdi:waypoint x="330.0" y="232.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
<omgdi:waypoint x="435.0" y="133.0"></omgdi:waypoint>
<omgdi:waypoint x="500.0" y="137.0"></omgdi:waypoint>
<omgdi:waypoint x="500.0" y="160.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="435.0" y="232.0"></omgdi:waypoint>
<omgdi:waypoint x="500.0" y="233.0"></omgdi:waypoint>
<omgdi:waypoint x="500.0" y="200.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
<omgdi:waypoint x="520.0" y="180.0"></omgdi:waypoint>
<omgdi:waypoint x="568.0" y="180.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
<omgdi:waypoint x="588.0" y="200.0"></omgdi:waypoint>
<omgdi:waypoint x="362.0" y="360.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13">
<omgdi:waypoint x="362.0" y="360.0"></omgdi:waypoint>
<omgdi:waypoint x="120.0" y="225.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15">
<omgdi:waypoint x="745.0" y="181.0"></omgdi:waypoint>
<omgdi:waypoint x="790.0" y="181.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16">
<omgdi:waypoint x="415.0" y="387.0"></omgdi:waypoint>
<omgdi:waypoint x="598.0" y="387.0"></omgdi:waypoint>
<omgdi:waypoint x="807.0" y="199.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow17" id="BPMNEdge_flow17">
<omgdi:waypoint x="608.0" y="180.0"></omgdi:waypoint>
<omgdi:waypoint x="640.0" y="181.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
Here is the workflow content model:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Definition of new Model -->
<model name="scwf:workflowModel"
xmlns="http://www.alfresco.org/model/dictionary/1.0">
<!-- Optional meta-data about the model -->
<description>...</description>
<author>...</author>
<version>...</version>
<!-- Imports are required to allow references to definitions in other models -->
<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>
<!-- Introduction of new namespaces defined by this model -->
<namespaces>
<namespace uri="http://.../model/workflow/1.0" prefix="scwf" />
</namespaces>
<types>
<type name="scwf:submitReviewTask">
<parent>bpm:startTask</parent>
</type>
<type name="scwf:activitiFirstReview">
<parent>scwf:activitiReviewTask</parent>
</type>
<type name="scwf:activitiSecondReview">
<parent>scwf:activitiReviewTask</parent>
</type>
<type name="scwf:activitiRevise">
<parent>bpm:activitiOutcomeTask</parent>
<properties>
<property name="scwf:reviseOutcome">
<type>d:text</type>
<default>Abort</default>
<constraints>
<constraint type="LIST">
<parameter name="allowedValues">
<list>
<value>Re-submit</value>
<value>Abort</value>
</list>
</parameter>
</constraint>
</constraints>
</property>
</properties>
<overrides>
<property name="bpm:packageItemActionGroup">
<default>edit_package_item_actions</default>
</property>
<property name="bpm:outcomePropertyName">
<default>{http://.../model/workflow/1.0}reviseOutcome</default>
</property>
</overrides>
</type>
<type name="scwf:activitiReviewTask">
<parent>bpm:activitiOutcomeTask</parent>
<properties>
<property name="scwf:approveRejectOutcome">
<type>d:text</type>
<default>Reject</default>
<constraints>
<constraint type="LIST">
<parameter name="allowedValues">
<list>
<value>Approve</value>
<value>Reject</value>
</list>
</parameter>
</constraint>
</constraints>
</property>
</properties>
<overrides>
<property name="bpm:packageItemActionGroup">
<default>read_package_item_actions</default>
</property>
<property name="bpm:outcomePropertyName">
<default>{http://.../model/workflow/1.0}approveRejectOutcome</default>
</property>
</overrides>
</type>
<type name="scwf:activitiApprovedNotification">
<parent>bpm:workflowTask</parent>
<overrides>
<property name="bpm:packageItemActionGroup">
<default>read_package_item_actions</default>
</property>
</overrides>
</type>
</types>
</model>
On my local computer installed:
Alfresco Share v5.2.d (r134641-b15, Aikau 1.0.101.3, Spring Surf 5.2.d, Spring WebScripts 6.13, Freemarker 2.3.20-alfresco-patched, Rhino 1.7R4-alfresco-patched, Yui 2.9.0-alfresco-20141223)
Alfresco Community v5.2.0 (r134428-b13) schema 10005
And everything works fine...
However, the problem occurs when I installed the system on the server, where:
Alfresco Share v5.2.c (r133673-b12, Aikau 1.0.99, Spring Surf 5.2.c, Spring WebScripts 6.11, Freemarker 2.3.20-alfresco-patched, Rhino 1.7R4-alfresco-patched, Yui 2.9.0-alfresco-20141223)
Alfresco Community v5.2.0 (r133656-b12) schema 10005
In the process of approval, I get this error message:
org.activiti.engine.ActivitiException: Unknown property used in expression: ${scwf_approveCount < 2}
NB: Error appears only after processing by the next group (no matter first or second) - for example, if the contract approved / rejected by the first group, then the second group can't neither approve nor reject.
The portal ecmarchitect says that:
"You may be wondering why this is a service task instead of a script task. In 5.0.d, the underlying JavaScript engine in Activiti switched from Rhino to Nashorn. This caused a problem related to setting execution variables. The work around is to use a service task."
And shows the example of how to initialize variables:
<serviceTask id="scripttask1" name="Submit" activiti:class="org.alfresco.repo.workflow.activiti.script.AlfrescoScriptDelegate">
<extensionElements>
<activiti:field name="script">
<activiti:string><![CDATA[execution.setVariable('scwf_approveCount', 0);
execution.setVariable('scwf_tpApproved', false);]]></activiti:string>
</activiti:field>
</extensionElements>
</serviceTask>
I found several discussions about this, but none of the approach described in them did not help in my case:
For example, I tried to initialize the variables by these ways:
...
<scriptTask id="scripttask1" name="Submit" scriptFormat="javascript" activiti:autoStoreVariables="true">
<script>var scwf_approveCount = 0; var scwf_tpApproved = false;</script>
</scriptTask>
...
<scriptTask id="scripttask1" name="Submit" scriptFormat="javascript">
<script><![CDATA[var scwf_approveCount = 0; var scwf_tpApproved =
false;]]></script>
</scriptTask>
...
<scriptTask id="scripttask1" name="Submit" scriptFormat="javascript" activiti:autoStoreVariables="true">
<script>execution.setVariable('scwf_approveCount', 0); execution.setVariable('scwf_tpApproved', false);</script>
</scriptTask>
...
I think that I need to reinstall Alfresco on the server for matching the local installation.
Is there another way to solve this problem? I would be very grateful for the information. Thanks to all.
Additional information: I installed exactly the same systems. On the server and on my local computer:
Alfresco Share v5.2.d (r134641-b15, Aikau 1.0.101.3, Spring Surf 5.2.d, Spring WebScripts 6.13, Freemarker 2.3.20-alfresco-patched, Rhino 1.7R4-alfresco-patched, Yui 2.9.0-alfresco-20141223)
Alfresco Community v5.2.0 (r134428-b13) schema 10005
But it's very strange - locally everything works fine but on the server I get the same error again:
org.activiti.engine.ActivitiException: Unknown property used in expression: ${scwf_approveCount < 2}
I compared the data in the diagram and in the underlying XML and they are the same.
scwf_approveCount You are using this property make sure that you have defined this property in your workflow's model file as scwf: approveCount You are using this property scwf_approveCount and it may be not defined in your model file.