Salesforce Apex Trigger Scenarios

Hello everyone, I am sharing list of commonly asked apex trigger questions in interviews. Please go through them in depth.

Check Complete Series for Better Learning and for doubts post in comment section:

Points to Remember:

1.As per Order of execution before trigger fire and then after trigger fire.

  • Before insert event
  • Data committed to database
  • After insert event

2.Before triggers are used to perform the logic on the same object and it triggers fired before the data saved into the database.

3.Best way if you want to update the same record in trigger then always go with before event. This way you can skip the extra DML.

4.In Before trigger, the records are not committed to database so we can skip the DML as whatever value we give to records will naturally assigned to database. The Id is not generated because it is not committed to database

5.Once record is committed to database means the record Id is generated and your trigger records in read only mode you can’t update the values now(because it is committed to database). That’s why we need to perform extra DML for updating records.

6.If in after event if any error occurs then complete DML operation is rollback.

7.After Triggers are usually used to send Emails or update records of a different object based on the value of the record of the object on which the trigger is written

8.Avoid SOQL queries and DML inside for loops so that governor limit cannot be hit.

I hope you are clear with theory so let’s get started with scenarios:

1.Create related contact when Account is created

Trigger triggername on Account(after insert){
List<Contact> cclist = new <Contact>();
for(Account acc:trigger.new){
Contact c = new Contact();
c.lastname = acc.lastname;
c.accountid = acc.id;
cclist.add(c);
}
insert cclist;
}

2.Prefix first name with Dr when new Lead is created or updated

Trigger PrefixDoctorTrigger on Lead(before insert, before update)
{
	for(Lead l:trigger.new)
	{
		l.FirstName ='Dr' + l.FirstName;
	}
}

Test Class:

@isTest
public class PrefixDoctorTest {
    Public static testMethod void PreDoctor(){
        Lead l=new Lead();
        l.FirstName='Dr Swati';
        l.company='sfdcAmplified';
        l.Status='Open - Not Contacted;
		insert l;
		Lead le = [Select id,FirstName from Lead where company='sfdcAmplified'];
		System.assertEquals(le.FirstName.ContainsIgnoreCase('Dr'),'Dr');
    }
}

 

3. Update Account Rating to ‘Hot ‘on account when opportunity stage equals ‘closed one’

trigger updateAccountRating on opportunity(after insert,after update)
{
    Set<id> Accountids = new set<id>();
    List<Account> Accounts = new List<Account>();
        if(trigger.new != null)
        {
            for(opportunity opp:trigger.new)
            {
                if(opp.StageName =='Closed Won')
                    {
                  	  AccountIds.add(opp.AccountId);
                    }
            }
        }
    List<Account> a  = [Select id,Rating from Account where Id IN: AccountIds];
    if(a != null){
        for(Account acc: a)
       {
          acc.Rating ='Hot';
          Accounts.add(acc);
       }
    }
          update Accounts;
}

Test Class:

@istest
public class testClassForTrigger{
	public void testmethod triggerTest{
	//link account with opportunity
		account acc = new account();
		acc.name='test';
		insert acc;
		
		account acc1 = new account();
		acc1.name='test1';
		insert acc1;
		
		opportunity opp = new opportunity();
		opp.name='test opp';
		opp.stagename='closed won';
		opp.AccountId = acc.id;
		insert opp;
		
		opportunity opp1 = new opportunity();
		opp1.name='test opp';
		opp1.stagename='closed won';
		opp1.AccountId = acc1.id;
		insert opp1;
 
		test.startTest();  
		List<Account> acc = [Select id,rating from account where id =: opp.AccountId];
		acc.get[0]; //return acc object
		system.assertequals(acc.get[0].Rating,'hot');
		test.stopTest();
	}
}

 

4.Whenever phone field is updated in account then the name field should also get updated with name and phone number in accounts

Trigger updateName on Account (before update){	

for(account acc:trigger.new)
		{
			if(acc.phone != trigger.oldMap.get(acc.id).phone)
			{			
				acc.name = acc.name + acc.phone
			}
		}
}

5.Prevent account from deleting, if it has 2 or more contacts

Before delete will be used here

trigger.old, trigger.oldmap is in before delete

trigger deleteacc on Account (before delete) {
Set<id> Accountids = new Set<id>();
		for(account acc:trigger.old)
		{
		Accountids.add(acc.id);
		}
	
List<Account> account = [select id,name,(select id, name from contacts) from account where id in: Accountids];
Map<id,Account> mapacc = new Map<id,Account>();
for(account a:account){
}
//for showing error use context variable bcoz error shows on context variable
 for(account acc:trigger.old)
		{
		if(mapacc.get(acc.id).contacts.size()>=2)
				{
				acc.adderror('account cannot be deleted');
				}
		}
	}

6.When lead is created or updated then check if the email of lead is already there in existing contacts. If email already exist then throw error.

trigger DuplicateEmailsInLead on Lead (before insert, before update) {
    map<String,Contact>  mapOfContact = new map<String, Contact>();
    list<Contact> con = [select id,email from contact];
     for (contact c:con)
     {
        mapofcontact.put(c.email,c);
   	 }
        for(lead l : trigger.new)
        {
                    if((l.email != null) && (trigger.isInsert || (l.email != trigger.oldmap.get(l.id).email))){
                        if(mapofContact.containsKey(l.email)){
                            l.Email.addError('Email already exists');
                  }                  
           }               
     }
}

7.Write a trigger to update a field (city) in Account when same field(city) is updated in opportunity

After update will be used here

Trigger.new,trigger.newmap,trigger.old, trigger.oldmap is available in after update.

trigger AccountUpdate on Account (after update) {
Set<id> AccountIds = new Set<id>();
    for(Account a: trigger.new)
    {
        if(a.city__c != trigger.oldmap.get(a.id).city__c){
        AccountIds.add(a.id);
    }
    }
    List<opportunity> opport=[select id, City__c,Accountid from Opportunity where accountid in: Accountids];
    
        for(opportunity opp:opport)
        {
                     opp.City__c = trigger.newmap.get(opp.accountid).city__c;
        }
        update opport;
}

8.Whenever TestPhoneOpportunity__c field in opportunity is updated ,its related field (TestPhoneAccount__c) in Account and (TestPhoneContact__c ) in Contact should get updated with the updated value with TestPhoneOpportunity__c

After update will be used here

Trigger.new,trigger.newmap,trigger.old, trigger.oldmap is available in after update.

trigger oppupdate on Opportunity(after update);
{
Set<id>accountIds  = new set<id>();
List<contact> cc = new List<Contact>();
Map<Id, opportunity> accountidtoopp = new Map<Id, opportunity>();

	if(trigger.new!=null)
	{
		for(opportunity opp:trigger.new)
        if(opp.TestPhoneOpportunity__c != trigger.oldmap.get(opp.id).TestPhoneOpportunity__c){
			accountIds.add(opp.AccountId);
			accountidtoopp.put(op.accountid,op);

		}
	}	
	List<Account> acc = [Select id,TestPhoneAccount__c, (Select id,TestPhoneContact__c,AccountId from contacts )from Account where Id IN: accountIds ];
	
	for(Account a:acc)
	{
		a.TestPhoneAccount__c = accountidtoopp.get(a.Id).TestPhoneOpportunity__c;
		for(contact c: a.contacts){
			c.TestPhoneContact__c = accountidtoopp.get(c.AccountId).TestPhoneOpportunity__c;
			cc.add(c);
		}
	}
	update acc;
	update cc;

9.When an opportunity is inserted or updated then if the stage name is ‘Closed won’ then add the task.

After insert, After update will be used here.

Trigger.new,trigger.newmap is available in after insert.

Trigger.new,trigger.newmap,trigger.old, trigger.oldmap is available in after update.

trigger ClosedOpportunityTrigger on Opportunity (after insert, after update) {
   List<Task> taskList = new List<Task>();
    for (Opportunity o :[SELECT Id,StageName FROM Opportunity WHERE StageName ='Closed Won' AND Id IN :Trigger.New]) 
    {
        if(o.StageName == 'Closed Won')    
        {
            taskList.add(new task (Subject ='Follow Up Test Task' , WhatId=o.Id));
        }
            
    }
    if(taskList.size() > 0){
         insert taskList;
   }
}

10. Divide individual balance equally on contacts based on the total balance on related accounts whenever account is updated

After update will be used here.

Trigger.new,trigger.newmap,trigger.old,trigger.oldMap is available in after update.

Trigger calculateBalance on Account(after insert, after update)
{
 
 
List <Account> accList = [select id,name,Balance__c, (select id,name, IndividualBalance__c from Contacts) from account where Balance__c > 0];
List <Contact> contactList = new List<Contact> ();
for(Account acc: accList)
{
 if(acc.Contacts.size() >0){ 
   Decimal storeAmount = acc.Balance__c/acc.Contacts.size();
    for(Contact cc:acc.Contacts)
    {
        cc.IndividualBalance__c = storeAmount;
        contactList.add(cc);
    }
   }
}
   update contactList;
}

11. Whenever new account is created with annual revenue more than 50,000 then add Smriti Sharan as contact name

After insert will be used here.

Trigger.new and trigger.newmap is available in after insert.

Trigger annualRevenueAcc on Account(after insert){
List<Contact> cc  = new list<Contact>();
 
 
      for(Account acc:trigger.new)
    {
            if(acc.AnnualRevenue > 50,000)
              { 
			  contact con = new contact();
                 con.FirstName ='Smriti';
                 con.lastName ='Sharan';
				 con.accountid=acc.id;
				 cc.add(con);
              }  
    }      
	          insert cc;                
         }

12. Whenever account is created with industry as banking then create a contact for account,contact lastname as account name and contact phone as account phone

After insert will be used here.

AFTER triggers are usually used when information needs to be updated in a separate table/object due to a change. They run after changes have been made to the database (not necessarily committed).

Trigger.new and trigger.newmap is available in after insert.

Trigger industryAcc on Account(after insert){
List<Contact> cc = new List<Contact>();
      for( Account acc: Trigger.new)
       {
          
             if(acc.Industry =='Banking')

          {   
                Contact c=new Contact();
                c.accountid = c.id;
                c.lastname = a.name;
                c.phone=a.phone; 
                cc.add(c);
           
          }
        }  
                 insert cc;
  }

13.Whenever case is created with origin as email then set status as new and priority as Normal

Before insert  has Trigger.new

Trigger.New Returns a list of the new versions of the sObject records.

Trigger emailCase on Case(before insert){
         for(case c:trigger.new)
  {
            if(c.origin =='Email')
              {
                 c.status ='New';
                 c.priority ='Normal';
              }
  }
}

14. Whenever lead is created with lead source as web then give rating as cold otherwise hot

It will be before insert

Before insert has trigger.new.The triggernew provides the records that are about to be inserted, or updated.

Trigger leadsource on lead(before insert){
        for(lead l:trigger.new)
       {
         if(l.leadsource =='Web')
          {
             l.Rating ='Hot';
          }
        else {
             
             l.Rating='Cold';
        }
       }
}

15. Whenever account phone is modified then update contact record with phone field (otherphone with oldvalue and homephone with new value) associated with account records.

Trigger phoneAcc on Account(after update)
{
List<Contact> cc = new List<Contact>();
Set<id> accid = new Set<id>();
	{
       for(Account acc:trigger.new)
	   {
            if(acc.phone != trigger.oldMap.get(acc.id).phone){
	        accid.add(acc.id); 
             }
	   }
	}
if(!accId.isEmpty){
}

List<Account> ac= [Select id,name,(Select id, otherphone,homephone from contacts) from Account where Id =: accid]; 
for(Account acc:ac)
	{
	  
        for(contact c: acc.contacts){
           c.homephone = trigger.newMap.get(acc.id).phone;
		   c.otherphone = trigger.oldMap.get(acc.id).phone;
           cc.add(c);
          }    
     		
	}
  if(!cc.isEmpty()){
		update cc;
      }
}

16.Whenever opportunity stagename is modified to closed won then set closedate as today and type as customer.

As it is on same object so we will use before update
Before update has trigger.new,trigger.old, trigger.newmap,trigger.oldmap

To get curent date use system.today();

Trigger stageNameOpp on Opportunity(before update)
{ 
   for(Opportunity opp:trigger.new){
   if(opp.Stagename == 'Closed Won')
    {      
           opp.CloseDate= System.today();
            opp.Type ='Customer';
    }
  }     
 }
    

17.When a new contact is created for existing account then set contact other phone as account phone

Trigger  phoneCon on Contact(before insert){
	  
	  Set<id> accIds = new Set<id>;();
	  for(Contact c:trigger.new){
	  accIds.add(c.AccountId)
	  }
	  
	  Map<id,account> accmap = new Map<id,account>();
	  List<Account> a = [select id,phone from Account where id IN:accIds ];
	  for(account acc:a)
	  {
	     accmap.put(a.id,a)
	  }
	  
	  for(Contact con:trigger.new)
	  {    
	      if(con.accountId =! null)
		  {
		    con.otherphone =accmap.get(con.accountId).phone;
		  }
	  }
    }

18.When a new Account record is inserted verify the industry field value, if industry field value is Education then assign the owner as Smriti

Owner is a lookup field populating user id therefore  get user record and put that in ownerid

Trigger industryAcc on Account(before insert){
User u=[select id from User where username='smriti@sfdc.com'];

     for(Account acc:trigger.new)  
 {     

    if(acc.Industry =='Education')      
   {          
      acc.ownerId = u.id;    
  
   } 

 }
}

19.The trigger will prevent the users from deleting the Accounts. This is because System Administrator has all the permissions, we cannot change the permissions.

Trigger deleteAcc on Account(before delete){
   
 for(Account acc:trigger.old)
	{
	   acc.AddError('You Cannot Delete the Account Record')
	}
 }

20. When the value of AssistantPhone field on contact is updated , I would like the field value of phone__c the opportunity and phone on account also get updated.

Trigger UpdatePhoneOppAccTrigger on Contact(after update){
Set<id> setAccId = new Set<id>();
List<Opportunity> oppNewList = New List<Opportunity>();
List<Account> accNewList = New List<Account>();
Map<id,String> mapContactPhone = New Map<id,String>();
for(contact c: Trigger.New)
{
if(c.AssistantPhone!=null && c.AssistantPhone!=Trigger.OldMap.get(c.id).AssistantPhone
&& c.accountid !=null ){
setAccId.add(c.accountid);
}

List<Account> acclist = [select id,phone,(Select id,phone__c from Opportunities) from Account where Id IN: setAccId];
if (acclist.size() > 0) {
for(Account acc: acclist){
for(Opportunity opp: acc.Opportunities){
acc.phone= c.AssistantPhone;
opp.phone__c= c.AssistantPhone;
accNewList.add(acc);
oppNewList.add(opp);
}
}
}
}
update oppNewList;
update accNewList;
}
Did you enjoy this article?
Signup today and receive free updates straight in your inbox.
I agree to have my personal information transfered to MailChimp ( more information )
50% LikesVS
50% Dislikes