Question?
- Which Object
- Contact
- Events
- after insert, after delete, after undelete, after update
- Functionality
- Develop a Solution that will count the related contact related to the Account and store the information in the “Number of Contacts” field.
What is Roll-Up Summary Trigger?
In Salesforce, a Roll-Up Summary Trigger is a mechanism used to calculate and summarize data from related records and update a field on a parent record accordingly.
For example, consider a scenario where you have a custom object called "Invoice Line Item" and another object called "Invoice". Each Invoice can have multiple Invoice Line Items associated with it. If you want to calculate the total amount of all the Invoice Line Items and display it on the corresponding Invoice record, you can use a Roll-Up Summary Trigger.
Roll-up summary triggers in Salesforce typically use "after" triggers. This is because roll-up summary triggers need to recalculate the aggregate values on the parent record after any changes to the child records have been committed to the database.
public class ContactTriggerHandler {
public static void handleAfterInsert(Map<Id, Contact> newRecordsMap){
ContactTriggerHelper.countContact(newRecordsMap);
}
public static void handleAfterUndelete(Map<Id, Contact> newRecordsMap){
ContactTriggerHelper.countContact(newRecordsMap);
}
public static void handleAfterDelete(Map<Id, Contact> oldRecordsMap){
ContactTriggerHelper.countContact(oldRecordsMap);
}
public static void handleAfterUpdate(Map<Id, Contact> newRecordsMap, Map<Id, Contact> oldRecordsMap){
Set<Id> accountIdsSet = new Set<Id>();
for(Contact newRecord : newRecordsMap.values() ){
Contact oldRecord = oldRecordsMap.get(newRecord.Id);
if(oldRecord.AccountId <> newRecord.AccountId){
accountIdsSet.add(oldRecord.AccountId); // ABC
accountIdsSet.add(newRecord.AccountId); // XYZ
}
}
List<AggregateResult> aggregateList = [SELECT count(Id), AccountId
FROM Contact WHERE AccountId IN:accountIdsSet Group By AccountId];
List<Account> accountListToUpdate = new List<Account>();
for(AggregateResult ag : aggregateList){
String accountId = (String)ag.get('AccountId'); // Object
Integer totalContact = (Integer)ag.get('expr0'); // Object
Account accountRecord = new Account();
accountRecord.Id = accountId;
accountRecord.Number_of_Contacts__c = totalContact;
accountListToUpdate.add(accountRecord);
}
update accountListToUpdate;
}
}
Here's a step-by-step procedure of writing a roll-up summary trigger in Salesforce, considering various scenarios:
Step 1: Understand Requirements
Before writing the trigger, thoroughly understand the requirements including:
- Which object will act as the parent and which as the child.
- The relationship between the parent and child objects.
- The type of aggregation needed (sum, count, max, min, etc.).
- Any filtering criteria.
Step 2: Design the Trigger Logic
Determine how you'll implement the roll-up summary logic. Considerations may include:
- Filtering child records.
- Handling bulk data.
- Consideration for Governor Limits.
Step 3: Write the Trigger Skeleton
trigger RollupSummaryTrigger on ChildObject__c (after insert, after update, after delete, after undelete) {
// Logic will be added in subsequent steps
}
Step 3.1: Store Parent IDs from Child Records
Before querying the parent records, store the IDs of the parent records related to the child records being modified. This step ensures that you have a reference to all relevant parent records.
Step 4: Query Parent Records
Query the parent records related to the child records being modified. This step retrieves all the parent records that need to be updated.
Step 5: Determine Calculation Method
Determine whether to use aggregate queries directly or parse the child records to calculate the aggregates. The decision depends on factors like data volume, complexity of calculation, and governor limits.
If Using Aggregate Queries Directly:
- Proceed to Step 6.
- This method is suitable when dealing with large datasets or complex calculations, as aggregate queries can efficiently perform calculations across multiple records.
If Parsing Child Records:
- Proceed to Step 5.1.
- This method is suitable for simpler calculations or scenarios where aggregate queries may not suffice due to limitations or complexities.
Step 5.1: Parse Child Records (Optional)
If you've decided to parse child records instead of using aggregate queries, loop through the child records related to each parent record queried in Step 4.
Step 6: Calculate Aggregates
Perform the aggregation calculations for each parent record based on the child records. This step may involve summing up values, counting records, finding maximum or minimum values, etc.
If Using Aggregate Queries Directly:
- Use SOQL aggregate functions (like SUM, COUNT, MAX, MIN) directly in the query to calculate aggregates.
If Parsing Child Records:
- Iterate through child records related to each parent record queried in Step 4.
- Calculate the aggregates manually within the loop based on the child record values.
Step 7: Update Parent Records
Update the parent records with the calculated aggregate values obtained in Step 6.