Skip to main content

ServiceNow 3-strike rule on RITM (auto-close Service Request in awaiting customer)

ServiceNow 3-strike rule on RITM (auto-close Service Request in awaiting customer)


(ordinarily for incident Flow Designer might be used)

alas, on New York version this is not possible, and below is a business rule + scheduled job option to avoid having to update all the RITM workflows (though a second workflow to attach to the RITM could be an alternative option)

in this particular solution, the customer carried out work at the RITM level as catalog tasks were not yet being used by the fulfilment teams

Code assumes a custom field u_closure_code is used on the RITM table

3-strike rule for RITMs


Contents

How it works

Build

New fields

Business rules

Event registry

ACLs

Scheduled job

Notification

How to test

Scheduled job script

 

How it works

 

·       When an RITM is placed in state=on hold and on hold reason=awaiting caller, a business rule will populate a new field:

 


 

This field will not be editable by ITIL users or placed on the form but is viewable via list view.

 

·       A scheduled job will run daily at 21h and will check for all active RITMs with this new date field populated where the date is > one day ago. The job will not run on Saturdays, Sundays or Mondays to account for weekends.

·       If such requests are located, the following actions will take place

o   Chase up notification is sent to the user

o   An additional custom field is populated:


o   The awaiting customer date is re-set to the date the scheduled job is run



·       Simultaneously, the scheduled job checks for RITMs where the follow up email sent is true and the awaiting customer date is > 2days ago, and if such tickets are located, they are auto-closed. Close code and notes set as follows:


 

·       If a response is received from the customer or the RITM is otherwise changed from awaiting caller, the awaiting customer date and follow up email will be re-set to blank / false

 

Build

New fields

 


Business rules

 

Business rule

Purpose

RITM awaiting customer

 

Set the ‘Awaiting customer date’ to today’s date if the on hold reason changes to 'awaiting caller'


current.u_awaiting_customer_date.setDisplayValue(gs.nowDateTime());
RITM clear date and flag

 

Reset the ‘Awaiting customer date’ and ‘Follow up email sent’ so the scheduled job ignores the record, as the RITM is no longer in awaiting caller state


if (previous.u_hold_reason == 1 && current.u_hold_reason != 1) { if (!gs.nil(current.u_awaiting_customer_date)) { current.u_awaiting_customer_date = ""; current.u_follow_up_email_sent = false; } }

 

 

 

Event registry (RITM table)

 

Used to queue the notification within the scheduled job script

emailcaller.reminder.ritm

 

ACLs

Restrict write access to the new fields to sys admins


Scheduled job (see further down for copy script)

 

“Send chase up email or close RITM - awaiting customer”

Dual purpose:

·       Send follow up reminder email for awaiting customer RITMs where the ticket was set to awaiting customer > 1 day ago

·       Auto-close RITMs which previously were set to awaiting customer and the follow up email flag was set to true

The job will not execute on Saturday, Sunday, Monday to exclude weekends

 

Notification

 

3-strike chase-Await cust response RITM

 

How to test

 

·       Go to a RITM and set it to on hold>  awaiting caller

·       Verify that the Awaiting Customer date is set


·       Either wait a day or 2, or from list view manually set the Awaiting Customer date field to > 2 days ago

·       Execute the scheduled job, and check the email logs for the chase-up email (and check servicenowtest mailbox)

·       Verify that the job has also set the Follow up email flag to true (from the RITM list) and has now re-set the Awaiting customer date to today’s date

·       Verify that replies from the customer will set the ticket back to in progress and the job will skip over them (fields are reset and thus the record is excluded)

·       If the RITM is still awaiting customer with the Follow up email flag set to true, update the Awaiting customer to > 2 days ago and execute the scheduled job

·       Verify that the RITM is closed with close code and notes populated

 

Scheduled job script:

//--RDS CloudMinus89 Ltd, June2020 //--for 3 strike rule on requests //--in conjunction with business rule //--don't run it on a Sat, Sun var sDateQuery='u_awaiting_customer_dateRELATIVELE@hour@ago@24';//updated over 24 hours ago var d = new Date(); var n = d.getDay(); //--Sunday is 0, Monday is 1, and so on. if (n != 6 && n != 0) { chaseAwaitingCustomer(sDateQuery); gs.sleep (2000); autoCloseRITMs(sDateQuery); } function chaseAwaitingCustomer(sDateQuery) { var grRITMs = new GlideRecord('sc_req_item'); grRITMs.addActiveQuery(); grRITMs.addQuery('u_hold_reason=1'); //--awaiting caller grRITMs.addQuery('u_follow_up_email_sent', 'false'); grRITMs.addQuery(sDateQuery); grRITMs.query(); while (grRITMs.next()) { gs.eventQueue("cu.emailcaller.reminder.ritm", grRITMs, "", ""); grRITMs.u_awaiting_customer_date.setDisplayValue(gs.nowDateTime()); //--reset the date counter grRITMs.u_follow_up_email_sent = true; grRITMs.update(); } } function autoCloseRITMs(sDateQuery) { var grRITMs_C = new GlideRecord('sc_req_item'); grRITMs_C.addActiveQuery(); grRITMs_C.addQuery('u_hold_reason=1'); //--awaiting caller grRITMs_C.addQuery('u_follow_up_email_sent', 'true'); grRITMs_C.addQuery(sDateQuery); grRITMs_C.query(); while (grRITMs_C.next()) { grRITMs_C.state=3; grRITMs_C.close_notes='No Response from User'; grRITMs_C.u_closure_code='No Response from User'; grRITMs_C.update(); gs.log(grRITMs_C.number, "schJob:autoCloseRITMs"); } }

Comments

Popular posts from this blog

ServiceNow check for null or nil or empty (or not)

Haven't tested these all recently within global/local scopes, so feel free to have a play! option 1 use an encoded query embedded in the GlideRecord , e.g.  var grProf = new GlideRecord ( 'x_cls_clear_skye_i_profile' ); grProf . addQuery ( 'status=1^ owner=NULL ' ); grProf . query (); even better use the glideRecord  addNotNullQuery or addNullQuery option 2 JSUtil.nil / notNil (this might be the most powerful. See this link ) example: if ( current . operation () == 'insert' && JSUtil . notNil ( current . parent ) && ! current . work_effort . nil ())  option 3 there might be times when you need to get inside the GlideRecord and perform the check there, for example if the code goes down 2 optional routes depending on null / not null can use gs.nil : var grAppr = new GlideRecord ( 'sysapproval_approver' ); var grUser = new GlideRecord ( 'sys_user' ); if ( grUser . get ( 'sys_id' , current . approver )){...

Code a pause/wait - gs.sleep or gs.wait alternative, pause script for specified seconds (timer)

Code a pause/wait - gs.sleep / gs.wait alternative, pause script for specified seconds (timer)  e.g. 10 seconds: do_sleep ( 10000 ); function do_sleep ( milliseconds ) { var start = new Date (). getTime (); for ( var i = 0 ; i < 1e7 ; i ++) { if (( new Date (). getTime () - start ) > milliseconds ){ gs . print ( 'waking up!' ); break ; } } }