+ Start a Discussion
XactiumBenXactiumBen 

Automatic Approval Processing

I am trying to automatically submit a record for approval in a visualforce page but hitting some problems.  I tried following the Apex Approval Processing example (http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_process_example.htm) but I get this error:

Code:
System.DmlException: Process failed. First exception on row 0; first error: NO_APPLICABLE_PROCESS, No applicable approval 
process found.

 
So I thought I needed to create a ProcessInstance but trying to insert this results in:

Code:
System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, 
Required fields are missing: [ProcessDefinitionId, CurrentNodeId]: [ProcessDefinitionId, CurrentNodeId]

 
I have set up an approval process for my custom object and it is active so that doesn't seem to be the problem.  This is a controller extension for my VF page and the 'record' variable is the object that has been passed into the page.  Here is my function that uses the submit for approval :

Code:
public void SubmitApproval()
    {
/* Attempting to set up a ProcessInstance
ProcessInstance approvalProcess = new ProcessInstance(); approvalProcess.TargetObjectId = record.Id; //approvalProcess.ProcessDefinitionId = ; approvalProcess.Status = 'Started'; //approvalProcess.CurrentNodeId = ; //insert approvalProcess;
*/

// Create an approval request
  Approval.ProcessSubmitRequest approvalRequest = new Approval.ProcessSubmitRequest(); approvalRequest.setComments('Testing Approval Submit'); approvalRequest.setObjectId(record.Id); Approval.ProcessResult approvalResult = Approval.process(approvalRequest); if (!approvalResult.isSuccess()) { ApexPages.Message error = new ApexPages.Message(ApexPages.Severity.ERROR, 'There was an error with the Submit For Approval Request.'); ApexPages.addMessage(error); } }

 
Edit:  Just a quick update.  If I submit the record for approval using the normal way I can then create a commandButton that approves the pending request.  This approval doesn't run into any problems at all.  I must be missing something from my Submit request.






Message Edited by XactiumBen on 06-24-2008 03:21 AM

Message Edited by XactiumBen on 06-24-2008 03:50 AM
mtbclimbermtbclimber
The DMLException here should be expected often per the way approvals work.  You can not create an approval process in apex. Approval processes must be established through the UI. If you want to avoid the exception you can create an approval process with a filter that essentially accepts all records if that is your goal.

Check out the online help for creating approval processes, specifically the section named Specify Criteria for Entering Process (must be logged into salesforce.com).
XactiumBenXactiumBen
I've actually fixed this.  Turns out I was missing the Id of the approver (setNextApproverIds field) since I have to specify one for my approval process. 
virtcoudvirtcoud

Given XactiumBen is doing this in a Visual Force custom controllers it sounds like it doable and given the sample it is implied that this is doable from APEX.

 

XactiumBen I know some time has passed since your post, can you share your code that worked?

 

Thanks!

 

 

jarrodmichaeljarrodmichael

Yes, I would be interested in your code as well.  I am trying to accomplish this very thing.

jarrodmichaeljarrodmichael

Hi, would you mind sharing your code on this?  I am trying to do the exact same thing and can't get it figured out.  Thanks!

Kirk F.ax361Kirk F.ax361

XactiumBen, you wrote you've fixed the problem with submitting a record into an approval process.  Could you share your successful code with us?

Kirk F.ax361Kirk F.ax361

A quick hack, while we wait for the apex answer:

 

If you're lucky enough to have your approval process started off by an action a user took in the UI, then you can submit via this:

 

PageReference submitPage = new PageReference (
'/p/process/Submit?id=' + getOpportunity().id +
'&retURL=%2F' + getOpportunity().id ); submitPage.setRedirect(true); return submitPage;

 This redirects the user to the ordinary approval process submit page, passing the given object, and the retURL is the page you want them to see after the submittal.  Here, for example, I'm submitting an opportunity into the approval process, and returning the user to that same opportunity in read mode (so they can see the workflow stage).  They just hear a couple clicks as the redirection happens.  Hacking the URL is not the Right Answer, but may be useful for some cases.

 

NikiVankerkNikiVankerk

Hi there.  Came across this posting that may help those looking for an apex answer.  I haven't tried it yet myself but looks promising.

 

Creating Auto Approval Process Trigger

 

Niki

www.vankerksolutions.com

atidevatidev

Hi,

  I have 6 levels of approval matrix for Oportunity.  The level5 approver wants go do the approval automatically (system should approve on his behalf) and send email to him regarding the details of the opportunity. Is it possible to do?

 

Thanks,

DevNVDevNV

That doesn't really sound like an approval to me, more like a notification of something going through approvals.  Why not add an email alert to that level 5 approver that is sent out when the level 4 Approval is granted, and then continue on with the final approval step?  That way the person doesn't have to actually approve but they are notified at the right time of the Opportunity moving through the process.

 

Niki

Admin1112Admin1112

my approval process works fine but getting error in test coverage, can you please help, below is the code and error.

 

 

@isTest(SeeAllData=true)
private class TestOpportunitySubmitForApproval {

static testMethod void myUnitTest() {
// TO DO: implement unit test
Opportunity opp = new Opportunity ();
opp.StageName = 'Demo Call';
opp.Name = 'Test 1';
opp.CloseDate = Date.today();
opp.Work_Order_Discount_1__c = 10;
insert opp;
opp.Work_Order_Discount_1__c = 25;
opp.Id='006O0000002bhG0';
update opp ;


List<ProcessInstance> ap = [SELECT ID,Status, TargetObjectID
FROM ProcessInstance
WHERE TargetObjectID= :opp.id];
system.debug('processInstance List' + ap);

ProcessInstance processInstance = new ProcessInstance();
processInstance.TargetObjectId = opp.Id;
processInstance.Status = 'Pending';
insert processInstance;

List<ProcessInstanceStep> actor = [SELECT ActorID,ProcessInstanceID
FROM ProcessInstanceStep
WHERE (StepStatus='Approved' OR StepStatus='Rejected') AND ProcessInstanceID in: ap];
system.debug('processInstanceStep List' + actor);

ProcessInstanceStep piStep = new ProcessInstanceStep();
piStep.StepStatus = 'Approved';
piStep.ProcessInstanceID = processInstance.ID;
piStep.ActorId = '00590000000vc59';


}
}

 

------

 

error

 

|FATAL_ERROR|System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [ProcessDefinitionId, CurrentNodeId]: [ProcessDefinitionId, CurrentNodeId]