Monday, September 9, 2013

Setting Long-Term Workflows in Dynamics CRM

I originally wrote this article for MS Dynamics World who gave me permission to recreate it on my blog.

Setting Long-Term Workflows

Workflows are remarkably useful because they are so powerful as well as being easy to configure. A feature of them which takes a little getting used to are the ‘waiting’ steps. I recently had a problem where a client needed to use the waiting steps well beyond the time limits available in Dynamics CRM.

The Problem

The client in question was a financial management client who classified clients into three categories (let us call them gold, silver and bronze). Based on their category, a major review of their financial situation happens every one, three or five years respectively. The idea was that when the record was created, a review date would be set. A month before this review date the client was contacted and an appointment set up (handled by a different workflow). When the review date passed, the review date was again reset.

The problem is timeouts can only happen up to 24 months out, not three or five years out.

clip_image002

My initial reaction was to tell the client it was not possible. My main contact smiled and she suggested I think it over. Sure enough I found a solution.

The Solution

The solution in the end turned out to be quite simple.

clip_image004

To start at the top, the workflow begins on the creation of the record (Account Category is a mandatory field so we can guarantee it will have a value). It can also be called by another workflow as a child process (I am planning to loop this workflow).

The first step the workflow has is to set the review date to one year in the future.

clip_image006

In this case I have set the Review Date to 12 months after the ‘Execution Time’. The Execution Time is a commonly misunderstood expression and leads to no end of confusion when setting up workflows. The Execution Time is the time the expression is evaluated. In other words it is the time at which this update step updates the Review Date. Given this is the first step in the workflow it is almost exactly the same time as the Accounts Created On value and almost exactly the same time as when the workflow started but if the update step was further down in the workflow with timeouts and the like before it, the execution time would be very different to the start time of the workflow and the Created On time of the Account.

It then checks if the Account is Silver or Bronze and, if so, increases the Review Date by another two years.

clip_image008

This use of the Review Date to set itself is completely valid.

For Bronze Accounts, this is then repeated. The net result is Gold clients will have a 12 months Review date, Silver clients will have a 36 month review date and Bronze clients will have a 60 month review date, as required.

The final step is to wait until the Review Date and then reset it by calling the workflow again.

clip_image010

We now see the reason we used the Execution Time in our first expression rather than the more commonly used, and less confusing, Created On value. The Created On value will still be the same whereas the Execution Time will now be approximately the same as the Review Date, as required.

As a word of warning, generally speaking CRM will fail a looping workflow. However, for longer cycles it will let them happen. I cannot remember the exact time limit for loop detection but it is of the order of minutes and hours, rather than months and years.

Conclusions

This is a nice example which combines a few of the trickier aspects of workflow creation such as timeouts, looping and the Execution Time. One other thing to take note of is often people will shy away from creating long-running workflows fearing they consume resources. My understanding is this is not the case. When a timeout is encountered, the workflow unloads from memory and is only reloaded when the timeout condition is met.

2 comments:

paulnieuwelaar said...

You could also just add multiple timeout's one after the other, eg: 1 timeout for 2 years, then immediately after have another timeout for 1 year.

However I generally avoid timeouts of this duration in case the server or async service restarts anyway.

Bed-Guy said...

Very nice, thank you.