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
lkplkp 

Order of Execution Triggers and Workflow

Hi I have a trigger that requires a Contact Role to be provided for each Opportunity (the code is below).  On the Opportunity I also have workflows that are field updates to the record for timestamps when the Opportunity Stage gets changed.  The issue I am having is the since the Order of Execution has workflow's go first, the trigger is firing off on Opportunity creation.  Since the Contact Roles is on a related list, you can not add a Contact Role until after first edit after save.  With this, I can not save any Opportunity since the trigger has already fired off.  I'm not sure if there is a work around to fire off the trigger after save so I don't affect the field update workflows.

Here is the code:

trigger Opportunity_Contact_Required on Opportunity (before update, after update) {
    Set<Id> allOpptyIds = new Set<Id>();
    Set<Id> OpptyswithContactsIds = new Set<Id>();

     // fetch all the Opportunity Id's in SFDC and throw in list
     for(Opportunity opp : trigger.new)
     {
              allOpptyIds.add(opp.Id);   
     }
    

     // fetch Opportunity Id's that have a Primary Contact associated and throw in list
     for(OpportunityContactRole co : [Select OpportunityId, IsPrimary From OpportunityContactRole Where OpportunityId IN : allOpptyIds ])
     {
         if((co.IsPrimary == True))
         {
               OpptyswithContactsIds.add(co.OpportunityId);             
         }
         
     }

     // compare the two sets (one has all Opportunity Id's and other has just Opportunity Id's with a Primary Contact)
     // Left out Opportunity should not be allowed to be edited until a Primary Contact is associated with the Opportunity, so we throw an error.
     for(Opportunity o : trigger.new)
     {
           if(allOpptyIds.contains(o.Id) && !OpptyswithContactsIds.contains(o.Id))
                o.addError('At least one Primary Contact Role is required on the Opportunity.');
     }
}
ShashankShashank (Salesforce Developers) 
You can try adding a custom checkbox field:

1.) Create a custom checkbox field.
2.) Fire the trigger only if this checkbox is checked.
3.) Update the checkbox in a workflow field update so that the trigger fires only after the workflow in an after update operation which happens again due to the workflow field update.