Building a wizard to mirror the functionality of the opportunity products wizard built in (minus an otherwise unmovable field). The first page, where the user can select from a list of products works fine, the controller (as far as I can tell) works fine. The unit tests all passed. But the second page, which is supposed to show a repeated section of fields displays nothing, even when the list containing all the items is populated. Does anyone know what is wrong?
Controller:
public class OpportunityProductsController {
// PROPERTIES
public List<SelectableListProduct> wrappedList { get; set; }
public List<OpportunityLineItem> itemsToAdd { get; set; }
public Opportunity controllingOpp { get; set; }
// CONSTRUCTOR
public OpportunityProductsController() {
//Init Id
try {
controllingOpp = [SELECT Id FROM Opportunity WHERE Id=:ApexPages.currentPage().getParameters().get('oid') LIMIT 1];
} catch (System.QueryException e) {
controllingOpp = new Opportunity();
}
//Initialise lists.
wrappedList = new List<SelectableListProduct>();
itemsToAdd = new List<OpportunityLineItem>();
//Get a list of pricebook entries.
List<PricebookEntry> unwrappedEntries = new List<PricebookEntry>();
unwrappedEntries = [SELECT Id,
Product2.Name,
Product2.ProductCode,
Product2.Standard_Install_Cost__c,
Product2.Standard_Monthly_Cost__c,
Product2.Supplier__c
FROM PricebookEntry WHERE Product2.IsActive = true];
wrappedList = PopulateWrappedList(unwrappedEntries);
}
List<SelectableListProduct> PopulateWrappedList(List<PricebookEntry> unwrapped) {
List<SelectableListProduct> returnList = new List<SelectableListProduct>();
//For each record returned, created a wrapped object and put it in the list.
for (PricebookEntry entry : unwrapped) {
SelectableListProduct newSLP = new SelectableListProduct(entry, false);
returnList.add(newSLP);
}
//Sort the list.
returnList.sort();
return returnList;
}
List<OpportunityLineItem> PopulateSelectedList(List<SelectableListProduct> wrapped) {
List<OpportunityLineItem> returnList = new List<OpportunityLineItem>();
for (SelectableListProduct entry : wrapped) {
if (entry.isSelected) {
OpportunityLineItem newOLI = new OpportunityLineItem();
newOLI.OpportunityId = controllingOpp.Id;
newOLI.PricebookEntryId = entry.cProduct.Id;
newOLI.UnitPrice = 0;
newOLI.Install_Cost__c = entry.cProduct.Product2.Standard_Install_Cost__c;
newOLI.Monthly_Cost__c = entry.cProduct.Product2.Standard_Monthly_Cost__c;
returnList.add(newOLI);
}
}
returnList.sort();
return returnList;
}
public PageReference Step1() {
return Page.SelectNewItems;
}
public PageReference Step2() {
//populate selected products list
itemsToAdd = PopulateSelectedList(wrappedList);
return Page.EditNewItems;
}
public PageReference Save() {
//Attempt to save items.
try {
insert itemsToAdd;
} catch (System.DMLException e) {
ApexPages.addMessages(e);
return null;
}
//Redir to opp detail page.
PageReference opportunityPage = new ApexPages.StandardController(controllingOpp).view();
opportunityPage.setRedirect(true);
return opportunityPage;
}
public PageReference Cancel() {
PageReference opportunityPage = new ApexPages.StandardController(controllingOpp).view();
opportunityPage.setRedirect(true);
return opportunityPage;
}
}
The first visualforce page (works fine):
<apex:page controller="OpportunityProductsController" tabstyle="Opportunity">
<apex:sectionHeader title="Add New Opportunity Products" subtitle="Select Products"/>
<apex:form >
<apex:pageBlock title="Product List">
<apex:pageBlockButtons >
<apex:commandButton action="{!Step2}" value="Next" immediate="true"/>
<apex:commandButton action="{!Cancel}" value="Cancel"/>
</apex:pageBlockButtons>
<!-- PRODUCT LIST -->
<apex:pageBlockTable value="{!wrappedList}" var="SelectableListProduct">
<apex:column >
<apex:inputCheckbox value="{!SelectableListProduct.isSelected}"/>
</apex:column>
<apex:column value="{!SelectableListProduct.cProduct.Product2.Name}"/>
<apex:column value="{!SelectableListProduct.cProduct.Product2.ProductCode}"/>
<apex:column value="{!SelectableListProduct.cProduct.Product2.Standard_Install_Cost__c}"/>
<apex:column value="{!SelectableListProduct.cProduct.Product2.Standard_Monthly_Cost__c}"/>
<apex:column value="{!SelectableListProduct.cProduct.Product2.Supplier__c}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>
The second visualforce page (displays buttons and nothing else):
<apex:page controller="OpportunityProductsController" tabStyle="Opportunity">
<apex:sectionHeader title="Add New Opportunity Products" subtitle="Edit Products"/>
<apex:form >
<apex:pageBlock title="Edit Item Information">
<apex:pageBlockButtons >
<apex:commandButton action="{!Save}" value="Done"/>
<apex:commandButton action="{!Step1}" value="Back"/>
<apex:commandButton action="{!Cancel}" value="Cancel"/>
</apex:pageBlockButtons>
<apex:outputField value="{!controllingOpp.Name}"/>
<apex:repeat value="{!itemsToAdd}" var="currentItem">
<apex:outputField value="{!currentItem.PricebookEntry.Name}" />
<apex:inputField value="{!currentItem.Install_Cost__c}" />
<apex:inputField value="{!currentItem.Monthly_Cost__c}" />
</apex:repeat>
</apex:pageBlock>
</apex:form>
</apex:page>
EDIT: Here's selectable list product:
public class SelectableListProduct implements Comparable
{
public Boolean isSelected {get;set;}
public PricebookEntry cProduct {get;set;}
public SelectableListProduct(PricebookEntry cProduct, Boolean selected){
this.cProduct = cProduct;
this.isSelected = selected;
}
public Integer compareTo(Object comparisonObject)
{
SelectableListProduct comparisonProduct = (SelectableListProduct)comparisonObject;
return cProduct.Product2.Name.compareTo(comparisonProduct.cProduct.Product2.Name);
}
}