0

I have created the batch class to send separate email to each Opportunity owner based on their order outstanding by grouping the opportunity based on their ownership.

But while executing the data am facing the below issue. Kindly help here to resolve this issue.

Issue:

EXCEPTION_THROWN [74]|System.LimitException: Too many Email Invocations: 11

global class OppOutstandingRemainder implements Database.Batchable<sObject>, Database.Stateful
{

global Database.QueryLocator start (Database.BatchableContext BC)
    {
   return Database.getQueryLocator([SELECT Id,Name,DispatchDate__c,Outstanding_Amount__c,Account.Name,Owner.Email,Owner.Name FROM Opportunity WHERE
                             OutstandingRemainder__c>Today and Outstanding_Amount__c>0]);
    }
    
    global void execute (Database.Batchablecontext bc, List<sObject> scope)
    {
        list<String> toAddresses = New list<String>();
         Map<string,string>mapownername= New map<string,string>();
        set<string> emaillist=new set<string>();
        //list<String> CCAddresses = New list<String>();
         String[] CCAddresses = new String[] {'[email protected]'};
        List<Opportunity> lstopp= scope;                
        for (Opportunity emp: lstopp){
        emaillist.add(emp.owner.email);
        mapownername.put(emp.owner.email,emp.owner.Name);
        }    
        // toAddresses=emaillist;
        System.debug('mapownername-->'+mapownername);
        System.debug('Oppowneremaillist-->'+emaillist);
          
        For(String  to:emaillist){
        System.debug('Firstemail-->'+to);
        
          String[] toAddresses1 = new String[] {to};
          System.debug('Listemail1--->'+toAddresses1);
          string TCName=mapownername.get(String.valueof(to));
           System.debug('TCName--->'+TCName);
        Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
        email.setToAddresses(toAddresses1);   
        email.setccAddresses(CCAddresses);             
        email.setUseSignature(false);
        email.setSubject('TC :'+mapownername.get(String.valueof(to))+' -Project OutStanding List for '+String.Valueof(Date.today().addDays(+1)));
        Integer i = 0;
         String s; String OwnerName; String ProjectDispatchDate; String Comments; string CustomerName ;Decimal Amount;string owneremail; String workorderNumber;
                               
        String htmlBody = '';
       
       
        htmlBody = '<table border="1" style="border-collapse: collapse"><caption>Project OutStanding List</caption><tr><th>S.no</th><th>Workorder Number</th><th>Customer Name</th><th>Opportunity Owner Name</th><th>Project DispatchDate</th><th>Out Standing Amount</th></tr>';
        
       for(Opportunity u : [SELECT Id,Name,Work_Order_No__c,Account.Name,DispatchDate__c,Outstanding_Amount__c,Owner.Email,Owner.Name FROM Opportunity WHERE
                            OutstandingRemainder__c>Today and Owner.Email=:toAddresses1 and Outstanding_Amount__c>0]){
                            
                                  i++;                   workorderNumber=u.Work_Order_No__c;
                                                         CustomerName=u.Account.Name;
                                                         OwnerName=u.Owner.Name;
                                                         ProjectDispatchDate=string.Valueof(u.DispatchDate__c);
                                                         Amount=u.Outstanding_Amount__c;
                                                         //owneremail=u.owner.Email;
                                                        
                                 
                                 
                                 
                                 
                                 
                                    htmlBody += '<tr><td>'+String.ValueOf(i) +'</td><td>' + workorderNumber+'</td><td>' +CustomerName +'</td><td>'+ OwnerName+ '</td><td>' + ProjectDispatchDate+ '</td><td>'+Amount+'</td></tr>';
                                                       
                              }
       
       
       
        htmlBody += '</table>';
        
        
        
        
        //  email.setHtmlBody('<br/><br/>&nbsp;&nbsp;please click the below link to review the Expenses list for tomorrow <font color="green">'+'</font>test<br/><br/>'+ S);
        email.setHtmlBody( 'Dear Team,<br><br/> Please find the below outstanding list for '+String.Valueof(Date.today().addDays(+1))+'. Kindly take the action accordingly.<br><br/>'+ htmlBody+'<br/><br/><br/><br/>'+'Thanks, <br/> Finance Team<br/><br/>');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[]{email});  
        
     }   
    }
    
    global void finish (Database.BatchableContext bc)
    {
        
    }   
}
1
  • 1
    Fundamentally this is to do with limits. If you reference the documentation, you'll see that you can only call sendEmail 10 times in a given (synchronous or asynchronous) session.
    – Phil W
    Commented Dec 11, 2020 at 8:28

1 Answer 1

0

There is no email limit from Apex. The limit is on the number of times the sendEmail() method can be invoked from Apex. Note that salesforce does not enforce a limit for Emails from Apex, however, there is a limit around number of times the sendEmail() method can be invoked from Apex in a transaction.

Best practice is to ensure that you're not calling the sendEmail() method inside a for loop

Sample code for SendEmail()

NOTE: The code provided below is an example. You should always test code before pushing to production.

//method to send mail to a list of users
public static void DispatchEmail() {
    List lstMails = new List();
      lst = 20;
       for(Integer i : lst) {
          Messaging.SingleEmailMessage message = getEmail();       
 //Construct the email message here by populating the values such as body, subject
                //Adding emails to the list       
 lstMails.add(message);
    }  
   //Sending the email list in a single call.
    Messaging.sendEmail(lstMails);
  }

 
public static Messaging.SingleEmailMessage getEmail() {
    Messaging.SingleEmailMessage mailMessage = new Messaging.SingleEmailMessage();
    mailMessage.setSaveAsActivity(false);
    return mailMessage;
  }

Reference: https://help.salesforce.com/articleView?id=000324660&type=1&mode=1

I suggest checking this answer as well on the developer forums

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .