You need to sign in to do that
Don't have an account?
RossG
attempt to de-reference a null object error
I'm getting this error. Ususally I can resolve it but I can't seem to on this one.
This is a visualforce page with custom controller that is basically a custom product picker on opportunity object. The error I get when trying to add a product to the opp is:
Attempt to de-reference a null object
Error is in expression '{!modifyRecord}' in page manage_products: Class.ManageProductsController.modifyRecord: line 324, column 1
Does anyone see anything in this code below that could be causing the error?
This is a visualforce page with custom controller that is basically a custom product picker on opportunity object. The error I get when trying to add a product to the opp is:
Attempt to de-reference a null object
Error is in expression '{!modifyRecord}' in page manage_products: Class.ManageProductsController.modifyRecord: line 324, column 1
Does anyone see anything in this code below that could be causing the error?
public class ManageProductsController { /* Controller for "Manage Products" Visualforce Page, aka the "product picker" */ // Declare static variables private static final Map<String,String> PRODUCT_FILTER_VALUES_MAP; private static final Set<String> COREBLOX_PRODUCT_CODES = new Set<String>{'CBWK-H-PUL','PE-CS-CBWS'}; private static final Set<String> VALID_CHOICES_SET = new Set<String>{ 'CIC','CK','SC','TT' }; private static final Set<Id> ADMIN_PROFILE_ID_SET; // Which profiles can use product picker to edit won Opps private static final string PICKLIST_DEFAULT = 'All'; //defailt picklist value // Declare public class variables public Boolean editAfterClosed { get { return (editAfterClosed == null) ? false : editAfterClosed; } set; } public Boolean showAddProductsPanel { get { return (showAddProductsPanel == null) ? false : showAddProductsPanel; } set; } public String action { get; set; } public String productFilter { get; set; } public String useCase { get; set; } public String capability { get; set; } public String license { get; set; } public String upToQuantity { get; set; } public Id currentOliId { get; set; } public Opportunity currentOpp { get; set; } public List<OpportunityLineItem> oliExistingList { get; set; } public List<OpportunityLineItem> oliPickerList { get; set; } public List<PricebookEntry> pbeListActive { get; set; } public List<SelectOption> productFilterValues { get; set; } public Map<Id,Decimal> pbeCalculableSupportProductMap { get; set; } public Map<Id,String> pbeProductCodeMap { get; set; } public Map<Id,String> pbeProductNameMap { get; set; } public Map<Id,OpportunityLineItem> oliDetailsMap { get; set; } // Declare private class variables private ApexPages.StandardController stdController; private List<OpportunityLineItem> oliNewList = new List<OpportunityLineItem>(); private List<PricebookEntry> pbeListAll = new List<PricebookEntry>(); private Map<Id,PricebookEntry> pbeDetailsMapAll = new Map<Id,PricebookEntry>(); private Map<Id,PricebookEntry> pbeDetailsMapActive = new Map<Id,PricebookEntry>(); // Instantiate static variables static { ADMIN_PROFILE_ID_SET = new Set<Id>{ '00e40000000rTp1', // Custom Contract Admin '00e30000000bzB3' // System Administrator }; PRODUCT_FILTER_VALUES_MAP = new Map<String,String>{ 'All' => 'All', 'Bundles' => 'CB', 'Cloud Identity Connector' => 'CIC', 'Commercial Integration Kit' => 'CK', 'Connection Based' => 'CONN', 'CoreBlox' => 'CoreBlox', 'Discount' => 'Cust', 'ELA' => 'ELA', 'Endpoint' => 'EP', 'Oauth Add-on' => 'OAA', 'Oauth Standalone' => 'OAS', 'PingAccess' => 'PA', 'PingConnect' => 'PC', 'PingEnable Consulting' => 'PE', 'PingFed Server' => 'PFS', 'PingOne' => 'PO', 'PingEnable Training' => 'PT', 'Saas Program Bundle' => 'Saas', 'SaaS Connector' => 'SC', 'STS Add-on' => 'SSA', 'STS Standalone' => 'SSS', 'Support' => 'SUP', 'Token Translator' => 'TT', 'WAM Integration Kit' => 'WMIK', 'WAM Token Translator' => 'WMTT' }; } /* Constructor */ public ManageProductsController(ApexPages.StandardController stdController) { // Instantiate class variables this.stdController = stdController; currentOpp = (Opportunity)stdController.getRecord(); editAfterClosed = false; // Default value if (ADMIN_PROFILE_ID_SET.contains(UserInfo.getProfileId())) { editAfterClosed = true; } productFilterValues = new List<SelectOption>(); for (String s : PRODUCT_FILTER_VALUES_MAP.keySet()) { productFilterValues.add(new SelectOption(PRODUCT_FILTER_VALUES_MAP.get(s),s)); } productFilterValues.sort(); oliDetailsMap = new Map<Id,OpportunityLineItem>(); oliExistingList = new List<OpportunityLineItem>(); oliPickerList = new List<OpportunityLineItem>(); pbeListActive = new List<PricebookEntry>(); pbeCalculableSupportProductMap = new Map<Id,Decimal>(); pbeProductCodeMap = new Map<Id,String>(); pbeProductNameMap = new Map<Id,String>(); refreshData(); } /* STATIC METHODS */ /* Return set of Product Code values under 'CoreBlox' category in picker filter */ public static Set<String> getCoreBloxProductCodes(){ return COREBLOX_PRODUCT_CODES; } /** * Method returns a list of Product Use Case values as select options. * * @return a list of notes as select options */ public List<SelectOption> getUseCaseOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.Use_Case__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /** * Method returns a list of Product Capability values as select options. * * @return a list of notes as select options */ public List<SelectOption> getCapabilityOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.Capability__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /** * Method returns a list of Product License values as select options. * * @return a list of notes as select options */ public List<SelectOption> getLicenseOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.License__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /** * Method returns a list of Product Up_to_Quantity values as select options. * * @return a list of notes as select options */ public List<SelectOption> getUpToQuantityOptions() { List<SelectOption> options = new List<SelectOption>(); // Use schema describe functionality to generate list of options Schema.DescribeFieldResult fieldResult = Product2.Up_to_Quantity__c.getDescribe(); options.add(new SelectOption(PICKLIST_DEFAULT,PICKLIST_DEFAULT));//add defailt value to picklist List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues(); for(Schema.PicklistEntry f : ple) { options.add(new SelectOption(f.getLabel(), f.getValue())); } return options; } /* CLASS METHODS */ /* Add new product line items to Opportunity */ public void addProducts() { // Declare method variables PricebookEntry pbe; // Prepare selected items for insertion for (OpportunityLineItem oli : oliPickerList) { if (oli.Selected__c) { // Reset record-level variables pbe = pbeDetailsMapActive.get(oli.PricebookEntryId); // Set "Discount" to default value of 0 unless list price is 0 (in which case no discount could be applied) // Since record has not yet been inserted, cannot leverage formula field and must use map instead if (pbeDetailsMapActive.get(oli.PricebookEntryId).UnitPrice != 0 && oli.Discount__c == null) { oli.Discount__c = 0; } oli.Selected__c = FALSE; // Perform additional processing if (pbe.Product2.Calculate_Support_Pricing__c == 0) { // Set "Full Description" oli.Full_Description__c = ''; if (pbe.Product2.Price_Book_Group__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Group__c; } if (pbe.Product2.Price_Book_Type__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Type__c; } if (pbe.Product2.Price_Book_Environment__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Environment__c; } if (pbe.Product2.Price_Book_License__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_License__c; } if (pbe.Product2.Price_Book_Service__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Service__c; } if (pbe.Product2.Price_Book_Term__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Term__c; } if (pbe.Product2.Price_Book_Detailed_Description__c != null) { oli.Full_Description__c += ' - ' + pbe.Product2.Price_Book_Detailed_Description__c; } // Set various fields related to the "Choices" field if (oli.Choices__c == 'CIC') { oli.Cloud_Identity_Connectors__c = oli.Connector_Choice__c; } else if (oli.Choices__c == 'CK') { oli.Commercial_Integration_Kit__c = oli.Connector_Choice__c; } else if (oli.Choices__c == 'SC') { oli.SaaS_Connectors__c = oli.Connector_Choice__c; } else if (oli.Choices__c == 'TT') { oli.Commercial_Translators__c = oli.Connector_Choice__c; } } oliNewList.add(oli); } } // Insert new line items if (!oliNewList.isEmpty()) { try { // Insert new line items insert oliNewList; hideAddProductsPanel(); refreshData(); updateCalculatedSupportProducts(); } catch (DMLException e) { ApexPages.addMessages(e); } oliNewList.clear(); } } /* Redirect user to pricebook selection page if pricebook is not yet selected */ public PageReference displayAppropriatePage() { // Declare method variables PageReference pageRef = null; // Perform redirection as appropriate if (currentOpp.Pricebook2Id == null && currentOpp.OpportunityLineItems.isEmpty()) { pageRef = new PageReference( '/oppitm/choosepricebook.jsp?id=' + currentOpp.Id + '&cancelURL=' + currentOpp.Id + '&saveURL=/apex/Manage_Products?id=' + currentOpp.Id ); pageRef.setRedirect(true); } return pageRef; } /* Disable rendering of add products panel and refresh data */ public PageReference hideAddProductsPanel() { showAddProductsPanel = false; return null; } /* Update or delete existing products */ public void modifyRecord() { // Declare method variables OpportunityLineItem currentOli; Pricebookentry pbe; refreshAddProductsTableData(); // Instantiate method variables currentOli = oliDetailsMap.get(currentOliId); pbe = pbeDetailsMapAll.get(currentOli.PricebookEntryId); // Perform update or delete try { if (action == 'update') { update currentOli; } else if (action == 'delete') { delete currentOli; } refreshData(); if (pbe.Product2.Calculate_Support_Pricing__c == 0) { updateCalculatedSupportProducts(); } } catch (DMLException e) { ApexPages.addMessages(e); } } /* Respond to user clicking on "Filter by Product Code:" dropdown in add products table */ public void refreshAddProductsTableData() { // Declare method variables String choices; String oppCurrency = currentOpp.CurrencyISOCode; String productCodeRoot; String productFilterSearchString = productFilter + '%'; String queryStr; Id pricebookId = currentOpp.Pricebook2Id; // Reset relevant class collections oliPickerList.clear(); pbeListActive.clear(); pbeListAll.clear(); pbeCalculableSupportProductMap.clear(); pbeProductCodeMap.clear(); pbeProductNameMap.clear(); // Build query queryStr = 'SELECT '; queryStr += 'Id, '; queryStr += 'IsActive, '; queryStr += 'Name, '; queryStr += 'ProductCode, '; queryStr += 'Product2Id, '; queryStr += 'Product2.Calculate_Support_Pricing__c, '; queryStr += 'Product2.Default_Support_Percentage__c, '; queryStr += 'Product2.Description, '; queryStr += 'Product2.Price_Book_Detailed_Description__c, '; queryStr += 'Product2.Price_Book_Environment__c, '; queryStr += 'Product2.Price_Book_Group__c, '; queryStr += 'Product2.Price_Book_License__c, '; queryStr += 'Product2.Price_Book_Service__c, '; queryStr += 'Product2.Price_Book_Term__c, '; queryStr += 'Product2.Price_Book_Type__c, '; queryStr += 'Product2.ProductCode, '; queryStr += 'UnitPrice '; queryStr += 'FROM PricebookEntry '; queryStr += 'WHERE Pricebook2Id = :pricebookId '; queryStr += 'AND CurrencyISOCode = :oppCurrency '; if (productFilter != 'All') { if (productFilter == 'CoreBlox') { queryStr += 'AND ProductCode IN :COREBLOX_PRODUCT_CODES '; } else { queryStr += 'AND ProductCode LIKE :productFilterSearchString '; } } if (useCase != 'All'){ queryStr += 'AND Product2.Use_Case__c = :useCase '; } if (capability != 'All'){ queryStr += 'AND Product2.Capability__c = :capability '; } if (license != 'All'){ queryStr += 'AND Product2.License__c = :license '; } if (upToQuantity != 'All'){ queryStr += 'AND Product2.Up_to_Quantity__c = :upToQuantity '; } queryStr += 'ORDER BY Name '; // Retrieve records and refill collections pbeListAll.addAll((List<PricebookEntry>)Database.query(queryStr)); for (PricebookEntry pbe : pbeListAll) { pbeDetailsMapAll.put(pbe.Id,pbe); if (pbe.IsActive) { // Reset record-level variables choices = null; productCodeRoot = pbe.ProductCode.left(pbe.ProductCode.indexOf('-')); // Fill collections pbeListActive.add(pbe); pbeDetailsMapActive.put(pbe.Id,pbe); pbeCalculableSupportProductMap.put(pbe.Id,pbe.Product2.Calculate_Support_Pricing__c); pbeProductCodeMap.put(pbe.Id, pbe.ProductCode); pbeProductNameMap.put(pbe.Id, pbe.Name); //Determine "Choices" variable if (VALID_CHOICES_SET.contains(productCodeRoot)) { choices = productCodeRoot; } oliPickerList.add(new OpportunityLineItem( Choices__c = choices, OpportunityId = currentOpp.Id, PricebookEntryId = pbe.Id, Quantity = 1, // Default value Support__c = pbe.Product2.Default_Support_Percentage__c, UnitPrice = pbe.UnitPrice )); } } } /* Query data and update variables */ public void refreshData() { // Reset variables to default values productFilter = 'All'; showAddProductsPanel = false; // Refresh Opportunity data currentOpp = [ SELECT Id, Amount, CurrencyIsoCode, IsClosed, Name, Owner.Name, Pricebook2Id, StageName, ( SELECT Id, Choices__c, Connector_Choice__c, Discount__c, Full_Description__c, ListPrice, PricebookEntryId, PricebookEntry.Product2.Calculate_Support_Pricing__c, PricebookEntry.Product2.ProductCode, PricebookEntry.Product2.Name, Quantity, Selected__c, Support__c, Support_Basis__c, Term_End_Date__c, Term_Start_Date__c, TotalPrice, UnitPrice // "Sales Price" FROM OpportunityLineItems WHERE IsDeleted = FALSE ORDER BY SortOrder ) FROM Opportunity WHERE Id = :currentOpp.Id ]; // Clear collections oliExistingList.clear(); oliDetailsMap.clear(); // Refill collections oliExistingList.addAll(currentOpp.OpportunityLineItems); for (OpportunityLineItem oli : oliExistingList) { oliDetailsMap.put(oli.Id,oli); } } /* Enable rendering of add products panel */ public PageReference showAddProductsPanel() { refreshAddProductsTableData(); showAddProductsPanel = true; return null; } /* Evaluate all line items on the Opportunity that require support, sum their total price together, * and from there calculate the default pricing for any calculable support products (such as Support * Gold) on the Opp. */ private void updateCalculatedSupportProducts() { // Declare method variables Decimal supportBasis = 0; String supportDescription = ''; PricebookEntry pbe; List<OpportunityLineItem> oliList = new List<OpportunityLineItem>(); for (OpportunityLineItem oli : oliExistingList) { // Reset record-level variables pbe = pbeDetailsMapAll.get(oli.PricebookEntryId); // Aggregate non-support line item data if (pbe.Product2.Calculate_Support_Pricing__c == 0) { if (pbe.Product2.Price_Book_License__c != null && pbe.Product2.Price_Book_License__c.toLowerCase().contains('perpetual') ) { supportBasis += oli.Quantity * oli.UnitPrice; if (supportDescription != '') { supportDescription += ', '; } supportDescription += pbe.Product2.ProductCode; } // Tag as a support line item } else { // pbe.Product2.Calculate_Support_Pricing__c != 0 // oliList.add(oli); } } if (!oliList.isEmpty()) { // Perform processing on support line items for (OpportunityLineItem oli : oliList) { // Reset record-level variables pbe = pbeDetailsMapAll.get(oli.PricebookEntryId); // Set price and description oli.UnitPrice = supportBasis * oli.Support__c / 100; oli.Full_Description__c = supportDescription; oli.Support_Basis__c = supportBasis; } // Perform DML // update oliList; refreshData(); } } }
Initiate the object at Line#307 and try
Pricebookentry pbe = new Pricebookentry ();
Important :
If this is what you were looking for then please mark it as a "SOLUTION" or You can Click on the "Like" Button if this was beneficial for you.
I am not sure about this relationship pbe.Product2 but you can add not null check on Line#324.
like if(pbe != Null && pbe.Product2 != Null.......)