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
Anupama@28Anupama@28 

VF email template for casemilestone - how to pass CaseMilestoneId

We have a requirement to send email notification before 'X' min the milestone gets violated.
How to get the milestoneId or milestone name, and timeRemaining of that particular Casemilestone in VF email template that is going to violate.

e.g. A case has 3 milestones 'First response', 'Return to service' and 'Resolution'. I need to build a common email template, if 'First response' is going to violate in 'X' min then our email body should have the name and TimeRemaining of 'first response' milestone and same for other 2 respectively.

here is my sample code I have tried with

VF email template
---------------------------------------------------------------------
<messaging:emailTemplate subject="SLA violation alert : Case# {!relatedTo.caseNumber}" recipientType="User" relatedToType="Case">
    <messaging:htmlEmailBody >
        <html>
            <body>

               <!--------- HOW TO GET THE BELOW VALUE ? ------------------------>
                mileston Name : {!relatedTo.CaseMileStone.Name}          
                Time remaining : {!relatedTo.CaseMileStone.timeRemaining}  
                <!------------------------------------------------------------------------------------->
                                                                                   
            </body>
        </html>
    </messaging:htmlEmailBody>
</messaging:emailTemplate>


VF custom component
--------------------------------------------------------------------


 
NagendraNagendra (Salesforce Developers) 
Hi Anupama,

May I request you please post the complete code snippet with the approach you have tried so far so that we can look into it and help you accordingly.

Thanks,
Nagendra
 
Anupama@28Anupama@28
Nagendra, thanks for the quick response,

Tried with the below code and its working as expected but I just want to know is there any direct method to get the casemilestoneId that is going to violate. so that in controller I can directly have below SOQL
Select MilestoneType.Name,TimeRemainingInMins from caseMileStone Where Id = <VIOLATING_CASEMILESTONEID>

The email alert action is firing at the exact time what I have configured for each different milestones, which means there should be a way to fetch the details of the milestone whose time dependent warning action caused the email to fire.

VF template
-----------------------------------
<messaging:emailTemplate subject="SLA violation alert : Case# {!relatedTo.caseNumber}" recipientType="User" relatedToType="Case">
    <messaging:htmlEmailBody >
        <html>
            <body>
                <c:milestonewarningemailcontent caseId="{!relatedTo.Id}" />                                                                                                   
            </body>
        </html>
    </messaging:htmlEmailBody>
</messaging:emailTemplate>

VF  Component
------------------------------------
<apex:component controller="MilestoneWarningEmailContent" access="Global">
     <apex:attribute name="caseId" type="ID" description="caseId" assignTo="{!cId}"/>
     <a href="https://cs30.salesforce.com/{!cId}"> Case# {!caseNumber} </a> milestone {!MileStoneName} need to be completed in             {!mileStoneTimeRemaining} minutes for SLA compliance.
<br /> <br />
     Account Name : {!caseDetails[0].Account.Name} <br />
     Assigned To : {!caseDetails[0].Owner.Name} <br />      
     Subject : {!caseDetails[0].Subject} <br />
     Initial Severity : {!caseDetails[0].Initial_Severity__c} <br />
     Current Severity : {!caseDetails[0].Severity__c} <br />
     Problem Area : {!caseDetails[0].Problem_Area__c} <br />
     Category :  {!caseDetails[0].Category__c} <br />
</apex:component>

Apex controller
------------------------------
public class MilestoneWarningEmailContent 
{
    public Id cId {get; set;}
    public String mileStoneName {get; set;}
    Public String mileStoneTimeRemaining {get; set;}
    public List<Case> caseDetails {get; set;}     
    
    public String getCaseNumber()
    {
        caseDetails = [Select caseNumber, Account.Name, Owner.Name, subject, Initial_Severity__c, Severity__c, Problem_Area__c, Category__c from case Where Id = :cId]; 
        String csNumber = caseDetails[0].CaseNumber;               
        

       //***** If I have caseMilestoneId, no need to have the below for loop and filter criteria IsViolated = false AND IsCompleted = false  *****//

        List<CaseMileStone> lstMilestone = [Select MilestoneType.Name, TimeRemainingInMins from caseMileStone WHERE caseId =:cId AND IsViolated = false AND IsCompleted = false];
        
        for(caseMilestone cm : lstMilestone)
        {
            if(Integer.valueof(cm.TimeRemainingInMins.substringBefore(':')) <= 10)
            {
                mileStoneTimeRemaining = cm.TimeRemainingInMins;
                mileStoneName = cm.MilestoneType.Name;
            }
        }       
 
        return csNumber;
    }    
}