Range calculator scripts
Summarize
Summary of Range calculator scripts
Range calculator scripts enable you to define and enforce range restrictions and manage parent record updates within timeline pages in ServiceNow. These scripts are implemented as Script Includes and help customize how date ranges for child and parent records are calculated and synchronized, particularly for Agile development entities like sprints and releases.
Show less
Key Features
- ExampleUpdateParentsRangeCalculator: Automatically updates parent records (such as releases) when a child record's (such as a sprint) timeline span is moved or resized. It adjusts the parent’s start and end dates to encompass the child's new range.
- ExampleMinRangeCalculator: Calculates the earliest start date and latest end date across child records within a parent entity, returning details including IDs of records defining these boundaries.
- ExampleMaxRangeCalculator: Similar to the MinRangeCalculator but focuses on defining range boundaries from the perspective of the child record’s related parent record, ensuring the parent's dates reflect the child’s schedule.
- Date Conversion Utility Functions: Each script includes utility functions
getTimeMs()andgetTimeObject()to convert between GlideDateTime objects and milliseconds for accurate time comparisons and updates.
Practical Application for ServiceNow Customers
These script templates allow you to customize how timeline date ranges are maintained between hierarchical records, such as sprints and releases in Agile Development. By implementing these scripts, you can automate the synchronization of date fields, ensuring parent records always reflect the true span of their child records. This is crucial for accurate timeline visualization and project tracking within ServiceNow’s Agile or Release Management applications.
When customizing or creating your own range calculators:
- Use the provided script structure to implement your business logic for date range calculations.
- Leverage the date utility methods for consistent time conversion and comparison.
- Ensure that parent updates are triggered only when child spans change to maintain performance and data integrity.
This approach helps maintain accurate timelines and dependencies across related records, improving project visibility and management efficiency.
You can specify a script include that calculates range restrictions and processes parent updates in a timeline page.
Range Calculator Scripts
Following are three examples of script includes that help specify range restrictions.
ExampleUpdateParentsRangeCalculator
var ExampleUpdateParentsRangeCalculator = Class.create();
ExampleUpdateParentsRangeCalculator.prototype = {
initialize: function() { },
updateParents: function(id, table, startDate, endDate){
if (table == "rm_sprint"){
var releaseID;
var sprint = new GlideRecord(table);
sprint.addQuery('sys_id', id);
sprint.query();
if (sprint.next())
releaseID = sprint.release + "";
if (releaseID) {
var now_GR = new GlideRecord("rm_release_scrum");
gr.addQuery("sys_id", releaseID);
gr.query();
if (gr.next()) {
if (startDate && startDate < this.getTimeMs(gr.start_date))
gr.start_date = this.getTimeObject(startDate);
if (endDate && endDate > this.getTimeMs(gr.end_date))
gr.end_date = this.getTimeObject(endDate);
gr.update();
}
}
}
},
getMinRangeDetails: function(id, table){ return [-1, -1, "", ""]; },
getMaxRangeDetails: function(id, table){ return [-1, -1, ""]; },
getTimeMs: function(date){
return new GlideScheduleDateTime(date).getMS(); },
getTimeObject: function(timeMS) {
var gdt = new GlideDateTime();
gdt.setNumericValue(timeMS);
return gdt; },
logMessage: function(message){ gs.log(message); },
type: 'ExampleUpdateParentsRangeCalculator'
}In this example, the span is identified based on the id and table from function(id, table, startDate, endDate).
ExampleMinRangeCalculator
var ExampleMinRangeCalculator = Class.create();
ExampleMinRangeCalculator.prototype = {
initialize: function() { },
updateParents: function(id, table, startDate, endDate){ },
getMinRangeDetails: function(id, table){
var min = -1;
var max = -1;
var minID = "";
var maxID = "";
if (table == "rm_release_scrum"){
var now_GR = new GlideRecord("rm_sprint");
gr.addQuery("release", id);
gr.query();
while(gr.next()){
var start = this.getTimeMs(gr["start_date"]);
var end = this.getTimeMs(gr["end_date"]);
var id = gr["sys_id"];
if (min == - 1 || start <= min){
if (start != min)
minID = "";
min = start;
minID += "," + id;
}
if (max == -1 || end >= max){
if (end != max)
maxID = "";
max = end;
maxID += "," + id;
}
}
}
return [min, max, minID, maxID];
},
getMaxRangeDetails: function(id, table){ return [-1, -1, ""]; },
getTimeMs: function(date){ return new GlideScheduleDateTime(date).getMS(); },
getTimeObject: function(timeMS) {
var gdt = new GlideDateTime();
gdt.setNumericValue(timeMS);
return gdt; },
logMessage: function(message){ gs.log(message); },
type: 'ExampleUpdateParentsRangeCalculator'
}ExampleMaxRangeCalculator
var ExampleMaxRangeCalculator = Class.create();
ExampleMaxRangeCalculator.prototype = {
initialize: function() { },
updateParents: function(id, table, startDate, endDate){ },
getMinRangeDetails: function(id, table){ return [-1, -1, "", ""]; },
getMaxRangeDetails: function(id, table){
if (table == "rm_sprint"){
var sprint = new GlideRecord(table);
sprint.addQuery('sys_id', id);
sprint.query();
if (sprint.next())
releaseID = sprint.release + "";
if (releaseID) {
var now_GR = new GlideRecord("rm_release_scrum");
gr.addQuery("sys_id", releaseID);
gr.query();
if (gr.next())
return [this.getTimeMs(gr.start_date),
this.getTimeMs(gr.end_date), gr.sys_id];
}
}
return [-1, -1, ""];
},
getTimeMs: function(date){ return new ScheduleDateTime(date).getMS(); },
getTimeObject: function(timeMS) {
var gdt = new GlideDateTime();
gdt.setNumericValue(timeMS);
return gdt; },
logMessage: function(message){ gs.log(message); },
type: 'ExampleUpdateParentsRangeCalculator'
}getTimeMs: function(date){
return new ScheduleDateTime(date).getMS();
}
getTimeObject: function(timeMS) {
var gdt = new GlideDateTime();
gdt.setNumericValue(timeMS);
return gdt;
}