You need to sign in to do that
Don't have an account?
Help bulkifying trigger
I'm wondering if someone could help me bulkify this trigger. As background, we have a custom object RBA_Invoice_Line_Item__c in master-detail to RBA_Participant__c and RBA_Invoice__c. We would like to get a double amount updated on the Participant based on the Invoice Date. If it's in the current month, the total amount from the Line Items would update "Current Month Total" on the Participant. The same would happen for Line Items where the invoice date = last month, to update a "Previous Month Total" field on Participant.
Here is the trigger:
trigger RBA_Invoice_Line_Item_RollupTrigger on RBA_Invoice_Line_Item__c (after update, after insert, after delete) { Map<Id, Double> previousMonthTotals = new Map<Id, Double>(); Map<Id, Double> currentMonthTotals = new Map<Id, Double>(); List<RBA_Participant__c> participantsToUpdate = new List<RBA_Participant__c>(); List<RBA_Invoice_Line_Item__c> itemsForParticipant; List<RBA_Invoice_Line_Item__c> items; if (trigger.isDelete) { items = trigger.old; } else { items = trigger.new; } // Go through all of the line items that the trigger // is acting on for (RBA_Invoice_Line_Item__c triggerItem: items) { // Get the participant's ID for the line item and then // ensure their ID exists in the previous / current month totals // maps and their totals default to $0.00 Id participant = triggerItem.RBA_Participant__c; if (!previousMonthTotals.containsKey(participant)) { previousMonthTotals.put(participant, 0.0); } if (!currentMonthTotals.containsKey(participant)) { currentMonthTotals.put(participant, 0.0); } // Sum the total cost of all previous month's line items // for the current participant (see participant above) // // 1. get all of the line items for the previous month // 2. for each line item update the mapping for the participant // to be (previous total + total cost) itemsForParticipant = [SELECT Id, Total_Cost__c FROM RBA_Invoice_Line_Item__c WHERE Invoice_Date__c = LAST_MONTH AND RBA_Participant__c = :participant]; for (RBA_Invoice_Line_Item__c item : itemsForParticipant) { // previous month total = current total cost + total cost of line item previousMonthTotals.put(participant, previousMonthTotals.get(participant) + item.Total_Cost__c); } // Sum the total cost of all current month's line items // for the current participant (see participant above) // // 1. get all of the line items for the current month // 2. for each line item update the mapping for the participant // to be (previous total + total cost) itemsForParticipant = [SELECT Id, Total_Cost__c FROM RBA_Invoice_Line_Item__c WHERE Invoice_Date__c = THIS_MONTH AND RBA_Participant__c = :participant]; for (RBA_Invoice_Line_Item__c item : itemsForParticipant) { // current month total = current total cost + total cost of line item currentMonthTotals.put(participant, currentMonthTotals.get(participant) + item.Total_Cost__c); } } // Collect all of the unique participant IDs from both // mappings into a list List<Id> participants = new List<Id>(); // First add all previous month unique participants for (Id previous : previousMonthTotals.keyset()) { participants.add(previous); } // ... then add any participants in the current month totals // that aren't in the previous month totals for (Id current : currentMonthTotals.keyset()) { if (!previousMonthTotals.containsKey(current)) { participants .add(current); } } // For each collected participant ID from the previous step, retrieve the participant // record from Salesforce then update their totals if and only if we collected // totals from them for (Id id : participants) { RBA_Participant__c participant = [SELECT Id, Previous_Month_Total__c, Current_Month_Total__c FROM RBA_Participant__c WHERE Id = :id]; if (previousMonthTotals.containsKey(id)) { participant.Previous_Month_Total__c = previousMonthTotals.get(id); } if (currentMonthTotals.containsKey(id)) { participant.Current_Month_Total__c = currentMonthTotals.get(id); } // Collect participant record in a list we will then batch update // once we are done looping participantsToUpdate.add(participant); } // Batch update all updated participants update participantsToUpdate; }
I see this in the debug log:
09:22:32.982|CUMULATIVE_PROFILING|SOQL operations| Trigger.RBA_Invoice_Line_Item_RollupTrigger: line 43, column 1: [SELECT Id, Total_Cost__c FROM RBA_Invoice_Line_Item__c WHERE Invoice_Date__c = LAST_MONTH AND RBA_Participant__c = :participant]: executed 51 times in 279 ms Trigger.RBA_Invoice_Line_Item_RollupTrigger: line 60, column 1: [SELECT Id, Total_Cost__c FROM RBA_Invoice_Line_Item__c WHERE Invoice_Date__c = THIS_MONTH AND RBA_Participant__c = :participant]: executed 50 times in 182 ms
but I'm not sure how/where to move those queries?
Try This,
*** I have not compiled this code, so please correct if any syntax error.
All Answers
Try This,
*** I have not compiled this code, so please correct if any syntax error.
THANK YOU so much! I have a lot to learn!