How to cancel workflow Timer and Wait for condition activities through script??
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-25-2019 11:31 AM
Hi,
I know its not a best practice to use script for cancelling of activities in a workflow. But my workflow is little different it branches to a timer and wait for condition. If one of it executes first the other one has to be cancelled. If timer runs off first it will hit a run script activity and script takes care of cancelling the wait for condition and vice versa. I got a piece of code from but wasn't successful using that as reference.( https://community.servicenow.com/community?id=community_question&sys_id=abe50361db1cdbc01dcaf3231f96...) The result is so in-consistent . Can someone please help me on how to handle this use case. (Below: Code Snippet from run script activity )
if(current.getValue('u_approved') == 'true'){
gs.info("In the if condition");
var gr = new GlideRecord('wf_executing');
var strQuery = '^state=waiting';
strQuery += '^context.id=' + current.sys_id;
strQuery += '^activity.name=Wait for Approved == true';
gr.addEncodedQuery(strQuery);
gr.query();
if (gr.next()) {
gs.info("After the wf_executing query to cancel timer");
var job = new GlideRecord('sys_trigger');
gs.info("In the sys_trigger query");
strQuery = 'state=0';
strQuery += '^document=wf_executing';
strQuery += '^document_key=' + gr.sys_id;
strQuery += '^name=WFTimer' + gr.sys_id;
job.addEncodedQuery(strQuery);
job.query();
if (job.next()) {
gs.info("In the sys_trigger to cancel the timer");
job.deleteRecord();
}
gr.state='cancelled';
gr.update();
}
}
else {
gs.info("In the else condition");
var waitForCond = new GlideRecord('wf_executing');
var strQuery = '^state=waiting';
strQuery += '^context.id=' + current.sys_id;
strQuery += '^activity.name=Wait for condition Approved == true';
waitForCond.addEncodedQuery(strQuery);
waitForCond.query();
if (waitForCond.next()) {
gs.info("After the wf_executing query to cancel wait for condition");
waitForCond.state='cancelled';
waitForCond.update();
}
}
Form :
Check the workflow below.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-25-2019 03:54 PM
I didn't understand your workflow. Why are you cancelling the activity in both the cases?
Ideally you shouldn't have the timer at all. You should run a schedule job to cancel the workflow, if the approval is not done after a particular time.
Actually why do you need the workflow, if you just need to send notification
Please mark this response as correct or helpful if it assisted you with your question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-26-2019 06:22 AM
Its a just a workflow i created that mocks the actual workflow from my company. The scenario is that we send a notification to manager and we give him 3 days to approve it(not a OOB approval process). If he approves it before timer expires, the wait for condition will execute and the workflow moves on , If i don't cancel the timer through some sort of script, the timer will still be in running state and once it expire that branch will also execute and it will the hit the next notification again. The senior manager will get the notification twice.
This approval process is repeated three times in the workflow ( for manager , senior manager and Vice president ) If i don't cancel the timer or wait for condition activities they will still be running and the senior manager will be get notifications twice, the Vice president will get it 4 times. My whole point in writing that script is to avoid sending multiple notifications.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-03-2020 05:08 PM
Hi Anu,
I've done something similar in a large workflow and coded it like this:
// Clean up listening activities
var wfEventListeners = [];
wfEventListeners.push("Rack Received");
wfEventListeners.push("PBC Validation Trigger");
wfEventListeners.push("SMI Completed");
var gr = new GlideRecord("wf_executing");
gr.addQuery("context", String(context.sys_id));
gr.query();
workflow.info("Total executing activities: " + gr.getRowCount());
while (gr.next()) {
if (gr.activity.activity_definition.name == "Wait for WF Event" || gr.activity.activity_definition.name == "Wait for condition") {
if (wfEventListeners.indexOf(String(gr.activity.name)) > -1) {
workflow.info("Found Wait for WF Event or Condition! - " + String(gr.sys_id));
(new global.GlideGlobalUtil()).deleteGlobalRecord(gr);
//gr.deleteRecord();
}
}
}
This code is implemented as a script workflow activity placed at the point in the workflow where you want to cleanup the listeners. The wfEventListeners array is just an array of the name value you gave to each of the listener activities you've implemented. The line (new global.GlideGlobalUtil()).deleteGlobalRecord(gr) is a custom globally scoped utility that I created as a helper, because this code is run from a workflow in a custom application scope, so if your workflow is global you can replace this line with gr.deleteRecord(). Hope this helps.