I want to create a custom workflow in order to review a document by a group that contains two users, those two users should be able to review the document in parallel. How can i do that?
All I have done is review a document by one user ( see attached code), what do i need to change in order to assign the review task to a group?
activiti-demand-workflow-context.xml
<?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="lifecycle.workflowaBootstrap" parent="workflowDeployer">
<property name="workflowDefinitions">
<list>
<props>
<prop key="engineId">activiti</prop>
<prop key="location">alfresco/extension/activiti-demand.bpmn20.xml</prop>
<prop key="mimetype">text/xml</prop>
<prop key="redeploy">false</prop>
</props>
</list>
</property>
<property name="models">
<list>
<value>alfresco/extension/workflowdemandModel.xml</value>
</list>
</property>
<property name="labels">
<list>
<value>alfresco/extension/activiti-demand-messages</value>
</list>
</property>
</bean>
</beans>
activiti-demand-messages.properties
activitiDemand.workflow.title=Demand
activitiDemand.workflow.description=Process of demand validation
wfa_workflowmodelk.type.wfa_submitReviewTaskk.title=review demand
wfa_workflowmodelk.type.wfa_submitReviewTaskk.description=review demand
workflowdemandModel.xml
<?xml version="1.0" encoding="UTF-8"?>
<model name="wfa:workflowmodelk" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<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="wfa.workflow.model" prefix="wfa"/>
</namespaces>
<types>
<!-- -->
<!-- Basic Review & Approve Tasks -->
<!-- -->
<type name="wfa:submitReviewTaskk">
<parent>bpm:startTask</parent>
<mandatory-aspects>
<aspect>bpm:assignee</aspect>
</mandatory-aspects>
</type>
<type name="wfa:activitiReviewTaskk">
<parent>bpm:activitiOutcomeTask</parent>
<properties>
<property name="wfa:reviewOutcome">
<type>d:text</type>
<default>Reject</default>
<constraints>
<constraint name="wfa:reviewOutcomeOptions" type="LIST">
<parameter name="allowedValues">
<list>
<value>Approve</value>
<value>Reject</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://www.alfresco.org/model/workflow/1.0}reviewOutcome</default>
</property>
</overrides>
</type>
<type name="wfa:approvedTaskk">
<parent>bpm:workflowTask</parent>
</type>
<type name="wfa:rejectedTaskk">
<parent>bpm:workflowTask</parent>
</type>
</types>
</model>
activiti-demand.bpmn20.xml
<?xml version="1.0" encoding="UTF-8" ?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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://alfresco.org">
<process id="activitiDemand" name="review process">
<startEvent id="start" name="Submit Review Task"
activiti:formKey="wfa:submitReviewTaskk" />
<sequenceFlow id='flow1'
sourceRef='start'
targetRef='reviewTask' />
<userTask id="reviewTask" name="Review Task"
activiti:formKey="wfa:activitiReviewTaskk">
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
if (typeof bpm_workflowDueDate != 'undefined') task.dueDate = bpm_workflowDueDate
if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
</activiti:string>
</activiti:field>
</activiti:taskListener>
<activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
execution.setVariable('wfa_reviewOutcome', task.getVariable('wfa_reviewOutcome'));
if (task.getVariable('wfa_reviewOutcome') == 'Approve')
{
bpm_package.children[0].addTag("Approved_demand");
}
else
{
if (task.getVariable('wfa_reviewOutcome') == 'Reject')
{
bpm_package.children[0].addTag("Rejected_demand");
}
}
</activiti:string>
</activiti:field>
<activiti:field name="runAs">
<activiti:string>admin</activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
<humanPerformer>
<resourceAssignmentExpression>
<formalExpression>${bpm_assignee.properties.userName}</formalExpression>
</resourceAssignmentExpression>
</humanPerformer>
</userTask>
<!-- <sequenceFlow id='flow2'
sourceRef='reviewTask'
targetRef='reviewDecision' /> -->
<!-- <exclusiveGateway id="reviewDecision" name="Review Decision" /> -->
<!-- <sequenceFlow id='flow3' sourceRef='reviewDecision' targetRef='approved' >
<conditionExpression xsi:type="tFormalExpression">${wfa_reviewOutcome == 'Approve'}</conditionExpression>
</sequenceFlow>
<sequenceFlow id='flow4'
sourceRef='reviewDecision'
targetRef='rejected' />-->
<!-- <userTask id="approved" name="Document Approved"
activiti:formKey="wfa:approvedTaskk" >
<documentation>
The document was reviewed and approved.
</documentation>
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
execution.setVariable("bpm_assignee", task.getVariable("bpm_assignee"));
if (typeof bpm_workflowDueDate != 'undefined') task.dueDate = bpm_workflowDueDate
if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
</activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
<humanPerformer>
<resourceAssignmentExpression>
<formalExpression>${initiator.exists() ? initiator.properties.userName : 'admin'}</formalExpression>
</resourceAssignmentExpression>
</humanPerformer>
</userTask>-->
<!-- <userTask id="rejected" name="Document Rejected"
activiti:formKey="wfa:rejectedTaskk" >
<documentation>
The document was reviewed and rejected.
</documentation>
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
execution.setVariable("bpm_assignee", task.getVariable("bpm_assignee"));
if (typeof bpm_workflowDueDate != 'undefined') task.dueDate = bpm_workflowDueDate
if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
</activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
<humanPerformer>
<resourceAssignmentExpression>
<formalExpression>${initiator.exists() ? initiator.properties.userName : 'admin'}</formalExpression>
</resourceAssignmentExpression>
</humanPerformer>
</userTask>-->
<!-- <sequenceFlow id='flow5' sourceRef='approved'
targetRef='end' />
<sequenceFlow id='flow6' sourceRef='rejected'
targetRef='end' />-->
<endEvent id="end" />
</process>
<!-- Graphical representaion of diagram -->
<bpmndi:BPMNDiagram id="BPMNDiagram_activitiReview">
<bpmndi:BPMNPlane bpmnElement="activitiReview"
id="BPMNPlane_activitiReview">
<bpmndi:BPMNShape bpmnElement="start"
id="BPMNShape_start">
<omgdc:Bounds height="35" width="35" x="30" y="200"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="reviewTask"
id="BPMNShape_reviewTask">
<omgdc:Bounds height="55" width="105" x="125"
y="190"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="reviewDecision"
id="BPMNShape_reviewDecision">
<omgdc:Bounds height="40" width="40" x="290" y="197"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="approved"
id="BPMNShape_approved">
<omgdc:Bounds height="55" width="105" x="390"
y="97"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="rejected"
id="BPMNShape_rejected">
<omgdc:Bounds height="55" width="105" x="390"
y="297"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
<omgdc:Bounds height="35" width="35" x="555" y="307"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="65" y="217"></omgdi:waypoint>
<omgdi:waypoint x="125" y="217"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="230" y="217"></omgdi:waypoint>
<omgdi:waypoint x="290" y="217"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="310" y="197"></omgdi:waypoint>
<omgdi:waypoint x="310" y="124"></omgdi:waypoint>
<omgdi:waypoint x="390" y="124"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="310" y="237"></omgdi:waypoint>
<omgdi:waypoint x="310" y="324"></omgdi:waypoint>
<omgdi:waypoint x="390" y="324"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
<omgdi:waypoint x="495" y="124"></omgdi:waypoint>
<omgdi:waypoint x="572" y="124"></omgdi:waypoint>
<omgdi:waypoint x="572" y="307"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="495" y="324"></omgdi:waypoint>
<omgdi:waypoint x="555" y="324"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
You cannot assign a task to a group. But you can have multiple instance of a task.
Define your review task as a multi-instance task.
<userTask id="reviewTask" name="Review Task" activiti:formKey="wfa:activitiReviewTaskk">
<multiInstanceLoopCharacteristics isSequential="false">
<loopDataInputRef>assigneeList</loopDataInputRef>
<inputDataItem name="assignee" />
</multiInstanceLoopCharacteristics>
...
</userTask>
To create an instance for each user of the reviewers group you can set assigneeList to the list of users from the group when the workflow starts.
You should also define when is the task to be considered completed. Two or more instances of the review task are completed?
<completionCondition>${nrOfCompletedInstances >= 2 }</completionCondition>
Or all of them?
<completionCondition>${nrOfCompletedInstances==nrOfInstances}</completionCondition>
Finally, you should also think about what the overall review result ought to be. Do all users have to approve the document in order for it to be considered approved? Two or more? At least 50%?
One way to accomplish something like this is to increase the value of a counter whenever an instance of the review task ends with approval, and to check this value when the task is resolved.
See also Multi-instance tasks and Xml representation of multi-instance tasks.
You can assign a task to a group/s with this attribute inside your userTask tag:
activiti:candidateGroups="GROUP_development"
You can add more than one group in a comma separated value format and each group name must be prefixed with "GROUP_".
Have in mind that doing in that way converts your task in pooled task wich means that the first user who complete the task finalize it.
Related
im developing a web application to manage alfresco workflows using Rest api , in my process i have an exclusive gateway with a condition on flow22 as shown in this image :
(if decision variable is equal to 'approve' the process moves to task 3 )
For the first and second task everything works fine except i get this error while completing task2 with Rest, knowing that i already set my variable to approve .
this is my bpm
<?xml version="1.0" encoding="UTF-8"?>
<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="pres" name="prestation" isExecutable="true">
<startEvent id="startevent1" name="Start" activiti:initiator="${initiator.properties.userName}" activiti:formKey="pfewf:submitHelloWorldTask"></startEvent>
<userTask id="usertask1" name="Remplir formulaire demande" activiti:assignee="${initiator.properties.userName}" activiti:formKey="pfewf:demandepres">
<extensionElements>
<activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string><![CDATA[execution.setVariable('pfewf_nomprenomDemA',task.getVariableLocal('pfewf_nomprenomDem'));
execution.setVariable('pfewf_ipDemA',task.getVariableLocal('pfewf_ipDem'));
execution.setVariable('pfewf_organismeDemA',task.getVariableLocal('pfewf_organismeDem'));
execution.setVariable('pfewf_refDemA',task.getVariableLocal('pfewf_refDem'));
execution.setVariable('pfewf_appDemA',task.getVariableLocal('pfewf_appDem'));
execution.setVariable('pfewf_dateDemA',task.getVariable('pfewf_dateDem'));
execution.setVariable('pfewf_typeDemA',task.getVariableLocal('pfewf_typeDem'));
execution.setVariable('pfewf_userDetailsA',task.getVariableLocal('pfewf_userDetails'));
execution.setVariable('pfewf_respTech',task.getVariableLocal('pfewf_respTech'));
execution.setVariable('pfewf_respTechR',task.getVariableLocal('pfewf_respTech'));]]></activiti:string>
</activiti:field>
</activiti:taskListener>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string><![CDATA[var date = new Date();
var timeInMillisecs = date.getTime();
var ISODate = utils.toISO8601(timeInMillisecs);
var origDate = utils.fromISO8601(ISODate);
execution.setVariable('pfewf_dateDem',origDate);]]></activiti:string>
</activiti:field>
</activiti:taskListener>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string><![CDATA[execution.setVariable('pfewf_userDetails',task.getVariable('pfewf_userDetails'));]]></activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
</userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<userTask id="usertask2" name="Responsable technique" activiti:assignee="${pfewf_respTech.properties.userName}" activiti:formKey="pfewf:avisTech">
<extensionElements>
<activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string><![CDATA[execution.setVariable('pfewf_nomprenomDemR',task.getVariable('pfewf_nomprenomDemA'));
execution.setVariable('pfewf_ipDemR',task.getVariable('pfewf_ipDemA'));
execution.setVariable('pfewf_organismeDemR',task.getVariable('pfewf_organismeDemA'));
execution.setVariable('pfewf_refDemR',task.getVariable('pfewf_refDemA'));
execution.setVariable('pfewf_appDemR',task.getVariable('pfewf_appDemA'));
execution.setVariable('pfewf_dateDemR',task.getVariable('pfewf_dateDemA'));
execution.setVariable('pfewf_typeDemR',task.getVariable('pfewf_typeDemA'));
execution.setVariable('pfewf_userDetailsR',task.getVariable('pfewf_userDetails'));
execution.setVariable('pfewf_userDetailsA',task.getVariable('pfewf_userDetails'));
execution.setVariable('pfewf_testR',task.getVariable('pfewf_testA'));
execution.setVariable('pfewf_avisRespTech',task.getVariableLocal('pfewf_avisRespTech'));
execution.setVariable('pfewf_respTechR',task.getVariable('pfewf_respTech'));
execution.setVariable('pfewf_remarquesR',task.getVariableLocal('pfewf_remarquesA'));]]></activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
</userTask>
<sequenceFlow id="flow3" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
<userTask id="usertask3" name="Revision demande" activiti:assignee="${initiator.properties.userName}" activiti:formKey="pfewf:revisionDem"></userTask>
<exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
<sequenceFlow id="flow8" sourceRef="usertask2" targetRef="exclusivegateway1"></sequenceFlow>
<sequenceFlow id="flow9" name="a reviser" sourceRef="exclusivegateway1" targetRef="usertask3">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${pfewf_avisRespTech
== 'A Rectifier'}]]></conditionExpression>
</sequenceFlow>
<exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
<sequenceFlow id="flow10" sourceRef="usertask3" targetRef="exclusivegateway2"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow11" name="annuler" sourceRef="exclusivegateway2" targetRef="endevent1">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${pfewf_decisionR
== 'Annuler'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow12" name="renvoyer" sourceRef="exclusivegateway2" targetRef="usertask2">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${pfewf_decisionR
== 'Renvoyer'}]]></conditionExpression>
</sequenceFlow>
<endEvent id="endevent2" name="End"></endEvent>
<sequenceFlow id="flow13" name="refuser" sourceRef="exclusivegateway1" targetRef="endevent2">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${pfewf_avisRespTech
== 'Refuser'}]]></conditionExpression>
</sequenceFlow>
<userTask id="usertask4" name="Avis DHE" activiti:candidateGroups="GROUP_DHE" activiti:formKey="pfewf:dhe">
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string><![CDATA[execution.setVariable('pfewf_nomprenomDemD',task.getVariable('pfewf_nomprenomDemA'));
execution.setVariable('pfewf_ipDemD',task.getVariable('pfewf_ipDemA'));
execution.setVariable('pfewf_organismeDemD',task.getVariable('pfewf_organismeDemA'));
execution.setVariable('pfewf_refDemD',task.getVariable('pfewf_refDemA'));
execution.setVariable('pfewf_appDemD',task.getVariable('pfewf_appDemA'));
execution.setVariable('pfewf_dateDemD',task.getVariable('pfewf_dateDemA'));
execution.setVariable('pfewf_typeDemD',task.getVariable('pfewf_typeDemA'));
execution.setVariable('pfewf_userDetailsD',task.getVariable('pfewf_userDetails'));
execution.setVariable('pfewf_testD',task.getVariable('pfewf_testA'));
execution.setVariable('pfewf_nomprenomDemDr',task.getVariable('pfewf_nomprenomDemA'));
execution.setVariable('pfewf_ipDemDr',task.getVariable('pfewf_ipDemA'));
execution.setVariable('pfewf_organismeDemDr',task.getVariable('pfewf_organismeDemA'));
execution.setVariable('pfewf_refDemDr',task.getVariable('pfewf_refDemA'));
execution.setVariable('pfewf_appDemDr',task.getVariable('pfewf_appDemA'));
execution.setVariable('pfewf_dateDemDr',task.getVariable('pfewf_dateDemA'));
execution.setVariable('pfewf_typeDemDr',task.getVariable('pfewf_typeDemA'));
execution.setVariable('pfewf_userDetailsDr',task.getVariable('pfewf_userDetails'));
execution.setVariable('pfewf_testDr',task.getVariable('pfewf_testA'));]]></activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
</userTask>
<sequenceFlow id="flow14" name="valider" sourceRef="exclusivegateway1" targetRef="usertask4">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${pfewf_avisRespTech
== 'Valider'}]]></conditionExpression>
</sequenceFlow>
<userTask id="usertask5" name="Avis DRSM" activiti:candidateGroups="GROUP_DRSM" activiti:formKey="pfewf:drsm"></userTask>
<sequenceFlow id="flow15" sourceRef="usertask4" targetRef="usertask5"></sequenceFlow>
<endEvent id="endevent3" name="End"></endEvent>
<sequenceFlow id="flow16" sourceRef="usertask5" targetRef="endevent3"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_pres">
<bpmndi:BPMNPlane bpmnElement="pres" id="BPMNPlane_pres">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="310.0" y="323.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="71.0" width="112.0" x="400.0" y="305.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="65.0" width="105.0" x="558.0" y="308.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
<omgdc:Bounds height="55.0" width="105.0" x="688.0" y="461.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
<omgdc:Bounds height="40.0" width="40.0" x="720.0" y="321.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
<omgdc:Bounds height="40.0" width="40.0" x="590.0" y="468.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="480.0" y="471.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent2" id="BPMNShape_endevent2">
<omgdc:Bounds height="35.0" width="35.0" x="723.0" y="220.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask4" id="BPMNShape_usertask4">
<omgdc:Bounds height="55.0" width="105.0" x="805.0" y="314.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask5" id="BPMNShape_usertask5">
<omgdc:Bounds height="55.0" width="105.0" x="955.0" y="314.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent3" id="BPMNShape_endevent3">
<omgdc:Bounds height="35.0" width="35.0" x="1105.0" y="324.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="345.0" y="340.0"></omgdi:waypoint>
<omgdi:waypoint x="400.0" y="340.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="512.0" y="340.0"></omgdi:waypoint>
<omgdi:waypoint x="558.0" y="340.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
<omgdi:waypoint x="663.0" y="340.0"></omgdi:waypoint>
<omgdi:waypoint x="720.0" y="341.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
<omgdi:waypoint x="740.0" y="361.0"></omgdi:waypoint>
<omgdi:waypoint x="740.0" y="461.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="16.0" width="48.0" x="752.0" y="390.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
<omgdi:waypoint x="688.0" y="488.0"></omgdi:waypoint>
<omgdi:waypoint x="630.0" y="488.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
<omgdi:waypoint x="590.0" y="488.0"></omgdi:waypoint>
<omgdi:waypoint x="515.0" y="488.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="16.0" width="42.0" x="532.0" y="500.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
<omgdi:waypoint x="610.0" y="468.0"></omgdi:waypoint>
<omgdi:waypoint x="610.0" y="373.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="16.0" width="48.0" x="615.0" y="431.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13">
<omgdi:waypoint x="740.0" y="321.0"></omgdi:waypoint>
<omgdi:waypoint x="740.0" y="255.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="16.0" width="39.0" x="752.0" y="296.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14">
<omgdi:waypoint x="760.0" y="341.0"></omgdi:waypoint>
<omgdi:waypoint x="805.0" y="341.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="16.0" width="100.0" x="760.0" y="341.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15">
<omgdi:waypoint x="910.0" y="341.0"></omgdi:waypoint>
<omgdi:waypoint x="955.0" y="341.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16">
<omgdi:waypoint x="1060.0" y="341.0"></omgdi:waypoint>
<omgdi:waypoint x="1105.0" y="341.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
How can i deal with exclusivegateways through Rest api ?
Thank you in advance.
I strongly doubt that the decision variable is already set, after completing task2 you can check the value of the variable by calling this endpoint:
GET /tasks/{taskId}/variables
To set variables before completing a task you have to do it like this
URL:
PUT /tasks/{taskId}?select=state,variables
Request body:
{
"state": "completed",
"variables": [
{
"name": "decision",
"type": "d_text",
"value": "approve",
"scope": "global"
}
]
}
There are many solutions:
You can use this condition in your flow14 "${pfewf_avisRespTech != 'Refuser' && pfewf_avisRespTech != 'A Rectifier'}".
In your model set the default value of pfewf_avisRespTech as "Valider" for example
Before asking workflow engine to complete your task, ask him to update the value of your pfewf_avisRespTech
In the complete listener of task2 check the value of "pfewf_avisRespTech" if it's equal to "" or null gives it some value.
sI use activiti for my workflow on alfresco 4.2.c. I want to assign to a group from my form selection. But when I press submit task it throws an exception: org.activiti.engine.ActivitiException: Unknown property used in expression
My activiti is:
<userTask id="kiemtranoidungthethuc" name="Kiểm tra nội dung, thể thức VB- Chuyển cho phòng TCHC" activiti:assignee="${bpm_assignee.properties.userName}" activiti:formKey="wfdi:kiemtranoidungthethucTask_tc">
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
if (typeof bpm_workflowDueDate != 'undefined') task.dueDate = bpm_workflowDueDate;
if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
</activiti:string>
</activiti:field>
</activiti:taskListener>
<activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
execution.setVariable('wfdi_userVanthu', person);
execution.setVariable('wfdi_chapthuan_tc', task.getVariable('wfdi_chapthuan_tc'));
<!-- execution.setVariable('bpm_assignee', person);-->
execution.setVariable('bpm_dueDate', task.getVariable('dueDate'));
execution.setVariable('bpm_priority', task.priority);
execution.setVariable('bpm_groupAssignee',task.bpm_groupAssignee);
</activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
</userTask>
<userTask id="kiemtrathethucchuky" name="Phòng TCHC - Kiểm tra thể thức, chữ ký - Chuyển cho BGH"
activiti:candidateGroups="${bpm_groupAssignee.properties.authorityName}" activiti:formKey="wfdi:kiemtrathethucchukyTask_tc">
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
if (typeof bpm_workflowDueDate != 'undefined') task.dueDate = bpm_workflowDueDate;
if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_priority;
<!-- if (typeof bpm_comment != 'undefined') task.setVariable('bpm_comment', bpm_comment);-->
</activiti:string>
</activiti:field>
</activiti:taskListener>
<activiti:taskListener event="complete" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
execution.setVariable('wfdi_kiemtra_tc', task.getVariable('wfdi_kiemtra_tc'));
execution.setVariable('bpm_dueDate', task.getVariable('dueDate'));
execution.setVariable('bpm_priority', task.priority);
</activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
My form is:
<config evaluator="task-type" condition="wfdi:kiemtranoidungthethucTask_tc">
<forms>
<form>
<field-visibility>
<show id="message" />
<show id="taskOwner" />
<show id="bpm:priority" />
<show id="bpm:dueDate" />
<show id="bpm:taskId" />
<show id="packageItems" />
<show id="bpm:groupAssignee" />
<show id="bpm:comment" />
<show id="wfdi:chapthuan_tc" />
</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="workflow.set.items" />
<set id="assignee" appearance="title" label-id="workflow.set.assignee" />
<set id="response" appearance="title" label-id="workflow.set.response" />
<field id="message">
<control template="/org/alfresco/components/form/controls/info.ftl" />
</field>
<field id="taskOwner" set="info" />
<field id="bpm:taskId" set="info">
<control template="/org/alfresco/components/form/controls/info.ftl" />
</field>
<field id="bpm:priority" set="info" read-only="true">
<control template="/org/alfresco/components/form/controls/workflow/priority.ftl" />
</field>
<field id="bpm:dueDate" set="info" label-id="workflow.field.due">
<control template="/org/alfresco/components/form/controls/info.ftl" />
</field>
<field id="packageItems" set="items" />
<field id="bpm:groupAssignee" label-id="workflow.field.review_group" set="assignee" />
<field id="bpm:comment" label-id="workflow.field.comment" set="response">
<control template="/org/alfresco/components/form/controls/textarea.ftl" />
</field>
<field id="wfdi:chapthuan_tc" label-id="workflow.field.outcome" set="response">
<control template="/org/alfresco/components/form/controls/workflow/activiti-transitions.ftl" />
</field>
</appearance>
</form>
</forms>
My model is:
<type name="wfdi:kiemtranoidungthethucTask_tc">
<parent>bpm:workflowTask</parent>
<properties>
<property name="wfdi:chapthuan_tc">
<type>d:text</type>
<default>Tu_Choi</default>
<constraints>
<constraint name="wfdi:chapthuanOption_tc" type="LIST">
<parameter name="allowedValues">
<list>
<value>Chuyen_Phong_TCHC</value>
<value>Tu_Choi</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://www.alfresco.org/model/workflow/1.0}chapthuan</default>
</property>
</overrides>
<mandatory-aspects>
<aspect>bpm:groupAssignee</aspect>
</mandatory-aspects>
I know the problem is: activiti:candidateGroups="${bpm_groupAssignee.properties.authorityName}"
but I don't know how to fix it.
Can anybody help me?
Thank in advance.
I am trying to build a custom workflow in alfresco community edition. Basically I am trying to modify the existing workflow called lifecycleprocess. I have been able to deploy the process using workflow console without error. But I am not able to do any change at all on the workflow form. My workflow is called leaveprocess and I have the following code :
Path : alfresco/tomcat/shared/classes/alfresco/extension/
leave-process-bpmn20.xml
<?xml version="1.0" encoding="UTF-8" ?>
<definitions id="leave-definitions"
typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://activiti.org/bpmn20"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:activiti="http://activiti.org/bpmn">
<process id="activitileaveApproval" name="Leave Process">
<extensionElements>
<!-- When process is deleted/cancelled, status should be set to draft -->
<activiti:executionListener event="end" class="org.alfresco.repo.workflow.activiti.listener.ScriptExecutionListener">
<activiti:field name="script">
<activiti:string>
if(cancelled || deleted) {
for (var i = 0; i < bpm_package.children.length; i++)
{
if (!bpm_package.children[i].hasAspect("wfl:status"))
{
bpm_package.children[i].properties["wfl:status"] = "Draft";
bpm_package.children[i].save();
}
}
}
</activiti:string>
</activiti:field>
</activiti:executionListener>
</extensionElements>
<startEvent id="start"
activiti:formKey="wf:submitReviewTask" />
<sequenceFlow id='flow1'
sourceRef='start'
targetRef='reviewTask'>
<extensionElements>
<activiti:executionListener event="take" class="org.alfresco.repo.workflow.activiti.listener.ScriptExecutionListener">
<activiti:field name="script">
<activiti:string>
for (var i = 0; i < bpm_package.children.length; i++)
{
if (!bpm_package.children[i].hasAspect("wfl:status"))
{
bpm_package.children[i].addAspect("wfl:status");
}
}
</activiti:string>
</activiti:field>
</activiti:executionListener>
</extensionElements>
</sequenceFlow>
<userTask id="reviewTask" name="Review Task"
activiti:formKey="wf:activitiReviewTask">
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
for (var i = 0; i < bpm_package.children.length; i++)
{
if (bpm_package.children[0].hasAspect("wfl:status")) {
bpm_package.children[i].properties["wfl:status"] = "In Review";
bpm_package.children[i].save();
}
}
</activiti:string>
</activiti:field>
</activiti:taskListener>
<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>
</extensionElements>
<humanPerformer>
<resourceAssignmentExpression>
<formalExpression>${bpm_assignee.properties.userName}</formalExpression>
</resourceAssignmentExpression>
</humanPerformer>
</userTask>
<sequenceFlow id='flow2'
sourceRef='reviewTask'
targetRef='reviewDecision' />
<exclusiveGateway id="reviewDecision" name="Review Decision" />
<sequenceFlow id='flow3' sourceRef='reviewDecision' targetRef='approved' >
<conditionExpression xsi:type="tFormalExpression">${wf_reviewOutcome == 'Approve'}</conditionExpression>
</sequenceFlow>
<sequenceFlow id='flow4'
sourceRef='reviewDecision'
targetRef='rejected' />
<userTask id="approved" name="Document Approved"
activiti:formKey="wf:approvedTask" >
<documentation>
The document was reviewed and approved.
</documentation>
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
for (var i = 0; i < bpm_package.children.length; i++)
{
if (bpm_package.children[0].hasAspect("wfl:status")) {
bpm_package.children[i].properties["wfl:status"] = "Approved";
bpm_package.children[i].save();
}
}
</activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
<humanPerformer>
<resourceAssignmentExpression>
<formalExpression>${initiator.properties.userName}</formalExpression>
</resourceAssignmentExpression>
</humanPerformer>
</userTask>
<userTask id="rejected" name="Document Rejected"
activiti:formKey="wf:rejectedTask" >
<documentation>
The document was reviewed and rejected.
</documentation>
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
for (var i = 0; i < bpm_package.children.length; i++)
{
if (bpm_package.children[0].hasAspect("wfl:status"))
{
bpm_package.children[i].properties["wfl:status"] = "Draft";
bpm_package.children[i].save();
}
}
</activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
<humanPerformer>
<resourceAssignmentExpression>
<formalExpression>${initiator.properties.userName}</formalExpression>
</resourceAssignmentExpression>
</humanPerformer>
</userTask>
<sequenceFlow id='flow5' sourceRef='approved'
targetRef='end' />
<sequenceFlow id='flow6' sourceRef='rejected'
targetRef='end' />
<endEvent id="end" />
</process>
</definitions>
leave-messages.properties
# For JBPM leave Workflow Example
wfl_leaveapproval.workflow.title=Leave Application
wfl_leaveapproval.workflow.description=Leave Application (Auto updates document status)
wfl_leaveapproval.node.review.transition.reject.title=Reject
wfl_leaveapproval.node.review.transition.reject.description=Reject
wfl_leaveapproval.node.review.transition.approve.title=Approve
wfl_leaveapproval.node.review.transition.approve.description=Approve
# For Activiti leave Workflow Example
activitileaveApproval=Leave Application
activitileaveApproval=Leave Application workflow Activiti (Auto updates document status)
leave-workflow-context.xml
<?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="leave.workflowBootstrap" parent="workflowDeployer">
<property name="workflowDefinitions">
<list>
<!-- JBPM version of leave process -->
<props>
<prop key="engineId">jbpm</prop>
<prop key="location">alfresco/extension/leave_processdefinition.xml</prop>
<prop key="mimetype">text/xml</prop>
<prop key="redeploy">false</prop>
</props>
<!-- Activiti version of leave process -->
<props>
<prop key="engineId">activiti</prop>
<prop key="location">alfresco/extension/leave-process.bpmn20.xml</prop>
<prop key="mimetype">text/xml</prop>
<prop key="redeploy">false</prop>
</props>
</list>
</property>
<property name="models">
<list>
<value>alfresco/extension/leaveModel.xml</value>
</list>
</property>
<property name="labels">
<list>
<value>alfresco/extension/leave-messages</value>
</list>
</property>
</bean>
</beans>
leave_processdefinition.xml
<?xml version="1.0" encoding="UTF-8"?>
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="wfl:leaveapproval">
<swimlane name="initiator" />
<start-state name="start">
<task name="wf:submitReviewTask" swimlane="initiator" />
<event type="node-leave">
<!-- Call script once the workflow package exists i.e. on node-leave -->
<action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
<!-- Apply the Workflow leave Aspect (wfl:status) if not set already. Note: The default wfl:status property is draft -->
<script>
for (var i = 0; i < bpm_package.children.length; i++)
{
if (!bpm_package.children[i].hasAspect("wfl:status"))
{
bpm_package.children[i].addAspect("wfl:status");
}
}
</script>
</action>
</event>
<transition name="" to="review" />
</start-state>
<swimlane name="reviewer">
<assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment">
<actor>#{bpm_assignee}</actor>
</assignment>
</swimlane>
<task-node name="review">
<event type="node-enter">
<!-- Update the status to In Review when we enter this task -->
<action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
<script>
for (var i = 0; i < bpm_package.children.length; i++)
{
bpm_package.children[i].properties["wfl:status"] = "In Review";
bpm_package.children[i].save();
}
</script>
</action>
</event>
<task name="wf:reviewTask" swimlane="reviewer">
<event type="task-create">
<script>
if (bpm_workflowDueDate != void) taskInstance.dueDate = bpm_workflowDueDate;
if (bpm_workflowPriority != void) taskInstance.priority = bpm_workflowPriority;
</script>
</event>
</task>
<transition name="approve" to="approved" />
<transition name="reject" to="rejected" />
</task-node>
<task-node name="rejected">
<event type="node-enter">
<!-- Update the status to Draft when we enter this task -->
<action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
<script>
for (var i = 0; i < bpm_package.children.length; i++)
{
bpm_package.children[i].properties["wfl:status"] = "Draft";
bpm_package.children[i].save();
}
</script>
</action>
</event>
<task name="wf:rejectedTask" swimlane="initiator" />
<transition name="" to="end" />
</task-node>
<task-node name="approved">
<event type="node-enter">
<!-- Update the status to Approved when we enter this task -->
<action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
<script>
for (var i = 0; i < bpm_package.children.length; i++)
{
bpm_package.children[i].properties["wfl:status"] = "Approved";
bpm_package.children[i].save();
}
</script>
</action>
</event>
<task name="wf:approvedTask" swimlane="initiator" />
<transition name="" to="end" />
</task-node>
<end-state name="end" />
<event type="process-end">
<action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
<script>
if (cancelled)
{
for (var i = 0; i < bpm_package.children.length; i++)
{
if (bpm_package.children[0].hasAspect("wfl:status"))
{
bpm_package.children[i].properties["wfl:status"] = "Draft";
bpm_package.children[i].save();
}
}
if (logger.isLoggingEnabled()) logger.log("Workflow cancelled, status reset to Draft");
}
else
{
if (logger.isLoggingEnabled()) logger.log("Workflow completed");
}
</script>
</action>
</event>
</process-definition>
leaveModel.xml
<?xml version="1.0" encoding="UTF-8"?>
<model name="wfl:workflowleavemodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<!-- Optional meta-data about the model -->
<description>Workflow leave Model</description>
<author></author>
<version>1.0</version>
<!-- Imports are required to allow references to definitions in other models -->
<imports>
<!-- Import Alfresco Dictionary Definitions -->
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
<!-- Import Alfresco Content Domain Model Definitions -->
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" />
</imports>
<namespaces>
<namespace uri="wfl.model" prefix="wfl" />
</namespaces>
<constraints>
<constraint name="wfl:status" type="LIST">
<parameter name="allowedValues">
<list>
<value>Draft</value>
<value>In Review</value>
<value>Approved</value>
</list>
</parameter>
</constraint>
</constraints>
<aspects>
<!-- Status property is used to manage workflow approval -->
<aspect name="wfl:status">
<title>Status</title>
<properties>
<property name="wfl:status">
<title>Status</title>
<type>d:text</type>
<default>Draft</default>
<constraints>
<constraint ref="wfl:status" />
</constraints>
</property>
</properties>
</aspect>
</aspects>
</model>
Path : alfresco/tomcat/webapps/share/WEB-INF/classes/alfresco/
share-workflow-form-config.xml
<!-- Leave Workflow Definition -->
<config evaluator="string-compare" condition="jbpm$wfl:leaveApproval">
<forms>
<form>
<field-visibility>
<show id="bpm:workflowDescription" />
<show id="bpm:workflowDueDate" />
<show id="bpm:workflowPriority" />
<show id="bpm:assignee" />
<show id="packageItems" />
<show id="bpm:sendEMailNotifications" />
</field-visibility>
<appearance>
<set id="" appearance="title" label-id="workflow.set.general" />
<set id="info" appearance="" template="/org/alfresco/components/form/2-column-set.ftl" />
<set id="assignee" appearance="title" label-id="workflow.set.assignee" />
<set id="items" appearance="title" label-id="workflow.set.items" />
<set id="other" appearance="title" label-id="workflow.set.other" />
<field id="bpm:workflowDescription" label-id="workflow.field.message">
<control template="/org/alfresco/components/form/controls/textarea.ftl">
<control-param name="style">width: 95%</control-param>
</control>
</field>
<field id="bpm:workflowDueDate" label-id="workflow.field.due" set="info" />
<field id="bpm:workflowPriority" label-id="workflow.field.priority" set="info">
<control template="/org/alfresco/components/form/controls/workflow/priority.ftl" />
</field>
<field id="bpm:assignee" label-id="workflow.field.reviewer" set="assignee" />
<field id="packageItems" set="items" />
<field id="bpm:sendEMailNotifications" set="other">
<control template="/org/alfresco/components/form/controls/workflow/email-notification.ftl" />
</field>
</appearance>
</form>
</forms>
</config>
<config evaluator="string-compare" condition="activiti$activitileaveApproval">
<forms>
<form>
<field-visibility>
<show id="bpm:workflowDescription" />
<show id="bpm:workflowDueDate" />
<show id="bpm:workflowPriority" />
<show id="bpm:assignee" />
<show id="packageItems" />
<show id="bpm:sendEMailNotifications" />
</field-visibility>
<appearance>
<set id="" appearance="title" label-id="workflow.set.general" />
<set id="info" appearance="" template="/org/alfresco/components/form/2-column-set.ftl" />
<set id="assignee" appearance="title" label-id="workflow.set.assignee" />
<set id="items" appearance="title" label-id="workflow.set.items" />
<set id="other" appearance="title" label-id="workflow.set.other" />
<field id="bpm:workflowDescription" label-id="workflow.field.message">
<control template="/org/alfresco/components/form/controls/textarea.ftl">
<control-param name="style">width: 95%</control-param>
</control>
</field>
<field id="bpm:workflowDueDate" label-id="workflow.field.due" set="info">
<control template="/org/alfresco/components/form/controls/date.ftl">
<control-param name="showTime">false</control-param>
<control-param name="submitTime">false</control-param>
</control>
</field>
<field id="bpm:workflowPriority" label-id="workflow.field.priority" set="info">
<control template="/org/alfresco/components/form/controls/workflow/priority.ftl" />
</field>
<field id="bpm:assignee" label-id="workflow.field.reviewer" set="assignee" />
<field id="packageItems" set="items" />
<field id="bpm:sendEMailNotifications" set="other">
<control template="/org/alfresco/components/form/controls/workflow/email-notification.ftl" />
</field>
</appearance>
</form>
</forms>
</config>
I am unable to understand, no matter what changes I do in this code for share-workflow-form-config.xml, It does not reflect when go to Share->Workflows I've started->select Leave Process. It always show the default form there. Somebody please guide me what I am doing wrong here.
You need to replace this
<form>
with following line
<form id="workflow-details">
means add attribute "id" in your form tag
After making changes in share-config you have to restart alfresco :)
Deploy of workflow (via workflow console) makes just re-deploy of the workflow definitions (also like deploy of models,.. )
But
<config evaluator="string-compare" condition="jbpm$wfl:leaveApproval">
Should works :D, no other idea why not working..
I tried to change the Entities Table Name and encountered an error.
I just renamed TblRecord as the name was from the Table Name
What is the mistake here and how to resolve it ?
Error :
+ _innerException {"The specified table does not exist. [ Records ]"} System.Exception {System.Data.SqlServerCe.SqlCeException}
The Edmx File
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
<!-- EF Runtime content -->
<edmx:Runtime>
<!-- SSDL content -->
<edmx:StorageModels>
<Schema Namespace="Xz.Business.Matches.Store" Alias="Self" Provider="System.Data.SqlServerCe.4.0" ProviderManifestToken="4.0" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
<EntityContainer Name="XzBusinessMatchesStoreContainer">
<EntitySet Name="Records" EntityType="Xz.Business.Matches.Store.Records" store:Type="Tables" />
</EntityContainer>
<EntityType Name="Records">
<Key>
<PropertyRef Name="Record" />
</Key>
<Property Name="Record" Type="nvarchar" Nullable="false" MaxLength="100" />
<Property Name="Relations" Type="nvarchar" MaxLength="450" />
</EntityType>
</Schema>
</edmx:StorageModels>
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema Namespace="Xz.Business.Matches" Alias="Self" p1:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns:p1="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
<EntityContainer Name="RecordzEntities" p1:LazyLoadingEnabled="true">
<EntitySet Name="Records" EntityType="Xz.Business.Matches.TblRecord" />
</EntityContainer>
<EntityType Name="TblRecord">
<Key>
<PropertyRef Name="Record" />
</Key>
<Property Name="Record" Type="String" Nullable="false" MaxLength="100" Unicode="true" FixedLength="false" />
<Property Name="Relations" Type="String" MaxLength="450" Unicode="true" FixedLength="false" />
</EntityType>
</Schema>
</edmx:ConceptualModels>
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
<EntityContainerMapping StorageEntityContainer="XzBusinessMatchesStoreContainer" CdmEntityContainer="RecordzEntities">
<EntitySetMapping Name="Records">
<EntityTypeMapping TypeName="Xz.Business.Matches.TblRecord">
<MappingFragment StoreEntitySet="Records">
<ScalarProperty Name="Record" ColumnName="Record" />
<ScalarProperty Name="Relations" ColumnName="Relations" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
</edmx:Runtime>
<!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
<Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
<Connection>
<DesignerInfoPropertySet>
<DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
</DesignerInfoPropertySet>
</Connection>
<Options>
<DesignerInfoPropertySet>
<DesignerProperty Name="ValidateOnBuild" Value="true" />
<DesignerProperty Name="EnablePluralization" Value="True" />
<DesignerProperty Name="IncludeForeignKeysInModel" Value="True" />
<DesignerProperty Name="CodeGenerationStrategy" Value="None" />
</DesignerInfoPropertySet>
</Options>
<!-- Diagram content (shape and connector positions) -->
<Diagrams></Diagrams>
</Designer>
</edmx:Edmx>
This is EF5 & VS12
If you're renamed the table in the DB you will need to update the mapping in the EDMX. The error message is self describing.
Failing that you could just delete the model TblRecord from the edmx designer and re-add it with the new name Record.
I have a problem where I've mapped a stored procedure named sp_getMyEntity, which takes in one parameter called Id and then maps the results to a custom entity called MyEntity
I'm using mock data to illustrate the point. When I run the stored procedure with an id of 1, I get two distinct results back from the database:
exec [dbo].[sp_getMyEntity] #Id=1
Results:
ID - AddressId
1 - 6
1 - 3
When querying the ObjectContext using LINQ, I get 2 MyEntity's back but the AddressId for both of them is 6, not 6 and 3 respectively. Here is my call using LINQ:
Entities context = new Entities();
var entities = from s in context.GetMyEntity(1)
select s;
return entities.ToList();
Here is the EDMX xml:
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<!-- EF Runtime content -->
<edmx:Runtime>
<!-- SSDL content -->
<edmx:StorageModels>
<Schema Namespace="MyProjectModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
<EntityContainer Name="MyProjectModelStoreContainer">
<EntitySet Name="MyEntitySet" EntityType="MyProjectModel.Store.MyEntity" />
</EntityContainer>
<Function Name="sp_getMyEntity" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<Parameter Name="Id" Type="int" Mode="In" />
</Function>
<EntityType Name="MyEntity">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="int" Nullable="false" />
<Property Name="AddressId" Type="int" Nullable="true" />
</EntityType>
</Schema>
</edmx:StorageModels>
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema Namespace="MyProjectModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
<EntityContainer Name="MyProjectViewEntities" >
<EntitySet Name="MyEntitySet" EntityType="MyProjectModel.MyEntity" />
<FunctionImport Name="GetMyEntity" EntitySet="MyEntitySet" ReturnType="Collection(MyProjectModel.MyEntity)">
<Parameter Name="Id" Mode="In" Type="Int32" />
</FunctionImport>
</EntityContainer>
<EntityType Name="MyEntity">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Int32" Nullable="false" />
<Property Name="AddressId" Type="Int32" Nullable="true" />
</EntityType>
</Schema>
</edmx:ConceptualModels>
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
<EntityContainerMapping StorageEntityContainer="MyProjectModelStoreContainer" CdmEntityContainer="MyProjectViewEntities" >
<FunctionImportMapping FunctionImportName="GetMyEntity" FunctionName="MyProjectModel.Store.sp_getMyEntity" />
<EntitySetMapping Name="MyEntitySet">
<EntityTypeMapping TypeName="IsTypeOf(MyProjectModel.MyEntity)">
<MappingFragment StoreEntitySet="MyEntitySet">
<ScalarProperty Name="AddressId" ColumnName="AddressId" />
<ScalarProperty Name="Id" ColumnName="Id" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
</edmx:Runtime>
<!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
<edmx:Designer xmlns="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:Connection>
<DesignerInfoPropertySet>
<DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
</DesignerInfoPropertySet>
</edmx:Connection>
<edmx:Options>
<DesignerInfoPropertySet>
<DesignerProperty Name="ValidateOnBuild" Value="true" />
</DesignerInfoPropertySet>
</edmx:Options>
<!-- Diagram content (shape and connector positions) -->
<edmx:Diagrams>
<Diagram Name="MyProjectModel" ZoomLevel="100" >
<EntityTypeShape EntityType="MyProjectModel.MyEntity" Width="1.5" PointX="5.25" PointY="0.5" Height="7.8375048828125" />
<EntityTypeShape EntityType="MyProjectModel.MyEntity" Width="1.5" PointX="5.5" PointY="1.375" Height="1.2636116536458335" /></Diagram></edmx:Diagrams>
</edmx:Designer>
</edmx:Edmx>
Any ideas why the MyEntity's are not unique?
Because the SP column which your SSDL identifies as the key is not a unique column. You cannot have a "key" with duplicate values.
As Craig stated above my Key property was not unique, so I ended up changing the SQL to look at follows:
SELECT
ROW_NUMBER() OVER(ORDER BY Id) AS KeyId
, Id
, AddressId
FROM
MyTable
WHERE
Id = #Id
Then the EDMX xml looks as follows, notice the new key is a bigint and Int64:
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<!-- EF Runtime content -->
<edmx:Runtime>
<!-- SSDL content -->
<edmx:StorageModels>
<Schema Namespace="MyProjectModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
<EntityContainer Name="MyProjectModelStoreContainer">
<EntitySet Name="MyEntitySet" EntityType="MyProjectModel.Store.MyEntity" />
</EntityContainer>
<Function Name="sp_getMyEntity" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<Parameter Name="Id" Type="int" Mode="In" />
</Function>
<EntityType Name="MyEntity">
<Key>
<PropertyRef Name="KeyId" />
</Key>
<Property Name="KeyId" Type="bigint" Nullable="false" />
<Property Name="Id" Type="int" Nullable="false" />
<Property Name="AddressId" Type="int" Nullable="true" />
</EntityType>
</Schema>
</edmx:StorageModels>
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema Namespace="MyProjectModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
<EntityContainer Name="MyProjectViewEntities" >
<EntitySet Name="MyEntitySet" EntityType="MyProjectModel.MyEntity" />
<FunctionImport Name="GetMyEntity" EntitySet="MyEntitySet" ReturnType="Collection(MyProjectModel.MyEntity)">
<Parameter Name="Id" Mode="In" Type="Int32" />
</FunctionImport>
</EntityContainer>
<EntityType Name="MyEntity">
<Key>
<PropertyRef Name="KeyId" />
</Key>
<Property Name="KeyId" Type="Int64" Nullable="false" />
<Property Name="Id" Type="Int32" Nullable="false" />
<Property Name="AddressId" Type="Int32" Nullable="true" />
</EntityType>
</Schema>
</edmx:ConceptualModels>
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
<EntityContainerMapping StorageEntityContainer="MyProjectModelStoreContainer" CdmEntityContainer="MyProjectViewEntities" >
<FunctionImportMapping FunctionImportName="GetMyEntity" FunctionName="MyProjectModel.Store.sp_getMyEntity" />
<EntitySetMapping Name="MyEntitySet">
<EntityTypeMapping TypeName="IsTypeOf(MyProjectModel.MyEntity)">
<MappingFragment StoreEntitySet="MyEntitySet">
<ScalarProperty Name="AddressId" ColumnName="AddressId" />
<ScalarProperty Name="Id" ColumnName="Id" />
<ScalarProperty Name="KeyId" ColumnName="KeyId" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
</edmx:Runtime>
<!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
<edmx:Designer xmlns="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:Connection>
<DesignerInfoPropertySet>
<DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
</DesignerInfoPropertySet>
</edmx:Connection>
<edmx:Options>
<DesignerInfoPropertySet>
<DesignerProperty Name="ValidateOnBuild" Value="true" />
</DesignerInfoPropertySet>
</edmx:Options>
<!-- Diagram content (shape and connector positions) -->
<edmx:Diagrams>
<Diagram Name="MyProjectModel" ZoomLevel="100" >
<EntityTypeShape EntityType="MyProjectModel.MyEntity" Width="1.5" PointX="5.25" PointY="0.5" Height="7.8375048828125" />
<EntityTypeShape EntityType="MyProjectModel.MyEntity" Width="1.5" PointX="5.5" PointY="1.375" Height="1.2636116536458335" /></Diagram></edmx:Diagrams>
</edmx:Designer>
</edmx:Edmx>