Skip to content

Scheduling a Process

Reviewed & updated pdexter 2022-10-21

This article demonstrates the setting of a process to occur once at a future date.

System Actions are used to schedule a process to occur once, via a ruleset, on a particular document at a particular future date/time.

For example, * A "Case" document has been set to Accepted and saved. * Once the Case is saved, it is required that a scheduled process fires after a number of hours, to check if the Case has been completed. * If the scheduled process finds that the Case is not Completed yet, it should email a supervisor that the Case is taking too long to complete.

System Action

A system action is a special document that is set to run a process once only at a specified future time.

System Action Process

A system action has associated with it the following properties needed to effect a timed process:

Property Description
document/data Data which contains reference to the document on which the action is to occur.
This may contain the entire document structure, but need only contain the documentId of the document.
dueDate Date/time at which the action is to occur.
ruleSet The ruleset to run.

A system action is generated through use of the ruleset function scheduleNewSystemAction.

System Action Lifecycle

  • An event on a document calls a corresponding ruleset (eg Case PreSaveServer)
  • This ruleset determines to create a system action for a later date (eg after Case Due Date has passed)
  • The system action is created, referencing both the document and a specific ruleset to run. It sits in the system, waiting to be run.
  • At (or very soon after) the trigger time, the system opens the system action, runs the corresponding ruleset with the original document reference.

Steps to Scheduling a Process

  • Define a System Action Ruleset
  • Script a System Action to use that ruleset

Defining a System Action Ruleset

  • Create a ruleset to run against the particular document type at the scheduled time.
  • Hint -- Be sure to name the ruleset clearly, as there is no other link to indicate the object it is working against. Eg "RKR Case CheckCompleted - OnSystemAction"
    NB -- This is the name used in the call to scheduleNewSystemAction later.
  • There is no need to link the ruleset to the particular document template, as would be required for other events.
  • Be aware, the ruleset will run server side only.

Note The passed document object to the ruleset (ntf.document) will NOT contain the current document as exists in the database; you will need to query for the current document, and perform the process with regard to the new state of the document.

Example Ruleset

// RuleSet: RKR Case CheckCompleted - OnSystemAction
// Updated by: peter.dexter@fieldtec.com 2018-08-17 15:15:30 +10:00
{
#include "JayRule Ruleset Overlay JS",

    ruleset : {
        name : 'RKR Case CheckCompleted - OnSystemAction',

        // ---------------------------------------------------------------------------
        // ruleGetCurrentDocument
        // ---------------------------------------------------------------------------
        ruleGetCurrentDocument : {
            ruleCondition : function(ntf) {
                return (!ntf.currentDocument);
            },

            ruleAction : function(ntf, callback) { 
                var ft3 = ntf.scope; 

                var eqry = {"query": {"bool": {"filter": [
                    {"term" : {"documentId" : (ntf.document.documentId || '0000')}}
                ]}}}; 

                ft3.findDocumentsByElastic(eqry, ntf.user.documentId, function(err, result) {
                    if (err) {
                        ntf.logger.error('Error in query: ' + err.message);
                    }
                    else if (result && result.data && result.data.hits && result.data.hits.total) {
                        ntf.currentDocument = result.data.hits.hits[0]._source;
                        ntf.logger.info('Found current document: ' + ntf.currentDocument.documentId);
                    }
                    else {
                        ntf.logger.error('XXX: No current document found.');
                    }
                    callback(ntf);
                });             
            }
        },

        // ---------------------------------------------------------------------------
        // ruleCheckStatus
        // ---------------------------------------------------------------------------
        ruleCheckStatus : {
            ruleCondition : function(ntf) {
                return (ntf.currentDocument);
            },

            ruleAction : function(ntf) { 
                if (ntf.currentDocument.status !== 'Completed') {
                    ntf.flagNotifySupervisor = true;
                }
            }
        },

        // ---------------------------------------------------------------------------
        // ruleNotifySupervisor
        // ---------------------------------------------------------------------------
        ruleNotifySupervisor : {
            ruleCondition : function(ntf) {
                return (ntf.flagNotifySupervisor);
            },

            ruleAction : function(ntf, callback) { 

                /// ... Send an email to the supervisor

            }
        }
    }
}

Scripting a System Action

Decide on what event you want to schedule a later process (eg on PreSaveServer of a Case).

Write script in the ruleset corresponding to that event, to schedule the calling of the scheduled System Action Ruleset at a future date.

To schedule a System Action, we use scheduleNewSystemAction. (See Function scheduleNewSystemAction )

Syntax

ft3.scheduleNewSystemAction(data, checkDate, objectEventDescriptor, user,
function(systemActionDocument, err) {
    ...
})

Part Description
data the data to pass to the system action ruleset
checkDate the date-time the system action should run
objectEventDescriptor the Name or Object Event Descriptor of the ruleset
user the user to use for the system action
systemActionDocument the newly created system action document
err any error that occurred; null if successful

Example Ruleset

{
#include "JayRule Ruleset Overlay JS",

    ruleset : {
        name : 'RKR Case - PreSaveServer',

        // ---------------------------------------------------------------------------
        // ruleScheduleCompleteCheck
        // If the status is Accepted, generate a system action to check again after 4 hours
        // --------------------------------------------------------------------------
        ruleScheduleCompleteCheck : {
            ruleCondition : function(ntf) { 
                return (
                    ntf.document.status === 'Accepted'    
                );
            },

            ruleAction : function(ntf, callback) { 
                var ft3 = ntf.scope; 

                var nbrMinutesToWait = 240;

                var checkDateM = ft3.moment().add(nbrMinutesToWait, 'minute');
                var checkDate = checkDateM.toDate();
                // OR
                var checkDate = new Date();
                checkDate.setMinutes(checkDate.getMinutes() + nbrMinutesToWait);

                // Create a stripped down version of the document to pass
                var dataToPass = {
                    documentId : ntf.document.documentId,
                    phaseId : '97016732',
                    note : 'document truncated - query for current'
                };

                ft3.scheduleNewSystemAction(docToPass, checkDate, 'RKR Case CheckCompleted - OnSystemAction', ntf.user, function(err, doc) {
                    if (err) {
                        ntf.logger.info(err.message);
                    }
                    else if (doc) {
                        ntf.logger.info('New system action created: ' + doc.documentId);
                    }
                    callback();
                });
            }
        }
    }
}

Note here that the data argument does not need to contain the full document object. It is normally wise that the scheduled process fetch the current document from the server/database when it fires, so we only really need to pass the documentId in the document argument object. Other information can also be passed with the data.