User and Group Utilities
Reusable functions for user and group operations.
#user #group #utilities #roles #manager-chain #on-call
Script Code
JavaScript
1var UserGroupUtils = Class.create();
2UserGroupUtils.prototype = {
3
4 /**
5 * Check if user has a specific role
6 *
7 * @param {string} userId - sys_id of user
8 * @param {string} roleName - Name of role to check
9 * @returns {boolean} True if user has role
10 */
11 userHasRole: function(userId, roleName) {
12 if (!userId || !roleName) {
13 return false;
14 }
15
16 var grUser = new GlideRecord('sys_user');
17 if (!grUser.get(userId)) {
18 return false;
19 }
20
21 return grUser.hasRole(roleName);
22 },
23
24 /**
25 * Get all users in a group
26 *
27 * @param {string} groupId - sys_id or name of group
28 * @param {boolean} includeInactive - Include inactive users (default: false)
29 * @returns {Array} Array of user objects {sys_id, name, email}
30 */
31 getUsersInGroup: function(groupId, includeInactive) {
32 var users = [];
33
34 // Get group record
35 var grGroup = new GlideRecord('sys_user_group');
36 if (!grGroup.get(groupId)) {
37 // Try by name
38 grGroup = new GlideRecord('sys_user_group');
39 grGroup.addQuery('name', groupId);
40 grGroup.setLimit(1);
41 grGroup.query();
42
43 if (!grGroup.next()) {
44 return users;
45 }
46 }
47
48 // Query group members
49 var grMember = new GlideRecord('sys_user_grmember');
50 grMember.addQuery('group', grGroup.sys_id);
51 grMember.query();
52
53 while (grMember.next()) {
54 var grUser = new GlideRecord('sys_user');
55 if (grUser.get(grMember.user)) {
56
57 // Skip inactive users unless specified
58 if (!includeInactive && grUser.active.toString() !== 'true') {
59 continue;
60 }
61
62 users.push({
63 sys_id: grUser.sys_id.toString(),
64 name: grUser.name.toString(),
65 email: grUser.email.toString(),
66 first_name: grUser.first_name.toString(),
67 last_name: grUser.last_name.toString()
68 });
69 }
70 }
71
72 return users;
73 },
74
75 /**
76 * Get user's manager chain (up to specified levels)
77 *
78 * @param {string} userId - sys_id of user
79 * @param {number} levels - Number of levels to traverse (default: 5)
80 * @returns {Array} Array of manager objects {sys_id, name, level}
81 */
82 getManagerChain: function(userId, levels) {
83 var managers = [];
84 levels = levels || 5;
85
86 var currentUserId = userId;
87 var currentLevel = 1;
88
89 while (currentUserId && currentLevel <= levels) {
90 var grUser = new GlideRecord('sys_user');
91 if (!grUser.get(currentUserId)) {
92 break;
93 }
94
95 var managerId = grUser.manager.toString();
96 if (!managerId) {
97 break;
98 }
99
100 var grManager = new GlideRecord('sys_user');
101 if (grManager.get(managerId)) {
102 managers.push({
103 sys_id: managerId,
104 name: grManager.name.toString(),
105 email: grManager.email.toString(),
106 level: currentLevel
107 });
108
109 currentUserId = managerId;
110 currentLevel++;
111 } else {
112 break;
113 }
114 }
115
116 return managers;
117 },
118
119 /**
120 * Get common manager between two users
121 *
122 * @param {string} userId1 - sys_id of first user
123 * @param {string} userId2 - sys_id of second user
124 * @returns {object} Common manager object or null
125 */
126 getCommonManager: function(userId1, userId2) {
127 var chain1 = this.getManagerChain(userId1);
128 var chain2 = this.getManagerChain(userId2);
129
130 // Find first common manager
131 for (var i = 0; i < chain1.length; i++) {
132 for (var j = 0; j < chain2.length; j++) {
133 if (chain1[i].sys_id === chain2[j].sys_id) {
134 return chain1[i];
135 }
136 }
137 }
138
139 return null;
140 },
141
142 /**
143 * Get on-call user for a group based on rotation schedule
144 *
145 * @param {string} groupId - sys_id of group
146 * @param {GlideDateTime} dateTime - Date/time to check (defaults to now)
147 * @returns {string} sys_id of on-call user or empty string
148 */
149 getOnCallUser: function(groupId, dateTime) {
150 dateTime = dateTime || new GlideDateTime();
151
152 // Get rotation schedule for group
153 var grRotation = new GlideRecord('cmn_rota');
154 grRotation.addQuery('group', groupId);
155 grRotation.addQuery('active', 'true');
156 grRotation.setLimit(1);
157 grRotation.query();
158
159 if (!grRotation.next()) {
160 return '';
161 }
162
163 // Get current roster member
164 var grRoster = new GlideRecord('cmn_rota_member');
165 grRoster.addQuery('roster', grRotation.sys_id);
166 grRoster.addQuery('from', '<=', dateTime);
167 grRoster.addQuery('to', '>=', dateTime);
168 grRoster.setLimit(1);
169 grRoster.query();
170
171 if (grRoster.next()) {
172 return grRoster.member.toString();
173 }
174
175 return '';
176 },
177
178 /**
179 * Check if user is member of any specified groups
180 *
181 * @param {string} userId - sys_id of user
182 * @param {Array} groupNames - Array of group names to check
183 * @returns {boolean} True if user is in any of the groups
184 */
185 isMemberOfAnyGroup: function(userId, groupNames) {
186 if (!userId || !groupNames || groupNames.length === 0) {
187 return false;
188 }
189
190 var grMember = new GlideRecord('sys_user_grmember');
191 grMember.addQuery('user', userId);
192 grMember.addQuery('group.name', 'IN', groupNames.join(','));
193 grMember.setLimit(1);
194 grMember.query();
195
196 return grMember.hasNext();
197 },
198
199 /**
200 * Get user's primary group (first active group they're a member of)
201 *
202 * @param {string} userId - sys_id of user
203 * @returns {object} Group object {sys_id, name} or null
204 */
205 getPrimaryGroup: function(userId) {
206 if (!userId) {
207 return null;
208 }
209
210 var grMember = new GlideRecord('sys_user_grmember');
211 grMember.addQuery('user', userId);
212 grMember.addQuery('group.active', 'true');
213 grMember.orderBy('group.name');
214 grMember.setLimit(1);
215 grMember.query();
216
217 if (grMember.next()) {
218 return {
219 sys_id: grMember.group.toString(),
220 name: grMember.group.name.toString()
221 };
222 }
223
224 return null;
225 },
226
227 type: 'UserGroupUtils'
228};
How to Use
1. Create a new Script Include
2. Set Name to "UserGroupUtils"
3. Leave "Client callable" unchecked
4. Copy the code above
5. Call from Business Rules or other Script Includes