Invocablemethod Apex Class Rollup Multiple Currency Fields

313 views Asked by At

I'm writing an invocablemethod batch apex class to rollup multiple currency fields on an "Order Package" object to its parent object of "Order Location". I thought I got everything added properly but it seems to be updating both the "Package_Monthly_Recurring_Fees__c" and the "Package_One_Time_Fees__c" to the same price from the Package_Monthly_Recurring_Fees__c field. Can someone help me identify why it's using the same price for both fields? Any help is much 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.*/
                if (System.isFuture() == false && System.isBatch() == false) {
                    summarizeOrderPackagesAsync(OrderLocationIds);
                }
                else {
                    new OrderLocationRollupSummary().summarizeOrderPackages(OrderLocationIds);
                }
            }
        }
    
        @future
        public static void summarizeOrderPackagesAsync(Set<Id> OrderLocationIds) {
            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, double> 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;
    
                if (results.containsKey(ordloc.Id)) {
                    mrf = results.get(ordloc.Id);
                    otf = results.get(ordloc.Id);
                }
    
                //Determine if Amounts have Changed
                if (ordloc.Package_Monthly_Recurring_Fees__c != mrf || 
                    ordloc.Package_One_Time_Fees__c != otf) {
                    
                    ordloc.Package_Monthly_Recurring_Fees__c = mrf;
                    ordloc.Package_One_Time_Fees__c = otf;
                    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, double> getOrderPackagesAmountsByLocationId(Set<Id> OrderLocationIds) {
            Map<Id, double> resultsByOrderLocationId = new Map<Id, double>();
    
            //Summarize Order Package Amounts by Order Location Id
            AggregateResult[] results = aggregateOrderPackageAmounts(OrderLocationIds);
            for (AggregateResult result : results) {
                Id orderlocationId = (Id) result.get('OrderLocation');
                double mrf = (double) result.get('MRFees');
                double otf = (double) result.get('OTFees');
    
                resultsByOrderLocationId.put(orderlocationId, mrf);
                resultsByOrderLocationId.put(orderlocationId, otf);
            }
            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
                FROM 
                    Order_New_Location__c 
                WHERE 
                    Id IN :OrderLocationIds];
        }
    
        private AggregateResult[] aggregateOrderPackageAmounts(Set<Id> OrderLocationIds) {
            return [SELECT 
                     New_Location_Name__c OrderLocation
                    ,SUM(Monthly_Recurring_Fees__c) MRFees
                    ,SUM(One_Time_Fees__c) OTFees
                FROM 
                    Order_Location_Package__c
                WHERE
                    New_Location_Name__c IN :OrderLocationIds
                GROUP BY 
                    New_Location_Name__c];
        }
    
    }
2

There are 2 answers

4
Robert Williams On BEST ANSWER

Within your summarizeOrderPackages method, the following code is setting the 'mrf' and 'oft' variables to the same value.

        if (results.containsKey(ordloc.Id)) {
            mrf = results.get(ordloc.Id);
            otf = results.get(ordloc.Id);
        }

Afterwards, you are then setting the fields in question to the mrf and otf variables (which have the same value).

        //Determine if Amounts have Changed
        if (ordloc.Package_Monthly_Recurring_Fees__c != mrf || 
            ordloc.Package_One_Time_Fees__c != otf) {
            
            ordloc.Package_Monthly_Recurring_Fees__c = mrf;
            ordloc.Package_One_Time_Fees__c = otf;
            orderlocationsToUpdate.add(ordloc); //Add location to collection to be updated
        }

Consider adding a wrapper and inner class within your OrderLocationRollupSummary class to solve this problem:

  public class Order_New_Location_Wrapper {
    Id orderlocationId = {get;set;}
    Double mrf = {get;set;}
    Double otf = {get;set;}
    public class Order_New_Location_Wrapper (Id arg1, Double arg2, Double arg3)
    orderlocationId = arg1;
    mrf = arg2;
    otf = arg3;
  }

Then call this new inner class within your getOrderPackagesAmountsByLocationId method:

public Map<Id, Order_New_Location_Wrapper> getOrderPackagesAmountsByLocationId(Set<Id> OrderLocationIds) {

//create a list of orderlocations to represent the collection objects coming from the wrapper 
        
        resultsByOrderLocationId = new Map<Id, Order_New_Location_Wrapper>();

        //Summarize Order Package Amounts by Order Location Id
        AggregateResult[] results = aggregateOrderPackageAmounts(OrderLocationIds);
        for (AggregateResult result : results) {
            Id orderlocationId = (Id) result.get('OrderLocation');
            double mrf = (double) result.get('MRFees');
            double otf = (double) result.get('OTFees');

            resultsByOrderLocationId.add(orderlocationId, new OpportunityWrapper(orderlocationId, mrg, otf));
        }
        return resultsByOrderLocationId;
    }

You'll also need to update your summarizeOrderPackages method to be something like this:

public void summarizeOrderPackages(Set<Id> OrderLocationIds) {
    //Get Order Locations to Update
    List<Order_New_Location__c> orderlocations = queryOrderLocationsById(OrderLocationIds);

    Map<Id, Order_New_Location_Wrapper> 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;

        if (results.containsKey(ordloc.Id)) {
            mrf = (Order_New_Location__c) results.get(ordloc.Id).mrf;
            otf = (Order_New_Location__c) results.get(ordloc.Id).otf;
        }

        //Determine if Amounts have Changed
        if (ordloc.Package_Monthly_Recurring_Fees__c != mrf || 
            ordloc.Package_One_Time_Fees__c != otf) {
            
            ordloc.Package_Monthly_Recurring_Fees__c = mrf;
            ordloc.Package_One_Time_Fees__c = otf;
            orderlocationsToUpdate.add(ordloc); //Add location to collection to be updated
        }
    }

    if(orderlocationsToUpdate.isEmpty() == false) {
        Database.SaveResult[] saveResults = Database.update(orderlocationsToUpdate, false);
        System.debug(saveResults);
    }
}
0
Scott On

I was able to take care of this just by updating a few of my methods, see below. Thanks again for your help Robert!

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.*/
        if (System.isFuture() == false && System.isBatch() == false) {
            summarizeOrderPackagesAsync(OrderLocationIds);
        }
        else {
            new OrderLocationRollupSummary().summarizeOrderPackages(OrderLocationIds);
        }
    }
}

@future
public static void summarizeOrderPackagesAsync(Set<Id> OrderLocationIds) {
    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;

        if (results.containsKey(ordloc.Id)) {
            AggregateResult ar = results.get(ordloc.Id);
            mrf = (double)ar.get('MRFees');
            otf = (double)ar.get('OTFees');
        }

        //Determine if Amounts have Changed
        if (ordloc.Package_Monthly_Recurring_Fees__c != mrf || 
            ordloc.Package_One_Time_Fees__c != otf) {
            
            ordloc.Package_Monthly_Recurring_Fees__c = mrf;
            ordloc.Package_One_Time_Fees__c = otf;
            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
        FROM 
            Order_New_Location__c 
        WHERE 
            Id IN :OrderLocationIds];
}

private AggregateResult[] aggregateOrderPackageAmounts(Set<Id> OrderLocationIds) {
    return [SELECT 
             New_Location_Name__c OrderLocation
            ,SUM(Monthly_Recurring_Fees__c) MRFees
            ,SUM(One_Time_Fees__c) OTFees
        FROM 
            Order_Location_Package__c
        WHERE
            New_Location_Name__c IN :OrderLocationIds
        GROUP BY 
            New_Location_Name__c];
}

}