0

I want to make a mail reminder that automatically send the email to my sales user every h+7 h+10 and h+15 created date.. how do I code the scheduler? using IF?

for example, I want this mail reminder on case object send automatically to case owner every h+7 h+10 and h+15 created date..


Edited

How about this? I used the daysDiff to get days between today and case closedate.. Im currently not in my workplace and didnt bring the laptop, so sorry cant post more code or testing result for next 4 hours..

global class SchReminderActivitytoOwner implements Schedulable  {


 public static String CRON_EXP = '0 0 8 * * ? *';
 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_Test22'];

Date now = Date.today();
String subject = 'Testing Reminder';                            
String htmlBody = et.HtmlValue;


map<string, list<case>> mapOwnerEmailtoCaseList = new map<string, list<case>>();
map<string, user> mapEmailtoUser = new map<string, user>();
for(Case objCase : [SELECT Id, Owner.Email, Status, Owner.Name, CaseNumber, CreatedBy.Name,Subject, OwnerId, SLA_Case_Closed_Days__c, CreatedDate  FROM Case where Status != 'Closed' AND Owner.Type = 'User']){

    if(mapOwnerEmailtoCaseList.containsKey(objCase.Owner.Email)) {
        List<Case> lstCase = mapOwnerEmailtoCaseList.get(objCase.Owner.Email);
        lstCase.add(objCase);
        mapOwnerEmailtoCaseList.put(objCase.Owner.Email, lstCase);
    } else {
        mapOwnerEmailtoCaseList.put(objCase.Owner.Email, new List<Case> { objCase });
    }
}               

for(User objUser : [SELECT Id, Name, ProfileId, Profile.Name, isActive,Email FROM User 
                    WHERE Email =: mapOwnerEmailtoCaseList.keyset() and IsActive = TRUE]){

    mapEmailtoUser.put(objUser.Email, objUser);
}        

map<string, string> mapOwnerEmailtoEmail = new map<string, string>();     
List<String> ccTo = new List<String>();
for(string strOwnerEmail : mapOwnerEmailtoCaseList.keyset()){

    User objUser = mapEmailtoUser.get(strOwnerEmail);
    htmlBody += '<br><table border="1" style="border-collapse: collapse"><tr><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>';
    list<Case> lstCase = mapOwnerEmailtoCaseList.get(strOwnerEmail);
    for(Case cs : lstCase){

        DateTime csDate = cs.CreatedDate;
        Date mycsDate = date.newinstance(csDate.year(), csDate.month(), csDate.day());
        Integer dayDiff = now.daysbetween(mycsDate);

            if (dayDiff == 7){
                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]';}

                htmlBody = htmlBody.replace('{!Case.OwnerFullName}', cs.Owner.Name);
                /*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>' + TicketNumber + '</td><td>' + Sbj + '</td><td>' + HandlingTimeTarget + '</td><td>' + PIC + '</td><td><a href="https://cs72.salesforce.com/' + Link + '">Click Here</a></td></tr>';

                mapOwnerEmailtoEmail.put(strOwnerEmail, htmlBody);
                }

    }
}



for(string strOwnerEmail : mapOwnerEmailtoCaseList.keyset()){

    if(strOwnerEmail != null){

    //system.debug('===strOwnerEmail===='+strOwnerEmail);
    string strHTML = mapOwnerEmailtoEmail.get(strOwnerEmail);
    strHTML += '</table><br><br><br><p>Terimakasih,</p><br><p>System Administrator</p>';
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); 

    List<String> sendTo = new List<String>();
    sendTo.add(strOwnerEmail);
    //mail.setTargetObjectId(sendTo);
    mail.setToAddresses(sendTo);
    mail.setSenderDisplayName('Administrator');
    mail.setSubject(subject);
    mail.setHtmlBody(strHTML);

    //List<String> ccTo = new List<String>();    
    //ccTo.add('rieftjong95@gmail.com');
    //mail.setCcAddresses(ccTo);
    mail.setSaveAsActivity(false);
    listmail.add(mail);

    }
    }
    Messaging.sendEmail(listmail);
}

}

2
  • Try first, if you can achieve through configuration Jul 15 '18 at 5:32
  • @SantanuBoral I know i can use workflow and time trigger, but the goal is to send 1 email with list of cases as email body to 1 owner. Not sending 1 email for 1 case to 1 owner.. I need some reference Jul 15 '18 at 7:26
1
  1. create a picklist field called 'ReminderType__c' with following items: 'first reminder', 'second reminder', 'third reminder' and 'None'
  2. create a formula field that calculate the age of the entries in hours, you can refer to this article.
  3. create a schedule job that iterate through the entries every 5 minutes so that it can send the reminders accordingly.

global class EmailReminderSchedule implements Schedulable {
    private static final Integer MINUTES = 5;

    public void execute(SchedulableContext sc) {
        if (sc != null) {
            CronTrigger job = [SELECT Id, CronJobDetail.Id, CronJobDetail.Name, CronJobDetail.JobType FROM CronTrigger WHERE Id = :sc.getTriggerId() ORDER BY CreatedDate DESC LIMIT 1];
            this.cronJobName = job.CronJobDetail.Name;
        }

        if (this.cronJobName.startsWith('Send reminders')) {
            sendReminders();
        }

        resetSchedule(); // after all is processed reschedule after 5 minutes
    }

    private void sendReminders() {
        List<Case> casesToUpdateList = new List<Case>();
        List<Messaging.Email> emailReminders = new List<Messaging.Email>();

        for (Case c : [SELECT ReminderType__c, AgeObjectInhours__c, Owner.Email FROM Case WHERE ReminderType__c != 'None' AND AgeObjectInhours__c >= 7]) {

            Messaging.SingleEmailMessage mail = new Massaging.Messaging.SingleEmailMessage();

            if (c.AgeObjectInhours__c >= 15) {
                mail.setSubject('Third case reminder : ' + c.Id);
                c.ReminderType__c = 'NONE';
            } else if (c.AgeObjectInhours__c >= 10) {
                mail.setSubject('Second case reminder : ' + c.Id);
                c.ReminderType__c = 'third reminder';
            } else if (c.AgeObjectInhours__c >= 7) {
                mail.setSubject('First case reminder : ' + c.Id);
                c.ReminderType__c = 'second reminder';
            }


            mail.setHtmlBody('Your case:<b> ' + case.Id + ' </b> .......');
            mail.setToAddresses(new List<String>{c.Owner.Email});

            emailReminders.add(mail);
            casesToUpdateList.add(c);
        }

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

    }

    public static void setSchedule() {
        System.schedule('Send reminders', getSchedulerEvery(MINUTES), new AutoApproveOpportunitySchedule());
    }

    public static void abortSchedule() {
        List<CronTrigger> cts = [SELECT Id FROM CronTrigger WHERE CronJobDetail.Name LIKE 'Send reminders%'];
        for (CronTrigger ct : cts) {
            System.abortJob(ct.Id);
        }
    }

    private static String getSchedulerEvery(Integer minutes) {
        DateTime mydate = system.now();
        Integer min = mydate.minute();

        min += minutes;
        if (min >= 60) min = 0;

        return String.format('0 {0} * * * ? ', new String[]{
                min.format()
        });
    }

    public static void resetSchedule() {
        abortSchedule();
        setSchedule();
    }
}
-----

References:

2
  • I tried something else with my code, using daysDiff.. will this works? Jul 18 '18 at 7:36
  • I think so; however, the way I suggested is not counting the weekends but the weekdays only. Jul 18 '18 at 8:09
0

You could also achieve this through configuration using a combination of Time based Workflow Rules and Visualforce Email Templates.

The approach would be as follows.

  1. Create a DateTime field on Case - NextEmailSendDate.
  2. Use an Action based Workflow Rule or Apex Trigger to detect the changes on the respective Case record and accordingly compute the date and time for sending the next email.
  3. Stamp the computed Date and Time value within the NextEmailSendDate field on the Case record.
  4. Setup up another time based workflow that sends an email based on the DateTime value in the NextEmailSendDate field on Case.
  5. Have the outgoing email leverage a Visualforce Email template in order to get the desired content format.
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.