Apex Trigger Interview Scenarios

Share This Post

1. write a trigger Account with more than two contacts that cannot be deleted.

trigger PreventAccountDeletion on Account (before delete) {
    List<Account> accountsToDelete = Trigger.old;
    List<Account> accountsToKeep = new List<Account>();
    
    for (Account a : accountsToDelete) {
        if (a.Contacts.size() > 2) {
            accountsToKeep.add(a);
        }
    }
    
    accountsToDelete.removeAll(accountsToKeep);
    
    if (accountsToKeep.size() > 0) {
        for (Account a : accountsToKeep) {
            a.addError('Account deletion failed: Accounts with more than 2 contacts cannot be deleted.');
        }
    }
}

2. On the opportunity object, there is a stage field, the condition only the system admin can change the stage of opportunity from prospect to close lost when the record type is not equal to external.

trigger EnforceStageChangeOnOpportunity on Opportunity (before update) {
    for (Opportunity opp : Trigger.new) {
        Opportunity oldOpp = Trigger.oldMap.get(opp.Id);

        // Check if the stage is changing from "Prospect" to "Close Lost"
        if (opp.StageName == 'Close Lost' && oldOpp.StageName != 'Close Lost') {
            // Check if the user is a System Administrator
            if (!UserInfo.isAdmin()) {
                // Check if the record type is not "External"
                if (opp.RecordType.Name != 'External') {
                    opp.StageName.addError('Only System Administrators can change the stage to "Close Lost" for non-External records.');
                }
            }
        }
    }
}

3. When inserting an Opportunity Line Item, if any of the Opportunity Line Item’s related Products contains “Sponsor” as a value for the “Product Family” field, then update the Parent Opportunity’s “Type” field to “Sponsor”.

trigger UpdateOpportunityTypeOnLineItem on OpportunityLineItem (after insert) {
    Set<Id> opportunityIdsToUpdate = new Set<Id>();

    // Collect Opportunity Ids that have related Products with "Sponsor" as Product Family
    for (OpportunityLineItem oli : Trigger.new) {
        if (oli.PricebookEntry.Product2.Product_Family__c == 'Sponsor') {
            opportunityIdsToUpdate.add(oli.OpportunityId);
        }
    }

    // Update the Parent Opportunities' Type field to "Sponsor"
    if (!opportunityIdsToUpdate.isEmpty()) {
        List<Opportunity> opportunitiesToUpdate = [
            SELECT Id
            FROM Opportunity
            WHERE Id IN :opportunityIdsToUpdate
        ];

        for (Opportunity opp : opportunitiesToUpdate) {
            opp.Type = 'Sponsor';
        }

        update opportunitiesToUpdate;
    }
}

4. We have one custom field that is Status__c on the Account object and Opportunity object and the values of these fields are InProgress, Won, and Lost. I want to update the Status field on the related account object status field based on the opportunity status field value.

trigger UpdateAccountStatusOnOpportunity on Opportunity (after insert, after update) {
    Set<Id> accountIdsToUpdate = new Set<Id>();

    for (Opportunity opp : Trigger.new) {
        if (opp.Status__c != null) {
            accountIdsToUpdate.add(opp.AccountId);
        }
    }

    List<Account> accountsToUpdate = [
        SELECT Id
        FROM Account
        WHERE Id IN :accountIdsToUpdate
    ];

    for (Account acc : accountsToUpdate) {
        // Assuming that Status__c on Account is a picklist with values "InProgress", "Won", "Lost"
        acc.Status__c = getAccountStatusFromOpportunityStatus(Trigger.newMap.get(acc.Id).Status__c);
    }

    update accountsToUpdate;
}

public static String getAccountStatusFromOpportunityStatus(String opportunityStatus) {
    if (opportunityStatus == 'InProgress' || opportunityStatus == 'Won' || opportunityStatus == 'Lost') {
        return opportunityStatus;
    }
    return null; // Handle cases where opportunityStatus doesn't match any expected values
}

5. Write a batchable class to send the count of the Account Record where the country is India.

public class IndiaAccountCountBatchable implements Database.Batchable<SObject> {
    public Database.QueryLocator start(Database.BatchableContext context) {
        String query = 'SELECT COUNT(Id) FROM Account WHERE Country = \'India\'';
        return Database.getQueryLocator(query);
    }

