I'm trying to link incoming cases to existing person accounts based on a first name + last name + email combo. If a unique person account exists (ie only one record with the value of first name, last name and email from the newly inserted case) - link the newly created case to that person account. If no match is found - create a new person account and link it to the newly created case. If more than one match is found (ie two person account records with the same first name + last name + email combo) - don't link the case at all.
I've been playing with the code found in another post (and replaced Contact with Case): Associating new contacts/cases with an account?
trigger CaseTrigger on Case (before insert) {
Map<String, Account[]> accountsByPersonEmail; // could be more than one Account w/ same email
Set<String> searchEmails = new Set<String>();
// Step 1 - gather search keys
for(Case c : Trigger.new){
if (c.AccountId == null && String.isNotBlank(c.SuppliedEmail)) {
searchEmails.add(c.SuppliedEmail);
}
}
// Step 2 - find Accounts by Case Supplied Email
accountsByPersonEmail = Util.pivotSObjectsByString(Account.PersonEmail,
[Select Id, Name, PersonEmail From Account Where Name IN : searchEmails]);
// Step 3 - Associate Case in trigger.new to Account
for(Case c : Trigger.new){
if (c.AccountId != null) {continue;} // nothing to do
Account[] matchingAccounts = accountsByPersonEmail(c.PersonEmail);
if (matchingAccounts.isEmpty()) {continue;} // how to create new account here and avoid recursion in the trigger?
if (matchingAccounts.size() > 1) {continue;} // ambiguous - do nothing
c.AccountId = matchingAccounts[0].Id; // unambiguous match
}
}
public static map<String,List<SObject>> pivotSObjectsByString(Schema.SObjectField fldToken, SObject[] sobjList) {
map<String,List<SObject>> res = new map<String,List<SObject>> ();
for (Sobject sobj: sobjList == null ? new list<Sobject>() : sobjlist) {
String pivotKey = (String) sobj.get(fldToken);
if (res.containsKey(pivotKey)) {
res.get(pivotKey).add(sobj);
}
else {
Sobject[] typedSobjs = makeTypedSobjList(sobj); // do this so resulting list.getSobjectType() doesn't return null
typedSobjs.add(sobj);
res.put(pivotKey,typedSobjs);
}
}
return res;
}
public static Sobject[] makeTypedSobjList(Sobject sobj) {
return (Sobject[]) Type.forName('List<'+sobj.getSObjectType()+'>').newInstance();
}
My concern is here:
if (matchingAccounts.isEmpty()) {continue;}
How can I avoid recursion in the trigger? I wish to create a new account for that case and insert that case (and relate that newly created case to the newly created person account)