Presented below is a compilation of 7 exercise challenges for Apex Triggers, tailored to assist beginners in initiating their journey with Salesforce Apex Triggers. These problems are regarded as classics, widely embraced, and proven to be highly effective. The triggers can be crafted using the developer console. Feel free to explore all solutions provided and don’t hesitate to reach out with any queries you may have.
For experienced who are more advanced and reading this, please keep in mind that this is merely for the purpose of learning.
Challenge 1
Assignment:
Create Account record whenever new contact is created without an account.
Resolution:
trigger ContactCustomTriggerExample on Contact (after insert) { List<Account> accListToInsert = new List<Account>(); for(Contact con : Trigger.New) { //check if account is null on contact if(con.AccountId == null ) { Account acc = new Account(); //Add all required field on Account acc.Name = con.LastName; acc.Phone = con.Phone; accListToInsert.add(acc); } } if(!accListToInsert.isEmpty()){ insert accListToInsert; } }
Challenge 2
Pre-Reqs:
Create a field on Account called “Only_Default_Contact”, checkbox, default off
Assignment:
When a new Account is created, create a new Contact that has the following data points:
- First Name = “Info”
- Last Name = “Default”
- Email = “info@websitedomain.tld”
- Only_Default_Contact = TRUE
When the Account has more than 1 Contact, update Only_Default_Contact to FALSE.
Resolution:
trigger defaultContact on account(after insert) { Account acc = [select id,Only_Default_Contact from account where id in : trigger.new]; contact con = new contact(); con.firstName = 'Info'; con.LastName = 'Default'; con.email = 'info@websitedomain.tld'; con.accountId = acc.id; insert con; //If you want to make checkbox true then use this also- acc.Only_Default_Contact = true; update acc; }
Challenge 3
Pre-Reqs:
Create a field on Account called “ Contact_Created__c ”, checkbox, default off
Assignment:
Create an apex trigger on the contact object and every time a new contact will be created and an account will be selected in the creation of that contact object then on that account object a checkbox filed ( Contact_Created__c ) will be checked true, which represent that this account has a contact.
Resolution:
trigger AcconuntForContact on Contact (after insert , before update){ if(trigger.isInsert && trigger.isAfter){ set<id> ids = new set<id>(); for(contact con: trigger.new){ if(con.accountid!=null){ ids.add(con.accountid); } } list<account> acclist = [select id,name,Contact_Created__c from account where id in: ids]; for(contact con : trigger.new){ for(account acc: acclist){ if(acc.id==con.accountid){ acc.Contact_Created__c= true; } } } if(accList.size()>0 update acclist; } } }
Challenge 4
Pre-Reqs:
Create a field on Account called “Out_of_Zip”, checkbox, default off
Assignment:
When a Billing Address is modified, get the new Postal Code. Then check which Contacts on the Account are outside that Postal Code. If 1 or more Contacts are outside of the Postal Code, mark Out_of_Zip as TRUE.
Resolution:
trigger TriggerExample on Account (before update, before insert) { Set<Id> changedAccounts = new Set<Id>(); for(Integer i = 0; i < Trigger.New.size(); i++) { Account newAcc = Trigger.New[i]; Account oldAcc = Trigger.Old[i]; if(newAcc.BillingStreet != oldAcc.BillingStreet || newAcc.BillingCity != oldAcc.BillingCity || newAcc.BillingState != oldAcc.BillingState || newAcc.BillingPostalCode != oldAcc.BillingPostalCode || newAcc.BillingCountry != oldAcc.BillingCountry) changedAccounts.add(newAcc.Id); Map<Id, Integer> accountsAndOutOfZips = new Map<Id, Integer>(); for(Contact c : [SELECT Id, Account.BillingPostalCode FROM Contact WHERE Id IN :changedAccounts]) { if(c.MailingPostalCode != c.Account.BillingPostalCode) { if(accountsAndOutOfZips.get(c.Id) == null) accountsAndOutOfZips.put(c.Id, 1); else accountsAndOutOfZips.put(c.Id, accountsAndOutOfZips.get(c.Id) + 1); } } for(Account acc : Trigger.New) { if(accountsAndOutOfZips.get(acc.Id) != null && accountsAndOutOfZips.get(acc.Id) > 1) acc.Out_of_Zip__c = true; else acc.Out_of_Zip__c = false; } } }
Challenge 5
Pre-Reqs:
Create a field on Contact called Profile, text, 255
Assignment:
When an Account is updated and the Website is filled in, update all the Profile field on all Contacts to:
- Profile = Website + ‘/’ + First Letter of First Name + Last Name
Resolution:
trigger TriggerExample3 on Account (After Update) { if(Trigger.isAfter && Trigger.isUpdate) { Set<Id> AccountId_Set = new Set<Id>(); new list<contact>(); for(Account ac : trigger.new) { if(ac.website != null) { AccountId_Set.add(ac.id); } } if(AccountId_Set.size()>0 { List<Contact> Contact_List = [select Id,Firstname,Lastname,Profile__c,Accountid,Account.website from contact where Accountid in :AccountId_Set]; for(Contact con : Contact_List) { if(con.FirstName != Null) { con.Profile__c = con.account.website + '/' + con.FirstName.substring(0, 1) + con.lastname; } } update Contact_List; } } }
Challenge 6
Pre-Reqs:
Create a field on Account called “is_gold”, checkbox, default off
Assignment:
When an Opportunity is greater than $20k, mark is_gold to TRUE
Resolution:
trigger TriggerExample4 on Account (After Update) { integer amount=20000; For(Account acc:trigger.new){ List<opportunity> opps=[select id from opportunity where Account.id=:acc.id And Amount > 20000]; If(opps.size()>0 acc.Is_Gold__c=True; }Else{ acc.Is_Gold__c=False; } update acc; } }
Challenge 7
Pre-Reqs:
Create a field on Account called “need_intel”, checkbox, default off
Create a field on Contact called “Dead”, checkbox, default off
Assignment:
If 70% or more of the Contacts on an Account are Dead, mark the need_intel field to TRUE
Resolution:
public static void DeadIntel(list<Contact> cont){ Set<Id> accIds = new Set<Id>(); for(Contact conList : cont){ if(conList.accountId!=null){ accIds.add(conList.accountId); } } Map<Id, List<Contact>> accContactMap = new Map<Id, List<Contact>>(); List<Account> accUpdateList = new List<Account>(); for(Contact obj : [SELECT accountId,Dead__c FROM Contact WHERE accountId IN :accIds]){ List<Contact> contLists; if(accContactMap.containsKey(obj.accountId)){ contLists = accContactMap.get(obj.accountId); }else{ contLists = new List<Contact>(); } contLists.add(obj); accContactMap.put(obj.accountId, contLists); } for(Id accId : accContactMap.keySet()){ Integer count_of_Dead = 0; Integer total_con = accContactMap.get(accId).size(); if(accContactMap.get(accId).size() > 1){ for(integer i =0 ; i<accContactMap.get(accId).size(); i++) if(accContactMap.get(accId)[i].Dead__c == true){ count_of_Dead++; } } if((count_of_Dead*100)/total_con) > 70) accUpdateList.add(new Account(id = accId, needintel__c = true)); } if(!accUpdateList.isEmpty()){ update accUpdateList; } } //Trigger trigger UpdateContact on Contact (after update) { if(Trigger.isUpdate && Trigger.isAfter){ AccountContact.DeadIntel(Trigger.new); } } view rawTriggerExample 5 hosted with ❤ by GitHub