0

I'm using the batch class to send an email with an attachment, but the issue is I'm able to add only 2000 records in single file. I have a huge amount of data so I'm getting multiple emails with different files. My code is as follows:

    global class PurchaseDetailsBatch implements Database.Batchable<sObject>{

  global Database.QueryLocator start(Database.BatchableContext bc) {
    //String customerRegion = 'Allied 10 EP MidAtlantic';
    String query = 'SELECT Id, Name, Beacon_Acc_Number__c,Region_Mincron__c,Days_Since_Last_Purchase__c, Owner.Name, Date_Last_Purchase__c FROM Account WHERE Days_Since_Last_Purchase__c >= 30 AND Beacon_Acc_Number__c != NULL AND Date_Last_Purchase__c != NULL AND Region_Mincron__c != NULL' ;
    return Database.getQueryLocator(query);
  }

  global void execute(Database.BatchableContext bc, List<Account> accList){
    String header = 'Customer Number, Name, Days Since Last Purchase, Date Last Purchase, Owner Name\n';
    String finalstr = header;
    List<Purchase_Details__c> purchaseDetailsList = Purchase_Details__c.getall().values();
    Map<String,String[]> purchaseMap = new Map<String,String[]>();
    Map<String,List<Account>> accountMap = new Map<String,List<Account>>();
    for(Purchase_Details__c objPurchase : purchaseDetailsList){
      if(objPurchase.Email__c.contains(',')){
         String[] address = objPurchase.Email__c.split(',');
         purchaseMap.put(objPurchase.Name, address);
      }else{
         purchaseMap.put(objPurchase.Name,new String[] {objPurchase.Email__c});
      }

    }
    Map<String,Blob> emailFileMap = new Map<String,Blob>();
    for(Account acc : accList){
        String records = acc.Beacon_Acc_Number__c+',';
        if(acc.Name.contains(',')){
         String temp = acc.Name.remove(',');
         records+=temp+',';
        }else{
         records+=acc.Name+',';
        }

        records+=acc.Days_Since_Last_Purchase__c+',';
        Date d = acc.Date_Last_Purchase__c;
        records+=d.day()+'-'+d.month()+'-'+d.year()+',';
        records+=acc.Owner.Name+',';
        records +='\n';      
        finalstr = finalstr+records;
        if(acc.Region_Mincron__c != null){
         emailFileMap.put(acc.Region_Mincron__c,Blob.valueOf(finalstr));
        }
    }
    System.debug('-->'+emailFileMap.keySet().size());
    List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();
    for(String regionStr : purchaseMap.keySet()){


      Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();
      blob excel;
       if(emailFileMap.containsKey(regionStr) && emailFileMap.get(regionStr) != null){
         excel = emailFileMap.get(regionStr);
       }
       //blob excel = blob.valueOf(finalstr);
       attach.setBody(excel);
       attach.setFileName(regionStr+' file.csv');
       String subject = regionStr;
       //String body = 'Users who are not logged in since last 30 days';
       String body = 'Please find attached file for purchase details';
       String[] addressFromLabel = purchaseMap.get(regionStr);

       Messaging.singleEmailMessage Emailwithattch = new Messaging.singleEmailMessage();

       Emailwithattch.setSubject(subject);

       Emailwithattch.setToaddresses(addressFromLabel);

       Emailwithattch.setHtmlBody(body);     

       Emailwithattch.setFileAttachments(new Messaging.EmailFileAttachment[]{attach});

       emails.add(Emailwithattch);



    }
      Messaging.SendEmailResult [] r =

      Messaging.sendEmail(emails);
  }    

  global void finish(Database.BatchableContext bc){         }   
  /*public void execute(SchedulableContext SC){
   Database.executeBatch(new SouthDivisionUsersBatch(), 2000);     
   }  */    
}

1 Answer 1

1

You are executing batch as Database.executeBatch(new PurchaseDetailsBatch(), 2000); and run emails sending in the execute method. Therefore, you have batches of 2000 records each.

To send them all in one file you need to set implements Database.Batchable<sObject>, Database.Stateful, add some variable to the class where you will store items, for example, public List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();. In the execute method just add completed items to that variable and send them all in finish method.

That should work properly for you.

You must log in to answer this question.

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