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
Amit Karlekar 4Amit Karlekar 4 

Apex Trigger Question

I would appreciate help with the following trigger question:


Write a trigger, Whenever an Opportunity is Created, Updated, Deleted, or Undeleted then Roll-Up the Opportunity amount to Account's Annual Revenue.

I have tried it with the handler class. I have just begun learning triggers, so I make a lot of silly mistakes. Any small help/guidance you can give will be helpful.

Trigger/Handle I wrote is:

 

Trigger: trigger PopulateOppAmntToAccAmnt on Opportunity (before insert) {

    if(Trigger.isInsert) {
        if(Trigger.isAfter) {
            CopyOppAmntToAccAmnt.populateAccAmnt(Trigger.new);
        }
    }
    
    if(Trigger.isDelete) {
        if(Trigger.isAfter) {
            CopyOppAmntToAccAmnt.populateAccAmnt(Trigger.old);
        }
    }
    
    if(Trigger.isUndelete) {
        if(Trigger.isAfter) {
            CopyOppAmntToAccAmnt.populateAccAmnt(Trigger.new);
        }
    }
    
    if(Trigger.isUpdate) {
        if(Trigger.isAfter) {
            CopyOppAmntToAccAmnt.populateAccAmnt(Trigger.new);
        }
    }  
}

 

Handle Class:
public class CopyOppAmntToAccAmnt {

    public static void populateAccAmnt(List<Opportunity> oppList) {
        
        Set<Id> accId = new Set<Id>();
        List<Account> accList = new List<Account>();
        
        for(Opportunity opp : oppList) {
            if(opp.AccountId != null) {
                accId.add(opp.AccountId);
            }
        }
        
        for(Account acc : [SELECT Id, Name, AnnualRevenue,
                          (SELECT Id, Name, Amount FROM Opportunities)
                          FROM Account WHERE Id IN: accId]) {
            acc.AnnualRevenue = acc.Opportunities.Amount;
                              accList.add(acc);
        }
    }
}

Gian Piere VallejosGian Piere Vallejos
Hello, 

First of all, the rule number one of any Salesforce Developer is to evalute using Declarative solutions before use code. In this case, your problem can be solved by using a roll-up summary field in the Acount Object that SUM all the Opportuninie's amount. You should go for it. 

Just for learning purposes, I'll share you how the trigger would be (in a fast way, this can be improved more). 

Please, always try to use declarative solutions. If you are not familiar with it, try to study the main subjects related to the Associate, Admin and App Builder Certifications of Salesforce.

TRIGGER CODE: 
trigger PopulateOppAmntToAccAmnt on Opportunity (after insert, after delete, after undelete, after update) {
  if(Trigger.isInsert) {
    if(Trigger.isAfter) {
        CopyOppAmntToAccAmnt.populateAccAmnt(Trigger.new);
    }
  }

  if(Trigger.isDelete) {
      if(Trigger.isAfter) {
          CopyOppAmntToAccAmnt.populateAccAmnt(Trigger.old);
      }
  }

  if(Trigger.isUndelete) {
      if(Trigger.isAfter) {
          CopyOppAmntToAccAmnt.populateAccAmnt(Trigger.new);
      }
  }

  if(Trigger.isUpdate) {
      if(Trigger.isAfter) {
          CopyOppAmntToAccAmnt.populateAccAmnt(Trigger.new);
      }
  }  
}

HANDLER CLASS:
public with sharing class CopyOppAmntToAccAmnt {
    public static void populateAccAmnt(List<Opportunity> oppList) {
        
        Set <Id> accIds = new Set <Id> ();
        for (Opportunity opp : oppList) {
            accIds.add(opp.AccountId);
        }

        List <Opportunity> opps = [SELECT AccountId, Amount FROM Opportunity WHERE AccountId IN :accIds];

        Map <Id, Decimal> annualRevuenueMap = new Map <Id, Decimal>();
        for (Opportunity opp : opps) {
            if (annualRevuenueMap.containsKey(opp.AccountId)) {
                Decimal value = annualRevuenueMap.get(opp.AccountId) + opp.Amount;
                annualRevuenueMap.put(opp.AccountId, value);
            } else {
                annualRevuenueMap.put(opp.AccountId, opp.Amount);
            }
        }

        List <Account> accs = [SELECT Id, annualRevenue FROM Account WHERE Id IN :annualRevuenueMap.keySet()];
        if (!accs.isEmpty()) {
            for (Account acc : accs) {
                acc.AnnualRevenue = annualRevuenueMap.get(acc.Id);
            }
            update accs;
        }
    }
}

I hope this would help you.
SubratSubrat (Salesforce Developers) 
Hello ,

Your trigger and handler class look mostly correct, but there are a few adjustments you need to make to correctly roll up the Opportunity amounts to the Account's Annual Revenue.

Trigger:
trigger PopulateOppAmntToAccAmnt on Opportunity (after insert, after update, after delete, after undelete) {
    if (Trigger.isInsert || Trigger.isUpdate) {
        CopyOppAmntToAccAmnt.populateAccAmnt(Trigger.new);
    } else if (Trigger.isDelete) {
        CopyOppAmntToAccAmnt.populateAccAmnt(Trigger.old);
    } else if (Trigger.isUndelete) {
        CopyOppAmntToAccAmnt.populateAccAmnt(Trigger.new);
    }
}


Handler Class:
public class CopyOppAmntToAccAmnt {
    public static void populateAccAmnt(List<Opportunity> oppList) {
        Set<Id> accIds = new Set<Id>();
        for (Opportunity opp : oppList) {
            if (opp.AccountId != null) {
                accIds.add(opp.AccountId);
            }
        }
        
        List<Account> accListToUpdate = new List<Account>();
        for (Account acc : [SELECT Id, Name, AnnualRevenue,
                            (SELECT Amount FROM Opportunities)
                            FROM Account WHERE Id IN :accIds]) {
            Decimal totalAmount = 0;
            for (Opportunity opp : acc.Opportunities) {
                totalAmount += opp.Amount;
            }
            acc.AnnualRevenue = totalAmount;
            accListToUpdate.add(acc);
        }
        
        if (!accListToUpdate.isEmpty()) {
            update accListToUpdate;
        }
    }
}
Now, when an Opportunity is created, updated, deleted, or undeleted, the trigger will invoke the populateAccAmnt method in the handler class. The handler class will query the related Accounts and their Opportunities, sum up the amounts, and update the Annual Revenue field of the respective Accounts.

Hope this helps !
Thank you.