I have an apex class and vf page that is based on the PricebookEntry object because I want to be able to have a list view of all pricebooks at the top of the vf page and each time a different pricebook is selected, the products in the pageblock area below rerender for the proudcts that are only associated with that pricebook selected. Right now my code shows all of the pricebooks but whenever you click on the pricebook the pageblock area shows all Pricebook entries whether they are in that pricebook or not.

I need a way to figure out how to dynamically SOQL the pricebook id into the code, but I can't seem to figure that out.

Class:

public with sharing class CustomPBListController {

public String getPageNumber() {
    return null;
}

Public PricebookEntry pbe {get;set;}
Public Pricebook2 pb2 {get;set;}
public ApexPages.StandardSetController ssc {get; private set;}
public List<SelectOption> sizeOptions {get; set;}
public List<Pricebook2> pbId {get;set;}
public List<PricebookEntry> standard {get;set;}
public List<PricebookEntry> pb3 {get;set;}
public List<PricebookEntry> pb4 {get;set;}
public String chosenSize {get; set;}
public Integer size {get;set;}
public Integer noOfRecords {get;set;}

public CustomPBListController() {
    ssc = new ApexPages.StandardSetController([select Id, Product2.Name, Productcode, Pricebook2.Name, Pricebook2.Id, UnitPrice, Minimum_Price__c from PricebookEntry Where Pricebook2.Name = 'Standard Price Book' Order By Product2.Name ASC limit 500]);
    pb2 = [select id, name from Pricebook2 limit 1];
    standard = [select Id, Product2.Name, Productcode, Pricebook2.Name, Pricebook2.Id, UnitPrice, Minimum_Price__c from PricebookEntry Where Pricebook2.Id =:pb2.Id Order By Product2.Name ASC];
    pb3 = [select Id, Product2.Name, Productcode, Pricebook2.Name, Pricebook2.Id, UnitPrice, Minimum_Price__c from PricebookEntry Where Pricebook2.Name = 'Test Pricebook' Order By Product2.Name ASC];
    pb4 = [select Id, Product2.Name, Productcode, Pricebook2.Name, Pricebook2.Id, UnitPrice, Minimum_Price__c from PricebookEntry Where Pricebook2.Name = 'Novation - Tier 1' Order By Product2.Name ASC];
    sizeOptions = new List<SelectOption> {
    new SelectOption('Standard Price Book', 'Standard Price Book'),
    new SelectOption('Test Pricebook', 'Test Pricebook'),
    new SelectOption('Novation - Tier 1', 'Novation - Tier 1'),
    new SelectOption('Acme Inc, Price Book', 'Acme Inc, Price Book'),
    new SelectOption('MedAssets', 'MedAssets')

};
chosenSize = 'Standard Price Book';

}
public PageReference ApplyFilter() {
    String query = 'select Id, Product2.Name, ProductCode, Pricebook2.Name, Pricebook2.Id, UnitPrice, Minimum_Price__c from PricebookEntry where ';
    if(chosenSize == 'Test Pricebook') {
        query += ' Pricebook2.Name Like \'Test Pricebook\' ';
        }
    else if(chosenSize == 'Novation - Tier 1') {
        query += ' Pricebook2.Name Like \'Novation - Tier 1\' ';
        }
    else if(chosenSize == 'Acme Inc, Price Book') {
        query += ' Pricebook2.Name Like \'Acme Inc, Price Book\' ';
        }
     else if(chosenSize == 'MedAssets') {
        query += ' Pricebook2.Name Like \'MedAssets\' ';
        }
     else if(chosenSize == 'Standard Price Book') {
        query += ' Pricebook2.Name Like \'Standard Price Book\' ';
        }      
    query += ' Order By Product2.Name Asc limit 500 ';
ssc = new ApexPages.StandardSetController(Database.Query(query));
return null;
}

public List<PricebookEntry> GetPBE() {
     return (List<PricebookEntry>)ssc.GetRecords();
}


public pageReference refresh() {
    ssc = null;
    getPBE();
    ssc.setPageNumber(1);
    return null;
 } 

 public PageReference export() {
     return page.PbList2;
     }
 public String xlsHeader {
    get {
        String strHeader = '';
        strHeader += '<?xml version="1.0"?>';
        strHeader += '<?mso-application progid="Excel.Sheet"?>';
        return strHeader;
    }
}

     public PageReference exportall() {
     return page.ExportPriceBookList;
     }  

  }

