4

Need a little help with a trigger. It’s my first, so I’m probably missing something straightforward.

Trying to update a field on Account when a field is updated on a related (master-detail) custom object. I don’t think I can use a Cross-Object workflow here because the field update is part of an Approval Process - so I’m going with a trigger.

When Approval_Stage__c = ‘Approved’ on the custom object I would like corresponding field on Account to read ‘Approved’. If Approval_Stage__c is anything else, the corresponding field on Account should be ‘Not Approved’ (or simply mirror whatever Approval_Stage__c is on the custom object- Pending Approval, Rejected, Submitted for Approval etc.)

The code below only works when Approval_Stage__c == 'Approved' as per the "if" statement - which is expected. I can't however seem to get anything to work when Approval_Stage__c is not equal to "Approved".

Any help would be greatly appreciated.

trigger DealApprovalStatusUpdate on Deal_Approval__c (after Update) {
    //creates a list of all deal approvals that are updated with the associated accountID
    List<ID> approvedAcctIds = new List<ID>();

    for(Deal_Approval__c dealApproval : Trigger.new){
    if (dealApproval.Approval_Stage__c == 'Approved')
    {
       approvedAcctIds.Add(dealapproval.account__r.id);
       } 
 }

    // duplicate the list above and below to hold all non-approved deals ?

   List <Account> approvedAccts = [Select Name, Deal_Approval_Status__c From Account WHERE ID IN: approvedAcctIds];
    for(integer i =0; i < approvedAccts.size(); i++)
    {
        approvedAccts[i].Deal_Approval_Status__c = 'Approved';
     }

    update approvedAccts;
}
  • What dotMiko has mentioned, should work but would like to say : if custom object is having master detail relationship with Account- why didn't you use Cross object Workflow field updates. Here I'm not seeing any complex logic which warrants use of Trigger. – curious_techy Jun 10 '15 at 13:40
3

It's not very clear from the other answers to your question but the reason your code is not working is because dealapproval.account__r.id is null. Your SOQL query on Account is not returning any records because of this. You should be doing the following to get the Account Id:

approvedAcctIds.Add(dealapproval.Account__c);

Related objects are not populated in triggers. For example: dealApproval.Approval_Stage__c works but if you reference account fields such as dealapproval.account__r.id they will be null or return a NullPointerException.

Alternative Logic:

If you know the Id of the Account you want to update then you don't need to do a query. You can use the pattern below to directly update the Account without the need for the SOQL statement.

The code below will keep the Account.Deal_Approval_Status__c field insync with the Deal_Approval__c.Approval_Stage__c

trigger DealApprovalStatusUpdate on Deal_Approval__c (after Update) {

    List<Account> accountsToUpdate = new List<Account>();

    for (Deal_Approval__c dealApproval : Trigger.new) {
        Account a = new Account(
                        Id = dealApproval.Account__c,
                        Deal_Approval_Status__c = dealApproval.Approval_Stage__c
                        );
         accountsToUpdate.add(a);
    }
    if (accountsToUpdate.size() > 0) {
        update accountsToUpdate;
    }
}

Or if you wanted the value on Account to be 'Approved' or 'Not Approved' then you can replace this line:

Deal_Approval_Status__c = dealApproval.Approval_Stage__c

with this:

Deal_Approval_Status__c = 
    dealApproval.Approval_Stage__c == 'Approved' 
    ? 'Approved' : 'Not Approved'
  • 1
    This worked great. Thanks for the explanation. I wasn't thinking you wanted to use Account a = new Account ( ) - for some reason I thought that only applied if you were inserting a 'new' account...... I tried a few variations on the code in my question and did see a null pointer exception, so really appreciate the insight as to why. – jshea Jun 11 '15 at 13:36
1

You can use Process Builder to do this:

Have your Process Builder set on your Child Custom Object. You'll want two different criterias in your Process Builder that fire off your updates.

1) if child object approved = yes, send off record update to account with update to the corresponding status - approved

2) if child object <> approved, send off a record update to account with update to the corresponding status - not approved

Shouldnt need a trigger!

0

you can Use Maps to have easily the matching between accountId and the approvalStatus.

so your code could be something like this:

trigger DealApprovalStatusUpdate on Deal_Approval__c (after Update) {

    Map<Id,String> approvalStatusByAcctIds = new Map<Id,String>();

    for(Deal_Approval__c dealApproval : Trigger.new){
        approvalStatusByAcctIds.put(dealapproval.account__c,dealApproval.Approval_Stage__c);
    }

    // Update accounts
    List <Account> accounts = [Select Name, Deal_Approval_Status__c From Account WHERE ID IN: approvalStatusByAcctIds.keySet()];
    for(integer i =0; i < accounts.size(); i++)
    {
        accounts[i].Deal_Approval_Status__c = approvalStatusByAcctIds.get(accounts[i].Id);
    }

    update accounts;
}
-1

you can simply use this:

    if (dealApproval.Approval_Stage__c == 'Approved')
    {
       dealapproval.Deal_Approval_status__c = 'Approved';
    }
    else
    {
       dealapproval.Deal_Approval_status__c = 'Not Approved';
    }

then update all your dealApprovals accordingly

  • Deal_Approval_status__c is a field on Account not Deal_Approval__c – BarCotter Jun 10 '15 at 14:46

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.