Skip to content

Commit

Permalink
Merge pull request #180 from ProcessMaker/feature/179
Browse files Browse the repository at this point in the history
Add event for conditioned transition
  • Loading branch information
caleeli authored Aug 19, 2020
2 parents 221b5da + 482fca4 commit 63ba5a3
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/ProcessMaker/Nayra/Bpmn/TransitionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace ProcessMaker\Nayra\Bpmn;

use ProcessMaker\Nayra\Bpmn\Models\Flow;
use ProcessMaker\Nayra\Contracts\Bpmn\CollectionInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\ConnectionInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\FlowElementInterface;
Expand Down Expand Up @@ -97,6 +98,18 @@ protected function conditionIsFalse()
*/
protected function doTransit(CollectionInterface $consumeTokens, ExecutionInstanceInterface $executionInstance)
{
if ($this instanceof ConditionedExclusiveTransition) {
$source = $this->outgoing()->item(0)->origin()->getOwner();
$target = $this->outgoing->item(0)->target()->getOwner();

// Find the flow that has the corresponding flow/source
$flow = $source->getOutgoingFlows()->findFirst(function ($flowElement) use ($target) {
return $flowElement->getTarget() === $target;
});

$this->notifyConditionedTransition(TransitionInterface::EVENT_CONDITIONED_TRANSITION, $this, $flow, $executionInstance);
}

$this->notifyEvent(TransitionInterface::EVENT_BEFORE_TRANSIT, $this, $consumeTokens);
$consumedTokensCount = $consumeTokens->count();
$consumeTokens->find(function (TokenInterface $token) use ($executionInstance) {
Expand All @@ -120,6 +133,18 @@ protected function doTransit(CollectionInterface $consumeTokens, ExecutionInstan
return true;
}

/**
* Notify in the bus that a conditioned transition has been activated
*
* @param $event
* @param mixed ...$arguments
*/
protected function notifyConditionedTransition($event, ...$arguments)
{
$this->getOwner()->getOwnerProcess()->getDispatcher()->dispatch($event, $arguments);
array_unshift($arguments, $event);
}

/**
* Evaluate and execute the transition rule.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface TransitionInterface extends ConnectionNodeInterface
const EVENT_BEFORE_TRANSIT = 'BeforeTransit';
const EVENT_AFTER_CONSUME = 'AfterConsume';
const EVENT_AFTER_TRANSIT = 'AfterTransit';
const EVENT_CONDITIONED_TRANSITION = 'ConditionedTransition';

/**
* Execute a transition.
Expand Down
38 changes: 38 additions & 0 deletions tests/Feature/Engine/ExclusiveGatewayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use ProcessMaker\Nayra\Contracts\Bpmn\ParallelGatewayInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\ProcessInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\StartEventInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\TransitionInterface;
use ProcessMaker\Nayra\Storage\BpmnDocument;

/**
* Test transitions
Expand Down Expand Up @@ -188,6 +190,7 @@ public function testExclusiveGateway()
GatewayInterface::EVENT_GATEWAY_TOKEN_ARRIVES,
GatewayInterface::EVENT_GATEWAY_ACTIVATED,
GatewayInterface::EVENT_GATEWAY_TOKEN_CONSUMED,
TransitionInterface::EVENT_CONDITIONED_TRANSITION,
GatewayInterface::EVENT_GATEWAY_TOKEN_PASSED,
ActivityInterface::EVENT_ACTIVITY_ACTIVATED,
]);
Expand Down Expand Up @@ -228,6 +231,7 @@ public function testExclusiveGatewayFirstConditionTrue()
GatewayInterface::EVENT_GATEWAY_TOKEN_ARRIVES,
GatewayInterface::EVENT_GATEWAY_ACTIVATED,
GatewayInterface::EVENT_GATEWAY_TOKEN_CONSUMED,
TransitionInterface::EVENT_CONDITIONED_TRANSITION,
GatewayInterface::EVENT_GATEWAY_TOKEN_PASSED,
ActivityInterface::EVENT_ACTIVITY_ACTIVATED,
]);
Expand Down Expand Up @@ -347,6 +351,7 @@ public function testParallelDivergingExclusiveConverging()
GatewayInterface::EVENT_GATEWAY_ACTIVATED,
GatewayInterface::EVENT_GATEWAY_TOKEN_CONSUMED,
ActivityInterface::EVENT_ACTIVITY_CLOSED,
TransitionInterface::EVENT_CONDITIONED_TRANSITION,
GatewayInterface::EVENT_GATEWAY_TOKEN_PASSED,
ActivityInterface::EVENT_ACTIVITY_ACTIVATED,
]);
Expand All @@ -363,6 +368,7 @@ public function testParallelDivergingExclusiveConverging()
GatewayInterface::EVENT_GATEWAY_ACTIVATED,
GatewayInterface::EVENT_GATEWAY_TOKEN_CONSUMED,
ActivityInterface::EVENT_ACTIVITY_CLOSED,
TransitionInterface::EVENT_CONDITIONED_TRANSITION,
GatewayInterface::EVENT_GATEWAY_TOKEN_PASSED,
ActivityInterface::EVENT_ACTIVITY_ACTIVATED,
]);
Expand Down Expand Up @@ -398,4 +404,36 @@ public function testParallelDivergingExclusiveConverging()
ProcessInterface::EVENT_PROCESS_INSTANCE_COMPLETED,
]);
}

public function testConditionalExclusiveParameters()
{
//Load a BpmnFile Repository
$bpmnRepository = new BpmnDocument();
$bpmnRepository->setEngine($this->engine);
$bpmnRepository->setFactory($this->repository);

$bpmnRepository->load(__DIR__ . '/files/ExclusiveGateway.bpmn');

//Create a data store with data.
$dataStore = $this->repository->createDataStore();
$dataStore->putData('Age', '8');

//Load a process from a bpmn repository by Id
$process = $bpmnRepository->getProcess('ExclusiveGatewayProcess');
$instance = $this->engine->createExecutionInstance($process, $dataStore);

//Get start event and event definition references
$start = $bpmnRepository->getStartEvent('StartEvent');
$activity1 = $bpmnRepository->getStartEvent('Exclusive1');


//Start the process
$start->start($instance);
$this->engine->runToNextState();

// Advance the first activity
$token0 = $activity1->getTokens($instance)->item(0);
$activity1->complete($token0);
$this->engine->runToNextState();
}
}
2 changes: 2 additions & 0 deletions tests/Feature/Engine/NayraModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use ProcessMaker\Nayra\Contracts\Bpmn\InclusiveGatewayInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\ProcessInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\StartEventInterface;
use ProcessMaker\Nayra\Contracts\Bpmn\TransitionInterface;
use ProcessMaker\Nayra\Contracts\RepositoryInterface;

/**
Expand Down Expand Up @@ -49,6 +50,7 @@ public function testProcessWithExclusiveGateway()
GatewayInterface::EVENT_GATEWAY_TOKEN_ARRIVES,
GatewayInterface::EVENT_GATEWAY_ACTIVATED,
GatewayInterface::EVENT_GATEWAY_TOKEN_CONSUMED,
TransitionInterface::EVENT_CONDITIONED_TRANSITION,
GatewayInterface::EVENT_GATEWAY_TOKEN_PASSED,
ActivityInterface::EVENT_ACTIVITY_ACTIVATED,
]);
Expand Down
41 changes: 41 additions & 0 deletions tests/Feature/Engine/files/ExclusiveGateway.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:pm="http://processmaker.com/BPMN/2.0/Schema.xsd" xmlns:tns="http://sourceforge.net/bpmn/definitions/_1530553328908" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://bpmn.io/schema/bpmn" exporter="ProcessMaker Modeler" exporterVersion="1.0" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://bpmn.sourceforge.net/schemas/BPMN20.xsd">
<bpmn:process id="ExclusiveGatewayProcess" name="ProcessName" isExecutable="true">
<bpmn:startEvent id="StartEvent" name="Start Event" pm:allowInterstitial="false">
<bpmn:outgoing>node_6</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:scriptTask id="Exclusive1" name="Exclusive1" pm:screenRef="27" pm:allowInterstitial="false" pm:assignment="requester">
<bpmn:incoming>node_6</bpmn:incoming>
<bpmn:outgoing>node_7</bpmn:outgoing>
<bpmn:script>CREATE_LOG_FILE</bpmn:script>
</bpmn:scriptTask>
<bpmn:exclusiveGateway id="node_3" name="Exclusive Gateway">
<bpmn:incoming>node_7</bpmn:incoming>
<bpmn:outgoing>node_8</bpmn:outgoing>
<bpmn:outgoing>node_9</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:scriptTask id="node_4" name="exclusive2" pm:screenRef="27" pm:allowInterstitial="false" pm:assignment="requester">
<bpmn:incoming>node_8</bpmn:incoming>
<bpmn:outgoing>node_11</bpmn:outgoing>
<bpmn:script>CREATE_LOG_FILE</bpmn:script>
</bpmn:scriptTask>
<bpmn:scriptTask id="node_5" name="Age&#60;=10" pm:screenRef="27" pm:allowInterstitial="false" pm:assignment="requester">
<bpmn:incoming>node_9</bpmn:incoming>
<bpmn:outgoing>node_12</bpmn:outgoing>
</bpmn:scriptTask>
<bpmn:sequenceFlow id="node_6" sourceRef="StartEvent" targetRef="Exclusive1" />
<bpmn:sequenceFlow id="node_7" sourceRef="Exclusive1" targetRef="node_3" />
<bpmn:sequenceFlow id="node_8" name="Mayor_10" sourceRef="node_3" targetRef="node_4">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">test.data['Age']&gt;10</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:sequenceFlow id="node_9" name="Menor_igual_10" sourceRef="node_3" targetRef="node_5">
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">test.data['Age']&lt;=10</bpmn:conditionExpression>
</bpmn:sequenceFlow>
<bpmn:endEvent id="node_10" name="End Event">
<bpmn:incoming>node_11</bpmn:incoming>
<bpmn:incoming>node_12</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="node_11" sourceRef="node_4" targetRef="node_10" />
<bpmn:sequenceFlow id="node_12" sourceRef="node_5" targetRef="node_10" />
</bpmn:process>
</bpmn:definitions>

0 comments on commit 63ba5a3

Please sign in to comment.