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
THUNDER CLOUDTHUNDER CLOUD 

Calculate Sum of Amounts from child records using trigger?

Can anyone tell me how to write trigger for this scenario?

Two objects are in lookup relationship - Department (parent) and Employee . Employee has "Amount" field and Department has "Total Amount ". I need to write trigger to calculate sum of "Amount" of child records and display it on Dept. object. 
Best Answer chosen by THUNDER CLOUD
mritzimritzi
It would be highly recommended to use Master-child relationship instead of Lookup relationship, and then make Total Amount field a Roll up summary field.
more details here:
https://developer.salesforce.com/trailhead/point_click_business_logic/roll_up_summary_fields


If you have any specific reason to use Trigger, then following may come handy for you:
 
trigger UpdateTotalAmount on Employee__c(before Insert, after Insert,
										 before Update, after Update,
										 before Delete, after Delete){
	if(Trigger.isAfter && Trigger.isInsert){
		List<Id> empIds =new List<Id>();
		List<Employee__c> empList = new List<Employee__c>();
		for(Employee__c e:Trigger.new){
			empIds.add(e.id);
			empList.add(e);
		}
		
		List<AggregateResult> arDeptSum = [Select SUM(Amount__c) totalSum, Employee__c From Department_c Where Employee__c IN :empIds GROUP BY Employee__c];
		for(Integer i=0;i<empIds.size();i++){
			//following is to make sure that data is mapped correctly, even though List is itself ordered
			for(Integer j=0;j<arDeptSum.size();j++){
				if(empids[i]==arDeptSum.get('Employee__c')){
					empList[i].Total_Amount__c = arDeptSum[j].get('totalSum');
					break;
				}
			}
		}
		update empList;
	}
}


Select it as Best Answer, if it solves your problem

All Answers

Prakash B 28Prakash B 28
Hi,

If you had used Master-Detail relationship between the 2 objects, then you could have used Roll up summary field to calculate the Total Amount instead of using a trigger.

In case you need a trigger then, you need to write the trigger on the amount object for all 3 cases, such as insert, update and delete.

trigger AmountTrigger on Emaployee__c (after insert, after update, after delete) {

  Set<Id> DepartmentIds = new Set<Id>();

   if(Trigger.isInsert || Trigger.isUpdate){
      for( Employee__c emp : Trigger.New){
          if(Trigger.isInsert || (Trigger.isUpdate && Trigger.oldMap.get(emp.ID).Amount__c != emp.Amount__c)){
                      DepartmentIds.add(emp.Department__c);
           }
      }

     if(Trigger.isDelete){
             for( Employee__c emp : Trigger.Old){   
                   DepartmentIds.add(emp.Department__c);
             } 
     }

    Map<Id, Decimal> TotalAmountMap = new Map<Id,Decimal>():
     for(Employee__c emp : [select Id, Amount__c, Department__c from Employee__c where Department__c IN: DepartmentIDs]){
               Decimal TotalAmount = 0;
               if(TotalAmountMap.containsKey(emp.Department__c)
                       TotalAmount = TotalAmountMap.get(emp.Department__c);
               TotalAmount = TotalAmount + emp.Amount__c;
               TotalAmountMap.put(emp.Department__c, TotalAmount);
     }

    List<Department__c> updateDepartments = new List<Department__c>();
    for(Id deptId : TotalAmountMap.keySet(){
       Department__c dept = new Department__c(Id = deptID);
       dept.Total_Amount__c = TotalAmountMap.get(deptId);
       updateDepartments.add(dept); 
   }

  If(updateDepartments.size() > 0)
       Update updateDepartments;
}

Regards,
Prakash B
mritzimritzi
It would be highly recommended to use Master-child relationship instead of Lookup relationship, and then make Total Amount field a Roll up summary field.
more details here:
https://developer.salesforce.com/trailhead/point_click_business_logic/roll_up_summary_fields


If you have any specific reason to use Trigger, then following may come handy for you:
 
trigger UpdateTotalAmount on Employee__c(before Insert, after Insert,
										 before Update, after Update,
										 before Delete, after Delete){
	if(Trigger.isAfter && Trigger.isInsert){
		List<Id> empIds =new List<Id>();
		List<Employee__c> empList = new List<Employee__c>();
		for(Employee__c e:Trigger.new){
			empIds.add(e.id);
			empList.add(e);
		}
		
		List<AggregateResult> arDeptSum = [Select SUM(Amount__c) totalSum, Employee__c From Department_c Where Employee__c IN :empIds GROUP BY Employee__c];
		for(Integer i=0;i<empIds.size();i++){
			//following is to make sure that data is mapped correctly, even though List is itself ordered
			for(Integer j=0;j<arDeptSum.size();j++){
				if(empids[i]==arDeptSum.get('Employee__c')){
					empList[i].Total_Amount__c = arDeptSum[j].get('totalSum');
					break;
				}
			}
		}
		update empList;
	}
}


Select it as Best Answer, if it solves your problem
This was selected as the best answer