|
1 | 1 | (function() { |
2 | | - var userEmailMap = {}; |
| 2 | + |
| 3 | + var userEmailMap = {}; |
| 4 | + var userCreatedMap = {}; |
| 5 | + var duplicatesFound = 0; |
| 6 | + |
3 | 7 | var userGR = new GlideRecord('sys_user'); |
4 | 8 | userGR.addNotNullQuery('email'); |
5 | 9 | userGR.addQuery('active', true); |
| 10 | + userGR.orderBy('email'); // Group by email |
6 | 11 | userGR.query(); |
7 | 12 |
|
8 | | - var duplicatesFound = 0; |
9 | | - |
10 | 13 | while (userGR.next()) { |
11 | 14 | var email = userGR.email.toLowerCase(); |
| 15 | + var createdOn = new GlideDateTime(userGR.sys_created_on).getNumericValue(); // Convert to timestamp |
12 | 16 |
|
13 | 17 | if (!userEmailMap[email]) { |
14 | | - // First user with this email |
| 18 | + // First user found for this email temporarily mark as master |
15 | 19 | userEmailMap[email] = userGR.sys_id.toString(); |
| 20 | + userCreatedMap[email] = createdOn; |
16 | 21 | } else { |
17 | | - // Duplicate found then merge with master |
18 | | - duplicatesFound++; |
| 22 | + // Another user with same email found |
19 | 23 | var masterSysId = userEmailMap[email]; |
| 24 | + var masterCreatedOn = userCreatedMap[email]; |
| 25 | + |
| 26 | + var masterIsOlder = createdOn > masterCreatedOn ? true : false; |
20 | 27 |
|
21 | | - // Reassign related incidents |
22 | | - var incGR = new GlideRecord('incident'); |
23 | | - incGR.addQuery('caller_id', userGR.sys_id); |
24 | | - incGR.query(); |
25 | | - var incidentsReassigned = 0; |
26 | | - while (incGR.next()) { |
27 | | - incGR.caller_id = masterSysId; |
28 | | - incGR.update(); |
29 | | - incidentsReassigned++; |
| 28 | + if (masterIsOlder) { |
| 29 | + // If this user was created later, we keep the existing master |
| 30 | + // earliest created record will be accepted |
| 31 | + mergeDuplicateUser(userGR, masterSysId); |
| 32 | + } else { |
| 33 | + // If this user was created earlier, this becomes the new master |
| 34 | + var oldMasterGR = new GlideRecord('sys_user'); |
| 35 | + if (oldMasterGR.get(masterSysId)) { |
| 36 | + mergeDuplicateUser(oldMasterGR, userGR.sys_id); // merge old master into new master |
| 37 | + } |
| 38 | + // Update maps |
| 39 | + userEmailMap[email] = userGR.sys_id.toString(); |
| 40 | + userCreatedMap[email] = createdOn; |
30 | 41 | } |
31 | 42 |
|
32 | | - // Deactivate duplicate |
33 | | - userGR.active = false; |
34 | | - userGR.u_merged_to = masterSysId; // optional custom field |
35 | | - userGR.update(); |
36 | | - |
37 | | - gs.info("Merged duplicate user '" + userGR.name + "' into master. Reassigned " + incidentsReassigned + " incidents."); |
| 43 | + duplicatesFound++; |
38 | 44 | } |
39 | 45 | } |
40 | 46 |
|
41 | 47 | gs.info("Total duplicates merged: " + duplicatesFound); |
42 | 48 |
|
| 49 | + |
| 50 | + |
| 51 | + function mergeDuplicateUser(duplicateGR, masterSysId) { |
| 52 | + // Reassign related incidents |
| 53 | + var incGR = new GlideRecord('incident'); |
| 54 | + incGR.addQuery('caller_id', duplicateGR.sys_id); |
| 55 | + incGR.query(); |
| 56 | + var count = 0; |
| 57 | + while (incGR.next()) { |
| 58 | + incGR.caller_id = masterSysId; |
| 59 | + incGR.update(); |
| 60 | + count++; |
| 61 | + } |
| 62 | + |
| 63 | + // Deactivate user |
| 64 | + duplicateGR.active = false; |
| 65 | + duplicateGR.u_merged_to = masterSysId; // optional custom field |
| 66 | + duplicateGR.update(); |
| 67 | + |
| 68 | + gs.info("Merged duplicate user '" + duplicateGR.name + "' → master: " + masterSysId + ". Reassigned " + count + " incidents."); |
| 69 | + } |
| 70 | + |
43 | 71 | })(); |
0 commit comments