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
kris chitkris chit 

Advanced Apex Specialist- Step 3 Error "Ensure that the Visualforce page is displayed when a use clicks the New button on the Product object"

Hi,
I am stuck at Step 3 of Advanced Apex Specialist. Below is my code.  I am adding below 3 code samples. I have tried overcoming this multiple this but without any results. Please guide me.
 
public  class Product2Extension {
    public List<ProductWrapper> productsToInsert {get;set;}
    public Product2Extension(ApexPages.StandardController controller){
        productsToInsert = new List<ProductWrapper>();
        addRows();
    }

    public void AddRows(){
        for ( Integer i=0; i<Constants.DEFAULT_ROWS; i++ ){
            ProductWrapper prodWrapper = new ProductWrapper();
            productsToInsert.add( prodWrapper );
        }
    }
    public List<ChartHelper.ChartData> GetInventory(){
        return ChartHelper.GetInventory();
    }

    public PageReference Save(){
        SavePoint sp1 = Database.setSavepoint();
        try {
            Map<Integer, Product2> products = new Map<Integer, Product2>();
			Map<Integer, PriceBookEntry> priceBookEntries = new Map<Integer, PriceBookEntry>();    
            Integer index = 0;
            for(ProductWrapper prdWrapper : productsToInsert) {
                if(String.isNotBlank(prdWrapper.productRecord.Name) && prdWrapper.pricebookEntryRecord.UnitPrice!=null && 
                   prdWrapper.productRecord.Initial_Inventory__c!=null && prdWrapper.productRecord.isActive && 
                   prdWrapper.productRecord.Initial_Inventory__c != 0 && prdWrapper.pricebookEntryRecord.UnitPrice!=0){
                          
                	products.put(index,prdWrapper.productRecord);
                    priceBookEntries.put(index,prdWrapper.pricebookEntryRecord);
                    index ++;
                }
            }
            
            insert products.values();
            
            List<PriceBookEntry> pbList = new List<PriceBookEntry>();
            for(Integer mapIndex : products.keySet()) {
            	PriceBookEntry currentPBEntry = priceBookEntries.get(mapIndex);
                if(products.get(mapIndex).Id!=null) {
                    currentPBEntry.Pricebook2Id = Constants.STANDARD_PRICEBOOK_ID;
                	System.debug('' + products.get(mapIndex).Id);
                	currentPBEntry.Product2Id = products.get(mapIndex).Id;
                	currentPBEntry.IsActive = true;
                    pbList.add(currentPBEntry);
                }
                
            }
            
            insert pbList;

            //If successful clear the list and display an informational message
            apexPages.addMessage(new ApexPages.message(ApexPages.Severity.INFO,pbList.size()+' Inserted'));
            productsToInsert.clear();   //Do not remove
            addRows();  //Do not remove
        } catch (Exception e){
			apexPages.addMessage(new ApexPages.message(ApexPages.Severity.ERROR,Constants.ERROR_MESSAGE));
            Database.rollback(sp1);
        }
        return null;
    }
    
