+ Start a Discussion
Muhammad Jawwad 16Muhammad Jawwad 16 

How to schedule batch apex for the 1st date of every month?

global class LoanOfficerBatch implements Database.Batchable<sObject> {
    public String query = 'SELECT Loan_Officer_1a__c,Loan_Officer_1a__r.Email, ConvertedOpportunityId, Name, Phone,' 
                          +  'Status, Est_Re_Pull_Date__c, Realtor_Name__c ' 
                          +   ' FROM Lead'; 
    public EmailTemplate templateId = [Select Id,HtmlValue,Subject from EmailTemplate where name = 'LoanOfficerRecord' LIMIT 1];

    global Database.QueryLocator start(Database.BatchableContext bc) {

        query += ' WHERE CreatedDate = LAST_MONTH  AND Loan_Officer_1a__c != null';
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, list<Lead> allLeads) {
        
        
         
        List<String> convertedOppId = new List<String>();
         for(Lead l: allLeads){
	         convertedOppId.add(l.ConvertedOpportunityId); 
             }

         Map<Id, Opportunity> opptyMap = new Map<Id, Opportunity>();  
         for(Opportunity o : [SELECT Id,Name,Contact__r.Name,Contact__r.Phone,Starting_Credit_Score__c,Enrolled_On__c,Est_Re_Pull_Date__c,StageName FROM Opportunity WHERE Id IN: convertedOppId]){
	      opptyMap.put(o.Id, o);
          }
        
        
        
        Map<Id,List<Lead>> leadMap = new Map<Id,List<Lead>>();
        List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMEssage>();
        if(allLeads != null && allLeads.size() > 0){
            for(Lead l: allLeads){
                if(!leadMap.containsKey(l.Loan_Officer_1a__c)){
                    leadMap.put(l.Loan_Officer_1a__c, new List<lead>());
                }
                leadMap.get(l.Loan_Officer_1a__c).add(l);
            }
        }
        if(leadMap.keySet().size() > 0){
            Map<Id,Contact> officers = new Map<Id,Contact>([SELECT Id,Email,Name FROM Contact WHERE Id IN: leadMap.keySet()]);
            for(Id i: leadMap.keySet()){
                Contact con = officers.get(i);
                System.debug(con);
                if(String.isnOtBlank(con.Email)){
                    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                    mail.setToAddresses(new String[]{con.EMail});
                    mail.setSubject(templateId.Subject);
                    String html = templateId.HtmlValue;
                    html = html.replace('||OfficerName||',con.Name);
                    String leadsTable = '<table cellpadding="3" cellspacing="3" width="100%" align="center" border="1" style="border-collapse:collapse;">'+
                        '<tr style="font-weight:bold;"><td>Name</td><td>Phone</td><td>Status</td><td>Est. Re Pull Date</td><td>Realtor Name</td></tr>';
                    
                    for(Lead l: leadMap.get(i))  
                    if(l.ConvertedOpportunityId==null)
                    {                    {
                        
                        
                        leadsTable += '<tr><td>'+l.Name+'</td>'+
                            '<td>'+l.Phone+'</td><td>'+l.Status+'</td>'+
                            '<td>'+l.Est_Re_Pull_Date__c+'</td><td>'+l.Realtor_Name__c+'</td></tr>';
                    }
                                               }
                    leadsTable += '</table>';
                    
                     String opptyTable = '<table cellpadding="3" cellspacing="3" width="100%" align="center" border="1" style="border-collapse:collapse;">'+
                        '<tr style="font-weight:bold;"><td>Name</td><td>Phone</td><td>Starting Credit Score</td><td>Enrolled On</td><td>Estimated Pull Date</td><td>StageName</td></tr>';
                    
                    for(Id idKey: opptyMap.keySet()){
                        Opportunity o = opptyMap.get(idKey);
                        
                        
                        opptyTable += '<tr><td>'+o.Contact__r.Name+'</td><td>'+o.Contact__r.Phone+'</td><td>'+o.Starting_Credit_Score__c+'</td><td>'+o.Enrolled_On__c+'</td>'
                            +'<td>'+o.Est_Re_Pull_Date__c+'</td><td>'+o.StageName+'</td></tr>';
                    }
                    opptyTable += '</table>';
                    html = html.replace('||Leads||',leadsTable);
                    html = html.replace('||Opportunity||',opptyTable);
                    html = html.replace('null',' ');
                    mail.setHTMLBody(html);
                    mails.add(mail);
                }
            }
        }
        if(mails.size() > 0){
            Messaging.sendEmail(mails);
        }
    }

    global void finish(Database.BatchableContext BC) {

    }
   
}
please help
 
