[SalesForce] Any way to recall arbitrary approval requests from Trigger

Scenario

I have a requirement for an approval process on Opportunity that must go to multiple approvers. Opportunities cannot be owned by queues, so the approval cannot be submitted to a queue. As the documentation states, although Approval.ProcessRequest.setNextApproverIds() takes a list of ids, you can only supply one id. Using the approach outlined in the sample code in this answer, I am submitting one request per potential reviewer (via trigger). This is working.

The second half of the requirement is that once any approver approves or rejects the request, the request should no longer appear on other approvers' home page "Items to approve" list. Unfortunately, using the process outlined above, this isn't the case. If I generate two approval requests and approver A approves the request, the approval actions run, but the request to approver B remains in the 'Pending' state.

The Problem

Since the approval action changes a field on the opportunity, I can use a trigger to take additional action upon approval/rejection. I have tried using Approval.ProcessWorkitemRequest.setAction('Removed') to recall the remaining 'pending' requests. The docs state that only sys admins can use 'Removed', although this answer shows that the submitter can also revoke a request if the approval process is so configured. However, the trigger will be invoked by an approver, who probably will not be a sys admin and will not be the submitter. I have confirmed that placing the code in a without sharing class has no effect; non-admins who approve a request and trigger the revoke logic will get INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY error.

Question(s)

Is there any way to revoke or otherwise cancel the extra approval requests that will work regardless of triggering user?

I tried deleting the ProcessInstanceWorkitem records. This does accomplish the goal of removing the extra requests, however, it does not complete the instance of the approval process – the ProcessInstance remains, and subsequent attempts to submit for other approval processes will fail with 'This record is currently in an approval process'. In fact, once the ProcessInstanceWorkItem is deleted, I can find no way to resolve the approval process. Ideally I would delete the ProcessInstance records, but delete is not supported; of the 5 Process* API objects, only ProcessInstanceWorkitem supports delete. Not sure why, since it breaks the approval instance as mentioned.

Baring a way to revoke/cancel/remove the additional approval requests, is there another way to meet the requirements that I've overlooked? Some way of submitting a single Approval.processSubmitRequest for multiple approvers that I have missed?

Best Answer

You can try method setSubmitterId by Approval.processSubmitRequest. This submitter can recall that ProcessInstance too.

Related Topic