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
HARSHIL U PARIKHHARSHIL U PARIKH 

Question on Working Trigger: Since Ids are not available in Before Trigger, then why it works inside the SOQL

Hello Developers!

I have this trigger on opportunity which allows only $500 opportunity amount per day per user. Now Trigger seem to be working fine. But however, I have a question.
Since the upcoming record's Id is not availble in Trigger.New then why is it works at line 18? Wouldn't the opp.Id is null at that line?
Trigger FiveHundred_Dollars_Opp_Amount_Limit on Opportunity(Before Insert, Before Update, After UnDelete){
     
     If(Trigger.IsInsert || Trigger.IsUpdate || Trigger.IsUnDelete){
         
         For(Opportunity opp : Trigger.New){
             
             If(Opp.Amount > 500){
                 Opp.addError('Opportunitys Amount Can not be greater than $500 per day.');
             }
             else If(Opp.Amount == null){
                 // Let it go.
             }
             
             else If(opp.Amount != null){
                 
                 List<Opportunity> FetchingCurrentUsersTodaysOpps = [Select Id, Amount
                                                                             FROM Opportunity
                                                                                 WHERE Id != :Opp.Id
                                                                                 AND   CreatedDate = Today
                                                                                 AND   Amount != null
                                                                                 AND   OwnerId =:Opp.OwnerId];
                 Double SummingAmount = Opp.Amount;
                 If(!FetchingCurrentUsersTodaysOpps.IsEmpty()){
                     
                     For(Opportunity EveryOpp : FetchingCurrentUsersTodaysOpps){
                         SummingAmount += EveryOpp.Amount;
                     }
                 If(SummingAmount > 500){
                     Opp.addError('You have reached the miximum limit of $500 opportunity Amount Per Day.');
                 }
                 }
             }
         }
     }
}

Thank You!
Best Answer chosen by HARSHIL U PARIKH
Mohit Sharma 37Mohit Sharma 37
Hi Govind,

Your query means:

List<Opportunity> FetchingCurrentUsersTodaysOpps = [Select Id, Amount
                                                                                 FROM Opportunity
                                                                                 WHERE Id != :Opp.Id
                                                                                 AND   CreatedDate = Today
                                                                                 AND   Amount != null
                                                                                 AND   OwnerId=:Opp.OwnerId];

ON BEFORE INSERT
There will be a null id in Opp.Id
System.debug('--- Opp.Id: ' + Opp.Id);
OUPUT: --- Opp.Id: null

There will be a user id
System.debug('--- Opp.OwnerId: ' + Opp.OwnerId);
OUPUT: --- Opp.OwnerId: 00590000001tohzAAA

So the means is:
Select fields from that opprotunities which ids are not equals to null and created date is equals to today and Amount is not equals to null and owner id is equals to the new opp owner id.

So your query is working because it find the existing data of this owner in system...

ON BEFORE UPDATE AND AFTER UNDELETE
 You will find the record id
--- Opp.Id: 0069000000eW7bl
--- Opp.OwnerId: 00590000001tohzAAA

Thanks

All Answers

Nithesh NNithesh N
Now I am Curious as well....
jigarshahjigarshah
@Govind Guru. You are correct that since the Salesforce Record Id is generated only after a record, is saved and committed to the object. However, as per your code the trigger runs on both Before and After Events for Insert, Update as well as Undelete operations. This happens because the code does not provide any clear demarcation of which before and after dml events the code should execute for.

If you check the debug log, by putting a System.debug() at line # 2 you should see it being printed twice due to the trigger executing twice - once for before and once for after event of a specific dml operation (I assume that ther is no situation causing recursive execution of you triggers)

You need to modify your code to add a check for the before and after context variables as follows so that your code only executes on the specific 3 events that you intend to.
 
Trigger FiveHundred_Dollars_Opp_Amount_Limit on Opportunity(Before Insert, Before Update, After UnDelete){
     
	 //This context variable check was missing and is required
	 If((Trigger.IsBefore && (Trigger.IsInsert || Trigger.IsUpdate)) || (Trigger.IsAfter && Trigger.IsUndelete)){
	 
			For(Opportunity opp : Trigger.New){
             
				 If(Opp.Amount > 500){
					 Opp.addError('Opportunitys Amount Can not be greater than $500 per day.');
				 }
				 else If(Opp.Amount == null){
					 // Let it go.
				 }
				 else If(opp.Amount != null){
					 
					 List<Opportunity> FetchingCurrentUsersTodaysOpps = [Select Id, Amount
																				 FROM Opportunity
																					 WHERE Id != :Opp.Id
																					 AND   CreatedDate = Today
																					 AND   Amount != null
																					 AND   OwnerId =:Opp.OwnerId];
					 Double SummingAmount = Opp.Amount;
					 If(!FetchingCurrentUsersTodaysOpps.IsEmpty()){
						 
						 For(Opportunity EveryOpp : FetchingCurrentUsersTodaysOpps){
							 SummingAmount += EveryOpp.Amount;
						 }
						 If(SummingAmount > 500){
							 Opp.addError('You have reached the miximum limit of $500 opportunity Amount Per Day.');
						 }
					 }
				 }
         }
	 }
}
Additionally you could optimize your logic for checking the Opportunity Amount as follows
 
If(Opp.Amount != null){     
  If(Opp.Amount > 500){         
	Opp.addError('Opportunitys Amount Can not be greater than $500 per day.');     
  }     
  Else{
    //Logic to fetch the total Opportunity Amount summation and display an error message if it is greater than $500     
  } 
}

Please mark this as the best answer if it helps you resolve the issue.

 
Malni Chandrasekaran 2Malni Chandrasekaran 2
Govind,
Your query works perfectly fine, because its purpose is to exlude the current record (Trigger.new) but to retrieve the other records created for the same owner on the same day.
In Before Insert, the id will be null and hence it will return all the other records created for that owner on that same day.

the code in line 22 Double SummingAmount = Opp.Amount; -  adds the new amount to the sum.

Similarly in before update, the old amount is excluded by that query.

Please mark it as solved if this answer helps
Mohit Sharma 37Mohit Sharma 37
Hi Govind,

Your query means:

List<Opportunity> FetchingCurrentUsersTodaysOpps = [Select Id, Amount
                                                                                 FROM Opportunity
                                                                                 WHERE Id != :Opp.Id
                                                                                 AND   CreatedDate = Today
                                                                                 AND   Amount != null
                                                                                 AND   OwnerId=:Opp.OwnerId];

ON BEFORE INSERT
There will be a null id in Opp.Id
System.debug('--- Opp.Id: ' + Opp.Id);
OUPUT: --- Opp.Id: null

There will be a user id
System.debug('--- Opp.OwnerId: ' + Opp.OwnerId);
OUPUT: --- Opp.OwnerId: 00590000001tohzAAA

So the means is:
Select fields from that opprotunities which ids are not equals to null and created date is equals to today and Amount is not equals to null and owner id is equals to the new opp owner id.

So your query is working because it find the existing data of this owner in system...

ON BEFORE UPDATE AND AFTER UNDELETE
 You will find the record id
--- Opp.Id: 0069000000eW7bl
--- Opp.OwnerId: 00590000001tohzAAA

Thanks
This was selected as the best answer
SAURABH RASTOGI 13SAURABH RASTOGI 13

Hi Mohit,

Really good explanation, It's help me a lot ...........    

HARSHIL U PARIKHHARSHIL U PARIKH
Thank you all for the explanation!