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
LuvaraLuvara 

Sort order in Visualforce template

I'm merging in product line items into a visualforce template and I'd like the products to sort the same way they are in the Opportunity. Does anyone know how to do this? Here is my code..

Thanks, Chris
Code:
<messaging:emailTemplate subject="Product Quote" recipientType="Contact" relatedToType="Opportunity">
<messaging:htmlEmailBody >       
<html>
        <body>
         <STYLE type="text/css">
               Body {font-size: 11px; font-face: verdana } 
               TH {font-size: 11px; font-face: arial;background: #CCCCCC; border-width: 1;  text-align: center } 
               TD  {font-size: 11px; font-face: verdana } 
               TABLE {border: solid #CCCCCC; border-width: 1}
               TR {border: solid #CCCCCC; border-width: 1}
         </STYLE>
             <font face="arial" size="2">
 <p>Dear {!recipient.name},</p>
         <table border="0" >
                 <tr > 
                     <th>Product Name</th><th>Quantity</th><th>Total Price</th><th>Monthly Fee</th>
                  </tr>
  <apex:repeat var="oli" value="{!relatedTo.OpportunityLineItems}">
       <tr>
           <td>{!oli.PricebookEntry.Product2.Name}</td>
           <td>{!oli.Quantity}</td>
           <td>${!oli.TotalPrice}</td>
           <td>${!oli.Extended_Monthly_Fee__c}</td>
       </tr>
 </apex:repeat> 


    </table>
    <p>
<apex:repeat var="opp" value="{!relatedTo}">
<p>
Total Subscription fees: ${!opp.X1St_Yr_ACV_Subscript__c}<br>
Total Services fees: ${!opp.Professional_Services__c}<br>
</p>
 </apex:repeat>     
    
    <p>
        Please contact me with any questions,
<apex:repeat var="o" value="{!relatedTo.Owner}">
<p>
{!o.Name}<br>
{!o.CompanyName}<br>
{!o.Phone}<br>
<a href="mailto:{!o.Email}">{!o.Email}</a><br>
</p>
 </apex:repeat> 
       <p />
 </font>
        </body>
    </html>


</messaging:htmlEmailBody>       
</messaging:emailTemplate>

 

Best Answer chosen by Admin (Salesforce Developers) 
dchasmandchasman
We should be able to leverage a custom component and a custom component controller to get the sorting you're looking for. Here is a working example (you'll need to supply your own sorting logic of course):

Code /apexcomponent/sortedlineitems:
<apex:component access="global" controller="SortedLineItemsController">
    <apex:attribute name="value" type="Opportunity" assignTo="{!opportunity}" description="TODO: Describe me"/>
    
    <apex:repeat var="li" value="{!sorted}">
        <tr>
            <td>{!li.PricebookEntry.Product2.Name}</td>
            <td>{!li.Quantity}</td>
            <td>${!li.TotalPrice}</td>
        </tr>
    </apex:repeat>
    
    <!-- Needed to work around limitation that the standard controller cannot "see" 
         the linkage between the value attribute and the opportunity property -->
    <apex:variable var="oli" value="{!value.OpportunityLineItems}" rendered="false">
        {!oli.PricebookEntry.Product2.Name}
        {!oli.Quantity}
        {!oli.TotalPrice}
    </apex:variable> 
</apex:component>

public class SortedLineItemsController {
public Opportunity opportunity { get; set; }

public OpportunityLineItem[] getSorted() {
if (opportunity == null || opportunity.opportunityLineItems== null) {
return null;
}

// TODO: Add your sorting logic here (demo just reverses the list)
OpportunityLineItem[] result = new OpportunityLineItem[1];
for (OpportunityLineItem item : opportunity.opportunityLineItems) {
result.add(0, item);
}

return result;
}
}

You can use this component in your email template like this:

Code:
<table border="0" >
<tr>
<th>Product Name</th><th>Quantity</th><th>Total Price</th><th>Monthly Fee</th>
</tr>
<c:sortedlineitems value="{!relatedTo}"/>
</table>



Message Edited by dchasman on 12-27-2008 12:14 PM

All Answers

CTU007CTU007
I also want to know, thanks.
dchasmandchasman
We should be able to leverage a custom component and a custom component controller to get the sorting you're looking for. Here is a working example (you'll need to supply your own sorting logic of course):

Code /apexcomponent/sortedlineitems:
<apex:component access="global" controller="SortedLineItemsController">
    <apex:attribute name="value" type="Opportunity" assignTo="{!opportunity}" description="TODO: Describe me"/>
    
    <apex:repeat var="li" value="{!sorted}">
        <tr>
            <td>{!li.PricebookEntry.Product2.Name}</td>
            <td>{!li.Quantity}</td>
            <td>${!li.TotalPrice}</td>
        </tr>
    </apex:repeat>
    
    <!-- Needed to work around limitation that the standard controller cannot "see" 
         the linkage between the value attribute and the opportunity property -->
    <apex:variable var="oli" value="{!value.OpportunityLineItems}" rendered="false">
        {!oli.PricebookEntry.Product2.Name}
        {!oli.Quantity}
        {!oli.TotalPrice}
    </apex:variable> 
</apex:component>

public class SortedLineItemsController {
public Opportunity opportunity { get; set; }

public OpportunityLineItem[] getSorted() {
if (opportunity == null || opportunity.opportunityLineItems== null) {
return null;
}

// TODO: Add your sorting logic here (demo just reverses the list)
OpportunityLineItem[] result = new OpportunityLineItem[1];
for (OpportunityLineItem item : opportunity.opportunityLineItems) {
result.add(0, item);
}

return result;
}
}

You can use this component in your email template like this:

Code:
<table border="0" >
<tr>
<th>Product Name</th><th>Quantity</th><th>Total Price</th><th>Monthly Fee</th>
</tr>
<c:sortedlineitems value="{!relatedTo}"/>
</table>



Message Edited by dchasman on 12-27-2008 12:14 PM
This was selected as the best answer
SimplySfdcSimplySfdc

Hi,

 

Is there any easier way to implement a default sorting in apex:repeat without apex class?  

Because it so complex if need to create apex class, create test method, create managed packaged in developer / sandbox and install it to enterprise edition JUST for a default sort.

 

sq 

imcclellanimcclellan
I totally agree, there should/has to be an easier way to do this! Force.com, please upgrade!  
PHKOGPHKOG

I'm using Simple Quote v1.0 and turns out, not so simple.

 

I am using visualforce to create a PDF of a quote from the Products in the Opportunity. But when I create the PDF, it doesn't sort the way that I have it in the opportunity. How can I fix this? I didn't completely understand the previous code for an email. Help please? Thanks! 

JMPlayer22JMPlayer22
I see your line "// TODO: Add your sorting logic here (demo just reverses the list)" ... can you clarify what you mean by "demo"?  Does that mean the code below your commented out line is the demo?  If so, I can't tell where the sorting logic is in there...and if not, could you please provide an example of sorting logic?
Glenn at MvistaGlenn at Mvista
Hi, did anyone respond with details on how to set up the sorting?  I have been poking around and cannot find anything on how to do it.
Glenn at MvistaGlenn at Mvista
How does one actually do the sorting?  Can you give some examples?
TBird92TBird92

I'm using Simple Quote v1.0 and turns out, not so simple.

 

I am using visualforce to create a PDF of a quote from the Products in the Opportunity. But when I create the PDF, it doesn't sort the way that I have it in the opportunity. How can I fix this? I didn't completely understand the previous code for an email. Help please? Thanks! 

Admin1112Admin1112

Do we have any solution for this without creating controller, can we do something in the email template itself.

Abebuckingham23Abebuckingham23
Still no answer?
Alok Kumar 62Alok Kumar 62
the below code snippet works and renders rows in sorted order. I have custom field - num_Quotation_Number__c  which maintains the serial number in the list view. I am using this field in the rendered attribute. 
 <apex:variable var="s_no" value="{!1}"/>
           <apex:repeat var="quoteLineItem" value="{!relatedTo.Quote_Line_Items__r}">
               <apex:repeat var="cx" value="{!relatedTo.Quote_Line_Items__r}">
                   <apex:outputPanel rendered="{!cx.num_Quotation_Number__c == s_no}" layout="none">
                       <tr><td>{!cx.num_Quotation_Number__c} </td>
                           <td>{!cx.pkl_Publisher__c}</td>
                           <td>{!cx.Name}</td>
                           .....
                        </tr>
                   </apex:outputPanel>           
            </apex:repeat>
        <apex:variable var="s_no" value="{!s_no+1}"/>
        </apex:repeat>