Skip to content

Configuring Grandparent (or Greater) Rollups

James Simone edited this page Sep 29, 2023 · 6 revisions

Grandparent Rollups

As mentioned in the Readme, it's possible to roll up values straight from grandchild-level descendants directly to the grandparent level. An example of this would be rolling up the TotalPrice field on all Opportunity Product items straight to the Account's Annual Revenue field:

  • Opportunity Product (grandchild)
  • Opportunity (parent)
  • Account (grandparent)

As is often the case, we'll be using standard Salesforce fields to demonstrate this example.

Configuring grandparent-level rollups through Custom Metadata

The Custom Metadata Setup

Only one additional field needs to be filled out on the Rollup CMDT record in order to get your basic grandparent rollup configured:

  • Grandparent Relationship Field Path: to fill out this field properly, include period separated relationship names up to and including the final rollup field you'd like to write to. With our Opportunity Product to Account example, this would be properly setup by using Opportunity.Account.AnnualRevenue. Opportunity stands for the relationship name on Opportunity Product to Opportunity; Account stands for the relationship name on Opportunity to Account, and AnnualRevenue is the field we want to write to.

Here's an example CMDT record set up properly:

Example grandparent rollup

The Apex Setup

To configure grandparent rollups properly, there are a few triggers that need to be modified (or trigger handler classes):

  • the trigger on Opportunity Product
  • the trigger on Opportunity

Here's your example Opportunity Product trigger:

trigger OpportunityProductTrigger on OpportunityLineItem (before insert, after insert, before update, after update, before delete, after undelete) {
  Rollup.runFromTrigger();
}

And your example Opportunity trigger:

trigger OpportunityTrigger on Opportunity (before insert, after insert, before update, after update, before delete, after undelete) {
  Rollup.runFromTrigger();
}

The reason it's required to also use the one-liner in your Opportunity trigger as well as the object where the Rollup is based is because if an Opportunity's Account lookup field is updated, we need to ensure that the rollup is re-calculated for both the old and new Accounts.

Configuring grandparent-level rollups through Flow

It's possible to use Record-Triggered Flows instead of the Apex-based approach outlined above. For a low or no-code org, this may be preferable; if you're using CMDT Rollup records, you can simply use the Rollup__mdt-based Apex Action to call your grandparent rollups:

Example grandparent flow

These are the only properties that you need to set:

  • Rollup Context - UPSERT for RT-flows set to run on create/update (otherwise you'll need three flows; one set to INSERT for a RT-flow set to run after a record is created; one set to UPDATE for a RT-flow set to run after a record is updated, as well as the DELETE flow stipulated next) and DELETE for a RT-flow to run before a record is deleted.
  • Prior Records To Rollup (only necessary if this a RT-flow set to run on create/update) - please see the New Assignment section for setting up the basic Flow Apex Action for more information
  • Records To Rollup - a collection variable with {!$Record} in it
  • Defer Processing - can be set to {!$GlobalConstant.False} if this is the only rollup you're configuring; otherwise, after all of your Apex Actions associated with Rollup, add the Process Deferred Rollups Apex Action to kick things off properly

This is what the simplest possible RT-flow for create/update would look like after having been set up (note that this assumes that Defer Processing was either not set, or was set to {!$GlobalConstant.True}:

What the flow should look like when properly configured

If you aren't using CMDT, please refer to the guide on setting up the basic Flow Apex Action for more detailed instructions.

Special Considerations For Flow

Please note that just like the Apex-configured approach, all intermediate objects (Opportunity, in our example) must also have a RT-flow setup to call the Apex Rollup actions. Again, this is to ensure rollups are always calculated correctly if any of the intermediate parent objects have their lookup fields changed.

Configuring More Complicated Grandparent Rollups

The only thing that's important to keep in mind if you are rolling up to a great-grandparent (or greater!) relationship:

  • You need to keep adding on the relationship name in the Grandparent Relationship Field Path. If you had a custom object below Opportunity Product that you were rolling up to the Account Annual Revenue field, your relationship field path might look like OpportunityLineItem__r.Opportunity.Account.AnnualRevenue (where OpportunityLineItem__r was the relationship name for the custom lookup field to Opportunity Product)
  • You also need to add the Apex one-liner or configure additional RT flows on both Opportunity Product and Opportunity; again, any intermediate object in the chain needs to call Apex Rollup so that any reparenting situations can be properly calculated. Any rollups configured on intermediate objects are not there to update the intermediate records, but rather exist to ensure that reparenting accurately re-triggers rollups for the eventual grandchildren records