Check if a record is in approval process

From Winter16 you can check this using the Approval system class

Pass it the Id of a record you want to check if is locked or not:

Approval.isLocked(recordId);

Make sure you set the class api version to 35.0 or higher!


How I have handled this in the past (leaving out the part where we get a set of the record Ids were are processing stored in recordIds):

set<Id> existingApprovalsSet = new set<Id>();

list<ProcessInstance> existingApprovals = [SELECT Id, TargetObjectId
                                            FROM ProcessInstance 
                                            WHERE TargetObjectId IN :recordIds];

if(existingApprovals.size() != 0){
                for(ProcessInstance e : existingApprovals){
                    existingApprovalsSet.add(e.TargetObjectId);
                }
            }

for(SObject record : recordList){
                    if(!existingApprovalsSet.contains(record.Id)){
                        filteredRecordList.add(record);
                    }
                }

This will give you a list of just the records that do not have an approval process. You can then continue processing them however you would like. What this doesn't give you is whether the record is locked or not, because that can be controlled on the Approval Process. You can adjust the SOQL query on ProcessInstance to account for the status of the Approval Process to try to account for this i.e.:

list<ProcessInstance> existingApprovals = [SELECT Id, TargetObjectId
                                                FROM ProcessInstance 
                                                WHERE TargetObjectId IN :recordIds
                                                AND Status = 'Pending'];

Again, this will depend on how the Approval Process is setup and whether it locks records on Submission, Approval, etc.


An alternative solution is to:

  • add a field update to the initial actions of the approval process that sets a boolean custom field is_locked__c in Case to true
  • and another field update when the case leaves the approval process (final accept/reject/recall action to set is_locked__c to false

Then the controller merely looks at the is_locked__c field to decide if record is locked