Trigger 3 - Roll up Summary Trigger

 Trigger to count the number of Contacts associated with an Account and display the Contacts count on the Account's custom field.


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

    if (Trigger.isAfter) {

        if (Trigger.isInsert || Trigger.isUndelete) {

            ContactTriggerHandler.countContacts(Trigger.new, null);

        } 

        else if (Trigger.isUpdate) {

            ContactTriggerHandler.countContacts(Trigger.new, Trigger.oldMap);

        } 

        else if (Trigger.isDelete) {

            ContactTriggerHandler.countContacts(null, Trigger.oldMap);

        }

    }

}



public class ContactTriggerHandler {

    

    public static void countContacts(List<Contact> newContacts, Map<Id, Contact> oldContactMap) {

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

        

        // 1. Capture Account IDs from New or Undeleted Contacts

        if (newContacts != null) {

            for (Contact con : newContacts) {

                if (con.AccountId != null) {

                    accountIds.add(con.AccountId);

                }

                // Handle reparenting: capture the old account ID if the account changed

                if (oldContactMap != null && oldContactMap.containsKey(con.Id)) {

                    Id oldAccountId = oldContactMap.get(con.Id).AccountId;

                    if (oldAccountId != null && oldAccountId != con.AccountId) {

                        accountIds.add(oldAccountId);

                    }

                }

            }

        }

        

        // 2. Capture Account IDs from Deleted Contacts

        if (newContacts == null && oldContactMap != null) {

            for (Contact con : oldContactMap.values()) {

                if (con.AccountId != null) {

                    accountIds.add(con.AccountId);

                }

            }

        }

        

        // 3. Process calculations if we have affected Accounts

        if (!accountIds.isEmpty()) {

            List<Account> accountsToUpdate = new List<Account>();

            

            // Initialize all targeted accounts with 0 to clear count if all contacts are deleted/moved

            for (Id accId : accountIds) {

                accountsToUpdate.add(new Account(Id = accId, Number_of_Contacts__c = 0));

            }

            

            // Query current counts using SOQL Aggregate

            List<AggregateResult> results = [

                SELECT AccountId, COUNT(Id) totalContacts 

                FROM Contact 

                WHERE AccountId IN :accountIds 

                GROUP BY AccountId

            ];

            

            // Map the active aggregated counts to a map structure

            Map<Id, Integer> accountCountMap = new Map<Id, Integer>();

            for (AggregateResult ar : results) {

                Id accId = (Id) ar.get('AccountId');

                Integer count = (Integer) ar.get('totalContacts');

                accountCountMap.put(accId, count);

            }

            

            // Populate the specific counted values back into our update array

            for (Account acc : accountsToUpdate) {

                if (accountCountMap.containsKey(acc.Id)) {

                    acc.Number_of_Contacts__c = accountCountMap.get(acc.Id);

                }

            }

            

            // Commit changes to the database

            if (!accountsToUpdate.isEmpty()) {

                update accountsToUpdate;

            }

        }

    }

}




Comments

Popular posts from this blog

Multi currency in Salesforce - Revenue Cloud Advance - Revenue Lifecycle Management

How to get sessionid and salesforce org base url in salesforce