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
Rida JRida J 

CloseWon count

I have  an account object on which I should create a field named 'close won count', whenever the opportunities associated to the account stage name change from open or prospecting to Close Won then the count on account field  'close won count' should increment by 1. And if the stage name is close won and from this it changes to any other stage name the count on 'close won count' should get decremented.
Path to follow: use trigger handler for logic. trigger on opportunity. For condition check try to use old values as it is going to be on update trigger
Best Answer chosen by Rida J
AnkaiahAnkaiah (Salesforce Developers) 
By using Apex class, you can avoid the logic in trigger. 

try with below code.

Apex trigger:
Trigger closedwoncountOpportunity on opportunity (after insert,after update, after delete) {
    OpportunityTriggerHandler handler = new OpportunityTriggerHandler();
	if(Trigger.isDelete){
		handler.OnAfterDelete(trigger.old)
    }
	if(Trigger.isInsert){
		handler.OnAfterInsert(trigger.new)
	
	}
	if(Trigger.isUpdate){
		handler.OnAfterUpdate(trigger.new)
	}
}

Apex class:
public with sharing class OpportunityTriggerHandler 
{

Public void OnAfterInsert(List<Opportunity> newopps){

Set<Id> AccountIds = new Set<Id>();	
    for(Opportunity op : newopps)
    {
        AccountIds.add(op.AccountId);
    }

}

Public void OnAfterUpdate(List<Opportunity> newopps){

Set<Id> AccountIds = new Set<Id>();	
    for(Opportunity op : newopps)
    {
        AccountIds.add(op.AccountId);
    }

}

Public void OnAfterDelete(List<Opportunity> oldopps){

Set<Id> AccountIds = new Set<Id>();	
    for(Opportunity op : oldopps)
    {
        AccountIds.add(op.AccountId);
    }

}

public static void updateCount( Set<Id> accountIds ) {

If(accountIds.size()>0){
List<AggregateResult> lstResult = [SELECT AccountId, COUNT(Id) countId 
                                        FROM Opportunity 
                                        WHERE AccountId IN:AccountIds AND StageName='ClosedWon'
                                        GROUP BY AccountId];

    List<Account> lstAccount = new List<Account>();
    for(AggregateResult result:lstResult)
    {
        Account acct = new Account (Id=(Id)result.get('AccountId'), 
                                        Closed_Won_Count__c = (Integer)result.get('countId'));

        lstAccount.add(acct);
    }

    update lstAccount; 
}

}


}

If this helps, Please mark it as best answer.

Thanks!!​​​​​​​

All Answers

Daniee DanielsDaniee Daniels
https://bdftpservers.com/discovery-ftp/ (https://bdftpservers.com)
AnkaiahAnkaiah (Salesforce Developers) 
Hi Rida,

Try with below code.
trigger closedwoncountOpportunity on Opportunity (after insert, after delete, after update) 
{
    Set<Id> AccountIds = new Set<Id>();

    list<Account> accList = new List<Account>();
	if(trigger.Isafter && (trigger.Isinsert ||trigger.Isupdate)){
    for(Opportunity op : trigger.new)
    {
        AccountIds.add(op.AccountId;)
    }
	}
	
	if(trigger.Isafter && trigger.Isdelete){
    for(Opportunity op : trigger.old)
    {
        AccountIds.add(op.AccountId;)
    }
	}
	
    List<AggregateResult> lstResult = [SELECT AccountId, COUNT(Id) countId 
                                        FROM Opportunity 
                                        WHERE AccountId IN:AccountIds AND StageName='ClosedWon'
                                        GROUP BY AccountId];

    List<Account> lstAccount = new List<Account>();
    for(AggregateResult result:lstResult)
    {
        Account acct = new Account (Id=(Id)result.get('AccountId'), 
                                        Closed_Won_Count__c = (Integer)result.get('countId'));

        lstAccount.add(acct);
    }

    update lstAccount; 
}

If this helps, Please mark it as best answer.

Thanks!!
Rida JRida J
I also wanted that all the best practice should be followed, how about if you could tell me this when the logic is written in the trigger
handler?
AnkaiahAnkaiah (Salesforce Developers) 
By using Apex class, you can avoid the logic in trigger. 

try with below code.

Apex trigger:
Trigger closedwoncountOpportunity on opportunity (after insert,after update, after delete) {
    OpportunityTriggerHandler handler = new OpportunityTriggerHandler();
	if(Trigger.isDelete){
		handler.OnAfterDelete(trigger.old)
    }
	if(Trigger.isInsert){
		handler.OnAfterInsert(trigger.new)
	
	}
	if(Trigger.isUpdate){
		handler.OnAfterUpdate(trigger.new)
	}
}

Apex class:
public with sharing class OpportunityTriggerHandler 
{

Public void OnAfterInsert(List<Opportunity> newopps){

Set<Id> AccountIds = new Set<Id>();	
    for(Opportunity op : newopps)
    {
        AccountIds.add(op.AccountId);
    }

}

Public void OnAfterUpdate(List<Opportunity> newopps){

Set<Id> AccountIds = new Set<Id>();	
    for(Opportunity op : newopps)
    {
        AccountIds.add(op.AccountId);
    }

}

Public void OnAfterDelete(List<Opportunity> oldopps){

Set<Id> AccountIds = new Set<Id>();	
    for(Opportunity op : oldopps)
    {
        AccountIds.add(op.AccountId);
    }

}

public static void updateCount( Set<Id> accountIds ) {

If(accountIds.size()>0){
List<AggregateResult> lstResult = [SELECT AccountId, COUNT(Id) countId 
                                        FROM Opportunity 
                                        WHERE AccountId IN:AccountIds AND StageName='ClosedWon'
                                        GROUP BY AccountId];

    List<Account> lstAccount = new List<Account>();
    for(AggregateResult result:lstResult)
    {
        Account acct = new Account (Id=(Id)result.get('AccountId'), 
                                        Closed_Won_Count__c = (Integer)result.get('countId'));

        lstAccount.add(acct);
    }

    update lstAccount; 
}

}


}

If this helps, Please mark it as best answer.

Thanks!!​​​​​​​
This was selected as the best answer
Rida JRida J
Hey I also try using this code, could you tell me handler for this trigger??
trigger getRelatedOpportunitiesCount on Opportunity (after insert,after update, after delete, after undelete){
    Set<Id> accID = new Set<Id>();
    if(Trigger.isInsert || Trigger.isUpdate || Trigger.isUndelete){
        for(Opportunity opp : Trigger.New){
            accID.add(opp.AccountId);
        }
        updateAcc(accID);
    }
    else if(Trigger.isDelete){
        for(Opportunity opp : Trigger.old){
            accID.add(opp.AccountId);
        }
        updateAcc(accID);
    }
    private void updateAcc(Set<Id> accIds){
        List<Account> accList = [select id, Close_Won_Count__c from Account where Id in :accIds];
        List<Opportunity> oppsList = [select id from Opportunity where AccountId in :accIds and StageName='Closed Won'];
        for(Account a : accList){
            a.Close_Won_Count__c= oppsList.size();
        }
        update accList;
    }
}