function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
sumit dsumit d 

Account trigger to count no. of opportunity

Hi All,
​         i want to create a trigger on Account to count number of opportinty and contact relateed to Account.
How to do it?
Any suggestion?
Best Answer chosen by sumit d
Amit Chaudhary 8Amit Chaudhary 8
Hi Sumit,

You dnt need trigger for opportunity. You can use the roll-up summery field for this.

And for contact you can try below trigger with halper.
Trigger.
Trigger ContactTrigger on Contact (after insert,after update, after delete, after undelete) {
    ContactTriggerHandler handler = new ContactTriggerHandler();
	if(Trigger.isDelete){
		handler.OnAfterDelete(trigger.new,trigger.old,Trigger.newMap,trigger.oldMap)
    }else if(Trigger.isInsert ){
		handler.OnAfterInsert(trigger.new,trigger.old,Trigger.newMap,trigger.oldMap)
	
	}else if(Trigger.isUndelete){
		handler.OnAfterUndelete(trigger.new,trigger.old,Trigger.newMap,trigger.oldMap)
	
	} else if(Trigger.isUpdate){
		handler.OnAfterUpdate(trigger.new,trigger.old,Trigger.newMap,trigger.oldMap)
	}
}

Handler
public with sharing class ContactTriggerHandler 
{
    public void OnAfterInsert( List<Contact> newContact, List<Contact> oldContact, Map<ID, Contact> newContactMap , Map<ID, Contact> oldContactMap ) {
		Set<Id> accountIds = new Set<Id>();
        for(Contact conRecord : newContact){
			accountIds.add(conRecord.AccountId);
		}	
		updateCount(accountIds);
    }

    public void OnAfterUndelete( List<Contact> newContact, List<Contact> oldContact, Map<ID, Contact> newContactMap , Map<ID, Contact> oldContactMap ) {
		Set<Id> accountIds = new Set<Id>();
        for(Contact conRecord : newContact){
			accountIds.add(conRecord.AccountId);
		}	
		updateCount(accountIds);
    }

    public void OnAfterUpdate( List<Contact> newContact, List<Contact> oldContact, Map<ID, Contact> newContactMap , Map<ID, Contact> oldContactMap ) {
		Set<Id> accountIds = new Set<Id>();
        for(Contact conRecord : newContact) {
            if(conRecord.AccountId != oldContactMap.get(conRecord.Id).AccountId) {
                accountIds.add(conRecord.AccountId);
                accountIds.add(oldContactMap.get(conRecord.Id).AccountId);
            }
        }    
		updateCount(accountIds);
    }
	
    public void OnAfterDelete( List<Contact> newContact, List<Contact> oldContact, Map<ID, Contact> newContactMap , Map<ID, Contact> oldContactMap )
    {
		Set<Id> accountIds = new Set<Id>();
        for(Contact conRecord : oldContact ){
            accountIds.add(conRecord.AccountId);
		}	
		updateCount(accountIds);
    }
	
	
	public static void updateCount( Set<Id> accountIds ) {
	
		if(accountIds.size() > 0) {
			List<Account> accountList = [SELECT Roll_up_Contact__c, (SELECT Id FROM Contacts) FROM Account WHERE Id in: accountIds];
			if(accountList.size() > 0){
				for(Account accRecord : accountList)
				{
					accRecord.Roll_up_Contact__c = accRecord.Contacts.size();
				}	
				UPDATE accountList;
			}
		}
    }	
	
}

Please check below post for Trigger Framework
http://amitsalesforce.blogspot.com/2015/06/trigger-best-practices-sample-trigger.html

Let us know if this will help you

All Answers

SandhyaSandhya (Salesforce Developers) 
Hi,

Try below sample code
List<id> TriggerList = new List<id>();
if(Trigger.isInsert)
{
    List<id> TriggerList = new List<id>();
    for(Opportunity Opp : Trigger.new)
    {
        TriggerList.add(Opp.AccountId);
    }
    List<Account> DML = New List<Account>();
    List<Account> Ls = [select id,(select id from Opportunities) from Account where id in:TriggerList];  

    for(Account AccNew : ls)
    {
        Integer Num = AccNew.Opportunities.size();
        AccNew.AccountNumber=String.valueOf(Num);
        DML.add(AccNew);
    }
    update ls;
}

if(Trigger.isDelete)
{
    for(Opportunity Opp : Trigger.old)
    {
        TriggerList.add(Opp.AccountId);
    }

    List<Account> DML = New List<Account>();
    List<Account> Ls = [select id,(select id from Opportunities) from Account where id in:TriggerList];
    for(Account act : Ls)
    {
        act.AccountNumber=String.valueOf(act.Opportunities.size());
        DML.add(act);
    }
    update Ls;
}  
}

Also refer below link.

http://www.infallibletechie.com/2013/09/trigger-to-count-number-of-contacts.html

 Please mark it as solved if my reply was helpful. It will make it available for other as the proper solution.
                                             
Best Regards
Sandhya
 
Ravi Dutt SharmaRavi Dutt Sharma
Hi Sumit,

