Salesforce Apex Trigger Lead Conversion
In Salesforce, we can convert the Lead to Account, Contact and/or Opportunity with the “Convert” button from the front end. However, this can also be done by using the Database.LeadConvertResult Database method in Apex Class.
Here’s a sample lead conversion trigger scenario:
- Convert Lead to Contact when the contact value is created or updated.
- Use Contact email to query the related Lead and then merge them with the Contact
Now, let’s see how the apex trigger code looks like:
- Create a Map to keep the Contact Object. Use the Contact’s email as the key and Contact object as the value.
- Create a Set of Contact for query later
Map<String, Contact> contMap = new Map<String, Contact>(); Set contEmailSet = new Set(); for(Contact contObj: trigger.new){ if(contObj.Email != null){ contMap.put(contObj.Email, contObj); contEmailSet.add(contObj.Email); } }
Once the email Set is created, we can start to query the related Lead and then merge the lead with the contact.
Map<String, Lead> leadMap = new Map<String, Lead>(); if(contEmailSet.size() > 0){ for(Lead leadObj: [Select Id, Name, Email, isConverted from Lead Where Email in: contEmailSet]){ Database.LeadConvert lc = new Database.LeadConvert(); lc.setLeadId(leadObj.Id); lc.setAccountId(contMap.get(leadObj.Email).AccountId); lc.setContactId(contMap.get(leadObj.Email).Id); lc.setDoNotCreateOpportunity(true); LeadStatus convertStatus = [SELECT Id, MasterLabel, IsConverted FROM LeadStatus WHERE IsConverted=true limit 1]; lc.setConvertedStatus(convertStatus.MasterLabel); try{ Database.LeadConvertResult lcResults = Database.convertLead(lc); }Catch(Exception exp){ contMap.get(leadObj.Email).addError(exp.getMessage()); } } } }
In order to convert the lead we need to provide the following information:
- Lead Id – Use to identify which lead to convert
- Contact Id – Use to identify which contacts will merge with the lead
- Account Id – Use to identify which account the lead will be assigned to
- setConvertedStatus – Use to set the converted lead status
For more information please refer to Salesforce Lead Conversion guide.
Notes:
1. When the lead is converted to Contact, Salesforce will need to update the Contact again for the merging.
2. This will cause the trigger to fire again resulting infinite loop in the trigger
3. We have to create a recursive controller class to prevent infinite loop (Please refer to this blog for more information)
Below is the sample of the recursive control function that will wrap up the implementation for this requirement.
trigger ConvertLeadToAccount on Contact (after insert, after update) { //Initial the Map and Set Map<String, Contact> contMap = new Map<String, Contact>(); Set<String> contSet = new Set<String>(); //Call the RecursiveTriggerCheck class and check if this is the first run if(RecursiveTriggerCheck.getRunTimes() < 1){ //Get related contact from trigger.new for(Contact contObj: trigger.new){ //check if this record fulfill our requirement if(contObj.Email != null && contObj.Merge_Leads__c == true){ //put the related fulfilled record into the map and set for later uses contMap.put(contObj.Email, contObj); contSet.add(contObj.Email); } } //set the run time flag RecursiveTriggerCheck.setRunTimes(); //check if there is a lead ready for convert if(contSet.size() > 0){ //get the related lead record(s) from the set(contSet) for(Lead leadObj: [Select Id, Name, Email, isConverted from Lead Where Email in: contSet and isConverted = false]){ Database.LeadConvert lc = new Database.LeadConvert(); lc.setLeadId(leadObj.Id); lc.setAccountId(contMap.get(leadObj.Email).AccountId); lc.setContactId(contMap.get(leadObj.Email).Id); lc.setDoNotCreateOpportunity(true); //get the lead status from the LeadStatus obejct LeadStatus convertStatus = [SELECT Id, MasterLabel, IsConverted FROM LeadStatus WHERE IsConverted=true limit 1]; lc.setConvertedStatus(convertStatus.MasterLabel); try{ //convert the lead. Try Catch is used to display the error message Database.LeadConvertResult lcResults = Database.convertLead(lc); }Catch(Exception exp){ contMap.get(leadObj.Email).addError(exp.getMessage()); } } } } }