0

I have a custom object called Daily Assessment and this object has a master detail relation ship with Entitlements. Every day a Daily Assessment record has to be under the entitlements (Meaning that daily assessment report was generated for that Entitlement).I wanted a Scheduled class which will fire an email if there are no child records created on the entitlement on any given day. The following is the code i have:

global class DailyAssessmentSchedulable implements Schedulable {

    public static String emailAddress = '****.******@example.com';

    global void execute(SchedulableContext ctx) {
        List<Entitlement> entitlementList = new List<Entitlement>();
        List<Entitlement> notificationList = new List<Entitlement>();
        List<Daily_Assessment__c> dailyAssessmentList = new List<Daily_Assessment__c>();
        MAP<Id, Entitlement> entitlementMap = new Map<Id, Entitlement>([SELECT Id,
                                  Name, 
                                  (SELECT Id, 
                                          CreatedDate, 
                                          Entitlement_Name__c 
                                   FROM Daily_Assessments__r 
                                   WHERE CreatedDate = TODAY) 
                                  FROM Entitlement
                                  WHERE Name LIKE '%MSO%']);

        entitlementList = entitlementMap.values();
        for(Entitlement ent : entitlementList){
            //logic to decide which user has not submitted and 
            //add it to a list and send email using sendEmail() method
            dailyAssessmentList = new List<Daily_Assessment__c>();
            dailyAssessmentList = ent.Daily_Assessments__r;
            if(dailyAssessmentList.isEmpty()){
               notificationList.add(ent);
            }
        }

        sendEmail(notificationList);
    }

    //send email method
    private void sendEmail(List<Entitlement> notificationList){
        if(notificationList != null){
            Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
            message.toAddresses = new String[] {emailAddress};
            message.subject = 'Entitlement Daily Assessment reports update';
            message.plainTextBody = 'Daily Assessments for the following entitlements were not submitted today: ';
            for(Entitlement ent : notificationList){
               message.plainTextBody += ent.Name + ', ';    
            }            
            Messaging.SingleEmailMessage[] messages =   new List<Messaging.SingleEmailMessage> {message};
            Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);

            if (results[0].success) {
                System.debug('The email was sent successfully.');
            } else {
                System.debug('The email failed to send: ' + results[0].errors[0].message);
            }
        }
    }

}

The issue with this code is whenever i run this class it is looking for the entitlement's child record created date and if all the entitlements are having new child date on that calendar day then an empty Email is being sent with the foloowing text (Daily Assessments for the following entitlements were not submitted today). How can i add a condition so that i will not fire the email if the Entitlements have child records on a calendar day.

3
  • The answer that was deleted should have worked. Wrap the sendEmail in a check to see if the notification list is not empty. How did you deploy that change to test it? If you deployed and the job was still scheduled you need to compile all classes to have the scheduler pick up the changes. Otherwise it uses a cached version of the code.
    – Eric
    Mar 14, 2017 at 19:39
  • You don't need the map. for (Entitlement ent : [select ...]) { if (!ent.Daily_Assessments__r.isEmpty()) notifcationList.add(ent);}
    – cropredy
    Mar 14, 2017 at 19:55
  • @erick : I removed the job which was scheduled and then to test that condition i i run the class from Dev Console. I got the empty email with the text that i have in the text body. Mar 14, 2017 at 20:01

1 Answer 1

1

The issue was because of a Null check.

You had initialised the notificationList in your execute method and then were passing a reference to sendEmail method and were checking for Null state. As, it is never going to be Null and it will always go inside the If loop and send an empty email. You actually needed to check if there are any records in the list.

I have updated your code to make some slight changes:

global void execute(SchedulableContext ctx) {

    List<Entitlement> notificationList = new List<Entitlement>();

    for(Entitlement ent : [SELECT Id,Name, 
                                  (SELECT Id,CreatedDate,Entitlement_Name__c 
                                     FROM Daily_Assessments__r 
                                    WHERE CreatedDate = TODAY) 
                             FROM Entitlement
                            WHERE Name LIKE '%MSO%']){

        //logic to decide which user has not submitted and 
        //add it to a list and send email using sendEmail() method

        if(ent.Daily_Assessments__r.isEmpty())
           notificationList.add(ent);
        }
    }

    if(!notificationList.isEmpty())
        sendEmail(notificationList);
}

Here is your updated Send email method

private void sendEmail(List<Entitlement> notificationList){
        if(!notificationList.isEmpty()){
            Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
            message.toAddresses = new String[] {emailAddress};
            message.subject = 'Entitlement Daily Assessment reports update';
            message.plainTextBody = 'Daily Assessments for the following entitlements were not submitted today: ';
            for(Entitlement ent : notificationList){
               message.plainTextBody += ent.Name + ', ';    
            }            
            Messaging.SingleEmailMessage[] messages =   new List<Messaging.SingleEmailMessage> {message};
            Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);

            if (results[0].success) {
                System.debug('The email was sent successfully.');
            } else {
                System.debug('The email failed to send: ' + results[0].errors[0].message);
            }
        }
    }
3
  • By writing a SOQL Query within a For loop, I may violate the DML Limits. So i Just changed the Send email method By replacing if(notificationList != null) with if(!notificationList.isEmpty()). Now everything is working fine. Thank you so much for your help. Mar 15, 2017 at 13:36
  • This SOQL query will be executed only once and will return a collection for the for loop to iterate over. Mar 15, 2017 at 13:39
  • Also mark the Answer as Best answer to help others for such issues. Mar 15, 2017 at 13:40

You must log in to answer this question.

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