Skip to Content

Display Business Rule - Calculate Values

Calculate and display values on forms without modifying the database, useful for showing metrics, totals, or derived information.

Table: incident When: display
#display #calculated-fields #metrics #read-only #performance #aggregation

Script Code

JavaScript
1(function executeRule(current, previous /*null when async*/) {
2
3  // Display Business Rules run when records are fetched for display
4  // Values set here are NOT saved to database
5  // Use for calculated fields, metrics, and display-only information
6
7  try {
8    // Example 1: Calculate time since incident opened
9    if (current.opened_at) {
10      var openedAt = new GlideDateTime(current.opened_at);
11      var now = new GlideDateTime();
12      var duration = GlideDateTime.subtract(openedAt, now);
13
14      // Convert to days
15      var durationMs = duration.getNumericValue();
16      var durationDays = Math.abs(durationMs / (1000 * 60 * 60 * 24));
17
18      // Set display field (create a read-only field for this)
19      current.u_days_open = durationDays.toFixed(1);
20    }
21
22    // Example 2: Calculate SLA breach risk
23    if (current.sla_due) {
24      var slaDue = new GlideDateTime(current.sla_due);
25      var now = new GlideDateTime();
26      var timeUntilDue = GlideDateTime.subtract(now, slaDue);
27      var hoursUntilDue = timeUntilDue.getNumericValue() / (1000 * 60 * 60);
28
29      if (hoursUntilDue < 0) {
30        current.u_sla_status = 'Breached';
31      } else if (hoursUntilDue < 2) {
32        current.u_sla_status = 'Critical - ' + hoursUntilDue.toFixed(1) + 'h remaining';
33      } else if (hoursUntilDue < 4) {
34        current.u_sla_status = 'Warning - ' + hoursUntilDue.toFixed(1) + 'h remaining';
35      } else {
36        current.u_sla_status = 'On Track - ' + hoursUntilDue.toFixed(1) + 'h remaining';
37      }
38    }
39
40    // Example 3: Count related records
41    var relatedTaskCount = new GlideAggregate('incident_task');
42    relatedTaskCount.addQuery('incident', current.sys_id);
43    relatedTaskCount.addQuery('active', 'true');
44    relatedTaskCount.addAggregate('COUNT');
45    relatedTaskCount.query();
46
47    if (relatedTaskCount.next()) {
48      current.u_active_tasks_count = relatedTaskCount.getAggregate('COUNT');
49    } else {
50      current.u_active_tasks_count = '0';
51    }
52
53    // Example 4: Calculate priority score (weighted calculation)
54    var urgency = parseInt(current.urgency) || 3;
55    var impact = parseInt(current.impact) || 3;
56    var priorityScore = (urgency * 0.6) + (impact * 0.4);
57    current.u_priority_score = priorityScore.toFixed(2);
58
59    // Example 5: Show caller's total incident count
60    if (current.caller_id) {
61      var callerIncidentCount = new GlideAggregate('incident');
62      callerIncidentCount.addQuery('caller_id', current.caller_id);
63      callerIncidentCount.addAggregate('COUNT');
64      callerIncidentCount.query();
65
66      if (callerIncidentCount.next()) {
67        current.u_caller_incident_count = callerIncidentCount.getAggregate('COUNT');
68      }
69    }
70
71    // Example 6: Calculate estimated resolution time based on category
72    var categoryResolutionTimes = {
73      'hardware': 4,
74      'software': 2,
75      'network': 1,
76      'database': 6,
77      'inquiry': 0.5
78    };
79
80    var category = current.category.toString();
81    if (categoryResolutionTimes[category]) {
82      var estimatedHours = categoryResolutionTimes[category];
83      current.u_estimated_resolution_hours = estimatedHours.toString();
84
85      // Calculate estimated completion time
86      if (current.opened_at) {
87        var opened = new GlideDateTime(current.opened_at);
88        opened.addHours(estimatedHours);
89        current.u_estimated_completion = opened.getValue();
90      }
91    }
92
93    // Example 7: Show assignment group workload
94    if (current.assignment_group) {
95      var groupWorkload = new GlideAggregate('incident');
96      groupWorkload.addQuery('assignment_group', current.assignment_group);
97      groupWorkload.addQuery('active', 'true');
98      groupWorkload.addQuery('state', 'NOT IN', '6,7,8');  // Not resolved/closed/cancelled
99      groupWorkload.addAggregate('COUNT');
100      groupWorkload.query();
101
102      if (groupWorkload.next()) {
103        var workloadCount = groupWorkload.getAggregate('COUNT');
104        current.u_group_workload = workloadCount + ' active incidents';
105
106        // Set workload indicator
107        if (workloadCount > 50) {
108          current.u_group_capacity = 'Over Capacity';
109        } else if (workloadCount > 30) {
110          current.u_group_capacity = 'High Load';
111        } else if (workloadCount > 15) {
112          current.u_group_capacity = 'Normal';
113        } else {
114          current.u_group_capacity = 'Low Load';
115        }
116      }
117    }
118
119    // Example 8: Calculate business hours remaining
120    if (current.sla_due) {
121      var schedule = new GlideSchedule();
122      schedule.load('8-5 weekdays excluding holidays');  // Use your schedule
123
124      var now = new GlideDateTime();
125      var slaDue = new GlideDateTime(current.sla_due);
126
127      var businessHoursRemaining = schedule.duration(now, slaDue);
128      var businessHours = businessHoursRemaining.getByFormat('HH:mm');
129
130      current.u_business_hours_remaining = businessHours;
131    }
132
133  } catch (e) {
134    gs.error('Display BR error for incident ' + current.number + ': ' + e.message);
135  }
136
137})(current, previous);

How to Use

1. Create a new Business Rule on your table 2. Set When: "display" 3. Leave Insert, Update, Delete, Query unchecked 4. Create display-only fields (read-only) for calculated values 5. Add your calculation logic 6. Test by viewing records - values should appear but not save 7. Consider performance impact - runs on every record view 8. Use GlideAggregate carefully to avoid slow queries

Explore More Scripts

Browse our complete library of ServiceNow scripts

View All Scripts