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
imaliveagainimaliveagain 

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 
Best Answer chosen by Admin (Salesforce Developers) 
IanRIanR

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

IanRIanR

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

 

 

 

 

This was selected as the best answer
imaliveagainimaliveagain

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