Trigger Scenario Based Questions in Salesforce

Asking simple straightforward questions in Salesforce is history. Few years back Salesforce certified people were very less. Hence criteria was just to check whether that person know about Salesforce or not.

So questions used to be:
What is Salesforce?
What is account and contact?
What is relationship between account contact?
What is workflow?
What is approval process?
etc.

If you notice above questions are crisp to the point. But now since in market there are many Salesforce certified people above style of interview doesn't work. One could easily memories these.

I too take interviews in my company and now style is different. Focus is more to ask scenario questions rather then what how etc.

In this blog series, I have tried to cover trigger scenario based questions that are often asked from a Salesforce developer in an interview.

Trigger Scenario 1 :
When ever a case is created with origin as email then set status as new and Priority as Medium.

Object : Case
Trigger: Before Insert

Trigger Code: CaseOrigin.apxt

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

Output :

–> Case is created with origin as email :

Status : Working
Priority : High
Case Origin : Email

–> Before Insert :

As per the requirement, we are performing an operation on the trigger when the user save the new case that means we need to use as before insert trigger.

Status : New
Priority : Medium
Case Origin : Email



Trigger Scenario 2 :
When ever Lead is created with LeadSource as Web then give rating as cold otherwise hot.

Object : Lead
Trigger: Before Insert

Trigger Code: LeadScenario.apxt

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

Output:

–> Lead is created with LeadSource as Web :

–> Before Insert :

As per the requirement, we are performing an operation on the trigger when the user save the new lead that means we need to use as before insert trigger.

Here the user has selected the lead source as 'web', so the rating will be 'cold'


Trigger Scenario 3 :
Whenever New Account Record is created then needs to create associated Contact Record automatically.

Object : Account
Trigger: After Insert

Description : When ever new Account record is successfully created, then create the corresponding contact record for the account with:

account name as contact lastname
account phone as contact phone

Trigger Code: AccountAfter.apxt

trigger AccountAfter on Account (after insert) {
    List<contact> cons=new List<contact>();
    for(Account acc: Trigger.New){
        Contact c=new Contact();
        c.accountid=acc.id;
        c.lastname=acc.name;
        c.phone=acc.phone;
        cons.add(c);
    }
    insert cons;

}

Test Class:

@isTest
private class AccountAfterHandler {
    @isTest
    static void testme(){
        Integer count=[select count() from Account];
        Integer size=[select count() from Contact];
        Account acc=new Account(Name='LearnFrenzy',phone='022-845454');
        
        try{
            insert acc;
        }catch(Exception e){
            System.debug(e);
        }
        
        Integer newCount=[select count() from Account];
        Integer newsize=[select count() from Contact];
        Contact c=[select lastname,phone from Contact where accountid=:acc.id];
        System.assertEquals(c.lastname,acc.name);
        System.assertEquals(c.phone,acc.phone);
    }
}

Trigger Scenario 4 :
When ever the Account is created with Industry as Banking then create a contact for account, Contact Lastname as Account name and contact phone as account phone.

Object : Account
Trigger: After Insert

Trigger Code: CreateAccountContact.apxt

trigger CreateAccountContact on Account (after insert) {
    
    list<contact> contacts = new list<contact>();
    
    for(account acc : trigger.new){
        
        if(acc.Industry == 'Banking'){
            
            contact con = new contact();
            
            con.LastName = acc.name;
            
            con.Phone = acc.Phone;
            
            con.AccountId = acc.Id;
            
            contacts.add(con);
            
        }
        
    }

    insert contacts;
}

Output:

–> New Account is created with Industry as Banking :

–> After Insert :

As per the requirement, we are performing an operation on the trigger when the user save the new account that means we need to use as after insert trigger.

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 Scenario 5 :
Creates the number of contacts which are equal to the number which we will enter in the Number of Locations field on the Account Object.

Create Custom field called “Number of Locations” on the Account Object (Data Type=Number)

Object : Account
Trigger: After Insert

Trigger Code: ContactsCreation.apxt

trigger ContactsCreation on Account (after insert) {
    
    list<contact> listContact = new list<contact>();
    
    map<id,decimal> mapAcc = new map<id,decimal>();
    
    for(Account acc:trigger.new){
        
        mapAcc.put(acc.id,acc.NumberofLocations__c);
        
    }
    
    if(mapAcc.size()>0 && mapAcc!=null){
        
        for(Id accId:mapAcc.keyset()){
            
            for(integer i=0;i<mapAcc.get(accId);i++){
                
                contact newContact=new contact();
                
                newContact.accountid=accId;
                
                newContact.lastname='contact'+i;
                
                listContact.add(newContact);
                
            }
            
        }
        
    }
    
    if(listContact.size()>0 && listContact!=null)
        
        insert listContact;
    
}

Output:

–> Enter in the Number of Locations field on the Account Object. :

Here the user has created a new account 'LearnFrenzy' and the Number of Locations is 4.

–> After Insert :

As per the requirement, we are performing an operation on the trigger when the user creates the number of contacts which are equal to the number which we will enter in the Number of Locations field on the Account Object. That means we need to use as after insert trigger.

Trigger Scenario 6 :
When ever Opportunity "Stage" is modified to "Closed Won" then set "Close Date" as "Today Date" and "Type" as "New Customer".

Object : Opportunity
Trigger: Before Update

Trigger Code: OpportunityUpdate.apxt

trigger OpporUpdate on Opportunity (before update) {
    
    Map<Id,Opportunity> oppOld = Trigger.oldMap;
    
    Map<Id,Opportunity> oppNew = Trigger.newMap;
    
    Set<Id> keys =oppOld.keySet();
    
    for(Id rid :keys){
        
        Opportunity oldOpportunity = oppOld.get(rid);
        
        Opportunity newOpportunity = oppNew.get(rid);
        
        if(oldOpportunity.stagename!='Closed Won' && newOpportunity.stagename=='Closed Won'){
            
            newOpportunity.closeDate=System.today();
            
            newOpportunity.type='New Customer';
            
        }
        
    }
    
}

Output:

–> Opportunity "Stage" name is modified to Closed Won :

For Below Example: 

Stage -> Closed Won
Closed Date -> 5/17/2019
Type -> Existing Customer - Replacement

–> Before Update :

As per the requirement, we are performing an operation on the trigger when the user modified the stage name that means we need to use as before update trigger.

Here the user has modified the "Stage" name as 'Closed Won', so before update the "Type" will be 'New Customer' and "Closed Date" will be "Today Date".


Trigger Scenario 7 :
when a new contact is created for a existing account then set contact otherphone as account phone.

Object : Contact
Trigger: Before Insert

Trigger Code: ContactAccountRelation.apxt

trigger ContactAccountRelation on Contact (before insert) {
    
    Set<Id> accIdSet = new Set<Id>();
    
    for(Contact con : trigger.new){
        if(String.isNotBlank(con.AccountId)){
            accIdSet.add(con.AccountId);
        }
    }
    
    if(accIdSet.size() > 0){
        Map<Id,Account> accMap = new Map<Id,Account>([Select Id, Phone From Account where id In:accIdSet]);
        
        for(Contact con : trigger.new){
            if(con.AccountId != null && accMap.containskey(con.AccountId)){
                if(accMap.get(con.AccountId).Phone != null){
                    con.OtherPhone = accMap.get(con.AccountId).Phone;
                }
            }
        }
        
    }
}

Output:

–> Existing Account :

Account Name* : Learnfrenzy
Phone: +91-9999-888-777

–> Before Insert :

As per the requirement, we are performing an operation on the trigger when the user create new contact is created for a existing account then set contact otherphone as account phone that means we need to use as before insert trigger.

–> New Contact :

Account Name* : Learnfrenzy
Contact : Ms. Alexa Jhon
Other Phone : +91-9999-888-777


Trigger Scenario 8 :
The following Trigger will fires when we try to create the account with same name i.e. Preventing the users to create Duplicate Accounts

Object : Account
Trigger: Before Insert, Before Update

 MIND IT !

Here (Way-1), I have used SOQL inside for loop which will affect governor limit and it is not best practice.

The most important being that it is not bulkified. We should always avoid SOQL inside loop. So please see second way-2 below for best practices.

WAY-1

Trigger Code: AccountDuplicateTrigger.apxt

trigger AccountDuplicateTrigger on Account (before insert, before update) {
    for(Account a:Trigger.new)
    {
        List<Account> acc=[select ID from account where Name=:a.Name and Rating=:a.rating];
        if(acc.size()>0)
        {
            a.adderror('You cannot create a duplicate account');
        }
    }
}

Test Class: AccountDuplicateTriggerTest

@istest
public class AccountDuplicateTriggerTest{
  static testmethod void myTest(){
      Boolean result =false;
      Account a = new Account();
      a.Name= 'Learnfrenzy';
      a.Rating='Warm';
      insert a;
 
      try{
      Account a1=new account();
      a1.Name= 'Learnfrenzy';
      a1.Rating='Warm';
      insert a1;
      }
      catch(DMLException ex)
      {
      result=true;
      system.assert(result);
      }
  }
 }

Output:

–> Existing Account :

Account Name* : Learnfrenzy
Rating: Hot


–> when we try to create the account with same name i.e. Preventing the users to create Duplicate Accounts (before insert, before update) :



WAY-2 :Here, avoid SOQL Queries or DML statements inside FOR Loops

trigger AccountDuplicateTrigger on Account (before insert, before update) {
    
    list<string> acc = new list<string>();
    for(Account a:Trigger.new)
    {
        acc.add(a.name);
    }
    list<Account> listOfDuplicateAccounts = [select id, Name from Account where Name in :acc];
    for(Account account:trigger.new)
    {
        if(trigger.isInsert){
            if(listOfDuplicateAccounts.size()!=0)
            {
                account.addError('Account already exists with this name');
            }
        }
        if(trigger.isUpdate)
        {
            for(Account oldaccount :trigger.old)
            {
                if(account.Name!=oldAccount.Name && listOfDuplicateAccounts.size()!=0)
                {
                    account.addError('Account already exists with this name');
                }
            }
        }
    }  
}

Output:

–> Existing Account :

Account Name* : Learnfrenzy
Rating: Hot


–> when we try to create the account with same name i.e. Preventing the users to create Duplicate Accounts (before insert, before update) :



As like as this code you can write Trigger to prevent from creating Duplicate Records in your object.


Trigger Scenario 9 :
Write a trigger in which if an account that has related contacts and the user tries to delete that account it throws you an error "Account cannot be deleted".

Object : Account
Trigger: Before Delete

Trigger Code: PreventAccountFromDeletion.apxt

trigger PreventAccountFromDeletion on Account (before delete){
    
    List<account> accList = new List<account>();  
    Set<id> accIdSet = new Set<id>();  
    for(Account acc : Trigger.old)  
    {  
        accIdSet.add(acc.id);  
    }  
  
 Map<Id, Account> accts = new Map<Id, Account>([Select Id, (Select Id from contacts) from Account where id in :accIdSet]);
    
    for(Account acc : Trigger.old)
    {
        if(accts.get(acc.id).contacts.size()>0)
        {
            acc.adderror('Account cannot be deleted');
        }
    }                                       
    
}

Output:

–> Account :

Account Name* : LearnFrenzy - Salesforce
Contacts(2)

Saurabh Samir
Azusa Zeal

Open a account record in your Salesforce org. Click on the inverted triangle icon located on the top-right of the account record. It will open a dropdown, click on the ‘Delete’.


–> Before Delete :

As per the requirement, account that has related contacts should not be deleted. That means we need to use as Before Delete trigger.

It will prompt you to confirm the delete action by clicking on the ‘Delete’ button.


As soon as you click on the button, you will see the error message which we wrote in our trigger class that ‘Account cannot be deleted’.


Trigger Scenario 10 :
Write a trigger on lead to prevent duplicate records based on lead email, if a record already created with the same Email, Or record is Updated. The trigger should throw an error.

