Useful Scheduling Scripts

From ServiceNow Wiki
Home > Script > Useful Scripts > Useful Scheduling Scripts
Jump to: navigation, search

This is a searchable version of the Useful Scheduling Scripts. For an easy-to-navigate version, visit the Useful Scripts portal.



Role required
Functionality described here requires the Admin role.
As-is functionality
Caution: The customization described here was developed for use in specific ServiceNow 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.

Name: Calculate Duration Given a Schedule

Type: Before Update/Insert Business Rule

Table: Incident

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

The example below sets the Resolved Duration field when the incident state moves to Resolved:

Condition: current.incident_state.changesTo(6)

Parameters:

Script:

Note
Note: This API call changed in the Calgary release:
  • GlideSchedule replaces Packages.com.glide.schedules.Schedule

The new script object calls apply to the Calgary release and beyond. For releases prior to Calgary, substitute the packages call as described above. Packages calls are not valid beginning with the Calgary release. For more information, see Scripting API Changes.

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()));
}
Role required
Functionality described here requires the Admin role.
As-is functionality
Caution: The customization described here was developed for use in specific ServiceNow 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.

Name: Check Upcoming Termination Dates

Type: Scheduled Script

Table:

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

Parameters:

Script:

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";
  } 
  else if ((gr.u_termination_date <= gs.daysAgo(-50)) && (gr.u_contract_duration == "Medium")) {
    gr.u_contract_status = "In review";
    } 
  else if ((gr.u_termination_date <= gs.daysAgo(-10)) && (gr.u_contract_duration == "Short")) {
    gr.u_contract_status = "In review";
    }
  gr.update();
  }
 
}

It is possible to compare two date fields (or two date/time fields) in a business rule, and abort a record insert or update if they're not correct. For example, you may want a "start" date to be before an "end" date.

Here's an example script that could be used in a business rule:

if ((!current.u_date1.nil()) && (!current.u_date2.nil())) {
  var start = current.u_date1.getGlideObject().getNumericValue();
  var end = current.u_date2.getGlideObject().getNumericValue();
  if (start > end) {
    gs.addInfoMessage('start must be before end');
    current.u_date1.setError('start must be before end');
    current.setAbortAction(true);
  }
}

It's a good idea to make the business rule a "before" business rule for your table, and probably good to have it active on both "insert" and "update".

  • u_date1 and u_date2 are simply the names of the two date fields. Replace with your own field names.
  • Above, the first line simply checks that both fields actually have a value.
  • The next two lines create variables that will have the dates' numerical values. Easier to compare this way.
  • The next two lines create different Alert Messages for the end user (one at the top of the form, one by the u_date1 field in the form).
  • The last line aborts the insert or update if the date fields aren't correct.


Here is a more complex example of the above comparison. If you have more than one start/end pair, you can use arrays as shown. Additionally, this script will require the input dates to be within a certain range, in this case, no fewer than 30 days previous, and no more than 365 days in the future.

Note
Note: This API call changed in the Calgary release:
  • GlideDateTime replaces Packages.com.glide.glideobject.GlideDateTime

The new script object calls apply to the Calgary release and beyond. For releases prior to Calgary, substitute the packages call as described above. Packages calls are not valid beginning with the Calgary release. For more information, see Scripting API Changes.

// Enter all start and end date fields you wish to check, as well as the previous values
// Make sure that you keep the placement in the sequence the same for all pairs
var startDate = new Array(current.start_date,current.work_start);
var prevStartDate = new Array(previous.start_date,previous.work_start);
var endDate = new Array(current.end_date,current.work_end);
var prevEndDate = new Array(previous.end_date,previous.work_end);
// the text string below will be added to the front of ' start must be before end'
var userAlert = new Array('Planned','Work');
 
// Set the number of Previous Days you want to check
var pd = 30;
// Det the number of Future Days you want to check
var fd = 365;
 
 
// You shouldn't have to modify anything below this line
 
var nowdt = new GlideDateTime();
nowdt.setDisplayValue(gs.nowDateTime());
var nowMs = nowdt.getNumericValue();
var pdms = nowMs;
//subtract the product of previous days to get value in milliseconds
pdms -= pd*24*60*60*1000;
var fdms = nowMs;
//add the product of future days to get value in miliseconds
fdms += fd*24*60*60*1000;
var badDate = false;
 
//Iterate through all start and end date / time fields
for(x = 0; x < startDate.length; x++) {
  if ((!startDate[x].nil()) && (!endDate[x].nil())) {
  var start = startDate[x].getGlideObject().getNumericValue();
  var end = endDate[x].getGlideObject().getNumericValue();
    if (start > end) {
      gs.addInfoMessage(userAlert[x] + ' start must be before end');
      startDate[x].setError(userAlert[x] + ' start must be before end');
      badDate = true;
    }
    else if ((prevStartDate[x]) != (startDate[x])){
      if (start < pdms){
        gs.addInfoMessage(userAlert[x] + ' start must be fewer than ' + pd + ' days ago');
        startDate[x].setError(userAlert[x] + ' start must be fewer than ' + pd + ' days ago');
        badDate = true;
      }
    }
    else if ((prevEndDate[x]) != (endDate[x])){
      if (end > fdms){
        gs.addInfoMessage(userAlert[x] + ' end must be fewer than ' + fd + ' days ahead');
        endDate[x].setError(userAlert[x] + ' end must be fewer than ' + fd + ' days ahead');
        badDate = true;
      }
    }
  }
}
if(badDate == true){
current.setAbortAction(true);
}
Role required
Functionality described here requires the Admin role.
As-is functionality
Caution: The customization described here was developed for use in specific ServiceNow 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.

Name: Schedule Script for Weekdays

Type: Business Rules/Client Scripts

Table:

Description: This script schedules the script for weekdays. Insert any script where it says "Your Script Here."

Parameters:

Script:

var now = new Date();
var day = now.getDay(); 
 
// do not run on saturday or sunday 
if (day != 0 && day != 6) { 
 
  // (your script here)
 
}
Role required
Functionality described here requires the Admin role.
As-is functionality
Caution: The customization described here was developed for use in specific ServiceNow 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.

Name: Set Date Field According To Current Date

Type:

Table:

Description: 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.

Parameters:

Script:

Note
Note: This API call changed in the Calgary release:
  • GlideDateTime replaces Packages.com.glide.glideobject.GlideDateTime

The new script object calls apply to the Calgary release and beyond. For releases prior to Calgary, substitute the packages call as described above. Packages calls are not valid beginning with the Calgary release. For more information, see Scripting API Changes.

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());
else if ((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 hardcoded 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 "glide_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) { 
  if (!value) {
    return true;
  }
  return (getDateFromFormat(value,'yyyy-MM-dd HH:mm:ss') != 0);
 
}


DateTimeValidation1.png

Was this article helpful?
Yes, I found what I needed
No, I need more assistance
Views
Personal tools