• Scott Landes
  • NEWBIE
  • 20 Points
  • Member since 2020

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 5
    Questions
  • 7
    Replies

I'm trying to figure out how to create an Apex trigger that fires different classes depending on the Opportunity Type. I added what I thought would work below, but it doesn't seem to be pulling the fields like I thought it would. Can someone show me how to pull in values from the updated record? Any help is greatly appreciated as I'm trying to get this fixed as soon as possible.

trigger OrderRollupSummaryTrigger on Order_Location_Package__c (after insert, after update, after delete, after undelete) {
    
	if (Order_Location_Package__c.Order_Sheet__c.Opportunity__c.Type = 'NEW' || Order_Location_Package__c.Order_Sheet__c.Opportunity__c.Type = 'Renewal') {
	    if (trigger.isAfter && (trigger.isInsert || trigger.isUpdate || trigger.isUndelete)) {
	        OrderLocationRollupSummary.rollupOrderPackages(trigger.new);
	    }
	    else if (trigger.isAfter && trigger.isDelete) {
	        OrderLocationRollupSummary.rollupOrderPackages(trigger.old);
		}
	}

	else if (Order_Location_Package__c.Order_Sheet__c.Opportunity__c.Type != 'NEW' || Order_Location_Package__c.Order_Sheet__c.Opportunity__c.Type != 'Renewal') {
	    if (trigger.isAfter && (trigger.isInsert || trigger.isUpdate || trigger.isUndelete)) {
	        OrderLocationRollupSummaryOther.rollupOrderPackages(trigger.new);
	    }
	    else if (trigger.isAfter && trigger.isDelete) {
	        OrderLocationRollupSummaryOther.rollupOrderPackages(trigger.old);
		}
	}
}
 

Thanks!

Hello,

I'm having an issue with this trigger not firing in Production. Everything works fine in the Sandbox and everything seems active so I'm unsure of what's happening. Any help is much appreciated! I'm supposed to have this live by tomorrow!

trigger OrderDiscountsRollupSummaryTrigger on Discount__c (after insert, after update, after delete, after undelete) {
    if (trigger.isAfter && (trigger.isInsert || trigger.isUpdate || trigger.isUndelete)) {
        OrderDiscountsOTFRollupSummary.rollupotfdiscounts(trigger.new);
        OrderDiscountsMRFRollupSummary.rollupmrfdiscounts(trigger.new);
    }
    else if (trigger.isAfter && trigger.isDelete) {
        OrderDiscountsOTFRollupSummary.rollupotfdiscounts(trigger.old);
        OrderDiscountsMRFRollupSummary.rollupmrfdiscounts(trigger.old);
  }
}


One of my classes is below, they are both pretty much identical.

