Author Archives: Biswajeet

About Biswajeet

Biswajeet is my Name, Success is my Aim and Challenge is my Game. Risk & Riding is my Passion and Hard Work is my Occupation. Love is my Friend, Perfection is my Habit and Smartness is my Style. Smiling is my Hobby, Politeness is my Policy and Confidence is my Power.

Salesforce Apex Trigger Framework

Benefits of Apex Trigger Framework:

  • A single trigger per object gives complete control over the order of execution.
  • Implementing trigger logic in handler class, makes unit testing and maintenance much easier.
  • Implementation of best practices.
  • It enforces trigger to work in a consistent way.
  • It allows to prevent trigger recursion without adding separate logic.
  • It is easier to work on a single trigger for multiple developers and reduce the development lifecycle.
  • It allows to make decisions to active/inactive the trigger from transaction and UI as well.

Each trigger must be implemented in a custom setting that allows the trigger to be active/inactive from UI.
Custom Settings: (Trigger Setting)

Trigger Setting Data: (Create record for each trigger)

Trigger Interface: (ITriggerHandler)

/*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Trigger Handler Interface
*/
public interface ITriggerHandler{
    
    /*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Called by the trigger framework before insert of the records
@Parameters : List<sObject> newList , Map<Id, sObject> newMap
*/
    void beforeInsert(List<sObject> newList);
    
    /*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Called by the trigger framework after insert of the records
@Parameters : List<sObject> newList
*/
    void afterInsert(List<sObject> newList, Map<Id, sObject> newMap);
    
    /*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Called by the trigger framework before update of the records
@Parameters : List<sObject> newList, Map<Id, sObject> newMap,  List<sObject> oldList, Map<Id, sObject> oldMap
*/
    void beforeUpdate(List<sObject> newList, Map<Id, sObject> newMap,  List<sObject> oldList, Map<Id, sObject> oldMap);
    
    /*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Called by the trigger framework after update of the records
@Parameters : List<sObject> newList, Map<Id, sObject> newMap,  List<sObject> oldList, Map<Id, sObject> oldMap
*/
    void afterUpdate(List<sObject> newList, Map<Id, sObject> newMap,  List<sObject> oldList, Map<Id, sObject> oldMap);
    
    /*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Called by the trigger framework before delete of the records
@Parameters : List<sObject> oldList , Map<Id, sObject> oldMap
*/            
    void beforeDelete(List<sObject> oldList , Map<Id, sObject> oldMap);
    
    /*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Called by the trigger framework after delete of the records
@Parameters : Map<Id, sObject> oldMap
*/
    void afterDelete(List<sObject> oldList , Map<Id, sObject> oldMap);
    
    /*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Called by the trigger framework after undelete of the records
@Parameters : List<sObject> newList, Map<Id, sObject> newMap
*/
    void afterUnDelete(List<sObject> newList, Map<Id, sObject> newMap);
    
    /*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Called by the trigger framework to check the trigger for the object is enabled or disabled
@Parameters :
*/
    Boolean isDisabled();
}

Trigger Dispatcher Class:(TriggerDispatcher)

/*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Trigger Dispatcher.
*/
public class TriggerDispatcher {
    
