You need to sign in to do that
Don't have an account?
dash27
Problem with Visualforce and Forecasts - Error: Argument 1 cannot be null
Hi all,
My goal is to create a simple report that shows several key bits of information along with a Rep's current forecast. Everything works wonderfully in my sandbox, but I am unable to successfully deploy to my production site. I'm pretty sure its because I am doing something odd in the test.
Visualforce page:
<apex:page standardController="RevenueForecast" extensions="WeeklyForecastExtension"> <apex:sectionHeader Title="Pipeline Report"/> Click on a person's name below to edit or see more details on his or her forecast. <apex:pageBlock > <apex:pageBlockTable value="{!forecastList}" var="forecast" > <apex:column headerValue="Owner" width="300"> <apex:outputLink value="https://cs13.salesforce.com/027/s?forecastUserId_lkid={!forecast.OwnerId}&mode=view" id="theLink"> {!salesRepName[forecast.OwnerId]} </apex:outputLink> </apex:column> <apex:column headerValue="{!year} YTD Sales" width="300" style="text-align:right" > <apex:outputText value="{!repSalesForYear[forecast.OwnerId]}"/> </apex:column> <apex:column headerValue="{!quarter} QTD Sales" width="300" style="text-align:right" > <apex:outputText value="{!repSalesForQuarter[forecast.OwnerId]}"/> </apex:column> <apex:column headerValue="Commit" width="300" style="text-align:right" > <apex:outputField value="{!forecast.Commit}"/> </apex:column> <apex:column headerValue="Best Case" width="300" style="text-align:right" > <apex:outputField value="{!forecast.Upside}"/> </apex:column> <apex:column headerValue="{!quarter} Pipeline" width="300" style="text-align:right"> <apex:outputField value="{!forecast.Pipeline}"/> </apex:column> <apex:column headerValue="{!Year} Pipeline" width="300" style="text-align:right"> <apex:outputText value="{!repOppsOver30[forecast.OwnerId]}"/> </apex:column> </apex:pageBlockTable> </apex:pageBlock> </apex:page>
Forecast Extension:
public class WeeklyForecastExtension { //Create containers and variables needed on Visualforce page public list<RevenueForecast> forecastList {get; set;} public list<Opportunity> allOpportunities{get; set;} public list<user> salesReps {get; set;} public map<id, string> salesRepName {get; set;} public map<id, string> repSalesForYear{get; set;} public map<id, string> repSalesForQuarter {get; set;} public map<id, string> repOppsOver30 {get; set;} public integer year {get; set;} public string quarter {get; set;} public WeeklyForecastExtension(ApexPages.StandardController controller) { //Determine date variables (Current Quarter, Year and today's date) string forecastDateString = ''; date today = date.today(); year = today.year(); boolean isQ1 = false; boolean isQ2 = false; boolean isQ3 = false; boolean isQ4 = false; if(today.month()== 1 || today.month()== 2 || today.month()== 3 ){ isQ1 = true; quarter = 'Q1'; forecastDateString = year + '-1-1'; } else if(today.month()== 4 || today.month()== 5 || today.month()== 6 ){ isQ2 =true; quarter = 'Q2'; forecastDateString = year + '-4-1'; } else if(today.month()== 7 || today.month()== 8 || today.month()== 9 ){ isQ3 =true; quarter = 'Q3'; forecastDateString = year + '-7-1'; } else if(today.month()== 10 || today.month()== 11 || today.month()== 12 ){ isQ4 =true; quarter = 'Q4'; forecastDateString = year + '-10-1'; } date forecastPeriod = date.valueOf(forecastDateString); //Collect User information into a list UserRole salesRepRole = [select id from UserRole where Name =: 'Sales']; id roleId = salesRepRole.id; salesReps = new List<user>([select FirstName, Id, LastName, isActive from User where userRoleId =: salesRepRole.id and isActive = true and ForecastEnabled = true]); //Collect all relevant forecasts into a list forecastList = new list<RevenueForecast>([select OwnerId, StartDate, Quota, Commit, Pipeline, Upside, Closed from RevenueForecast where StartDate =: forecastPeriod and OwnerId in :salesReps]); allOpportunities = new List<Opportunity>([select OwnerId, Amount, IsWon, CloseDate, Close_Year__c, ForecastCategoryName, Probability, isClosed from Opportunity where Close_Year__c =: year]); //Define maps collections salesRepName = new map<id, string>(); repSalesForYear = new map<id, string>(); repSalesForQuarter = new map<id, string>(); repOppsOver30 = new map<id, string>(); //Loop through each Sales Rep and determine his/ her name, YTD Amount, QTD Amount and ProbabilityAbove30Amount by looping through each //opportunity and adding up the relevant values. for(integer x = 0; x < salesReps.size(); x++){ //Determine the name of the sales rep string salesRepNameString = salesReps[x].FirstName + ' ' + salesReps[x].LastName; salesRepName.put(salesReps[x].id, salesRepNameString); //Set initial values. decimal ytdAmount = 0; decimal qtdAmount = 0; decimal probabilityAbove30Amount = 0; //Loop through each opportunity in the list. for(integer y = 0; y < allOpportunities.size(); y++){ if(salesReps[x].id == allOpportunities[y].OwnerId){ if(allOpportunities[y].isWon){ //If the Oppoortunity belongs to the current SalesRep and is Won, add the Opportunity's Amount to the rep's YTD AMount. ytdAmount += allOpportunities[y].Amount; //If the Oppoortunity belongs to the current SalesRep, is Won and was closed this quarter, add the Opportunity's Amount to //the rep's QTD AMount. date closeDate = allOpportunities[y].CloseDate; boolean isCurrentQuarter = false; if((closeDate.month()== 1 || closeDate.month()== 2 || closeDate.month()== 3 )&& isQ1){ qtdAmount += allOpportunities[y].Amount; } else if((closeDate.month()== 4 || closeDate.month()== 5 || closeDate.month()== 6 ) && isQ2){ qtdAmount += allOpportunities[y].Amount; } else if((closeDate.month()== 7 || closeDate.month()== 8 || closeDate.month()== 9 )&& isQ3){ qtdAmount += allOpportunities[y].Amount; } else if((closeDate.month()== 10 || closeDate.month()== 11 || closeDate.month()== 12 )&& isQ4){ qtdAmount += allOpportunities[y].Amount; } } //If the Opp is open and has a probability of >= 30%, add the Opp's Amount to the rep's probabilityAbove30Amount if(allOpportunities[y].Probability >= 30 && !allOpportunities[y].isWon && !allOpportunities[y].isClosed){ probabilityAbove30Amount += allOpportunities[y].Amount; } } } //Enter in the Rep's ID and total values into these map collections repSalesForYear.put(salesReps[x].id, Global_Variables.convertToCurrencyFormat(ytdAmount.setScale(2)) ); repSalesForQuarter.put(salesReps[x].id, Global_Variables.convertToCurrencyFormat(qtdAmount.setScale(2)) ); repOppsOver30.put(salesReps[x].id, Global_Variables.convertToCurrencyFormat(probabilityAbove30Amount.setScale(2)) ); } }//End constructor }
Test Class:
@isTest private class WeeklyForecast_Test { static testMethod void myUnitTest() { System.debug('Begining WeeklyForecast_Test'); UserRole salesRepRole = [select id from UserRole where Name =: 'Sales']; Profile p = [select id from profile where name='Standard User']; User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ]; System.runAs ( thisUser ) { //Create users for test User salesRep1 = new User(alias = 'standt', email='salesRep1@testorg.com', emailencodingkey='UTF-8', profileId = p.id, firstname = 'Sales', lastname='Rep1', languagelocalekey='en_US',localesidkey='en_US', userRoleId = salesRepRole.id, timezonesidkey='America/Los_Angeles', username='salesRep1@testorg.com', isActive = true, ForecastEnabled = true); insert salesRep1; User salesRep2 = new User(alias = 'standt', email='salesRep2@testorg.com', emailencodingkey='UTF-8', profileId = p.id, firstname = 'Sales', lastname='Rep2', languagelocalekey='en_US',localesidkey='en_US', userRoleId = salesRepRole.id, timezonesidkey='America/Los_Angeles', username='salesRep2@testorg.com', isActive = true, ForecastEnabled = true); insert salesRep2; //Create Opportunities for Test list<Opportunity> oppsToInsert = new list<Opportunity>(); Opportunity SalesRep1_Closed_Quarter = new Opportunity(name = 'SalesRep1_Closed_Quarter', StageName = '100% - Closed Won', OwnerId = salesRep1.id, CloseDate = date.valueOf('2012-4-15'), Amount = 100); oppsToInsert.add(SalesRep1_Closed_Quarter); Opportunity SalesRep1_Closed_Year = new Opportunity(name = 'SalesRep1_Closed_Year', StageName = '100% - Closed Won', OwnerId = salesRep1.id, CloseDate = date.valueOf('2012-1-15'), Amount = 300); oppsToInsert.add(SalesRep1_Closed_Year); Opportunity SalesRep1_Under30 = new Opportunity(name = 'SalesRep1_Under30', StageName = '20% - Conference / E-Lead', OwnerId = salesRep1.id, CloseDate = date.valueOf('2012-6-15'), Amount = 20); oppsToInsert.add(SalesRep1_Under30); Opportunity SalesRep1_30 = new Opportunity(name = 'SalesRep1_30', StageName = '30% - Appt Set', OwnerId = salesRep1.id, CloseDate = date.valueOf('2012-4-25'), Amount = 30); oppsToInsert.add(SalesRep1_30); Opportunity SalesRep1_Best = new Opportunity(name = 'SalesRep1_Best', StageName = '50% - Renewal', OwnerId = salesRep1.id, CloseDate = date.valueOf('2012-5-5'), Amount = 500); oppsToInsert.add(SalesRep1_Best); Opportunity SalesRep1_Commit = new Opportunity(name = 'SalesRep1_Commit', StageName = '80% - PO in Process', OwnerId = salesRep1.id, CloseDate = date.valueOf('2012-5-15'), Amount = 500); oppsToInsert.add(SalesRep1_Commit); insert oppsToInsert; //Calculate Totals decimal rep1YearTotal = SalesRep1_Closed_Quarter.Amount + SalesRep1_Closed_Year.Amount; decimal rep1QuarterTotal = SalesRep1_Closed_Quarter.Amount; decimal rep1Commit = SalesRep1_Closed_Quarter.Amount + SalesRep1_Commit.Amount; decimal rep1Best = SalesRep1_Closed_Quarter.Amount + SalesRep1_Commit.Amount + SalesRep1_Best.Amount; decimal rep1Pipeline = SalesRep1_Commit.Amount + SalesRep1_Best.Amount; decimal rep1Closed = SalesRep1_Closed_Quarter.Amount; decimal rep1Over30 = SalesRep1_30.Amount + SalesRep1_Commit.Amount + SalesRep1_Best.Amount; RevenueForecast rep1Forecast = new RevenueForecast(OwnerId = salesRep1.id, StartDate = date.valueOf('2012-4-1'), Quota = 0); insert rep1Forecast; //Initialize variables PageReference pref = Page.WeeklyForecast; Test.setCurrentPage(pref); ApexPages.StandardController con = new ApexPages.StandardController(rep1Forecast); WeeklyForecastExtension ext = new WeeklyForecastExtension(con); /***************************** /* Start Test /*****************************/ Test.startTest(); //Clone Map container from extension map<id, string> test_salesRepName = new map<id,String>(); test_salesRepName = ext.salesRepName.clone(); String string_rep1Name = test_salesRepName.get(salesRep1.id); //Verify values are as expected. system.assertEquals(string_rep1Name, 'Sales Rep1'); //Clone Map container from extension map<id, string> test_repSalesForYear = new map<id,String>(); test_repSalesForYear = ext.repSalesForYear.clone(); String string_repSalesForYear = test_repSalesForYear.get(salesRep1.id); //Verify values are as expected. system.assertEquals(string_repSalesForYear, Global_Variables.convertToCurrencyFormat(rep1YearTotal.setScale(2))); //Clone Map container from extension map<id, string> test_repSalesForQuarter = new map<id,String>(); test_repSalesForQuarter = ext.repSalesForQuarter.clone(); String string_repSalesForQuarter = test_repSalesForQuarter.get(salesRep1.id); //Verify values are as expected. system.assertEquals(string_repSalesForQuarter, Global_Variables.convertToCurrencyFormat(rep1QuarterTotal.setScale(2))); //Clone Map container from extension map<id, string> test_repOppsOver30 = new map<id,String>(); test_repOppsOver30 = ext.repOppsOver30.clone(); String string_repOver30 = test_repOppsOver30.get(salesRep1.id); //Verify values are as expected. system.assertEquals(string_repOver30, Global_Variables.convertToCurrencyFormat(rep1Over30.setScale(2))); } } }
The page should not require a parameter and therefore I'm not sure what to put in when defining the Controller.
Any help is greatly appreciated.
I figured it out. The issue I was having was that I was including Opportunities that had null for the Amount value. Once i filtered these Opportunities out, everything worked GREAT!