[SalesForce] Roll up summary Trigger performing total sum in account

I am not able to perform insertion,updation,deletion on account

Apex class:

 public static void parentUpdate(list<Contact> records){   
 set<ID> ids = new set<ID>();
 for(Contact c: records){
    if(c.Amount__c  != Null){
        ids.add(c.AccountId);
    }
 }  
 list<Account> apayList=[select id,Total_Amount__c,(select Amount__c from Contacts) from Account where id IN:ids];
 for(Account ac:apayList){


     double amount=0;         
     for(Contact co:ac.Contacts){
         if(ac.Contacts.size()>0 && co.AccountId!=null){
             amount+=co.Amount__c;
           }            
       }          

      ac.Total_Amount__c =amount;


 }
  update apayList;

   system.debug('#####'+apayList);
  }

@future
   public static void countparentupdate(Id recordId){
    list<Contact> records= [select id,AccountId,Amount__c from Contact WHERE 
  AccountId = :recordId];
        parentUpdate(records); 
  }

Apex Trigger:

trigger updateAccount on Contact (after insert,after update,after delete) {

if(Trigger.isAfter && (Trigger.isInsert || Trigger.isUpdate)){
    for(Contact c :Trigger.new){
         AccountTotalAmount.countparentupdate(c.AccountId);
    }       
}

if(Trigger.isAfter && (Trigger.isUpdate || Trigger.isDelete)){
   for(Contact c :Trigger.old){
         AccountTotalAmount.countparentupdate(c.AccountId);
    }       
}
}

Stack Trace Error:

updateAccount: execution of AfterUpdate caused by:
System.DmlException: Update failed. First exception on row 0 with id
0017F00001odBxkQAE; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY,
Contactupdate: maximum trigger depth exceeded Contact trigger event
AfterUpdate Account trigger event AfterUpdate Contact trigger event
AfterUpdate Account trigger event AfterUpdate Contact trigger event
AfterUpdate Account trigger event AfterUpdate Contact trigger event
AfterUpdate Account trigger event AfterUpdate Contact trigger event
AfterUpdate Account trigger event AfterUpdate Contact trigger event
AfterUpdate Account trigger event AfterUpdate Contact trigger event
AfterUpdate Account trigger event AfterUpdate Contact trigger event
AfterUpdate Account trigger event AfterUpdate: []
Class.AccountTotalAmount.parentUpdate: line 51, column 1
Class.AccountTotalAmount.countparentupdate: line 59, column 1
Trigger.updateAccount: line 5, column 1

Best Answer

The repeated:

event AfterUpdate Contact trigger event AfterUpdate Account trigger

in the stack trace suggests you also have a trigger on Account that updates Contact as well as the trigger you have posted on Contact that updates Account. This causes a never-ending loop.

One way to break that is to be more selective e.g. only update the Account when the specific field you are rolling up changes:

Set<Id> accountIds = new Set<Id>();
for(Contact c :Trigger.new){
    Contact old = Trigger.oldMap.get(c.Id);
    if (c.Amount__c != old.Amount__c) {
        accountIds.add(c.AccountId);
    }
}
if (accountIds.size() > 0) {
    Account[] accounts = [
        select Id, (select Amount__c from Contacts)
        from Account
        where Id in :accountIds
    ];
    for (Account a : accounts) {
        a.Total_Amount__c = 0;
        for (Contact c : a.Contacts) {
            if (c.Amount__c != null) {
                a.Total_Amount__c += c.Amount__c;
            }
        }
    }
    update accounts;
}

Note that your code was not bulkified: the above logic addresses that too.

Related Topic