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
Gus protoGus proto 

convert trigger into batch apex class

How do I convert this trigger into a batch apex class so i can process over 5 millions record,
Trigger AutoConverter on Lead (after insert,after update) {
     LeadStatus convertStatus = [
          select MasterLabel
          from LeadStatus
          where IsConverted = true
          limit 1
     ];
     List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>();

     for (Lead lead: Trigger.new) {
          if (!lead.isConverted ) {
               Database.LeadConvert lc = new Database.LeadConvert();

               lc.setLeadId(lead.Id);
               lc.setDoNotCreateOpportunity(TRUE); 
               lc.setConvertedStatus(convertStatus.MasterLabel);

                String leadOwner = lead.OwnerId;
              if(leadOwner.startsWith('00G')){
               Lc.OwnerId = '00535000001ZOZN'; }
               leadConverts.add(lc);
          }
     }

     if (!leadConverts.isEmpty()) {
          List<Database.LeadConvertResult> lcr = Database.convertLead(leadConverts);
     }
}

 
PRAKASH JADA 13PRAKASH JADA 13
Hi,

I am including 2 codes one with schedule and the other one without a schedule.

This includes schedulable as well.
global class AutoConverterBatch implements Database.Batchable<SObject>, Database.RaisesPlatformEvents, Schedulable {
    
    private final String CONVERTED_STATUS = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1].MasterLabel;
    
    // Empty constructor
    global AutoConverterBatch() {
        
    }
    
    // Start Method
    global Database.QueryLocator start(Database.BatchableContext ctx){
        String query = 'SELECT Id FROM Lead WHERE ConvertedContactId = null';
        return Database.getQueryLocator(query);
    }
    
    // Excute Method
    global void execute(Database.BatchableContext ctx, List<Lead> leads){
        List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>();
        // Loop to iterate over the list of Leads
        for(Lead lead : Leads) {
            Database.LeadConvert lc = new Database.LeadConvert();
            
            lc.setLeadId(lead.Id);
            lc.setDoNotCreateOpportunity(TRUE); 
            lc.setConvertedStatus(CONVERTED_STATUS);
            
            String leadOwner = lead.OwnerId;
            
            // Condition to check for the owner Id
            if(leadOwner.startsWith('00G')){
                lead.OwnerId = '00535000001ZOZN'; 
            }
            
            leadConverts.add(lc); //adding to list
        }
        
        
        if (!leads.isEmpty()) {
            Database.convertLead(leadConverts, true);
        }
    }
    
    //Finish Method
    public void finish(Database.BatchableContext ctx){
        
    }
    
    // Schedle Apex
    global void execute(System.SchedulableContext SC) {
        
        Database.executeBatch(new AutoConverterBatch(), 200);
        
    }
}


If you don't need schedule part then consider this code

global class AutoConverterBatch implements Database.Batchable<SObject>, Database.RaisesPlatformEvents {
    
    private final String CONVERTED_STATUS = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1].MasterLabel;
    
    // Empty constructor
    global AutoConverterBatch() {
        
    }
    
    // Start Method
    global Database.QueryLocator start(Database.BatchableContext ctx){
        String query = 'SELECT Id FROM Lead WHERE ConvertedContactId = null';
        return Database.getQueryLocator(query);
    }
    
    // Excute Method
    global void execute(Database.BatchableContext ctx, List<Lead> leads){
        List<Database.LeadConvert> leadConverts = new List<Database.LeadConvert>();
        // Loop to iterate over the list of Leads
        for(Lead lead : Leads) {
            Database.LeadConvert lc = new Database.LeadConvert();
            
            lc.setLeadId(lead.Id);
            lc.setDoNotCreateOpportunity(TRUE); 
            lc.setConvertedStatus(CONVERTED_STATUS);
            
            String leadOwner = lead.OwnerId;
            
            // Condition to check for the owner Id
            if(leadOwner.startsWith('00G')){
                lead.OwnerId = '00535000001ZOZN'; 
            }
            
            leadConverts.add(lc); //adding to list
        }
        
        
        if (!leads.isEmpty()) {
            Database.convertLead(leadConverts, true);
        }
    }
    
    //Finish Method
    public void finish(Database.BatchableContext ctx){
        
    }
   
}
Gus protoGus proto
getting this error now: caused by: System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Lead.OwnerId
Gus protoGus proto
Looks like the lead owner changed if it is queue no longer works:  First error: ConvertLead failed. First exception on row 17; first error: REQUIRED_FIELD_MISSING, Converted objects can only be owned by users. If the lead is not owned by a user, you must specify a user for the Owner field.: [OwnerId]
PRAKASH JADA 13PRAKASH JADA 13
OwnerId add ownerId to your query like this
String query = 'SELECT Id, OwnerId
 FROM Lead WHERE ConvertedContactId = null';
Gus protoGus proto
I get this error now: caused by: System.DmlException: ConvertLead failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Converted objects can only be owned by users.  If the lead is not owned by a user, you must specify a user for the Owner field.: [OwnerId]
PRAKASH JADA 13PRAKASH JADA 13
If the lead is not owned by a user, you must specify a user for the Owner field.: [OwnerId] It is due to the data that you are having in the org. Please check the data " leadOwner.startsWith('00G') " . Here is your check if the owner Id didn't start with 00G then for those records you need to specity the owner Id field. that what the error means.

Thanks