global class OrderDiscountsMRFRollupSummary implements Database.Batchable<sObject>, Schedulable {

    //Invocable Method
    @InvocableMethod(label='Rollup All MRF Discounts to Order Packages')
    global static void rollupAllMRFDiscounts(List<Discount__c> mrfdiscounts) {
        rollupmrfdiscounts(mrfdiscounts);
    }

    //Batchable Methods
    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator([SELECT Id FROM Order_Location_Package__c]);
    }

    global void execute(Database.BatchableContext context, List<sObject> batch){
        Set<Id> OrderPackageIds = new Set<Id>();

        for (sObject ordpack : batch) {
            OrderPackageIds.add(ordpack.Id);
        }

        summarizemrfdiscounts(OrderPackageIds);
    }

    global void finish(Database.BatchableContext context) {}

    //Schedulable Methods
    global void execute(SchedulableContext context){
        OrderDiscountsMRFRollupSummary batchJob = new OrderDiscountsMRFRollupSummary();
        Database.executeBatch(batchJob);
    }

    //Static Methods
    public static void rollupmrfdiscounts(List<Discount__c> mrfdiscounts) {
        Set<Id> OrderPackageIds = new Set<Id>();

        //Get Order Location Ids from specified mrfdiscounts
        for (Discount__c ordmrfd : mrfdiscounts) {
            OrderPackageIds.add(ordmrfd.Location_Package__c);
        }

        if (OrderPackageIds.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 OrderDiscountsMRFRollupSummary().summarizemrfdiscounts(OrderPackageIds);
        }
    }

    //Public Methods
    public void summarizemrfdiscounts(Set<Id> OrderPackageIds) {
        //Get Order Locations to Update
        List<Order_Location_Package__c> orderpackages = queryOrderPackagesById(OrderPackageIds);

        Map<Id, AggregateResult> results = getmrfdiscountsAmountsByPackageId(OrderPackageIds);

        //Loop Order Locations and set Amounts
        List<Order_Location_Package__c> orderpackagesToUpdate = new List<Order_Location_Package__c>();
        for (Order_Location_Package__c ordpack : orderpackages) {
            double ddis = 0;
            double pdis = 0;

            if (results.containsKey(ordpack.Id)) {
                AggregateResult ar = results.get(ordpack.Id);
                pdis = (double)ar.get('PercentDiscount');
                ddis = (double)ar.get('DollarDiscount');
            }

            //Determine if Amounts have Changed
            if (
                ordpack.Dollar_Discount_MRR__c != ddis || 
                ordpack.Percent_Discount_MRR__c != pdis
                ) 
            {
                
                ordpack.Dollar_Discount_MRR__c = ddis;
                ordpack.Percent_Discount_MRR__c = pdis;
 
                orderpackagesToUpdate.add(ordpack); //Add location to collection to be updated
            }
        }

        if(orderpackagesToUpdate.isEmpty() == false) {
            Database.SaveResult[] saveResults = Database.update(orderpackagesToUpdate, false);
            System.debug(saveResults);
        }
    }
    //Private Methods
    public Map<Id, AggregateResult> getmrfdiscountsAmountsByPackageId(Set<Id> OrderPackageIds) {
        Map<id,AggregateResult> resultsByOrderLocationId= new Map<Id,AggregateResult>();

        //Summarize Discount Amounts by Order Package Id
        AggregateResult[] results = aggregateMRFDiscountAmounts(OrderPackageIds);
        for (AggregateResult result : results) {
            Id orderlocationId = (Id) result.get('OrderPckg');
            resultsByOrderLocationId.put(orderlocationId, result );
        }
        return resultsByOrderLocationId;
    }

    //Query Methods
    private List<Order_Location_Package__c> queryOrderPackagesById(Set<Id> OrderPackageIds) {
        return [SELECT 
                Id,
                Dollar_Discount_MRR__c,
                Percent_Discount_MRR__c

            FROM 
                Order_Location_Package__c
            WHERE 
                Id IN :OrderPackageIds];
    }

    private AggregateResult[] aggregateMRFDiscountAmounts(Set<Id> OrderPackageIds) {
        return [SELECT 
                Location_Package__c OrderPckg,
                SUM(Discount__c) PercentDiscount,
                SUM(Dollar_Discount__c) DollarDiscount

            FROM 
                Discount__c
            WHERE
                Location_Package__c IN :OrderPackageIds AND Fee__c = 'Monthly Recurring Fees'
            GROUP BY 
                Location_Package__c];
    }

}

Hey All,

I'm a bit new to writing apex and test classes, but I'm unsure why I'm getting the compiling error "Variable does not exist: Monthly_Recurring_Fees__c". I'm attempting to pull the "Monthly_Recurring_Fees__c" field from the "queriedOrder" query. Any help is appreciated!

@isTest
private class OrderRollupSummaryTest {

    private static testMethod void doTest() {
    	
    	Account testAcc  = new Account ();          
    			testAcc.Name = 'Test Account';
    			testAcc.Primary_Vertical__c = 'Multifamily Housing';
    			testAcc.Total_Locations_Owned_Managed__c = 1;
    			
    			insert testAcc;


    	Opportunity testOpp  = new Opportunity ();
       			testOpp.Name = 'Test Opportunity';
    			testOpp.AccountId = testAcc.Id;
    			testOpp.Opportunity_Source__c = 'Sales Generated';
    			testOpp.Type = 'New';
    			testOpp.StageName = 'Contract';
    			testOpp.Number_of_locations_for_opportunity__c = 1;
    			testOpp.Amount = 0;
    			testOpp.Implementation__c = 0;
    			testOpp.CloseDate = System.today() + 5;
    			testOpp.Deal_Confidence__c = 100;
    			
    			insert testOpp;

    	Package__c testPackage  = new Package__c ();
    			testPackage.Name = 'Test Package';
    			testPackage.Package_Type__c = 'Website Package';
    			testPackage.Status__c = 'Active';
    			testPackage.One_Time_Price__c = String.ValueOf(200);
    			testPackage.Monthly_Recurring_Price__c = String.ValueOf(100);
    			
    			insert testPackage;


    	Order_Sheet__c testOrder  = new Order_Sheet__c ();
    			testOrder.Opportunity__c = testOpp.id;
    			
    			insert testOrder;


    	Order_New_Location__c testOrderLocation  = new Order_New_Location__c ();
    			testOrderLocation.Order_Sheet__c = testOrder.id;
    			testOrderLocation.Name = 'Test Location';
    			
    			insert testOrderLocation;


    	Order_Location_Package__c testOrderPackage  = new Order_Location_Package__c ();
    			testOrderPackage.Order__c = testOrder.Id;
    			testOrderPackage.New_Location_Name__c = testOrderLocation.Id;
    			testOrderPackage.Package__c = testPackage.Id;
    			
    			insert testOrderPackage;

        Discount__c testMRFDiscount  = new Discount__c ();
                testMRFDiscount.Location_Package__c = testOrderPackage.Id;
                testMRFDiscount.Dollar_Discount__c = 50;
                testMRFDiscount.Fee__c = 'Monthly Recurring Fees';
                
                insert testMRFDiscount;

        Discount__c testOTFDiscount  = new Discount__c ();
                testOTFDiscount.Location_Package__c = testOrderPackage.Id;
                testOTFDiscount.Dollar_Discount__c = 50;
                testOTFDiscount.Fee__c = 'One-Time Fees';
                
                insert testOTFDiscount;


 /* --- OrderRollupSummaryTest Test --- */
		Test.startTest();

		/* --- Run Create Method--- */
    	OrderRollupSummary.rollupAllorderlocations(new List<Order_New_Location__c>{testOrderLocation});
		
		/* --- Query for Order--- */
		list<Order_Sheet__c>queriedOrder = [Select Monthly_Recurring_Fees__c FROM Order_Sheet__c WHERE Id = :testOrder.id];
        System.debug('Price after trigger fired: ' + queriedOrder.Monthly_Recurring_Fees__c);
		
		/* --- Checks to see if amounts updated --- */
        system.assertEquals(50, queriedOrder.Monthly_Recurring_Fees__c);

        Test.stopTest();


    }
}

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];
    }

}
Hello! I'm a bit new at writing Apex but I'm attempting to create an invocablemethod batch apex class to rollup multiple currency fields on an "Order Package" object to its parent object of "Order Location". Everything seems to be working as expected but I need to rollup multiple fields and I'm running into issues. Can someone show me how I might be able to include multiple fields in the rollup? I attempted to simply add another field but right now it looks like it's assigning the same amount to both fields I included. This seems to be because I am assigning the same "results" to both fields but I can't figure out how I can assign the aggregate query to multiple fields. 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.*/
                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];
        }
    
    }

 

I'm trying to figure out how to create an Apex trigger that fires different classes depending on the Opportunity Type. I added what I thought would work below, but it doesn't seem to be pulling the fields like I thought it would. Can someone show me how to pull in values from the updated record? Any help is greatly appreciated as I'm trying to get this fixed as soon as possible.

