Recursive Workflows in Dynamics CRM


Share on LinkedIn

Dynamics CRM workflows can wait, but they can’t loop. Here’s how I think about Wait conditions:

  • A workflow can wait for something to happen. For example, a business process might wait until a record’s status changes, or until it gets reassigned. In cases like these, a workflow with a Wait condition will just sit there … waiting (its System Job’s status reason value will be equal to “Waiting”, in case you want to do an Advanced Find to verify)…until the status changes or the record gets reassigned.
  • A workflow can also wait for time to pass. There’s a special “Timeout” function you can access through Local Values in the Specify Workflow Conditions dialog you can use for these kinds of wait conditions. This is useful for processes that wait for a certain time after a record is created. For example, a lead might need to be followed up on, or a service level agreement might require a case to be resolved within a certain period of time.

But what if you had a staged sales process and in certain scenarios you need to go back to a previous stage in the process? Or what if a lead record needs to be reassigned to successive people or queues if it’s neglected for too long? Or what if a case needs to be escalated if it’s not resolved according to a service level agreement?

These are all scenarios where a looping process can help, and while there’s no built-in functionality for looping, you can get the same result by having a workflow call itself recursively. 

Recursive Workflow Mechanics

I like to start out with a simple example that has absolutely no business value, but is the simplest way to see how recursive workflows work. Consider the following workflow:


Figure 1

The only thing this one does is call itself with the Start child workflow action. (Remember that As a child workflow needs to be checked in for a workflow to be “callable” like this.) Notice that this little pedagogic workflow is only available to run On demand, also. After publishing the workflow and selecting a lead record to run it on, here’s what you’ll see on the lead record:


Figure 2

It runs successfully six times, then fails on the seventh. This is the built-in “infinite-loop” protection and it’s a good thing it’s there! Suppose I make two small additions to the workflow:


Figure 3

The Update action does a single thing: it uses the “Increment by” operator to add a “1″ to a numeric field on the lead record. (I use the “Employee count” field for demo purposes; in anything other than an illustrative workflow like this one, I’d generally add a custom integer attribute called something like “Counter” to keep track of how many times the workflow has called itself.) 

Then I added a Wait/Timeout condition to force a 2-hour wait between recursions.

To test a workflow like this one you have to be a little more patient, so I’ll come back and take a look tomorrow and see how it worked….

…zzzzzzzzzz….[sound of alarm ringing] Wake up!…yawn, stretch, rub eyes…

OK, I’m back, let’s see how that workflow did. This time, if I open the lead record and click the Workflows button I see a different result:


Figure 4

Notice that the Infinite Loop detector didn’t Fail the workflow this time. The two-hour wait I put in there gets around that, since you really might have a business process that requires a workflow to call itself like this more than six times! 

Besides the longer timeout period, the only difference between this workflow and the first version is the Update action you can see in Figure 3. Next, I’ll show you an (actually) useful variation on this theme, and how you can increment a counter field within the Update action. This can be important, since it introduces persistence across different instances of the same workflow, giving each instance information it would not otherwise have…like how many times a case has been escalated. 

Now, a Recursive Workflow that Does Something!

A common scenario requiring an escalation process is for service cases. Suppose you’ve got an SLA requiring case resolution within a certain period of time of when the case record is created. Dynamics CRM case records can be “assigned” to queues, so I’ll show an example using three queues: “Standard Service”, “Escalation Level 1″, and “Escalation Level 2″:


Figure 5

For simplicity, let’s assume that when a new case is created it gets routed to the Standard Service queue. Then if it’s not resolved according to the SLA requirements, it “escalates” to the Escalation Level 1 queue. Then if it still doesn’t get resolved it ends up in the Escalation Level 2 (!) queue, alarms go off, heads roll, senior engineers get involved…[fill in your business-specific case escalation scenario here].

Figures 6-8 show a workflow that implements this process, starting with the Workflow Properties section:

Figure 6

Figure 6

  The workflow itself is dvidided into two main sections. The first is a conditional block that starts by checking the status of the case record, and if it’s still active, uses the “counter” attribute to route the case to the appropriate queue:


Figure 7

Figure 7

Next, the “Wait, then escalate” section will look a little familiar:

Figure 8

Figure 8

First, notice the one-minute timeout. I generally use that when I’m testing a workflow like this to get some quick feedback. Just remember to thoroughly test one of these recursive workflows, you will need to test with whatever the real timeout value’s going to be.  

Finally, here’s what the Update action looks like if I click the Set Properties button in Figure 8:

Figure 9

Figure 9

For this workflow, the important part is the “Escalation Counter” field, which gets incremented by “1″ every time the workflow runs. If you haven’t done this before, it takes a little getting used to setting one of these, but if you follow these steps you can get it to work every time:

  1. Click inside the counter field. (It needs to be a numeric field for this to work correctly.)
  2. In the Dynamic Values section, select Increment by from the drop down Operator list.
  3. Then type “1″ in the Default value field, and click OK.

Notice I customized the case form by adding a “Troubleshooting information” section and placing my Escalation Counter field there (along with a couple others I’ll describe in a minute). Obviously this is not information you want the CSRs seeing or updating! Before moving this workflow to production you’d want to remove those from the user form; in the workflow design environment they’ll still be accessible on the Additional Fields tab. 

The only customization to the case entity required to make this work is the Escalation Counter attribute. I mentioned this before but it bears repeating: this is what provides the workflow the information it needs to route the case to the appropriate queue (Figure 7).  I think of this as introducing some “persistence” across workflows: without something like this, one instance of a workflow doesn’t know anything about another one. Ben Vollmer’s ”Round-Robin” lead assignment trick is another of my favorite examples of the general technique. Once you start thinking about it, it’s easy to come up with other examples:

  • Leads might be assigned, and if not qualified within a certain time, reassigned to another user. After a specified time or a certain number of reassignments, you could use a “Dead Leads” queue to flag leads before disqalifying them.
  • Or what if you wanted to treat a case differently if it had already been resolved and then got reactivated? An automatic workflow might run on “Status change” and need to take appropriate action if the previous status value was “Resolved”. Out of the box, the workflow instance won’t know anything about what the previous status value was, so you could use something like the techniques described here to give it something to go on.

A related point is the lack of any history information for Dynamics CRM records. There are plenty of examples of how to build “audit trails” to track how records change over time, and there’s even an accelerator on Codeplex for it. Baseline duplicate checking got added in the 4.0 release; who knows, maybe we can look forward to some audit functionality in 5.0?

In the meantime, we have what we have, and you can use approaches like the one I described here to build looping functionality into your workflows. Here’s a video illustrating the case escalation workflow. It’s an excerpt from my one-day live online class, “Building Workflows in Dynamics CRM”, and if you like the recording, you will love it live!

Republished with author's permission from original post.

Richard Knudson
Richard Knudson is a Dynamics CRM consultant and instructor, and has a special interest in cloud computing and helping organizations realize the potential of social CRM. His company, IMG, specializes in helping businesses implement and customize the Dynamics CRM platform.


Please use comments to add value to the discussion. Maximum one link to an educational blog post or article. We will NOT PUBLISH brief comments like "good post," comments that mainly promote links, or comments with links to companies, products, or services.

Please enter your comment!
Please enter your name here