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
Forrest MulduneForrest Muldune 

Apex Sum on Opportunities

All,

I need some help with some Apex coding since I am a beginner and I appreciate all help. I have tried to modfiy the coding completed by another developer but it is not working.

below are the object and fields that will be involved with the trigger

Object
Opportunities

Field 
Engagement_Total_Fees__c  (Currency(16, 2) - label name Engagement

Custom Object
Matter__c

Fields
Total_Fees__c    (Currency(16, 2) 
Deal__c  Lookup(Opportunity) 

Schema below - Lookup relationship from Matters__c (object label Engagement)
User-added image

Request.

When a  record is updated, created, or deleted in the Total_Fees__c field in Matter__c object, I want a total sum in Total_Fees__c field to be inserted in the Engagement_Total_Fees__c field within the related Opportunity.

Will it best to place this trigger in Opportunities Or Matter__c object? 

I appreciate all of your help.

Regards


 
Best Answer chosen by Forrest Muldune
Bhanu MaheshBhanu Mahesh
Change trigger.isInsert to trigger.isUpdate in line 11
 
trigger UpdateToTalFeeOnOpportunity on Matter__c(after insert,after update,after delete){
	Set<Id> oppIds = new Set<Id>();
	List<Opportunity> lstOppToBeUpdated = new List<Opportunity>();
	
	if(Trigger.isAfter){
		if(Trigger.isInsert || Trigger.isUpdate){
			for(Matter__c matter : trigger.new){
				if(Trigger.isInsert){
					oppIds.add(matter.Deal__c);
				}
				else if(Trigger.isUpdate){
					if(matter.Total_Fees__c != trigger.OldMap.get(matter.Id).Total_Fees__c){
							oppIds.add(matter.Deal__c);
					}
				}
			}
		}
		if(Trigger.isDelete){
				for(Matter__c matter : trigger.old){
					oppIds.add(matter.Deal__c);	
				}
		}
	}
	if(!oppIds.isEmpty()){
		for(Opportunity opp :[SELECT Id,Engagement_Total_Fees__c,(SELECT Id,Total_Fees__c FROM Engagements__r   ) FROM Opportunity WHERE Id IN :oppIds]){
					Decimal totalFee = 0;
					for(Matter__c matter : opp.Engagements__r   ){
							if(matter.Total_Fees__c != null){
								totalFee = totalFee + matter.Total_Fees__c;
							}
					}
					opp.Engagement_Total_Fees__c = totalFee;
					lstOppToBeUpdated.add(opp);
		}
		if(!lstOppToBeUpdated.isEmpty()){
			update lstOppToBeUpdated;
		}
	}
}

 

All Answers

Bhanu MaheshBhanu Mahesh
Hi Forrest,

Your trigger should be on Matter__c object and it will be after insert,after update,after delete events as you want to update the opportunity records.

Try below code
trigger UpdateToTalFeeOnOpportunity on Matter__c(after insert,after update,after delete){
	Set<Id> oppIds = new Set<Id>();
	List<Opportunity> lstOppToBeUpdated = new List<Opportunity>();
	
	if(Trigger.isAfter){
		if(Trigger.isInsert || Trigger.isUpdate){
			for(Matter__c matter : trigger.new){
				if(Trigger.isInsert){
					oppIds.add(matter.Deal__c);
				}
				else if(Trigger.isInsert){
					if(matter.Total_Fees__c != trigger.OldMap.get(matter.Id).Total_Fees__c){
							oppIds.add(matter.Deal__c);
					}
				}
			}
		}
		if(Trigger.isDelete){
				for(Matter__c matter : trigger.old){
					oppIds.add(matter.Deal__c);	
				}
		}
	}
	if(!oppIds.isEmpty()){
		for(Opportunity opp :[SELECT Id,Engagement_Total_Fees__c,(SELECT Id,Total_Fees__c FROM Matters__r) FROM Opportunity WHERE Id IN :oppIds]){
					Decimal totalFee = null;
					for(Matter__c matter : opp.Matters__r){
							totalFee = totalFee + matter.Total_Fees__c;
					}
					opp.Engagement_Total_Fees__c = totalFee;
					lstOppToBeUpdated.add(opp);
		}
		if(!lstOppToBeUpdated.isEmpty()){
			update lstOppToBeUpdated;
		}
	}
}

NOTE: (SELECT Id,Total_Fees__c FROM Matters__r) Assuming child relationship name to be Matters__r. If it is changed, modify thie API Name. You can find child Relation ship name by clicking on Deal__c field.

Mark this as "SOLVED" if your query is Answered.

Regards,
Bhanu Mahesh
Forrest MulduneForrest Muldune
Bhanu,

First of all, thank you so much for the trigger, I appreciate it very much.

on line 25 I received the error messages below.

Error: Compile Error: Didn't understand relationship 'Matter__r' in FROM part of query call. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names. at line 25 column 30

Error: Compile Error: Invalid field Matters__r for SObject Opportunity at line 27 column 44


I went into the Deal__c field in Matter__c and information is listed below. 

User-added image

FYI - In the Matter__c object in the Custom Object Definition Detail, the folllowing information is below.

Singular Label is " Engagement "
Plural Label is " Engagements "
Object Name is " Matter "
API Name is " Matter__c ".

question instead of Matters__r should I enter Engagements__r ? 

I appreciate your time.

Regards,

 
Bhanu MaheshBhanu Mahesh
Hi Forrest,

Yes correct. You have to replace Matters__r with Engagements__r

Let me know if you have any issues

 
Forrest MulduneForrest Muldune
Bhanu,

Below is  the updated code.

trigger UpdateToTalFeeOnOpportunity on Matter__c(after insert,after update,after delete){
    Set<Id> oppIds = new Set<Id>();
    List<Opportunity> lstOppToBeUpdated = new List<Opportunity>();
    
    if(Trigger.isAfter){
        if(Trigger.isInsert || Trigger.isUpdate){
            for(Matter__c matter : trigger.new){
                if(Trigger.isInsert){
                    oppIds.add(matter.Deal__c);
                }
                else if(Trigger.isInsert){
                    if(matter.Total_Fees__c != trigger.OldMap.get(matter.Id).Total_Fees__c){
                            oppIds.add(matter.Deal__c);
                    }
                }
            }
        }
        if(Trigger.isDelete){
                for(Matter__c matter : trigger.old){
                    oppIds.add(matter.Deal__c); 
                }
        }
    }
    if(!oppIds.isEmpty()){
        for(Opportunity opp :[SELECT Id,Engagement_Total_Fees__c,(SELECT Id,Total_Fees__c FROM Engagements__r) FROM Opportunity WHERE Id IN :oppIds]){
                    Decimal totalFee = null;
                    for(Matter__c matter : opp.Engagements__r){
                            totalFee = totalFee + matter.Total_Fees__c;
                    }
                    opp.Engagement_Total_Fees__c = totalFee;
                    lstOppToBeUpdated.add(opp);
        }
        if(!lstOppToBeUpdated.isEmpty()){
            update lstOppToBeUpdated;
        }
    }
}


I added the Engagements__r to the rows below 

for(Opportunity opp :[SELECT Id,Engagement_Total_Fees__c,(SELECT Id,Total_Fees__c FROM Engagements__r) FROM Opportunity

for(Matter__c matter : opp.Engagements__r){


When I tried to create a new record on the Matter__c (Engagement) object, I received the error message below.

Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger UpdateToTalFeeOnOpportunity caused an unexpected exception, contact your administrator: UpdateToTalFeeOnOpportunity: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.UpdateToTalFeeOnOpportunity: line 28, column 1

User-added image


I believe there is something not working on line 28, column 1 in the trigger, am I correct?
Bhanu MaheshBhanu Mahesh
Try This
trigger UpdateToTalFeeOnOpportunity on Matter__c(after insert,after update,after delete){
	Set<Id> oppIds = new Set<Id>();
	List<Opportunity> lstOppToBeUpdated = new List<Opportunity>();
	
	if(Trigger.isAfter){
		if(Trigger.isInsert || Trigger.isUpdate){
			for(Matter__c matter : trigger.new){
				if(Trigger.isInsert){
					oppIds.add(matter.Deal__c);
				}
				else if(Trigger.isInsert){
					if(matter.Total_Fees__c != trigger.OldMap.get(matter.Id).Total_Fees__c){
							oppIds.add(matter.Deal__c);
					}
				}
			}
		}
		if(Trigger.isDelete){
				for(Matter__c matter : trigger.old){
					oppIds.add(matter.Deal__c);	
				}
		}
	}
	if(!oppIds.isEmpty()){
		for(Opportunity opp :[SELECT Id,Engagement_Total_Fees__c,(SELECT Id,Total_Fees__c FROM Matters__r) FROM Opportunity WHERE Id IN :oppIds]){
					Decimal totalFee = 0;
					for(Matter__c matter : opp.Matters__r){
							if(matter.Total_Fees__c != null){
								totalFee = totalFee + matter.Total_Fees__c;
							}
					}
					opp.Engagement_Total_Fees__c = totalFee;
					lstOppToBeUpdated.add(opp);
		}
		if(!lstOppToBeUpdated.isEmpty()){
			update lstOppToBeUpdated;
		}
	}
}

 
Forrest MulduneForrest Muldune
Bhanu,

Sorry it did not work, I received the error message below 


Error: Invalid Data.
Review all error messages below to correct your data.
Apex trigger UpdateToTalFeeOnOpportunity caused an unexpected exception, contact your administrator: UpdateToTalFeeOnOpportunity: execution of AfterInsert caused by: System.DmlException: Update failed. First exception on row 0 with id 006e0000007luaiAAA; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, updateEngagement: execution of AfterUpdate caused by: System.SObjectException: Invalid field Opportunity__c for AggregateResult Trigger.updateEngagement: line 8, column 1: []: Trigger.UpdateToTalFeeOnOpportunity: line 36, column1

User-added image

Also in line 25 I changed Matters__r to Engagements__r   . In line 27 I changed Matters__r to Engagements__r as well.

I appreciate your patience. 





 
Bhanu MaheshBhanu Mahesh
Hi,

The error is coming from updateEngagement trigger on opportunity. As we are updatinh opportunities, opportunity trigger will fire and it is giving exception.

Please check that trigger
 
Forrest MulduneForrest Muldune
Bhanu,

For the most part of it it works. I made the other trigger in Opportunities inactive, sorry about this, I should have made it inactive.

The only requirement that is not working is when I change the value from the Total_Fees__c    (Currency(16, 2) field in Matter__c object , the value in the Engagement_Total_Fees__c  (Currency(16, 2) field in the related Opportunity record does not update for some reason. 

FYI - When I first created an Engagement record in Matter__c and I entered a value in the Total_Fees__c and connected it to the Opportunity, the values in the Engagement_Total_Fees__c calculated. When I changed the value in the Total_Fees__c in the same record in Matters__c, the value in the Engagement_Total_Fees__c did not calculate the changes.

I really do appreciate you taking the time for this.
Bhanu MaheshBhanu Mahesh
Change trigger.isInsert to trigger.isUpdate in line 11
 
trigger UpdateToTalFeeOnOpportunity on Matter__c(after insert,after update,after delete){
	Set<Id> oppIds = new Set<Id>();
	List<Opportunity> lstOppToBeUpdated = new List<Opportunity>();
	
	if(Trigger.isAfter){
		if(Trigger.isInsert || Trigger.isUpdate){
			for(Matter__c matter : trigger.new){
				if(Trigger.isInsert){
					oppIds.add(matter.Deal__c);
				}
				else if(Trigger.isUpdate){
					if(matter.Total_Fees__c != trigger.OldMap.get(matter.Id).Total_Fees__c){
							oppIds.add(matter.Deal__c);
					}
				}
			}
		}
		if(Trigger.isDelete){
				for(Matter__c matter : trigger.old){
					oppIds.add(matter.Deal__c);	
				}
		}
	}
	if(!oppIds.isEmpty()){
		for(Opportunity opp :[SELECT Id,Engagement_Total_Fees__c,(SELECT Id,Total_Fees__c FROM Engagements__r   ) FROM Opportunity WHERE Id IN :oppIds]){
					Decimal totalFee = 0;
					for(Matter__c matter : opp.Engagements__r   ){
							if(matter.Total_Fees__c != null){
								totalFee = totalFee + matter.Total_Fees__c;
							}
					}
					opp.Engagement_Total_Fees__c = totalFee;
					lstOppToBeUpdated.add(opp);
		}
		if(!lstOppToBeUpdated.isEmpty()){
			update lstOppToBeUpdated;
		}
	}
}

 
This was selected as the best answer
Forrest MulduneForrest Muldune
Bhanu,

The coding worked perfectly! I am so appreciate it of you for your coding! I spent all morning researching the code and I actually understood some parts of the coding. Obviously I will have to do more studying. I will be taking a beginner's course in Java soon. 

I used the same structure of coding you created for a similar situation, view below 


Settlement__c  (custom object)
  • Recovery_Total__c  - Formula (Currency) field with formula -  Initial_Value__c - Book_Value__c
  • Deal__c - Lookup(Opportunity)

Opportunity
  • Settlement_Recovery_Total__c - Currency(16, 2) field

trigger UpdateToRecoveryTotalOnOpportunity on Settlement__c (after insert,after update,after delete){
    Set<Id> oppIds = new Set<Id>();
    List<Opportunity> lstOppToBeUpdated = new List<Opportunity>();
   
    if(Trigger.isAfter){
        if(Trigger.isInsert || Trigger.isUpdate){
            for(Settlement__c settlement : trigger.new){
                if(Trigger.isInsert){
                    oppIds.add(settlement.Deal__c);
                }
                else if(Trigger.isUpdate){
                    if(settlement.Reovery_Total__c != trigger.OldMap.get(matter.Id).Reovery_Total__c){
                            oppIds.add(settlement.Deal__c);
                    }
                }
            }
        }
        if(Trigger.isDelete){
                for(Settlement__c settlement : trigger.old){
                    oppIds.add(settlement.Deal__c);
                }
        }
    }
    if(!oppIds.isEmpty()){
        for(Opportunity opp :[SELECT Id,Settlement_Recovery_Total__c,(SELECT Id,Recovery_Total__c FROM Settlements__r) FROM Opportunity WHERE Id IN :oppIds]){
                    Decimal RecoveryTotal = 0;
                    for(Settlement__c matter : opp.Settlements__r){
                            if(settlement.Recovery_Total__c!= null){
                                RecoveryTotal = RecoveryTotal + settlement.Recovery_Total__c;
                            }
                    }
                    opp.Settlement_Recovery_Total__c = RecoveryTotal;
                    lstOppToBeUpdated.add(opp);
        }
        if(!lstOppToBeUpdated.isEmpty()){
            update lstOppToBeUpdated;
        }
    }
}


Question - can Apex Triggers recognize Formula (Currency) fields in an Object? the reason for my question is because I received an error message below. 

Error: Compile Error: Variable does not exist: settlement.Recovery_Total__c at line 29 column 65

Which is this line code below within the Settlement__c object 

RecoveryTotal = RecoveryTotal + settlement.Recovery_Total__c;

I really appreciate your time, I have learned a lot from your assistance.




 
Bhanu MaheshBhanu Mahesh
Hi

Replace matter to settlement in below line

for(Settlement__c matter : opp.Settlements__r)
 
Forrest MulduneForrest Muldune
Bhanu,

Thank you so much for your assistance, time and patience on this issues. I will use the code you have provided and apply it to other triggers.

Do you know any websites or other sources I can use to learn Apex trigger coding? 

Regards,

Forrest