Email body - Answers - Salesforce Trailblazer Community
Trailblazer Community
Ask Search:
Harish GAADEHarish GAADE 

Email body

Hi All,
i have schedule class which schedule the job and send the html email  template to the user but my issue is customer are changing the mail body now and then so we are changing the code every time.
i wanted to know is their is any other way such that if i wanted to update their it will change in the code so that i no need to change the code every time customer to change the body of the html template.
 
class:-
global class RCH_SendSignatureCaptureEmailScheduler implements Database.Batchable<sObject>, Schedulable,Database.Stateful {
   public Integer callSignatureCount = 0;
   global void execute(SchedulableContext sc){
       RCH_SendSignatureCaptureEmailScheduler Batch = new RCH_SendSignatureCaptureEmailScheduler();
        database.ExecuteBatch(Batch,10);
   }
   global final String Query='select Id,CreatedBy.Name,CreatedBy.Email,OCE__Account__r.Name,OCE__Account__r.OCE__Email__c,RCH_Is_Signature_Sent__c,OCE__IsSignatureCopyRequested__c,OCE__SignatureDate__c,CreatedBy.TimeZoneSidKey,OwnerID  from OCE__Call__c where OCE__Status__c =\'Submitted\' and RCH_Is_Signature_Sent__c= false and OCE__NumberOfCallSampleOrders__c!=0';//OCE__IsSignatureCopyRequested__c = true and 
   global Database.QueryLocator start(Database.BatchableContext BC){
        AsyncApexJob apexJob = [SELECT CompletedDate, JobItemsProcessed, JobType, NumberOfErrors, Status, TotalJobItems, CreatedDate, ApexClassId
                FROM AsyncApexJob
                WHERE Id = :  bc.getJobId()];
        OCE__JobStatistics__c jobStatisticsItem = new OCE__JobStatistics__c();
        jobStatisticsItem.OCE__JobName__c = 'Call Signature Capture Email Scheduler';
        jobStatisticsItem.OCE__Type__c = 'Call Signature Capture Email Scheduler';
        jobStatisticsItem.OCE__JobId__c = apexJob.Id;
        jobStatisticsItem.OCE__Start__c = apexJob.CreatedDate;
        Database.insert(jobStatisticsItem,false);
      return Database.getQueryLocator(query);
   }
   
   global void execute(Database.BatchableContext BC, List<sObject> scope){
       try{
            List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();
            List<OCE__Call__c> Calls = scope;
            List<ID> CallIds = new List<ID>();  
            set<ID> ownerIds = new  set<ID>();         
            for(OCE__Call__c callInstance:Calls){
                CallIds.add(callInstance.id); 
                ownerIds.add(callInstance.OwnerID);   
            }
            map<ID,String> mapUserTimeZone = new map<ID,String>();
            for(User userInstance:[select id,TimeZoneSidKey from user where id in:ownerIds]){
                mapUserTimeZone.put(userInstance.Id, userInstance.TimeZoneSidKey );
            }            
            Map<string,OCE__CallSampleOrder__c> callSampleOrderMap=new Map<string,OCE__CallSampleOrder__c>();
            for(OCE__CallSampleOrder__c sampleOrderRec: [select Id,OCE__Call__c,RCH_Preferred_Delivery_Days__c from OCE__CallSampleOrder__c where OCE__Call__c in : CallIds order by lastmodifieddate desc]){
                callSampleOrderMap.put(sampleOrderRec.OCE__Call__c,sampleOrderRec);
            }
            
            callSignatureCount += CallIds.size();
            List<String> documentIds = new List<String>();
            Map<String, Attachment> mapCallAttachment = new Map<String, Attachment>();        
            List<Attachment> docList = [SELECT Id,ParentID,Body,Name FROM Attachment WHERE ParentID in :CallIds];  
            
            for(Attachment attachmentInstance:docList){
                mapCallAttachment.put(attachmentInstance.parentID, attachmentInstance);   
            }      
                  
            
            for(OCE__Call__c callInstance:Calls){
                String subject = 'Sample Order eCopy'; 
                String fromaddress = Label.RCH_DTP_Sender_Email;
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                OrgWideEmailAddress[] owea = [select Id from OrgWideEmailAddress where Address = :fromaddress];
                if ( owea.size() > 0 ) {
                    mail.setOrgWideEmailAddressId(owea.get(0).Id);
                }
                mail.setSaveAsActivity(false);
                mail.setSubject(subject);
                String htmlBody = 'Dear '+callInstance.OCE__Account__r.Name +',';
                htmlBody += '<br/><br/>';
                htmlBody += 'Thank you for your Actemra (tocilizumab) SC sample request on '+ callInstance.OCE__SignatureDate__c.format('dd-MM-yyyy',mapUserTimeZone.get(callInstance.ownerID)); 
                //htmlBody=htmlBody.left(htmlBody.length()-9);
                htmlBody += '.<br/><br/>';
                htmlBody += 'A copy of your order is visible below.';
                htmlBody += '<br/><br/>';
                if(callSampleOrderMap.containskey(callInstance.Id)){
                    htmlBody += 'Please expect your Actemra samples to be delivered as requested on ';
                    OCE__CallSampleOrder__c sampleOrderRec=callSampleOrderMap.get(callInstance.Id);
                    if(sampleOrderRec.RCH_Preferred_Delivery_Days__c!=null){
                            if(!sampleOrderRec.RCH_Preferred_Delivery_Days__c.contains(';'))
                            htmlBody +=sampleOrderRec.RCH_Preferred_Delivery_Days__c;
                            else{
                                string temphtmlBody=htmlBody;
                                for(String dayVal:sampleOrderRec.RCH_Preferred_Delivery_Days__c.split(';')){
                                    temphtmlBody+=dayVal+', ';
                                }
                                temphtmlBody=temphtmlBody.removeend(', ');
                                integer indexofLastComma=temphtmlBody.lastIndexOf(',');
                                htmlBody=temphtmlBody.left(indexofLastComma)+' or'+temphtmlBody.Right(temphtmlBody.length()-indexofLastComma-1);
                            }
                    }
                    htmlBody += '.<br/><br/>';
                }
                htmlBody += 'Should you have any further queries please contact ZEST on 1800 706 609';
                htmlBody += '.<br/><br/>';
                htmlBody += '<b>IMPORTANT - Actemra SC samples will need refrigerated storage on delivery.</b>';
                htmlBody += '<br/><br/>';                
                htmlBody += '<div align=center><table border=1 cellspacing=0 cellpadding=0 width=620 style="mso-cellspacing:0in;background:white;border:solid windowtext 1.0pt; mso-border-alt:solid windowtext .5pt;mso-yfti-tbllook:1184;mso-padding-alt: 0in 0in 0in 0in"> <tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes"> <td style="border:none;background:#E4E4E4;padding:22.5pt 22.5pt 0in 22.5pt"> <p align=center style="margin-bottom:0in;margin-bottom:.0001pt;  text-align:center;line-height:15.0pt"><span lang=EN-AU style="font-size:9.0pt;  font-family:Helvetica,sans-serif;mso-fareast-font-family:Times New Roman;  color:#606060;letter-spacing:.25pt">To report an adverse event or other urgent safety issue, please contact the Australian Drug Safety Department on&nbsp;</span><u><span lang=EN-AU style="font-size:9.0pt;font-family:Helvetica,sans-serif; mso-fareast-font-family:Times New Roman;color:#0C73D2;letter-spacing:.25pt"><a href="mailto:australia.drug_safety@roche.com" target="_blank"><span  style="color:#0C73D2">australia.drug_safety@roche.com</span></a></span></u><span  lang=EN-AU style="font-size:9.0pt;font-family:Helvetica,sans-serif;  mso-fareast-font-family:Times New Roman;color:#606060;letter-spacing:.25pt">&nbsp;or  on&nbsp;<u><a href="tel:+61-2-9454-9444" target="_blank"><span  style="color:#606060">+61 2 9454 9444.</span></a></u><o:p></o:p></span></p>  </td> </tr> <tr style="mso-yfti-irow:1">  <td style="border:none;background:#E4E4E4;padding:7.5pt 22.5pt 0in 22.5pt">  <p  align=center style="margin-bottom:0in;margin-bottom:.0001pt;  text-align:center;line-height:15.0pt"><span lang=EN-AU style="font-size:9.0pt;  font-family:Helvetica,sans-serif;mso-fareast-font-family:Times New Roman;  color:#606060;letter-spacing:.25pt">Confidentiality: This message is intended only for the use of the named recipient(s) and may contain confidential and/or proprietary information. If you are not the intended recipient, please contact the sender and delete this message. Any unauthorised use of the information contained in this message is prohibited.<o:p></o:p></span></p>  </td> </tr> <tr style="mso-yfti-irow:2">  <td style="border:none;background:#E4E4E4;padding:7.5pt 22.5pt 0in 22.5pt">  <p  align=center style="margin-bottom:0in;margin-bottom:.0001pt;  text-align:center;line-height:15.0pt"><span lang=EN-AU style="font-size:9.0pt;  font-family:Arial,sans-serif;mso-fareast-font-family:Times New Roman;  color:#767171;mso-themecolor:background2;mso-themeshade:128">Roche is committed to protecting your privacy by collecting, storing, using and disclosing your personal information in accordance with the&nbsp;<i>Privacy Act 1988&nbsp;</i>(<span class=SpellE>Cth</span>) and the Australian Privacy Principles as set out in the&nbsp;<u><a  href="https://www.roche-australia.com/en_au/privacy.html" target="_blank"><span  style="color:#767171;mso-themecolor:background2;mso-themeshade:128">Roche Privacy Policy</span></a></u>. If you would like to request access to your personal information&nbsp;held by Roche; request an amendment or correction of your personal information held by Roche; ask us to remove your personal information from our system, or ask us questions, please make email us at&nbsp;<u><a href="mailto:australia.privacy-request@roche.com"  target="_blank"><span style="color:#767171;mso-themecolor:background2;  mso-themeshade:128">australia.privacy-request@roche.com</span></a></u>.</span><span  lang=EN-AU style="font-size:9.0pt;font-family:Helvetica,sans-serif;  mso-fareast-font-family:Times New Roman;color:#606060;letter-spacing:.25pt"><o:p></o:p></span></p>  </td> </tr> <tr style="mso-yfti-irow:3">  <td style="border:none;background:#E4E4E4;padding:9.0pt 22.5pt 0in 22.5pt">  <table Table border=0 cellspacing=0 cellpadding=0 width="100%"   style="width:100.0%;mso-cellspacing:0in;mso-yfti-tbllook:1184;mso-padding-alt:   0in 0in 0in 0in">   <tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;mso-yfti-lastrow:yes">    <td style="border:solid #9F9F9F 1.0pt;mso-border-alt:solid #9F9F9F .75pt;    background:white;padding:7.5pt 11.25pt 7.5pt 11.25pt">    <p  align=center style="margin-bottom:0in;margin-bottom:    .0001pt;text-align:center;line-height:14.4pt"><b><span lang=EN-AU    style="font-size:9.0pt;font-family:Helvetica,sans-serif;mso-fareast-font-family: Times New Roman;color:#606060;letter-spacing:.25pt">PBS Information: </span></b><span    class=SpellE><span lang=EN-AU style="font-size:9.0pt;font-family:Helvetica,sans-serif;  mso-fareast-font-family:Times New Roman;color:#606060;letter-spacing:.25pt;mso-bidi-font-weight:bold">Actemra</span></span><span lang=EN-AU   style="font-size:9.0pt;font-family:Helvetica,sans-serif;mso-fareast-font-family:Times New Roman;color:#606060;letter-spacing:.25pt;mso-bidi-font-weight:    bold"> IV:</span><span lang=EN-AU style="font-size:9.0pt;font-family:Helvetica,sans-serif;    mso-fareast-font-family:Times New Roman;color:#606060;letter-spacing:    .25pt">&nbsp;Written authority required for RA, <span class=SpellE>sJIA</span>,    <span class=SpellE>pJIA</span>. <span class=SpellE>Actemra</span> SC:    Written authority required for RA, <span class=SpellE>pJIA</span>, GCA.    Refer to the PBS schedule for full information.<o:p></o:p></span></p>    </td>   </tr>  </table>  </td> </tr> <tr style="mso-yfti-irow:4">  <td style="border:none;background:#E4E4E4;padding:7.5pt 22.5pt 0in 22.5pt">  <p  align=center style="margin-bottom:0in;margin-bottom:.0001pt;  text-align:center;line-height:15.0pt"><span lang=EN-AU style="font-size:11pt;  font-family:Helvetica,sans-serif;mso-fareast-font-family:Times New Roman;  color:#606060;letter-spacing:.25pt">Please review the Product Information before prescribing. The Product Information can be accessed at&nbsp;</span><u><span lang=EN-AU style="font-size:11pt;font-family:Helvetica,sans-serif;  mso-fareast-font-family:Times New Roman;color:#0C73D2;letter-spacing:.25pt"><a  href="https://edm.roche-australia.com/t/r-l-jdgdhjk-udllihmhl-i/"  target="_blank"><span style="color:#0C73D2">www.roche-australia.com/productinfo/actemra</span></a></span></u><span  lang=EN-AU style="font-size:11pt;font-family:Helvetica,sans-serif;  mso-fareast-font-family:Times New Roman;color:#606060;letter-spacing:.25pt">.  Further information is available from Roche Medical Information on&nbsp;<u><a  href="tel:1800%20233%20950" target="_blank"><span style="color:#606060">1800 233 950</span></a></u>.<o:p></o:p></span></p>  </td> </tr> <tr style="mso-yfti-irow:5">  <td style="border:none;background:#E4E4E4;padding:7.5pt 22.5pt 0in 22.5pt">  <p  align=center style="margin-bottom:0in;margin-bottom:.0001pt;  text-align:center;line-height:15.0pt"><span lang=EN-AU style="font-size:9.0pt;  font-family:Helvetica,sans-serif;mso-fareast-font-family:Times New Roman;  color:#606060;letter-spacing:.25pt">Further information is available on request from Roche Products Pty Limited, ABN 70 000 132 865, Level 8,&nbsp;30-34&nbsp;Hickson&nbsp;Road, Sydney NSW&nbsp;2000. Medical Information:&nbsp;<u><a href="tel:1800%20233%20950" target="_blank"><span  style="color:#606060">1800 233 950</span></a></u>.&nbsp;</span><sup><span  lang=EN-AU style="font-size:7.0pt;font-family:Helvetica,sans-serif;  mso-fareast-font-family:Times New Roman;color:#606060;letter-spacing:.25pt">®</span></sup><span  lang=EN-AU style="font-size:9.0pt;font-family:Helvetica,sans-serif;  mso-fareast-font-family:Times New Roman;color:#606060;letter-spacing:.25pt">Registered Trademark. EMVACT1507 EC-AU-8614 PreparedSep19.<o:p></o:p></span></p>  </td> </tr> <tr style="mso-yfti-irow:6;mso-yfti-lastrow:yes">  <td style="border:none;background:#E4E4E4;padding:7.5pt 22.5pt 0in 22.5pt">  <p  align=center style="margin-bottom:0in;margin-bottom:.0001pt;  text-align:center;line-height:15.0pt"><span lang=EN-AU style="font-size:9.0pt;  font-family:Helvetica,sans-serif;mso-fareast-font-family:Times New Roman;  color:#606060;letter-spacing:.25pt">If you would like to withdraw your consent for inclusion in Roche electronic mail, click</span><u><span  lang=EN-AU style="font-size:9.0pt;font-family:Helvetica,sans-serif;  mso-fareast-font-family:Times New Roman;color:#0C73D2;letter-spacing:.25pt"><a  href="https://edm.roche-australia.com/t/r-l-jdgdhjk-udllihmhl-d/"  target="_blank" title=Unsubscribe><span style="color:#0C73D2">&nbsp;here</span></a></span></u><span  lang=EN-AU style="font-size:9.0pt;font-family:Helvetica,sans-serif;  mso-fareast-font-family:Times New Roman;color:#606060;letter-spacing:.25pt">.<br  style="mso-special-character:line-break">  <![if !supportLineBreakNewLine]><br style="mso-special-character:line-break">  <![endif]><o:p></o:p></span></p>  </td> </tr></table></div>';
                
                mail.setHTMLBody( htmlBody);
                if(String.isNotBlank(callInstance.OCE__Account__r.OCE__Email__c) && callInstance.OCE__IsSignatureCopyRequested__c==true)
                    mail.setToAddresses(new String[] { callInstance.OCE__Account__r.OCE__Email__c });
                if(String.isNotBlank(Label.RCH_Request_Receipt_BCC_Email))
                    mail.setBccAddresses(new String[] {Label.RCH_Request_Receipt_BCC_Email});
                Attachment attachmentInstance = mapCallAttachment.get(callInstance.ID);
                if(attachmentInstance!=null){
                    Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
                    efa.setFileName('Sample Order eCopy'+'.jpeg');
                    efa.setBody(attachmentInstance.Body);
                    mail.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});                       
                }            
                emails.add(mail);
                
            }
            
            Messaging.sendEmail(emails);   
            for(OCE__Call__c callInstance:Calls){
               callInstance.RCH_Is_Signature_Sent__c = true;
            }
            database.update(Calls);  
       }
       Catch(Exception e){
           
       }
    }

   global void finish(Database.BatchableContext BC){
        //update statistics
        AsyncApexJob apexJob = [SELECT CompletedDate, JobItemsProcessed, JobType, NumberOfErrors, Status, TotalJobItems, CreatedDate, ApexClassId
                FROM AsyncApexJob
                WHERE Id = : bc.getJobId()];
        OCE__JobStatistics__c jobStatisticsItem = [SELECT Id, OCE__JobItemsProcessed__c, OCE__ApexClassID__c, OCE__End__c, OCE__JobId__c, OCE__NumberOfErrors__c, OCE__Start__c, OCE__Status__c, OCE__TotalJobItems__c, OCE__JobName__c, OCE__Type__c, OCE__ZipsProcessed__c, OCE__AccountsUpdated__c
                FROM OCE__JobStatistics__c
                WHERE OCE__JobId__c = : bc.getJobId()];
        jobStatisticsItem.OCE__JobItemsProcessed__c = apexJob.JobItemsProcessed;
        jobStatisticsItem.OCE__ApexClassID__c = apexJob.ApexClassId;
        jobStatisticsItem.OCE__Status__c = apexJob.Status;
        jobStatisticsItem.OCE__AccountsUpdated__c = callSignatureCount;
        jobStatisticsItem.OCE__End__c = System.now();
        jobStatisticsItem.OCE__NumberOfErrors__c = apexJob.NumberOfErrors;
        jobStatisticsItem.OCE__TotalJobItems__c = apexJob.TotalJobItems;
        Database.update(jobStatisticsItem,false);
        
   }
}

 
Nitin ChandwaniNitin Chandwani
Hi Harish, 

