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
jmarinchakjmarinchak 

My first visualforce attempt

I'm trying to write a short commission calculation page that takes all opportunities and calculates a commission amount based on users quota and variable salary.  The variable salary and quota should be multiplied together to determine a commission "rate."  The user should navigate to the page, enter their numbers (I could probably store these somplace) and they would get a list of their opportunities, the opportunity amount and a commission amount.  It would also be nice to have the total commission amount listed at the end.
 
If I can get this basic idea working, I would add a few things -
* Date selector - allowing the user to select a date rage (start and end)
* Account selector - allowing the user to select accounts to include (a checkbox approach might work here)
* Group the results by account, show subtotals for each account
* Provide a PDF generation (commission statement)
 
I got a skeleton of the idea put together but, it isn't really working.  I've got a few problems with this code.  The page will render but, I the error below when I press calculate.  I'm also trying to figure out how to capture a number in the inputfield.  This code is using inputext but, I'm really trying to capture number (currency amount) - so I can't use the input values yet and I've just hard coded 10% commission.  How should I capture this amount?  Should I create a custom currency object just to capture the number?
 
System.NullPointerException: Attempt to de-reference a null object
 
Class.ACommissionController.cOpportunity.<init>: line 15, column 33
Class.ACommissionController.getMyList: line 29, column 28
External entry point
 
Thanks in advance for any help you can provide!
 
Jeff
 
Apex Page:
Code:
<apex:page controller="ACommissionController"> 
<apex:form >

  <apex:pageBlock title="Inputs">
      <p><b>Report for {!$User.FirstName} {!$User.LastName}</b></p> <br />
      
      <b>Quota </b>
      <apex:inputText value="{!Quota}" /> <br />
      
      <b>Variable Salary </b>
      <apex:inputText value="{!Variable_Salary}" /> <br /><br />
      
      <apex:commandButton action="{!getMyList}" value="Calculate" rerender="MyOpps" status="status"/> <br />
      <apex:pageMessages ></apex:pageMessages>
  </apex:pageBlock>

  <apex:actionStatus startText="Updating..." id="status"/>
  
  <apex:pageBlock title="MyOpps" >
  <apex:dataTable value="{!MyList}" var="aOpp" width="100%">
     <apex:column >
      <apex:facet name="header"><b>AccountId</b></apex:facet>
      {!aOpp.myopp.Id}
     </apex:column>
     <apex:column >
      <apex:facet name="header"><b>Name</b></apex:facet>
      {!aOpp.myopp.Name}
     </apex:column>
     <apex:column >
      <apex:facet name="header"><b>Amount</b></apex:facet>
      {!aOpp.myopp.Amount}
     </apex:column>
     <apex:column >
      <apex:facet name="header"><b>Commission</b></apex:facet>
     {!aOpp.Commission_Amount}
     </apex:column>
   </apex:dataTable>                
   </apex:pageBlock>
</apex:form>

</apex:page>

 
Controller:
Code:
public class ACommissionController {

    public string Quota {get; set;}
    public string Variable_Salary {get; set;}
    
     /* New wrapper class */
    public class cOpportunity{
        public Opportunity myopp {get; set;}
        public Double Commission_Amount{get; set;}
        
        /*This is the constructor method. When we create a new cCommission object we pass a 
        SCRB_Salesorder_c that is set to the corder property. We also set the Commission_Amount value to zero*/
        public cOpportunity(Opportunity o){
            myopp = o;
            Commission_Amount = o.Amount * 0.10;
        }
    }

    //A collection of the class/wrapper objects cOpportunity
    public List<cOpportunity> MyList {get; set;}
    
    //This method uses a SOQL query to return a List of Opportunities
    public List<cOpportunity> getMyList(){
          if(MyList == null){
            MyList = new List<cOpportunity>();
          }          
             for(Opportunity opp : [Select Id, Name, Amount FROM Opportunity    ]){
                /* As each opportunity is processed I create a new cOpportunity object and add it to MyList */
                MyList.add(new cOpportunity(opp));
            }
        return MyList;
    }
}

 
Best Answer chosen by Admin (Salesforce Developers) 
JimRaeJimRae
Here is some updated controller code that checks to make sure there is an amount, and also caps the commission amount.  Also, fixed it so that if you press the calculate button multiple times, it doesn't duplicate the entries.

Code:
public class ACommissionController {

    public PageReference genMyList() {
        MyList = bMyList();
        return null;
    }


    public Double Quota {get; set;}
    public Double Variable_Salary {get; set;}
    
     /* New wrapper class */
    public class cOpportunity{
        public Opportunity myopp {get; set;}
        public Double Commission_Amount{get; set;}
        
        /*This is the constructor method. When we create a new cCommission object we pass a 
        SCRB_Salesorder_c that is set to the corder property. We also set the Commission_Amount value to zero*/
        public cOpportunity(Opportunity o,Double Q,Double VS){
            myopp = o;
            if(!(o.Amount==null)){
                Double commcalc = (VS/ Q)< .20—(VS/ Q):.20;
                Commission_Amount = o.Amount * commcalc;
            }else{
                Commission_Amount = 0;
            }
        }
    }

    //A collection of the class/wrapper objects cOpportunity
    public List<cOpportunity> MyList {get; set;}
    
    //This method uses a SOQL query to return a List of Opportunities
    public List<cOpportunity> bMyList(){
          if(MyList == null){
              MyList = new List<cOpportunity>();
              for(Opportunity opp : [Select Id, Name, Amount FROM Opportunity    ]){
                    /* As each opportunity is processed I create a new cOpportunity object and add it to MyList */
                    MyList.add(new cOpportunity(opp,Quota,Variable_Salary));
              }
          }
        return MyList;
    }
}

 

All Answers

