2

I want to pass the pricebook2id from an opportunity to my apex class and then use this when querying. I can get it using the Controller.addFields when declaring the controller like this:

public AddProduct(ApexPages.StandardController controller) {
Controller.addFields(new List<String>{'Name', 'PriceBook2Id'});
}

But then I have issues passing the test.

So how do I properly use this information in the query in the method to add a Opportunityproduct aka method AddJuice?

Here is the relevant visualforce page info with the passed variable attempt:

<apex:page  standardController="Opportunity"  extensions="MyExtension" >
 <apex:outputField value = "{!Opportunity.Pricebook2id}" rendered="false"/>
 <apex:form >
  <apex:pageBlock title="Add Opportunity Product" >
   <apex:commandButton action="{!AddJuice}" value="Add Juice" />
   <apex:commandButton action="{!AddMilk}" value="Add Milk" />
  </apex:pageBlock>
 </apex:form>    
</apex:page>

Here is my extension class:

 public class myextension {

        private ApexPages.StandardController sc;
        public String PassedPricebookId {
                get {
                    return String.valueOf(Opportunity.Pricebook2id.id);
                        }
                private set;
              }
 system.debug(OppPBId);

 public AddProduct(ApexPages.StandardController controller) {
                sc= controller;
                ELI = new OpportunityLineItem();
                CusLI = new OpportunityLineItem();
               if (!Test.isRunningTest()) Controller.addFields(new List<String>{'Name', 'PriceBook2Id'}); //-- this can work but won't pass test!
            }

  public PageReference AddJuice (){
                Opportunity TheOpp = (Opportunity)sc.GetRecord();
                ELI.OpportunityId=TheOpp.id;
                ELI.PricebookEntryId=[select id from PricebookEntry 
                where name =: 'Juice' 
                and Pricebook2id=:(how do I get the PassedPricebookId in here?].id;
        //more fields etc

              PageReference ScheduleUrl = new PageReference
             ('/oppitm/scheduleedit.jsp?id='+ELi.id+'&sUrl=%2F'+ELi.id+'&retURL=%2F'+TheOpp.id);
        return ScheduleUrl;
            }

Secondary question - why does my line system.debug(OppPBId); throw an error:

unexpected token: ')'

  • can you post more VFP code on what basis you want to pass value to controller, like any field selection or changing any values from VFP – Santanu Boral Jun 29 '17 at 19:55
  • sure, more added – jaw999 Jun 29 '17 at 20:04
  • can you post your test class code and let us know what issue you are facing – Santanu Boral Jul 6 '17 at 14:58
  • I am having issue where I can't set the Pricebook2id for the op. I have a processBuilder that sets it in prod but it is not setting. And when I try to declare it, it returns no rows and errors, even though the same query in the query editor returns a valid Pricebookid – jaw999 Jul 6 '17 at 15:02
  • check my answer, not sure it helps, because your question is still confusing to me as to how you are setting the pricebookId and how you are accessing. – Santanu Boral Jul 6 '17 at 16:30
3
+25

I have made small changes in the Extension class.

Added TheOpp = (Opportunity)sc.getRecord(); in the Constructor.

public class myextension {

    private ApexPages.StandardController sc;
    public Opportunity TheOpp{get;set;}

    public String PassedPricebookId {
            get {
                return String.valueOf(TheOpp.Pricebook2id); //take from Controller TheOpp
            }
            private set;
          }

    public AddProduct(ApexPages.StandardController controller) 
    {
        sc= controller;
        TheOpp = (Opportunity)sc.getRecord(); //initialize TheOpp

        ELI = new OpportunityLineItem();
        CusLI = new OpportunityLineItem();
       if (!Test.isRunningTest()) Controller.addFields(new List<String>{'Name', 'PriceBook2Id'}); //-- this can work but won't pass test!
    }

  public PageReference AddJuice (){
        ELI.OpportunityId=TheOpp.id;
        ELI.PricebookEntryId=[select id from PricebookEntry 
        where name =: 'Juice' 
        and Pricebook2id=:PassedPricebookId;
        //more fields etc

      PageReference ScheduleUrl = new PageReference
     ('/oppitm/scheduleedit.jsp?id='+ELi.id+'&sUrl=%2F'+ELi.id+'&retURL=%2F'+TheOpp.id);
        return ScheduleUrl;
     }
}

Change the Visualforce

<apex:outputField value = "{!TheOpp.Pricebook2id}" rendered="false"/>

It is still confusing to me PassedPricebookId property. I could assume it will take from Opportunity itself.

and this line

if (!Test.isRunningTest()) Controller.addFields(new List<String>{'Name', 'PriceBook2Id'});

Given an approach how you can create test records for Opportunity and PriceBook in test class. You could change based on your need.

@isTest
public class OpportunityExtnTest {
    // Utility method that can be called by Apex tests to create price book entries.
    static testmethod void AddJuiceTesting() {
        // First, set up test price book entries.
        // Insert a test product.
        Product2 prod = new Product2(Name = 'Laptop X200', 
            Family = 'Hardware');
        insert prod;

        // Get standard price book ID.
        // This is available irrespective of the state of SeeAllData.
        Id pricebookId = Test.getStandardPricebookId();

        // 1. Insert a price book entry for the standard price book.
        // Standard price book entries require the standard price book ID we got earlier.
        PricebookEntry standardPrice = new PricebookEntry(Name='Juice',
            Pricebook2Id = pricebookId, Product2Id = prod.Id,
            UnitPrice = 10000, IsActive = true);
        insert standardPrice;

        //Create Account
        Account acct = new Account(Name='TestAccount1');
        insert acct;

        //now create Opportunity with PriceBookId
        Opportunity oppty = new Opportunity(Name='TestOppty', AccountId=acct.id, Pricebook2Id=pricebookId);
        insert oppty;

        //now create OpportunityLineItems
        OpportunityLineItem oli = new OpportunityLineItem(OpportunityId = oppty.Id, Product2Id = prod.Id);
        insert oli;

        //now pass value to Controller.
        //create pageReference
        PageReference page = Page.MyVFP;
        Test.setCurrentPage(page);

        //pass parameter to the page
        ApexPages.currentPage().getParameters().put('id',oppty.Id);

        //create an instance of controller.
        ApexPages.StandardController standrdcontroller = new ApexPages.StandardController(oppty);
        myextension myextensionObj = new myextension(standrdcontroller);

        myextensionObj.AddJuice();

    }
}
|improve this answer|||||
0
ELI.PricebookEntryId = [select id from PricebookEntry 
                where name =: 'Juice' 
                and Pricebook2Id = :TheOpp.Pricebook2Id];

Also you can't put system.debug's in the area where you are declare your member variables. Put it inside a function or a get/set method. OppPBId is a variable that doesn't exist anywhere, so it will still throw you another error saying the variable doesn't exist even after you put it in a function.

|improve this answer|||||
  • If I use this, I need to use Controller.addFields(new List<String>{'Name', 'PriceBook2Id'}); and then that can't pass Test – jaw999 Jun 29 '17 at 20:23
  • Your test class should look like this: Opportunity opp = new Opportunity(Pricebook2Id = <id of pricebook2id>); MyExtension controller = new MyExtension(new ApexPages.StandardController(opp)); – willard Jun 29 '17 at 20:28
  • I am not geting a pass on the test run - myExtension controller = new MyExtension(new ApexPages.StandardController(opp)); controller.AddJuice(); - can you put the test info in your answer? Am told query has no rows for assignment but buttons work in prod – jaw999 Jun 29 '17 at 20:48
0

If your concern is just getting 100% test coverage, you will never be able to do it with the addFields() method in your code.

The work around is to include the fields in you visualforce page, even if you aren't rendering them.

<apex:page  standardController="Opportunity"  extensions="MyExtension" >
 <apex:outputField value = "{!Opportunity.Pricebook2id}" rendered="false"/>
 <apex:form >
  <apex:pageBlock title="Add Opportunity Product" >
   <apex:commandButton action="{!AddJuice}" value="Add Juice" />
   <apex:commandButton action="{!AddMilk}" value="Add Milk" />
  </apex:pageBlock>
 <apex:outputField value="{!Name}" rendered="false" />
 <apex:outputField value="{!PriceBook2Id}" rendered="false" />
 </apex:form>    
</apex:page>

Although if you would prefer to leave the addFields() method as it is, you could just chalk this up to a deficiency in the testing framework and leave it as less than 100% test coverage.


As for the PassedPricebookId class attribute,

return String.valueOf(Opportunity.Pricebook2id.id);

should just be

return String.valueOf(Opportunity.Pricebook2Id);
// or just // return Opportunity.Pricebook2Id;

The reason is that the Pricebook2Id field is itself an Id.

|improve this answer|||||
  • I have terrible coverage right now... I like the method you describe but I am keep being unable to use the passed Pricebook2id in my methods - please see my code where I have (how do I get the PassedPricebookId in here?] – jaw999 Jul 6 '17 at 14:46

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.