+ Start a Discussion
Prince VenkatPrince Venkat 

Batch Apex email Scheduling

Hi

when ever a record inserted by batch apex mail should be send to the respective owner how to achieve this

Thanks in advance
mukesh guptamukesh gupta
Hi Prince, 

you can follow below code:
global class accountInsert implements Database.Batchable, Schedulable{
    List<sObject> batchList;
	
	 global accountInsert(List<sObject> objList) {
      // modify list if necessary (e.g., trap null)
      if (objList == null) objList = new List<sObject>();      
      this.batchList = objList;
   }
	
	

    
    global void execute(Database.BatchableContext batchableContext, List<sObjects> objList){
        try{
            insert objList;
			emailOwners(objList);
        }catch(Exception e){
            System.debug('Exception :: ' + e.getMessage());
        }
        
    }
    
    global void finish(Database.BatchableContext batchableContext) { 
        
    }
    
   
    private void emailOwners(List<Account> accList){
        
        List mailList = new List();
        EmailTemplate templateId = [Select Id from EmailTemplate where DeveloperName  = 'Template Name'];
        for(Account acc : accList){
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            mail.setTargetObjectId(acc.id);
            mail.setTreatTargetObjectAsRecipient(false);
            mail.setToAddresses(new List{acc.Owner.Email});
            mail.setTemplateID(templateId.Id);
            mail.setSaveAsActivity(false);
            mailList.add(mail);
        }
        if(mailList != null){
            Messaging.sendEmail(mailList);
        } 
    }
}

if you need any assistanse, Please let me know!!


Kindly mark my solution as the best answer if it helps you.

Thanks
Mukesh
Suraj Tripathi 47Suraj Tripathi 47
Hi Mukesh,

You can take reference from this below code:-
global class InactiveApplication implements Database.Batchable<sObject>
{
    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        String query = 'Select Id, Name, Owner.Email from Trade_Ally_Account__c where Stage__c = 'Prospecting' and LastModifiedDate = LAST_N_DAYS:31';
        return Database.getQueryLocator(query);
    }
 
    global void execute(Database.BatchableContext BC, List<Trade_Ally_Account__c> scope)
    {       
        EmailTemplate emailTemplate = [select Id, Body from EmailTemplate where DeveloperName = 'Update_Service_Request'];
        
        for(Trade_Ally_Account__c ta : (List<Trade_Ally_Account__c>)scope) {
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
            email.setToAddresses(new String[] {ta.Owner.Email});
            email.setSaveAsActivity(false);
            email.setTargetObjectId(ta.OwnerId);
            email.setTemplateId(emailTemplate.Id);
            email.setWhatId(ta.Id);
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
        }
    }  
    global void finish(Database.BatchableContext BC)
    {
    }
}

In case you find any other issue please mention. 
If you find your Solution then mark this as the best answer. 

 
Prince VenkatPrince Venkat
Hi suraj/mukesh

below is my code

Global class BatchEmail implements Database.Batchable<SObject>
{
    Global Database.QueryLocator Start(Database.BatchableContext bContext)
    {
        string accountsQuery = 'Select id, name, annualrevenue, fax, customerpriority__C, active__C from Account';
        return Database.getQueryLocator(accountsQuery);
    }
    
    Global void Execute(Database.BatchableContext bContext, List<SObject> recordsToProcess)
    {
        if(! recordsToProcess.isEmpty())
        {
            List<Account> accountsToUpdate = new List<Account>();
            
            for(SObject obj : recordsToProcess)
            {
                   
                   Account acc = (Account) obj;
                    acc.AnnualRevenue = 6000000;
                    acc.Fax = '99998888';
                    acc.CustomerPriority__c = 'High';
                    acc.Active__c = 'Yes';
                
              accountsToUpdate.Add(acc);
            }
            
           if(! accountsToUpdate.isEmpty())
            {
                Update accountsToUpdate;
            }
        }
    }
    
    Global void Finish(Database.BatchableContext bContext)
    {   
       EmailTemplate templateId = [Select Id from EmailTemplate where DeveloperName  = 'Testing'];
        List<account> lstAccount = new list<account>();
        for(Account acc : lstAccount)
        {
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            mail.setTargetObjectId(acc.id);
            mail.setTreatTargetObjectAsRecipient(false);
          //  mail.setToAddresses(new String[] {ta.Owner.mail});
            mail.setTemplateID(templateId.Id);
            mail.setSaveAsActivity(false);
            lstAccount.add(acc);
           insert  lstAccount;       
            
             Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
        }
    }
}

But i could not able to achieve my usecase

