Apex Triggers
Apex Triggers
Configuration:
● In Contact Object - Create the two Record Type as enlisted below
○ Direct
○ Indirect
● In Account Object - Create the two Number Type fields as enlisted below
○ Direct Contacts
○ Indirect Contacts
Write a Unit test in Apex to ensure the above trigger covers all the scenarios
==============================HANDLER========================
/*
@MethodName : displayContactOnAccount
@param : List<Contact> lstContactNew.
@Description: displayContactOnAccount method will display No.of direct and indirect
contacts on Related Acoount.
*/
Private void displayContactOnAccount(List<Contact> lstContactNew){
//Instance of Account.
Account objAccountUpdate = new Account(Id = objAccount.Id,
Indirect_Contacts__c = indirectContact,
Direct_Contacts__c = DirectContact);
lstAccountToUpdate.add(objAccountUpdate);
}
update lstAccountToUpdate;
}
===============TEST CLASS=======================================
/*
@MethodName : createContact
@param :-
@Description: createContact method will create the contact record.
*/
@isTest
static void createContact(){
//create Account record.
Account objAccount = new Account(Name = 'Muffu');
insert objAccount;
mapContacrtRecordTypes.put(objRecordType.Name, objRecordType.Id);
}
System.assertEquals(5, objAccountToCheck.Direct_Contacts__c);
System.assertEquals(5, objAccountToCheck.Indirect_Contacts__c);
completed
Rushikesh: TASK 2 : Roll-up Contact level information to its respective Account
Configuration:
● In Account Object
○ Create a Text Area(Long) type field named “All Mailing States”
if(objContact.AccountId != Null)
setAccountIds.add(objContact.AccountId);
setAccountStr.add(objContact.MailingState);
}
if(objContact.MailingState != Null)
setAccountStr.add(objContact.MailingState);
}
//Instance of Account.
Account objAccountUpdate = new Account(Id = objAccount.Id,
All_Mailing_States__c =String.join(new
List<String>(setAccountStr), ', '));
lstAccountToUpdate.add(objAccountUpdate);
}
update lstAccountToUpdate;
}
================================test=====================================
static void createUser(){
//create Contact records related to objAccount.
List<Contact> lstContact = new List<Contact>();
Contact objContact = new Contact(LastName = 'muffasser12',
Create_User__c = true,
MailingState = 'ab',
Email ='[email protected]');
lstContact.add(objContact);
Contact objContact1 = new Contact(LastName = 'muffasser34',
Create_User__c = true,
MailingState = 'bc',
Email ='[email protected]');
lstContact.add(objContact1);
test.startTest();
Sl_FutureMethodToCreateUser.futureMethodToInsertUser(setid);
test.stopTest();
Completed
Ratan: TASK 3 : Sending email and creation of Task on opportunity status change.
insert lstTask;
insert lstOpportunity;
/*
@MethodName : UpdateOpportunity
@param :-
@Description: UpdateOpportunity method will update the Opportunity record.
*/
@isTest
static void UpdateOpportunity(){
list<Opportunity> lstOpportunity = new list<Opportunity>();
lstOpportunity.add(objOpportunity);
lstOpportunity.add(objOpportunity2);
insert lstOpportunity;
//update status
objOpportunity.StageName = 'Closed Won';
update objOpportunity;
References:
Opportunity Stages
- https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/
object_reference/sforce_api_objects_opportunitystage.htm
- https://garysmithpartnership.com/opportunity-stages/#:~:text=Opportunity%20stages
%20describe%20the%20high,visibility%20through%20reports%20and%20dashboards.
Task Data Model and SOAP API
- https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/
sforce_api_erd_activities.htm
- https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/
sforce_api_objects_task.htm
Sending Email Messages:
- https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/
apex_forcecom_email_outbound.htm
- https://www.sfdc99.com/2014/03/01/sending-emails-using-apex/
Completed
Vineet: TASK 4 : As a India Team I need to receive any automated notifications as and
when the Opportunity Probability% and Stages are moving upwards/downwards as soon
as the updates are reflected in Salesforce, so that I can keep tabs on the pipeline
forecast.
DESIGN CONSIDERATIONS
● Create a Custom Field of type Picklist(single select) in Opportunity object called "Group"
Values in this picklist would be as follows:
1. Professional Services
2. Managed Services
● Create a Trigger in the Opportunity object to notify via email to the relevant emails as
mentioned below in the conditions, that reflects the changes of Probability and Stage
fields from its previous values.
ACCEPTANCE CRITERIA
NOTIFICATION 1:
Condition:
● Group = Professional Services AND
● (Opportunity Probability has changed OR Opportunity Stage has changed)
Action:
● Send an Email to the [email protected] email group
● Notifying the changes of Probability and Stage fields capturing Earlier Values Vs
New Values.
NOTIFICATION 2:
Condition:
● Opportunity Group = Managed Services AND
● (Opportunity Probability has changed OR Opportunity Stage has changed)
Action:
● Send Email to the [email protected] email group
● Notifying the changes of Probability and Stage fields capturing Earlier Values Vs
New Values.
//Iterate Opportunity .
for(Opportunity objOpportunityNew : lstOpportunityNew){
insert lstOpportunity;
//Fetching and update stageName & probability on Opportunity.
Opportunity objOpportunityToUpdate = [SELECT Id,StageName,Probability FROM
Opportunity WHERE id =: objOpportunity.Id];
objOpportunityToUpdate.StageName = 'Closed Won';
objOpportunityToUpdate.Probability =86.8;
update objOpportunityToUpdate;
Completed
Govardhini: TASK 5 : Write a trigger to implement a logic so that at any given time there
should be only one Contact under an Account which is marked as Primary.
DESIGN CONSIDERATIONS:
● On Account we have one Text field called Primary Contact
● On Contact we have one checkbox field called Primary
● Using trigger implement a logic so that at any given time there should be only one
Contact under an Account which is marked as Primary,
● Example(Scenario):
○ Account Name --> Test Account
○ Related Contacts --> A, B, C, D
○ If Contact B is marked as Primary then all other Contact's Primary checkbox
should be set to false.
○ Now if I go update Contact C as Primary then Contact C will become primary and
all other Contact's Primary Contact should be set to false.
○ The trigger should also update Account's Primary Contact field with selected
Primary Contact Name.
if(objContact.Primary__c)
objContact.Primary__c = False;
lstContactToUpdate.add(objContact);
}
update lstContactToUpdate;
}
====================================test=========================
/*
@MethodName : primaryContact
@param :-
@Description: primaryContact method will create and Update the contact record.
*/
@isTest
static void primaryContact(){
DESIGN CONSIDERATIONS:
● Create a custom field of type Checkbox in Lead Object named “Convert Lead”
● Whenever the Convert Lead field is set to true
○ Convert this lead in context to
■ Account
■ Contact
■ Opportunity
objLeadOld = mapLeadOld.get(objLeadNew.Id);
}
//Instance Database.LeadConvertResult.
Database.LeadConvertResult objLeadConvertResult =
Database.convertLead(objLeadConvert);
}
}
}
}
}
================================tEST======================
/*
@MethodName : convertLead
@param :-
@Description: convertLead method will create the Lead record.
*/
@ISTest
static void convertLead(){
lstlead.add(objLead1);
}
insert lstlead;
lstleadToUpdate.add(objLeadToUpdate);
}
update lstleadToUpdate;
References :
● https://trailhead.salesforce.com/en/content/learn/modules/
leads_opportunities_lightning_experience/create-and-convert-leads-lightning
● https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/
langCon_apex_dml_examples_convertlead.htm
Test class pending
Sagar P: TASK 7 : Write a trigger to create a Task whenever a Lead is getting converted.
DESIGN CONSIDERATIONS:
● Whenever the Lead is getting Converted
○ Create a Task
■ Subject - 'Please reach out to the Contact to understand next steps'
■ Type - Phone
■ Task Owner - Converted Account’s Owner
■ WhatID - Converted Account’s Id
■ WhoID - Converted Contact’s Id
if(objLeadNew.isConverted == false){
//Instance Database.LeadConvert.
Database.LeadConvert objLeadConvert = new Database.LeadConvert();
objLeadConvert.setLeadId(objLeadNew.Id);
objLeadConvert.setConvertedStatus(convertStatus.MasterLabel);
//Instance Database.LeadConvertResult.
Database.LeadConvertResult objLeadConvertResult =
Database.convertLead(objLeadConvert);
if(objLeadConvertResult.accountid != Null)
setAccountIds.add(objLeadConvertResult.accountid);
lstleadsConvertResult.add(objLeadConvertResult);
}
}
}
lstlead.add(objLead);
lstlead.add(objLead1);
}
insert lstlead;
if(!objLead.IsConverted){
lstleadToUpdate.add(objLeadToUpdate);
}
}
update lstleadToUpdate;
Completed
Syeda: TASK 8 : Write a trigger to create a Task whenever a Case is populated with a
Contact.
DESIGN CONSIDERATIONS:
● Whenever the Case is populated with a Contact
○ Create a Task with the below details
■ Subject - 'Please reach out to the Contact to understand next steps'
■ Type - Phone
■ Task Owner - Case’s Account’s Owner
■ WhatID - Case Id
■ WhoID - Case’s Contact Id
//check trigger event and compare old and new value of case.
if(strTriggerEvent == 'Insert' || objCaseNew.ContactId != objCaseOld.ContactId){
if(objCaseNew.AccountId != Null){
setAccountIds.add(objCaseNew.AccountId);
}
lstCaseToUpdate.add(objCaseNew);
}
}
}
mapAccount.put(objAccount.Id, objAccount);
}
}
//create task.
List<Task> lstTask = new List<Task>();
for(Case objCase : lstCaseToUpdate){
Task objTask = new Task(Subject = 'Please reach out to the Contact to understand
next steps',
Type = 'Phone',
WhatId = objCase.Id,
WhoId = objCase.ContactId);
lstCase.add(objCase2);
insert lstCase;
lstContact.add(objContact);
lstContact.add(objContact1);
insert lstContact;
lstCase.add(objCase);
Completed
Shubham: TASK 9 : Write a trigger to create a Task whenever the PULSE in an Account is
marked as “RED”.
DESIGN CONSIDERATIONS:
● Create a custom field of type Picklist in Account Object named “PULSE” with values as
listed below
○ RED
○ YELLOW
○ GREEN
● Whenever the Pulse is changed to RED
○ Create a Task with the below details
■ Subject - 'You will need to setup a call with the team to understand what
are the next steps to be taken care to make it Green or Yellow’
■ Type - Phone
■ Task Owner - Account’s Owner
■ WhatID - Account Id
if(objAccount.Pulse__c == 'RED'){
//create task.
Task objTask = new Task(Subject = 'You will need to setup a call with the
team to understand what are the next steps to be taken care to make it Green or Yellow',
Type = 'Phone',
OwnerId = objAccount.OwnerId,
WhatId = objAccount.Id);
lstTask.add(objTask);
}
}
}
insert lstTask;
}
================================tEST======================
/*
@MethodName : checkTaskCreated
@param :-
@Description: checkTaskCreated method will create the Account record.
*/
@isTest
private static void checkTaskCreated(){
//create profile for the user.
Profile objProfile = [SELECT Id FROM Profile WHERE Name='System Administrator'
limit 1];
//create user.
user objUser = new User(LastName = 'User1',
Email = '[email protected]',
Alias = 'Test1',
Username = '[email protected]',
CommunityNickname = 'test12',
LocaleSidKey = 'en_US',
TimeZoneSidKey = 'GMT',
profileId = objProfile.Id,
LanguageLocaleKey = 'en_US',
EmailEncodingKey = 'UTF-8');
insert objUser;
insert lstAccount;
Completed
Kiran: TASK 10 : Write a trigger, if the owner of an account is changed then the previous
owner should be notified of this change.
DESIGN CONSIDERATIONS:
● Whenever the owner of an Account is changed
○ Send an email notification to the previous owner stating that the Account’s
ownership got changed from him/her to the new owner in context
//Iterate Account.
for(Account objAccount : lstAccountNew){
if(mapAccountOld.containskey(objAccount.id)){
if(objAccount.OwnerId != objAccountOld.OwnerId){
//Store Account prior values in setAccountOldId.
setAccountOldId.add(objAccountOld.Id);
setAccountIds.add(objAccount.Id);
}
}
}
lstMails.add(email);
}
}
/*
@MethodName : changeAccountOwner
@param :-
@Description: changeAccountOwner method will change the Account owner.
*/
@isTest
static void changeAccountOwner(){
//create user.
user objUser1 = new User(LastName = 'User1',
Email = '[email protected]',
Alias = 'Test1',
Username = '[email protected]',
CommunityNickname = 'test123',
LocaleSidKey = 'en_US',
TimeZoneSidKey = 'GMT',
profileId = objProfile.Id,
LanguageLocaleKey = 'en_US',
EmailEncodingKey = 'UTF-8');
lstUser.add(objUser1);
//create user.
user objUser2 = new User(LastName = 'User2',
Email = '[email protected]',
Alias = 'Test2',
Username = '[email protected]',
CommunityNickname = 'test456',
LocaleSidKey = 'en_US',
TimeZoneSidKey = 'GMT',
profileId = objProfile.Id,
LanguageLocaleKey = 'en_US',
EmailEncodingKey = 'UTF-8');
lstUser.add(objUser2);
insert lstUser;
completed
Shveta: TASK 11 : Write a trigger, to split the Total Amount budgeted from the Account
into its Contact records equally.
DESIGN CONSIDERATIONS:
● Create a custom field of type Currency in Account Object named “Total Budgeted
Amount”. This is a mandatory field.
● Create a custom field of type Currency in Contact Object named “Budget Amount”. This
is a mandatory field.
● Whenever the Total Budgeted Amount is populated or changed in the Account then
○ Distribute the Total Budgeted amount from the Account equally among it’s
related Contacts.
if(objAccount.Total_Budgeted_Amount__c == Null){
objAccount.addError('Enter Total Budgeted Amount filed');
}
else{
mapAccountToStore.put(objAccount.Id, objAccount);
}
}
objContact.Budgeted_Amount__c =
(mapAccountToStore.get(objContact.AccountId).Total_Budgeted_Amount__c/
lstContact.size());
lstContactToUpdate.add(objContact);
}
update lstContactToUpdate;
}
}
=============================TEST======================================
/*
@MethodName : displayBugdetOnAccount
@param :-
@Description: displayBugdetOnAccount method will create the Account record.
*/
@isTest
static void displayBugdetOnAccount(){
lstContact.add(objContact);
}
insert lstContact;
DESIGN CONSIDERATIONS:
● Create a custom field of type Percentage in Contact Object named “Budget Allocation”.
This is a mandatory field. However, this field can accept a value as 0.
● Whenever Contact is created/updated/deleted
○ Validate the summation of the Budget Allocation field of all the Contact(s) under
an Account is always 100%.
@MethodName : budgetAllocation
@param
: List<Contact> lstContactNew, Map<Id,Contact> mapContactOld, String strTriggerEvent.
if(objContact.AccountId != Null){
if(objContact.Budget_Allocation__c == Null){
objContact.addError('Please enter the Budget_Allocation__c field');
}
double totalPercent = 0;
for(Contact objContact : [SELECT Id, Budget_Allocation__c FROM Contact WHERE
AccountId =: setAccountIds]){
totalPercent += objContact.Budget_Allocation__c;
}
If(strTriggerEvent == 'delete')
totalPercent-= objContactToUpdate.Budget_Allocation__c;
}
}
}
===============================Test======================================
/*
@MethodName : budgetAllocation
@param :-
@Description: budgetAllocation method will create the contact record.
*/
@isTest
static void budgetAllocation(){
delete objContact1;
}
completed
Noel: TASK 13 : Write a trigger, to create a User whenever the Create User field in
Contact is checked the first time.
DESIGN CONSIDERATIONS:
● Create a custom field of type checkbox in Contact Object named “Create User”. Not a
required field.
● Create a custom field of type text in User Object named “Contact ID”.
● Whenever Contact is created/updated with the Create User checkbox as Checked for
the first time AND there is no User already created for this Contact Then
○ Create a User record with details from Contact.
○ Also ensure to assign Contact Id field on User record with Contact’s Id.
//calling futureMethodToInsertUser;
Sl_FutureMethodToCreateUser.futureMethodToInsertUser(setContactIds);
}
=============FUTURE METHOD
public class Sl_FutureMethodToCreateUser{
/*
@MethodName : futureMethodToInsertUser
@param : List<Contact> lstContactNew, Map<Id,Contact> mapContactOld,
String strTriggerEvent.
@Description: futureMethodToInsertUser method called on is After update of
Contact Object.
*/
@future
public static void futureMethodToInsertUser(Set<Id> contactIds){
if(objContact.Create_User__c){
//Taking instance of User
User objUserToInsert = new User(LastName=objContact.LastName,
Email=objContact.LastName+'a'+System.now().millisecond()
+ '[email protected]',
Alias='a'+System.now().millisecond(),
Username = System.now().millisecond() + '[email protected]',
UserRoleId=portalRole.Id,
ProfileId=objProfile.Id,
IsActive=false,
TimeZoneSidKey='GMT',
LanguageLocaleKey='en_US',
EmailEncodingKey= 'UTF-8',
LocaleSidKey= 'en_US',
Contact_ID__c=objContact.Id);
// objUserToInsert.ContactId=objContact.Id;
if(objUserToInsert!=NULL)
lstUser.Add(objUserToInsert);
}
}
System.debug('=======>'+lstUser);
insert lstUser;
}
}
=============================TEST======================================
/*
@MethodName : createUser
@param :-
@Description: createUser method will create the contact record.
*/
@isTest
static void createUser(){
//create Contact records related to objAccount.
List<Contact> lstContact = new List<Contact>();
Contact objContact = new Contact(LastName = 'muffasser12',
Create_User__c = true,
MailingState = 'ab',
Email ='[email protected]');
lstContact.add(objContact);
Contact objContact1 = new Contact(LastName = 'muffasser34',
Create_User__c = true,
MailingState = 'bc',
Email ='[email protected]');
lstContact.add(objContact1);
test.startTest();
Sl_FutureMethodToCreateUser.futureMethodToInsertUser(setid);
test.stopTest();
completed
Sumanth P: TASK 14 : Write a trigger, to assign the user to the relevant group based on
profile.
DESIGN CONSIDERATIONS:
● Create a public group named “Users”
● Create a public group named “Admins”
● Whenever User is created/updated/deactivated
○ Check for the Profile of the User and add/remove the User to the respective
groups as shown below in the mapping
=============================Handler============================
/*
* @ClassName : SL_UserHandler
* @JIRATicket : -
* @CreatedOn : 30/Aug/2022
* @ModifiedBy : SL_R_MD_MUFFASSER
* @Description : This is the handler class for User trigger runs when insert And update
operation are doing.
*/
public class SL_UserHandler{
/*
@MethodName : isAfterInsert
@param : List<User> lstUserNew.
@Description: isAfterInsert method called on is After Insert of User object.
*/
public void isAfterInsert(List<User> lstUserNew){
/*
@MethodName : isAfterUpdate
@param : List<User> lstUserNew, Map<Id,User> mapUserOld.
@Description: isAfterUpdate method called on is After update of User Object.
*/
public void isAfterUpdate(List<User> lstUserNew, Map<Id,User> mapUserOld){
/*
@MethodName : assignUsersToGroup
@param : List<User> lstUserNew, Map<Id,User> mapUserOld.
@Description: assignUsersToGroup method will add/remove the User to the
respective groups .
*/
private void assignUsersToGroup(List<User> lstUserNew, Map<Id,User> mapUserOld,
String strTriggerEvent){
//Fetching profile Id's
Profile objUserProfile = [SELECT Id FROM Profile WHERE Name='Standard User' Limit
1];
Profile objAdminProfile = [SELECT Id FROM Profile WHERE Name='System
Administrator' Limit 1];
//Itreating User
list<GroupMember> lstGroupMember = new list<GroupMember>();
for(User objUserNew : lstUserNew){
//Check user profile id with Standard User and adding to public group.
if(objUserNew.ProfileId == objUserProfile.Id){
GroupMember objGroupMember = new GroupMember(GroupId
=mapUserToFetch.get('Users').Id,
UserOrGroupId = objUserNew.Id);
lstGroupMember.add(objGroupMember);
}
//Check user profile id with System Administrator and adding to public group.
else if(objUserNew.ProfileId == objAdminProfile.Id){
GroupMember objGroupMember = new GroupMember(GroupId
=mapUserToFetch.get('Admins').Id,
UserOrGroupId = objUserNew.Id);
lstGroupMember.add(objGroupMember);
}
}
//create user.
list<User> lstUser = new list<User>();
insert lstUser;