You can create a custom email template and use it instead of hardcoing the email body which won't need code changes in your class if you want to change email body. 

https://help.salesforce.com/articleView?id=admin_emailtemplates.htm&type=5
https://help.salesforce.com/articleView?id=creating_custom_html_email_templates.htm&type=5

Once created you can use the template with the code snippet given below.
EmailTemplate tem=[Select id,name from EmailTemplate where name = '<Template Name>' limit 1];
Messaging.MassEmailMessage Email = new Messaging.MassEmailMessage();
Email.setTemplateId(tem.id);

Thanks
Harish GAADEHarish GAADE
@Nitin Chandwani
thank you for your reply.
But i have some issue here i.e in  class i have line which are in the below  if you see  after Dear  i am getting the name from my custom object .and i am getting "callInstance.OCE__SignatureDate__c.format('dd-MM-yyyy',mapUserTimeZone.get(callInstance.ownerID))"  date from the code.
  • how can i assign the date value to the line through custom object.
  • i have created custom html email temp but i not sure were i have to use becauce i did add the below lines i.e Dear and 'Thank you for your Actemra (tocilizumab) SC sample request on
if you seen the screen short you can see Red and Yellow part i have create custom html email template but read part i have not add in email template.
  • how can i combined and send the both red part and yellow lines as one mail ?
  • how can i use the email tempate in the code?
