I have a trigger on lead after insert that query all accounts and all contacts created the past 30 days to compare 4 fields (external id and legal number on accounts / mobile and email on contacts) and automatically convert the lead if a match is found.
I'm a beginner in APEX, even so I've tried to avoid nested queries and other traps thanks to answers from the community 1 year ago, I feel that my code is still not optimized. Indeed, it works most of the time but I still reach limits sometimes.
If you have any clues to help me here, it would be really appreciated !
trigger LeadDeduplicate2 on Lead (after insert) {
List<Account> accounts = [SELECT ID, Account_ID__c, Siret__c, OwnerId FROM Account WHERE Account_ID__c != NULL AND CreatedDate = LAST_N_DAYS:1];
List<Contact> contacts = [SELECT ID, Email, MobilePhone, AccountId, OwnerId FROM Contact WHERE CreatedDate = LAST_N_DAYS:30];
Map<String, Account> m1 = new Map<String, Account>();
Map<String, Account> m2 = new Map<String, Account>();
Map<String, Contact> m3 = new Map<String, Contact>();
Map<String, Contact> m4 = new Map<String, Contact>();
for(Account myAccount :accounts){
if(myAccount.Account_ID__c != null) {
m1.put(myAccount.Account_ID__c, myAccount);
}
if(myAccount.Siret__c != null) {
m2.put(myAccount.Siret__c, myAccount);
}
}
for(Contact myContact :contacts){
If(myContact.MobilePhone != null && myContact.MobilePhone != 'null'){
String phoneWithoutCountryCode = Utils.mobilePhoneWithoutCodeCountry(myContact.MobilePhone);
m4.put(phoneWithoutCountryCode, myContact);
}
if(myContact.Email != null) {
m3.put(myContact.Email, myContact);
}
System.debug(Limits.getCPUTime());
}
for(Lead lead : trigger.new) {
if(lead.IsExternal__c) {
if(m1.containsKey(lead.Account_ID__c)){
Account account = m1.get(lead.Account_ID__c);
Utils.mergeLeadWithAccount(lead, account);
break;
}
if(m2.containsKey(lead.Siret__c)){
Account account = m2.get(lead.Siret__c);
Utils.mergeLeadWithAccount(lead, account);
break;
}
if(m3.containsKey(lead.Email)){
Contact contact = m3.get(lead.Email);
Utils.mergeLeadWithContact(lead, contact);
break;
}
if(lead.MobilePhone != null && lead.MobilePhone != 'null'){
String phoneWithoutCountryCode = lead.MobilePhone.substring(lead.MobilePhone.length() - 9, lead.MobilePhone.length());
if(m4.containsKey(phoneWithoutCountryCode)){
Contact contact = m4.get(phoneWithoutCountryCode);
Utils.mergeLeadWithContact(lead, contact);
break;
}
}
}
}
System.debug(Limits.getCPUTime());
}
Utils
being the apex class used for matching and conversion.
public class Utils {
public static boolean hasTheSameAccountId(Lead lead, Account account) {
return acccountIdIsNotNull(lead, account) && account.Account_ID__c == lead.Account_ID__c;
}
public static boolean hasTheSameSiret(Lead lead, Account account) {
return siretIsNotNull(lead, account) && account.Siret__c == lead.Siret__c;
}
public static boolean acccountIdIsNotNull(Lead lead, Account account) {
return account.Account_ID__c != null && lead.Account_ID__c != null;
}
public static boolean siretIsNotNull(Lead lead, Account account) {
return account.Siret__c != null && lead.Siret__c != null;
}
public static boolean hasTheSameEmail(Lead lead, Contact contact) {
return emailIsNotNull(lead, contact) && lead.Email == contact.Email;
}
public static boolean hasTheSameMobile(Lead lead, Contact contact) {
return mobileIsNotNull(lead, contact) && Utils.mobilePhoneWithoutCodeCountry(lead.MobilePhone) == Utils.mobilePhoneWithoutCodeCountry(contact.MobilePhone);
}
public static String mobilePhoneWithoutCodeCountry(String phoneNumber) {
return phoneNumber.length() <= 9 ? phoneNumber : phoneNumber.substring(phoneNumber.length() - 9, phoneNumber.length());
}
public static boolean emailIsNotNull(Lead lead, Contact contact) {
return lead.Email != null && contact.Email != null;
}
public static boolean mobileIsNotNull(Lead lead, Contact contact) {
return lead.MobilePhone != null && lead.MobilePhone != 'null' && contact.MobilePhone != null && contact.MobilePhone != 'null';
}
public static void mergeLeadWithAccount(Lead lead, Account account) {
Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(lead.Id);
lc.setConvertedStatus('Qualifié');
lc.setDoNotCreateOpportunity(true);
lc.setAccountId(account.Id);
lc.setOwnerId(account.OwnerId);
try {
Database.LeadConvertResult lcr = Database.convertLead(lc);
System.assert(lcr.isSuccess());
} catch (DmlException e) {
System.debug('The following exception has occurred: ' + e.getMessage());
}
}
public static void mergeLeadWithContact(Lead lead, Contact contact) {
Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(lead.Id);
if(contact.AccountId != null) {
lc.setConvertedStatus('Qualifié');
lc.setDoNotCreateOpportunity(true);
lc.setAccountId(contact.AccountId);
lc.setOwnerId(contact.OwnerId);
lc.setContactId(contact.Id);
try {
Database.LeadConvertResult lcr = Database.convertLead(lc);
System.assert(lcr.isSuccess());
} catch (DmlException e) {
System.debug('The following exception has occurred: ' + e.getMessage());
}
}
}
}