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
sparrowbradsparrowbrad 

Custom Product Interface - Making Users Select Pricebook, Only 1 Available

Everything posted here is in reference to this post
http://www.michaelforce.org/recipeView?id=a0G30000006eVxVEAU

 

Installed this unmanaged package from the link above and trying to figure out why this is making user select a pricebook even though there is only one available.

 

This package includes 3 classes and 2 VF pages.

 

I can posts the others if needed, but it seems like the "issue" is within this class. Even the documentation states it shouldn't ask for a pricebook if only exists. I'm not a developer, so are there anything that stands out here.

 

 

 

public with sharing class opportunityProductEntryExtension {

public Opportunity theOpp {get;set;}
public String searchString {get;set;}
public opportunityLineItem[] shoppingCart {get;set;}
public priceBookEntry[] AvailableProducts {get;set;}
public Pricebook2 theBook {get;set;}

public String toSelect {get; set;}
public String toUnselect {get; set;}
public Decimal Total {get;set;}

public Boolean overLimit {get;set;}
public Boolean multipleCurrencies {get; set;}

private Boolean forcePricebookSelection = false;

private opportunityLineItem[] forDeletion = new opportunityLineItem[]{};


public opportunityProductEntryExtension(ApexPages.StandardController controller) {

// Need to know if org has multiple currencies enabled
multipleCurrencies = UserInfo.isMultiCurrencyOrganization();

// Get information about the Opportunity being worked on
if(multipleCurrencies)
theOpp = database.query('select Id, Pricebook2Id, Pricebook2.Name, CurrencyIsoCode from Opportunity where Id = \'' + controller.getRecord().Id + '\' limit 1');
else
theOpp = [select Id, Pricebook2Id, PriceBook2.Name, Start_Date__c, End_Date__c from Opportunity where Id = :controller.getRecord().Id limit 1];

// If products were previously selected need to put them in the "selected products" section to start with
shoppingCart = [select Id, Quantity, TotalPrice, UnitPrice, Desired_Amount__c, Discount, Description, PriceBookEntryId, PriceBookEntry.Name, PriceBookEntry.IsActive, PriceBookEntry.Product2Id, PriceBookEntry.Product2.Name, PriceBookEntry.PriceBook2Id from opportunityLineItem where OpportunityId=:theOpp.Id];

// Check if Opp has a pricebook associated yet
if(theOpp.Pricebook2Id == null){
Pricebook2[] activepbs = [select Id, Name from Pricebook2 where isActive = true limit 2];
if(activepbs.size() == 2){
forcePricebookSelection = true;
theBook = new Pricebook2();
}
else{
theBook = activepbs[0];
}
}
else{
theBook = theOpp.Pricebook2;
}

if(!forcePricebookSelection)
updateAvailableList();
}

// this is the 'action' method on the page

public PageReference priceBookCheck(){

// if the user needs to select a pricebook before we proceed we send them to standard pricebook selection screen
if(forcePricebookSelection){
return changePricebook();
}
else{

//if there is only one active pricebook we go with it and save the opp
if(theOpp.pricebook2Id != theBook.Id){
try{
theOpp.Pricebook2Id = theBook.Id;
update(theOpp);
}
catch(Exception e){
ApexPages.addMessages(e);
}
}

return null;
}
}

public String getChosenCurrency(){

if(multipleCurrencies)
return (String)theOpp.get('CurrencyIsoCode');
else
return '';
}

public void updateAvailableList() {

// We dynamically build a query string and exclude items already in the shopping cart
String qString = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Family, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and Pricebook2Id = \'' + theBook.Id + '\'';
if(multipleCurrencies)
qstring += ' and CurrencyIsoCode = \'' + theOpp.get('currencyIsoCode') + '\'';

// note that we are looking for the search string entered by the user in the name OR description
// modify this to search other fields if desired
if(searchString!=null){
qString+= ' and (Product2.Name like \'%' + searchString + '%\' or Product2.Description like \'%' + searchString + '%\')';
}

Set<Id> selectedEntries = new Set<Id>();
for(opportunityLineItem d:shoppingCart){
selectedEntries.add(d.PricebookEntryId);
}

if(selectedEntries.size()>0){
String tempFilter = ' and Id not in (';
for(Id i : selectedEntries){
tempFilter+= '\'' + (String)i + '\',';
}
String extraFilter = tempFilter.substring(0,tempFilter.length()-1);
extraFilter+= ')';

qString+= extraFilter;
}

qString+= ' order by Product2.Name';
qString+= ' limit 101';

system.debug('qString:' +qString);
AvailableProducts = database.query(qString);

// We only display up to 100 results... if there are more than we let the user know (see vf page)
if(AvailableProducts.size()==101){
AvailableProducts.remove(100);
overLimit = true;
}
else{
overLimit=false;
}
}

public void addToShoppingCart(){

// This function runs when a user hits "select" button next to a product

for(PricebookEntry d : AvailableProducts){
if((String)d.Id==toSelect){
shoppingCart.add(new opportunityLineItem(OpportunityId=theOpp.Id, PriceBookEntry=d, PriceBookEntryId=d.Id, UnitPrice=d.UnitPrice));
break;
}
}

updateAvailableList();
}

public PageReference removeFromShoppingCart(){

// This function runs when a user hits "remove" on an item in the "Selected Products" section

Integer count = 0;

for(opportunityLineItem d : shoppingCart){
if((String)d.PriceBookEntryId==toUnselect){

if(d.Id!=null)
forDeletion.add(d);

shoppingCart.remove(count);
break;
}
count++;
}

updateAvailableList();

return null;
}

public PageReference onSave(){

// If previously selected products are now removed, we need to delete them
if(forDeletion.size()>0)
delete(forDeletion);

// Previously selected products may have new quantities and amounts, and we may have new products listed, so we use upsert here
try{
if(shoppingCart.size()>0)
upsert(shoppingCart);
}
catch(Exception e){
ApexPages.addMessages(e);
return null;
}

// After save return the user to the Opportunity
return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id'));
}

public PageReference onCancel(){

// If user hits cancel we commit no changes and return them to the Opportunity
return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id'));
}

public PageReference changePricebook(){

// This simply returns a PageReference to the standard Pricebook selection screen
// Note that is uses retURL parameter to make sure the user is sent back after they choose

PageReference ref = new PageReference('/oppitm/choosepricebook.jsp');
ref.getParameters().put('id',theOpp.Id);
ref.getParameters().put('retURL','/apex/opportunityProductEntry?id=' + theOpp.Id);

return ref;
}
}