· 4 years ago · Jul 21, 2021, 03:16 AM
1/**
2* @Description : Compares two record collections and returns records that are the shared and records that are unique to each collection.
3* Specify the Ids you want to compare for each sObject and the action will take care of the rest.
4* @Author : Adam White
5* @Last Modified By : adamwhiteuva@gmail.com
6* @Last Modified On : 1/26/2021
7* @Modification Log :
8* Ver Date Author Modification
9* 1.0 1/26/2021 adamwhiteuva@gmail.com Initial release
10**/
11global without sharing class FindCommonAndUniqueRecords {
12 @InvocableMethod(label='Get Common and Unique Records'description='Extract and return two collections comparing a source and target collection'category='Util')
13 global static List <Result> compareRecords(List<Request> requestList) {
14
15 List<Result> outputResults = new List<Result>();
16 Map<String, Map<String, SObjectField>> sobjectTypeMap = new Map<String, Map<String, SObjectField>>();
17
18 //make sure we check that both collections are not empty/null
19 for (Request request: requestList) {
20 if (request.sourceRecordCollection != null &&
21 !request.sourceRecordCollection.isEmpty() &&
22 request.targetRecordCollection != null &&
23 !request.targetRecordCollection.isEmpty()) {
24
25 List<SObject> sourceRecordCollection = request.sourceRecordCollection;
26 List<SObject> targetRecordCollection = request.targetRecordCollection;
27
28 Result result = new Result();
29 result.sourceCommonRecordCollection = new List<sObject>();
30 result.targetCommonRecordCollection = new List<sObject>();
31 result.sourceUniqueRecordCollection = new List<sObject>();
32 result.targetUniqueRecordCollection = new List<sObject>();
33
34 //puts the source collection into a map so we can compare with the target collection map
35 Set<String> sourceSet = new Set<String>();
36 string objectType = string.valueOf(sourceRecordCollection[0].Id.getSObjectType());
37 string targetObjectType = string.valueOf(targetRecordCollection[0].Id.getSObjectType());
38
39 if(!sobjectTypeMap.containsKey(objectType)){
40 Schema.SObjectType s = sourceRecordCollection[0].Id.getSObjectType();
41 Map<String, SObjectField> sourceFieldMap = s.getDescribe().fields.getMap();
42 sobjectTypeMap.put(string.valueOf(s), sourceFieldMap);
43 }
44
45 if(!sobjectTypeMap.containsKey(targetObjectType)){
46 Schema.SObjectType s = sourceRecordCollection[0].Id.getSObjectType();
47 Map<String, SObjectField> sourceFieldMap = s.getDescribe().fields.getMap();
48 sobjectTypeMap.put(string.valueOf(s), sourceFieldMap);
49 }
50
51 if(sobjectTypeMap.containsKey(objectType)){
52 Schema.SobjectField sourceCurField = sobjectTypeMap.get(objectType).get(request.sourceUniqueID);
53
54 // Loop over the source collection
55 for (sObject sourceRecord : sourceRecordCollection) {
56
57 //grab the value of the Unique ID field
58 String sourceCurrentFieldValue = (String)sourceRecord.get(sourceCurField);
59
60 //as long as the unique value isnt blank, put it in the sourceMap map to be used later
61 if (sourceCurrentFieldValue != null && sourceCurrentFieldValue != '') {
62 sourceSet.add(sourceCurrentFieldValue);
63 }
64
65 }
66 }
67
68 if(sobjectTypeMap.containsKey(targetObjectType)){
69
70 //puts the target collection into a map so we can compare with the source collection
71 Map<String, sObject> targetMap = new Map<String, sObject>();
72
73 // The key to the map is the api name of the field
74 Schema.SobjectField targetCurField = sobjectTypeMap.get(targetObjectType).get(request.targetUniqueID);
75
76 for (sObject targetRecord : targetRecordCollection) {
77 String targetCurFieldValue = (String)targetRecord.get(targetCurField);
78
79 //as long as the unique value isnt blank, put it in the targetMap map to be used later
80 if (targetCurFieldValue != null && targetCurFieldValue != '') {
81 targetMap.put(targetCurFieldValue, targetRecord);
82 }
83
84 }
85
86 for (sObject sourceRecord : sourceRecordCollection ) {
87 //if it is, we add it to the common record collection and remove it from the target map. We do this
88 String sourceFieldValue = sourceRecord.get(request.sourceUniqueID).toString();
89
90 if (targetMap.containsKey(sourceFieldValue)) {
91 result.sourceCommonRecordCollection.add(sourceRecord);
92 } else {
93 result.sourceUniqueRecordCollection.add(sourceRecord);
94 }
95 }
96
97 // we loop over the 'Target' collection to see if the record is in the 'Source' collection'.
98 for (sObject targetRecord : targetRecordCollection ) {
99 //if it is, we add it to the common record collection and remove it from the target map. We do this
100 String targetFieldValue = targetRecord.get(request.targetUniqueID).toString();
101
102 if (sourceSet.contains(targetFieldValue)) {
103 result.targetCommonRecordCollection.add(targetRecord);
104 }
105
106 else {
107 result.targetUniqueRecordCollection.add(targetRecord);
108 }
109
110 }
111 }
112 //add this result to the bulkified results (invocable specific)
113 outputResults.add(result);
114 }
115 }
116
117 return outputResults;
118 }
119
120 global class Request {
121 @InvocableVariable(description='The first record collection you want to compare to' required=true)
122 global List<SObject> sourceRecordCollection;
123
124 @InvocableVariable(description='The Source Record Unique ID (Field API Name) you want to compare against the Target Unique ID' required=true)
125 global String sourceUniqueID;
126
127 @InvocableVariable(description='The second record collection you want to compare against' required=true)
128 global List<sObject> targetRecordCollection;
129
130 @InvocableVariable(description='The Target Record Unique ID (Field API Name) you want to compare against the Source Unique ID' required=true)
131 global String targetUniqueID;
132
133 }
134
135 global class Result {
136 @InvocableVariable(description='The unique records in the source collection when compared against the target collection')
137 global List<sObject> sourceUniqueRecordCollection;
138
139 @InvocableVariable(description='The shared records between the two collections')
140 global List<sObject> sourceCommonRecordCollection;
141
142 @InvocableVariable(description='The unique records in the target collection when compared against the source collection')
143 global List<sObject> targetUniqueRecordCollection;
144
145 @InvocableVariable(description='The shared records between the two collections')
146 global List<sObject> targetCommonRecordCollection;
147
148 }
149
150}