← Script library

Business Rules

Calculate and Update SLA

Automatically calculate SLA due dates based on priority, business hours, and update SLA status.

JavaScript
(function executeRule(current, previous /*null when async*/) {

  // Configuration: Define SLA response times by priority (in hours)
  var slaResponseTimes = {
    '1': 1,    // Critical: 1 hour
    '2': 4,    // High: 4 hours
    '3': 8,    // Moderate: 8 hours
    '4': 24,   // Low: 24 hours
    '5': 48    // Planning: 48 hours
  };

  // Configuration: Define SLA resolution times by priority (in hours)
  var slaResolutionTimes = {
    '1': 4,    // Critical: 4 hours
    '2': 8,    // High: 8 hours
    '3': 24,   // Moderate: 24 hours
    '4': 72,   // Low: 72 hours
    '5': 120   // Planning: 120 hours
  };

  // Get the default schedule sys_id (8-5 weekdays excluding holidays)
  var scheduleId = 'c6a2389e0a0a0b9b006cfc04227be354';

  // Only calculate SLA on new records or when priority changes
  if (current.isNewRecord() || current.priority.changes()) {

    var priority = current.priority.toString();
    var responseHours = slaResponseTimes[priority];
    var resolutionHours = slaResolutionTimes[priority];

    // Calculate response due date
    if (responseHours && current.isNil('u_response_due')) {
      var schedule = new GlideSchedule(scheduleId);
      var startTime = new GlideDateTime();

      // Add business hours to current time
      var duration = new GlideDuration(responseHours * 60 * 60 * 1000);  // Convert to ms
      var responseDue = schedule.add(startTime, duration);

      current.u_response_due = responseDue;
      gs.info('Set response SLA due date for incident ' + current.number + ': ' + responseDue.getDisplayValue());
    }

    // Calculate resolution due date
    if (resolutionHours && (current.isNewRecord() || current.priority.changes())) {
      var schedule = new GlideSchedule(scheduleId);
      var startTime = new GlideDateTime();

      var duration = new GlideDuration(resolutionHours * 60 * 60 * 1000);
      var resolutionDue = schedule.add(startTime, duration);

      current.u_resolution_due = resolutionDue;
      gs.info('Set resolution SLA due date for incident ' + current.number + ': ' + resolutionDue.getDisplayValue());
    }
  }

  // Check SLA breach status
  if (!current.isNewRecord()) {
    var now = new GlideDateTime();

    // Check response SLA breach
    if (!current.u_response_due.nil() && current.isNil('u_responded_at')) {
      var responseDue = new GlideDateTime(current.u_response_due);
      if (now.after(responseDue)) {
        current.u_response_sla_breached = true;
        current.work_notes = 'Response SLA breached at ' + now.getDisplayValue();
      }
    }

    // Check resolution SLA breach
    if (!current.u_resolution_due.nil() && current.state.toString() !== '6') {
      var resolutionDue = new GlideDateTime(current.u_resolution_due);
      if (now.after(resolutionDue)) {
        current.u_resolution_sla_breached = true;
        current.work_notes = 'Resolution SLA breached at ' + now.getDisplayValue();
      }
    }

    // Mark SLA as met when incident is resolved within timeframe
    if (current.state.changesTo('6')) {  // Resolved
      if (!current.u_resolution_sla_breached.toString() === 'true') {
        current.u_sla_met = true;
      }
    }
  }

})(current, previous);

How to use it

1. Create a before Business Rule on your table 2. Check "Insert" and "Update" checkboxes 3. Create custom fields: u_response_due, u_resolution_due, u_response_sla_breached, u_resolution_sla_breached, u_responded_at, u_sla_met 4. Update schedule sys_id to match your business hours 5. Customize SLA times based on your organization's requirements 6. Consider using ServiceNow's built-in SLA engine for production use

Adapt the table names, fields, and conditions to your instance. Test the behavior in a development environment before using it in production.