function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Melissa BunchMelissa Bunch 

Apex Trigger to Validate Field During Approval Process

Hello!

I need some help writing an Apex Trigger and I have 0 code knowledge.
I found a very helpful article by Christopher Alun Lewis (http://christopheralunlewis.blogspot.com/2012/09/making-rejection-comments-mandatory-in.html), but because his scenario is a bit different from mine, I'm stuck.

I have a single step approval process on the order object.
The order is created and automatically entered into the approval process.
The approver must then make sure that the OpportunityId field on the Order is populated before approving.

The trigger I am trying to write should say "If OpportunityId is null and Status is changed to Approved, display error and cancel approval process."

Here is what I've edited from Christopher's code so far, but as you can see I have extra stuff in it to find the processinstancesId and check rejectedStatements that I don't  need - I don't know how to make this applicable to me or if what I've already edited is even correct.

SFDC Support doesn't support editing/creating code, so they cannot assist.

Any help would be greatly appreciated!!!


trigger ValidateOpportunity on Order (before update) 
{
  Map<Id, Order> OpportunityId
             = new Map<Id, Order>{};

  for(Order inv: trigger.new)
  {
    /* 
      Get the old object record, and check if the approval status 
      field has been updated to Approved. If so, put it in a map 
      so we only have to use 1 SOQL query to do all checks.
    */
    Order oldInv = System.Trigger.oldMap.get(inv.Id);

    if (oldInv.Status != 'Approved' 
     && inv.Status == 'Approved')
    { 
      OpportunityId.put(inv.Id, inv);  
    }
  }
   
  if (!OpportunityId.isEmpty())  
  {
    // Get the most recent approval process instance for the object.
    // If there are some approvals to be reviewed for approval, then
    // get the most recent process instance for each object.
    List<Id> processInstanceIds = new List<Id>{};
    
    for (Order invs : [SELECT (SELECT ID
                                              FROM ProcessInstances
                                              ORDER BY CreatedDate DESC
                                              LIMIT 1)
                                      FROM Order
                                      WHERE ID IN :rejectedStatements.keySet()])
    {
        processInstanceIds.add(invs.ProcessInstances[0].Id);
    }
      
    // Now that we have the most recent process instances, we can check
    // the most recent process steps for comments.  
    for (ProcessInstance pi : [SELECT TargetObjectId,
                                   (SELECT Id, StepStatus, Comments 
                                    FROM Steps
                                    ORDER BY CreatedDate DESC
                                    LIMIT 1 )
                               FROM ProcessInstance
                               WHERE Id IN :processInstanceIds
                               ORDER BY CreatedDate DESC])   
    {                   
      if ((pi.Steps[0].Comments == null || 
           pi.Steps[0].Comments.trim().length() == 0))
      {
        rejectedStatements.get(pi.TargetObjectId).addError(
          'Operation Cancelled: Please add an Opportunity to the Order before Approving');
      }
    }  
  }
}
AnudeepAnudeep (Salesforce Developers) 
Hi Melissa - Have you tried editing the below code line
 
rejectedStatements.get(pi.TargetObjectId).addError(
          'Operation Cancelled: Please add an Opportunity to the Order before Approving');

to
 
rejectedStatements.get(pi.TargetObjectId).addError(
          'If OpportunityId is null and Status is changed to Approved, display error and cancel approval process.');

The message that Christopher is trying to display is coming from the line specified above so you can replace yours there. If the logic is different the addError should go into a different condition/block of code