I need to know what is the criteria and how to find that particular Opportunity object is in approval process? I presume that some of Opportunity fields is changed. Which is that field and how can I find the value of the field before and after the submit for approval button is pressed.


If you do the bare minimum in setting up an Approval Process, the only thing that submitting a record to that Approval Process will do is lock your record.

In other words, there are no fields on your Opportunity that will be changed, by default, when that Opportunity is submitted for approval.

If you want to check to see if an Opportunity is currently in an approval process, there are a few methods you can use:

Simple, with Clicks, not code:

The simplest way out of this issue is to create an initial submission action to perform a field update on the record that's being submitted.

You'll be able to choose almost any field that you want, though a standard or custom Status field seems to be the most popular choice.

The only other thing that you might have to worry about is to make sure that you also set up a recall, final approval, and final rejection actions to update your chosen field so you know when your record is no longer in the approval process.

Least reliable:

You can simply call System.Approval.isLocked(<opportunityId here>).

Approval processes will lock records, so if your Opportunity is in approval, the result of this call will be true.

However, since Winter '16, we have had the ability to lock and unlock records via Apex. This means that this check is not infallible.

More reliable:

You can query the ProcessInstance object to see if any process instance contains your Opportunity in its targetObjectId field.

To make use of the result, it's probably best to use a SOQL for loop to iterate over the query results and build a set that contains the resulting targetObjectId.

A brief example

Set<Id> oppIds = trigger.newMap.keySet();
Set<Id> oppIdsInApproval = new Set<Id>();

for(ProcessInstance instance :[SELECT Id, targetObjectId FROM ProcessInstance WHERE targetObjectId IN :oppIds AND completedDate = null]){

for(Opportunity opp :trigger.new){
        // In this block, we know that the current Opportunity is in an Approval Process
    } else {
        // In this 'else' block, we know that the current Opportunity is /not/
        //   in an Approval Process

Now, that query that I used in my example doesn't limit itself to any single approval process. If your record is in any approval process, it'll be captured by that query.

If you want to limit things to a specific approval process, just use the following query instead

[SELECT Id, targetObjectId FROM ProcessInstance WHERE targetObjectId IN :oppIds AND ProcessDefinitionId IN (SELECT Id FROM ProcessDefinition WHERE DeveloperName = '<process_name_here>')]

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.