I've created a class to manually do a mass merge of Contacts from different Accounts, creating AccountContactRelation records between the new master Contact and Accounts from the duplicates. Due to the limit of merging only 3 records per merge command, I'm hitting the Too many SOQL queries: 101 limit when I run a group of Contacts through.
This is not going to be an ongoing job, just a once-off to clean our database. How do I bulkify the code to run through all my contacts?
global class MergeRecords {
public boolean MergeContacts(){
Contact master;
list<Contact> masters = new list<Contact>([select Id, AccredoId__c
from Contact where Master__c = true order by AccredoId__c]);
set<string> acrIds = new set<string>();
list<Contact> duplicates = new list<Contact>();
map<string, list<Contact>> mapDups = new map<string, list<Contact>>();
list<AccountContactRelation> acrs = new list<AccountContactRelation>();
try{
//Find all the Contacts that were duplicates, that have been marked as being the master Contact for the direct relationship
for(Contact c : masters){
if(c.AccredoID__c != null){
acrIds.add(c.AccredoId__c);
}
}
System.debug('#####MergeContacts acrIds: ' + acrIds);
//Now get all those marked as being duplicates of the masters identified above. These will be merged into the master with
//indirect relationships created to the original Accounts. The fields specific to those Accounts need to be populated after the ACR
//has been created.
duplicates = [select Id, AccountId, Department, Email, Phone, Title, Inactive__c, AccredoID__c,
CallCycleFrequency__c, AccredoCRMGroup__c, LastCallCycleVisitOn__c, Preferred_Day__c,
MasterAccredoId__c
from Contact where masterAccredoId__c in: acrIds order by MasterAccredoId__c, AccredoID__c];
if(!duplicates.isEmpty()){
Contact dup = duplicates[0];
list<Contact> dups = new list<Contact>();
for(Contact d : duplicates){
if(d.MasterAccredoId__c != dup.MasterAccredoId__c){
mapDups.put(dup.MasterAccredoId__c, dups);
dup = d;
dups = new list<Contact>();
}
dups.add(d);
}
mapDups.put(dup.MasterAccredoId__c, dups);
for(Contact c : masters){
list<Contact> cdups = mapDups.get(c.AccredoId__c);
if(cdups != null){
list<Contact> merges = new list<Contact>();
database.MergeResult[] results;
integer i = 0;
for(Contact cd : cdups){
i += 1;
merges.add(cd);
if(i < 3){
results = database.merge(c, merges, false);
merges = new list<Contact>();
i = 0;
}
for(database.MergeResult res : results){
System.debug('#####MergeContacts Master record ID: ' + res.getId());
List<Id> mergedIds = res.getMergedRecordIds();
}
//Create the ACR since the merge doesn't do so
AccountContactRelation acr = new AccountContactRelation();
acr.AccountId = cd.AccountId;
acr.ContactId = c.Id;
acr.Acc_Email__c = cd.Email;
acr.Acc_Phone__c = cd.Phone;
acr.Acc_Title__c = cd.Title;
acr.Acc_Department__c = cd.Department;
acrs.add(acr);
System.debug('#####MergeContacts acr: ' + acr);
}
}
}
}
if(!acrs.isEmpty()){
insert acrs;
}
return true;
}
catch(Exception e){
System.debug('#####MergeContacts ERROR: ' + e);
return false;
}
}
}