Salesforce Asked by J. Neilan on February 14, 2021
I have a trigger and helper class (both below) on a custom object. I’ve been told that I should have a trigger, helper class, and a utility class as a best practice, but I have not used utility classes before. Does the code below require a utility class and if so how would I need to update my existing trigger and helper class?
Trigger:
trigger VTrigger on V_Type__c (after insert, after update, after delete) {
if(Trigger.isAfter && Trigger.isInsert){
VTriggerHandler.onAfterInsUp(Trigger.new);
}
if(Trigger.isAfter && Trigger.isUpdate){
VTriggerHandler.onAfterInsUp(Trigger.new);
}
if(Trigger.isAfter && Trigger.isDelete){
VTriggerHandler.onAfterDelete(Trigger.old);
}
}
Helper Class:
public class VTypeTriggerHandler {
public static void onAfterDelete (List<V_Type__c> vType){
// Sets for related Account & Contact IDs
Set<Id> acctIds = new Set<ID>();
Set<Id> contIds = new Set<ID>();
// Maps for V Types
Map<V_Type__c, V_Type__c> contactTypeMap = new Map<V_Type__c, V_Type__c>();
Map<Id, Set<String>> contactTypeMapDel = new Map<Id, Set<String>>();
// Get all the Account & Contact Ids in the Set being removed
for(V_Type__c v : vType){
acctIds.add(v.Account__c);
contIds.add(v.Contact__c);
contactTypeMapDel.put(v.Contact__c , new set<String>());
}
// Query the Accounts
List<Account> acct = new List<Account>();
// Use the V Types to get all the related Types for the Account
acct = [SELECT Id, V_Types__c,(Select V_Type__c FROM V_Types__r ORDER BY V_Type__c)
FROM Account
WHERE Id in :acctIds];
// Iterate over each Account and V record
for(Account a : acct){
a.V_Types__c = '';
for(V_Type__c v: a.V_Types__r){
if(!a.V_Types__c.contains(v.V_Type__c) || a.V_Types__c == ''){ // Check if the Type is already in the Account Field. if not add it otherwise skip
a.V_Types__c += v.V_Type__c + '; ';
}
}
}
// Update the Account
update acct;
}
public static void onAfterInsUp (List<V_Type__c> vType){
// Sets for related Account & Contact IDs
Set<Id> acctIds = new Set<ID>();
Set<Id> contIds = new Set<ID>();
// Maps for V Types
Map<V_Type__c, V_Type__c> contactTypeMap = new Map<V_Type__c, V_Type__c>();
Map<Id, Set<String>> contactTypeMapDel = new Map<Id, Set<String>>();
// Get all the Account & Contact Ids in the Set being removed
for(V_Type__c v : vType) {
acctIds.add(v.Account__c);
contIds.add(v.Contact__c);
}
List<V_Type__c> vRecs = [SELECT Id,Account__c,Contact__c,V_Type__c
FROM V_Type__c
WHERE Contact__c = :contIds AND ID NOT IN:vType];
//Check for V Types already entered for Contact
Map<Id,set<string>> existingTypeMap = new Map<Id,set<string>>();
for(V_Type__c v: vRecs) {
set<string> existingTypes = new set<string>();
if(existingTypeMap.containsKey(v.Contact__c)){
existingTypes = existingTypeMap.get(v.Contact__c);
}
existingTypes.add(v.VIP_Type__c);
existingTypeMap.put(v.Contact__c,existingTypes);
}
for (V_Type__c v : vType)
{
if (existingTypeMap.containsKey(v.Contact__c)){
if (existingTypeMap.get(v.contact__c).contains(v.V_Type__c)){
trigger.newMap.get(v.Id).addError('The V Type of '+v.V_Type__c+' already exists for this Contact');
}
else
{
Set<string> existingTypes = existingTypeMap.get(v.Contact__c);
existingTypes.add(v.V_Type__c);
existingTypeMap.put(v.Contact__c,existingTypes);
}
}
}
// Query the Accounts
List<Account> acct = new List<Account>();
// Use the V Types to get all the related Types for the Account
acct = [SELECT Id, V_Types__c,(Select V_Type__c FROM V_Types__r ORDER BY V_Type__c)
FROM Account
WHERE Id in :acctIds];
// Iterate over each Account and V record
for(Account a : acct){
a.V_Types__c = '';
for(V_Type__c v: a.V_Types__r){
if(!a.V_Types__c.contains(v.V_Type__c) || a.V_Types__c == ''){ // Check if the Type is already in the Account Field. if not add it otherwise skip
a.V_Types__c += v.V_Type__c + '; ';
}
}
}
// Update the Account
update acct;
}
}
So in the above classes if certain pieces of code that you want to use a piece of code for example like calculate total that is called in both of the methods then this piece of code is created as a method in the utility class so that there is no repetitive code.
Also, I would suggest try changing the below code from
if(Trigger.isAfter && Trigger.isInsert){
VTriggerHandler.onAfterInsUp(Trigger.new);
}
if(Trigger.isAfter && Trigger.isUpdate){
VTriggerHandler.onAfterInsUp(Trigger.new);
}
to
if(Trigger.isAfter && (Trigger.isInsert|| Trigger.isUpdate)){
VTriggerHandler.onAfterInsUp(Trigger.new);
}
You can have a look at these links that can help:
Correct answer by Anutej on February 14, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP