22

Once every few months this requirement appears as part of a project. Here is some sample code:

trigger AfterUpdate on Contact (After update) {

    for(Contact newContact: Trigger.new){

        Contact oldContact = Trigger.oldMap.get(newContact.id);

        if (oldContact.mailingStreet <> newContact.mailingStreet) {
            Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();

            req.setComments('Approving an address change.');
            req.setObjectId(newContact.id);
            req.setNextApproverIds(new List<Id>{'005i0000000h5az', '005i0000000hASk'});

            Approval.ProcessResult res = Approval.process(req);
        }
    }
}

This yields the following error message:

Error:Apex trigger AfterUpdate caused an unexpected exception, contact your administrator: AfterUpdate: execution of AfterUpdate caused by: System.DmlException: Process failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, missing required field: []: Trigger.AfterUpdate: line 14, column 1

If you change the list in the setNextApproverIds method parameter to only have a single ID then this error disappears.

This begs the question, can you require multiple approvers through Apex? And if so, how?

For added context, there is only one approval step and the details are:

Approval Step Details

12

Might this statement in the docs for the ProcessRequest class, the parent class for the ProcessSubmitRequest, provide some insight?

If the next step in your approval process is another Apex approval process, you specify exactly one user ID as the next approver.

ProcessRequest class


Update:

One method to do this would be to rearrange the trigger behavior to create a single process request per approver and then use the process method overload which takes a list parameter.

trigger AfterUpdate on Contact (After update) {

    for(Contact newContact: Trigger.new){

        Contact oldContact = Trigger.oldMap.get(newContact.id);

        if (oldContact.mailingStreet <> newContact.mailingStreet) {
            List<Id> approverIds = new List<Id>{'005i0000000h5az', '005i0000000hASk'};
            List<Approval.ProcessSubmitRequest> requests = new List<Approval.ProcessSubmitRequest>();

            for (Id approverId : approverIds) {
                Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();

                req.setComments('Approving an address change.');
                req.setObjectId(newContact.id);
                req.setNextApproverIds(new List<Id>{approverId});

                requests.add(req);
            }

            List<Approval.ProcessResult> results = Approval.process(requests);
        }
    }
}

Would this suffice for your scenario?

  • I don't think so, the code above is all the code I'm using. – Wes Nolte Feb 28 '13 at 17:16
  • Well, if your next step is another apex approval process, the code you are leveraging will inherit this restriction from it's parent class. Even though the ProcessSubmitRequest class doesn't explicitly mention this caveat, the class inheritance and the behavior you're seeing would lead me to believe this is the reason it only works with a single ID. What is your next process step? – Mark Pond Feb 28 '13 at 17:28
  • Updated my post to add more info. Let me know what else you might need. – Wes Nolte Feb 28 '13 at 19:42
  • That'll do the trick :) – Wes Nolte Feb 28 '13 at 20:54
  • 1
    Please note that this solution initiates multiple copies of the approval process. If you send 2 approval requests and the first if approved or rejected, the second will remain pending, and you will not be able to submit to other approval processes. See salesforce.stackexchange.com/questions/50634/… for more details. – Jason Clark Sep 26 '14 at 13:16

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.