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
ChubbyChubby 

Apex code to update field on grandparent when a field on grandchild inserted or update

Hi All,

I have 3 objects A(grandparent), B(parent), C(grandchild). whenever grand child with type XXX is inserted or updated i want to update a field on grandparent. Pls help me with coding.

Thanks for your help.
Ashutosh GurjarAshutosh Gurjar
public static void UpdateExpensesWhenDelete( List<Expense_Item__c> listOfOldExpenseItem) {
        // using static flag to avoid recursion
        if(ExpenceItemTriggerHelper.ExpenseItemStatus == true) {
            
            //setting static flag to false
            ExpenseItemStatus = false;
            //Set of id fro  monthly expenses
            Set <Id> expenseIdMonthly = new Set<Id>();
            
            Set<id> rejectedItems = new set<Id>();
            
            //Set of ids for yearly expoenses
            Set <Id> expenseIdYearly = new Set<Id>();
            
            //map for monthly Expense
            Map<id,Expense__c> mapExpense = new Map<id,Expense__c>();
            
            //map for yearly Expense
            Map<id,Expense__c> mapExpenseYearly = new Map<id,Expense__c>();
            
                   
            //Loop to get ids of monthly expense
            For(Expense_Item__c newList : listOfOldExpenseItem) {
                
                   rejectedItems.add(newLIst.Id);  
                  //adding values to set of monthly ids
                expenseIdMonthly.add(newLIst.Expense__c); 
                }
            system.debug('The expenseIdMonthly list '+expenseIdMonthly);
            system.debug('The reejected list '+rejectedItems);
            //Loop to get ids of yearly expenses
            For(Expense__c yearlyList: [SELECT Yearly_Expense__c 
                                        FROM Expense__c 
                                        WHERE Type__c = 'monthly' AND Id IN : expenseIdMonthly]) {
                
                //adding values to set of yearly ids
                expenseIdYearly.add(yearlyList.Yearly_Expense__c);   
            }
            
            //updating monthly--------------------------------------
            //this loop will iterate on the aggregate query result
            for (AggregateResult ar:[SELECT sum(Expense_Amount__c) ExpenseTotal, Expense__c expenseId,Expense_Type__c expenseType
                                     FROM Expense_Item__c
                                     WHERE Expense__c IN : expenseIdMonthly AND Id NOT  IN : rejectedItems  
                                     GROUP BY  Expense__c, Expense_Type__c]) {
                
                //this check if our local set does not contain the id of Expense than we add it into the set
                If(!mapExpense.containsKey((Id)ar.get('expenseId')))
                    mapExpense.put((Id)ar.get('expenseId'), New Expense__c(Id = (Id)ar.get('expenseId'), Fuel_Expenses__c = 0,Food_Expenses__c=0,Other_Expenses__c=0));
                
                //if Expense type is fuel than add sum into the fuel expense field in the expense object 
                If(ar.get('expenseType') == 'Fuel') {
                    mapExpense.get((Id)ar.get('expenseId')).Fuel_Expenses__c = (Double)ar.get('ExpenseTotal');
                }
                //if Expense type is food than add sum into the food expense field in the expense object
                else If(ar.get('expenseType') == 'Food' ) {
                    mapExpense.get((Id)ar.get('expenseId')).Food_Expenses__c = (Double)ar.get('ExpenseTotal');
                }
                
                //if Expense type is other than fuel and food than add sum into the Other expense field in the expense object
                else {
                    //addiing values to other expenses
                    mapExpense.get((Id)ar.get('expenseId')).Other_Expenses__c = (Double)ar.get('ExpenseTotal');
                } 
            }
            
            //if there is any Expense item than update the fileds of Expense object
            If(mapExpense.Size() > 0) {
                
                ExpenseTriggerHelper.ExpenseStatus = false;
                Update mapExpense.Values();
            }
            
            //updating yearly expense-----------------------------------------------
            
            For(AggregateResult ar : [SELECT Yearly_Expense__c,sum(Food_Expenses__c) sumFood, sum(Fuel_Expenses__c) sumFuel, sum(Other_Expenses__c) sumOther FROM Expense__c 
                                      WHERE Type__c='monthly' AND Yearly_Expense__c IN : expenseIdYearly
                                      GROUP BY Yearly_Expense__c]) {
                
                //this check if our local set does not contain the id of Expense than we add it into the set
                if(!mapExpenseYearly.containsKey((Id)ar.get('Yearly_Expense__c'))) {
                    
                    mapExpenseYearly.put((Id)ar.get('Yearly_Expense__c'), New Expense__c(Id = (Id)ar.get('Yearly_Expense__c'), Fuel_Expenses__c = 0, Food_Expenses__c=0, Other_Expenses__c=0));   
                }
                
                //adding values to record in yearly expense 
                mapExpenseYearly.get((Id)ar.get('Yearly_Expense__c')).Other_Expenses__c += (Double)ar.get('sumOther');
                mapExpenseYearly.get((Id)ar.get('Yearly_Expense__c')).Fuel_Expenses__c += (Double)ar.get('sumFuel');
                mapExpenseYearly.get((Id)ar.get('Yearly_Expense__c')).Food_Expenses__c += (Double)ar.get('sumFood');   
            }
            
            //if there is any Expense item than update the fileds of Expense object
            If(mapExpenseYearly.Size() > 0) {
                system.debug('HHHEEEy'+mapExpenseYearly);
                ExpenseTriggerHelper.ExpenseStatus = false;
                Update mapExpenseYearly.Values();
            }    
        }
    }


Hi Chubby,

This code i hvae in my org so i have send you for just information ,,here expense_Item__c is grand child and Expense__c is its parent . And Expense__c have lookup on itself as well i called it yearly expense.

But you have one other best way to update grand parent is that you run you grand child object on before Trigger ,,,and parent trigger in After Trigger. The benifit of it is that in after trigger you have the id of grand child object record id as well and that record is already hit to the database,,, so you can just get the grandchild record through query and update grand parent according to that

Thanks