0

hello i created a trigger who auto submit the approval request into the approval process. when i create opportunity with the entry criteria of the trigger and the procces i get to approval requeset if i try to approve or reject one of them i get this error:

Validation Errors While Saving Record(s)

There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger OpportunitySubmitForOrderListApproval caused an unexpected exception, contact your administrator: OpportunitySubmitForOrderListApproval: execution of AfterUpdate caused by: System.DmlException: Process failed. First exception on row 0; first error: ALREADY_IN_PROCESS, This record is currently in an approval process. A record can be in only one approval process at a time.: []: Trigger.OpportunitySubmitForOrderListApproval: line 10, column 1".

this is the trigger

trigger OpportunitySubmitForOrderListApproval on Opportunity(after update) {
    for (Integer i = 0; i < Trigger.new.size(); i++) {
        if ((Trigger.old[i].Integration_fees__c == 0 && Trigger.old[i].Integration_waived__c == True) && (Trigger.new[i].Integration_fees__c == 0 && Trigger.new[i].Integration_waived__c == True)) {
            // create the new approval request to submit
            Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
            req.setComments('Submitted for approval. Please approve.');
            req.setObjectId(Trigger.new[i].Id);
            // submit the approval request for processing
            Approval.ProcessResult result = Approval.process(req);
            // display if the reqeust was successful
            System.debug('Submitted for approval successfully: ' + result.isSuccess());
        }
    }
}

this is the entry criteria of the proccess.

(Opportunity: Integration fees EQUALS 0) AND (Opportunity: Integration waived EQUALS True).

Thank you very much to the helpers!! i'm getting crazy from this problem.

  • 1. may there is process builder setup for approval process or Approval.ProcessResult result = Approval.process(req); you are submitting this inside for loop – Ratan Paul May 17 '16 at 12:32
  • @Ratan but i need to submitting this inside the if and the if is inside the loop,i take the trigger from blog.jeffdouglas.com/2010/01/04/… i dont know why i get this problems. – DR.P May 17 '16 at 12:49
  • @DR.P There are two possibilities: 1) You have another approval process , or 2) Your trigger is firing twice Please check debug logs you will get the answer , also for approval process it is good to put try catch block – C0DEPirate May 17 '16 at 14:21
  • i solve this problem with the process builder , i create auto submision their and delete the trigger, thank you very much! – DR.P May 17 '16 at 14:30
1

This trigger is not bulkified. You can create a set of records for submission in an initial for loop. That removes any duplicate Ids of records that may already be contained in your trigger. Since that's unlikely, you may need to run a query to see if there's already an approval process going on this record. I responded to the question you asked yesterday and still don't see anything that prevents recursion. So it's likely that you're attempting to create duplicate approval processes on the same records.

Use a 2nd for loop to create your submissions. Be aware that each ProcessSubmitRequest counts as one DML operation. Your execution context can only contain a total of 150 DML operations before you'll exceed governor limits. For that reason, it would be wise to use the limits class to check available DML limits before you proceed.

Compare available DML limits with the number of records that you need to process if you're going to do them individually. That's the only way I've seen this done, but it may be possible to do it using a list or map. I can't say as I've never tried. Otherwise, you'll want to use an @future call to move this to an asynchronous process where you could "chain" them in queuables using loops of no more than 150 records per transaction before calling another queueble to process the remaining records.

For your recursion, you need to first create the following class:

Public class triggerHelper{

  Public static boolean reEntry = false;

}

Now, modify the start of your code as follows:

trigger OpportunitySubmitForOrderListApproval on Opportunity(after update) {
    if(!triggerHelper.reEntry){
        triggerHelper.reEntry = true;

        // now start your for loop
        for (Integer i = 0; i < Trigger.new.size(); i++) {


        } // end of for loop

    } // end if

} // end trigger

The 2nd time your trigger is called in an execution context, the boolean will be true and your trigger won't execute to create an 2nd approval process instance.

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.