You need to sign in to do that
Don't have an account?
Trigger help System.NullPointerException Attempt to de-reference a null object
Help please.....
I am new to coding in general so please go easy on me. I got some help with my code but can't seem to figure out why I am getting a "System.NullPointerException: Attempt to de-reference a null object" error from my trigger every time I save. Here is the scenario:
Basically do screenings and we record Total_cash__c, Total_charges__c, and Total_checks__c collected on our opportunities. We needed a way to link each opportunity to a custom object Deposit__c and be able to sum each related field on the Deposit__c. There will never be more than 10 opportunities attached to one Deposit via lookup. Because I cannot create a master-detail with an opportunity to run a roll-up I need to do it with a trigger on an opportunity with a lookup field to the Deposit custom object. My code compiles but gives me the de-reference a null object error and I can figure out why.
The error starts here. Am I doing something wrong in the way I am accessing and trying to set the value of the fields of Sum_of_Cash__c, Sum_of_Checks, Sum_of_Charges ??The fields are created on the Deposit__c custom object and of the same type on the related opportunity.
thisDeposit.Sum_of_Cash__c = totalSumCash;
trigger DepositRollup on Opportunity (after insert, after update) {
//instantiate opportunity
Opportunity thisScreening = Trigger.New[0];
// retrieve from the DB all of the opportunities related to the current related deposit
List<Opportunity> screenings = [SELECT Deposited__r.Name, Total_cash__c, Total_checks__c, Total_charges__c
FROM Opportunity WHERE Deposited__c =: thisScreening.Deposited__c];
//instantiate this related deposit
Deposit__c thisDeposit = thisScreening.Deposited__r;
// init variables for sum
double totalSumCash = 0, totalSumChecks = 0, totalSumCharges = 0;
//iterate through each opportunity in this list, calculate the sum on the deposit
for(Opportunity o :screenings){
totalSumCash += o.Total_Cash__c;
totalSumCharges += o.Total_Charges__c;
totalSumChecks += o.Total_Checks__c;
}
thisDeposit.Sum_of_Cash__c = totalSumCash;
thisDeposit.Sum_of_Checks__c = totalSumCash;
thisDeposit.Sum_of_Credit__c = totalSumCash;
// update the related deposit record in the DB
update thisDeposit;
}
Thanks for helping anyone who tackles this
Hi,
the variable thisScreening.Deposit__r will be null. Set 'thisDeposit' to be screenings[0].Deposit__r
(you may want to to a null check on the 'screenings' List, too!)
HTH, IanR
All Answers
Hi,
the variable thisScreening.Deposit__r will be null. Set 'thisDeposit' to be screenings[0].Deposit__r
(you may want to to a null check on the 'screenings' List, too!)
HTH, IanR
The solution worked and I have been writing a test class to get coverage on the trigger but I am having trouble getting past the 11%. Again I am a beginner so I could use a little direction. I'm still a little fuzzy on test coverage. To get a good test scenario I am going to do the following. Create 1 opportunity, 1 deposit, one account, link them and insert them to fire my trigger then do a system.assertEquals to test the result. Then I want to do it with 15 Opportunities. This is what I have so far.
My trigger is
-------------------------------
trigger DepositRollup on Opportunity (after insert, after update,after delete) {
//instantiate opportunity
Opportunity thisScreening = Trigger.New[0];
// retrieve from the DB all of the opportunities related to the current related deposit
if (thisScreening.Deposited__c != null){
List<Opportunity> screenings = [SELECT Deposited__r.Name, Total_Collected__c, Total_cash__c, Total_checks__c, Total_charges__c
FROM Opportunity WHERE Deposited__c =: thisScreening.Deposited__c];
//instantiate this related deposit
Deposit__c thisDeposit = screenings[0].Deposited__r;
double totalSumCash = 0, totalSumChecks = 0, totalSumCharges = 0, totalSumSales = 0;
//iterate through each opportunity in this list, calculate the sum on the deposit
for(Opportunity o :screenings){
totalSumCash += o.Total_Cash__c;
totalSumCharges += o.Total_Charges__c;
totalSumChecks += o.Total_Checks__c;
totalSumSales += o.Total_Collected__c;
}
thisDeposit.Sum_of_Cash__c = totalSumCash;
thisDeposit.Sum_of_Checks__c = totalSumChecks;
thisDeposit.Sum_of_Credit__c = totalSumCharges;
thisDeposit.Sum_of_Sales__c = totalSumSales;
// update the related deposit record in the DB
update thisDeposit;
}
}
--------------------------------------------------------------------
@istest
private class DepositTestClass {
//create account
static testMethod void TestDepositRUTrigger(){
Account acct = new Account(name='Test Account');
insert acct;
//create deposit with name and todays date
Deposit__c dep = new Deposit__c();
dep.Name_of_Deposit__c = 'Deposit 2';
dep.Deposit_Date__c = System.Today();
insert dep;
//insert a single opportunity
Opportunity[] createopps = new Opportunity[]{};
double SumCashResult =0;
Opportunity sop = new Opportunity(AccountId=acct.Id,Deposited__c=dep.Name,
Name='screening',CloseDate=System.today(),Scout__Sales_Order_Number__c ='1199556',
Total_cash__c=10, Total_checks__c=20, Total_Charges__c=30, StageName='Event Occurred', RecordTypeID='012700000001THf');
createopps.add(sop);
//insert opportunity to fire the trigger
insert createopps;
//Run query to grab a field from the deposit affected by the trigger linked to the opportunity and check
for(Opportunity ch: [SELECT Deposited__r.Name,Deposited__r.Sum_of_Cash__c FROM Opportunity where Deposited__r.Name ='deposit 2']){
SumCashResult = ch.Deposited__r.Sum_of_cash__c;
}
System.assertEquals(10, SumCashResult);
}
}
I am going to use a for loop for the 15 opportunities but want to do it with one first. Once I run the tests it tells me I need coverage on the screenings list but I don't understand why my system.assertEquals isn't covering it. I still need coverage on the rest but can anyone help me from here?
Thanks