Here’s a list of Apex trigger scenarios for practice, covering beginner to intermediate levels and Intermediate to Advanced levels: Beginner Level: Intermediate Level: Advanced
Write a trigger to throw an error when the user deactivates the account record and if that account has at least one opportunity with the stage not equal to closed won or closed lost.
trigger PreventAccountDeactivation on Account(before update) {
// Loop through the list of accounts being updated
for (Account acc: Trigger.new) {
// Check if the account's IsActive field is being set to false (i.e. deactivated)
if (acc.IsActive == false && Trigger.oldMap.get(acc.Id).IsActive == true) {
// Query for opportunities related to this account where the stage is not "Closed Won" or "Closed Lost"
List < Opportunity > opps = [
SELECT Id
FROM Opportunity
WHERE AccountId =: acc.Id
AND StageName NOT IN('Closed Won', 'Closed Lost')
];
// If there are any such opportunities, throw an error
if (!opps.isEmpty()) {
acc.addError('Cannot deactivate this account because it has opportunities with a stage other than "Closed Won" or "Closed Lost".');
}
}
}
}
Employee record’s Status cannot be changed to “Terminated” if there is/are no Employee Review records added to it
trigger PreventTerminatedStatus on Employee__c (before update) {
// Loop through the list of employees being updated
for (Employee__c emp : Trigger.new) {
// Check if the employee's Status field is being set to "Terminated"
if (emp.Status__c == 'Terminated' && Trigger.oldMap.get(emp.Id).Status__c != 'Terminated') {
// Query for Employee Review records related to this employee
List<Employee_Review__c> reviews = [ SELECT Id FROM Employee_Review__c WHERE Employee__c = :emp.Id ];
// If there are no Employee Review records, throw an error
if (reviews.isEmpty()) {
emp.addError('Cannot set status to "Terminated" because there are no Employee Review records added to this employee.');
}
}
}
}
There will be Three Objects User, Contact, and Account. and these objects have one custom field name is isActive. so if I will uncheck the IsActive Checkbox from the Account then also uncheck the isActive checkbox of the related user of that account and all the contact associate with the account.
trigger DeactivateRelatedRecords on Account (before update) {
// Loop through the list of accounts being updated
for (Account acc : Trigger.new) {
// Check if the account's IsActive field is being set to false (i.e. deactivated)
if (acc.IsActive == false && Trigger.oldMap.get(acc.Id).IsActive == true) {
// Query for related users and contacts
List<User> users = [ SELECT Id, IsActive FROM User WHERE AccountId = :acc.Id ];
List<Contact> contacts = [ SELECT Id, IsActive FROM Contact WHERE AccountId = :acc.Id ];
// Set the IsActive field to false for all related users and contacts
for (User user : users) {
user.IsActive = false;
}
for (Contact contact : contacts) {
contact.IsActive = false;
}
// Update the related users and contacts
update users;
update contacts;
}
}
}
What is the Difference Between Context variables and Static variables in triggers?
What are the Different types of Context variables in triggers?
isExecuting | Returns true if the current context for the Apex code is a trigger, not a Visualforce page, a Web service, or an execute anonymous() API call. |
isInsert | Returns true if this trigger was fired due to an insert operation, from the Salesforce user interface, Apex, or the API. |
isUpdate | Returns true if this trigger was fired due to an update operation, from the Salesforce user interface, Apex, or the API. |
isDelete | Returns true if this trigger was fired due to a delete operation, from the Salesforce user interface, Apex, or the API. |
isBefore | Returns true if this trigger was fired before any record was saved. |
isAfter | Returns true if this trigger was fired after all records were saved. |
isUndelete | Returns true if this trigger was fired after a record is recovered from the Recycle Bin. This recovery can occur after an undelete operation from the Salesforce user interface, Apex, or the API. |
new | Returns a list of the new versions of the sObject records. This sObject list is only available in insert, update, and undelete triggers, and the records can only be modified in before triggers. |
newMap | A map of IDs to the new versions of the sObject records. This map is only available in before update, after insert, after update, and after undelete triggers. |
old | Returns a list of the old versions of the sObject records. This sObject list is only available in update and delete triggers. |
oldMap | A map of IDs to the old versions of the sObject records. This map is only available in update and delete triggers. |
operationType | Returns an enum of type System.TriggerOperation corresponding to the current operation. Possible values of the System.TriggerOperation enum are: BEFORE_INSERT, BEFORE_UPDATE, BEFORE_DELETE,AFTER_INSERT, AFTER_UPDATE, AFTER_DELETE, and AFTER_UNDELETE. If you vary your programming logic based on different trigger types, consider using the switch statement with different permutations of unique trigger execution enum states. |
size | The total number of records in a trigger invocation, both old and new. |
Whenever the Account is created with the Industry field as “IT” then create a contact for the account, use the Contact “Lastname” value from the Account name and the contact phone from the account phone.
trigger CreateContactOnAccountCreation on Account (before insert) {
// Loop through the list of accounts being inserted
for (Account acc : Trigger.new) {
// Check if the account's Industry field is set to "IT"
if (acc.Industry == 'IT') {
// Create a new contact record
Contact contact = new Contact();
// Set the Lastname field to the account name
contact.LastName = acc.Name;
// Set the Phone field to the account phone
contact.Phone = acc.Phone;
// Set the AccountId field to the ID of the account being inserted
contact.AccountId = acc.Id;
// Add the contact to the list of records to be inserted
insert contact;
}
}
}
Write a trigger on the account to count all the accounts with their respective countries.
trigger CountAccountsByCountry on Account (after insert, after update, after delete, after undelete) {
// Query for all the distinct countries where accounts are located
Set<String> countries = new Set<String>();
for (Account acc : [SELECT BillingCountry FROM Account]) {
countries.add(acc.BillingCountry);
}
// Create a map to store the counts for each country
Map<String, Integer> counts = new Map<String, Integer>();
// Initialize the counts to 0 for each country
for (String country : countries) {
counts.put(country, 0);
}
// Query for all the accounts and update the counts
for (Account acc : [SELECT Id, BillingCountry FROM Account]) {
counts.put(acc.BillingCountry, counts.get(acc.BillingCountry) + 1);
}
// Update the custom field on the Account object with the counts for each country
List<Account> accountsToUpdate = new List<Account>();
for (String country : counts.keySet()) {
Account acc = new Account();
acc.BillingCountry = country;
acc.Accounts_in_Country__c = counts.get(country);
accountsToUpdate.add(acc);
}
update accountsToUpdate;
}
How to check the old value in the field using a trigger?
1000 records are being processed through a Batch to update any object like Account. Write code to maintain how many records failed to be updated.
trigger AccountTrigger on Account (before update) {
// Declare a variable to store the count of failed records
Integer failedRecordCount = 0;
// Loop through the records in the trigger context
for (Account account : Trigger.new) {
// Check if the record is in an error state
if (account.isValid() == false) {
// If the record is in an error state, increment the failed record count
failedRecordCount++;
}
}
// Save the failed record count in a custom field on the object
for (Account account : Trigger.new) {
account.Failed_Record_Count__c = failedRecordCount;
}
}
Make a field on account object “No of Total Contact”. Write a trigger to count the total no of contact associated with the particular account when the contact is inserted or deleted.
trigger ContactTrigger on Contact (after insert, after delete) {
// Get the list of account IDs for the inserted or deleted contacts
Set<Id> accountIds = new Set<Id>();
for (Contact contact : Trigger.new) {
accountIds.add(contact.AccountId);
}
// Query for the accounts with the matching IDs
List<Account> accounts = [
SELECT Id, No_of_Total_Contacts__c
FROM Account
WHERE Id IN :accountIds
];
// Loop through the accounts and update the "No of Total Contacts" field
for (Account account : accounts) {
account.No_of_Total_Contacts__c = [
SELECT COUNT()
FROM Contact
WHERE AccountId = :account.Id
];
}
// Update the accounts with the new contact count
update accounts;
}
The account has 10 opportunity links to them. The owner changed the email field to any one of the one opportunities It will update all the sibling’s opportunities with the same account.
trigger AccountTrigger on Account (before update) {
// Get the list of account IDs that have been updated
Set<Id> accountIds = new Set<Id>();
for (Account account : Trigger.new) {
accountIds.add(account.Id);
}
// Query for the opportunities with matching account IDs
List<Opportunity> opportunities = [ SELECT Id, AccountId, Email__c FROM Opportunity WHERE AccountId IN :accountIds ];
// Loop through the opportunities and update the email field
for (Opportunity opportunity : opportunities) {
// Find the corresponding account for the opportunity
Account account = Trigger.oldMap.get(opportunity.AccountId);
// Update the email field on the opportunity
opportunity.Email__c = account.Email;
}
// Update the opportunities with the new email field value
update opportunities;
}
When the user is deactivated then its related Accounts and opportunities will automatically assign to its manager.
trigger UserTrigger on User (before update) {
// Get the list of user IDs that have been updated
Set<Id> userIds = new Set<Id>();
for (User user : Trigger.new) {
userIds.add(user.Id);
}
// Query for the users with the matching IDs
List<User> users = [ SELECT Id, IsActive, ManagerId FROM User WHERE Id IN :userIds ];
// Create a map of user IDs to managers
Map<Id, Id> userManagerMap = new Map<Id, Id>();
for (User user : users) {
userManagerMap.put(user.Id, user.ManagerId);
}
// Query for the accounts and opportunities with matching owner IDs
List<Account> accounts = [ SELECT Id, OwnerId FROM Account WHERE OwnerId IN :userIds ];
List<Opportunity> opportunities = [ SELECT Id, OwnerId FROM Opportunity WHERE OwnerId IN :userIds ];
// Loop through the accounts and opportunities and update the owner field
for (Account account : accounts) {
account.OwnerId = userManagerMap.get(account.OwnerId);
}
for (Opportunity opportunity : opportunities) {
opportunity.OwnerId = userManagerMap.get(opportunity.OwnerId);
}
// Update the accounts and opportunities with the new owner field value
update accounts;
update opportunities;
}
Conclusion
I hope you like this blog and if you want any help let me know in the comment section.
Stay tuned, there is way more to come! Follow me on LinkedIn, Instagram, and Twitter. So you won’t miss out on all future articles.