1

Im new in salesforce apex programming..

I want to make an email reminder if case status != closed to case owner H+5, H+7, and H+10 ..

H = created date

.. how do i get the owner email value? and send only 1 email to the owner who have many cases? (using apex class) sorry for bad english

this is what i`ve tried so far.. i tried to learn how to send the email 1st to user (Mine), still figuring out how to match the case id and owner..

Global class SchReminderActivitytoOwner implements Schedulable  {

    Global void execute(SchedulableContext ctx) {

        List<Messaging.SingleEmailMessage> listmail = new List<Messaging.SingleEmailMessage>();
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        EmailTemplate et = [SELECT Id, Subject, HtmlValue FROM EmailTemplate WHERE developerName  = 'ET_Case_Reminder_Testing'];

        String subject = 'Testing Reminder'; //'et.Subject';                            
        String htmlBody = et.HtmlValue;
        Date MyDate = Date.Today();

        id OwnerLast;

        List<Case> listcase = new List<Case>(); 
        listcase = [SELECT Id, ContactEmail, Owner_Name__c, Owner.Email, Status, Ticket_Number__c, CaseNumber, Subject, SLA_Case_Closed_Days__c
                    FROM Case WHERE Email_Target__c = '[email protected]' and Status != 'Closed' Order by Owner.Name];

        List<User> listUser = new List<User>();
        listUser = [SELECT Id, Name, ProfileId, Profile.Name, isActive,  Email FROM User 
                        WHERE Email = '[email protected]'];  

        for (Case cs : listcase){
                htmlBody = htmlBody.replace('{!Case.OwnerFullName}', cs.Owner_Name__c);
                htmlBody = htmlBody.replace('{!Case.Ticket_Number__c}', String.Valueof(cs.CaseNumber));
                htmlBody = htmlBody.replace('{!Case.Subject}', cs.Subject);
                htmlBody = htmlBody.replace('{!Case.SLA_Handling_Time_Target__c}', String.Valueof(cs.SLA_Case_Closed_Days__c));         

            for (user us : listUser){

                        //If (cs.Status != 'Closed'){
                            string [] toaddress= New string[]{us.Email};
                            //String emailReceiver = rcv.Email;
                            mail.setSubject(subject);
                            mail.setHtmlBody(htmlBody); 
                            mail.setToAddresses(toaddress);
                            mail.setSaveAsActivity(false);
                            Messaging.sendEmail(New Messaging.SingleEmailMessage[]{mail});
        }
                        //}
                        /*
                        mail.setSubject('Testing Apex Scheduler-Subject');
                        mail.setPlainTextBody('Testing Apex Scheduler-Body');
                        mail.setToAddresses(toaddress);
                        Messaging.sendEmail(New Messaging.SingleEmailMessage[]{mail});

                        listmail.add(mail);
                        Messaging.sendEmail(listmail);
                        */
                }
    }
   }
2
  • You dont need owner Email value, you can set Targetid as ownerId and send emails. That being said, can you post code of what you have tried so far, it Commented Jun 29, 2018 at 11:12
  • @PranayJaiswal thats what ive tried so far ^ .. Commented Jun 29, 2018 at 11:26

3 Answers 3

2

I assume there are less than 50K unclosed cases in your Org. As you are sending email to the owner, you can use setTargetObjectId which you can set as OwnerId , it will allow you to get rid of single email 5000 emails a day limit

global class SchReminderActivitytoOwner implements Schedulable  {

global void execute(SchedulableContext ctx) {

    List<Messaging.SingleEmailMessage> listmail = new List<Messaging.SingleEmailMessage>();

    EmailTemplate et = [SELECT Id, Subject, HtmlValue FROM EmailTemplate WHERE developerName  = 'ET_Case_Reminder_Testing'];

    String subject = 'Testing Reminder';                            
    String htmlBody = et.HtmlValue;
    Date MyDate = Date.Today();       

    List<Case> listcase = [SELECT Id, ContactEmail, Owner_Name__c, Owner.Email, Status, Ticket_Number__c, CaseNumber, Subject, SLA_Case_Closed_Days__c
                        FROM Case WHERE Email_Target__c = '[email protected]' and Status != 'Closed' Order by Owner.Name];


    for (Case cs : listcase){
            htmlBody = htmlBody.replace('{!Case.OwnerFullName}', cs.Owner_Name__c);
            htmlBody = htmlBody.replace('{!Case.Ticket_Number__c}', String.Valueof(cs.CaseNumber));
            htmlBody = htmlBody.replace('{!Case.Subject}', cs.Subject);
            htmlBody = htmlBody.replace('{!Case.SLA_Handling_Time_Target__c}', String.Valueof(cs.SLA_Case_Closed_Days__c));         

            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            mail.setSubject(subject);
            mail.setHtmlBody(htmlBody); 
            mail.setTargetObjectId(cs.OwnerId);
            mail.setSaveAsActivity(false);
            listmail.add(mail);




            }

            Messaging.sendEmail(listmail);
}
}
3
  • Thanks!! Btw sorry it takes a very long time for me to reply.. Commented Jul 1, 2018 at 14:08
  • now I want to make a table (as email body), so the email body = list of cases that the owner has (sending 1 email with the list of cases to 1 owner), instead of sending 1 email for 1 case to 1 owner. .. how do i write the loop? Commented Jul 1, 2018 at 14:15
  • Dynamically create html table rows based on List of cases Commented Jul 1, 2018 at 16:22
0

I would actually suggest creating a standard report and subscribing your users to it instead of using a custom Apex solution. Mainly for two reasons:

  1. Like @PranayJaiswal said, you have a scalability issue since Salesforce cannot send more than 5.000 daily emails. If you start sending let's say, 1.000 emails just with reminders for this feature, you're already working against the limits.

  2. The apex solution needs to be tested thoroughly and changing a requirement down the road implies that you have to ask the development team to do it. On the other hand, a custom report can be done on the fly and is pretty bulletproof since it's a very standard Salesforce core feature.

The only pitfall to my suggestion is that you will not be delivering a very customized message - users will just get a daily/weekly/monthly email with their open cases. But I think that the pros are much bigger than the small con, specially since it's more of an internal company email.

0

i did this but nothing happen .. but if i use the toAddresses() and type my mail address manually, i got the mail exactly what i wanted..

List<Messaging.SingleEmailMessage> listmail = new List<Messaging.SingleEmailMessage>();

EmailTemplate et = [SELECT Id, Subject, HtmlValue FROM EmailTemplate WHERE developerName  = 'ET_Case_Reminder_Testing'];

String subject = 'Testing Reminder';                            
String htmlBody ='<h1>***JANGAN DIBALAS/DO NOT REPLY***</h1><br>Dear {!Case.OwnerFullName}, <br>Mohon untuk menindaklanjuti pengajuan interaksi berikut ini sebelum melewati waktu SLA<br><br><caption><b>System - Case Reminder</b></caption><table border="1" style="border-collapse: collapse"><tr><th><b>No</b></th><th><b>Ticket Number</b></th><th><b>Subject</b></th><th><b>SLA Handling Time Target</b></th><th><b>Created By</b></th><th><b>Detail</b></th></tr>';
Date MyDate = Date.Today();       

List<Case> listcase = [SELECT Id, ContactEmail, Owner_Name__c, Owner.Email, Status, Ticket_Number__c, CaseNumber, Subject, SLA_Case_Closed_Days__c, CreatedBy.Name, OwnerId
                    FROM Case WHERE Email_Target__c = '[email protected]' AND Status != 'Closed' Order by Owner.Name];

Integer i;
for (Case cs : listcase){  


    String TicketNumber = String.Valueof(cs.CaseNumber); if(cs.CaseNumber == null){TicketNumber = '[Not Provided]';}
    String Sbj = cs.Subject; if(cs.Subject == null){Sbj = '[Not Provided]';}
    String HandlingTimeTarget = String.Valueof(cs.SLA_Case_Closed_Days__c); if(cs.SLA_Case_Closed_Days__c == null){TicketNumber = '[Not Provided]';}
    String Link = cs.Id; if(cs.Id == null){Link = '[Not Provided]';}
    String PIC = cs.CreatedBy.Name; if(cs.CreatedBy.Name == null){PIC = '[Not Provided]';}

    for (i = 1;  i <= listcase.size(); i++){
        htmlBody = htmlBody.replace('{!Case.OwnerFullName}', cs.Owner_Name__c);
        /*htmlBody = htmlBody.replace('{!Case.Ticket_Number__c}', String.Valueof(cs.CaseNumber));
        htmlBody = htmlBody.replace('{!Case.Subject}', cs.Subject);
        htmlBody = htmlBody.replace('{!Case.SLA_Handling_Time_Target__c}', String.Valueof(cs.SLA_Case_Closed_Days__c)); */        
        htmlBody += '<tr><td>' + String.ValueOf(i) + '</td><td>' + TicketNumber + '</td><td>' + Sbj + '</td><td>' + HandlingTimeTarget + '</td><td>' + PIC + '</td><td><a href="https://cs72.salesforce.com/' + Link + '">Click Here</a></td></tr>';

    }

        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        //Id [] toaddress= New Id[]{cs.OwnerId};
        mail.setSubject(subject);
        mail.setHtmlBody(htmlBody); 
        mail.setTargetObjectId(cs.OwnerId);
        //mail.setToAddresses(toaddress);
        mail.setSaveAsActivity(false);
        listmail.add(mail);
        Messaging.sendEmail(listmail);
}

} }

You must log in to answer this question.

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