    public List<SelectOption> GetFamilyOptions(){
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption(Constants.SELECT_ONE,Constants.SELECT_ONE));
        for(Schema.PicklistEntry entry : Constants.PRODUCT_FAMILY){
			options.add(new SelectOption(entry.getLabel(),entry.getValue()));
        }
		return options;
    }
    
    
    public class ProductWrapper{
        public Product2 productRecord {get;set;}
        public PriceBookEntry pricebookEntryRecord {get;set;}
        
        public ProductWrapper() {
            productRecord = new Product2(Initial_Inventory__c =0);
            pricebookEntryRecord = new PricebookEntry(Unitprice=0.0);
        }
    }

}
public without sharing class ChartHelper {

  @AuraEnabled
  public static List<chartData> GetInventory(){
    List<chartData> cht = new List<chartData>();

    for(AggregateResult ar : [SELECT Family, SUM(Quantity_Remaining__c) FROM Product2 WHERE Quantity_Remaining__c > 0 AND IsActive = true GROUP BY Family]) {
      cht.add(new ChartData(String.ValueOf(ar.get('Family')), Integer.ValueOf(ar.get('expr0'))));
    }

    return cht;
  }


  public class ChartData {
    public String name {get; set;}
    public Decimal val {get; set;}

    public ChartData(String name, Decimal val){
      this.name = name;
      this.val = val;
    }
  }

}
<apex:page standardController="Product2" extensions="Product2Extension" >
    <apex:sectionHeader title="New Product" subtitle="Add Inventory" />
    <apex:pageMessages id="pageMessages" />
    <apex:form id="form" >
        <apex:actionRegion >
            <apex:pageBlock title="Existing Inventory" id="chart-section">
                <apex:chart height="350" width="450" data="{!inventory}">
                    <apex:axis type="Numeric" position="bottom" title="Quantity Remaining" grid="true"
                               fields="val" dashSize="2">
                        <apex:chartLabel />
                    </apex:axis>
                    <apex:axis type="Category" position="left" fields="name" title="Product Family">
                        <apex:chartLabel rotate="315"/>
                    </apex:axis>
                    <apex:barSeries orientation="horizontal" axis="left" 
                                    xField="val" yField="name"/>
                    <apex:legend position="right"/>
                </apex:chart>
            </apex:pageBlock>
            <apex:pageBlock title="New Products" >
                <apex:pageBlockButtons location="top">
                    <apex:commandButton action="{!save}" value="Save" reRender="chart-section"/>
                </apex:pageBlockButtons>
                <apex:pageBlockButtons location="bottom">
                    <apex:commandButton action="{!addRows}" value="Add" reRender="pageMessages,orderItemTable"/>
                </apex:pageBlockButtons>
                
                <apex:pageBlockTable value="{!productsToInsert}" var="p" id="orderItemTable" >
                    <apex:column headerValue="{!$ObjectType.Product2.Fields.Name.Label}" >
                        <apex:inputText value="{!p.productRecord.Name}" />
                    </apex:column>
                    <apex:column headerValue="{!$ObjectType.Product2.Fields.Family.Label}" >
                        <apex:selectList value="{!p.productRecord.Family}" size="1" multiselect="false" >
                            <apex:selectOptions value="{!FamilyOptions}"/>
                        </apex:selectList>
                    </apex:column>
                    <apex:column headerValue="{!$ObjectType.Product2.Fields.isActive.Label}" >
                        <apex:inputField value="{!p.productRecord.isActive}" />
                    </apex:column>
                    <apex:column headerValue="{!$ObjectType.PriceBookEntry.Fields.UnitPrice.Label}" >
                        <apex:inputText value="{!p.pricebookEntryRecord.UnitPrice}" />
                    </apex:column>
                    <apex:column headerValue="{!$ObjectType.Product2.Fields.Initial_Inventory__c.Label}" >
                        <apex:inputField value="{!p.productRecord.Initial_Inventory__c}" />
                    </apex:column>
                </apex:pageBlockTable>
            </apex:pageBlock>
        </apex:actionRegion>
    </apex:form>
</apex:page>



 
Best Answer chosen by kris chit
Raj VakatiRaj Vakati
Use this code
 
