function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Semira@gmail.comSemira@gmail.com 

how to fectch the actual approver ID from Approval history

Hi I have written a trigger to update a field "Approved By" on a custom object. However, due to record locked by Approval process, the trigger had to be before trigger. Is there a way I can fetch the ID of the user who actually approved the process? 

processinstance[0].WorkItems[0].ActorId will return the first or the last userid depending on the index. I cannot figure out how to fetch who is actual approver. 

Also ActorID only returns an ID of a queue if the process assigns it to a queue. Not the userID. How can I get the the user ID.. PLEASEE PLEASEEE HELP!! 

I need to release this code within 2-3 days so I'm in dier need of help right now!
Best Answer chosen by Semira@gmail.com
Semira@gmail.comSemira@gmail.com
Hi Swati, 

Thank you for your help. It's actually not WorkItem. It is StepsandWorkItems which is processInstanceHistory that I was trying to access. 

What I needed to do is set a if statement to check is the StepStatus was approved and then go throuhg the list of StepandWorkItems. It was tough to figure it out since it's the first time. But debug statement and logs really helped me out. 

When I queried the stepsandworkitems, it was returning all the ActorID. In this case, it could be anyone in the list. But once I checked the one with approved status, it only returns id of that user. That is exactly what I needed. It works for all the use cases now. 

Thank you, though.

All Answers

Swati GSwati G
Hi,

Have you tried querying ProcessInstanceWorkItem. This object is related to processInstance, so use process instance id to filter the record.

http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_objects_processinstanceworkitem.htm

Swati GSwati G
Hi,

You can use below query and filter the approval using target object id.

SELECT Id,TargetObjectid, Status,(select id,actor.name from Workitems),(SELECT Id, StepStatus, Comments,Actor.Name FROM Steps) FROM ProcessInstance where TargetObjectId = '5009000000Kjecr'

In this query, you can access actual approver from step's ActorId field.
Semira@gmail.comSemira@gmail.com
Hi Swati, 

Thank you for your help. It's actually not WorkItem. It is StepsandWorkItems which is processInstanceHistory that I was trying to access. 

What I needed to do is set a if statement to check is the StepStatus was approved and then go throuhg the list of StepandWorkItems. It was tough to figure it out since it's the first time. But debug statement and logs really helped me out. 

When I queried the stepsandworkitems, it was returning all the ActorID. In this case, it could be anyone in the list. But once I checked the one with approved status, it only returns id of that user. That is exactly what I needed. It works for all the use cases now. 

Thank you, though.
This was selected as the best answer
Swati GSwati G
Yes, thats correct. ProcessInstaceWorkItem represents a user's pending approval request and ProcessInstanceHistory shows all steps and pending approval requests associated with an approval process
Ayush UjjainAyush Ujjain
Hi Semira,
Can you please provide me the query.I am facing same problem but none of my queries giving exact result.Any help would be highly appreciated.

Regards,
Ayush
Semira@gmail.comSemira@gmail.com
Hi Aush, 

I since then updated my code. This is how I did it with a help of index. 

 
//Retrieve the ID of the expense
//retrieve all the approvalInstance where expense.id matches.
//then below steps

Id approverId;
            Integer index;
            Map<Id,Id> expApproverIdMap = new Map<Id,Id>();

            if( !expenseApprInstance.isEmpty() ){
                for(Expense__c exp: [SELECT Id,Status__c,Approved_By__c 
                                     FROM Expense__c 
                                     WHERE Id IN :expenseApprInstance.keySet()]){  
                    index = expenseApprInstance.get(expense.Id).Steps.size()-1;
                    while(index >= 0)
                    {
                        if(expenseApprInstance.get(expense.Id).Steps[index].StepStatus == 'Approved')
                        {
                            approverId = expenseApprInstance.get(expence.Id).Steps[index].ActorId;
                            expApproverIdMap.put(expense.Id, approverId);
                            break;
                        }
                        index--;
                    }
                }


 
Sagar BhatiaSagar Bhatia
Hi All,

Can anyone answer my query : https://developer.salesforce.com/forums/?id=9060G0000005W54QAE

Thanks