1

I need to make discount depends from Registration date (i.e. 3% discount to Opportunity when Accoun registered 1-2 years ago). Sample of code:

 for (Opportunity opp : TriggeredOpps){
        If (Account.Registration_Date__c != null){
            Date todayDate = Date.today();
            Date RegDay = opp.Account.Registration_Date__c;
            Integer numberOfDays = RegDay.daysBetween(todayDate);
            if(numberOfDays >= 365 || numberOfDays < 730 ){
                for (Discount__mdt disc : DiscountRecords){
                    if(disc.Years_Sinse_Reg__c == 1){
                        opp.Amount = opp.Amount - (opp.Amount*(disc.Discount__c / 100));
                    }
                }
            }
        }   
    }

but part Integer numberOfDays = RegDay.daysBetween(todayDate) doesn't work. Can somebody help with what is wrong here?

During manual testing

System.NullPointerException: Attempt to de-reference a null object Class.OpportunityTriggerHandler.DiscountOpportunityRegDay: line 48, column 1

line 48 - it's exactly Integer numberOfDays = RegDay.daysBetween(todayDate)

2
  • what exactly problem are you facing ? some exceptions during code execution? Jun 4, 2021 at 10:13
  • During manual testing "System.NullPointerException: Attempt to de-reference a null object Class.OpportunityTriggerHandler.DiscountOpportunityRegDay: line 48, column 1" - line 48 - it's exactly Integer numberOfDays = RegDay.daysBetween(todayDate) Jun 4, 2021 at 10:46

2 Answers 2

3

I can make an assumption, that you are calling this code from the Opportunity trigger. That means opportunity fields of the trigger context records will be accessible e.g.

for (Opportunity opp : TriggeredOpps){
    System.debug(opp.Amount); // will be accessible
....

However, if you want to access parent fields, you need explicitly to query them. In this example, in the trigger context field, opp.Account.Registration_Date__c is not populated. You need to query it. That is why you do have NullPointerException.

Also, you have a wrong checking for null in if condition.

if (Account.Registration_Date__c != null){

this checks, if sobjectfield is not null. (and of cause it is not null)

that should be:

if (opp.Account.Registration_Date__c != null){

In general you code should be like:

// collect parent `AccountId`s
Set<Id> accountIdsSet = new Set<Id>();
for (Opportunity opp : TriggeredOpps){
    accountIdsSet.add(opp.AccountId);
}
accountIdsSet.remove(null);

//explicitly querieng parent accounts to get account field values
Map<Id, Account> parentAccountsMap = new Map<Id, Account>([
    SELECT Id, Registration_Date__c
    FROM Account
    WHERE Id IN :accountIdsSet
]);

for (Opportunity opp : TriggeredOpps){
    Account parentAccount = parentAccountsMap.get(opp.AccountId);
    If (parentAccount.Registration_Date__c != null){
        Date todayDate = Date.today();
        Date RegDay = parentAccount.Registration_Date__c;
        Integer numberOfDays = RegDay.daysBetween(todayDate);
        if(numberOfDays >= 365 || numberOfDays < 730 ){
            for (Discount__mdt disc : DiscountRecords){
                if(disc.Years_Sinse_Reg__c == 1){
                    opp.Amount = opp.Amount - (opp.Amount*(disc.Discount__c / 100));
                }
            }
        }
    }   
}
2
  • Great! I'm a newbie and your detailed answer helped me a lot! Thanks Oleksandr! Jun 4, 2021 at 11:15
  • @IvanSholok We all were newbies one day. Happy to help Jun 4, 2021 at 11:18
0

If RegDay was in the past, then

Integer numberOfDays = RegDay.daysBetween(todayDate);

will result in a negative number.

You would probably want to try:

Integer numberOfDays = todaysDate.daysBetween(RegDay);

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .