[SalesForce] Apex Class + Process Builder to fire assignment rules

We have a couple of actions on the Opportunity that create Cases. In order to trigger case assignment rules, I have a simple apex class that is being called by process builder. I'm very new to apex, and put together the class based on some suggestions from related Salesforce ideas. It works when I test it out in my personal dev org but not the sandbox or production instances where it is actually needed. I suspect something could be off with my process builder or the class, and just need a second pair of eyes on it. I'd appreciate any input.

Class:

  public class CaseAssignment {

    @InvocableMethod
        public static void CaseAssign(List<Id> CaseIds)
        {
                Database.DMLOptions dmo = new Database.DMLOptions();
                dmo.assignmentRuleHeader.useDefaultRule = true;
                Case Cases=[select id from case where case.id in :CaseIds];        
                Cases.setOptions(dmo);
                update Cases;
       } 
}

Test Class (the test passes)

@istest
class CaseAssignment_Test {

   @istest
   static void testCaseAssignment(){

      Case c = New Case ();
      c.Client_Access_End_Date__c = Date.today();
      insert c;
      List<Id> caseids = new List<Id> ();
      caseIds.add(c.id);
      CaseAssignment.CaseAssign(caseIds);
   }
}

Process Builder:
Process Builder - invokes apex class

  • When to start the process: when a record is created or edited
  • criteria: I tried setting it to no criteria, or a formula of "true"
  • immediate actions: setting a text field to check that the process runs. It does. I see the text field on my test case updated.
  • 0 hours after, invoke apex class. No case assignment takes place.

Result:
When a case is created via the custom action, I can see the text field update via process builder. I see the apex step under "paused and waiting interviews" via Setup > flows. I get no error message, but the case does not change ownership.

Other observations:
– when a case record is created via the case layout and the "assign using active assignment rules" field is checked, the case gets re-assigned properly.
– The same case class and process builder criteria is selected in my dev org, and I see the case get re-assigned as expected.

Best Answer

You can't properly schedule an action using either of the options you specified. The "no criteria" option will disable scheduled actions for "on create and update", and the "formula evaluates to true" option requires the "only when the specified changes are made to the record" option, which means that a simple formula like "true" will never trigger the scheduled action.

Options

Synchronous Action

Execute the @InvocableMethod as an immediate action, and have that method call a @future/Queueable method.

Trigger

Simply write a trigger, and call a @future/Queueable method instead. This makes your solution all-code, since you already need code to begin with.


Side Notes

"On create" is probably a better choice if you stick with Process. Otherwise, you end up with an infinite loop, which is the reason why the configuration you've tried shouldn't work. Your trigger should be "after insert", and not "after update" to avoid the problem if you use code. The system is designed to limit the possibility of infinite loops.


Using configuration/code like this may result in multiple notifications/ownership changes, for example, when using Web-to-Case or when cases are manually created. You may want to simply add an additional read-only field with a default value that you can criteria/filter off of in order to prevent unnecessary extra notifications/history tracking/etc.


I'm not sure you even need the assignment rule to be executed asynchronously if you use an InvocableMethod, because any previous assignment rules would have already been decided, so the Apex code here would take precedence. If you moved to a trigger, though, you'd still need to use a @future/Queueable method.


When writing unit tests, be prepared to test the results of your execution. Your unit test doesn't actually test the code, it only provides coverage. That is not the same thing. You should make sure that the owner actually did change (even if you don't know whom it is, it should ideally not be the user running the test).

Related Topic