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
Damon HedgspethDamon Hedgspeth 

How to show Approval Steps in order on VisualForce Email Template

I've created an email template that will be sent to Accounts payable once an Invoice (custom object) has been approved.  In the email, I would like to show the full approval history for that invoice. including when it was submitted, and any rejections and subsequent approval.

My problem is, I can not seem to pull the dates/times in any order that makes since.    See code - notice that the Dates and Status areUser-added image out of order.
<messaging:emailTemplate subject="A new IS Invoice has been approved." recipientType="User" relatedToType="Bill_Item__c">
 <messaging:htmlEmailBody >

    <html>
    <head>
  
    <script>
         var people, asc1 = 1,
            asc2 = 1,
            asc3 = 1;
        window.onload = function () {
            people = document.getElementById("people");
           var peps = people;
peps.reverse();
        }

        function sortTable(){
    var tbl = document.getElementById("caltbl").tBodies[0];
    var store = [];
    for(var i=0, len=tbl.rows.length; i<len; i++){
        var row = tbl.rows[i];
        var sortnr = parseFloat(row.cells[0].textContent || row.cells[0].innerText);
        if(!isNaN(sortnr)) store.push([sortnr, row]);
    }
    store.sort(function(x,y){
        return x[0] - y[0];
    });
    for(var i=0, len=store.length; i<len; i++){
        tbl.appendChild(store[i][1]);
    }
    store = null;
}
        
        </script>

</head>
      <body onload="sortTable()">
        

        <STYLE type="text/css">
        
        
   
        #DIV_Top{font-size: 24px; font-weight: Bold;  padding: 0 0 0 10px; margin: 0; background-color: #add0c8; color: #ffffff;}
#Top_Text {font-size: 18px; font-face: arial; color:#ea896a}
#Top_Text0 {font-size: 18px; font-face: arial; color:#000000}
#Print{border: solid #CCCCCC; border-width: 1;background-color: #add0c8; width: 100px; }
#Print a:link { color: #ffffff;font-size: 14px; font-weight: bold;}
#Print a:visited { color: #ffffff;font-size: 14px;font-weight: bold; }
#Print a:hover { color: #ffffff; font-size: 14px;font-weight: bold;}
#Print a:active { color: #ffffff; font-size: 14px;font-weight: bold;}


