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
ajbtv2ajbtv2 

Logic to satisify email and soql limits on InstallDate of Asset

I've been tasked with the following:

 

1.  Identify all assets with an Install Date of Today.

2.  Identify the Contact and Public Group Users associated with the Asset.

3.  Email all identified people with details about their asset.

 

Because of the Salesforce limits of only being able to send out 10 emails and online invoke 100 SOQL statements, I have not been able to find logic that will successfully satisfy this requirement.

 

I was going to use Mass Email, but it will not work with WhatIds of Assets (not will it allow me to connect users to the Asset).

 

I have had success in sending the email through a trigger when the Install Date is entered line by line, but any Mass Updates fail because of the limits mentioned and the requirement being to identify the individuals and Information per Asset Record.

 

Any assistance would be greatly appriciated.

mark.peplowmark.peplow

I reckon you're trigger will fail at some time too. Since salesforce batches up 200 records at a time, and you are allowed 10 single email calls per transaction you will run into problems with email limits.

 

Its way more complicated than it should be, but the folowing approach should work:

 

  • build a batch apex class that accepts a list of contacts
  • Use single email message class
  • pass in 10 contacts at a time

You will have to come up with a way to identify the contacts that are to be emailed. Either by using a custom object to create a list of contacts or adding a custom field to contact.

 

I have written something like this before. If i locate it i will post it.

 

 

mark.peplowmark.peplow

try this as a start point for your batch apex. I built a visualforce page to fire off the batch process for 10 items at a time.

 

public class RunBatchjobs {
Public Id Testid;
public AsyncApexJob getAsyncApexJob()
{return [SELECT id, ApexClassId,JobItemsProcessed, TotalJobItems,NumberOfErrors FROM AsyncApexJob WHERE ID =: testid];
}
    public PageReference Progress() {

        return null ;
    }


    public PageReference submit() {
        SendMassEmailItems Test1 = new SendMassEmailItems ();
        Id DeleteProcessId = Database.executeBatch(Test1,10); 
        testid=DeleteProcessId;
        return null;
    }
    public string getProgress() 
    {
      return null;
    }
}

global class SendMassEmailItems implements Database.Batchable<sObject> {
global SendMassEmailItems ()
{

}
global Database.QueryLocator start(Database.BatchableContext BC){
   return Database.getQueryLocator([SELECT id, name, Email_Subject__c,Email_Text__c,Case__c,
     contact__c, Owner__c FROM Email_Item__c
     WHERE Mass_Email_Secondary__c = TRUE ORDER BY Requested_Date__c DESC ]);
}
global void execute(Database.BatchableContext BC,List<sObject> scope){
list <OrgWideEmailAddress> OrgEmailid = [select id from OrgWideEmailAddress where 
      DisplayName=:'Communications' limit 1];
EmailTemplate EmailTempl = [select id, DeveloperName from EmailTemplate where
    DeveloperName =:'Generic_Comms' limit 1];
for (sObject s : scope) {
      Email_Item__c EMItem= (Email_Item__C) s;
      String EmailSubject = EMItem.Email_Subject__c;
      string EmailBody = EMItem.Email_Text__c;
      string caseid = EMItem.Case__c;
      String ContactId = EMItem.contact__c;
      String Ownerid = EMItem.Owner__c;
      string emailItemId =  EMItem.id;
      //setup email
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
      If (OrgEmailid.size()!=0){
         mail.setOrgWideEmailAddressId(OrgEmailid.get(0).id);}
      Else{
         mail.setSenderDisplayName('Customer Support');}
      mail.setreplyto('test@test.com');
      mail.setSaveAsActivity(true);
      mail.setTemplateID(EmailTempl.id);
      mail.setTargetObjectId(ContactId);
      mail.setWhatId(emailItemId );
      EMItem.Status__c='Sent to Customer';
      EMItem.Once_Approved__c = TRUE;
      //send the email
      Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail } );
         //Move Email Item Activity History to Case Activity History
 
            //Any additional account object processing...
       }
        //Any final processing...
        //Move Email Item Activity History to Case Activity History
        //List<Task> listTasks = [Select Id,WhatId,Type From Task Where whatid =: EmailItemDetails.id];
        //for (Task T :listTasks) {
         //    T.Whatid =caseid  ;
        //     T.Type = 'Email';}
         //    Update listTasks ;
    }

global void finish(Database.BatchableContext BC){

 AsyncApexJob a = [Select Id, Status, NumberOfErrors, JobItemsProcessed,
   TotalJobItems, CreatedBy.Email
   from AsyncApexJob where Id =:BC.getJobId()];

  // Send an email to the Apex job's submitter notifying of job completion.  
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  String[] toAddresses = new String[] {'test@test.com'};
  mail.setToAddresses(toAddresses);
  mail.setSubject('Apex Sharing Recalculation ' + a.Status);
  mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +
    ' batches with '+ a.NumberOfErrors + ' failures.');

  Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}

}