Standard Object : Lead
Trigger: Before Insert, After Insert, Before Update, After Update

Trigger Code: DuplicateEmailsInLead.apxt (Apex Class Trigger)

It will be fired whenever New Lead is Created Or Updated

trigger DuplicateEmailsInLead on Lead (before insert, after insert, before update, after update) {
    
    if(trigger.isBefore){
        if(trigger.isInsert){  
            leadHandlerController.updateInsertLead(trigger.new);
        }
        if(trigger.isUpdate){
            
            leadHandlerController.updateInsertLead(trigger.new);
        }
        
    }
    else if(trigger.isAfter){
        system.debug('I am inside of after method');
    }
    
}

Apex Class Controller: leadHandlerController.apxc

Apex handler trigger to prevent duplicate records based on lead email.

public class leadHandlerController {
    public static void updateInsertLead(List<Lead> leadObjList){
        Set<String> leadSet= new Set<String>();
        List<Lead> leadObj = new List<Lead>();
        List<Lead> leadList=[Select Id, Name, Email, Phone From Lead Where Email != null];
        for(Lead d1:leadList){
            leadSet.add(d1.Email);
        }
        
        for(lead e1:leadObjList){
            if(leadSet.contains(e1.Email)){
                e1.Email.addError('Do not allow duplicate Email');
            }
        }
    }
}

Output:

–> Lead Record Page   :

Name : Jack Jhon

Email : [email protected]

The below example is based on trigger on lead to prevent duplicate records based on lead email, if a record already created with the same Email, Or record is Updated. The trigger should throw an error.



 --> When updating a lead source in an existing record, where the email already exists.



Trigger Scenario 11 :

A salesforce company named ABC and plan to launch a product in different region (ASIA, EMEA, NA, SA) across the globe.They also want to sell the products to their clients which are in ASIA,EMEA, NA and SA .

From Admin point of view this particular scenario need to be logged into CRM for:

Create a Multi picklist name In Account Object “Working in”

Picklist Values:

1. ASIA
2. EMEA
3. NA
4. SA

(I) Write a script to get the total Quantity of Products sold in only Accounts Working in = ASIA.

(II) Write a Trigger to stop creating or updating Opportunities with Account having “Working in = ASIA” and Already 2 Closed Won Opportunity under same Account.

Solution :

Script : (I) Write a script to get the total Quantity of Products sold in only Accounts Working in = ASIA.

First we will create a Multi picklist name In Account Object “Working in”. After creation you can see the filed name.

OBJECT : Account
FIELD LABEL : Working in
FIELD NAME : Working_in__c
DATA TYPE : Picklist (Multi-Select)


OBJECT : Opportunity
FIELD LABEL : Quantity
FIELD NAME : TotalOpportunityQuantity (Default in Opportunity Object)
DATA TYPE : Number(16, 2)


Apex Class: GetProductQuantity.apxc

public class GetProductQuantity {
    public static void GetToatlProductQty(){        
        List<account> AccList = [select id,Name from Account where Working_in__c = 'ASIA'];        
        //system.debug('ACCCC'+AccList);        
        if(AccList.size()>0){            
            List<Opportunity> oppList =[select id,TotalOpportunityQuantity,AccountId from Opportunity where AccountId IN: AccList AND StageName='Closed Won'];            
            //system.debug('opp'+oppList);            
            for(Opportunity opp:oppList){                
                System.debug('ACCOUNT'+opp.AccountId+'Number Of Product Sol'+opp.TotalOpportunityQuantity);            
            }        
        }    
    } 
    
}

To readers:If you find any mistakes let me know


 MIND IT !

Facing interview is very stressful situation for everyone who want to get the job. For every problem there is a solution. Practice the best solution to crack the interview. Pick the best source and practice your technical and HR interview with experienced persons which helpful to boost confidence in real interview.

Share This Post:

About The Author

Saurabh Samir - I have been helping aspirants to clear different competitive exams. LearnFrenzy as a team gave me an opportunity to do it on a larger level an reach out to more students. Do comment below if you have any questions or feedback's.