Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Function for Condition Control/Exclusive Gateway #196

Open
shaansriv opened this issue Nov 26, 2024 · 1 comment
Open

Custom Function for Condition Control/Exclusive Gateway #196

shaansriv opened this issue Nov 26, 2024 · 1 comment

Comments

@shaansriv
Copy link

shaansriv commented Nov 26, 2024

Hi, we have implement bpmn-js for our project and we are using bpmn-modeller to build flow xml which is used for AGI calling. The engine which we are using for bpmn flow execution during AGI call is bpmn-engine.
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","&lt;=","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","&gt;","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?

@paed01
Copy link
Owner

paed01 commented Nov 29, 2024

Firstly there is no need for eval when using javascript condition:

<conditionExpression xsi:type="tFormalExpression" language="javascript">next(null,this.environment.services.compareDate(this.environment.variables.ivrVar.payment.testingHeader.expiry, "&lt;=", new Date(), "MMYY"));</conditionExpression>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants