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:

@isTest
private class OpportunityTriggerTest {
@testSetup
static void setupTestData() {
// Create test data
Account testAccount = new Account(Name = 'Test Account');
insert testAccount;

// Create Opportunities
List<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;
}

@isTest
static void testOpportunityTrigger() {
// Retrieve test data
Account 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 Insertion
Opportunity 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 Won
testOpportunity.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 Won
testOpportunity.StageName = 'Closed Won';
update testOpportunity;

testAccount = [SELECT Id, TotalOpportunityAmount__c FROM Account WHERE Id = :testAccount.Id];
System.assertEquals(3500, testAccount.TotalOpportunityAmount__c);

// Test Opportunity Deletion
delete testOpportunity;

testAccount = [SELECT Id, TotalOpportunityAmount__c FROM Account WHERE Id = :testAccount.Id];
System.assertEquals(1500, testAccount.TotalOpportunityAmount__c);
// Test Opportunity Undelete
undelete testOpportunity;
testAccount = [SELECT Id, TotalOpportunityAmount__c FROM Account WHERE Id = :testAccount.Id];
System.assertEquals(3500, testAccount.TotalOpportunityAmount__c);
}
}
Code Coverage: 100%
Like it ? Share : Do Nothing

Leave a Reply