I'm trying to link incoming cases (through the UI and through our REST API). Essentially, I'm checking for a combination of first name, last name and email on the incoming case, and if that combination exists on a Person Account - link it to that existing person account, else create a new person account. My only concern is that if there are two or more person accounts (duplicates), the case is linked to one of them - I wish to avoid this step altogether, meaning: If there is more than person account match, don't link the case to any account at all.
public with sharing class CaseAccountLink {
public static void linkCasesToAccount(List<Case> caseList) {
List<Case> casesReceived = [SELECT Id, Web_First_Name__c, Web_Last_Name__c, SuppliedEmail, Privacy_Policy__c, Country__c, Market__c, RecordTypeId
FROM Case
WHERE Id IN :caseList
AND AccountId = null];
List<String> caseEmails = Collection.of(caseEmails).pluckStrings(Case.SuppliedEmail);
List<Account> accountsToCheck = [SELECT Id, FirstName, LastName, PersonEmail
FROM Account
WHERE PersonEmail
IN :caseEmails];
Map<ps_CustomerDetailsKey, Id> existingAccountIdsByKey = new Map<ps_CustomerDetailsKey, Id>(); // Just a custom map
for (Account eachAcc : accountsToCheck) {
existingAccountIdsByKey.put(new ps_CustomerDetailsKey(eachAcc.FirstName, eachAcc.LastName, eachAcc.PersonEmail), eachAcc.Id);
}
Map<ps_CustomerDetailsKey, Account> newAccountsByKey = new
Map<ps_CustomerDetailsKey, Account>();
List<Case> linkCaseToAccount = new List<Case>();
List<Case> casesToUpdate = new List<Case>();
for (Case eachCase :casesReceived) {
ps_CustomerDetailsKey caseKey = new ps_CustomerDetailsKey(eachCase.Web_First_Name__c, eachCase.Web_Last_Name__c, eachCase.SuppliedEmail);
Id foundAccountId = existingAccountIdsByKey.get(caseKey);
if (foundAccountId != null) {
// The case maps to an account and the foundAccountId specifies which one
eachCase.AccountId = foundAccountId;
linkCaseToAccount.add(eachCase);
casesToUpdate.add(eachCase);
} else {
// No account for the case is found
Account newAccount = newAccountsByKey.get(caseKey);
if (newAccount == null) {
newAccountsByKey.put(caseKey,
new Account(
FirstName = eachCase.Web_First_Name__c,
LastName = eachCase.Web_Last_Name__c,
PersonEmail = eachCase.SuppliedEmail
));
}
}
}
Database.insert(newAccountsByKey.values(), false);
// newly created cases (and accounts) that couldn't be linked
// needs to be re-checked and linked
for (Case eachCase : casesReceived) {
ps_CustomerDetailsKey key = new ps_CustomerDetailsKey(eachCase.Web_First_Name__c, eachCase.Web_Last_Name__c, eachCase.SuppliedEmail);
Account newAccount = newAccountsByKey.get(key);
if (newAccount != null) {
// Should always be the case!
eachCase.AccountId = newAccount.Id;
casesToUpdate.add(eachCase);
}
}
update casesToUpdate;
}
}
ps_CustomerDetailsKey:
public class ps_CustomerDetailsKey {
List<Object> key;
public ps_CustomerDetailsKey(String first, String last, String email) {
this.key = new List<Object>{ first, last, email };
}
public Boolean equals(Object other) {
if(other instanceof ps_CustomerDetailsKey) {
return this.key.equals(((ps_CustomerDetailsKey) other).key);
}
return false;
}
public override Integer hashCode() {
return key.hashCode();
}
public String getFirst() {
return (String) key [0];
}
public String getLast() {
return (String) key [1];
}
public String getEmail() {
return (String) key [2];
}
}
ps_CustomerDetailsKey
? Can you add another field like a flag forduplicate
?Napoleon Bonaparte emperor@france.co.fr
andnapoleon bonaparte emperor@france.co.fr