Use Case:
Example 10.
Write an Apex trigger named “OpportunityTrigger” that automatically updates a custom field named “TotalOpportunityAmount” on the Account object whenever an Opportunity related to that Account is closed/won.
The custom field should contain the sum of the Amount values from all closed/won Opportunities associated with the Account. Ensure that the trigger follows Salesforce Apex trigger best practices and handles bulk updates correctly.
trigger OpportunityTrigger on Opportunity (after insert, after update, after delete, after undelete) {if (Trigger.isAfter && (Trigger.isInsert || Trigger.isUpdate || Trigger.isDelete || Trigger.isUndelete)) {OpportunityTriggerHandler.handleTrigger(Trigger.new, Trigger.oldMap, Trigger.isInsert, Trigger.isUpdate, Trigger.isDelete, Trigger.isUndelete);}}public class OpportunityTriggerHandler {public static void handleTrigger(List<Opportunity> newOpportunities, Map<Id, Opportunity> oldOpportunitiesMap,Boolean isInsert, Boolean isUpdate, Boolean isDelete, Boolean isUndelete) {if (isInsert || isUpdate || isUndelete) {updateAccountTotalOpportunityAmount(newOpportunities);} else if (isDelete) {updateAccountTotalOpportunityAmount(getClosedWonOpportunities(oldOpportunitiesMap.values()));}}private static List<Opportunity> getClosedWonOpportunities(List<Opportunity> opportunities) {List<Opportunity> closedWonOpportunities = new List<Opportunity>();for (Opportunity opportunity : opportunities) {if (opportunity.StageName == 'Closed Won') {closedWonOpportunities.add(opportunity);}}return closedWonOpportunities;}private static void updateAccountTotalOpportunityAmount(List<Opportunity> opportunities) {Set<Id> accountIds = new Set<Id>();for (Opportunity opportunity : opportunities) {accountIds.add(opportunity.AccountId);}List<Account> accountsToUpdate = [SELECT Id,(SELECT Amount, StageName FROM Opportunities WHERE StageName = 'Closed Won')FROM Account WHERE Id IN :accountIds];for (Account account : accountsToUpdate) {Decimal totalAmount = 0;for (Opportunity opportunity : account.Opportunities) {if (opportunity.StageName == 'Closed Won') {totalAmount += opportunity.Amount;}}account.TotalOpportunityAmount__c = totalAmount;}update accountsToUpdate;}}
Test Class:
@isTestprivate class OpportunityTriggerTest {@testSetupstatic void setupTestData() {// Create test dataAccount testAccount = new Account(Name = 'Test Account');insert testAccount;// Create OpportunitiesList<Opportunity> testOpportunities = new List<Opportunity>();testOpportunities.add(new Opportunity(Name = 'Opportunity 1', StageName = 'Closed Won',Amount = 2000, AccountId = testAccount.Id,CloseDate = Date.today().addDays(10)));testOpportunities.add(new Opportunity(Name = 'Opportunity 2', StageName = 'Closed Lost',Amount = 1000, AccountId = testAccount.Id,CloseDate = Date.today().addDays(5)));insert testOpportunities;}@isTeststatic void testOpportunityTrigger() {// Retrieve test dataAccount testAccount = [SELECT Id, TotalOpportunityAmount__c FROM Account LIMIT 1];System.assertEquals(2000, testAccount.TotalOpportunityAmount__c);Opportunity testOpportunity = [SELECT Id, StageName, Amount FROM Opportunity WHERE StageName = 'Closed Won' LIMIT 1];// Test Opportunity InsertionOpportunity newOpportunity = new Opportunity(Name = 'New Opportunity', StageName = 'Closed Won',Amount = 1500, AccountId = testAccount.Id,CloseDate = Date.today().addDays(15));insert newOpportunity;testAccount = [SELECT Id, TotalOpportunityAmount__c FROM Account WHERE Id = :testAccount.Id];System.assertEquals(3500, testAccount.TotalOpportunityAmount__c);// Test Opportunity Update to Closed WontestOpportunity.StageName = 'Closed Lost';update testOpportunity;testAccount = [SELECT Id, TotalOpportunityAmount__c FROM Account WHERE Id = :testAccount.Id];System.assertEquals(1500, testAccount.TotalOpportunityAmount__c);// Test Opportunity Update from Closed Lost to Closed WontestOpportunity.StageName = 'Closed Won';update testOpportunity;testAccount = [SELECT Id, TotalOpportunityAmount__c FROM Account WHERE Id = :testAccount.Id];System.assertEquals(3500, testAccount.TotalOpportunityAmount__c);// Test Opportunity Deletiondelete testOpportunity;testAccount = [SELECT Id, TotalOpportunityAmount__c FROM Account WHERE Id = :testAccount.Id];System.assertEquals(1500, testAccount.TotalOpportunityAmount__c);// Test Opportunity Undeleteundelete testOpportunity;testAccount = [SELECT Id, TotalOpportunityAmount__c FROM Account WHERE Id = :testAccount.Id];System.assertEquals(3500, testAccount.TotalOpportunityAmount__c);}}
Code Coverage: 100%