You need to sign in to do that
Don't have an account?
Scott Landes
How to add Record Collection to Invocablemethod Apex Class
Hello, I'm writing a rollup apex class to rollup multiple currency fields to a parent object. I've got almost everything dialed in except I'm running into an issue with this running after I've deleted records. Once the records are deleted, I would imagine that I would need to pass in a record collection into the class to rollup any existing records, but my invocablemethod only allows a single record to be added. Is there any way I could pass in a record collection and have this class perform the rollup on each record?
Any help is greatly appreciated!!
global class OrderLocationRollupSummary implements Database.Batchable<sObject>, Schedulable { //Invocable Method @InvocableMethod(label='Rollup All Order Packages to Locations') global static void rollupAllorderpackages(List<Order_Location_Package__c> orderpackages) { rollupOrderPackages(orderpackages); } //Batchable Methods global Database.QueryLocator start(Database.BatchableContext bc) { return Database.getQueryLocator([SELECT Id FROM Order_New_Location__c]); } global void execute(Database.BatchableContext context, List<sObject> batch){ Set<Id> OrderLocationIds = new Set<Id>(); for (sObject ordloc : batch) { OrderLocationIds.add(ordloc.Id); } summarizeOrderPackages(OrderLocationIds); } global void finish(Database.BatchableContext context) {} //Schedulable Methods global void execute(SchedulableContext context){ OrderLocationRollupSummary batchJob = new OrderLocationRollupSummary(); Database.executeBatch(batchJob); } //Static Methods public static void rollupOrderPackages(List<Order_Location_Package__c> orderpackages) { Set<Id> OrderLocationIds = new Set<Id>(); //Get Order Location Ids from specified orderpackages for (Order_Location_Package__c ordpckg : orderpackages) { OrderLocationIds.add(ordpckg.New_Location_Name__c); } if (OrderLocationIds.isEmpty() == false) { /*Execute as a future call so that the user doesn't have to wait around for the rollup to finish. Unless, already in a future or batch call state then just perform the rollup.*/ new OrderLocationRollupSummary().summarizeOrderPackages(OrderLocationIds); } } //Public Methods public void summarizeOrderPackages(Set<Id> OrderLocationIds) { //Get Order Locations to Update List<Order_New_Location__c> orderlocations = queryOrderLocationsById(OrderLocationIds); Map<Id, AggregateResult> results = getOrderPackagesAmountsByLocationId(OrderLocationIds); //Loop Order Locations and set Amounts List<Order_New_Location__c> orderlocationsToUpdate = new List<Order_New_Location__c>(); for (Order_New_Location__c ordloc : orderlocations) { double mrf = 0; double otf = 0; double vdotf = 0; double vdmrr = 0; double bdotf = 0; double bdmrr = 0; double dmrf = 0; double dotf = 0; if (results.containsKey(ordloc.Id)) { AggregateResult ar = results.get(ordloc.Id); mrf = (double)ar.get('MRFees'); otf = (double)ar.get('OTFees'); vdotf = (double)ar.get('VDOTFQ'); vdmrr = (double)ar.get('VDMRRQ'); bdotf = (double)ar.get('BDOTFQ'); bdmrr = (double)ar.get('BDMRRQ'); dmrf = (double)ar.get('DDMRF'); dotf = (double)ar.get('DDOTF'); } //Determine if Amounts have Changed if ( ordloc.Package_Monthly_Recurring_Fees__c != mrf || ordloc.Package_One_Time_Fees__c != otf || ordloc.Volume_Discount_OTF__c != vdotf || ordloc.Volume_Discount_MRR__c != vdmrr || ordloc.Bundle_Discount_OTF__c != bdotf || ordloc.Bundle_Discount_MRR__c != bdmrr || ordloc.Discretionary_Discounts_MRF__c != dmrf || ordloc.Discretionary_Discounts_OTF__c != dotf ) { ordloc.Package_Monthly_Recurring_Fees__c = mrf; ordloc.Package_One_Time_Fees__c = otf; ordloc.Volume_Discount_OTF__c = vdotf; ordloc.Volume_Discount_MRR__c = vdmrr; ordloc.Bundle_Discount_OTF__c = bdotf; ordloc.Bundle_Discount_MRR__c = bdmrr; ordloc.Discretionary_Discounts_MRF__c = dmrf; ordloc.Discretionary_Discounts_OTF__c = dotf; orderlocationsToUpdate.add(ordloc); //Add location to collection to be updated } } if(orderlocationsToUpdate.isEmpty() == false) { Database.SaveResult[] saveResults = Database.update(orderlocationsToUpdate, false); System.debug(saveResults); } } //Private Methods public Map<Id, AggregateResult> getOrderPackagesAmountsByLocationId(Set<Id> OrderLocationIds) { Map<id,AggregateResult> resultsByOrderLocationId= new Map<Id,AggregateResult>(); //Summarize Order Package Amounts by Order Location Id AggregateResult[] results = aggregateOrderPackageAmounts(OrderLocationIds); for (AggregateResult result : results) { Id orderlocationId = (Id) result.get('OrderLocation'); resultsByOrderLocationId.put(orderlocationId, result ); } return resultsByOrderLocationId; } //Query Methods private List<Order_New_Location__c> queryOrderLocationsById(Set<Id> OrderLocationIds) { return [SELECT Id, Package_Monthly_Recurring_Fees__c, Package_One_Time_Fees__c, Bundle_Discount_MRR__c, Bundle_Discount_OTF__c, Volume_Discount_MRR__c, Volume_Discount_OTF__c, Discretionary_Discounts_MRF__c, Discretionary_Discounts_OTF__c FROM Order_New_Location__c WHERE Id IN :OrderLocationIds]; } private AggregateResult[] aggregateOrderPackageAmounts(Set<Id> OrderLocationIds) { return [SELECT New_Location_Name__c OrderLocation, SUM(Total_Monthly_Recurring_Fees__c) MRFees, SUM(Total_One_Time_Fees__c) OTFees, SUM(Volume_Discount_OTF__c) VDOTFQ, SUM(Volume_Discount_MRR__c) VDMRRQ, SUM(Bundle_Discount_OTF__c) BDOTFQ, SUM(Bundle_Discount_MRR__c) BDMRRQ, SUM(Discount_MRF__c) DDMRF, SUM(Discount_OTF__c) DDOTF FROM Order_Location_Package__c WHERE New_Location_Name__c IN :OrderLocationIds GROUP BY New_Location_Name__c]; } }
I tried to avoid using a trigger, and just use flow, but I think the below trigger is my best bet. Does anyone have any other suggestions at all?