zenami
zenami

Reputation: 131

Assign workflow to a group in Alfresco with activiti

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>

Upvotes: 0

Views: 769

Answers (2)

JuanH
JuanH

Reputation: 51

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.

Upvotes: 0

GiulioP
GiulioP

Reputation: 126

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.

Upvotes: 0

Related Questions