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
Arundhati DebArundhati Deb 

How to write a trigger to update a field in account by adding the amount field of different opportunities against that account.

I have a field called '"credit blocked" on account. I need to update this field by adding the amount field of different opportunities against this account. Also only those opportunities have to be considered whose stage is not "closed won" or "closed lost." I have to write a trigger.
 
Best Answer chosen by Arundhati Deb
Khan AnasKhan Anas (Salesforce Developers) 
Hi Arundhati,

I trust you are doing very well.

Below is the sample code which I have tested in my org and it is working fine. Kindly modify the code as per your requirement.
 
trigger UpdateAmount on Opportunity (after insert, after update) {
    
    Map<Id, List<Opportunity>> acctIdOppt = new Map<Id, List<Opportunity>>();
    Set<Id> acctIds = new Set<Id>();
    List<Opportunity> oppList = new List<Opportunity>();
    if(trigger.isUpdate || trigger.isInsert){
        for(Opportunity opp : trigger.New){
            if(opp.AccountId != null && opp.StageName != 'Closed Won' && opp.StageName != 'Closed Won'){
                acctIds.add(opp.AccountId);
            }
        }    
    }
    if(trigger.isDelete){
        for(Opportunity opp : trigger.old){
            if(opp.AccountId != null && opp.StageName != 'Closed Won' && opp.StageName != 'Closed Won'){
                acctIds.add(opp.AccountId);
            }
        }    
    }
    if(acctIds.size() > 0){
        oppList = [SELECT Amount, AccountId FROM Opportunity WHERE AccountId IN : acctIds];
        for(Opportunity opp : oppList){
            if(!acctIdOppt.containsKey(opp.AccountId)){
                acctIdOppt.put(opp.AccountId, new List<Opportunity>());
            }
            acctIdOppt.get(opp.AccountId).add(opp); 
        }   
        List<Account> acctList = new List<Account>();
        acctList = [SELECT Total_Amount__c FROM Account WHERE Id IN: acctIds];
        for(Account acct : acctList){
            List<Opportunity> tempOpptyList = new List<Opportunity>();
            tempOpptyList = acctIdOppt.get(acct.Id);
            Double totalOpptyAmount = 0;
            for(Opportunity opp : [SELECT AccountId, Amount, StageName FROM Opportunity WHERE AccountId IN :acctIds AND StageName!= 'Closed Won' AND StageName!= 'Closed Lost']){
                if(opp.Amount != null && opp.StageName != 'Closed Won' && opp.StageName != 'Closed Won'){
                    totalOpptyAmount += opp.Amount;
                }
            }
            acct.Total_Amount__c = totalOpptyAmount;
        }
        update acctList;
    }
}


I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in future.

Thanks and Regards,
Khan Anas

All Answers

Khan AnasKhan Anas (Salesforce Developers) 
Hi Arundhati,

I trust you are doing very well.

Below is the sample code which I have tested in my org and it is working fine. Kindly modify the code as per your requirement.
 
trigger UpdateAmount on Opportunity (after insert, after update) {
    
    Map<Id, List<Opportunity>> acctIdOppt = new Map<Id, List<Opportunity>>();
    Set<Id> acctIds = new Set<Id>();
    List<Opportunity> oppList = new List<Opportunity>();
    if(trigger.isUpdate || trigger.isInsert){
        for(Opportunity opp : trigger.New){
            if(opp.AccountId != null && opp.StageName != 'Closed Won' && opp.StageName != 'Closed Won'){
                acctIds.add(opp.AccountId);
            }
        }    
    }
    if(trigger.isDelete){
        for(Opportunity opp : trigger.old){
            if(opp.AccountId != null && opp.StageName != 'Closed Won' && opp.StageName != 'Closed Won'){
                acctIds.add(opp.AccountId);
            }
        }    
    }
    if(acctIds.size() > 0){
        oppList = [SELECT Amount, AccountId FROM Opportunity WHERE AccountId IN : acctIds];
        for(Opportunity opp : oppList){
            if(!acctIdOppt.containsKey(opp.AccountId)){
                acctIdOppt.put(opp.AccountId, new List<Opportunity>());
            }
            acctIdOppt.get(opp.AccountId).add(opp); 
        }   
        List<Account> acctList = new List<Account>();
        acctList = [SELECT Total_Amount__c FROM Account WHERE Id IN: acctIds];
        for(Account acct : acctList){
            List<Opportunity> tempOpptyList = new List<Opportunity>();
            tempOpptyList = acctIdOppt.get(acct.Id);
            Double totalOpptyAmount = 0;
            for(Opportunity opp : [SELECT AccountId, Amount, StageName FROM Opportunity WHERE AccountId IN :acctIds AND StageName!= 'Closed Won' AND StageName!= 'Closed Lost']){
                if(opp.Amount != null && opp.StageName != 'Closed Won' && opp.StageName != 'Closed Won'){
                    totalOpptyAmount += opp.Amount;
                }
            }
            acct.Total_Amount__c = totalOpptyAmount;
        }
        update acctList;
    }
}


I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in future.

Thanks and Regards,
Khan Anas
This was selected as the best answer
Steven NsubugaSteven Nsubuga
Trigger creditBlockedTrigger on Opportunity (after insert, after update, after delete) {
    
    Set<Id> accountIds = new Set<Id>();
    List<Account> accountsToUpdate = new List<Account>();
    
    if (trigger.isInsert || trigger.isUpdate) {
        for (Opportunity opp : Trigger.new) {
            if(opp.StageName != 'Closed Won' && opp.StageName != 'Closed Lost' && opp.AccountId != null) {
                accountIds.add(opp.AccountId);
            }
        }   
    }
    if (Trigger.isDelete){  
        for (Opportunity opp : Trigger.old) {
            if(opp.StageName != 'Closed Won' && opp.StageName != 'Closed Lost' && opp.AccountId != null) {
                accountIds.add(opp.AccountId);  
            }
        }
    }
    
    // get a map of the Accounts
    Map<id, Account> accountMap = new Map<id, Account>([select id, credit_blocked__c from Account where id IN :accountIds]);
    for (id accountId : accountMap.keySet()) {
        accountMap.get(accountId).credit_blocked__c = 0;
    }
    
    List<AggregateResult> ars = [SELECT AccountId, sum(amount) FROM Opportunity WHERE AccountId IN :accountIds AND StageName NOT IN ('Closed Won','Closed Lost') group by AccountId];
    for (AggregateResult ar : ars) {
        accountMap.get(String.valueOf(ar.get('AccountId'))).credit_blocked__c = Integer.valueOf(ar.get('expr0'));
    }
    update accountMap.values();
}