All Projects → abhinavguptas → Salesforce Lookup Rollup Summaries

abhinavguptas / Salesforce Lookup Rollup Summaries

Apex utility classes that makes it easy to write trigger that rollup on LOOKUP parent child relationships.

Labels

Projects that are alternatives of or similar to Salesforce Lookup Rollup Summaries

Batch Entry For Salesforce.com
jQuery-based quick entry screen that works with any object. Highly configurable and flexible.
Stars: ✭ 82 (-34.92%)
Mutual labels:  apex
Apex Unified Logging
Platform-Event-based Apex logger for unified logging over transaction boundaries
Stars: ✭ 101 (-19.84%)
Mutual labels:  apex
Node Lambda Log
Basic logging mechanism for Node 6.10+ Lambda Functions
Stars: ✭ 115 (-8.73%)
Mutual labels:  apex
Sirono Common
Common Apex utility classes and frameworks used by Sirono products
Stars: ✭ 87 (-30.95%)
Mutual labels:  apex
Force Dot Com Esapi
Enterprise Security API for the Apex language on the Force.com platform.
Stars: ✭ 98 (-22.22%)
Mutual labels:  apex
Zippex
Native Apex Zip library for Salesforce.com
Stars: ✭ 106 (-15.87%)
Mutual labels:  apex
Query.apex
A dynamic SOQL and SOSL query builder on Salesforce.com platform
Stars: ✭ 78 (-38.1%)
Mutual labels:  apex
Fflib Apex Common Samplecode
Samples application illustrating the Apex Enterprise Patterns library
Stars: ✭ 121 (-3.97%)
Mutual labels:  apex
Vim Force.com
Vim plugin for force.com
Stars: ✭ 98 (-22.22%)
Mutual labels:  apex
Df12 Deployment Tools
Stars: ✭ 112 (-11.11%)
Mutual labels:  apex
Automated Testing For Force.com
Salesforce testing automation runs all tests and emails your team. Native Force.com Apex code delivers lightweight Salesforce continuous integration.
Stars: ✭ 88 (-30.16%)
Mutual labels:  apex
Sfdx Travisci
Stars: ✭ 95 (-24.6%)
Mutual labels:  apex
Testdatafactory
The ultimate Apex Test Data Factory 🏭
Stars: ✭ 108 (-14.29%)
Mutual labels:  apex
Dialogue Generation
Generating responses with pretrained XLNet and GPT-2 in PyTorch.
Stars: ✭ 86 (-31.75%)
Mutual labels:  apex
Sfdx Simple
Stars: ✭ 119 (-5.56%)
Mutual labels:  apex
Apextestkit
A way to simplify your Salesforce data creation.
Stars: ✭ 80 (-36.51%)
Mutual labels:  apex
Easy Spaces Lwc
Sample application for Lightning Web Components on Salesforce Platform. Part of the sample gallery. Event management use case. Get inspired and learn best practices.
Stars: ✭ 104 (-17.46%)
Mutual labels:  apex
Visualforce Table Grid
Flexible and highly customizable Visualforce table grid component. Salesforce.com Classic Look and Feel.
Stars: ✭ 126 (+0%)
Mutual labels:  apex
Apex Nitro
Your essential APEX companion
Stars: ✭ 122 (-3.17%)
Mutual labels:  apex
Sfdx Dreamhouse
Stars: ✭ 110 (-12.7%)
Mutual labels:  apex

What problem are we trying to solve ?

Rollup summary fields are pretty common requirement in force.com customizations and app development. Rollups are easy to create on master-detail relationships as they are available as a field type. But on certain limits/situations we need to write apex code for rolling up the child information for common aggregations like COUNT, SUM, AVG, MAX/MIN etc, some of these limitations are

The 'USUAL' approach to handle this limitation is to either

  • Write trigger on various DML(Create, Update, Delete/Undelete) events on child sobject. These trigger either manually aggregated the information via Apex or used SOQL Aggregate queries for the same.
  • Write some batch/scheduled apex to perform this nightly.

Problem in USUAL approach ?

Most of the times the rollup code/logic is pretty similar. Bigger problem happens sometimes in following situation

  • Client asked for a rollup field on lookup
    • Developer added a trigger on child object with required events
  • After few weeks client asked for another such rollup field on the same lookup object.
    • Developer tried not to disturb logic of existing trigger and added new trigger on same object for addressing the requirement

