Server-side
// SLA Escalation Business Rule - runs on SLA Definition table
// Trigger: After Update, When: SLA State changes
(function executeRule(current, previous) {
var slaEscalationUtil = new SLAEscalationUtil();
// Check if SLA has reached 50% (warning) threshold
if (current.percentage.toString() >= '50' && previous.percentage.toString() < '50') {
slaEscalationUtil.handleWarningEscalation(current);
}
// Check if SLA has reached 80% (critical) threshold
if (current.percentage.toString() >= '80' && previous.percentage.toString() < '80') {
slaEscalationUtil.handleCriticalEscalation(current);
}
// Check if SLA has breached (100%)
if (current.stage.toString() == 'breached' && previous.stage.toString() != 'breached') {
slaEscalationUtil.handleBreachEscalation(current);
}
})(current, previous);
// Script Include for SLA Escalation Logic
var SLAEscalationUtil = Class.create();
SLAEscalationUtil.prototype = {
initialize: function() {
this.notificationUtil = new GlideEmailOutbound();
},
handleWarningEscalation: function(slaGR) {
var taskGR = this._getTaskRecord(slaGR.task.toString());
if (!taskGR.isValidRecord()) return;
// Send warning notification to assigned user and group
this._sendNotification(taskGR.assigned_to.toString(), 'SLA Warning',
'SLA ' + slaGR.sla.name + ' is at 50% for ' + taskGR.number);
if (taskGR.assignment_group.toString()) {
this._notifyGroup(taskGR.assignment_group.toString(), 'SLA_WARNING', taskGR);
}
// Log the escalation
gs.log('SLA Warning escalation triggered for task: ' + taskGR.number +
', SLA: ' + slaGR.sla.name, 'SLAEscalation');
},
handleCriticalEscalation: function(slaGR) {
var taskGR = this._getTaskRecord(slaGR.task.toString());
if (!taskGR.isValidRecord()) return;
// Escalate to management and higher tier group
var escalationGroup = this._getEscalationGroup(taskGR.assignment_group.toString());
if (escalationGroup) {
taskGR.assignment_group = escalationGroup;
taskGR.assigned_to = '';
taskGR.work_notes = 'Auto-escalated due to SLA critical threshold (80%)';
taskGR.update();
}
// Notify management chain
this._notifyManagementChain(taskGR, 'SLA_CRITICAL');
gs.log('SLA Critical escalation triggered for task: ' + taskGR.number, 'SLAEscalation');
},
handleBreachEscalation: function(slaGR) {
var taskGR = this._getTaskRecord(slaGR.task.toString());
if (!taskGR.isValidRecord()) return;
// Set high priority and escalate to senior management
taskGR.priority = '1';
taskGR.escalation = '3'; // Highest escalation level
taskGR.work_notes = 'SLA BREACHED - Auto-escalated to senior management';
// Reassign to breach handling group
var breachGroup = gs.getProperty('sla.breach.assignment.group', '');
if (breachGroup) {
taskGR.assignment_group = breachGroup;
taskGR.assigned_to = '';
}
taskGR.update();
// Send breach notifications to all stakeholders
this._sendBreachNotifications(taskGR, slaGR);
// Create escalation task for management follow-up
this._createEscalationTask(taskGR, slaGR);
gs.log('SLA BREACH escalation triggered for task: ' + taskGR.number, 'SLAEscalation');
},
_getTaskRecord: function(taskSysId) {
var taskGR = new GlideRecord('task');
taskGR.get(taskSysId);
return taskGR;
},
_getEscalationGroup: function(currentGroupId) {
var groupGR = new GlideRecord('sys_user_group');
if (groupGR.get(currentGroupId)) {
// Look for escalation group in custom field or use parent group
if (groupGR.u_escalation_group.toString()) {
return groupGR.u_escalation_group.toString();
} else if (groupGR.parent.toString()) {
return groupGR.parent.toString();
}
}
return null;
},
_notifyManagementChain: function(taskGR, notificationType) {
// Get group manager
var groupGR = new GlideRecord('sys_user_group');
if (groupGR.get(taskGR.assignment_group.toString())) {
if (groupGR.manager.toString()) {
this._sendNotification(groupGR.manager.toString(), notificationType,
'SLA escalation for ' + taskGR.number + ' requires attention');
}
}
// Notify assigned user's manager if available
if (taskGR.assigned_to.toString()) {
var userGR = new GlideRecord('sys_user');
if (userGR.get(taskGR.assigned_to.toString()) && userGR.manager.toString()) {
this._sendNotification(userGR.manager.toString(), notificationType,
'Direct report SLA escalation: ' + taskGR.number);
}
}
},
_sendBreachNotifications: function(taskGR, slaGR) {
// Create notification event for breach
gs.eventQueue('sla.breach.notification', taskGR, slaGR.sla.name.toString(),
slaGR.percentage.toString());
},
_createEscalationTask: function(taskGR, slaGR) {
var escalationGR = new GlideRecord('u_escalation_task');
escalationGR.initialize();
escalationGR.short_description = 'SLA Breach Follow-up: ' + taskGR.number;
escalationGR.description = 'Review SLA breach for ' + taskGR.number +
'. SLA: ' + slaGR.sla.name + ' breached at ' +
new GlideDateTime().toString();
escalationGR.parent_task = taskGR.sys_id.toString();
escalationGR.priority = '1';
escalationGR.assignment_group = gs.getProperty('sla.breach.management.group', '');
escalationGR.insert();
},
_notifyGroup: function(groupId, notificationType, taskGR) {
var event = new GlideRecord('sysevent');
event.initialize();
event.name = 'sla.group.notification';
event.instance = gs.getProperty('instance_name');
event.source = 'SLAEscalation';
event.node = gs.getNodeName();
event.parameters = 'group_id=' + groupId + ',task_number=' + taskGR.number +
',notification_type=' + notificationType;
event.insert();
},
_sendNotification: function(userId, subject, message) {
if (!userId) return;
var notification = new GlideRecord('sys_email');
notification.initialize();
notification.recipients = userId;
notification.subject = subject;
notification.body = message;
notification.type = 'send-ready';
notification.insert();
},
type: 'SLAEscalationUtil'
};
The code demonstrates a complete SLA escalation framework using business rules on the SLA Definition table to monitor percentage thresholds and stage changes. The SLAEscalationUtil Script Include handles the escalation logic with different actions for warning (50%), critical (80%), and breach (100%) stages, including automatic reassignment, management notifications, and escalation task creation.