Hi, we have implement bpmn-js for our project and are using bpmn-modeller to build flow xml which is used for AGI calling.
BPMN provides condition control component (also known as Exclusive Gateway), for which a string is saved in sequenceFlow tag which is executed only when the condition is true.
For example:
<sequenceFlow id="Flow_0zfcb76" sourceRef="Gateway_0z1dp2u" targetRef="Activity_0zkrwq8">
<conditionExpression xsi:type="tFormalExpression" language="javascript">next(null,this.environment.variables.test1 === "IS_DUPLICATE");</conditionExpression>
</sequenceFlow>
<sequenceFlow id="Flow_0bkz9zr" sourceRef="Gateway_0z1dp2u" targetRef="Event_03wrqjm">
<conditionExpression xsi:type="tFormalExpression" language="javascript">next(null,this.environment.variables.test1 !== "IS_DUPLICATE");</conditionExpression>
</sequenceFlow>
which is working perfectly fine.
But now I want that instead of writing comparison string, I call a function for the same, which is already present in this.environment.services.
So, after implementing, XML generated is as follows:
<sequenceFlow id="Flow_1a5xpmo" sourceRef="Gateway_0rubtqe" targetRef="Activity_0009n6k">
<conditionExpression xsi:type="tFormalExpression" language="javascript">next(null,this.environment.services.compareDate(this.environment.variables.ivrVar,"payment.testingHeader.expiry","<=","new Date()","MMYY"));</conditionExpression>
</sequenceFlow>
<sequenceFlow id="Flow_1ki3yf7" sourceRef="Gateway_0rubtqe" targetRef="Activity_0q4maht">
<conditionExpression xsi:type="tFormalExpression" language="javascript">next(null,this.environment.services.compareDate(this.environment.variables.ivrVar,"payment.testingHeader.expiry",">","new Date()","MMYY"));</conditionExpression>
</sequenceFlow>
And the function compareDate:
async function compareDate1(ivrVar, variable, operator, value, dateFormat) {
console.log("comparing date");
const keys = variable.split('.');
// Use reduce to iterate over the keys and access the value dynamically
let date = keys.reduce((acc, key) => acc[key], ivrVar);
const formattedDate = DateUtil.format({dateString:date, sourceDateFormat:dateFormat, targetDateFormat:"YYYY-MM-DD"});
// Convert formattedDate to a Date object to compare
const formattedDateObj = new Date(formattedDate);
const currDateObj = eval(value);
// Compare the two Date objects using the operator
let result;
switch (operator) {
case '<=':
result = formattedDateObj <= currDateObj;
break;
case '>=':
result = formattedDateObj >= currDateObj;
break;
case '>':
result = formattedDateObj > currDateObj;
break;
case '<':
result = formattedDateObj < currDateObj;
break;
case '===':
result = formattedDateObj === currDateObj;
break;
case '!==':
result = formattedDateObj !== currDateObj;
break;
default:
result = false; // In case of an invalid operator
}
return result;
}
For the first sequence flow, it returns false, so ideally it should move the execution to second sequence flow and same function should be executed again to check the case, but after first sequence flow only the execution moves to the targetRef of first sequence flow.
Current scenario:
- First sequence flow executes the function compareDate.
- False is returned from compareDate as per use case.
- Now the execution goes to targetRef of first sequence flow, despite of the function returning false.
Expected behaviour:
- First sequence flow executes the function compareDate.
- False is returned from compareDate as per use case.
- So the execution should now go for second sequence flow.
- If the function compareDate returns true now, then the flow should move to targetRef of second sequence flow.
Can someone please assist with this issue?