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
Michael MMichael M 

Schedule email containing a list of all records owned by each user

I need to send out a monthly email, to every record owner (for 1 of our custom objects), which contains a list of all of their records, with 3 columns (each different fields on each of those records.) Can you please post an example of code that would work for the correct queries? 
Best Answer chosen by Michael M
AnudeepAnudeep (Salesforce Developers) 
Hi Michael, 

Here is a sample code. Please make changes as per your requirement
 
global class sendEmails implements Database.Batchable<sObject> {
   global Database.QueryLocator start(Database.BatchableContext bc) {
       String soql = 'SELECT Field__1, Field__2, Field__3, OwnerId FROM Account';
       return Database.getQueryLocator(soql);
   }
  
   global void execute(Database.BatchableContext bc, List<account> recs) {
       List<Messaging.SingleEmailMessage> mailList = new List<Messaging.SingleEmailMessage>();
       Date D =Date.today();
                  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                    List<String> toAddresses = new List<String>();
                    String messageBody;
                    list<string> accstring =new list<string>();
       for(account m : recs) {
            messageBody = m.Field1__c+'--'+ m.Field2__c+'--'+m.Field3__c ;
            accstring.add(messageBody );           
           toAddresses.add(m.owner.email);
       }                
           mail.setToAddresses(toAddresses);
           mail.setSubject('Account Owners');
           string allstring = string.join(accstring,'<br/>');
       mail.setHtmlBody('<html><body>Hi <br>'+'<br> Here are <br>'+allstring + ',<br> The records you own <br>Kindly contact your administrator if there are any descrepencies.<br><br><b>Regards,</b><br>Regards <br/></body></html>'); 

                  mailList.add(mail);   

       Messaging.sendEmail(mailList);
   }
  
   global void finish(Database.BatchableContext bc) {
   }
}

You can use system.scheduleBatch to schedule the batch

If you find this information helpful, please mark this answer as Best. It may help others in the community. Thank You!

Anudeep


 

All Answers

AnudeepAnudeep (Salesforce Developers) 
Hi Michael, 

Here is a sample code. Please make changes as per your requirement
 
global class sendEmails implements Database.Batchable<sObject> {
   global Database.QueryLocator start(Database.BatchableContext bc) {
       String soql = 'SELECT Field__1, Field__2, Field__3, OwnerId FROM Account';
       return Database.getQueryLocator(soql);
   }
  
   global void execute(Database.BatchableContext bc, List<account> recs) {
       List<Messaging.SingleEmailMessage> mailList = new List<Messaging.SingleEmailMessage>();
       Date D =Date.today();
                  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                    List<String> toAddresses = new List<String>();
                    String messageBody;
                    list<string> accstring =new list<string>();
       for(account m : recs) {
            messageBody = m.Field1__c+'--'+ m.Field2__c+'--'+m.Field3__c ;
            accstring.add(messageBody );           
           toAddresses.add(m.owner.email);
       }                
           mail.setToAddresses(toAddresses);
           mail.setSubject('Account Owners');
           string allstring = string.join(accstring,'<br/>');
       mail.setHtmlBody('<html><body>Hi <br>'+'<br> Here are <br>'+allstring + ',<br> The records you own <br>Kindly contact your administrator if there are any descrepencies.<br><br><b>Regards,</b><br>Regards <br/></body></html>'); 

                  mailList.add(mail);   

       Messaging.sendEmail(mailList);
   }
  
   global void finish(Database.BatchableContext bc) {
   }
}

You can use system.scheduleBatch to schedule the batch

If you find this information helpful, please mark this answer as Best. It may help others in the community. Thank You!

Anudeep


 
This was selected as the best answer
Michael MMichael M
Hi Anudeep, This is very helpful. I just tested this, and it is sending a list of every single record to every single owner. How can I make it so that it ONLY sends each owner the records that HE owns? (using schedule instead of batchable)



global class LeadOwnershipEmail implements Schedulable{
    global void execute(SchedulableContext SC) {
 
        list<community_lead__c> recs = [SELECT Referral_Source__c, Services_Needed__c, owner.email, Lead_initiated_by__c, OwnerId FROM Community_Lead__c];

       List<Messaging.SingleEmailMessage> mailList = new List<Messaging.SingleEmailMessage>();
       Date D =Date.today();
                  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
       List<String> toAddresses = new List<String>();
                    String messageBody;
                    list<string> accstring =new list<string>();
       for(Community_Lead__c m : recs) {
            messageBody = m.Referral_Source__c+'--'+ m.Services_Needed__c+'--'+m.Lead_initiated_by__c ;
            accstring.add(messageBody );           
           toAddresses.add(m.owner.email);
       }                
           mail.setToAddresses(toAddresses);
           mail.setSubject('Account Owners');
           string allstring = string.join(accstring,'<br/>');
       mail.setHtmlBody('<html><body>Hi <br>'+ '<br> Here are the records you own. Kindly contact your administrator if there are any descrepencies.<br>'+allstring +'<br><b>Regards,</b><br>Regards <br/></body></html>

                  mailList.add(mail);   
 
       Messaging.sendEmail(mailList);
   }

}

 
Michael MMichael M
Hi David, Deliverablity settings were indeed set to "All Email". Is there anything else wrong with the code?
AnudeepAnudeep (Salesforce Developers) 
Hi Michael, 

Here is what I recommend to ensure it only sends each owner the records that he owns

Query for an additional field - CreatedById in the SOQL query and compare it with OwnerID and only send the email if it matches. Something like this
 
SELECT Referral_Source__c, CreatedById, Services_Needed__c, owner.email, Lead_initiated_by__c, OwnerId FROM Community_Lead__c]
 
for(account m : recs) {
            messageBody = m.Field1__c+'--'+ m.Field2__c+'--'+m.Field3__c ;
            accstring.add(messageBody );           
          if(m.CreatedById==m.OwnerId) {
           toAddresses.add(m.owner.email);
}
       }

Doing this with Scheduled Apex instead of the batch is fairly simple. See the syntax in the following documentation

Just move the same code to the execute method. The logic remains the same. Hope this helps

Anudeep
Michael MMichael M
Thanks again!!