Tag Archives: Apex Trigger

Webservice Callout From Apex Trigger

In certain scenarios, we need to make the webservice callout from the apex trigger to call an external webservice. We cannot call external web services synchronously from triggers, because calling a web service synchronously from triggers will hold up the database transaction until the callout completed. This will impact performance for other transactions. In this scenario we can invoke callouts from triggers by encapsulating the callouts in @future methods. Here is an example, how to invoke webservice callouts from trigger.

Apex Class:

public class LeadTriggerHandler {
    
    @future (callout=true)
    public static void sendLeadInfo(string firstName, string lastName, string email) {
        try{
            HttpRequest request = new HttpRequest();
            HttpResponse response = new HttpResponse();
            Http http = new Http();
            
            request.setEndpoint('Your Endpoint URL');
            request.setHeader('Content-Type','application/json'); 
            request.setMethod('POST');
            request.setBody('fname='+EncodingUtil.urlEncode(firstName, 'UTF-8')+'&lname='+EncodingUtil.urlEncode(lastName, 'UTF-8')
                            '&email='+EncodingUtil.urlEncode(email, 'UTF-8'));
            request.setCompressed(true);
            
            response = http.send(request);
            if (response.getStatusCode() == 200) {
                System.debug('Response-' + response);
            }
        }
        catch(System.CalloutException e){
            System.debug('Error-' + e.getMessage());   
        }
    }
}

Apex Trigger:

trigger LeadTrigger on Lead (after insert) {
    
    for (Lead objLead : Trigger.new) {
        //make webservice callout 
        LeadTriggerHandler.sendLeadInfo(objLead.FirstName, objLead.LastName, objLead.Email);
    }
}

Restrict multiple approval for a single user to a single record in Salesforce

I had a requirement to restrict multiple approval for a single user to a single record. There were multiple steps of approval process and the approver may be in different queue or as a manager for a user.

So, I implemented it using a trigger. In this article I’ll demonstrate how to implement it.
Here Application__c is the object, on which 3 steps approval process has implemented.
A custom check box field Check_Approver__c has set value to true, in all 3 steps field update action.

In below trigger I filtered the ProcessInstanceStep object records with current user Id in ActorId and the object Id (here object Id means record Id) in ProcessInstance.TargetObjectId.

  • If an User will approve or reject a record, then the SOQL query will return a single record.
  • If the SOQL query return a record, then trigger will throw an error message.

Trigger source code:

trigger ApplicationTrigger on Application__c (before Update)
{
    if(trigger.isUpdate){

        Id currentUserId = UserInfo.getUserId();
        for(Application__c sf: trigger.new){   
                  
            if(sf.Check_Approver__c == true){
              
                List<processinstancestep> existingApprovals = [SELECT ActorId
                                    FROM ProcessInstanceStep WHERE ProcessInstance.TargetObjectId = :sf.Id
                                    AND (StepStatus = 'Approved' OR StepStatus = 'Rejected')
                                    AND ActorId = :currentUserId];
                                      
                if(existingApprovals != null){
                  
                    if(existingApprovals.size() > 0){

                        sf.addError('You have already approved or rejeted the record.');
                    }
                }                  
             }
         }                         
    }
}

Salesforce Apex Trigger Variable Availability to Events

Trigger.new Trigger.newMap Trigger.Old Trigger.OldMap
Before Insert Yes No No No
Before Update Yes Yes Yes Yes
Before Delete Yes Yes Yes Yes
After Insert Yes Yes No No
After Update Yes Yes Yes Yes
After Delete No No Yes No
After Undelete Yes Yes No No

Rollup Summary Trigger for a Lookup Relationship

Here is a sample Rollup Summary calculation trigger for Lookup relationship. In below example I’m using Account object as parent and Contact object as child.

I’m updating parent object Account record field Total__c with Sum of all related child object Contact records Amount__c field value.

Apex Trigger:

trigger RollUpFromChildToParent on Contact (after insert, after update, after delete, after undelete) {
    
    Set<Id> accountIds = new Set<Id>();
    List<Account> accList = new List<Account>();
    
    if(Trigger.isInsert || Trigger.isUpdate || Trigger.isUndelete){
        for(Contact con : Trigger.new){
            if(con.AccountId != null){
                accountIds.add(con.AccountId); 
            }
        }
    }
    
    If(Trigger.isDelete){
        for(Contact con : Trigger.old){
            if(con.AccountId != null){
                accountIds.add(con.AccountId);
            }
        }
    }
    
    for(AggregateResult aRes : [SELECT AccountId, SUM(Amount__c) Total FROM Contact WHERE AccountId IN :accountIds GROUP BY AccountId]) {
        accList.add(new Account(Id = (Id)aRes.get('AccountId'), Total__c = (Decimal)aRes.get('Total')));
    }
    
    try{
        Update accList;
    }catch(DmlException de){
        System.debug(de);
    }
}