THURSDAY, FEBRUARY 09, 2012

Canceling executing workflows on task closure

S

ervice-now.com provides a very robust and simple way to manage your tasks and approvals (among other things) through its graphical workflow engine.  It is very common to use graphical workflow to help facilitate some change management process within your organization.  One common requirement in change management is to be able to cancel or close the change request at any time during the process.  “Simple”, you say.  “Just allow the user to change the value of the ‘State’ field to ‘Closed’.”

You would not be incorrect in saying something like that, but you would be forgetting about part of the problem with closing or canceling a change request or other task ticket.  What if the attached workflow(s) still think that the change request and its associated tasks and approvals are still in progress?  Should the attached workflow context(s) continue to run indefinitely?  If your workflow doesn’t have a way to know about the completion of the change request then it will continue to run (or more likely just sit and be forgotten).

The answer to this problem is actually pretty simple.  Service-now.com comes with several out-of-box workflow utility functions defined under ‘System Definition -> Script Includes’ that can be helpful in situations like these.  While you don’t want to modify these script includes, it is probably a good idea as a Service-now administrator to become familiar with the tools and functions there.  One of the functions in the ‘Workflow’ script include is called ‘cancel’.  It can be used to cancel any running workflow activities for a given record. This script could be called from a UI action button, another workflow, or a business rule. You just need to be able to tell the function what GlideRecord should have its workflows canceled. The example below shows how you could create a business rule to cancel all running workflows for a given record if the ‘active’ field changed to ‘false’. The cancellation in the example below happens for the ‘current’ GlideRecord object (which is the current record being updated).

Cancel All Workflow Contexts for a given Record

Cancel Workflow Business Rule
Name: Cancel workflows
When: After
Insert: True
Update: True
Condition: current.active.changesTo(false)
Script:

//Query for all executing workflows and cancel any running activities
new Workflow().cancel(current);


Cancel a Single Workflow Context (by name) for a given Record

You may also encounter situations where you don’t want to cancel all associated workflow contexts, just a single one, or all but one. Again, you can find the solution in the ‘Workflow’ script include by way of the ‘getRunningFlows’ and ‘cancelContext’ functions. The following script could be run from a business rule, UI action, or even within a ‘Run Script’ workflow activity. The example given here cancels any ‘Routine Change’ workflow contexts associated with the ‘current’ record.

//Query for all executing workflow contexts
var flows = new Workflow().getRunningFlows(current);
while(flows.next()){
   //Check for associated workflows by name
   if(flows.workflow_version.getDisplayValue() == 'Routine Change'){
      //Cancel the workflow context
      new Workflow().cancelContext(flows);
   }   
}

Comments

Posted On
Dec 29, 2009
Posted By
alli

thanks for this

was very helpful, was looking for workflow scripts in the wiki, couldn’t find any

I’ll bookmark this site

cheers

Posted On
Jan 04, 2010
Posted By
Mark Stanger

I’m glad you found something that works for you. Thanks for your comments. I’m hoping to continue to build out this site with useful content that might not be as prominent on other sites. Please use the ‘Ask The Guru’ link to post any suggestions for the site or content. I’d love to hear your suggestions.

Posted On
Apr 23, 2010
Posted By
jointheclub

What is the best practice to implement this? A business rule on the table? e.g. if task set to closed, then run. Or run as a job periodically? The example above shows query, then run the cancel method. If I were to implement it as a business rule what exactly would I call (just Workflow().cancel(current); )? let me know the best way to accomplish this.

Posted On
Apr 23, 2010
Posted By
Mark Stanger

You’re right, that was kind of vague. I’ve updated the document above to add a little bit more clarity. Probably the best way to implement this is in a business rule on the table where the cancellation takes place.

Posted On
May 03, 2010
Posted By
alli

Hi Mark,

what if I don’t want the approvals to get cancelled, just the workflow?

as of now, all approvals even approved changed to cancelled. we need to know who approved or not in a change.

is this possible?

thanks

Alli

Posted On
Jun 24, 2010
Posted By
Arun

Hi Mark,

Is it possible to delete a workflow context from a business rule, We have situation, where if the user changes the environment we need to trigger a new workflow, the old one must be deleted.

Thanks

Arun

Posted On
Jun 25, 2010
Posted By
Mark Stanger

You can simply by performing a GlideRecord query. It’s probably better though to just cancel as shown above and then set the conditions on your other workflow so that it attaches when the environment changes.

Leave a Reply


Notify me of followup comments via e-mail. You can also subscribe without commenting.

Latest Comments

  • Aric: Finally figured out what I was doing wrong, incase someone else wants to do this. Mark is correct about needing...
  • Mark Stanger: You’ll probably need at least 3 total ACLs then. You’ll need one...
  • Mark Stanger: Hey Paul, I assume you’re talking about ‘task_ci’, not ‘task_group. If so, the...
  • ND: Hi Mark, This is cool. How can I do same at the form level. I have created a slushbucket variable and I want to...