[SalesForce] Apex Trigger on Contact to Update Field on Account

I have a custom field on Account called "Contact_Exist__c" (api name). I'm trying to write an apex trigger on contact that when the field is updated/inserted and it has an account name linked or unlinked to it, it updated on Account "Contact_Exist__c" by an increment of 1 or a decrement of 1. I tried to implement the following (I know its wrong)

Final version fixes all my issues. It no longer needs to sum off a column and instead works as is using count functionality.

    trigger updateContactCountOnAccount on Contact (after insert, after update, after delete, after undelete) {

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

    if(!Trigger.isDelete){
        for (Contact ct : Trigger.new) {        

            if(Trigger.isInsert && ct.AccountId != null){
                AccountIds.add(ct.AccountId);
            }
     //For Contact Update scenarios, Contact.AccountId value should be checked for null in new and old record.
            if(Trigger.isUpdate){
                if(ct.AccountId==null && Trigger.oldMap.get(ct.Id).AccountId != null){
                    AccountIds.add(Trigger.oldMap.get(ct.Id).AccountId);
                }
                if(ct.AccountId!=null && Trigger.oldMap.get(ct.Id).AccountId != null && ct.AccountId != Trigger.oldMap.get(ct.Id).AccountId){
                    AccountIds.add(ct.AccountId);
                    AccountIds.add(Trigger.oldMap.get(ct.Id).AccountId);
                }
                if(ct.AccountId!=null && Trigger.oldMap.get(ct.Id).AccountId == null){
                    AccountIds.add(ct.AccountId);
                }
            }

            if(Trigger.isUndelete && ct.AccountId != null){
                AccountIds.add(ct.AccountId);
            }
        }
    }else{
        for (Contact ct : Trigger.old){
            if(Trigger.isDelete && ct.AccountId != null){
                AccountIds.add(ct.AccountId);
            }
        }   
    }


            Map<ID, Account> account_updater = new Map<ID, Account>();


            //Preset to 0
            for(AggregateResult ar : [Select Id,sum(NumberContacts__c) cnt from Account where Id IN :accountIDs Group By Id ]){
                Account tmp = New Account(ID=(id)ar.get('Id'), NumberContacts__c = 0);
                account_updater.put(tmp.id,tmp);
            }




            for(AggregateResult ar : [Select AccountID,sum(ValidContactWorkflor__c) cnt From Contact Where AccountId IN :accountIDs Group By AccountID ]){
                Account tmp = New Account(ID=(id)ar.get('accountid'), NumberContacts__c = (decimal)ar.get('cnt'));
                account_updater.put(tmp.id,tmp);
            }

            update account_updater.values();  

     }

Best Answer

I understand that you are trying to get the count of Contacts and update it in a field in Account record. If yes, you may check the below trigger.

trigger updateContactCountOnAccount on Contact (after insert, after update, after delete, after undelete) {

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

if(!Trigger.isDelete){
    for (Contact ct : Trigger.new) {        

        if(Trigger.isInsert && ct.AccountId != null){
            AccountIds.add(ct.AccountId);
        }
 //For Contact Update scenarios, Contact.AccountId value should be checked for null in new and old record.
        if(Trigger.isUpdate){
            if(ct.AccountId==null && Trigger.oldMap.get(ct.Id).AccountId != null){
                AccountIds.add(Trigger.oldMap.get(ct.Id).AccountId);
            }
            if(ct.AccountId!=null && Trigger.oldMap.get(ct.Id).AccountId != null && ct.AccountId != Trigger.oldMap.get(ct.Id).AccountId){
                AccountIds.add(ct.AccountId);
                AccountIds.add(Trigger.oldMap.get(ct.Id).AccountId);
            }
            if(ct.AccountId!=null && Trigger.oldMap.get(ct.Id).AccountId == null){
                AccountIds.add(ct.AccountId);
            }
        }

        if(Trigger.isUndelete && ct.AccountId != null){
            AccountIds.add(ct.AccountId);
        }
    }
}else{
    for (Contact ct : Trigger.old){
        if(Trigger.isDelete && ct.AccountId != null){
            AccountIds.add(ct.AccountId);
        }
    }   
}

List<Account> AcctToUpdate = new List<Account>();
//AggregateResult to get count of Contact for each Account
for (AggregateResult ar: [Select Count(Id) ContactCount, AccountId from Contact where AccountId IN: AccountIds GROUP BY AccountId]){
    Account tmp = new Account(Id=(Id)ar.get('AccountId'), NumberContacts__c=(Decimal)ar.get('ContactCount'));
    AcctToUpdate.add(tmp);
}
if(AcctToUpdate.size()>0) update AcctToUpdate;
 }
Related Topic