logo

NJP

Catalog Task Workflow Activity - How to execute code AFTER the task is created (eg. add checklists, etc)

Import · Oct 05, 2018 · article

We recently were asked to add checklists to some of our catalog tasks, so that our service desk could easily track the specific steps that needed to be taken for the completion of the catalog task.

Ideally, we would like to manage the checkbox creation from within the "Catalog Task Activity", to make configuration and maintenance easy. It also would mean that the configuration of the checklist is also tied nicely to the workflow version, in case things need to change over time.

Unfortunately, the catalog task's "Advanced Script" function seems to be executed before the catalog task is created, meaning we dont know the task's sysid, which is something we need in order to link a checklist to the resulting task.

Below is the solution we came up with. If anyone knows of a better way, I am always interested to hear it.

Cheers,

- James

Step 1: Script Include

We created a script include with a series of methods which will accept a catalog task, look for the associated workflow activity, find the "Advanced Script" function, parse that script and look for a given function, and then execute the code.

We also included some script to create a checklist.

var workflowTools = Class.create();
workflowTools.prototype = {
    initialize: function() {
    },
    createChecklist: function (table_name, record_sys_id, description, owner_sys_id){
    //Create Checklist
        var gr_checklist = new GlideRecord('checklist');
        gr_checklist.initialize(); 
        gr_checklist.table = table_name;
        gr_checklist.document = record_sys_id;
        gr_checklist.name = description;
        gr_checklist.owner = owner_sys_id; 
        return gr_checklist.insert();
    },
    addChecklistItem: function(checklist_sys_id, description, order){
        var gr_item = new GlideRecord('checklist_item');
        gr_item.checklist = checklist_sys_id;
        gr_item.complete = false;
        gr_item.name = description;
        gr_item.order = order;
        return gr_item.insert();
    },
    runScript: function(script, vars){
        //Thanks to https://community.servicenow.com/community?id=community_question&sys_id=881b8faddb5cdbc01dcaf3231f9619c1&view_source=searchResult
        var result;
        var evaluator = new GlideScopedEvaluator();   
        var gr = new GlideRecord('sys_script');   
        gr.addQuery('sys_policy','read'); //additional protection against accidental update
        gr.setLimit(1);   
        gr.query();   
        if (gr.next()) {
            gr.setValue('script',script);   
            try {
                result = evaluator.evaluateScript(gr, 'script', vars);
            } catch (e) {
                gs.error(e);
            }
        } else {
            throw new Error('No rows were found to dynamically use GlideScopedEvaluator against');
        }
        return result;
    },
    getExecutingActivityFromTask: function(task, document_sysid){
        //get all executing activities against the target document and find the one tied to this specific task
        var executingActivity;
        var gr_executingActivity = new GlideRecord('wf_executing');
        var join_wf_context = gr_executingActivity.addJoinQuery('wf_context', 'context', 'sys_id');
        join_wf_context.addCondition('id', "" + document_sysid);
        gr_executingActivity.query();
        while(gr_executingActivity.next()){
            if(gr_executingActivity.scratchpad.taskID == ("" + task.sys_id)){
                executingActivity = gr_executingActivity;
            }
        }
        return executingActivity;   
    },
    getScriptFunction: function(str_script, str_tag_start, str_tag_end){
        var str_function;
        if(str_script){
            if(str_script.length > 0){
                //Find start of Function.
                var int_startPos = str_script.indexOf(str_tag_start);
                if(int_startPos > -1){
                    //Found start of function
                    var int_endPos = str_script.indexOf(str_tag_end,int_startPos);
                    if(int_endPos > -1){
                        //Found end of function
                        str_function = str_script.substring(int_startPos,int_endPos+1);
                    }
                }
            }
        }
        return str_function;
    },
    callTaskFunction: function(functionName, task, document_table, document_sysid){
        //Get Corresponding wf_activity for this task
        var bool_processedSuccessfully = false;
        var executingActivity = this.getExecutingActivityFromTask(task, document_sysid);
        if(executingActivity){
            //Get task's advanced script
            var gr_varval = new GlideRecord('sys_variable_value');
            gr_varval.addQuery('document','wf_activity');
            gr_varval.addQuery('document_key',"" + executingActivity.activity);
            gr_varval.addQuery('variable','98b96f90c0a800666b58ec516f330397'); // Advanced Script
            gr_varval.query();
            while(gr_varval.next()){
                var str_fullscript = gr_varval.getValue('value');
                var str_function = this.getScriptFunction(str_fullscript, 'function ' + functionName + '(task,document){', '}//end' + functionName);
                if(str_function){
                    //Get Current Document Record
                    var gr_document = new GlideRecord(document_table);
                    if(gr_document.get(document_sysid)){
                        var vars = {'task' : task, 'document' : gr_document};
                        var result = this.runScript(str_function + ";" + functionName + "(task,document);", vars);
                        bool_processedSuccessfully = result.success;
                    }
                }
            }
        }
        return bool_processedSuccessfully;
    },
    type: 'workflowTools'
};

Step 2: Business Rule

We created a business rule that runs after each catalog task is created, and uses the above script to execute the function "onTaskCreated" within the catalog task's associated activity record's "Advanced Script" function.

Table: sc_task

When: async

Insert: Yes

Update: No
Script:

(function executeRule(current, previous /*null when async*/) {
    var wfTools = new workflowTools();

    //Process onClick script specified in Workflow Activity
    var bool_processedSuccessfully = wfTools.callTaskFunction('onTaskCreated', current, 'sc_req_item', "" + current.request_item);
})(current, previous);

Step 3: Add custom function in catalog task activity's Advanced Script:

// Set values for the task in this script.  Use the variable 'task' when setting additional values.
// Note: This script is run after the task values are set using the Fields, Template or Values you have specified.
//
// For example:
//     task.short_description = current.short_description;
function onTaskCreated(task,document){
    var wfTools = new workflowTools();
    var user_sys_id = '..your desired owner user account sysid here..'; 
    var checklist_sys_id = wfTools.createChecklist("sc_task", task.sys_id, "Reciept Checklist",user_sys_id);
    wfTools.addChecklistItem(checklist_sys_id, "Ship the phone", 0);
    wfTools.addChecklistItem(checklist_sys_id, "Have a beer", 1);   
}//endonTaskCreated

After the Catalog task activity generates its catalog task, the business rule fires and looks for the "onTaskCreated" function inside its associated activity and executes it. The checklist is created and linked to the catalog task.

Labels:

image

View original source

https://www.servicenow.com/community/developer-articles/catalog-task-workflow-activity-how-to-execute-code-after-the/ta-p/2327720