JimRaeJimRae
Couple things I noticed that will get you started.  Your button needs to call a PageReference method.  I use this call to update a list object with my result data. Also, you have a rerender set but you did not use the id tag on the object you want to rerender.  I did a quick update to your code, including a simple way to get your inputs inside of your class object.

Code:
<apex:page controller="ACommissionController"> 
<apex:form >

  <apex:pageBlock title="Inputs">
      <p><b>Report for {!$User.FirstName} {!$User.LastName}</b></p> <br />
      
      <b>Quota </b>
      <apex:inputText value="{!Quota}" /> <br />
      
      <b>Variable Salary </b>
      <apex:inputText value="{!Variable_Salary}" /> <br /><br />
      
      <apex:commandButton action="{!genMyList}" value="Calculate" rerender="MyOpps" status="status"/> <br />
      <apex:pageMessages ></apex:pageMessages>
  </apex:pageBlock>

  <apex:actionStatus startText="Updating..." id="status"/>
  
  <apex:pageBlock title="MyOpps" id="MyOpps" >
  <apex:dataTable value="{!MyList}" var="aOpp" width="100%">
     <apex:column >
      <apex:facet name="header"><b>AccountId</b></apex:facet>
      {!aOpp.myopp.Id}
     </apex:column>
     <apex:column >
      <apex:facet name="header"><b>Name</b></apex:facet>
      {!aOpp.myopp.Name}
     </apex:column>
     <apex:column >
      <apex:facet name="header"><b>Amount</b></apex:facet>
      {!aOpp.myopp.Amount}
     </apex:column>
     <apex:column >
      <apex:facet name="header"><b>Commission</b></apex:facet>
     {!aOpp.Commission_Amount}
     </apex:column>
   </apex:dataTable>                
   </apex:pageBlock>
</apex:form>

</apex:page>

Code:
public class ACommissionController {

    public PageReference genMyList() {
        MyList = bMyList();
        return null;
    }


    public Double Quota {get; set;}
    public Double Variable_Salary {get; set;}
    
     /* New wrapper class */
    public class cOpportunity{
        public Opportunity myopp {get; set;}
        public Double Commission_Amount{get; set;}
        
        /*This is the constructor method. When we create a new cCommission object we pass a 
        SCRB_Salesorder_c that is set to the corder property. We also set the Commission_Amount value to zero*/
        public cOpportunity(Opportunity o,Double Q,Double VS){
            myopp = o;
            Commission_Amount = o.Amount * (Q/ VS);
        }
    }

    //A collection of the class/wrapper objects cOpportunity
    public List<cOpportunity> MyList {get; set;}
    
    //This method uses a SOQL query to return a List of Opportunities
    public List<cOpportunity> bMyList(){
          if(MyList == null){
            MyList = new List<cOpportunity>();
          }          
             for(Opportunity opp : [Select Id, Name, Amount FROM Opportunity    ]){
                /* As each opportunity is processed I create a new cOpportunity object and add it to MyList */
                MyList.add(new cOpportunity(opp,Quota,Variable_Salary));
            }
        return MyList;
    }
}

 


 

jmarinchakjmarinchak
Thanks for your help!  I really appreciate it.
 
I'm still getting the null pointer exception.  I've tried rewriting the controller code.  No luck yet.
 
System.NullPointerException: Attempt to de-reference a null object

Class.ACommissionController.cOpportunity.<init>: line 21, column 33
Class.ACommissionController.bMyList: line 35, column 28
Class.ACommissionController.genMyList: line 4, column 18
External entry point
 
Jeff
JimRaeJimRae
So, I wonder, for the user you are running the code for, are there any existing opportunities?  based on the way you are showing the error, I would guess there was at least one, but, does it have an Amount included?
That could be causing the error, and would be a good thing to test for in the wrapper class code.
JimRaeJimRae
Here is some updated controller code that checks to make sure there is an amount, and also caps the commission amount.  Also, fixed it so that if you press the calculate button multiple times, it doesn't duplicate the entries.

Code:
public class ACommissionController {

    public PageReference genMyList() {
        MyList = bMyList();
        return null;
    }


    public Double Quota {get; set;}
    public Double Variable_Salary {get; set;}
    
     /* New wrapper class */
    public class cOpportunity{
        public Opportunity myopp {get; set;}
        public Double Commission_Amount{get; set;}
        
        /*This is the constructor method. When we create a new cCommission object we pass a 
        SCRB_Salesorder_c that is set to the corder property. We also set the Commission_Amount value to zero*/
        public cOpportunity(Opportunity o,Double Q,Double VS){
            myopp = o;
            if(!(o.Amount==null)){
                Double commcalc = (VS/ Q)< .20—(VS/ Q):.20;
                Commission_Amount = o.Amount * commcalc;
            }else{
                Commission_Amount = 0;
            }
        }
    }

    //A collection of the class/wrapper objects cOpportunity
    public List<cOpportunity> MyList {get; set;}
    
    //This method uses a SOQL query to return a List of Opportunities
    public List<cOpportunity> bMyList(){
          if(MyList == null){
              MyList = new List<cOpportunity>();
              for(Opportunity opp : [Select Id, Name, Amount FROM Opportunity    ]){
                    /* As each opportunity is processed I create a new cOpportunity object and add it to MyList */
                    MyList.add(new cOpportunity(opp,Quota,Variable_Salary));
              }
          }
        return MyList;
    }
}

 

This was selected as the best answer
jmarinchakjmarinchak
This worked like a charm.  Thanks again for all your help.  This type of help is the difference between being curious about visualforce and using it to delivery new capabilities to my sales team.
 
At Dreamforce next year, I owe you a drink!
 
Jeff
JimRaeJimRae
If I am able to go, I will take you up on that!   :smileyhappy: