rollup summary with bulk record handling without hitting governer limits

 Contact Trigger :



================================================

trigger ContactTrigger on Contact (after insert, after update, after delete, after undelete) {
    Set<Id> accountIds = new Set<Id>();

    // Insert, Update (new AccountId), Undelete
    if (Trigger.isInsert || Trigger.isUpdate || Trigger.isUndelete) {
        for (Contact con : Trigger.new) {
            if (con.AccountId != null) {
                accountIds.add(con.AccountId);
            }
        }
    }

    // Delete, Update (old AccountId)
    if (Trigger.isDelete || Trigger.isUpdate) {
        for (Contact con : Trigger.old) {
            if (con.AccountId != null) {
                accountIds.add(con.AccountId);
            }
        }
    }

    if (!accountIds.isEmpty()) {
        // Step 1: Query accounts to update
        Map<Id, Account> accountMap = new Map<Id, Account>(
            [SELECT Id, Number_of_Contacts__c FROM Account WHERE Id IN :accountIds]
        );

        // Step 2: Aggregate live contacts count
        Map<Id, Integer> contactCounts = new Map<Id, Integer>();
        for (AggregateResult ar : [
            SELECT AccountId, COUNT(Id) total
            FROM Contact
            WHERE AccountId IN :accountIds
            GROUP BY AccountId
        ]) {
            contactCounts.put((Id)ar.get('AccountId'), (Integer)ar.get('total'));
        }

        // Step 3: Update each Account’s count
        List<Account> accountsToUpdate = new List<Account>();
        for (Id accId : accountMap.keySet()) {
            Account acc = accountMap.get(accId);
            acc.Number_of_Contacts__c = contactCounts.containsKey(accId) ? contactCounts.get(accId) : 0;
            accountsToUpdate.add(acc);
        }

        // Step 4: Bulk update
        if (!accountsToUpdate.isEmpty()) {
            update accountsToUpdate;
        }
    }
}


====================================================================================


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

  

   Set<Id> accIds = new Set<Id>();// set to store parent account ids of contacts

   map<string,Account> accconmap1=new map<string,Account>();

   map<string,string> accconmap=new map<string,string>();

   map<string,string> accconmap2=new map<string,string>();

if(trigger.isAfter && (trigger.isInsert || trigger.isUndelete))

{

if(!trigger.new.isEmpty()){

            Integer i=0;

for(Contact con : trigger.new)

{

                 accIds.add(con.AccountId);

                 accconmap.put(con.id,con.AccountId);

}

}

}

if(trigger.isAfter && trigger.isUpdate)

{

if(!trigger.new.isEmpty()){

for(Contact con : trigger.new)

{

                if(con.AccountId!= trigger.oldMap.get(con.Id).AccountId){

                   if(con.AccountId == null && trigger.oldMap.get(con.Id).AccountId != null){

                        accconmap2.put(con.id,trigger.oldMap.get(con.Id).AccountId);

                        accIds.add(trigger.oldMap.get(con.Id).AccountId);

                    }else if(con.AccountId != null && trigger.oldMap.get(con.Id).AccountId == null){

                        accconmap.put(con.id,con.AccountId);

                        accIds.add(con.AccountId);

                    }

                }

}

}

}

if(trigger.isAfter && trigger.isDelete)

{

if(!trigger.old.isEmpty())

{

for(Contact con : trigger.old)

{

if(con.AccountId !=null)

{

accIds.add(con.AccountId);

                    accconmap2.put(con.id,con.AccountId);

                    

}

}

}

}

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

if(!accIds.isEmpty())

{

List<Account> acclist = [Select Id, Number_of_Contacts__c from Account where Id IN : accIds];

        if(!acclist.isEmpty()){

            for(Account acc: acclist){

                if( accconmap.values().contains(acc.id)){

                    if(!(accconmap1.containsKey(acc.id))){

                        Account a=new Account();

                        a.id=acc.id;

                        if(acc.Number_of_Contacts__c==null || acc.Number_of_Contacts__c == 0)

                        { 

                            a.Number_of_Contacts__c=1;

                        }

                        

        else if(acc.Number_of_Contacts__c >= 1)

                        {

                            a.Number_of_Contacts__c =acc.Number_of_Contacts__c+1;

                        }

        accconmap1.put(a.id,a);

                        

                    }else{

                        Account a1=accconmap1.get(acc.id);

                        a1.Number_of_Contacts__c += 1;

                        accconmap1.put(a1.id,a1);

                     }

                }

                if( accconmap2.values().contains(acc.id)){

                    if(!(accconmap1.containsKey(acc.id))){

                        Account a=new Account();

                        a.id=acc.id;

                        if(acc.Number_of_Contacts__c!=null && acc.Number_of_Contacts__c>=1)

                        {

                            a.Number_of_Contacts__c=acc.Number_of_Contacts__c-1;

                        }

                        accconmap1.put(a.id,a);

                    }else{

                        Account a=accconmap1.get(acc.id);

                        a.Number_of_Contacts__c -=1;

                        accconmap1.put(a.id,a);

                    }

                }

                

}

}

}

    

