[SalesForce] issue with final approval / rejection action with unanimous approval through apex

Scenario

  • custom object X that needs several approvals
  • custom object where the approval routings are defined. (so to which approvers does the system need to send the object depending on a stage of the custom object X)
  • several actual approval processes where for each of them, the approvers are set to "manually selected". Each of these approvals also have specific "final approval" and "final rejection" actions
  • each approval process should work in a unanimous approval way, meaning that it's either all approvers that approve or that approval should be rejected

What is OK so far

Since I need to get the approval entities dynamically from my approval routing object, I needed to work with apex to submit the approvals.
I quickly noticed that the setNextApproverIds didn't except just multiple user ID's but only one… I still find this über-strange but OK…
I found this post which sort of does the trick, at least part of it.

Apex approval process that requires unanimous approval from multiple approvers

The problem

The problem however with this is that working this way, the "final approval" and "final rejection" action would fire immediately as soon as only 1 of the approvers would take action. This because instead of having 1 approval instance with multiple approvers, you just have 1 approval instance per approver…

The question

  1. Is there really no way through apex to do a unanimous approval exactly like it would work through the usual approval processes?
  2. If the answer to 1 is no, how to correctly handle these final approval / rejection actions? This, also knowing that we can have multiple approval processes on the same record.

Best Answer

We came across this situation recently and this is how we solved it..

  1. Set the approvers in the process using "Related User" fields. If you leave it as "Manually selected" then you won't be able to submit to multiple approvers from Apex because the method setNextApproverIds() accepts only one ID (as you already know). By using "Related User" fields, you're eliminating the need to call setNextApproverIds() method.

  2. In your code, populate the related users (approvers) on the object before you submit for approval. This implies that you define approver fields (lookups to User) on the object.

This way you have only one approval instance with multiple approvers and your unanimous setting in the process definition will work as expected and so do your final approval/rejection actions. Basically, you're defining everything in the approval process itself (which is how it should be) and in Apex you're just populating user fields and submitting for approval.

Now, one restriction you'll run into- you will need to populate all the approvers (related users) you defined in the approval process. For example, if you defined 3 approvers in the process then you must populate all 3 approvers. If a particular record needs only 1 approver as opposed to 3 defined in the process then it will fail. A workaround for that is to set the same approver for all three!