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
Manoj Goswami 5Manoj Goswami 5 

I am stuck in Advanced Apex Specialist - Challenge 3. please HELP !!!

Error : 
User-added image

I have overridden the add and new standard buttons as well.
User-added image
Product2Extension.cls :
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);
    }
  }
}
Product2New​.page :
<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>
product2Trigger : 
trigger product2Trigger on Product2 (after update) {
  Product2Helper.AfterUpdate((List<Product2>)Trigger.new);
}
Constants.cls : 
public class Constants {
  public static final Integer DEFAULT_ROWS = 5;
  public static final String SELECT_ONE = Label.Select_One;
  public static final String INVENTORY_LEVEL_LOW = Label.Inventory_Level_Low;
  public static final List<Schema.PicklistEntry> PRODUCT_FAMILY = Product2.Family.getDescribe().getPicklistValues();
  public static final String DRAFT_ORDER_STATUS = 'Draft';
  public static final String ACTIVATED_ORDER_STATUS = 'Activated';
  public static final String INVENTORY_ANNOUNCEMENTS = 'Inventory Announcements';
  public static final String ERROR_MESSAGE = 'An error has occurred, please take a screenshot with the URL and send it to IT.';
  public static final Id STANDARD_PRICEBOOK_ID = '01s6A0000031LaYQAU'; //Test.isRunningTest() ? Test.getStandardPricebookId() : [SELECT Id FROM PriceBook2 WHERE isStandard = true LIMIT 1].Id;
}
Can somebody try and paste the working code here. It would be a great help.
Thanks in advance.




 
NagendraNagendra (Salesforce Developers) 
Hi Manoj,

Sorry for this issue you are encountering.

May I suggest you please check with below links which might help you further. Hope this helps.

Thanks,
Nagendra
Manoj Goswami 5Manoj Goswami 5
Hi Nagendra,

I tried the above mentioned solution. Still no luck.
Can you provide more solutions please.

Thanks ,
Manoj 
NewBie09NewBie09
How did you resolve this? Am facing this issue and have no idea what might be the problem?
Priyanka Vaishnav 20Priyanka Vaishnav 20
Change your SAVE method

  public PageReference Save(){
    SavePoint sp = Database.setSavepoint();
    Integer insertedCount = 0;
    try {
      List<Product2> newProducts = new List<Product2>();
      List<PriceBookEntry> pbeList = new List<PriceBookEntry>();
      List<ProductWrapper> filteredProductWrappers = new List<ProductWrapper>();

      for(ProductWrapper eachPW : productsToInsert) {
        if(!String.isBlank(eachPW.productRecord.Name) && !String.isBlank(eachPW.productRecord.Family) && eachPW.productRecord.Family != Constants.SELECT_ONE && eachPW.productRecord.isActive && eachPW.pricebookEntryRecord.UnitPrice != null && eachPW.pricebookEntryRecord.UnitPrice != 0 && eachPW.productRecord.Initial_Inventory__c != null && eachPW.productRecord.Initial_Inventory__c != 0) {
          filteredProductWrappers.add(eachPW);
        }
      }
      for(ProductWrapper eachPW : filteredProductWrappers) {
        newProducts.add(eachPW.productRecord);
      }

      Database.SaveResult[] productSaveResults = Database.insert(newProducts, false);

      for(Integer i = 0; i < productSaveResults.size(); i++) {
        if(productSaveResults[i].isSuccess()) {
          PriceBookEntry pbe = filteredProductWrappers[i].pricebookEntryRecord;
          pbe.Product2Id = productSaveResults[i].getId();
          pbe.IsActive = true;
          pbe.Pricebook2Id = Constants.STANDARD_PRICEBOOK_ID;
          pbeList.add(pbe);
          insertedCount++;
        }
      }

      Database.SaveResult[] pbeSaveResults = Database.insert(pbeList, false);

      apexPages.addMessage(new ApexPages.message(ApexPages.Severity.INFO,insertedCount + ' Inserted'));
      productsToInsert.clear();
      addRows();
    }
    catch (Exception e){
      System.debug('Exception occured:'+e.getMessage());
      Database.rollback(sp);
      apexPages.addMessage(new ApexPages.message(ApexPages.Severity.ERROR, Constants.ERROR_MESSAGE));
    }
    return null;
  }
 