if(!accconmap1.values().isEmpty()){

update accconmap1.values();

}

    

}



=========================================================

Test Class with 89 percent coverage : 


==============================================================


@istest//(seealldata=true)

private class  ContactTriggerTest {

    @isTest static void testName(){

        Account testOpportunity = new Account(Name = 'Test Opp');

        insert testOpportunity;

        Contact cont = new Contact();

cont.FirstName='Test';

cont.LastName='Test24211';

        cont.Cost__c=300;

cont.Accountid= testOpportunity.id;

insert cont;

        Contact cont1 = new Contact();

cont1.FirstName='Test';

cont1.LastName='Test12';

        cont1.Cost__c=200;

cont1.Accountid= testOpportunity.id;

insert cont1;

        cont1.Cost__c=100;

        update cont1;

        cont1.Accountid= null;

        update cont1;

        cont1.Accountid= testOpportunity.id;

        update cont1;

        delete cont1;

        undelete cont1;

    }

    @isTest static void testName1(){

        Account testOpportunity = new Account(Name = 'Test Opp1');

        insert testOpportunity;

        Contact cont1 = new Contact();

cont1.FirstName='Test1';

cont1.LastName='Test1';

        cont1.Cost__c=200;

        cont1.Email='msivareddysfdc@gmail.com';

cont1.Accountid= testOpportunity.id;

        insert cont1;

        

        Contact cont = new Contact();

cont.FirstName='Test';

cont.LastName='Test';

        cont.Cost__c=300;

        cont.Email='msivareddysfdc1@gmail.com';

cont.Accountid= testOpportunity.id;

        insert cont;

        try{

            cont.LastName=null;

            testOpportunity.Name=null;

            update testOpportunity;

            update cont;

            

        }catch(Exception e){

                

            }

        

    }

}

============================================================================


New code 

==========================================================================

trigger ContactTrigger on Contact (

    before insert, after insert, before update, after update,

    before delete, after undelete, after delete

) {

    // Collect all impacted Account Ids

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


    // Maps for contact movements

    Map<Id, Id> contactToNewAcc = new Map<Id, Id>();   // Contact -> New AccountId

    Map<Id, Id> contactToOldAcc = new Map<Id, Id>();   // Contact -> Old AccountId


    // -----------------------------

    // Identify Accounts to update

    // -----------------------------

    if (Trigger.isAfter) {

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

            for (Contact con : Trigger.new) {

                if (con.AccountId != null) {

                    accIds.add(con.AccountId);

                    contactToNewAcc.put(con.Id, con.AccountId);

                }

            }

        }


        if (Trigger.isUpdate) {

            for (Contact con : Trigger.new) {

                Id oldAccId = Trigger.oldMap.get(con.Id).AccountId;

                Id newAccId = con.AccountId;


                if (oldAccId != newAccId) {

                    if (oldAccId != null) {

                        accIds.add(oldAccId);

                        contactToOldAcc.put(con.Id, oldAccId);

                    }

                    if (newAccId != null) {

                        accIds.add(newAccId);

                        contactToNewAcc.put(con.Id, newAccId);

                    }

                }

            }

        }


        if (Trigger.isDelete) {

            for (Contact con : Trigger.old) {

                if (con.AccountId != null) {

                    accIds.add(con.AccountId);

                    contactToOldAcc.put(con.Id, con.AccountId);

                }

            }

        }

    }


    // -----------------------------

    // Query Accounts

    // -----------------------------

    if (!accIds.isEmpty()) {

        Map<Id, Account> accountsToUpdate = new Map<Id, Account>();


        for (Account acc : [

            SELECT Id, Number_of_Contacts__c

            FROM Account

            WHERE Id IN :accIds

        ]) {

            Integer currentCount = acc.Number_of_Contacts__c == null ? 0 : acc.Number_of_Contacts__c;

            Integer delta = 0;


            // Count increases for new links

            if (contactToNewAcc.values().contains(acc.Id)) {

                delta += contactToNewAcc.values().count(acc.Id);

            }


            // Count decreases for removed links

            if (contactToOldAcc.values().contains(acc.Id)) {

                delta -= contactToOldAcc.values().count(acc.Id);

            }


            if (delta != 0) {

                accountsToUpdate.put(acc.Id, new Account(

                    Id = acc.Id,

                    Number_of_Contacts__c = currentCount + delta

                ));

            }

        }


        if (!accountsToUpdate.isEmpty()) {

            update accountsToUpdate.values();

        }

    }

}



==================================================================

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