Skip to content

Perform Rollup On Records Base Invocable Action

james simone edited this page Mar 31, 2023 · 13 revisions

Perform rollup on records Invocable

This Invocable Action is referred to as the "base" action because it comes from Rollup.cls, the entry point for all things apex-rollup. It works best when called from a Record-Triggered Flow, where you have access to the $Record and $Record_Prior variables.

Prerequisites

Please ensure you've enabled the Rollup Setting Custom Setting org default record prior to setting up any flows - otherwise your rollups won't calculate!

Setting Up Your Record-Triggered Flow

Let's start from the beginning by going screen-by-screen on a new Record-Triggered Flow:

Setting up a Record-Triggered Flow

To properly pass your input variables to the flow, create two Collection variables (you can call them whatever you'd like; I tend to go with Records and OldRecords):

Create flow collection variables

  • the easiest way to do this is to start in an Assignment element and click the box under the "Variable" section
  • click "New Resource"
    • Resource Type: Variable
    • API Name: again, I usually go with "Records" and "OldRecords"
    • Description: optional
    • Data Type: Record (be sure to check off the "Allow multiple values" checkbox)
    • Object: select the same object that your Record-Triggered flow starts from
    • Availability Outside The Flow: make sure to check off "Available for Input"
  • select your newly created resource and change the Operator value to "Add"
  • use $Record as the value for your "Records" collection, and $Record_Prior for the "OldRecords" collection. Note that the assingment of $Record_Prior is only necessary if you're using a Record-Triggered Flow set to run when A record is created or updated

Here's what your Assignment element should look like once all that jazz is done:

Assign to collection variables

Once you've assigned your variable(s) to their respective collections, you're ready to interact with the base invocable action! Click the "+" sign on your flow path and under "Interactions", select "Action" - by default, the actions are brought up with "Categories" as the filtered-on drop-down on the left side of the pop-up. If you scroll down within this categorized list, you'll find "Rollups" as one of the listed categories:

Find Rollups in the categorized list of Actions

Now, when you start typing in the Action search bar on the right side of the pop-up, you'll only see options out of the three invocable actions included with apex-rollup:

Find Rollups in the categorized list of Actions

The first search result, Perform rollup on records is the "base" invocable action. Once you've selected that, the pop-up will transform and you'll be able to start entering the required information for this Action to work! You'll have to fill out both objects under the "Select Objects" header with the type of child object you're working with* (footnote below) before the other invocable fields will be shown:

Filling out the base action's first screen

*: Unless the rollup is triggered from the parent using the Is Rollup Started From Parent optional field, in which case you would be selecting the parent type here.

Once you've filled out these fields, the rest of the Action's fields are displayed:

Filling out the base action's first screen

Filling Out Action Fields

Now, let's walk field-by-field through the pictured options on the base Action so that you know exactly how to fill it out:

Required Fields

Important note before beginning - while the below fields are the only ones that are required, there are two record collection fields in the optional section, at least one of which is actually required.

  • Calc Item Calc Field - the field on your child object that contains the value(s) that will be rolled up. Note that you are using the API name (including the __c for custom fields) for the field here, not its field label.
  • Calc Item Lookup Field - the field on your child object that contains the reference to the parent object. While "lookup" field is part of the name here, the field does not have to be a lookup; any text field containing a Salesforce Id or other unique identifier on another object will work. Like Calc Item Calc Field, use the field's API name.
  • Rollup Object API Name - this is the API name for the parent object. Going off of the example pictured above, I would use RollupParent__c here.
  • Rollup Object Calc Field - the API name of the field where the rolled-up values will be stored.
  • Rollup Object Lookup Field - the API name of the field that lines up with the parent's unique relationship to its children (this field should match, per parent, the child values found in Calc Item Lookup Field). Using Id here will be very common when the relationship is a straightforward lookup relationship.
  • Rollup Operation - the values here correspond to the values found on the Rollup__mdt.RollupOperation__c picklist (and they should be written out in all caps):
    • ALL
    • AVERAGE
    • CONCAT_DISTINCT
    • CONCAT
    • COUNT_DISTINCT
    • COUNT
    • FIRST
    • LAST
    • MAX
    • MIN
    • MOST
    • NONE
    • SOME
  • Rollup Operation Context - for a Record-Triggered Flow, this describes when the flow will run:
    • INSERT - if your flow only runs after a record is created
    • UPDATE - if your flow only runs after a record is updated
    • UPSERT - if your flow runs after a record is created or updated
    • REFRESH - if you want the rollup action to fully recalculate the rollup values for any parent object that has children records passed through the flow
    • DELETE - if your flow runs before a record is deleted

Here's what the base action's required fields look like when filled out:

Filling out the base action's required fields


Optional Fields

At least one of the two record collection fields here are actually required; they are listed as optional to prevent some Flow -> Apex issues:

  • Prior records to rollup -- only required if you are using a RT-flow set to run on create and update, or an update RT-flow. Use the collection variable you've already set up in your assignment element and reference the collection variable you made earlier that contains $Record_Prior
  • Records to rollup -- actually required for all flows calling the Apex action. For a Record-Triggered Flow, you'll use the collection variable you made earlier that contains $Record. This collection could also be set to the results of a Get Records element.

Here's a screenshot with the same RT-flow pictured above, with the two collection variables filled out:

Filling out the base action's collection variables

In addition to the required attributes for your invocable, there are quite a few optional properties that can be filled out. Some of these are intended to be used in conjunction with other optional properties; these dependencies are called out within the description wherever applicable. Other properties are compatible but aren't explicitly called out as such: for example, it's possible to perform both a grandparent rollup (Opportunity Line Item -> Opportunity -> Account) and roll up to the ultimate hierarchical account using the hierarchy Parent Account ID field.

Without further ado, the additional properties:

  • Calc Item Changed Fields -- a comma-separated text variable holding the API names of fields you'd like to check for changes. Note that for Record-Triggered Flows using the UPSERT rollup context, this calculation won't be done for records that are being newly created; the check will only be done for items that are updated. If you are using a SOQL Where Clause To Exclude Calc Items, I would not recommend using this field.
  • Calc Item Type When Rollup Started From Parent -- to be used in conjunction with Is Rollup Started From Parent. The API name of the child object when the records being passed into the flow are the parent records, and you want to find all matching children for each parent record passed in.
  • Concat Delimiter -- by default, operations using CONCAT or CONCAT_DISTINCT will use a comma when appending additional values. You can override this default by supplying a value here. Note that if you are rolling up to a multi-select picklist, this field value will be ignored in favor of a semi-colon.
  • Defer Processing -- if you have multiple rollup operations to perform within a single flow, you should consider toggling this field off and setting it to {!$GlobalConstant.True}. If you don't use this field, each rollup you're performing will fire immediately; for rollups all using the same parent object, this can lead to extra updates (and burn through extra Async Apex Jobs). At the same time, using this field requires you to use the third included invocable action, Process Deferred Rollups -- otherwise, it's possible that not all of your queued rollups will run before your flow ends.
  • Full Recalculation Default Number Value -- entering a number in this field will use that number (instead of whatever pre-existing value is on the parent record) as the basis for beginning rollup calculations.
  • Full Recalculation Default String Value -- same as Full Recalculation Default Number Value, but for all text-based rollup fields.
  • Grandparent Relationship Field Path -- please see the Grandparent Rollups section of the README for full details.
  • Is Full Record Set -- use with caution. By default, rollup operations don't assume that the children records being passed in are the full list of children for any given parent record. However, if you know that the records being passed in will always be the full list of children for a given parent (most typically because you've just retrieved all applicable children via a Get Records element), you can set this field equal to {!$GlobalConstant.True}. You'll also want to use either Full Recalculation Default Number Value (if the parent field is a number) or Full Recalculation Default String Value (if the parent field is text-based) when using this field. Also note that some operations (AVERAGE, CONCAT_DISTINCT, COUNT_DISTINCT, FIRST, LAST) always try to make sure (by using SOQL) that additional children related to the same parent don't exist prior to rolling up, because those operations don't "work" in the absence of the full record set. For those operations, you don't need to use this field, because you're already covered.
  • Is Rollup Started From Parent -- set to {!$GlobalConstant.True} if the records that are triggering the rollup are the parent-level items, and you want to recalculate the rollup field(s) for the parent items. If this field is used, you must also fill out Calc Item Type When Rollup Started From Parent.
  • Order By (First/Last) (optional) - only valid when FIRST/LAST/MOST is used as the Rollup Operation (alternatively, if a Limit Amount is stipulated). Accepts a comma-separated list associated with the fields you'd like to order by, including the sort order and null sort order. For example: Name nulls last, Industry would use the Name field on a record with nulls last, followed by a sort on the Industry field to do tie-breakers. This field is optional on a first/last operation, and if a field is not supplied, the Rollup Field On Calc Item is used.
    • If this is not filled out, the rollup items will be ordered using the Rollup field on Calc Item field for rollups where ordering is required.
  • Should rollup to ultimate hierarchy parent -- must be used in conjunction with Ultimate Parent Field (below). Enables hierarchical rollups on any lookup field that is self-referential (e.g. a lookup field back to the same object as the Lookup Object field). Set to {!$GlobalConstant.True} to enable.
  • Should run sync -- basically the opposite of Defer Processing (though the two can be used in tandem -- spicy!). When set to {!$GlobalConstant.True}, rollup calculations will begin immediately. If Defer Processing is also enabled, the synchronous part will only begin after the Process Deferred Rollup action is called.
  • SOQL Where Clause To Exclude Calc Items -- think of this like adding a SOQL where clause to rollup calculations. Please see the Special Considerations For Usage Of The Calc Item Where Clause section of the README for advanced tidbits.
  • Ultimate Parent Field -- used in conjunction with Should rollup to ultimate hierarchy parent. The API name of the field on the Lookup Object that contains the hierarchy lookup field. On Account, this would be ParentId. Unlike Lookup Field On Lookup Object, where a lookup field isn't truly required so long as there is a matching key value from the Calc Item Lookup Field to the Rollup Object Lookup Field, this field truly requires a lookup field as the backing value.