Deepak BasivireddyDeepak Basivireddy
How did you resolved this issue? Am also facing the same issue and no clue where it went wrong.
Glen NinanGlen Ninan
I got the same error message. It went away when I added an IF statement before I add the Products to the the list of Products to insert.
On the  Product2Extension class, all I did is add the line in BOLD font and the error went away.
-----------------------------------------
...
    public PageReference Save(){
        savepoint sp = database.setsavepoint();
        try {
            list<product2> newProducts = new list<product2>();
            list<PriceBookEntry> newPBEntries = new list<PriceBookEntry>();
            for(ProductWrapper eachPW : productsToInsert) {
                if(eachPW.productRecord.Name != null && eachPW.productRecord.Family != null && constants.SELECT_ONE != eachPW.productRecord.Family && eachPW.productRecord.Initial_Inventory__c != null && eachPW.pricebookEntryRecord.UnitPrice != null) {
                    newProducts.add(eachPW.productRecord);
                    eachPW.pricebookEntryRecord.IsActive = true;
                    eachPW.pricebookEntryRecord.Pricebook2Id = Constants.STANDARD_PRICEBOOK_ID;
                    newPBEntries.add(eachPW.pricebookEntryRecord);
                }
            }
            insert newProducts;
....
-----------------------------------------------

Kindly mark this question as SOLVED if this solution worked for you.
Sathyapriya VSathyapriya V
hi @Glen pls help me to complete the challenge. here is my code

public without sharing 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();
    Integer insertedCount = 0;
    try {
      List<Product2> newProducts = new List<Product2>();
      List<PriceBookEntry> pbeList = new List<PriceBookEntry>();
      List<ProductWrapper> filteredProductWrappers = new List<ProductWrapper>();

      for(ProductWrapper eachPW : productsToInsert) {
        if(!String.isBlank(eachPW.productRecord.Name) && !String.isBlank(eachPW.productRecord.Family) && eachPW.productRecord.Family != Constants.SELECT_ONE && eachPW.productRecord.isActive && eachPW.pricebookEntryRecord.UnitPrice != null && eachPW.pricebookEntryRecord.UnitPrice != 0 && eachPW.productRecord.Initial_Inventory__c != null && eachPW.productRecord.Initial_Inventory__c != 0) {
          filteredProductWrappers.add(eachPW);
        }
      }
      for(ProductWrapper eachPW : filteredProductWrappers) {
        newProducts.add(eachPW.productRecord);
      }

      Database.SaveResult[] productSaveResults = Database.insert(newProducts, false);

      for(Integer i = 0; i < productSaveResults.size(); i++) {
        if(productSaveResults[i].isSuccess()) {
          PriceBookEntry pbe = filteredProductWrappers[i].pricebookEntryRecord;
          pbe.Product2Id = productSaveResults[i].getId();
          pbe.IsActive = true;
          pbe.Pricebook2Id = Constants.STANDARD_PRICEBOOK_ID;
          pbeList.add(pbe);
          insertedCount++;
        }
      }

      Database.SaveResult[] pbeSaveResults = Database.insert(pbeList, false);

      apexPages.addMessage(new ApexPages.message(ApexPages.Severity.INFO,insertedCount + ' Inserted'));
      productsToInsert.clear();
      addRows();
    }
    catch (Exception e){
      System.debug('Exception occured:'+e.getMessage());
      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);
    }
  }
}
Anna RudasAnna Rudas
You need to override buttons Add and New on Product to work with the visualforce page.
1. Go to the Product object.
2. Click Buttons, Links and Actions.
3. Edit Add button -> Select Salesforce Classic Override -> Visualforce Page -> Product2New
4. Edit New button -> Select Salesforce Classic Override -> Visualforce Page -> Product2New

That's it.
Suchismita Mukherjee 7Suchismita Mukherjee 7
getting same error, can anyone pls help with code