    public void execute(Database.BatchableContext context, List<SObject> scope) {
        Integer indiaAccountCount = (Integer) scope[0];
        sendCountToDestination(indiaAccountCount);
    }

    public void finish(Database.BatchableContext context) {
        // Perform any post-processing if required
    }

    private void sendCountToDestination(Integer count) {
        // Implement your logic here to send the count to the destination
        // For example, you can use Messaging or HTTP callouts to send the count
        // Replace the below debug statement with your actual logic
        System.debug('India Account Count: ' + count);
    }
}
public class ScheduleIndiaAccountCountBatch {
    public static void scheduleBatchJob() {
        // Remove any existing scheduled jobs with the same name
        System.abortJob('IndiaAccountCountBatch');

        // Schedule the batch job to run every day at 1 AM
        String schedule = '0 0 1 * * ?';
        System.schedule('IndiaAccountCountBatch', schedule, new IndiaAccountCountBatchable());
    }
}

6. Write a trigger to count the number of contacts on the account object and the trigger should run the before insertion.

trigger CountContacts on Contact (before insert) {
    // Create a set to hold Account Ids
    Set<Id> accountIds = new Set<Id>();

    // Collect Account Ids from the incoming Contact records
    for (Contact con : Trigger.new) {
        accountIds.add(con.AccountId);
    }

    // Query for related contacts and update Account records
    List<Account> accountsToUpdate = new List<Account>();
    for (AggregateResult ar : [SELECT AccountId, COUNT(Id) contactCount
                               FROM Contact
                               WHERE AccountId IN :accountIds
                               GROUP BY AccountId]) {
        Id accountId = (Id)ar.get('AccountId');
        Integer count = (Integer)ar.get('contactCount');

        // Create an Account object with the updated count
        Account acc = new Account(Id = accountId, NumberOfContacts__c = count);
        accountsToUpdate.add(acc);
    }

    // Update the Account records with the contact counts
    if (!accountsToUpdate.isEmpty()) {
        update accountsToUpdate;
    }
}

7. whenever the contact is inserted then the contact’s last name will update with the associate account accountSource value and the contact’s last name. So, write a Trigger to update the contact’s last name.

trigger UpdateContactLastName on Contact (before insert) {
    // Collect the Account Ids for the associated contacts
    Set<Id> accountIds = new Set<Id>();
    for (Contact contact : Trigger.new) {
        if (contact.AccountId != null) {
            accountIds.add(contact.AccountId);
        }
    }

    // Query the Account Source and Account Name for the associated accounts
    Map<Id, Account> accountMap = new Map<Id, Account>(
        [SELECT Id, AccountSource, Name FROM Account WHERE Id IN :accountIds]
    );

    // Update Contact Last Names based on associated Account data
    for (Contact contact : Trigger.new) {
        if (contact.AccountId != null && accountMap.containsKey(contact.AccountId)) {
            Account associatedAccount = accountMap.get(contact.AccountId);
            contact.LastName = associatedAccount.AccountSource + ' ' + associatedAccount.Name;
        }
    }
}

8. write a trigger to update the no of employee field on the account based on the no of contacts from that account

trigger UpdateEmployeeCountOnAccount on Contact (after insert, after update, after delete, after undelete) {
    Set<Id> accountIdsToUpdate = new Set<Id>();

    if (Trigger.isInsert || Trigger.isUpdate || Trigger.isUndelete) {
        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) {
        accountsToUpdate.add(new Account(
            Id = accountId,
            Number_of_Employees__c = [SELECT COUNT() FROM Contact WHERE AccountId = :accountId AND IsDeleted = false]
        ));
    }

    update accountsToUpdate;
}

Leave a Reply

Your email address will not be published. Required fields are marked *

Subscribe To Our Newsletter

Get updates and learn from the best

More To Explore

NetSuite Salesforce Integration: An Automation Guide

NetSuite Salesforce Integration is the seamless connection between NetSuite, a leading cloud-based Enterprise Resource Planning (ERP) system, and Salesforce, a premier Customer Relationship Management (CRM) platform.