trigger <TriggerName> on <ObjectName> (<trigger_events>) {
// Trigger logic goes here
}
public class TriggerHandlerName {
public static void beforeInsert(List<sObject> newList) {
// before insert logic
}
}
trigger AccountTrigger on Account (before insert, after insert) {
// Check if the trigger is running before the records are inserted
if (Trigger.isBefore && Trigger.isInsert) {
// Call the handler class method 'beforeInsert' to handle the before insert logic
AccountTriggerHandler.beforeInsert(Trigger.new);
}
// Check if the trigger is running after the records have been inserted
if (Trigger.isAfter && Trigger.isInsert) {
// Call the handler class method 'afterInsert' to handle the after insert logic
AccountTriggerHandler.afterInsert(Trigger.new, Trigger.newMap);
}
}
public class AccountTriggerHandler {
// Method for handling 'before insert' event
public static void beforeInsert(List<Account> newAccountList) {
// Logic for before insert goes here
for (Account acc : newAccountList) {
// Example: Setting a default value before insert
acc.Name = acc.Name != null ? acc.Name : 'Default Account Name';
}
}
// Method for handling 'after insert' event
public static void afterInsert(List<Account> newAccountList, Map<Id,Account> newAccountMap) {
// Logic for after insert goes here
for (Account acc : newAccountList) {
// Example: Logic after record is inserted
System.debug('Account inserted: ' + acc.Id);
}
}
// Add other methods for other trigger events (before update, after delete, etc.)
}
Create Automation on Account and Contact:
a) If a user updates the Email field on the Account, automatically updates the Email field of all related Contacts.
b) If a user updates the Email field on a Contact, automatically update the Email field of the related Account.
c) Create Test class.
/*
a) Account Trigger
*/
trigger AccountTrigger on Account (after update) {
if(Trigger.isAfter && Trigger.isUpdate){
AccountTriggerHandler.afterUpdate(Trigger.new, Trigger.oldMap);
}
}
/*
*********************************************************
Apex Class Name : AccountTriggerHandler
Created Date : 05-02-2025
@description : This is class is used for Account Trigger
@author : Dipak Kumar
*********************************************************
*/
public class AccountTriggerHandler {
/*
*********************************************************
@Method Name : afterUpdate
@author : Dipak Kumar
@description : this method is used for custom logic on trigger after update execution
@param : Trigger.new
@param : Trigger.oldMap
@return : void
********************************************************
*/
public static void afterUpdate(List<Account> newAccountList, Map<Id, Account> oldAccountMap) {
Set<Id> accountIds = new Set<Id>();
// Loop through updated Accounts
for (Account acc : newAccountList) {
// Check if Email__c is changed
if (acc.Email__c != null && acc.Email__c != oldAccountMap.get(acc.Id).Email__c) {
accountIds.add(acc.Id); // Store the Account Ids where Email has changed
}
}
// If there are affected accounts, update the related contacts
if (!accountIds.isEmpty()) {
List<Contact> contactUpdateList = new List<Contact>();
// Query contacts related to the modified accounts
for (Contact con : [SELECT Id, AccountId, Email, Account.Email__c
FROM Contact
WHERE AccountId IN :accountIds]) {
// Update contact email if it differs from the Account email
if (con.Email != con.Account.Email__c) {
con.Email = con.Account.Email__c;
contactUpdateList.add(con);
}
}
// Perform update only if there are changes
if (!contactUpdateList.isEmpty()) {
update contactUpdateList;
}
}
}
}
/*
b) Contact Trigger
*/
trigger ContactTrigger on Contact (before insert, after insert, after update) {
// After Insert: Perform actions like logging, related record updates, or external integrations
if (Trigger.isAfter && Trigger.isInsert) {
ContactTriggerHandler.afterInsert(Trigger.new, Trigger.newMap);
}
// After Update: Handle logic when an existing Contact record is updated
if (Trigger.isAfter && Trigger.isUpdate) {
ContactTriggerHandler.afterUpdate(Trigger.new, Trigger.oldMap);
}
}
/*
*********************************************************
Apex Class Name : ContactTriggerHandler
Created Date : 05-02-2025
@description : This is class is used for Contact Trigger
@author : Dipak Kumar
*********************************************************
*/
public class ContactTriggerHandler {
/*
*********************************************************
@Method Name : afterUpdate
@author : Dipak Kumar
@description : this method is used for custom logic on trigger befor update execution
@param : Trigger.new
@return : void
********************************************************
*/
public static void beforeInsert(List<Contact> newContactList) {
List<Account> accountList = new List<Account>(); // List to store new Accounts
Map<Contact, Account> contactAccountMap = new Map<Contact, Account>(); // Map to associate Contact with new Account
for (Contact con : newContactList) {
// Check if Contact has no associated Account
if (con.AccountId == null) {
Account acc = new Account(Name = con.LastName); // Create a new Account using Contact's Last Name
contactAccountMap.put(con, acc);
accountList.add(acc);
}
}
// Insert newly created Accounts and update Contacts with the new Account Ids
if (!contactAccountMap.isEmpty()) {
insert contactAccountMap.values(); // Insert Accounts
for (Contact con : contactAccountMap.keySet()) {
con.AccountId = contactAccountMap.get(con).Id; // Assign new Account Id to Contact
}
}
}
/*
*********************************************************
@Method Name : afterInsert
@author : Dipak Kumar
@description : this method is used for custom logic on trigger after insert execution
@param : Trigger.new
@param : Trigger.newMap
@return : void
********************************************************
*/
public static void afterInsert(List<Contact> newContactList, Map<Id, Contact> newContactMap) {
List<Account> accList = new List<Account>(); // List to store Accounts for update
for (Contact con : newContactList) {
// If the Contact is linked to an Account, update the Account's Email
if (con.AccountId != null) {
Account acc = new Account(Id = con.AccountId);
acc.Email__c = con.Email;
accList.add(acc);
}
}
System.debug(' =====> After Insert accList : ' + accList);
// Perform the update only if there are accounts to update
if (!accList.isEmpty()) {
update accList;
}
}
/*
*********************************************************
@Method Name : afterUpdate
@author : Dipak Kumar
@description : this method is used for custom logic on trigger after update execution
@param : Trigger.new
@param : Trigger.oldMap
@return : void
********************************************************
*/
public static void afterUpdate(List<Contact> newContactList, Map<Id, Contact> oldContactMap) {
Set<Id> accountIdSet = new Set<Id>(); // Store unique Account Ids
Map<Id, String> accountEmailMap = new Map<Id, String>(); // Map to track Account Email updates
for (Contact con : newContactList) {
// If Contact has an Account, store its Id and Email
if (con.AccountId != null) {
accountIdSet.add(con.AccountId);
accountEmailMap.put(con.AccountId, con.Email);
}
}
List<Account> accountToUpdate = new List<Account>();
// Query Accounts that need Email updates
if (!accountIdSet.isEmpty()) {
for (Account acc : [SELECT Id, Email__c FROM Account WHERE Id IN :accountIdSet]) {
// Update Account Email if it differs from Contact Email
if (accountEmailMap.containsKey(acc.Id) && acc.Email__c != accountEmailMap.get(acc.Id)) {
acc.Email__c = accountEmailMap.get(acc.Id);
accountToUpdate.add(acc);
}
}
// Update Accounts if there are any changes
if (!accountToUpdate.isEmpty()) {
update accountToUpdate;
}
}
}
}
/*
Create Apex Trigger on Case Object to calculate and store the number of hours a case
remains in a specific status?
a) Add a custom field on the Case object called "Status Waiting Hour".
b) The purpose of this field is to track the total time (in hours a case stays in a
specific status. For example, if the status is "New"
and gets updated to another value (e.g.,"Web") after 48 hours,
the "Status Waiting Hour" field should show 48 hours.
Note :
create two fields Last_Status_Change__c and Status_Waiting_Hour__c
*/
// Trigger on Case object to handle logic before insert and update operations.
trigger CaseTrigger on Case (before update, before insert) {
// Before Insert: Calls the handler method to execute logic before inserting a new Case record.
if(Trigger.isBefore && Trigger.isInsert){
CaseTriggerHandler.beforeInsert(Trigger.new);
}
// Before Update: Calls the handler method to execute logic before updating an existing Case record.
if(Trigger.isBefore && Trigger.isUpdate){
CaseTriggerHandler.beforeUpdate(Trigger.new, Trigger.oldMap);
}
}
/*
*********************************************************
Apex Class Name : CaseTriggerHandler
Created Date : 05-02-2025
@description : This is handler class is used for Case Trigger
@author : Dipak Kumar
*********************************************************
*/
public class CaseTriggerHandler {
/*
*********************************************************
@Method Name : afterUpdate
@author : Dipak Kumar
@description : this method is used for custom logic on trigger after update execution
@param : Trigger.new
@param : Trigger.oldMap
@return : void
********************************************************
*/
public static void beforeInsert(List<Case> newCaseList) {
for (Case caseObj : newCaseList) {
// Set the initial timestamp when the case is created
caseObj.Last_Status_Change__c = Datetime.now();
}
}
/*
*********************************************************
@Method Name : beforeUpdate
@author : Dipak Kumar
@description : this method is used for custom logic on trigger before update execution
@param : Trigger.new
@param : Trigger.oldMap
@return : void
********************************************************
*/
public static void beforeUpdate(List<Case> newCaseList, Map<Id, Case> oldCaseMap) {
for (Case caseObj : newCaseList) {
// Check if the Status field has changed
if (caseObj.Status != oldCaseMap.get(caseObj.Id).Status) {
// Ensure the previous timestamp exists before calculating hours spent
if (caseObj.Last_Status_Change__c != null) {
// Calculate the time difference in hours between status changes
Decimal hoursSpent = (Datetime.now().getTime() - caseObj.Last_Status_Change__c.getTime()) / (1000 * 60 * 60);
// Accumulate the total hours spent in previous statuses
if (caseObj.Status_Waiting_Hour__c != null) {
caseObj.Status_Waiting_Hour__c += hoursSpent;
} else {
caseObj.Status_Waiting_Hour__c = hoursSpent;
}
}
// Update the Last_Status_Change__c field to track the time of the new status change
caseObj.Last_Status_Change__c = Datetime.now();
}
}
}
}