Skip to content
Dynamics 365 Blog

image


Today’s guest blogger is CRM MVP Ayaz Ahmad who is a CRM Solution Architect with more than seven years in software development and managing large projects and technical teams. Ayaz blogs at http://ayazahmad.wordpress.com/.


Microsoft Dynamics CRM provides very powerful workflow designer tools to create workflows for various business scenarios. Waiting workflows are one of them. Very often, it is required to create waiting workflow on dates. So if a date is changed the waiting workflow remains in waiting state and date change executes another waiting workflow. So this aggregation of workflows affects CRM Server performance and application functionality.


Recently I created a custom workflow activity to stop these waiting workflows in a recursive workflow. So I would like to share my experience with all of you.


I am in a condition to create a waiting workflow to reschedule my activity periodically such as in recurring appointments, Auto Reorder (Sales Order), etc. My workflow is fired on Create of activity/Order and on change of Next Due date/Next Order Date. So if the user has changed Next Due Date or Next Order Date, the workflows in waiting remains in waiting and also a new Waiting workflow is fired. My aim is to stop the existing workflow as it is invalid now and start a new waiting workflow with updated information.


My workflow name is Auto Reschedule Activity. Here is the description of my workflow:



Start:


    Wait for Next Due Date == Today


         Reschedule Activity Accordingly


         Recursive Call: Auto Reschedule Activity


End


What i am looking for is:



Start:


     Check if there is an existing workflow with same Workflow ID, Entity ID and in Waiting State.


          Then Kill that workflow.


     Wait for Next Due Date == Today


          Reschedule Activity Accordingly


          Recursive Call: Auto Reschedule Activity


End


So I started with a custom Activity to fetch workflows in waiting state with same name and regardingobjectid:


I created a query object in my custom workflow activity:



QueryExpression query = new QueryExpression();


query.EntityName = “asyncoperation”; 


query.ColumnSet = cols;


And created 3 conditions as below:



ConditionExpression c1 = new ConditionExpression();


c1.AttributeName = “name”;


c1.Operator = ConditionOperator.Equal;


c1.Values = new Object[] {‘My workflow Name’}; //Workflow


ConditionExpression c2 = new ConditionExpression();


C2.AttributeName = “statecode”;


C2.Operator = ConditionOperator.Equal;


C2.Values = new Object[] {1}; //Waiting


ConditionExpression c3 = new ConditionExpression();


C3.AttributeName = “regadingobjectid”;


C3.Operator = ConditionOperator.Equal;


C3.Values = new Object[] {context. PrimaryEntityId}; //Waiting


Now I have all the waiting workflows regarding my activity. Ideally there will be only one workflow in waiting state all the time. This workflow will be responsible for rescheduling.


Now is the time to kill the outdated workflow. Use code like this for setting that workflow to complete/cancelled.



foreach (BusinessEntity be in bec.BusinessEntities)


{


asyncoperation async = (asyncoperation)be;


async.statecode = new AsyncOperationStateInfo();


async.statecode.Value = AsyncOperationState.Completed;


service.Update(async);


}


Note that you can improve this workflow utility to add lot more functionality to the workflow designer. Workflow is also described in the Microsoft Dynamics CRM SDK.


Cheers,


Ayaz Ahmad






We're always looking for feedback and would like to hear from you. Please head to the Dynamics 365 Community to start a discussion, ask questions, and tell us what you think!