This approach tends to burst when there are many such code driven lookup fields added over the time, and multiple developers are working on same codebase. Its pretty easy to run close to governor limits, as similar aggregations are happening multiple times separately in different triggers, those governor limits most probably would be

  • Number of SOQL queries
  • Number of records fetched
  • Script statements consumed

How this lib ('LREngine') solves the problem ?

This library contains one single class called "LREngine" i.e. "L"ookup "R"ollup Engine, which

  • Performs rollup on multiple such fields in a single aggregate soql query.
  • Allows easy addition/removal of new fields to rollup as requirement changes over the span of time.
  • Developer needs to write only a single trigger for multiple rollup fields.
  • Allows developer to filter the child records getting rolled up, just like standard rollup summary fields

Using LREngine in Triggers

Using LREngine in trigger is fairly simple as indicated in the code snippet, developer just needs to take care of checks related to business requirements and call the LREngine.

Please note : Make sure you have trapped all create/delete/undelete/update events on child object to make sure all calculations are correct.

trigger OppRollup on Opportunity (after insert, after update, 
                                        after delete, after undelete) {
      // modified objects whose parent records should be updated
     Opportunity[] objects = null;   

     if (Trigger.isDelete) {
         objects = Trigger.old;
     } else {
        /*
            Handle any filtering required, specially on Trigger.isUpdate event. If the rolled up fields
            are not changed, then please make sure you skip the rollup operation.
            We are not adding that for sake of similicity of this illustration.
        */ 
        objects = Trigger.new;
     }

     /*
      First step is to create a context for LREngine, by specifying parent and child objects and
      lookup relationship field name
     */
     LREngine.Context ctx = new LREngine.Context(Account.SobjectType, // parent object
                                            Opportunity.SobjectType,  // child object
                                            Schema.SObjectType.Opportunity.fields.AccountId // relationship field name
                                            );     
     /*
      Next, one can add multiple rollup fields on the above relationship. 
      Here specify 
       1. The field to which aggregated value will be saved in master/parent object
       2. The field to aggregate in child object
       3. The aggregate operation to be done i.e. SUM, AVG, COUNT, MIN/MAX
     */
     ctx.add(
            new LREngine.RollupSummaryField(
                                            Schema.SObjectType.Account.fields.AnnualRevenue,
                                            Schema.SObjectType.Opportunity.fields.Amount,
                                            LREngine.RollupOperation.Sum 
                                         )); 
     ctx.add(
            new LREngine.RollupSummaryField(
                                            Schema.SObjectType.Account.fields.SLAExpirationDate__c,
                                               Schema.SObjectType.Opportunity.fields.CloseDate,
                                               LREngine.RollupOperation.Max
                                         ));                                       
	 
     /* 
      Calling rollup method returns in memory master objects with aggregated values in them. 
      Please note these master records are not persisted back, so that client gets a chance 
      to post process them after rollup
      */ 
     Sobject[] masters = LREngine.rollUp(ctx, objects);    

     // Persiste the changes in master
     update masters;
}

Using LREngine in Batch/Scheduled/etc Apex

If we are not using triggers for some reason to aggregate the detail records. In that case Batch or Scheduled Apex is used on some occasions. Calling LREngine is fairly easy, once you have master record ids in hand just call the API as indicated in the code snippet below:

LREngine.Context ctx = // create context with required roll up summary fields as shown in above code snippet
Set<Id> masterRecordIds = // master record ids as per the business logic
Sobject[] masters = LREngine.rollUp(ctx, masterRecordIds);   

Adding some conditional filtering to the rollup operation

Doing this is pretty easy, just add the condition in the Context constructor as shown below

LREngine.Context ctx = new LREngine.Context(Account.SobjectType, 
	                        Opportunity.SobjectType, 
	                        Schema.SObjectType.Opportunity.fields.AccountId,
	                        'Amount > 200' // filter out any opps with amount less than 200
	                        );

Installing LREngine

This is fairly simple, just copy the LREngine.cls (Core logic) and TestLREngine.cls(Test case + code coverage) to help.

Important points

  • Using LREngine is not recommended when number of child records associated with master records are too much. Because salesforce limit on "Total number of records retrieved by SOQL queries" is 50,000 as of now.
  • LREngine doesn't persists changes back to master records after rollup. This gives client code to perform any further calculations, but please make sure you call UPDATE on master records to persist the changes.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].