Skip to Content

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

Explore More Scripts

Browse our complete library of ServiceNow scripts

View All Scripts