Best Answer chosen by Muhammad Jawwad 16
Maharajan CMaharajan C
Hi Mohammad,

First create scheduler class to your batch class. Then only you can run your batch class monthly.

Scheduler Class:

global class LoanOfficerBatchSheduler implements Schedulable {
   global void execute(SchedulableContext sc) {
      LoanOfficerBatch b = new LoanOfficerBatch(); 
      database.executebatch(b);
   }
}

Then there is two way to run this batch class via the Scheduler:

1. Salesforce Standard Out of Box Scheduler : (Cons : you can only scehdule up to next five years)

Setup > Apex Classes > Shedule Apex Button > Then you can lookup the above Sheduler Class. Please refer the below screenshot for further:

User-added image



2. Using CRON and Developer Console:

Developer Console > Debug > Open Execute Anonymous Window > paste the below code > Execute


LoanOfficerBatchSheduler m = new LoanOfficerBatchSheduler();
String sch = '0 0 0 1 * ? *';
String jobID = system.schedule('Merge Job', sch, m);

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm
http://amitsalesforce.blogspot.com/2017/07/how-to-write-test-class-for-scheduler.html
https://webkul.com/blog/cron-expression-for-scheduling-jobs-in-salesforce/

Thanks,
Maharajan.C

All Answers

Alain CabonAlain Cabon
Hi,

Schedule Apex job: To schedule your batch Apex to run at regular intervals, you also need an Apex class that implements interface Schedulable or all in one class is also possible.

Crontab:
http://www.leftpropeller.com/2018/08/13/schedulable-batch-apex/

or Schedule Apex via user interface
Click “Schedule Apex” button in Setup / Develop / Apex Classes to create a schedule apex job.

https://www.xgeek.net/salesforce/writing-a-schedulable-batch-apex-in-salesforce/
Maharajan CMaharajan C
Hi Mohammad,

First create scheduler class to your batch class. Then only you can run your batch class monthly.

Scheduler Class:

global class LoanOfficerBatchSheduler implements Schedulable {
   global void execute(SchedulableContext sc) {
      LoanOfficerBatch b = new LoanOfficerBatch(); 
      database.executebatch(b);
   }
}

Then there is two way to run this batch class via the Scheduler:

1. Salesforce Standard Out of Box Scheduler : (Cons : you can only scehdule up to next five years)

Setup > Apex Classes > Shedule Apex Button > Then you can lookup the above Sheduler Class. Please refer the below screenshot for further:

User-added image



2. Using CRON and Developer Console:

Developer Console > Debug > Open Execute Anonymous Window > paste the below code > Execute


LoanOfficerBatchSheduler m = new LoanOfficerBatchSheduler();
String sch = '0 0 0 1 * ? *';
String jobID = system.schedule('Merge Job', sch, m);

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm
http://amitsalesforce.blogspot.com/2017/07/how-to-write-test-class-for-scheduler.html
https://webkul.com/blog/cron-expression-for-scheduling-jobs-in-salesforce/

Thanks,
Maharajan.C
This was selected as the best answer
Ajay K DubediAjay K Dubedi
Hi Muhammad,
Try this:
Firstly make scheduler:
global class BatchScheduerName implements Schedulable {

    global void execute(SchedulableContext ctx) {
        LoanOfficerBatch obj= new LoanOfficerBatch();
        //Batch size is 200, records will be split into batches
        Database.ExecuteBatch(obj, 200);
    }
}
Save it.

Now time to schedule it:
Run this code in Execute Anonymous Window.

BatchScheduerName b = new BatchScheduerName();
String chronJobId = ' 0 0 12 1 1/1 ? *';
System.schedule('BatchSchedule', chronJobId,  b);

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.

Thanks,
Ajay Dubedi