function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Gabe RothmanGabe Rothman 

Too many future calls error on lead conversion trigger, any help appreciated :-)

Hey all, I am pretty new to APEX, and I have built a lead conversion trigger, which is causing a "Too many future calls" error.  Based on my investigation it looks like I need to bulkify the service class that I am calling in the trigger, but I haven't been able to figure out the correct synatx.  Here is the class:

public with sharing class ConvertLeadOnActiveService {
    
    public static void convertLead(list<lead> convertList) {
    
    	for (Lead lead : convertList) {
      		if (lead.isConverted == false && lead.State__c == 'Active'){
       
        	Database.LeadConvert lc = new Database.LeadConvert();
        	lc.setLeadId(lead.Id);
       
     	    String oppName = lead.Company;
        	lc.setOpportunityName(oppName);
       
	        LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
    	    lc.setConvertedStatus(convertStatus.MasterLabel);
       
       		Database.LeadConvertResult lcr = Database.convertLead(lc);
       		System.assert(lcr.isSuccess());
       
    		}
  	}
    }
}

I am pretty sure that I need to move the following outside of the for loop, but I am not sure how to do it.

         LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
         lc.setConvertedStatus(convertStatus.MasterLabel);
      
         Database.LeadConvertResult lcr = Database.convertLead(lc);
         System.assert(lcr.isSuccess());

Any help greatly appreciated.  Thanks!
Best Answer chosen by Gabe Rothman
pconpcon
What you will want to do is move both the SOQL query out and the database.convertLead as you said.  You'll want to do something like:

public with sharing class ConvertLeadOnActiveService {
     public static void convertLead(list<lead> convertList) {
          LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
          List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>();
          for (Lead lead : convertList) {
               if (lead.isConverted == false && lead.State__c == 'Active'){
                    Database.LeadConvert lc = new Database.LeadConvert();
                    lc.setLeadId(lead.Id);

                    String oppName = lead.Company;
                    lc.setOpportunityName(oppName);
        
                    lc.setConvertedStatus(convertStatus.MasterLabel);
        
                    leadConverts.add(lc);
                 }
         }
          Database.LeadConvertResult lcr = Database.convertLead(leadConverts);
     }
}

NOTE: This code has not been tested to compile and may contain typographical errors

All Answers

pconpcon
What you will want to do is move both the SOQL query out and the database.convertLead as you said.  You'll want to do something like:

public with sharing class ConvertLeadOnActiveService {
     public static void convertLead(list<lead> convertList) {
          LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
          List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>();
          for (Lead lead : convertList) {
               if (lead.isConverted == false && lead.State__c == 'Active'){
                    Database.LeadConvert lc = new Database.LeadConvert();
                    lc.setLeadId(lead.Id);

                    String oppName = lead.Company;
                    lc.setOpportunityName(oppName);
        
                    lc.setConvertedStatus(convertStatus.MasterLabel);
        
                    leadConverts.add(lc);
                 }
         }
          Database.LeadConvertResult lcr = Database.convertLead(leadConverts);
     }
}

NOTE: This code has not been tested to compile and may contain typographical errors
This was selected as the best answer
Deepak Kumar ShyoranDeepak Kumar Shyoran
All you need to do is to create a List<Id> which will hold Id of Lead which you want to convert and then pass that List to your Database class which will convert those Lead in same manner.

Please don't use future or DML,SOQL,describe inside the loop just create a list for the Object let say Account and Contact and insert those list outside the loop to avoid such kind of exception

Please mark my answer as a solution to your question if it solves your problem.
Gabe RothmanGabe Rothman
Awesome! Thanks for the help.  I tested the updated code, but I am getting an error on line 18:

"Save error: Illegal assignment from LIST<Database.LeadConvertResult> to Database.LeadConvertResult"

Any suggestions?
pconpcon
Just change line 18 to List<Database.LeadConvertResult> instead of Database.LeadConvertResult
Gabe RothmanGabe Rothman
Ah, that makes sense.  Thanks again!