Manually Trigger Approval Process
Trigger a custom approval workflow with validation and user selection of approvers.
Form Button Table: change_request
#ui-action #form-button #approval #workflow #cab #server-side #change-management
Script Code
JavaScript
1// Server-side code
2(function() {
3 // Validation
4 if (current.isNewRecord()) {
5 gs.addErrorMessage('Please save the record before requesting approval');
6 return;
7 }
8
9 // Check if already in approval
10 if (current.approval.toString() !== 'not requested') {
11 gs.addErrorMessage('This change is already in approval process');
12 return;
13 }
14
15 // Validate required fields
16 var requiredFields = [
17 {field: 'short_description', label: 'Short Description'},
18 {field: 'risk', label: 'Risk'},
19 {field: 'impact', label: 'Impact'},
20 {field: 'implementation_plan', label: 'Implementation Plan'}
21 ];
22
23 var missingFields = [];
24 for (var i = 0; i < requiredFields.length; i++) {
25 if (current.isNil(requiredFields[i].field)) {
26 missingFields.push(requiredFields[i].label);
27 }
28 }
29
30 if (missingFields.length > 0) {
31 gs.addErrorMessage('Cannot request approval. Missing required fields: ' + missingFields.join(', '));
32 return;
33 }
34
35 try {
36 // Determine approval level based on risk and impact
37 var risk = current.risk.toString();
38 var impact = current.impact.toString();
39 var approvalLevel = 'standard';
40
41 if (risk === '1' || impact === '1') { // High risk or high impact
42 approvalLevel = 'cab'; // Change Advisory Board
43 } else if (risk === '2' || impact === '2') {
44 approvalLevel = 'manager'; // Manager approval
45 } else {
46 approvalLevel = 'standard'; // Standard approval
47 }
48
49 // Get approvers based on level
50 var approvers = [];
51
52 if (approvalLevel === 'cab') {
53 // Get CAB members
54 var grCAB = new GlideRecord('sys_user_grmember');
55 grCAB.addQuery('group.name', 'Change Advisory Board');
56 grCAB.query();
57
58 while (grCAB.next()) {
59 approvers.push(grCAB.user.toString());
60 }
61
62 } else if (approvalLevel === 'manager') {
63 // Get manager of assigned group
64 if (current.assignment_group) {
65 var grGroup = new GlideRecord('sys_user_group');
66 if (grGroup.get(current.assignment_group) && grGroup.manager) {
67 approvers.push(grGroup.manager.toString());
68 }
69 }
70
71 // Add change manager
72 var grRole = new GlideRecord('sys_user_has_role');
73 grRole.addQuery('role.name', 'change_manager');
74 grRole.addQuery('user.active', 'true');
75 grRole.query();
76
77 while (grRole.next()) {
78 approvers.push(grRole.user.toString());
79 }
80
81 } else {
82 // Standard approval - assignment group manager
83 if (current.assignment_group) {
84 var grGroup = new GlideRecord('sys_user_group');
85 if (grGroup.get(current.assignment_group) && grGroup.manager) {
86 approvers.push(grGroup.manager.toString());
87 }
88 }
89 }
90
91 // Remove duplicates
92 approvers = approvers.filter(function(item, pos) {
93 return approvers.indexOf(item) === pos;
94 });
95
96 if (approvers.length === 0) {
97 gs.addErrorMessage('No approvers found for this change. Please contact Change Management.');
98 return;
99 }
100
101 // Create approval records
102 var approvalCount = 0;
103 for (var i = 0; i < approvers.length; i++) {
104 var grApproval = new GlideRecord('sysapproval_approver');
105 grApproval.initialize();
106 grApproval.source_table = 'change_request';
107 grApproval.sysapproval = current.sys_id;
108 grApproval.approver = approvers[i];
109 grApproval.state = 'requested';
110 grApproval.due_date = new GlideDateTime();
111 grApproval.due_date.addDaysLocalTime(3); // 3 days to approve
112
113 grApproval.insert();
114 approvalCount++;
115 }
116
117 // Update change request
118 current.approval = 'requested';
119 current.work_notes = 'Approval requested by ' + gs.getUserName() + '. ' +
120 'Level: ' + approvalLevel + ', ' +
121 'Approvers: ' + approvalCount;
122 current.update();
123
124 // Send notifications
125 for (var i = 0; i < approvers.length; i++) {
126 gs.eventQueue('change.approval.requested', current, approvers[i], current.sys_id);
127 }
128
129 // Show success message
130 gs.addInfoMessage('Approval requested from ' + approvalCount + ' approver(s). Level: ' + approvalLevel);
131
132 } catch (e) {
133 gs.addErrorMessage('Error requesting approval: ' + e.message);
134 gs.error('Approval trigger error for ' + current.number + ': ' + e.message);
135 }
136
137})();
How to Use
1. Create a new UI Action on change_request table
2. Set Name to 'Request Approval'
3. Check 'Form button' checkbox
4. Uncheck 'Client' checkbox
5. Set Order: 100
6. Add condition: current.approval=='not requested' && !current.isNewRecord()
7. Paste the code above
8. Customize approval levels and approver logic
9. Update notification events
10. Test with various risk/impact combinations