จาก Blog ที่แล้วที่ผมได้เขียนเกี่ยวกับตัวอย่างของ multiInstanceLoopCharacteristics โดยใช้ตัวอย่างเรื่อง กระบวนการของการขอเสนอรางวัลให้กับพนักงานดีเด่น ซึ่งลองเล่นไป เล่นมาแล้วพบปัญหา ดังนี้
- Task "Evaluate Award" ได้ถูก Assign ให้เป็น Group โดยที่กรรมการแต่ละท่านเลือกไปทำครับ แต่มันสามารถ Claim ซ้ำกันได้ครับ แบบนี้ไม่ดีแน่ครับ
- ทางแก้ไขหล่ะ
- แบบที่ 1: แก้ไข Object ของ MultiInstance แล้วให้กำหนด User เป็น Assignee สำหรับ Task นั้นเลย
- แบบที่ 2:แก้ไขโดยการเพิ่ม Listener แล้วเขียน Code ขึ้นมาตรวจสอบครับ
- ** สำหรับใน Blog นี้ ผมใช้วิธีแรกครับ แต่จะแทรก ตัวอย่างของ Listener เข้าไปด้วยครับ
ลุยกันเลยครับ
- สำหรับภาพรวมของกระบวนการ (Process) เหมือนเดิมครับ แต่จะแก้ Coding และ Config ข้างในมากกว่าครับ
- มาเริ่มกันเลยครับ
- ใน Script Task "Setup Reviews" ผมแก้จากการใช้ List มาเป็น Dictionary ครับ โดยให้ key = ชื่อคณะกรรมการ และ value = ผลการประเมินครับ ตาม Code ตัวอย่างเลย
//create a collection to hold our multi-instance results. //ดึงข้อมูลผู้ใช้ออกมา def committee = [ 'jame', 'john', 'peter']; //สร้าง MAP เป็นข้อมูลแบบ Key/Value def reviewResultMap = [:]; for (i = 0; i <RequiredNumOfPeers; i++) { reviewResultMap.put(committee[i], "NOT_REVIEW"); } execution.setVariable ("reviewResultMap", reviewResultMap); //ดึง Id ของ Process มาแสดงผล RequestNo= execution.getProcessInstanceId(); execution.setVariable ("RequestNo", RequestNo);
- มาที่พระเอกของแรกแล้วครับ ตรง Sub-Process "EvaluateProcess" ที่ถูกกำหนดเป็น MultiInstance ครับ
- แก้ไข MultiInstance ครับ
- มาดูที่รูปก่อนครับ
- แล้วที่นี้กำหนดข้อมูลของแต่ะส่วน ดังนี้ครับ
- Loop Cadinality - อันนี้เหมือนเดิมครับ คือ เอาค่าจากตัวแปร ${RequiredNumOfPeers} ที่กำหนดมาจาก Task Associate Reviews
- Collection - Data ที่ใช้ใน multiInstanceLoopCharacteristics ครับ โดยช้อมูลชุดนี้เกิดจาก Task Setup Reviews ที่สร้าง MAP ชื่อ ${reviewResultMap} ที่มีขนาดเท่ากับ ${RequiredNumOfPeers} ถ้าในตัวอย่างเท่ากับ 3 ซึ่งในแต่ละ Instance ของ Task เห็นข้อมูล reviewsResult(Object แต่ละอันใน MAP reviewsResults โดยดึงมาเฉพาะ Key ถ้าดูในแบบจำลองในส่วน Collection กำหนดให้ค่าเท่ากับ ${reviewResultMap.keySet()} ) ซึ่งประกาศไว้ในส่วน element ในรูปแบบ 1 Instance ต่อ 1 Object ครับ
- completionCondition ครับ ซึ่งถ้าเงื่อนไขเป็นจริง ก็จะออกจาก multiInstanceLoopCharacteristics ครับ โดยเงื่อนไขทาง Business คือ กรรมการ 2 ใน 3 ท่าน ได้เข้าร่วมการประเมินครับ ซื่งสามารถกำหนดเงื่อนไขได้ ดังนี้
//เงื่อนไขทาง Business คือ กรรมการ 2 ใน 3 ท่าน ได้เข้าร่วมการประเมินครับ ส่วนอันหลังผมกำหนดขึ้น เพราะตรวจสอบว่าระหว่างที่ทำ Process ข้อมูลไม่ได้ถูกเพิ่มปรับแต่งอะไร ${(nrOfCompletedInstances >= RequiredMinNumofPeer) && (reviewResultMap.size() == nrOfInstances)}
- มาดูที่รูปก่อนครับ
- เพิ่ม Listener เพื่อกำหนดตัวแปรระดับ Local ให้ Engine รู้จักครับ โดยผมเพิ่มตัวแปร reviewer(ชื่อผู้ประเมิน) และ reviewResult(ผลการประเมิน) ซื้อยู่ใน Scope ของ Sub-Process "EvaluateProcess" ดังนี้ครับ
- มาดูที่รูปก่อนครับ
- ในส่วนของ Script มีการแก้ไข โดยจะ Execute ต่อเมื่อมีการเรียกใช้ Sub Process "EvaluateProcess" ครับ โดยมีรายละเอียดของ Script ดังนี้
execution.setVariable("reviewer", theCommitee,"EvaluateProcess"); execution.setVariable("reviewResult", "NOT_REVIEW","EvaluateProcess");
- มาดูที่รูปก่อนครับ
- แก้ไข MultiInstance ครับ
- Note: อย่าลืมแก้ไขชื่อตัวแปรให้ครับนะครับ ถ้าไป Run ที่ตัว BPMN Engine แล้วเสียเวลาพอสมควรครับ
ทดสอบกันเลยครับ
- Mary ได้เริ่มการทำงานของ Reward Process แล้วครับ
- Mary กรอกข้อมูลเพื่อเสนอชื่อของผมไปครับ (ในชีวิตจริงๆ ก็อยากได้เงินก้อนแบบนี้บ้าง T__T)
- กำหนดรายละเอียดของ Task Associate Reviews ครับ
- สังเกตุดีๆว่าตอนนี้ Task "Evaluate Award" ได้ถูก Assign เข้าไปที่คณะกรรมการแต่ละท่านแล้วครับ เมื่อ Mary ได้เขียน Flow มาจนถึง Sub Process "EvaluateProcess" พบว่า User ที่เป็นกรรมการทั้ง 3 ท่านได้ถูก Assign Task เรียบร้อยครับ
- User jame
- User john
- User peter
- User jame
- และเมื่อ 2 ใน 3 ของคณะกรรมการได้พิจารณา Task เรียบร้อยแล้ว พบ่วาระบบทำการ Clear อีก 1 Instance ให้อัตโนมัติครับ
- เมื่อจบการตัดสินของคณะกรรมการแล้ง ระบบตัดสินผลลัพธ์ และแจ้งให้ Mary รับทราบผลลัพธ์ครับ
สำหรับ Source Code ของแบบจำลองครับ
- มาดูที่ Github ได้เลยครับThis file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.11.3"> <bpmn:collaboration id="Collaboration_1ukzxwm"> <bpmn:participant id="Participant_1jytf7q" name="Reward Process" processRef="RewardMultiInstanceAssignee" /> </bpmn:collaboration> <bpmn:process id="RewardMultiInstanceAssignee" isExecutable="true"> <bpmn:laneSet> <bpmn:lane id="Lane_0r1co7i" name="Manager"> <bpmn:flowNodeRef>Task_0o9iylr</bpmn:flowNodeRef> <bpmn:flowNodeRef>EndEvent_111ifpl</bpmn:flowNodeRef> <bpmn:flowNodeRef>EndEvent_1mu7bj0</bpmn:flowNodeRef> <bpmn:flowNodeRef>Task_1uzfnxh</bpmn:flowNodeRef> <bpmn:flowNodeRef>Task_1l0vjpp</bpmn:flowNodeRef> <bpmn:flowNodeRef>Task_0p0dthr</bpmn:flowNodeRef> <bpmn:flowNodeRef>StartEvent_1</bpmn:flowNodeRef> <bpmn:flowNodeRef>ExclusiveGateway_1cfwqqd</bpmn:flowNodeRef> <bpmn:childLaneSet xsi:type="bpmn:tLaneSet" /> </bpmn:lane> <bpmn:lane id="Lane_0feow9m" name="Reward Commitee"> <bpmn:flowNodeRef>EvaluateProcess</bpmn:flowNodeRef> <bpmn:flowNodeRef>Task_0ofwv70</bpmn:flowNodeRef> </bpmn:lane> </bpmn:laneSet> <bpmn:sequenceFlow id="SequenceFlow_1nhdcp1" sourceRef="StartEvent_1" targetRef="Task_1l0vjpp" /> <bpmn:sequenceFlow id="SequenceFlow_0y00p8b" sourceRef="Task_1l0vjpp" targetRef="Task_0p0dthr" /> <bpmn:sequenceFlow id="SequenceFlow_0azgsh3" sourceRef="Task_0p0dthr" targetRef="EvaluateProcess" /> <bpmn:sequenceFlow id="SequenceFlow_0bslxhz" sourceRef="Task_0ofwv70" targetRef="ExclusiveGateway_1cfwqqd" /> <bpmn:sequenceFlow id="SequenceFlow_125qqc9" name="Rejected" sourceRef="ExclusiveGateway_1cfwqqd" targetRef="Task_1uzfnxh"> <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression"><![CDATA[${NumOfApprove < RequiredNumOfApproval}]]></bpmn:conditionExpression> </bpmn:sequenceFlow> <bpmn:sequenceFlow id="SequenceFlow_0qvflnw" sourceRef="Task_1uzfnxh" targetRef="EndEvent_1mu7bj0" /> <bpmn:sequenceFlow id="SequenceFlow_06tfs2q" name="Approved" sourceRef="ExclusiveGateway_1cfwqqd" targetRef="Task_0o9iylr"> <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression"><![CDATA[${NumOfApprove >= RequiredNumOfApproval}]]></bpmn:conditionExpression> </bpmn:sequenceFlow> <bpmn:sequenceFlow id="SequenceFlow_04bpp14" sourceRef="Task_0o9iylr" targetRef="EndEvent_111ifpl" /> <bpmn:userTask id="Task_0o9iylr" name="Note Personnel File Appproved" camunda:assignee="mary"> <bpmn:extensionElements> <camunda:formData> <camunda:formField id="RequestNo" label="RequestNo" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="EmployeeId" label="EmployeeId" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="EmployeeName" label="EmployeeName" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="Position" label="Position" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No1Workmanship" label="No1Workmanship" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No2Workmanship" label="No2Workmanship" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No3Workmanship" label="No3Workmanship" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="RewardAmount" label="RewardAmount" type="long" defaultValue="10000"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="RewardStatus" label="RewardStatus" type="string" defaultValue="Approved"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> </camunda:formData> </bpmn:extensionElements> <bpmn:incoming>SequenceFlow_06tfs2q</bpmn:incoming> <bpmn:outgoing>SequenceFlow_04bpp14</bpmn:outgoing> </bpmn:userTask> <bpmn:endEvent id="EndEvent_111ifpl" name="End Approved"> <bpmn:incoming>SequenceFlow_04bpp14</bpmn:incoming> </bpmn:endEvent> <bpmn:endEvent id="EndEvent_1mu7bj0" name="End Reject"> <bpmn:incoming>SequenceFlow_0qvflnw</bpmn:incoming> </bpmn:endEvent> <bpmn:userTask id="Task_1uzfnxh" name="Note Personnel File Rejected" camunda:assignee="mary"> <bpmn:extensionElements> <camunda:formData> <camunda:formField id="RequestNo" label="RequestNo" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="EmployeeId" label="EmployeeId" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="EmployeeName" label="EmployeeName" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="Position" label="Position" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No1Workmanship" label="No1Workmanship" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No2Workmanship" label="No2Workmanship" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No3Workmanship" label="No3Workmanship" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="RewardAmount" label="RewardAmount" type="long" defaultValue="10000"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="RewardStatus" label="RewardStatus" type="string" defaultValue="Rejected"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> </camunda:formData> </bpmn:extensionElements> <bpmn:incoming>SequenceFlow_125qqc9</bpmn:incoming> <bpmn:outgoing>SequenceFlow_0qvflnw</bpmn:outgoing> </bpmn:userTask> <bpmn:sequenceFlow id="SequenceFlow_1a0h9gg" sourceRef="EvaluateProcess" targetRef="Task_0ofwv70" /> <bpmn:startEvent id="StartEvent_1" name="Enter Employee who shall receive Reward"> <bpmn:extensionElements> <camunda:formData> <camunda:formField id="RequestNo" label="RequestNo" type="string" defaultValue="-"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="EmployeeId" label="EmployeeId" type="string"> <camunda:validation> <camunda:constraint name="required" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="EmployeeName" label="EmployeeName" type="string"> <camunda:validation> <camunda:constraint name="required" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="Position" label="Position" type="string"> <camunda:validation> <camunda:constraint name="required" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No1Workmanship" label="No1Workmanship" type="string"> <camunda:validation> <camunda:constraint name="required" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No2Workmanship" label="No2Workmanship" type="string" defaultValue="-"> <camunda:validation> <camunda:constraint name="required" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No3Workmanship" label="No3Workmanship" type="string" defaultValue="-"> <camunda:validation> <camunda:constraint name="required" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="RewardAmount" label="RewardAmount" type="long" defaultValue="10000" /> </camunda:formData> </bpmn:extensionElements> <bpmn:outgoing>SequenceFlow_1nhdcp1</bpmn:outgoing> </bpmn:startEvent> <bpmn:userTask id="Task_1l0vjpp" name="Associate Reviews" camunda:assignee="mary"> <bpmn:extensionElements> <camunda:formData> <camunda:formField id="RequestNo" label="RequestNo" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="EmployeeId" label="ReviewEmployeeId" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="EmployeeName" label="ReviewEmployeeName" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="RequiredNumOfPeers" label="RequiredNumOfPeers" type="long" defaultValue="3" /> <camunda:formField id="RequiredMinNumofPeer" label="RequiredMinNumofPeer" type="long" defaultValue="2" /> <camunda:formField id="RequiredNumOfApproval" label="RequiredNumOfApproval" type="long" defaultValue="2" /> </camunda:formData> </bpmn:extensionElements> <bpmn:incoming>SequenceFlow_1nhdcp1</bpmn:incoming> <bpmn:outgoing>SequenceFlow_0y00p8b</bpmn:outgoing> </bpmn:userTask> <bpmn:scriptTask id="Task_0p0dthr" name="Setup Reviews" scriptFormat="groovy"> <bpmn:incoming>SequenceFlow_0y00p8b</bpmn:incoming> <bpmn:outgoing>SequenceFlow_0azgsh3</bpmn:outgoing> <bpmn:script><![CDATA[//create a collection to hold our multi-instance results. def committee = [ 'jame', 'john', 'peter']; //Create MAP def reviewResultMap = [:]; for (i = 0; i <RequiredNumOfPeers; i++) { reviewResultMap.put(committee[i], "NOT_REVIEW"); } execution.setVariable ("reviewResultMap", reviewResultMap); RequestNo= execution.getProcessInstanceId(); execution.setVariable ("RequestNo", RequestNo);]]></bpmn:script> </bpmn:scriptTask> <bpmn:subProcess id="EvaluateProcess" name="Evaluate Process"> <bpmn:documentation><![CDATA[ ]]></bpmn:documentation> <bpmn:extensionElements> <camunda:executionListener event="start"> <camunda:script scriptFormat="groovy"><![CDATA[execution.setVariable("reviewer", theCommitee,"EvaluateProcess"); execution.setVariable("reviewResult", "NOT_REVIEW","EvaluateProcess"); ]]></camunda:script> </camunda:executionListener> </bpmn:extensionElements> <bpmn:incoming>SequenceFlow_0azgsh3</bpmn:incoming> <bpmn:outgoing>SequenceFlow_1a0h9gg</bpmn:outgoing> <bpmn:multiInstanceLoopCharacteristics camunda:collection="${reviewResultMap.keySet()}" camunda:elementVariable="theCommitee"> <bpmn:loopCardinality xsi:type="bpmn:tFormalExpression">${RequiredNumOfPeers}</bpmn:loopCardinality> <bpmn:completionCondition xsi:type="bpmn:tFormalExpression"><![CDATA[${(nrOfCompletedInstances >= RequiredMinNumofPeer) && (reviewResultMap.size() == nrOfInstances)}]]></bpmn:completionCondition> </bpmn:multiInstanceLoopCharacteristics> <bpmn:startEvent id="StartEvent_04zeqi7"> <bpmn:outgoing>SequenceFlow_1es6rsf</bpmn:outgoing> </bpmn:startEvent> <bpmn:endEvent id="EndEvent_0ov7unr"> <bpmn:incoming>SequenceFlow_0r400ep</bpmn:incoming> </bpmn:endEvent> <bpmn:sequenceFlow id="SequenceFlow_1es6rsf" sourceRef="StartEvent_04zeqi7" targetRef="Task_0eroej3" /> <bpmn:sequenceFlow id="SequenceFlow_1cbnqvg" sourceRef="Task_0eroej3" targetRef="Task_07hvbtg" /> <bpmn:userTask id="Task_0eroej3" name="Evaluate Award" camunda:assignee="${theCommitee}"> <bpmn:documentation>Group RewardCommitee</bpmn:documentation> <bpmn:extensionElements> <camunda:formData> <camunda:formField id="RequestNo" label="RequestNo" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="EmployeeId" label="EmployeeId" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="EmployeeName" label="EmployeeName" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="Position" label="Position" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No1Workmanship" label="No1Workmanship" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No2Workmanship" label="No2Workmanship" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="No3Workmanship" label="No3Workmanship" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="RewardAmount" label="RewardAmount" type="long" defaultValue="10000"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="reviewer" label="reviewer" type="string"> <camunda:validation> <camunda:constraint name="readonly" config="true" /> </camunda:validation> </camunda:formField> <camunda:formField id="reviewResult" label="reviewResult" type="enum"> <camunda:value id="NOT_REVIEW" name="NOT_REVIEW" /> <camunda:value id="APPROVE" name="APPROVE" /> <camunda:value id="REJECT" name="REJECT" /> </camunda:formField> </camunda:formData> </bpmn:extensionElements> <bpmn:incoming>SequenceFlow_1es6rsf</bpmn:incoming> <bpmn:outgoing>SequenceFlow_1cbnqvg</bpmn:outgoing> </bpmn:userTask> <bpmn:scriptTask id="Task_07hvbtg" name="Update Result" scriptFormat="groovy"> <bpmn:incoming>SequenceFlow_1cbnqvg</bpmn:incoming> <bpmn:outgoing>SequenceFlow_0r400ep</bpmn:outgoing> <bpmn:script><![CDATA[/*อัพเดต Result */ reviewResultMap[reviewer] = reviewResult; out:println "review result on instance id: " + loopCounter + "-value-"+ reviewResultMap[reviewer] + "-by-" + reviewer; execution.setVariable ("reviewResultMap", reviewResultMap); ]]></bpmn:script> </bpmn:scriptTask> <bpmn:sequenceFlow id="SequenceFlow_0r400ep" sourceRef="Task_07hvbtg" targetRef="EndEvent_0ov7unr" /> </bpmn:subProcess> <bpmn:scriptTask id="Task_0ofwv70" name="Calulate results" scriptFormat="groovy"> <bpmn:incoming>SequenceFlow_1a0h9gg</bpmn:incoming> <bpmn:outgoing>SequenceFlow_0bslxhz</bpmn:outgoing> <bpmn:script><![CDATA[/*นับจำนวนคนที่ Approved พนักงาน */ //เอา Review Result ของแต่ละคนออกมา //นับผลลัพธ์ int numofApprove = 0; for (review in reviewResultMap) { out:println "review result:" + review.key + "--" + review.value; if(review.value =="APPROVE") { numofApprove += 1; } } execution.setVariable ("NumOfApprove", numofApprove);]]></bpmn:script> </bpmn:scriptTask> <bpmn:exclusiveGateway id="ExclusiveGateway_1cfwqqd" name="Is Appoved Award"> <bpmn:incoming>SequenceFlow_0bslxhz</bpmn:incoming> <bpmn:outgoing>SequenceFlow_06tfs2q</bpmn:outgoing> <bpmn:outgoing>SequenceFlow_125qqc9</bpmn:outgoing> </bpmn:exclusiveGateway> </bpmn:process> <bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1ukzxwm"> <bpmndi:BPMNShape id="StartEvent_04zeqi7_di" bpmnElement="StartEvent_04zeqi7"> <dc:Bounds x="263" y="265" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="236" y="305" width="90" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="EndEvent_0ov7unr_di" bpmnElement="EndEvent_0ov7unr"> <dc:Bounds x="564" y="265" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="537" y="305" width="90" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNEdge id="SequenceFlow_1es6rsf_di" bpmnElement="SequenceFlow_1es6rsf"> <di:waypoint xsi:type="dc:Point" x="299" y="283" /> <di:waypoint xsi:type="dc:Point" x="320" y="283" /> <bpmndi:BPMNLabel> <dc:Bounds x="264.5" y="262" width="90" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="SequenceFlow_1cbnqvg_di" bpmnElement="SequenceFlow_1cbnqvg"> <di:waypoint xsi:type="dc:Point" x="420" y="283" /> <di:waypoint xsi:type="dc:Point" x="444" y="283" /> <bpmndi:BPMNLabel> <dc:Bounds x="387" y="262" width="90" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNShape id="UserTask_10a4qhe_di" bpmnElement="Task_0eroej3"> <dc:Bounds x="320" y="243" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Participant_1jytf7q_di" bpmnElement="Participant_1jytf7q"> <dc:Bounds x="123" y="-60" width="1099" height="465" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> <dc:Bounds x="227" y="-23" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="202" y="17" width="85" height="36" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="UserTask_0rmfsuf_di" bpmnElement="Task_1l0vjpp"> <dc:Bounds x="332" y="-45" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="ScriptTask_0zxuyho_di" bpmnElement="Task_0p0dthr"> <dc:Bounds x="487" y="-45" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="UserTask_1wa2mm2_di" bpmnElement="Task_1uzfnxh"> <dc:Bounds x="935" y="57" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="UserTask_0b03w9m_di" bpmnElement="Task_0o9iylr"> <dc:Bounds x="935" y="-45" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="EndEvent_111ifpl_di" bpmnElement="EndEvent_111ifpl"> <dc:Bounds x="1111" y="-23" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="1095" y="17" width="69" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="EndEvent_1mu7bj0_di" bpmnElement="EndEvent_1mu7bj0"> <dc:Bounds x="1111" y="79" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="1103" y="119" width="54" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="ExclusiveGateway_1cfwqqd_di" bpmnElement="ExclusiveGateway_1cfwqqd" isMarkerVisible="true"> <dc:Bounds x="789" y="21" width="50" height="50" /> <bpmndi:BPMNLabel> <dc:Bounds x="722" y="15" width="89" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="ScriptTask_1og7wn4_di" bpmnElement="Task_0ofwv70"> <dc:Bounds x="676" y="241" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="SubProcess_1sva43h_di" bpmnElement="EvaluateProcess" isExpanded="true"> <dc:Bounds x="243" y="182" width="377" height="195" /> </bpmndi:BPMNShape> <bpmndi:BPMNEdge id="SequenceFlow_1nhdcp1_di" bpmnElement="SequenceFlow_1nhdcp1"> <di:waypoint xsi:type="dc:Point" x="263" y="-5" /> <di:waypoint xsi:type="dc:Point" x="332" y="-5" /> <bpmndi:BPMNLabel> <dc:Bounds x="252.5" y="-26" width="90" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="SequenceFlow_0y00p8b_di" bpmnElement="SequenceFlow_0y00p8b"> <di:waypoint xsi:type="dc:Point" x="432" y="-5" /> <di:waypoint xsi:type="dc:Point" x="487" y="-5" /> <bpmndi:BPMNLabel> <dc:Bounds x="414.5" y="-26" width="90" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="SequenceFlow_0azgsh3_di" bpmnElement="SequenceFlow_0azgsh3"> <di:waypoint xsi:type="dc:Point" x="537" y="35" /> <di:waypoint xsi:type="dc:Point" x="537" y="120" /> <di:waypoint xsi:type="dc:Point" x="207" y="120" /> <di:waypoint xsi:type="dc:Point" x="207" y="281" /> <di:waypoint xsi:type="dc:Point" x="243" y="281" /> <bpmndi:BPMNLabel> <dc:Bounds x="327" y="99" width="90" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="SequenceFlow_125qqc9_di" bpmnElement="SequenceFlow_125qqc9"> <di:waypoint xsi:type="dc:Point" x="814" y="71" /> <di:waypoint xsi:type="dc:Point" x="814" y="97" /> <di:waypoint xsi:type="dc:Point" x="935" y="97" /> <bpmndi:BPMNLabel> <dc:Bounds x="821" y="79" width="43" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="SequenceFlow_0qvflnw_di" bpmnElement="SequenceFlow_0qvflnw"> <di:waypoint xsi:type="dc:Point" x="1035" y="97" /> <di:waypoint xsi:type="dc:Point" x="1111" y="97" /> <bpmndi:BPMNLabel> <dc:Bounds x="1073" y="76" width="0" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="SequenceFlow_06tfs2q_di" bpmnElement="SequenceFlow_06tfs2q"> <di:waypoint xsi:type="dc:Point" x="814" y="21" /> <di:waypoint xsi:type="dc:Point" x="814" y="-5" /> <di:waypoint xsi:type="dc:Point" x="935" y="-5" /> <bpmndi:BPMNLabel> <dc:Bounds x="820" y="-25" width="48" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="SequenceFlow_04bpp14_di" bpmnElement="SequenceFlow_04bpp14"> <di:waypoint xsi:type="dc:Point" x="1035" y="-5" /> <di:waypoint xsi:type="dc:Point" x="1091" y="-5" /> <di:waypoint xsi:type="dc:Point" x="1091" y="-5" /> <di:waypoint xsi:type="dc:Point" x="1111" y="-5" /> <bpmndi:BPMNLabel> <dc:Bounds x="1106" y="-11" width="0" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="SequenceFlow_0bslxhz_di" bpmnElement="SequenceFlow_0bslxhz"> <di:waypoint xsi:type="dc:Point" x="726" y="241" /> <di:waypoint xsi:type="dc:Point" x="726" y="46" /> <di:waypoint xsi:type="dc:Point" x="789" y="46" /> <bpmndi:BPMNLabel> <dc:Bounds x="696" y="137.5" width="90" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="SequenceFlow_1a0h9gg_di" bpmnElement="SequenceFlow_1a0h9gg"> <di:waypoint xsi:type="dc:Point" x="620" y="281" /> <di:waypoint xsi:type="dc:Point" x="676" y="281" /> <bpmndi:BPMNLabel> <dc:Bounds x="603" y="260" width="90" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNShape id="Lane_0feow9m_di" bpmnElement="Lane_0feow9m"> <dc:Bounds x="153" y="163" width="1069" height="242" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Lane_0r1co7i_di" bpmnElement="Lane_0r1co7i"> <dc:Bounds x="153" y="-60" width="1069" height="223" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="ScriptTask_0hlg5fz_di" bpmnElement="Task_07hvbtg"> <dc:Bounds x="444" y="243" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNEdge id="SequenceFlow_0r400ep_di" bpmnElement="SequenceFlow_0r400ep"> <di:waypoint xsi:type="dc:Point" x="544" y="283" /> <di:waypoint xsi:type="dc:Point" x="564" y="283" /> <bpmndi:BPMNLabel> <dc:Bounds x="554" y="262" width="0" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </bpmn:definitions>