Vf Page:

<apex:page controller="CustomPBListController" tabStyle="Pricebook2"  readOnly="true" >
 <apex:form >
     <apex:stylesheet value="{!URLFOR($Resource.jQueryDataTablesZip, 'jQueryDataTablesZip/css/jquery.dataTables.css')}"/>
 <style type="text/css">
 .sorting {
background: #f2f3f3 url('{! URLFOR($Resource.jQueryDataTablesZip, 'jQueryDataTablesZip/images/sort_both.png') }') no-repeat center right !important;
padding-right: 20px !important;
 }
 .sorting_asc {
background: #f2f3f3 url('{! URLFOR($Resource.jQueryDataTablesZip, 'jQueryDataTablesZip/images/sort_asc.png') }') no-repeat center right !important;
padding-right: 20px !important;
 }
 .sorting_desc {
background: #f2f3f3 url('{! URLFOR($Resource.jQueryDataTablesZip, 'jQueryDataTablesZip/images/sort_desc.png') }') no-repeat center right !important;
padding-right: 20px !important;
}
.sorting_asc_disabled {
background: #f2f3f3 url('{! URLFOR($Resource.jQueryDataTablesZip, 'jQueryDataTablesZip/images/sort_asc_disabled.png') }') no-repeat center right !important;
padding-right: 20px !important;
 }
 .sorting_desc_disabled {
background: #f2f3f3 url('{! URLFOR($Resource.jQueryDataTablesZip, 'jQueryDataTablesZip/images/sort_desc_disabled.png') }') no-repeat center right !important;
padding-right: 20px !important;
 }
 table.dataTable tr.odd { background-color: white; }
 table.dataTable tr.even { background-color: white; }
 table.dataTable tr.odd td.sorting_1 { background-color: white; }
 table.dataTable tr.odd td.sorting_2 { background-color: white; }
 table.dataTable tr.odd td.sorting_3 { background-color: white; }
 table.dataTable tr.even td.sorting_1 { background-color: white; }
 table.dataTable tr.even td.sorting_2 { background-color: white; }
 table.dataTable tr.even td.sorting_3 { background-color: white; }
 .dataTables_length, .dataTables_filter, .dataTables_info,   .dataTables_paginate {
padding: 3px;
 }
 </style>
     <apex:pageBlock >
        <apex:commandButton action="{!export}" value="Export to Excel" />
        <apex:commandButton action="{!exportall}" value="Export All Pricebooks" />
         <apex:pageBlockSection >
             <apex:selectList value="{!chosenSize}" size="1">
                 <apex:actionSupport action="{!ApplyFilter}" event="onchange"/>
                 <b>Pricebooks: </b>
                 <apex:selectOptions value="{!sizeOptions}"/>
             </apex:selectList>
        </apex:pageBlockSection>
         <apex:pageBlockTable value="{!ssc.Records}" var="a" styleClass="dataTable">
             <apex:column value="{!a['Product2.Name']}"/>
             <apex:column value="{!a['ProductCode']}"/>
             <apex:column value="{!a['UnitPrice']}"/>
             <apex:column value="{!a['Minimum_Price__c']}"/>
             <apex:column value="{!a['Pricebook2.Name']}"/>
     </apex:pageBlockTable>


     </apex:pageBlock>
 <script type="text/javascript" language="javascript" src="{!URLFOR($Resource.jQueryDataTablesZip, 'jQueryDataTablesZip/js/jquery.js')}">   </script>
 <script type="text/javascript" language="javascript" src="{!URLFOR($Resource.jQueryDataTablesZip, 'jQueryDataTablesZip/js/jquery.dataTables.js')}"></script>
  <script type="text/javascript" language="javascript">
 var j$ = jQuery.noConflict();
 j$('table.dataTable').dataTable({
 sPaginationType: "full_numbers"
 });

