A very frequent requirement that customers present for their CRM system functionality is that they will get automatic reminders from it when an item recorded into the database requires their attention after a specific date is reached. This might be a hard, physical date like a contract expiring or a softer variable such as a follow-up date on an open opportunity. Since receiving email notifications from various online services is such a ubiquitous pattern for process reminders these days, it’s only natural that the CRM system is expected to behave the same way.
What sounds like a straightforward thing to implement with the help of the Dynamics CRM workflow processes isn’t necessarily such an easy task – at least if you want the reminder workflow to operate correctly under all the possible circumstances. In a scenario where the reminder is set by the user via a value entered into a date field there’s a number of other variables that you should take into consideration besides that single data entry. For a developer who is used to dealing with user inputs and exceptions this may be just another routine task of figuring out the logic surrounding the reminder date variable, but for a functional consultant who typically works more directly with the end users and mainly just points & clicks in the CRM customization menus for building out the required functionality this may not be such familiar territory. I’ll be the first to admit that I struggle with workflow logic a lot.
Given how much time I’ve spent wondering “how should I do this” when it comes to CRM workflows, the wording of this blog post’s title is pretty bold. Is there really a single right way to build reminder workflows and do I know nearly enough about them to claim the privilege of defining the proper design pattern for them? This is actually just more of a provocation through which I’m hoping to gather feedback on the inevitable shortcomings of this post via the comments section. Another reason behind this choice of the title is that I stand on the shoulders of giants when it comes to my knowledge about CRM workflows, meaning everything I know about them I’ve read from blogs elsewhere and I’ll try my best to highlight the articles deserving most attention via linking to them as we move forward.
In this post I’ll use a scenario where the opportunity record has been extended with a custom follow-up date field. Entering a date into the field is done by any user who has access to update the opportunity. When the follow-up date is reached, a reminder should be sent to the owner of the opportunity, but only if the record is still in an open status, since won or lost opportunities don’t require reminders anymore. Sounds logical? Good, then let’s start working on implementing all the required business logic onto the Dynamics CRM workflow editor canvas.
The first thing we need to decide on when designing workflows is defining the criteria on when should we be performing any actions to begin with. In our scenario, any moment a user could enter a value into our reminder date field is a potential trigger for our workflow logic, so we should have the process started both on the create event of the record as well as the change event of the field in question.
Since we’re dealing with an optional field that doesn’t necessarily contain any value, we should check this right away. It’s not enough that there is a value in the field, but it also needs to be something we can act upon. There are two general things that interest us: 1) is the record sill active (meaning does it require any reminders) and 2) is the reminder date in the future. There’s no point in us sending an email to a user right away if he or she mistakenly enters a date that’s passed last month already, so better to just ignore any such input values and do nothing in this case.
Wait conditions and stopping the workflow
If we’ve determined that there is a valid reason for our workflow to take note of the event to which it has been attached to, the next step is to… just wait. No, I didn’t mean you can just start slacking away with your workflow design! Waiting in itself is a topic deserving your full attention as a CRM customizer, since there are more than just one type of waits in the platform we’re working with. Read this great article by Paul Nieuwelaar for an in-depth discussion on the different options available.
There are multiple possible outcomes that should cause our workflow process to wake up. It’s not only the events when a follow-up action should be performed but also any path that leads to a state where the workflow is no longer required. After all, you really don’t want to have an ever increasing number of workflow instances left forever waiting in your CRM system, hogging up resources unnecessarily. So, in our scenario, whenever the status of an opportunity changes to something else than “open” before the reminder date is reached, we’ll want to stop our workflow.
This brings up another best practice regarding Dynamics CRM workflows. We have the option of stopping a workflow with the status values of “Succeeded” or “Cancelled”. As a general rule of thumb, you should always choose to stop your workflow as “Succeeded” unless you have a good reason to do otherwise. This is because a “Cancelled” value is considered an exception in the workflow process job execution and it will leave a permanent record into the system for debugging purposes. If the stopping is just business as usual for your workflow logic, let the system job be deleted by choosing the “Succeeded” option. Only use the “Cancelled” value if you intend to go through and review all the cancelled process instances when testing or debugging your workflows.
Change of date
Since our trigger field is just a normal date field on the opportunity form, we need to take into consideration the fact that a user may at any stage go and update the date value. For example, when the opportunity in question gets delayed due to lack of actions from the customer’s decision makers, the opportunity follow-up reminder would naturally also get postponed to a later date. Whether a reminder has already been sent for the record or not doesn’t actually matter to us, since what we’re dealing with in this scenario is a reusable reminder field that should always work reliably and deliver a notification at the time specified by the user.
Since our start conditions were tied to not just the creation of a new record but also any changes made to the follow-up date field, this will create a new instance of the workflow process whenever the field value is updated. We don’t want to have multiple concurrent waiting workflows for the same record and we most certainly don’t want to send more than one reminder at the follow-up date, so we need a logic to get rid of the old process instance when a new one is created. But how do we tell the existing workflow that a new version has been created? [Read more…]