Sunday 24 April 2016

End BPM process instance on a given day of month

Use case:
We need to end (close) a process instance on a given day of month. To further complicate things let's assume that a day is not fixed. An admin should be able to change the end day without re-deploying the BPM project.

With 11gR1 (11.1.1.7) you can achieve the purpose by adding timer boundary event (make it the "Interrupting Event"), choosing a "Time Cycle" type and setting the boundary timer event to kick in, let's say every 12 hours. This does exactly what you want, but it kicks in every 12 hours and creates a task every 12 hours and closes it if the down the flow condition is not met.

Instead we can try another approach.

Set the timer type to "Time Cycle" and check the "Use Expression" attribute.

Write an expression, in my case it is:

oraext:query-database(concat('SELECT GET_CLOSURE_DURATION(', "'", bpmn:getDataObject('applicationDataDO')/ns:applicationId, "'" ,') NEXTDAY FROM dual'),false(),false(),'jdbc/DATASOURCE')

where get_closure_duration(applicationid in varchar2) is a function, which returns duration in the P1Y1DT1H1S - One year, one day, one hour and one second form. The function parameter applicationid is used to further fine tune the result.

Now we write the get_closure_duration function in a such a way, that it returns the duration. For demonstration purposes, I set the end date to be 7th day of the next month at 10 PM:

FUNCTION GET_CLOSURE_DURATION(
    APPLICATIONID VARCHAR2)
  RETURN VARCHAR2
IS
  NEXTDAY   NUMBER;
  NEXTDATE  DATE;
BEGIN
NEXTDAY:=7;
NEXTDATE:=TRUNC(LAST_DAY(SYSDATE) +NEXTDAY) + 22/24;

RETURN 'P'|| TRUNC(months_between(NEXTDATE, SYSDATE) /12) ||'Y'|| mod(TRUNC(months_between(NEXTDATE, SYSDATE)),
  12) ||'M'|| TRUNC(NEXTDATE-SYSDATE) || 'DT'|| TRUNC(mod((NEXTDATE-SYSDATE) *24, 24)) ||'H'|| TRUNC(mod((NEXTDATE  -  SYSDATE) *24*60, 60)) ||'M';

END GET_CLOSURE_DURATION;

E.g, to close the application on 07-MAY-16 at 22:00 the GET_CLOSURE_DURATION function gave P0Y0M6DT7H14M when run at 24-APR-16 14:45.