Any help is much appreciated as I this code has been making me crazy for about a week now!

This may or may not help - When using a StandardSetController extension class, I found I needed my own implementations to support user-selected filter changes. To wit, I had these properties in the controller:

public String               filterId {
    get {
         if (this.filterId == null)
            this.filterId = this.ssc.getFilterId();
         return this.filterId;
    }
    set {
        if (this.filterId != value) {
            // queryLocator limit 1 is fine, getRecords() + filter will get what you need 
            this.ssc = new ApexPages.StandardSetController(Database.getQueryLocator(somequeryExpression));  
            this.ssc.setPageNumber(1);
            this.ssc.setFilterId(value);    // change the ssc to a different filter
            this.productList = null; // reset for getter                

        }
        this.filterId = value;  // remember the filterId
    }

}

public List<SelectOption>   listViewOptions {
    get {return this.ssc.getListViewOptions();}
    private set;
}

I also decoupled the recordSetVar on the apex:page from the getter used to return the the list of records for the current filterId as in:

<apex:page standardController="PricebookEntry" recordSetVar="pListNameDoesntMatter"
   extensions="DynamicCustomizableListHandler">
....
<apex:pageBlockTable value="{!productList}" var="prod" id="productlist">

where productList has a controller getter that looks like this:

public List<Product2>   productList         {               
    get {
        if (productList == null)
            productList = (List<Product2>)this.ssc.getRecords();
        return this.productList;    
    }
    set;
}

This is meant to be a guide, not a rewrite of your class and page. One resource that was helpful was this doc - especially Chapter 4

UPDATE - How to get a list of Pricebooks and their PBE

Map<ID,Pricebook2> pbIdToPriceBookWithPbeMap = new map<ID,Pricebook2> (
    [select id, name, 
      (select id, currencyisoCode, listprice, productCode
        from pricebookEntries where isActive = true)
      from Pricebook2 where isStandard = false and isActive = true]);

from this map you can build other maps such as:

map<String,Pricebook2> pbNameToPriceBookWithPbeMap;

where you can then construct a selectlist of Pricebook name | id pairs.

  • I took your suggestions and changed my code above, but the problem that I don't know how to do is to make it dynamic so I don't have to add all of our pricebooks manually. – NewbieDeveloper27 Apr 9 '15 at 19:46
  • @NewbieDeveloper27 - it is kind of hard to know where you are stuck if you've changed the code -- you might want to edit the OP and use the current code plus screen shots of what you are trying to do versus what is happening – cropredy Apr 9 '15 at 21:14
  • In the ApplyFilter section of the apex class I have to reference each pricebook by adding new lines of code with the pricebook name in order for them to show up in the drop down list. What I want to be able to do is not have to list out every pricebook and have the code dynamically list the pricebook name in the drop down menu and then populate with the appropriate pricebook entries – NewbieDeveloper27 Apr 9 '15 at 22:00
  • To get list of Pricebook2, select id, name from Pricebook2 where isStandard = false and isActive = true – cropredy Apr 9 '15 at 22:25
  • Yes I have tried creating the soql query to get the pricebooks but when I try and set it to Pricebook2.Name =:pricebook.id .......that doesn't work. The String query needs to have the soql statement from the pricebook entry since I need the product codes and prices. Does this make sense? – NewbieDeveloper27 Apr 10 '15 at 15:27

I want to thank everyone who took the time to comment on this question, but I eventually figured out with a little help from a code consultation at Salesforce that the best way to do this was to create a custom setting for the Pricebooks and their entries and then reference that custom setting in my controller. Worked like a charm!

  • SF told you to make a custom setting to hold pricebook data that should be queried???? – Eric Sep 26 '16 at 12:29

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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