Apex Trigger Interview Scenarios – Part 2
By Aman Garg · Published · Interview Questions

Here are a few common Salesforce Apex Trigger Interview Scenarios along with their answers:
1. Create a trigger to change the account owner at the stage of close won.
trigger UpdateAccount on Opportunity (After Update){
if(trigger.isAfter && trigger.isUpdate){
List<Opportunity> oppsToUpdate = new List<Opportunity>();
for (Opportunity opp : Trigger.new) {
if(opp.stageName == 'Closed Won' || Trigger.oldMap.get(opp.Id).StageName != 'Close Won'){
opp.Account.OwnerId = 'new_owner_id';
oppsToUpdate.add(opp);
}
}
if (!oppsToUpdate.isEmpty()) {
update oppsToUpdate;
}
}
}2. Create a trigger to update the amount field on the account object based on the contact amount.
trigger UpdateAccountAmountBasedOnContacts on Contact (after insert, after update, after delete) {
Set<Id> accountIdsToUpdate = new Set<Id>();
if (Trigger.isInsert || Trigger.isUpdate) {
for (Contact contact : Trigger.new) {
accountIdsToUpdate.add(contact.AccountId);
}
}
if (Trigger.isDelete) {
for (Contact contact : Trigger.old) {
accountIdsToUpdate.add(contact.AccountId);
}
}
List<Account> accountsToUpdate = new List<Account>();
for (Id accountId : accountIdsToUpdate) {
// Calculate the sum of Amount from related Contacts
List<Contact> relatedContacts = [SELECT Amount__c FROM Contact WHERE AccountId = :accountId];
Decimal totalAmount = 0;
for (Contact c : relatedContacts) {
if (c.Amount__c != null) {
totalAmount += c.Amount__c;
}
}
// Update the Amount field on the Account
Account acc = new Account(Id = accountId, Amount__c = totalAmount);
accountsToUpdate.add(acc);
}
// Perform the updates
if (!accountsToUpdate.isEmpty()) {
update accountsToUpdate;
}
}3. Create a trigger on the account to update the no of contact which is associated with the particular contact.
trigger UpdateContactCount on Contact (after insert, after update, after delete) {
Set<Id> accountIds = new Set<Id>();
if (Trigger.isInsert || Trigger.isUpdate) {
for (Contact contact : Trigger.new) {
accountIds.add(contact.AccountId);
}
}
if (Trigger.isDelete) {
for (Contact contact : Trigger.old) {
accountIds.add(contact.AccountId);
}
}
List<Account> accountsToUpdate = new List<Account>();
for (Id accountId : accountIds) {
// Query the number of Contacts associated with each Account
Integer contactCount = [SELECT Count() FROM Contact WHERE AccountId = :accountId];
// Retrieve the Account and update the Contact_Count__c custom field
Account acc = new Account(Id = accountId, Contact_Count__c = contactCount);
accountsToUpdate.add(acc);
}
if (!accountsToUpdate.isEmpty()) {
update accountsToUpdate;
}
}4. Create a trigger on the account object to show an error message if the account has more than 2 contacts.
trigger UpdateContactCount on Contact (after insert, after update, after delete) {
Set<Id> accountIds = new Set<Id>();
if (Trigger.isInsert || Trigger.isUpdate) {
for (Contact contact : Trigger.new) {
accountIds.add(contact.AccountId);
}
}
if (Trigger.isDelete) {
for (Contact contact : Trigger.old) {
accountIds.add(contact.AccountId);
}
}
List<Account> accountsToUpdate = new List<Account>();
for (Id accountId : accountIds) {
Integer contactCount = [SELECT Count() FROM Contact WHERE AccountId = :accountId];
Account acc = new Account(Id = accountId, NumberOfContacts__c = contactCount);
accountsToUpdate.add(acc);
}
if (!accountsToUpdate.isEmpty()) {
update accountsToUpdate;
}
}5. If any workOrderItem is associated with WorkOrder then update the primary checkbox is true.
trigger UpdatePrimaryOnWorkOrder on WorkOrderItem (after insert, after update, after delete, after undelete) {
Set<Id> workOrderIds = new Set<Id>();
if (Trigger.isInsert || Trigger.isUpdate || Trigger.isDelete || Trigger.isUndelete) {
for (WorkOrderItem workOrderItem : Trigger.new) {
workOrderIds.add(workOrderItem.WorkOrderId);
}
}
List<WorkOrder> workOrdersToUpdate = new List<WorkOrder>();
for (Id workOrderId : workOrderIds) {
// Query for related Work Order Items
List<WorkOrderItem> relatedWorkOrderItems = [SELECT Id FROM WorkOrderItem WHERE WorkOrderId = :workOrderId];
// Update the "Primary" checkbox on the Work Order
WorkOrder workOrder = new WorkOrder(Id = workOrderId, Primary__c = !relatedWorkOrderItems.isEmpty());
workOrdersToUpdate.add(workOrder);
}
if (!workOrdersToUpdate.isEmpty()) {
update workOrdersToUpdate;
}
}6. write a trigger on the opportunity to show an error when the opportunity stage is closed won and someone trying to change the stage of opportunity
trigger PreventClosedWonChange on Opportunity (before update) {
for (Opportunity opp : Trigger.new) {
// Check if the stage is changing to "Closed Won"
if (opp.StageName == 'Closed Won') {
// Check if the previous stage was not "Closed Won"
Opportunity oldOpp = Trigger.oldMap.get(opp.Id);
if (oldOpp.StageName != 'Closed Won') {
opp.addError('You cannot change the stage to "Closed Won."');
}
}
}
}7. Write a trigger to restrict the user from creating an opportunity at 2nd time if the opportunity already exists
trigger PreventDuplicateOpportunity on Opportunity (before insert) {
Set<String> opportunityNames = new Set<String>();
for (Opportunity opp : Trigger.new) {
opportunityNames.add(opp.Name);
}
// Query for existing opportunities with the same name
List<Opportunity> existingOpportunities = [SELECT Name FROM Opportunity WHERE Name IN :opportunityNames];
for (Opportunity opp : Trigger.new) {
for (Opportunity existingOpp : existingOpportunities) {
if (opp.Name == existingOpp.Name) {
opp.addError('An opportunity with the same name already exists.');
}
}
}
}8. Write a trigger to update the address on the contact whenever update the address on account
trigger UpdateContactAddress on Account (after update) {
List<Contact> contactsToUpdate = new List<Contact>();
// Loop through the updated accounts
for (Account updatedAccount : Trigger.new) {
// Check if the Account's address fields have changed
if (Trigger.oldMap.get(updatedAccount.Id).BillingStreet != updatedAccount.BillingStreet ||
Trigger.oldMap.get(updatedAccount.Id).BillingCity != updatedAccount.BillingCity ||
Trigger.oldMap.get(updatedAccount.Id).BillingState != updatedAccount.BillingState ||
Trigger.oldMap.get(updatedAccount.Id).BillingPostalCode != updatedAccount.BillingPostalCode ||
Trigger.oldMap.get(updatedAccount.Id).BillingCountry != updatedAccount.BillingCountry) {
// Query for related contacts
List<Contact> relatedContacts = [SELECT Id, MailingStreet, MailingCity, MailingState, MailingPostalCode, MailingCountry
FROM Contact
WHERE AccountId = :updatedAccount.Id];
// Update the address on related contacts
for (Contact contact : relatedContacts) {
contact.MailingStreet = updatedAccount.BillingStreet;
contact.MailingCity = updatedAccount.BillingCity;
contact.MailingState = updatedAccount.BillingState;
contact.MailingPostalCode = updatedAccount.BillingPostalCode;
contact.MailingCountry = updatedAccount.BillingCountry;
contactsToUpdate.add(contact);
}
}
}
// Update the related contacts
if (!contactsToUpdate.isEmpty()) {
update contactsToUpdate;
}
}9. Write an apex method that takes a list of IDs of contacts and returns all the related accounts.
public class ContactAccountUtils {
// Method to retrieve related accounts for a list of contact IDs
public static List<Account> getRelatedAccounts(List<Id> contactIds) {
List<Account> relatedAccounts = new List<Account>();
// Query to retrieve related accounts for the given contact IDs
List<Contact> relatedContacts = [SELECT Id, AccountId FROM Contact WHERE Id IN :contactIds];
Set<Id> accountIds = new Set<Id>();
// Extracting Account IDs from related contacts
for (Contact relatedContact : relatedContacts) {
accountIds.add(relatedContact.AccountId);
}
// Query to retrieve related accounts for the extracted Account IDs
if (!accountIds.isEmpty()) {
relatedAccounts = [SELECT Id, Name FROM Account WHERE Id IN :accountIds];
}
return relatedAccounts;
}
}trigger ContactTrigger on Contact (after insert, after update) {
List<Id> contactIds = new List<Id>();
for (Contact contact : Trigger.new) {
contactIds.add(contact.Id);
}
List<Account> relatedAccounts = ContactAccountUtils.getRelatedAccounts(contactIds);
}