Best Practices for Creating Salesforce Roll-Up Summary Triggers

Understanding the Use of Roll-Up Summary Fields in Salesforce

Roll-up summary fields are a powerful feature in Salesforce that allow you to automatically display calculated values on a master record based on the related detail records. These detail records must be linked directly to the master record through a master-detail relationship. With roll-up summary fields, you can perform various calculations, such as totals, counts, and averages, making it easier to track important metrics related to your data.

Why Use Roll-Up Summary Fields?

Roll-up summary fields provide several benefits:

  • Automated Calculations: They automatically update whenever related detail records are created, updated, or deleted, ensuring your master record reflects the most current data.
  • Data Integrity: By consolidating information from related records, roll-up summary fields help maintain data integrity and accuracy within your Salesforce org.
  • Improved Reporting: They enhance your reporting capabilities by summarizing data without requiring complex queries or custom code.

Let's Code Together

In this section, we’ll implement a trigger that utilizes roll-up summary functionality to track the total amount, latest paid date, and count of opportunities related to any account. This trigger will activate whenever an opportunity is created, deleted, or restored from the recycle bin.

/**** @Author: skbsfdc @Description: Roll Up Trigger to get Total Amount, Latest Paid Date & Count of opportunities related to any account whenever any opportunity is created, deleted, or restored from the recycle bin. @Code Standard: Followed Best Practices ****/ trigger AccountOppRollUpSummary on Opportunity (after insert, after update, after delete, after undelete) { Opportunity[] objects = null; Set<Id> accountByIds = new Set<Id>(); Map<Id, Account> accountMapToUpdate = new Map<Id, Account>(); // Handling filter for delete logic if (Trigger.isDelete) { objects = Trigger.old; } else { objects = Trigger.new; } // Collect Account IDs from the opportunities if (objects.size() > 0) { for (Opportunity opp : objects) { // Adding Account IDs to the set accountByIds.add(opp.AccountId); } } // Query to aggregate data for the related accounts if (accountByIds.size() > 0) { // Using aggregate functions in SOQL to summarize data for (AggregateResult aggr : [SELECT Count(Id) ids, AccountId, SUM(Amount) amt, MAX(Paid_On__c) maxdate FROM Opportunity WHERE AccountId IN :accountByIds GROUP BY AccountId]) { Account accounts = new Account(); accounts.Total_Amount__c = (Decimal) aggr.get('amt'); accounts.Total_Opportunity__c = (Integer) aggr.get('ids'); accounts.Recent_Pay__c = (Date) aggr.get('maxdate'); accounts.Id = (Id) aggr.get('AccountId'); accountMapToUpdate.put(accounts.Id, accounts); } } // Update the accounts with the aggregated data try { update accountMapToUpdate.values(); } catch (Exception e) { System.debug('Exception Message: ' + e.getMessage() + ' | Line No: ' + e.getLineNumber()); } }

Explanation of the Code

  1. Trigger Declaration: The trigger activates on the Opportunity object for after insert, update, delete, and undelete operations.
  2. Collecting Account IDs: The trigger gathers Account IDs from the related opportunities.
  3. Aggregating Data: It uses a SOQL query with aggregate functions to count the number of opportunities, sum their amounts, and find the latest paid date for each account.
  4. Updating Accounts: The trigger updates the corresponding account records with the calculated values.

Conclusion

Roll-up summary fields in Salesforce provide a straightforward way to summarize related data automatically. By implementing triggers like the one shown above, you can maintain accurate and up-to-date information on your master records, enhancing both data integrity and reporting capabilities.

If you have any questions or need further assistance, feel free to reach out!

Comments

  1. i liked this post very much, wanted to check use inthis case with AggregatedResult.***THANKS***
    Please keep post like this.loop me in all your upcoming contents like this.

    ReplyDelete
  2. In case of reparenting opportunities to another account, old account ids will have to separately added to the account id set, so the first loop will become,

    for(Opportunity opp : updatedData){
    accountByIds.add(opp.AccountId);
    if(Trigger.isUpdate){
    accountByIds.add(Trigger.OldMap.get(opp.Id).AccountId);
    }
    }

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. This code has one bug. If account has only one opportunity and If I delete it. The aggreagateResult query will return null. So even if the account record will not have any child opportunity record anymore. Still the count field on account record page will still show 1.

    ReplyDelete

Post a Comment

Popular posts from this blog

CREATE WEB-FORM USING LIGHTNING WEB COMPONENTS SALESFORCE

Utilizing a Generic Pagination Class in Lightning Web Components - Part 1