Useful scheduling scripts

A business rule script specifies the actions that the business rule takes. Scripts commonly include predefined global variables to reference items in your system, such as the current record. Global variables are available to all business rules.

Caution: The customization described here was developed for use in specific instances, and is not supported by ServiceNow Customer Support. This method is provided as-is and should be tested thoroughly before implementation. Post all questions and comments regarding this customization to our community forum.

Calculate duration given a schedule

Type: Before update/insert business rule

Table: Inicident

Description: A Business Duration calculates the Open to Close duration on an incident based on the particular Schedules. If there is no schedule specified, the script will simply use the first schedule returned by the query.

Script example:

The example below sets the resolved duration when the incident state moves to resolved.
if(current.incident_state==6){
  var dur = calcDurationSchedule(current.opened_at,current.sys_updated_on);
  current.u_resolved_duration= dur;
 
  function calcDurationSchedule(start, end){ 
  // Get the user   
  var usr =new GlideRecord('sys_user');
  usr.get(gs.getUserID());
  // Create schedule - pass in the sys_id of your standard work day schedule and pass in the users timezone
  var sched =new GlideSchedule('08fcd0830a0a0b2600079f56b1adb9ae',usr.time_zone);
  // Get duration based on schedule/timezone 
  return(sched.duration(start.getGlideObject(), end.getGlideObject()));}

Check upcoming termination dates

Type: Scheduled script

Description: This script checks nightly for termination dates on contracts coming up in 90, 50, or 10 days (depending on the contract duration field).

Script example:

function contractNoticeDue(){
var gr =new GlideRecord("contract");
gr.addQuery("u_contract_status","Active");
gr.query();
while(gr.next()){
  if((gr.u_termination_date<= gs.daysAgo(-90))&&(gr.u_contract_duration=="Long")){
    gr.u_contract_status="In review";}
  elseif((gr.u_termination_date<= gs.daysAgo(-50))&&(gr.u_contract_duration=="Medium")){
    gr.u_contract_status="In review";}
  elseif((gr.u_termination_date<= gs.daysAgo(-10))&&(gr.u_contract_duration=="Short")){
    gr.u_contract_status="In review";}
  gr.update();}
 
}
Use scripts in business rules to accomplish common tasks such as:
  • Comparing two date fields.
  • Parsing XML payloads.
  • Aborting a database action in a business rule.
With scripts, you can also:
  • Specify the operation that triggers the business rule.
  • Use the scratchpad with display business rules to change form values just before a user loads the form.
  • Use the OR condition like you would in a condition builder.

You can also utilize the system's scripting functionality available for server-side scripts.

You can use options on the Business Rules form to build conditions, set field values, and display alert messages without needing to write a script.

Abort a database action in a business rule

During a before business rule script, you can cancel or abort the current database action using the current.setAbortAction(true) method.

For example, if the before business rule is executed during an insert action, and you have a condition in the script that calls current.setAbortAction(true), the new record stored in current is not created in the database.

Add autofill functionality

Add autofill functionality is also called incident template, auto assignments, quick calls, call script, or auto populate.

Let's say you want to auto-fill your Short Description based on the Subcategory selected. First, create a lookup table, then populate the key field, in this case Subcategory and the auto-filled field, Short Description. So let's say your table had a record with Subcategory = Password and Short Description = Password Reset. When the user selects the subcategory of Password on the Incident form a client script looks up the matching record and sets short description equal to Password Reset. Client script settings... Type = onChange, Table name = incident, Field name = Subcategory.

function onChange(control, oldValue, newValue, isLoading) { 
  if (isLoading) { return; } 
  var newrec = gel('sys_row');
  //Check if new record
  if (newrec.value == -1) { 
    var lookup = new GlideRecord('u_short_desc_lookup'); 
    lookup.addQuery('u_subcategory', g_form.getValue('subcategory'));
    lookup.query();
    var temp; //temp var - reusable
    if (lookup.next()) {
      temp = lookup.u_short_description;
        if (null != temp) { //Set the form value from lookup if there is a lookup value
          g_form.setValue('short_description', temp); } 
        else {
          g_form.setValue('short_description', "" ); } } 
   else { 
     //If a lookup record does not exist based on lookup.addQuery 
     //Then set to UNDEFINED or NULL depending on type
      g_form.setValue('short_description', ""); } }
 
 }

You could populate many fields or even pull in call script questions into the Comments field so call center personnel gather good information to pass on to a technician. There are already Assignment Rule, Templates and Wizards built in that perform similiar functions.

Example script: A default before-query business rule

You can use a query business rule that executes before the database query is made to prevent users from accessing certain records.

Caution: The customization described here was developed for use in specific instances, and is not supported by ServiceNow Customer Support. This method is provided as-is and should be tested thoroughly before implementation. Post all questions and comments regarding this customization to our community forum.

Consider the following example from a default business rule that limits access to incident records.

Table 1. Default business rule limits access to incident records
Name Table When
incident query Incident before, query

Example script

This example prevents users from accessing incident records unless they have the itil role are listed in the Caller or Opened by field. So, for example, when self-service users open a list of incidents, they can only see the incidents they submitted.
if(!gs.hasRole("itil")&& gs.isInteractive()){
  var u = gs.getUserID();
  var qc = current.addQuery("caller_id", u).addOrCondition("opened_by", u).addOrCondition("watch_list","CONTAINS", u);
  gs.print("query restricted to user: "+ u);}
Note: You can also use access controls to restrict the records that users can see.

Schedule script for weekdays

Type: Business Rules/Client Scripts

This script schedules the script for weekdays. Insert any script where it says "Your Script Here."
var go ='false';
var now =new Date(); 
 
// Correct time zone, which is by default GMT -7 
now.setHours(now.getHours()+8);
var day = now.getDay(); 
 
// No go on Saturday or Sunday 
if(day !=0&& day !=6){
 
// (your script here)
 
}

Set date field according to current date

This script sets a date field depending on the current day of the week. In this example, if the day is Monday through Wednesday, it sets the date to this coming Monday; otherwise it sets the date field to next Monday.
function setCabDate(){
var today =new Date();
var thisDay = today.getDay();
//returns 0 for Sunday, 1 for Monday, etc. thru 6 for Saturday.
var thisMon =new GlideDateTime();
thisMon.setDisplayValue(gs.beginningOfThisWeek());
var nextMon = thisMon.getNumericValue();
nextMon +=(1000*60*60*24*7);
 
if((thisDay <4)&&(thisDay >0))
  //if today is Mon thru Wed (thisDay = 1, 2, or 3), set cab to this coming Monday.
  current.u_req_cab_rev_date.setDateNumericValue(thisMon.getNumericValue());
elseif((thisDay >=4)||(thisDay ==0))
  //if today is Thurs thru Sun (thisDay = 4, 5, 6, or 0), set cab to next Monday.
  current.u_req_cab_rev_date.setDateNumericValue(nextMon);
}

To validate the input of all date/time fields, you can use the following in a validation script (System Definition > Validation Scripts). Because the date/time format is hard coded in this script, it must match your instance's date/time format. If your instance's date/time format changes, you must update your validation script.

Set the validation script's type to Date/Time. Then, with this validation script, if a user enters an incorrect format in a date/time field, they will receive an error message.
function validate(value){
// empty fields are still valid dates 
if(!value)returntrue; 
 
// We "should" have the global date format defined always defined. but there's always that edge case... 
if(typeof g_user_date_time_format !=='undefined')return isDate(value, g_user_date_time_format); 
 
// if we don't have that defined, we can always try guessing 
return parseDate(value)!==null;}
Figure 1. Date/time validation