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 = 'ajkreuer2@mydomain.com'; 

    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

  • 1
    You should use DLRS. Clicks not code. – Adrian Larson Jan 26 '16 at 19:46
  • why are you not using roll up summary ? – Himanshu Jan 26 '16 at 19:49
  • @Himanshu The relationship is M/D? Then yeah even using DLRS is more complicated than the solution demands. – Adrian Larson Jan 26 '16 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. – AJ47 Jan 26 '16 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 Jan 26 '16 at 20:09
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).

  • I am confused..shouldn't the trigger be on order object instead of Account? Thanks! – javanoob Jan 26 '16 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? – AJ47 Jan 26 '16 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 Jan 26 '16 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. – AJ47 Jan 26 '16 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 Jan 26 '16 at 23:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.