trigger OrderRollupSummaryTrigger on Order_Location_Package__c (after insert, after update, after delete, after undelete) {
    
	if (Order_Location_Package__c.Order_Sheet__c.Opportunity__c.Type = 'NEW' || Order_Location_Package__c.Order_Sheet__c.Opportunity__c.Type = 'Renewal') {
	    if (trigger.isAfter && (trigger.isInsert || trigger.isUpdate || trigger.isUndelete)) {
	        OrderLocationRollupSummary.rollupOrderPackages(trigger.new);
	    }
	    else if (trigger.isAfter && trigger.isDelete) {
	        OrderLocationRollupSummary.rollupOrderPackages(trigger.old);
		}
	}

	else if (Order_Location_Package__c.Order_Sheet__c.Opportunity__c.Type != 'NEW' || Order_Location_Package__c.Order_Sheet__c.Opportunity__c.Type != 'Renewal') {
	    if (trigger.isAfter && (trigger.isInsert || trigger.isUpdate || trigger.isUndelete)) {
	        OrderLocationRollupSummaryOther.rollupOrderPackages(trigger.new);
	    }
	    else if (trigger.isAfter && trigger.isDelete) {
	        OrderLocationRollupSummaryOther.rollupOrderPackages(trigger.old);
		}
	}
}
 

Thanks!

Hello,

I'm having an issue with this trigger not firing in Production. Everything works fine in the Sandbox and everything seems active so I'm unsure of what's happening. Any help is much appreciated! I'm supposed to have this live by tomorrow!

trigger OrderDiscountsRollupSummaryTrigger on Discount__c (after insert, after update, after delete, after undelete) {
    if (trigger.isAfter && (trigger.isInsert || trigger.isUpdate || trigger.isUndelete)) {
        OrderDiscountsOTFRollupSummary.rollupotfdiscounts(trigger.new);
        OrderDiscountsMRFRollupSummary.rollupmrfdiscounts(trigger.new);
    }
    else if (trigger.isAfter && trigger.isDelete) {
        OrderDiscountsOTFRollupSummary.rollupotfdiscounts(trigger.old);
        OrderDiscountsMRFRollupSummary.rollupmrfdiscounts(trigger.old);
  }
}


One of my classes is below, they are both pretty much identical.

global class OrderDiscountsMRFRollupSummary implements Database.Batchable<sObject>, Schedulable {

    //Invocable Method
    @InvocableMethod(label='Rollup All MRF Discounts to Order Packages')
    global static void rollupAllMRFDiscounts(List<Discount__c> mrfdiscounts) {
        rollupmrfdiscounts(mrfdiscounts);
    }

    //Batchable Methods
    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator([SELECT Id FROM Order_Location_Package__c]);
    }

    global void execute(Database.BatchableContext context, List<sObject> batch){
        Set<Id> OrderPackageIds = new Set<Id>();

        for (sObject ordpack : batch) {
            OrderPackageIds.add(ordpack.Id);
        }

        summarizemrfdiscounts(OrderPackageIds);
    }

    global void finish(Database.BatchableContext context) {}

    //Schedulable Methods
    global void execute(SchedulableContext context){
        OrderDiscountsMRFRollupSummary batchJob = new OrderDiscountsMRFRollupSummary();
        Database.executeBatch(batchJob);
    }

    //Static Methods
    public static void rollupmrfdiscounts(List<Discount__c> mrfdiscounts) {
        Set<Id> OrderPackageIds = new Set<Id>();

        //Get Order Location Ids from specified mrfdiscounts
        for (Discount__c ordmrfd : mrfdiscounts) {
            OrderPackageIds.add(ordmrfd.Location_Package__c);
        }

        if (OrderPackageIds.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 OrderDiscountsMRFRollupSummary().summarizemrfdiscounts(OrderPackageIds);
        }
    }

    //Public Methods
    public void summarizemrfdiscounts(Set<Id> OrderPackageIds) {
        //Get Order Locations to Update
        List<Order_Location_Package__c> orderpackages = queryOrderPackagesById(OrderPackageIds);

        Map<Id, AggregateResult> results = getmrfdiscountsAmountsByPackageId(OrderPackageIds);

        //Loop Order Locations and set Amounts
        List<Order_Location_Package__c> orderpackagesToUpdate = new List<Order_Location_Package__c>();
        for (Order_Location_Package__c ordpack : orderpackages) {
            double ddis = 0;
            double pdis = 0;

            if (results.containsKey(ordpack.Id)) {
                AggregateResult ar = results.get(ordpack.Id);
                pdis = (double)ar.get('PercentDiscount');
                ddis = (double)ar.get('DollarDiscount');
            }

            //Determine if Amounts have Changed
            if (
                ordpack.Dollar_Discount_MRR__c != ddis || 
                ordpack.Percent_Discount_MRR__c != pdis
                ) 
            {
                
                ordpack.Dollar_Discount_MRR__c = ddis;
                ordpack.Percent_Discount_MRR__c = pdis;
 
                orderpackagesToUpdate.add(ordpack); //Add location to collection to be updated
            }
        }

        if(orderpackagesToUpdate.isEmpty() == false) {
            Database.SaveResult[] saveResults = Database.update(orderpackagesToUpdate, false);
            System.debug(saveResults);
        }
    }
    //Private Methods
    public Map<Id, AggregateResult> getmrfdiscountsAmountsByPackageId(Set<Id> OrderPackageIds) {
        Map<id,AggregateResult> resultsByOrderLocationId= new Map<Id,AggregateResult>();

        //Summarize Discount Amounts by Order Package Id
        AggregateResult[] results = aggregateMRFDiscountAmounts(OrderPackageIds);
        for (AggregateResult result : results) {
            Id orderlocationId = (Id) result.get('OrderPckg');
            resultsByOrderLocationId.put(orderlocationId, result );
        }
        return resultsByOrderLocationId;
    }

    //Query Methods
    private List<Order_Location_Package__c> queryOrderPackagesById(Set<Id> OrderPackageIds) {
        return [SELECT 
                Id,
                Dollar_Discount_MRR__c,
                Percent_Discount_MRR__c

            FROM 
                Order_Location_Package__c
            WHERE 
                Id IN :OrderPackageIds];
    }

    private AggregateResult[] aggregateMRFDiscountAmounts(Set<Id> OrderPackageIds) {
        return [SELECT 
                Location_Package__c OrderPckg,
                SUM(Discount__c) PercentDiscount,
                SUM(Dollar_Discount__c) DollarDiscount

            FROM 
                Discount__c
            WHERE
                Location_Package__c IN :OrderPackageIds AND Fee__c = 'Monthly Recurring Fees'
            GROUP BY 
                Location_Package__c];
    }

}

Hey All,

I'm a bit new to writing apex and test classes, but I'm unsure why I'm getting the compiling error "Variable does not exist: Monthly_Recurring_Fees__c". I'm attempting to pull the "Monthly_Recurring_Fees__c" field from the "queriedOrder" query. Any help is appreciated!

@isTest
private class OrderRollupSummaryTest {

