Monday, December 25, 2017

Cancel Workflow using JavaScript and Web API in Microsoft Dynamic CRM

It was just another casual task, when business scenario got me into cancelling a specific waiting workflow in Microsoft Dynamic CRM for some specific entity.

First, I googled it looking around if someone had written something about it. I was getting lot of articles to execute workflows, but I was looking to cancel the waiting workflows. I decided to go-ahead and use SQL to find the Guid of specific workflow instance, so that I can execute my code to try canceling it.

I got surprised when I found multiple records of my workflow, but then on CRM UI it was just one.


Then I took a closer look at the workflow table and try to differentiate them and finally I was able to write a query to filter out the one that I was interested in.

(If you are not seeing multiple, just activate and deactivate a workflow few times and it will generate multiple records of the workflow)

So how to find the Guid of exact workflow that would get triggered based on name only?

Select top 100 categoryname,name,workflowid,statecodename,statuscodename, parentworkflowid,parentworkflowidname 
From FilteredWorkflow
Where name like '%Hold on%'
And category = 0 -- Workflow
And statecode = 1
And parentworkflowid is not null


Rest API request would be like:


"WorkflowSet?$select=WorkflowId
&$filter=StateCode/Value eq 1
and ParentWorkflowId/Id ne null
and Name eq \'' + workflowName + "\"



How to find the Async Job Id that get triggered and it’s associated to our workflow?

From the above query, we can find the workflow Id which is responsible for activating the instance of the workflow. That’s why it may have been named as Workflow Activation Id in AsyncOperation Table/Entity.

Now we use workflow id to filter out the instances, which we actually might be interested in.


/api/data/v8.1/asyncoperations?$select=asyncoperationid
&$filter=primaryentitytype eq 'invoice'
and operationtype eq 10
and  statecode eq 1
and ( statuscode eq 0 or  statuscode eq 20 or  statuscode eq 10)
and  _regardingobjectid_value eq 638F13B4-4AE9-E711-80DA-6C626DCF4746

and ( _workflowactivationid_value eq 98CA71E7-EEE6-E711-80D9-6C626DCF4746
      or _workflowactivationid_value eq 1AC0E180-39E9-E711-80DA-6C626DCF4746)


Finally, to cancel the workflow, here is a code.

function Cancel_Waiting_Workflows(asyncId)
{
       var entity = {};
       entity.statecode = 3;
       entity.statuscode = 32;

       var req = new XMLHttpRequest();
       req.open("PATCH", Xrm.Page.context.getClientUrl() + "/api/data/v8.1/asyncoperations(" + asyncId + ")", false);
       req.setRequestHeader("OData-MaxVersion", "4.0");
       req.setRequestHeader("OData-Version", "4.0");
       req.setRequestHeader("Accept", "application/json");
       req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
       req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
       req.onreadystatechange = function() {
              if (this.readyState === 4) {
                     req.onreadystatechange = null;
                     if (this.status === 204) {
                           //Success - No Return Data - Do Something
                     } else {
                           Xrm.Utility.alertDialog(this.statusText);
                     }
              }
       };
       req.send(JSON.stringify(entity));
}



It was great to explore in Dynamic CRM.

Keep Learning!!!