Auto Complete Recursive/Waiting Workflows – Microsoft CRM 4
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 have created a custom workflow activity to kill 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 i.e. 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 kill 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 EndWhat 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 EndSo 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}; //WaitingSo 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.
So now is the time to kill the outdated workflow. So here is the code for setting that workflow complete/cancelled.
foreach (BusinessEntity be in bec.BusinessEntities) { Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â asyncoperation async = (asyncoperation)be; Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â async.statecode = new AsyncOperationStateInfo(); Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â async.statecode.Value = AsyncOperationState.Completed; Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â service.Update(async); }You can improve this workflow utility to add lot more functionality to workflow designer.

What a wonderful blog! Please continue this great work I will be sure to check back regularly…
I simply wanted to add a comment here to say thanks for you very nice ideas. Blogs are troublesome to run and time consuming therefore I appreciate when I see well written material. Your time isn’t going to waste with your posts. Thanks so much and carry on You’ll defintely reach your goals! have a great day!
Thank you. Very educational posting.
Many thanks for the information. I liked it. You have a very nice site.
Nice post!
Hi, nice post. I just found this blog, but I will definitely bookmark it. Keep us updated.
good work. Realy helpful
Please don’t take this the wrong way. I think your overall ideas are fine but you might want to put a little more thought into your next posts. I say this becuase it seems like your writing style has gone downhill a bit as opposed to your previous posts. – C.
Outstanding posting. I thank you for posting it. Keep up the fine work.
hello mr. ayaz i’m really interrested in this post
but it’s giving me errors
i wish if i can get the fully typed .cs file so i can test this custom workflow
Thank you
Elie,
hello mr. ayaz i’m really interrested in this post
but it’s giving me errors
i wish if i can get the fully typed .cs file so i can test this custom workflow
Thank you
Elie,
Hi, just discovered this blog but I have to admit that it seems nice. I totally agree with you. Have a nice day, keep up the nice work and I’ll definitely keep checking your blog.
What exactly is the error?
It pretty simple Custom Workflow Activity.
Hey,
for exemple, about this line:
query.ColumnSet = cols;
what do we really mean about ‘cols’ ?
any way
that’s my e-mail elie_fadous@bemea.com
i’ll be very thankful if you can provide me with a sample .cs file
Thank you,
Elie
Declare a variable:
ColumnSet cols = new AllColumns();
this will fetch all columns associated with entity in query expression.
I cannt share the code due to contract restrictions.
Hope this helps,
thank you very much
You have a very nice site! Very informative and fun to read. I will be returning soon to check out what’s new.
I’ve been reading a few posts and really and enjoy your writing. I’m just starting up my own blog and only hope that I can write as well and give the reader so much insight.
i’m using timeout step in workflow. but this workflow keeps hitting the server thus causing perfomance issues. is there a way to limit the number of times this workflow hits the server.can someone help please
Hi,
This is a very nice code but for me it gets stuck at one place and that is retrieving of the asyncoperations. On the retrievemultiple it gives me the error that “Server was unable to process request.”. I am getting the error on the following line:
BusinessEntityCollection retrieved1 = crmService.RetrieveMultiple(query);
Can you please tell me what may be the reason? Following is the part of the code where I am retrieving the asyncoperation:
ConditionExpression c1 = new ConditionExpression();
c1.AttributeName = “name”;
c1.Operator = ConditionOperator.Equal;
c1.Values = new string[] {“DRC ACE”}; //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[] {ctx.PrimaryEntityId}; //Waiting
FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.And;
filter.AddCondition(c1);
filter.AddCondition(c2);
filter.AddCondition(c3);
QueryExpression query = new QueryExpression();
query.EntityName = EntityName.asyncoperation.ToString();
query.ColumnSet = new AllColumns();
query.Criteria = filter;
// Execute the request.
BusinessEntityCollection retrieved1 = crmService.RetrieveMultiple(query);
//Finally kill the workflows.
foreach (BusinessEntity be in retrieved1.BusinessEntities)
{
asyncoperation async = (asyncoperation)be;
async.statecode = new AsyncOperationStateInfo();
async.statecode.Value = AsyncOperationState.Completed;
crmService.Update(async);
}
Hi Amar,
This error is generic. Can you write down the detail message in SOAPException Or use trace to capture the detail error.
Hi Ayaz, its a very nice article,, but im using crm 2011, can you provice more information how to kill outstanding WF in crm 2011, since it doesnt have “BusinessEntityCollection”.
i really appreciate your helps.
Thanks