    /*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : It will invoke the appropriate methods on the handler depending on the trigger context.
@Parameters : ITriggerHandler handler
*/
    public static void run(ITriggerHandler handler, string triggerName){
        
        //Check if the trigger is disabled
        if (handler.IsDisabled()){
            return;
        }
        
        //Get the trigger active information from custom settings by trigger name
        Boolean isActive = TriggerSetting__c.getValues(triggerName).isActive__c;
        
        if(isActive){
            //Check trigger context from trigger operation type
            switch on Trigger.operationType {
                
                when BEFORE_INSERT {
                    //Invoke before insert trigger handler
                    handler.beforeInsert(trigger.new);
                }
                when AFTER_INSERT {
                    //Invoke after insert trigger handler
                    handler.afterInsert(trigger.new, trigger.newMap);
                }
                when BEFORE_UPDATE {
                    //Invoke before update trigger handler
                    handler.beforeUpdate(trigger.new, trigger.newMap, trigger.old, trigger.oldMap);
                }
                when AFTER_UPDATE {
                    //Invoke after update trigger handler
                    handler.afterUpdate(trigger.new, trigger.newMap, trigger.old, trigger.oldMap);
                }
                when BEFORE_DELETE {
                    //Invoke before delete trigger handler
                    handler.beforeDelete(trigger.old, trigger.oldMap);
                }
                when AFTER_DELETE {
                    //Invoke after delete trigger handler
                    handler.afterDelete(trigger.old, trigger.oldMap);
                }
                when AFTER_UNDELETE {
                    //Invoke after undelete trigger handler
                    handler.afterUnDelete(trigger.new, trigger.newMap);
                }
            }
        }
    }
}

Account Object Trigger: (AccountTrigger)

/*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Account Object Trigger.
*/
trigger AccountTrigger on Account(before insert, after insert, before update, after update, before delete, after delete, after unDelete) {
    TriggerDispatcher.run(new AccountTriggerHandler(), 'AccountTrigger');
}

Account Object Trigger Handler: (AccountTriggerHandler)

/*
@Author : Biswajeet Samal
@CreatedDate : 20th Oct 2019
@Description : Account Object Trigger Handler.
*/
public class AccountTriggerHandler implements ITriggerHandler{
    
    //Use this variable to disable this trigger from transaction
    public static Boolean TriggerDisabled = false;
    
    //check if the trigger is disabled from transaction
    public Boolean isDisabled(){
        return TriggerDisabled;
    }
    
    public void beforeInsert(List<sObject> newList) {
        
    }
    
    public void afterInsert(List<sObject> newList , Map<Id, sObject> newMap) {
        
    }
    
    public void beforeUpdate(List<sObject> newList, Map<Id, sObject> newMap, List<sObject> oldList, Map<Id, sObject> oldMap) {
        
    }
    
    public void afterUpdate(List<sObject> newList, Map<Id, sObject> newMap,  List<sObject> oldList, Map<Id, sObject> oldMap) {
        
    }
    
    public void beforeDelete(List<sObject> oldList , Map<Id, sObject> oldMap) {
        
    }
    
    public void afterDelete(List<sObject> oldList , Map<Id, sObject> oldMap) {
        
    }
    
    public void afterUnDelete(List<sObject> newList, Map<Id, sObject> newMap) {
        
    }
}

Count Unique Row Values in Salesforce Lightning Report

In Winter ’20 release Salesforce has introduced report Count Unique Row Values in Lightning experience.

Go to Setup | Reports and Dashboards Settings | Select Enable Unique Row Count Aggregate in Reports (Lightning Experience Only) | click Save.

While editing a report in the report builder, find the column for which you want to count unique values | Click Show More | Show Unique Count | Click Save.

JavaScript Confirm Dialog In Lightning Component

Lightning Component:

<aura:component implements="flexipage:availableForAllPageTypes,force:appHostable">
    
    <!--Attributes-->
    <aura:attribute name="showConfirmDialog" type="boolean" default="false"/>
    
    <!--Component Start-->
    <div class="slds-m-around_xx-large">
        <lightning:button name="delete" variant="brand" label="Delete" onclick="{!c.handleConfirmDialog}"/>
    </div>
    <!--Component End-->
</aura:component>

Lightning JS Controller:

({
    handleConfirmDialog : function(component, event, helper) {
        var selectedEventId = event.target.id;
        var msg ='Are you sure you want to delete this item?';
        if (!confirm(msg)) {
            console.log('No');
            return false;
        } else {
            console.log('Yes');
            //Write your confirmed logic
        }
    },
})

Output: