1

There is a need for a custom approval process at my company and I'm stuck on how to create this trigger.

I have a parent object called Bids with a child object related called Approvals. I want to update the status field (status_c) on the Bids object, when ALL of the Approvals that have a type of "Bid" change their status to "Foward", and change the Bid.Status_c to another value when ALL of the Approvals of a different type have a status of "Forward"

How would I do this with a trigger. I'm very new to Apex development but welcome any help.

I created this trigger but instead of updating the parent (Bid) when ALL of the child records (Approvals) have been updated based on certain criteria, it updates the parent every time ANY of the child records has been updated based on the criteria.

trigger ConcatenateFields on Approval__c(after insert,after update){    
  List<Bid__c> parentObjList = new List<Bid__c>();    
  public List<Id> listIds = new List<Id>();

  for(Approval__c childObj : Trigger.new){    
    listIds.add(childObj.Bid__c);    
  }

  parentObjList = [SELECT id,Name,(SELECT ID, status__c, type__c 
                   FROM Approvals__r) 
                   FROM Bid__c 
                   WHERE ID IN :listIds];

  for (Bid__c bid : parentObjList){
    for(Approval__c bsaa: bid.Approvals__r) {
      if(bsaa.Status__c =='Forward' && bsaa.type__c == 'Contract') {
        bid.Status__c='Approved';
      }
      if(bsaa.Status__c =='Forward' && bsaa.type__c == 'RFQ') {
        bid.Status__c='Approved';
      }
    }
  }

  update parentObjList;
}
1
  • 1
    Write trigger with after insert and after update events on Approvals, if the status of the approval changes, fetch all the approvals related to parent(bid), check status of approvals changes to Forward, if then update bid record.
    – Venkatesh
    Commented Aug 10, 2013 at 7:25

2 Answers 2

1

Like Venkatesh comments; in your trigger you should check if every child has the value you need.

trigger ConcatenateFields on Approval__c(after insert,after update){
    List<Bid__c> parentObjList = new List<Bid__c>();
    List<Id> listIds = new List<Id>();

    for(Approval__c childObj : Trigger.new){
        listIds.add(childObj.Bid__c);
    }

    parentObjList = [SELECT id, Name,(SELECT ID, status__c, type__c FROM Approvals__r)
                        FROM Bid__c
                        WHERE ID IN :listIds];

    for (Bid__c bid : parentObjList){
        Boolean setToApproved = true;
        for(Approval__c bsaa : bid.Approvals__r) {
            //if an approval is encountered for which the condition doesn't
            //hold, set the boolean to false, indicating no update is required
            if(!(bsaa.Status__c == 'Forward' && bsaa.type__c == 'Contract')) {
                setToApproved = false;
                break;
            }
            if(!(bsaa.Status__c == 'Forward' && bsaa.type__c == 'RFQ')) {
                setToApproved = false;
                break;
            }
       }

       if(setToApproved){
            bid.Status__c = 'Approved';
       }
    }
    update parentObjList;
}

You could, and probably should further enhance this to make sure that every Bid__c is only processed once. You can do that by using a Set of Id's instead of a list.

0

There could be another approach to this in a declarative only way.

If you have a master detail relationship between the two objects, you can use roll up summary fields with filters.

One called "Approved Approvals" one called "Forwarded Approvals", etc.

Then you create a process or a workflow rule, which updates the Status, whenever two of the values are 0 and one is not 0.

For example:

Approved Approvals = 3
Forwarded Approvals = 0
Untouched Approvals = 0

So the Status__c = 'Approved';

I would use the process builder for this, as you would need several workflow rules for this, but just one process.

Edit: Just noticed this question is two years old... Duh

You must log in to answer this question.

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