    private static testMethod void doTest() {
    	
    	Account testAcc  = new Account ();          
    			testAcc.Name = 'Test Account';
    			testAcc.Primary_Vertical__c = 'Multifamily Housing';
    			testAcc.Total_Locations_Owned_Managed__c = 1;
    			
    			insert testAcc;


    	Opportunity testOpp  = new Opportunity ();
       			testOpp.Name = 'Test Opportunity';
    			testOpp.AccountId = testAcc.Id;
    			testOpp.Opportunity_Source__c = 'Sales Generated';
    			testOpp.Type = 'New';
    			testOpp.StageName = 'Contract';
    			testOpp.Number_of_locations_for_opportunity__c = 1;
    			testOpp.Amount = 0;
    			testOpp.Implementation__c = 0;
    			testOpp.CloseDate = System.today() + 5;
    			testOpp.Deal_Confidence__c = 100;
    			
    			insert testOpp;

    	Package__c testPackage  = new Package__c ();
    			testPackage.Name = 'Test Package';
    			testPackage.Package_Type__c = 'Website Package';
    			testPackage.Status__c = 'Active';
    			testPackage.One_Time_Price__c = String.ValueOf(200);
    			testPackage.Monthly_Recurring_Price__c = String.ValueOf(100);
    			
    			insert testPackage;


    	Order_Sheet__c testOrder  = new Order_Sheet__c ();
    			testOrder.Opportunity__c = testOpp.id;
    			
    			insert testOrder;


    	Order_New_Location__c testOrderLocation  = new Order_New_Location__c ();
    			testOrderLocation.Order_Sheet__c = testOrder.id;
    			testOrderLocation.Name = 'Test Location';
    			
    			insert testOrderLocation;


    	Order_Location_Package__c testOrderPackage  = new Order_Location_Package__c ();
    			testOrderPackage.Order__c = testOrder.Id;
    			testOrderPackage.New_Location_Name__c = testOrderLocation.Id;
    			testOrderPackage.Package__c = testPackage.Id;
    			
    			insert testOrderPackage;

        Discount__c testMRFDiscount  = new Discount__c ();
                testMRFDiscount.Location_Package__c = testOrderPackage.Id;
                testMRFDiscount.Dollar_Discount__c = 50;
                testMRFDiscount.Fee__c = 'Monthly Recurring Fees';
                
                insert testMRFDiscount;

        Discount__c testOTFDiscount  = new Discount__c ();
                testOTFDiscount.Location_Package__c = testOrderPackage.Id;
                testOTFDiscount.Dollar_Discount__c = 50;
                testOTFDiscount.Fee__c = 'One-Time Fees';
                
                insert testOTFDiscount;


 /* --- OrderRollupSummaryTest Test --- */
		Test.startTest();

		/* --- Run Create Method--- */
    	OrderRollupSummary.rollupAllorderlocations(new List<Order_New_Location__c>{testOrderLocation});
		
		/* --- Query for Order--- */
		list<Order_Sheet__c>queriedOrder = [Select Monthly_Recurring_Fees__c FROM Order_Sheet__c WHERE Id = :testOrder.id];
        System.debug('Price after trigger fired: ' + queriedOrder.Monthly_Recurring_Fees__c);
		
		/* --- Checks to see if amounts updated --- */
        system.assertEquals(50, queriedOrder.Monthly_Recurring_Fees__c);

        Test.stopTest();


    }
}

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];
    }

}
Hello! I'm a bit new at writing Apex but I'm attempting to create an invocablemethod batch apex class to rollup multiple currency fields on an "Order Package" object to its parent object of "Order Location". Everything seems to be working as expected but I need to rollup multiple fields and I'm running into issues. Can someone show me how I might be able to include multiple fields in the rollup? I attempted to simply add another field but right now it looks like it's assigning the same amount to both fields I included. This seems to be because I am assigning the same "results" to both fields but I can't figure out how I can assign the aggregate query to multiple fields. 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.*/
                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];
        }
    
    }

 
Hi All,

i am working on Service Appointment History
i am fetching the record based on service appointment Id, Field is equal to Status, order by created date desc using Get Records.
next calling the loop
for every itteration i am checking a condition
if(loopvariable.NewValue=='InProgress'){
}

when i run this check it gives error 

Error element ttttt (FlowDecision).
Formula result is data type (Object), incompatible with expected data type (Text).

1. GetRecords
Get SAH REcord
2. Loop
Loop
3. Decision
Decision