2

Number fields on Account : "No of Contacts" Write trigger to populate/update field on Account record whenever a new Contact record is inserted or deleted.

-- whenever i am deleting last contact record it is not updating Account field from 1 to 0. Value should be updated to 0 or Blank

trigger UpdateContactCountOnAccount on Contact (after insert, after update, after delete) 
{
    Set<Id> AccountIds = new Set<Id>();

    if(!Trigger.isDelete)
    {
        for (Contact ct : Trigger.new) 
        {        
            if(Trigger.isInsert && ct.AccountId != null)
            {
                AccountIds.add(ct.AccountId);
            }
            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);
                }
            }
        }
    }
    else
    {
        for (Contact ct : Trigger.old)
        {
            if(Trigger.isDelete && ct.AccountId != null)
            {
                AccountIds.add(ct.AccountId);
            }
        }   
    }

    List<Account> AcctToUpdate = new List<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'), No_of_Contacts__c=(Decimal)ar.get('ContactCount'));
        AcctToUpdate.add(tmp);
    }
    if(AcctToUpdate.size()>0) 
        update AcctToUpdate;
 }

All is working fine but whenever i am deleting last contact record it is not updating Account field from 1 to 0 Can someone help me

2 Answers 2

6

This is because you are using an aggregate query on Contact:

for (AggregateResult ar: [Select Count(Id) ContactCount, AccountId 
                          from Contact where AccountId IN: AccountIds GROUP BY AccountId])

Once the final Contact is deleted, there's nothing to aggregate, so you will not see an AggregateResult with that Contact's AccountId and the value 0.

I'd suggest you maintain a second set of Account Ids, say accountsWithDeletedContacts, as you loop over Trigger.old. Then, as you loop over your aggregate results, remove each Account Id processed from the Set. Any Ids left after that process will be those Accounts with the final Contact deleted, and you can generate updates for those records as well.

1
  • Great, Thanks for the Clarification.
    – Dave
    Commented Jul 12, 2019 at 15:39
1

I Created another set of List for Old Values as and this worked for me Thanks Again @David Reed

//for New Accounts and Contacts
for(Account accountList : acc)
            {
                accountList.No_of_Contacts__c=con.size();
            }
            update acc;

            //for Old Accounts and Contacts
            List<Account> Oldacc = [select id,No_of_Contacts__c from Account where Id in:OldAId];
            List<Contact> OldCon = [select id from contact where AccountId in :OldAId];

            for(Account accountList : Oldacc)
            {
                accountList.No_of_Contacts__c=OldCon.size();
            }
            update Oldacc;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .