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
Related Scripts
Auto-assign Based on Category
Automatically assign tickets to the appropriate assignment group based on category.
Send Email Notifications
Send customized email notifications when specific conditions are met.
Populate Fields on Insert
Automatically populate fields with default values or calculated values when a record is created.