Ideally the trigger should not be Account. To store the count of Contact on parent account, you should write a trigger on Contact and handle the insert, update and delete event (and undelete if that's in scope). For opportunity, you can create a rollup on Account to store the opportunity count. This should be staight forward configuration, no code required for this.

Thanks,
Ravi
Shweta AlwaniShweta Alwani
Hi Sumit,

For opportunity you can create a roll-up filed on account which will automatically count the opporunity on account. And for contact you can try the following trigger : 

trigger ContactTrigger on Contact (after insert,after update, after delete, after undelete) {
   
    Set<Id> accountIds = new Set<Id>();
    if(Trigger.isDelete){
        for(Contact conRecord : Trigger.Old)
            accountIds.add(conRecord.AccountId);
    }else{
        for(Contact conRecord : Trigger.New){
            if(Trigger.isInsert || Trigger.isUndelete)
                accountIds.add(conRecord.AccountId);
            if(Trigger.isUpdate && conRecord.AccountId != Trigger.oldMap.get(conRecord.Id).AccountId){
                accountIds.add(conRecord.AccountId);
                accountIds.add(Trigger.oldMap.get(conRecord.Id).AccountId);
            }
        }        
    }
    if(accountIds.size() > 0){
        List<Account> accountList = [SELECT Roll_up_Contact__c, (SELECT Id FROM Contacts) FROM Account WHERE Id in: accountIds];
        if(accountList.size() > 0){
            for(Account accRecord : accountList)
                accRecord.Roll_up_Contact__c = accRecord.Contacts.size();
            UPDATE accountList;
        }
    }
        
}

WHERE Roll_up_Contact__c is  a number field on account.
sumit dsumit d
how to do it using helper class?
Amit Chaudhary 8Amit Chaudhary 8
Hi Sumit,

You dnt need trigger for opportunity. You can use the roll-up summery field for this.

And for contact you can try below trigger with halper.
Trigger.
Trigger ContactTrigger on Contact (after insert,after update, after delete, after undelete) {
    ContactTriggerHandler handler = new ContactTriggerHandler();
	if(Trigger.isDelete){
		handler.OnAfterDelete(trigger.new,trigger.old,Trigger.newMap,trigger.oldMap)
    }else if(Trigger.isInsert ){
		handler.OnAfterInsert(trigger.new,trigger.old,Trigger.newMap,trigger.oldMap)
	
	}else if(Trigger.isUndelete){
		handler.OnAfterUndelete(trigger.new,trigger.old,Trigger.newMap,trigger.oldMap)
	
	} else if(Trigger.isUpdate){
		handler.OnAfterUpdate(trigger.new,trigger.old,Trigger.newMap,trigger.oldMap)
	}
}

Handler
public with sharing class ContactTriggerHandler 
{
    public void OnAfterInsert( List<Contact> newContact, List<Contact> oldContact, Map<ID, Contact> newContactMap , Map<ID, Contact> oldContactMap ) {
		Set<Id> accountIds = new Set<Id>();
        for(Contact conRecord : newContact){
			accountIds.add(conRecord.AccountId);
		}	
		updateCount(accountIds);
    }

    public void OnAfterUndelete( List<Contact> newContact, List<Contact> oldContact, Map<ID, Contact> newContactMap , Map<ID, Contact> oldContactMap ) {
		Set<Id> accountIds = new Set<Id>();
        for(Contact conRecord : newContact){
			accountIds.add(conRecord.AccountId);
		}	
		updateCount(accountIds);
    }

    public void OnAfterUpdate( List<Contact> newContact, List<Contact> oldContact, Map<ID, Contact> newContactMap , Map<ID, Contact> oldContactMap ) {
		Set<Id> accountIds = new Set<Id>();
        for(Contact conRecord : newContact) {
            if(conRecord.AccountId != oldContactMap.get(conRecord.Id).AccountId) {
                accountIds.add(conRecord.AccountId);
                accountIds.add(oldContactMap.get(conRecord.Id).AccountId);
            }
        }    
		updateCount(accountIds);
    }
	
    public void OnAfterDelete( List<Contact> newContact, List<Contact> oldContact, Map<ID, Contact> newContactMap , Map<ID, Contact> oldContactMap )
    {
		Set<Id> accountIds = new Set<Id>();
        for(Contact conRecord : oldContact ){
            accountIds.add(conRecord.AccountId);
		}	
		updateCount(accountIds);
    }
	
	
	public static void updateCount( Set<Id> accountIds ) {
	
		if(accountIds.size() > 0) {
			List<Account> accountList = [SELECT Roll_up_Contact__c, (SELECT Id FROM Contacts) FROM Account WHERE Id in: accountIds];
			if(accountList.size() > 0){
				for(Account accRecord : accountList)
				{
					accRecord.Roll_up_Contact__c = accRecord.Contacts.size();
				}	
				UPDATE accountList;
			}
		}
    }	
	
}

Please check below post for Trigger Framework
http://amitsalesforce.blogspot.com/2015/06/trigger-best-practices-sample-trigger.html

Let us know if this will help you
This was selected as the best answer