(after updating records mails should be send to the respective owner of the record ( i have the email templete by the name testing))

Any assistance

Thanks in advance

 
mukesh guptamukesh gupta
Hi Prince,

Do you want to update account or insert account.? because  in FINISH method lstAccount list is empty that's why loop will not execute.

Please give me your requirment what exactly you want do

Regards
Mukesh

 
Prince VenkatPrince Venkat
Hi mukesh

I have two requirements insert and update in both the cases mail should be sent to the respective owner of the record.

In the above  code what changes should i do to run succesfully

Regrads
Teja
mukesh guptamukesh gupta
Hi Prince,

Please follow below code
 
Global class BatchEmail implements Database.Batchable<SObject>, Database.Stateful
{
     global List<Account> accountsToUpdate;
     global List<sObject> accountsToInsert;

	 global BatchEmail(List<sObject> newAccList){
   	  	accountsToUpdate = new List<Account>();
        if (newAccList == null) newAccList = new List<sObject>();      
            this.batchList = newAccList;
        }
    
    Global Database.QueryLocator Start(Database.BatchableContext bContext)
    {
        string accountsQuery = 'Select id, name, annualrevenue, fax, customerpriority__C, active__C from Account';
        return Database.getQueryLocator(accountsQuery);
    }
    
    Global void Execute(Database.BatchableContext bContext, List<SObject> recordsToProcess)
    {
        if(accountsToInsert.size() > 0){
            insert accountsToInsert;
        }
        
        
        if(! recordsToProcess.isEmpty())
        {
            for(SObject obj : recordsToProcess)
            {
                   
                   Account acc = (Account) obj;
                    acc.AnnualRevenue = 6000000;
                    acc.Fax = '99998888';
                    acc.CustomerPriority__c = 'High';
                    acc.Active__c = 'Yes';
                
              accountsToUpdate.Add(acc);
            }
            
           if(! accountsToUpdate.isEmpty())
            {
                Update accountsToUpdate;
            }
        }
    }
    
    Global void Finish(Database.BatchableContext bContext)
    {   
       ///////////////////////// ---Insert Account --- ////////////////////// 
       List<Messaging.SingleEmailMessage> mails1 =   new List<Messaging.SingleEmailMessage>();
       EmailTemplate templateId = [Select Id from EmailTemplate where DeveloperName  = 'Testing'];
        List<account> lstAccount = new list<account>();
        for(Account acc : accountsToInsert)
        {
            Messaging.SingleEmailMessage mail1 = new Messaging.SingleEmailMessage();
            mail1.setTargetObjectId(acc.id);
            mail1.setTreatTargetObjectAsRecipient(false);
            mail1.setToAddresses(new String[] {acc.Owner.email});
            mail1.setTemplateID(templateId.Id);
            mail1.setSaveAsActivity(false);
            //lstAccount.add(acc);
           //insert  lstAccount;       
            mails1.add(mail1);
        }
     if(mails1.size() > 0)
         Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail1});

    }
    ///////////////////////////////////////////////////////////////////////////////////// 
        
       ///////////////////////// ---Update Account --- ////////////////////// 
       List<Messaging.SingleEmailMessage> mails =   new List<Messaging.SingleEmailMessage>();
       EmailTemplate templateId = [Select Id from EmailTemplate where DeveloperName  = 'Testing'];
        List<account> lstAccount = new list<account>();
        for(Account acc : accountsToUpdate)
        {
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            mail.setTargetObjectId(acc.id);
            mail.setTreatTargetObjectAsRecipient(false);
            mail.setToAddresses(new String[] {acc.Owner.email});
            mail.setTemplateID(templateId.Id);
            mail.setSaveAsActivity(false);
            //lstAccount.add(acc);
           //insert  lstAccount;       
            mails.add(mail);
        }
     if(mails.size() > 0)
         Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});

    }
    /////////////////////////////////////////////////////////////////////////////////////
}

if you need any assistanse, Please let me know!!


Kindly mark my solution as the best answer if it helps you.

Thanks
Mukesh
Prince VenkatPrince Venkat
Hi mukesh 
Thanks for your response

i am getting these errors when trying to use your above code


Variable does not exist: batchList  (this.batchList = newAccList;)
Method does not exist or incorrect signature: void getQueryLocator(String) from the type DataBase (return Database.getQueryLocator(accountsQuery);)
Invalid loop variable type expected SObject was Account ( for(Account acc : accountsToInsert)
Variable does not exist: mail1 (Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail1});)
Expecting '}' but was: 'for' (for(Account acc : accountsToUpdate))

errors and corresponding code