You need to sign in to do that
Don't have an account?
Teja Sattoor
Bulkification of Lead Conversion Trigger
Hi, I am new to SF coding and I have written a lead conversion trigger that should convert a lead when it meets the criteria. My code works fine when I convert one lead at a time, but runs into "CANNOT_CONVERT_UPDATE_LEAD" when I run to convert multiple leads at once. Please find my trigger and apex class below.
Apex Trigger:
trigger AutoConvertLeads on Lead (after update) {
Set<Id> leadIds = new Set<Id>();
for(Lead myLead : Trigger.new){
if((myLead.isconverted == false) && (myLead.Convert_to_Contact__c == true)){
leadIds.add(myLead.Id);
}
if(leadIds.size() > 0) {
LeadConversionUtils.convertLeads(leadIds);
}
}
}
Apex Class:
public class LeadConversionUtils {
public static void convertLeads(Set<Id> leadIds) {
// Retrieve all the necessary fields for the Leads to be converted
List<Lead> leadList = new List<Lead>([SELECT Id, Company, Zlien_User_ID__c FROM Lead WHERE Id IN :leadIds]);
//Convert the lead
for(lead myLead : leadList){
List<Account> AccountList1 = [Select Account.Id, Account.Name from Account where Account.User_ID__c =: myLead.Zlien_User_ID__c];
if(!AccountList1.isEmpty()){
List<Contact> ContactList = new List<Contact>();
List<Account> AccountList = new List<Account>();
for(Account acc1 : AccountList1){
Database.LeadConvert lc = new database.LeadConvert();
lc.setLeadId(myLead.Id);
lc.setAccountId(acc1.Id);
lc.setConvertedStatus('Converted to Opportunity');
lc.setDoNotCreateOpportunity(true);
Database.LeadConvertResult lcr = Database.convertLead(lc);
System.assert(lcr.isSuccess());
Contact Con = [Select OwnerId, Lead_Status__c, Contact_Stage__c from Contact where Contact.Id =: lcr.getContactId()];
Account Acc = [Select OwnerId from Account where Account.Id =: lcr.getAccountId()];
Con.Lead_Status__c = 'Converted to Account/Contact';
Con.Contact_Stage__c = 'Current Customer';
Con.OwnerId = Acc.OwnerId;
ContactList.add(Con);
AccountList.add(Acc);
}
update ContactList;
update AccountList;
}
}
}
}
Could you please help me bulkify the trigger and also let me know the mistake I have been doing? Thanks
Apex Trigger:
trigger AutoConvertLeads on Lead (after update) {
Set<Id> leadIds = new Set<Id>();
for(Lead myLead : Trigger.new){
if((myLead.isconverted == false) && (myLead.Convert_to_Contact__c == true)){
leadIds.add(myLead.Id);
}
if(leadIds.size() > 0) {
LeadConversionUtils.convertLeads(leadIds);
}
}
}
Apex Class:
public class LeadConversionUtils {
public static void convertLeads(Set<Id> leadIds) {
// Retrieve all the necessary fields for the Leads to be converted
List<Lead> leadList = new List<Lead>([SELECT Id, Company, Zlien_User_ID__c FROM Lead WHERE Id IN :leadIds]);
//Convert the lead
for(lead myLead : leadList){
List<Account> AccountList1 = [Select Account.Id, Account.Name from Account where Account.User_ID__c =: myLead.Zlien_User_ID__c];
if(!AccountList1.isEmpty()){
List<Contact> ContactList = new List<Contact>();
List<Account> AccountList = new List<Account>();
for(Account acc1 : AccountList1){
Database.LeadConvert lc = new database.LeadConvert();
lc.setLeadId(myLead.Id);
lc.setAccountId(acc1.Id);
lc.setConvertedStatus('Converted to Opportunity');
lc.setDoNotCreateOpportunity(true);
Database.LeadConvertResult lcr = Database.convertLead(lc);
System.assert(lcr.isSuccess());
Contact Con = [Select OwnerId, Lead_Status__c, Contact_Stage__c from Contact where Contact.Id =: lcr.getContactId()];
Account Acc = [Select OwnerId from Account where Account.Id =: lcr.getAccountId()];
Con.Lead_Status__c = 'Converted to Account/Contact';
Con.Contact_Stage__c = 'Current Customer';
Con.OwnerId = Acc.OwnerId;
ContactList.add(Con);
AccountList.add(Acc);
}
update ContactList;
update AccountList;
}
}
}
}
Could you please help me bulkify the trigger and also let me know the mistake I have been doing? Thanks
Your apex trigger is fine but there are a few issues in your class code.
- Since you have queried Accounts (AccountList1) inside the for loop (a big no in apex), your code tries to convert a lead more than once in case there are multiple records returned by your query, hence the error.
- There are 2 more queries on Account (Acc) and Contact (Con) inside a for loop that is further nested in another for loop. This will definitely run into issues in case when you update more than 100 leads at once.
- I do not see any update on the Account fields, but you are still executing an update on AccountList. I am guessing that is not required at all.
I have made a few modifications to your class, below is the code:Let me know if this works for you
Thank you so much for your quick response. I now get a better idea of the mistake I have done, though I incur the same error again. Upon further investigation by looking into the logs, I realize that an other trigger is trying to update the converted lead. This is a "before update" trigger which is being called for the second time. I have no idea why this is being called again. I have only two triggers on my leads, one of which is a "before update"(the above one that is being called twice), and the lead conversion trigger which is an "after update" trigger.
I was hoping if you have any idea why this before update trigger was called twice and the best way to resolve this.
Thank you again,
Teja.
This is possibly a case of recursive trigger calls. This happens when your record gets updated by some other configuration (trigger/workflow/process builder, etc) which causes the before and after triggers to fire once again.
In order to prevent this, you can use a static variable and use it as a flag to only execute the lead conversion piece once. Here is how you can do this (I have modified the code mentioned in previous reply to include the static flag):
Thanks again. I have implemented the changes you have suggested. This time the code is no longer throwing an error but is converting only one of the leads. I looked at the logs and looks like the first lead that has been converted is turning the flag "true" thereby letting the second lead to bypass the conversion. I was hoping to see if I have to make changes to the trigger to send both(or more) leadIds at once to the conversion class.
I cannot thank you enough for your help.
Teja.
If this resolves your issue, please mark this as the best answer.
I did not change the trigger and I have even tried your code too. It still converts only one lead but doesn't through any error.
Thanks,
Teja.