Can you help how can i use this to complete my requriment.User-added image
String htmlBody = 'Dear '+callInstance.OCE__Account__r.Name +',';
                htmlBody += '<br/><br/>';
                htmlBody += 'Thank you for your Actemra (tocilizumab) SC sample request on '+ callInstance.OCE__SignatureDate__c.format('dd-MM-yyyy',mapUserTimeZone.get(callInstance.ownerID));

 
Nitin ChandwaniNitin Chandwani
@Harish, 

1. If you have a parent child relation then you can use Visualforce email template and can add relateted records(child) and parent fields upto 5 levels, you can also use visualforce component on visualforce email template if needed. 
http://sfdcsrini.blogspot.com/2014/07/visualforce-email-template-with-custom.html
2. If you don't want to go with #1 approach then you can use, rendered stored email template( https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_email_outbound_messaging.htm). What you can do is to create email template, then add some placeholders in email template {placeholder1} once done, use renderStoredEmailTemplate to generate parsed email content and get body and replace the placeholder with specifi values.
EmailTemplate tem=[Select id,name from EmailTemplate where name = '<Template Name>' limit 1];
if( tem != NULL ){
Messaging.SingleEmailMessage Email = new Messaging.renderStoredEmailTemplate( tem.Id, whoId, WhatId );
String emailBody  = Email.getHtmlBody(tem.id);
//TODO: replace placeholders using String class methods
Messaging.SingleEmailMessage newMailObj = new Messaging.SingleEmailMessage();
newMailObj.HtmlBody = emailBody ;
//TODO: populate other email parameters and send email
}

Thanks