<apex:page standardcontroller="Product2" extensions="Product2Extension">
  <apex:sectionHeader title="New Product" subtitle="Add Inventory"/>
  <apex:pageMessages id="pageMessages"/>
  <apex:form id="form">
    <apex:actionRegion>
      <apex:pageBlock title="Existing Inventory" id="existingInv">
        <apex:chart data="{!Inventory}" width="600" height="400">
          <apex:axis type="Category" fields="name" position="left" title="Product Family"/>
          <apex:axis type="Numeric" fields="val" position="bottom" title="Quantity Remaining"/>
          <apex:barSeries axis="bottom" orientation="horizontal" xField="val" yField="name"/>
        </apex:chart>
      </apex:pageBlock>
      <apex:pageBlock title="New Products">
        <apex:pageBlockButtons location="top">
          <apex:commandButton action="{!save}" value="Save" reRender="existingInv, orderItemTable, pageMessages"/>
        </apex:pageBlockButtons>
        <apex:pageBlockButtons location="bottom">
          <apex:commandButton action="{!addRows}" value="Add" reRender="orderItemTable, pageMessages"/>
        </apex:pageBlockButtons>

        <apex:pageBlockTable value="{!productsToInsert}" var="p" id="orderItemTable">
          <apex:column headerValue="{!$ObjectType.Product2.Fields.Name.Label}">
            <apex:inputText value="{!p.productRecord.Name}"/>
          </apex:column>
          <apex:column headerValue="{!$ObjectType.Product2.Fields.Family.Label}">
            <apex:selectList value="{!p.productRecord.Family}" size="1" multiselect="false">
              <apex:selectOptions value="{!FamilyOptions}"></apex:selectOptions>
            </apex:selectList>
          </apex:column>
          <apex:column headerValue="{!$ObjectType.Product2.Fields.IsActive.Label}">
            <apex:inputField value="{!p.productRecord.isActive}"/>
          </apex:column>
          <apex:column headerValue="{!$ObjectType.PricebookEntry.Fields.UnitPrice.Label}">
            <apex:inputText value="{!p.pricebookEntryRecord.UnitPrice}"/>
          </apex:column>
          <apex:column headerValue="{!$ObjectType.Product2.Fields.Initial_Inventory__c.Label}">
            <apex:inputField value="{!p.productRecord.Initial_Inventory__c}"/>
          </apex:column>
        </apex:pageBlockTable>
      </apex:pageBlock>
    </apex:actionRegion>
  </apex:form>
</apex:page>
 
public class Product2Extension {

  public List<ProductWrapper> productsToInsert {get; set;}

  public Product2Extension(ApexPages.StandardController controller){
    productsToInsert = new List<ProductWrapper>();
    AddRows();
  }

  public void AddRows(){
    for (Integer i=0; i<Constants.DEFAULT_ROWS; i++ ) {
      productsToInsert.add( new ProductWrapper() );
    }
  }

  public List<ChartHelper.ChartData> GetInventory(){
    return ChartHelper.GetInventory();
  }

  public List<SelectOption> GetFamilyOptions() {
    List<SelectOption> options = new List<SelectOption>();
    options.add(new SelectOption(Constants.SELECT_ONE, Constants.SELECT_ONE));
    for(PickListEntry eachPicklistValue : Constants.PRODUCT_FAMILY) {
      options.add(new SelectOption(eachPicklistValue.getValue(), eachPicklistValue.getLabel()));
    }
    return options;
  }

  public PageReference Save(){
    Savepoint sp = Database.setSavepoint();
    try {
      List<Product2> products = new List<Product2>();
      List<PricebookEntry> pbes = new List<PricebookEntry>();

      for (ProductWrapper prodwrapper : productsToInsert) {
        if(prodwrapper.productRecord != null && prodwrapper.pricebookEntryRecord != null) {
          if(prodwrapper.productRecord.Name != null && prodwrapper.productRecord.Family != null && constants.SELECT_ONE != prodwrapper.productRecord.Family && prodwrapper.productRecord.Initial_Inventory__c != null && prodwrapper.pricebookEntryRecord.UnitPrice != null) {
            products.add(prodwrapper.productRecord);
            PricebookEntry pbe = prodwrapper.pricebookEntryRecord;
            pbe.IsActive = true;
            pbe.Pricebook2Id = Constants.STANDARD_PRICEBOOK_ID;
            pbes.add(pbe);
          }
        }
      }

      insert products;

      for (integer i = 0; i < pbes.size(); i++) {
        pbes[i].Product2Id = products[i].Id;
      }
      insert pbes;

      //If successful clear the list and display an informational message
      apexPages.addMessage(new ApexPages.message(ApexPages.Severity.INFO,productsToInsert.size()+' Inserted'));
      productsToInsert.clear();         //Do not remove
      AddRows();        //Do not remove
    } catch (Exception e){
      Database.rollback(sp);
      apexPages.addMessage(new ApexPages.message(ApexPages.Severity.ERROR, Constants.ERROR_MESSAGE));
    }
    return null;
  }

  public class ProductWrapper {
    public Product2 productRecord {get; set;}
    public PriceBookEntry pricebookEntryRecord {get; set;}

    public ProductWrapper() {
      productRecord = new product2(Initial_Inventory__c =0);
      pricebookEntryRecord = new pricebookEntry(Unitprice=0.0);
    }
  }
}