1

I'm trying to write an apex code to update a custom currency field Order_Grand_Total__c on my Account Records to display the sum of all orders under that particular Account.

Here's my Account Trigger:

trigger SumOrders on Account (after insert, after update) {

List<Order> orderList = [SELECT id, TotalAmount, AccountId FROM ORDER WHERE AccountId IN: Trigger.newMap.keySet()];

    for (Account a : Trigger.new)
    {  
        for (Order o : orderList)
        {
            if (a.id == o.AccountId && orderList.size() > 0)
            {
                a.Order_Grand_Total__c += o.TotalAmount;
            }
        }
    }
}

And my Test class, which is only covering 57% of the code (4/7):

@IsTest
public class SumOrders {

static testmethod void insertAccount() {

    Account a = new Account();

    a.Name = 'AJ Kreuer2';
    a.Last_Name__c = 'Kreuer2';
    a.Email__c = '[email protected]'; 

    insert a;

}

static testmethod void insertOrder() {

Order o = new Order();

    o.AccountId = '0013B000004Llt6';
    o.Order_ID__c = '0001';
    o.Status = 'Draft';
    o.EffectiveDate = Date.Today();


    insert o;
}


}

The end result is the custom field remains blank:

enter image description here

I'm a bit new to Salesforce and Apex coding so not really sure where to go from here, any ideas? Or is there a simpler way of achieving this?

EDIT:

I've also tried adding a Rollup Summary with the following settings:

enter image description here

However, the Real Time calculation doesn't seem to work, I have to manually click calculate to get the field to populate / update the current order amount on Account Records

5
  • 1
    You should use DLRS. Clicks not code.
    – Adrian Larson
    Commented Jan 26, 2016 at 19:46
  • why are you not using roll up summary ?
    – Himanshu
    Commented Jan 26, 2016 at 19:49
  • @Himanshu The relationship is M/D? Then yeah even using DLRS is more complicated than the solution demands.
    – Adrian Larson
    Commented Jan 26, 2016 at 19:51
  • I tried a roll up summary field on the Account but it only allows Opportunities for the Summarized Object, and not the standard Order object.
    – AJK
    Commented Jan 26, 2016 at 19:53
  • note that if an order (and by inference) its line items are ever inserted, updated, deleted, or undeleted, you have to make sure the order's Account has a DML update event occur. Note also that since orders require an account, an after insert trigger on Account is meaningless
    – cropredy
    Commented Jan 26, 2016 at 20:09

1 Answer 1

3

Assuming you didn't want to use a roll up summary (either DLRS as mentioned in the comments, or another method), you should be using an AggregateResult query:

 trigger sumOrders on Account (before update) {
     for(Account record: Trigger.new) {
        record.Order_Grand_Total_Amount__c = null;
     }
     for(AggregateResult result: [SELECT SUM(TotalAmount) Amt, AccountId Id FROM Order WHERE AccountId IN :Trigger.new GROUP BY AccountId]) {
         Trigger.newMap.get((Id)result.get('Id')).Order_Grand_Total_Amount__c = (Decimal)result.get('Amt');
     }
 }

At that point, your unit test simply needs to insert an order. Note that for your summary to work correctly, you'll also need to update the accounts from the order trigger:

trigger rollupOrder on Order (after insert, after update, after delete, after undelete) {
    Set<Id> accountIds = new Set<Id>();
    if(Trigger.old != null) {
        for(Order record: Trigger.old) {
            accountIds.add(record.AccountId);
        }
    }
    if(Trigger.new != null) {
        for(Order record: Trigger.new) {
            accountIds.add(record.AccountId);
        }
    }
    update [SELECT Id FROM Account WHERE Id IN :accountIds)];
}

Appropriate error handling is advised (not included here for brevity).

7
  • I am confused..shouldn't the trigger be on order object instead of Account? Thanks!
    – javanoob
    Commented Jan 26, 2016 at 21:11
  • @sfdcfox thank you! this is just about working perfectly, only thing I can't figure out is after an order gets created, I have to either update the order or account one more time to get it to register the amount, I've made a quick video showing this: screencast.com/t/ZddnSNDY I've tried adding before insert to the sumOrders trigger but same thing, any idea?
    – AJK
    Commented Jan 26, 2016 at 21:23
  • 1
    They need to be exactly as written. Before update on account, after insert, update, delete, and undelete on Order. Start from there and see if that helps.
    – sfdcfox
    Commented Jan 26, 2016 at 21:36
  • @sfdcfox Sounds good, I changed it back to what you have exactly, but still getting same issue as shown in that screencast. After submitting the order, I have to update either the order or account once more to populate the order sum amount.
    – AJK
    Commented Jan 26, 2016 at 21:44
  • @AJ47 Worse case scenario, TotalAmount may not be updating as timely as I thought (but that sounds suspect). How are you updating the value?
    – sfdcfox
    Commented Jan 26, 2016 at 23:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .