+ Start a Discussion
larrmill59larrmill59 

Submitting an approval request via a trigger

We want to be able to create a new custom record where the user fills out some info and clicks Save. At that point a trigger fires to populate another field on the record and it also submits the record into the approval process. Question is, can I append the code to submit the approval request into an existing trigger like I'm trying to do here, or do I write the trigger around the approval request and fill in the one field I need as part of that submission?

 

Right now it's telling me the following:

 

Error: Compile Error: Variable does not exist: a.id at line 12 column 18

 

The trigger code is below:

 

trigger RME_Approval on RME__c (after insert) {

  for(RME__c a: trigger.new){
  for  (Account Acct : [select id,owner.FirstName,owner.LastName from account where id = :a.account__c])
           {
   a.Account_Executive__c = Acct.owner.FirstName + ' ' + Acct.owner.LastName;
  update a;
          }
     }
     Approval.ProcessSubmitRequest req1 = new Approval.ProcessSubmitRequest();
req1.setComments('Submitting RME request for approval');
req1.setObjectId(a.id);
Approval.ProcessResult result = Approval.process(req1);
     }

 

Thanks

Larry

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

a is the variable declared in the for loop that iterates the trigger.new list.  Once the for loop is closed, this variable goes out of scope.

 

Your reference to a.id is outside the for loop, and thus a doesn't exist.

All Answers

bob_buzzardbob_buzzard

a is the variable declared in the for loop that iterates the trigger.new list.  Once the for loop is closed, this variable goes out of scope.

 

Your reference to a.id is outside the for loop, and thus a doesn't exist.

This was selected as the best answer
larrmill59larrmill59

Bob:

 

That worked as far as that variable is concerned and it compiled correctly. However when I tried to create a new record, it failed to update the record because the record is read-only due to being locked by the approval process. So now I have to figure out how to update the field on the record prior to the approval process.

 

Thanks

mtbclimbermtbclimber

And looking ahead you'll want to pull that query and the DML operation out of your loop otherwise when your trigger sees 21 records you'll hit a governor limit.

 

In addition to that you're better off not actually updating the same object directly in an after trigger if you can avoid it which I believe you can by splitting this logic into separate buckets for before and after insert events.

 

I took a stab at conforming this using the contact object instead of your custom one that sits under account so where you see Contact you should replace with RME__c:

 

 

trigger ApprovalSample on Contact (before insert, after insert) {
    /* Modify the new object here */
    if(Trigger.isBefore) {
        Set<Id> accountIDs = new Set<Id>();
	for(Contact c:Trigger.new) {
            if(c.accountId != null) {
                accountIDs.add(c.accountId);
            }
        }

        List<Account> accountList = new List<Account>([SELECT Owner.Firstname, Owner.LastName FROM Account WHERE id IN :accountIDs]);
        for(Account a:accountList) {
            //set your field values here.
        }

        Database.update(accountList);

    /* Perform the approval submit in the after */
    } else {

        List<Approval.ProcessRequest> requests = new List<Approval.ProcessRequest>();

        for(Contact c:Trigger.new) {

            Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
            req.setComments('The comment');
            req.setObjectId(c.id);
            requests.add(req);
        }

        Approval.process(requests);
    }

}