.myButton {
    -moz-box-shadow:inset 0px 1px 3px 0px #91b8b3;
    -webkit-box-shadow:inset 0px 1px 3px 0px #91b8b3;
    box-shadow:inset 0px 1px 3px 0px #91b8b3;
    background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #768d87), color-stop(1, #6c7c7c));
    background:-moz-linear-gradient(top, #768d87 5%, #6c7c7c 100%);
    background:-webkit-linear-gradient(top, #768d87 5%, #6c7c7c 100%);
    background:-o-linear-gradient(top, #768d87 5%, #6c7c7c 100%);
    background:-ms-linear-gradient(top, #768d87 5%, #6c7c7c 100%);
    background:linear-gradient(to bottom, #768d87 5%, #6c7c7c 100%);
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#768d87', endColorstr='#6c7c7c',GradientType=0);
    background-color:#768d87;
    -moz-border-radius:5px;
    -webkit-border-radius:5px;
    border-radius:5px;
    border:1px solid #566963;
    display:inline-block;
    cursor:pointer;
    color:#ffffff !important;
    font-family:Arial;
    font-size:15px;
    font-weight:bold;
    padding:11px 23px;
    text-decoration:none;
    text-shadow:0px -1px 0px #2b665e;
   
}
.myButton:hover {
    background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #6c7c7c), color-stop(1, #768d87));
    background:-moz-linear-gradient(top, #6c7c7c 5%, #768d87 100%);
    background:-webkit-linear-gradient(top, #6c7c7c 5%, #768d87 100%);
    background:-o-linear-gradient(top, #6c7c7c 5%, #768d87 100%);
    background:-ms-linear-gradient(top, #6c7c7c 5%, #768d87 100%);
    background:linear-gradient(to bottom, #6c7c7c 5%, #768d87 100%);
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#6c7c7c', endColorstr='#768d87',GradientType=0);
    background-color:#6c7c7c;
     color:#ffffff !important;
}
.myButton:active {
    position:relative;
    top:1px;
      color:#ffffff !important;
}
.myButton:a {
    position:relative;
    top:1px;
 color:#ffffff !important;
}
.myButton:visited {
    position:relative;
    top:1px;
      color:#ffffff !important;
}
           TH.blue{font-size: 14px; font-face: arial;color: #ffffff; background: #34b0cd; 
               border-width: 2;  text-align: left} 
          TH.green {font-size: 14px; font-face: arial;color: #ffffff; background: #add0c8; 
               border-width: 2;  text-align: left} 
           TH.orange {font-size: 14px; font-face: arial;color: #ffffff; background: #ea896a; 
               border-width: 2;  text-align: left} 
               
          TD  {font-size: 14px; font-face: verdana;border: solid #Cdcdcd; border-width: 1;  } 
          TABLE {border: solid #CCCCCC; border-width: 0; }
          
TR.blue:nth-child(even) {color: #12547d}

TR.green  {color: #529384}
TR.orange  {color: #ea896a}
          TR {border: solid #CCCCCC; border-width: 1; padding: 0px;}
          
        </STYLE>
        <apex:variable var="count" value="{!0}" /> 
            
<apex:repeat var="cc" value="{!relatedTo.Bill_Payments__r}">

     <apex:outputPanel layout="none" rendered="{!cc.Allotment_User_Id__c != '-Select-'}">
   <apex:variable var="count" value="{!count+1}"/>
     </apex:outputPanel>
</apex:repeat>
        <font face="arial" size="3" color="#534e4e">
           <div id="Logo">
           </div>
           <div id="DIV_Top">
            <p>&#10004; &nbsp; Invoice Approved</p>
           </div>
           <div id="Top_Text0">
           <apex:outputText value="{!IF(count=0  ,"","**New Process**")}"/>
           </div>
            <p />
            
 
  
   
    
   
            
            The invoice related to {!relatedTo.Vendor_Account__r.Request_Type__c} <a href="  {!relatedTo.Vendor_Account__r.PO_Link__c}">{!relatedTo.Vendor_Account__r.Purchase_Order__c}</a> has been approved. <br />
            Please print this page and the associated Invoice for your records. <a href="{!relatedTo.Box_Share_Link__c}" class="myButton">Print Invoice</a>
           <p />
              <div id="Top_Text">
        Approval History
        </div>
          
<table border="0" cellspacing="0" cellpadding="5">
    <tr border-bottom="1"> 
               <th class="green">Approver</th>
               <th class="green">Date Approved</th>
               <th class="green">Status</th>
               <th class="green">Comments</th>
               </tr>
    <apex:repeat var="cx" value="{!relatedTo.ProcessSteps}">
        <tr class="green" >
           
             <td >{!cx.Actor.name}</td>
              <td><apex:outputText value="{0,date,MM'/'dd'/'yyyy}">
    <apex:param value="{!cx.ProcessInstance.CompletedDate}" /> 
</apex:outputText></td>
             
            <td>{!cx.StepStatus}</td>
           
            
           
         
            
          <td>{!cx.Comments}</td>
        </tr>
         
    </apex:repeat>                 
</table>
     <p />


     <p />
        <hr class="Top_Text"/>
             <div id="Top_Text">
             Invoice Information
             </div>       
          <table border="0" cellspacing="0" cellpadding="5">
            <tr > 
               <th class="blue">Service Name</th>
               <th class="blue">Account Number:</th>
               <th class="blue">Invoice Number:</th>
               <th class="blue">Invoice Date:</th>
               <th class="blue">Billing Cyle</th>
               <th class="blue">Month Processed:</th>
              <th class="blue">Total:</th>
             
            </tr>
                <tr class="blue">
                <td>
                <strong>{!relatedTo.Vendor_Account__r.Name}</strong>
                </td>
                <td>
                {!relatedTo.Account_Number__c}
                </td>
                 <td>
                {!relatedTo.Invoice_Number__c}
                </td>
                 <td>
               <apex:outputText value="{0,date,MM'/'dd'/'yyyy}">
    <apex:param value="{!relatedTo.Invoice_Date__c}" /> 
</apex:outputText>
                </td>
                 <td>
                <apex:outputText value="{0,date,MM'/'dd'/'yyyy}">
    <apex:param value="{!relatedTo.Billing_Cycle_Start__c}" /> 
</apex:outputText>  -  <apex:outputText value="{0,date,MM'/'dd'/'yyyy}">
    <apex:param value="{!relatedTo.Billing_Cycle_End__c}" /> 
</apex:outputText>
                </td>
                 <td>
                {!relatedTo.Month_Processed__c}
                </td>
                 <td>
                <strong>${!relatedTo.Total_Allotted_Amount__c}</strong>
                </td>
              
                   </tr>       
          </table>
          <p />
      
      
 <div id="Top_Text">
        Applied Cost Codes
                </div>
<table border="0" cellspacing="0" cellpadding="5">
   <tr border-bottom="1"> 
               <th class="orange">Cost Code</th>
               <th class="orange">User Id</th>
               <th class="orange">Amount Charged</th>
                              </tr> 
                         
<apex:repeat var="cc" value="{!relatedTo.Bill_Payments__r}">
    <tr class="grey"><td>
        {!IF(cc.Bill_Cost_Code__c = "[]","",SUBSTITUTE(SUBSTITUTE(cc.Bill_Cost_Code__c,"[", ""),"]","" ))}
        
       </td>
       <td>{!IF(cc.Allotment_User_Id__c = "-Select-","",  cc.Allotment_User_Id__c )}
     
       </td>
       <td style="text-align:right">${!cc.Allotment_Amount__c}</td></tr>
</apex:repeat>
     </table>


<p />
</font>

   </body>
    </html>
  </messaging:htmlEmailBody> 
<messaging:plainTextEmailBody >

The invoice related to PO# {!relatedTo.Vendor_Account__r.Purchase_Order__c} has been approved.

Please print this page and the associated Invoice for your records located here >> {!relatedTo.Box_Share_Link__c}

Invoice Information:

Service Name: {!relatedTo.Vendor_Account__r.Name}
Account Number: {!relatedTo.Account_Number__c}
Invoice Number:   {!relatedTo.Invoice_Number__c}
Invoice Date: <apex:outputText value="{0,date,MM'/'dd'/'yyyy}"><apex:param value="{!relatedTo.Invoice_Date__c}" /> </apex:outputText>
Billing Cyle:  <apex:outputText value="{0,date,MM'/'dd'/'yyyy}"><apex:param value="{!relatedTo.Billing_Cycle_Start__c}" /></apex:outputText>  -  <apex:outputText value="{0,date,MM'/'dd'/'yyyy}"><apex:param value="{!relatedTo.Billing_Cycle_End__c}" /> </apex:outputText>
Month Processed: {!relatedTo.Month_Processed__c}
Total: {!relatedTo.Total_Allotted_Amount__c}
             
Approval History:
 <apex:repeat var="cx" value="{!relatedTo.ProcessSteps}">        
{!cx.Actor.name}
<apex:outputText value="{0,date,MM'/'dd'/'yyyy}">
<apex:param value="{!cx.ProcessInstance.CompletedDate}" /> 
</apex:outputText>         
{!cx.StepStatus}
{!cx.Comments}
</apex:repeat>          
           
//history = SELECT Id, (SELECT Actor.name, CompletedDate, StepStatus)
FROM ProcessInstance           
           
Applied Cost Codes / User ID
                        
<apex:repeat var="cc" value="{!relatedTo.Bill_Payments__r}">
{!IF(cc.Bill_Cost_Code__c = "[]","",cc.Bill_Cost_Code__c)}{!IF(cc.Allotment_User_Id__c = "-Select-","",cc.Allotment_User_Id__c)}
</apex:repeat>             

</messaging:plainTextEmailBody>
</messaging:emailTemplate>

 
NagaNaga (Salesforce Developers) 
Hi Damon,

Please see the sample code below

User-added image
Best Regards
Naga Kiran
Damon HedgspethDamon Hedgspeth
Thanks for you reply Naga. But that is the same sample code that I built my code from.  My issue is that it doesnt pull the steps in order.  Could it be that my Approval Process is not setup correctly?

User-added image
Damon HedgspethDamon Hedgspeth
If anyone can help with this, i would greatly appreciate it.
Chetan ChavanChetan Chavan
Hi Damon 
What error you are getting?
Damon HedgspethDamon Hedgspeth
No error. The results seem to be out of order. Notice in my example above "Started - Approved - Approved - Started".

I see how the first two could be accurate but for the last two it shows that I approved it before I started it.
Karel Lipus 13Karel Lipus 13
ressurrection, the same issue here