I have a VF page that replaces the Opportunity Product lookup / add / remove page. I am trying to put validations in place where if a user adds a product with ProductCode = 'PREM_PORT', they must add other products with a custom checkbox field (JN_Portfolio__c) checked as true. Likewise, if they enter products with the custom checkboxes checked, they must also have the PREM_PORT product included in their list. I added local boolean variables to my VF custom controller and perform the validation in my onSave method. I have 2 problems:

1) Upon initial save, my System.debug statement shows values that should trigger my validation messages, but the products save without any messages. I do have the apex:pageMessages tag in my VF page.

2) When adding a product, my local variables are not looking at existing products, even though I have attempted to loop through them in my controller extension.

Any help would be appreciated. Controller extension is below:

Controller Extension:

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 portfolio {get;set;}
    public Boolean portfolioChk {get;set;}

    private Boolean forcePricebookSelection = false;

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

    public opportunityProductEntryExtension(ApexPages.StandardController controller) {

            theOpp = [select Id, Pricebook2Id, PriceBook2.Name 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, JN_Portfolio__c, Quantity, UnitPrice, PriceBookEntryId, PriceBookEntry.Product2.ProductCode from opportunityLineItem where OpportunityId=:theOpp.Id];

        theBook = theOpp.Pricebook2;


    public void updateAvailableList() {

        // We dynamically build a query string and exclude items already in the shopping cart
        String qString = 'select Id, Pricebook2Id, Product2.Name, Product2.ProductCode, UnitPrice from PricebookEntry where  Pricebook2Id = \'' + theBook.Id + '\'';

        // 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
            qString+= ' and (Product2.Name like \'%' + searchString + '%\' or Product2.Description like \'%' + searchString + '%\')';

        Set<Id> selectedEntries = new Set<Id>();
        for(opportunityLineItem d:shoppingCart){
            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);

    public void addToShoppingCart(){

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

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

    public PageReference onSave(){

        for(opportunityLineItem oliExist : [SELECT ID, JN_Portfolio__c, PriceBookEntry.Product2.ProductCode
                                            FROM opportunityLineItem
                                            WHERE opportunityId =: theOpp.Id]){
            if(oliExist.JN_Portfolio__c == true){
                portfolioChk = true;
            if(oliExist.PriceBookEntry.Product2.ProductCode == 'PREM_PORTFOLIO'){
                portfolio = true;

        for(opportunityLineItem oli : shoppingCart){
            if(oli.JN_Portfolio__c == true){
                portfolioChk = true;
            if(oli.PriceBookEntry.Product2.ProductCode == 'PREM_PORTFOLIO'){
                portfolio = true;
System.debug('@@@@@@@@@@ portfolio: '+portfolio+'  ########## portfolioChk: '+portfolioChk);

        if(portfolio == true && portfolioChk == false){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'You need to add the associated Products and Rates for your Portfolio deal') );
        return null;

        if(portfolio == false && portfolioChk == true){
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'You need to add the Portfolio Product and Sale Price with the value of your portfolio deal') );
        return null;
        catch(Exception e){
            return null;
        return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id'));

I'd like to see your data but you have a logic problem. In your 'portfolio' and 'portfoliochk' assignments, you're assigning to both true and false.

The problem is that if the first row evaluated triggers the Boolean to true, but the second doesn't, the end result will leave the Boolean as false. Therefore Not triggering your logic in the if statement that follows.

Remove the "else" clauses and set the Booleans to false outside your loop. That should do it.

  • Thanks. That fixed my issue of recognizing existing products (#2), but my controller is still not firing the validations, even though the values are there: 08:01:35.0 (31374696)|USER_DEBUG|[208]|DEBUG|@@@@@@@@@@ portfolio: false ########## portfolioChk: true Jun 5 '17 at 15:03
  • I figured out my issue for #1...I did not have return null; for my validations to prevent returning to the Opp. I've updated my code above. Thanks for your help. Jun 5 '17 at 18:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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