Usually if I am creating a web resource and I need to run some internal Dynamics365 process my preferred method would be to write an action and then call that.
Sometimes though this isn’t always possible and the workflow already exists and rather than duplicate its existing functionality it becomes easier to use the existing code.
When deciding if writing something new the main thing to remember is that you can pass data into and sometimes more importantly return information back to you JavaScript with an action. A workflow is a bit of a fire and forget process although you can get the results by checking data in the Dynamics365 database.
The code to call the workflow is quite straightforward and you will need the Guid of the workflow that you wish to call. This is easy to find in the address bar of the browser so I won’t cover it here. The other piece of data you will need will be the ID of the record that you are calling the workflow against.
var recId = formContext.data.entity.getId();
This can be obtained quite easily through the Dynamics JavaScript API, and the workflow Id can be obtained and hardcoded or you could search for the workflow using code. The rules are the same as inside the Dynamics365 interface the workflow must be created against the entity type you are running it against otherwise an error will occur.
function MakeWorkflowRequest(recId, workflowId) {
this.EntityId = {
"guid": recId
};
this.entity = {
id: workflowId,
entityType: "workflow"
};
this.getMetadata = function () {
return {
boundParameter: "entity",
parameterTypes: {
"entity": {
"typeName": "Microsoft.Dynamics.CRM.workflow",
"structuralProperty": 5
},
"EntityId": {
"typeName": "Edm.Guid",
"structuralProperty": 1
}
},
operationType: 0,
operationName: "ExecuteWorkflow",
};
};
};
This is the actual function that builds the object containing the information that will run the workflow and requires the Id of the CRM record and the workflowId parameters.
function ExecuteWorkflow(requestObject, onSuccessFunction) {
Xrm.WebApi.online.execute(requestObject).then(
onSuccessFunction
,
function (error) {
console.log(error.message);
});
}
This function actually triggers the workflow, and it gets the object created in the first function, and to make things more flexible I pass in a function that will be executed after the workflow. Because the API is Asynchronous simply adding code after I call the workflow may mean that this gets executed before the workflow has run, especially if the workflow is set to run in the background. when an error occurs I write the error to the browser console. If I don’t need this I simply pass in a NULL.
function runWorkflow(recId, workflowId, onSuccessFunction) {
var workflowObject = new MakeWorkflowRequest(recId, workflowId);
ExecuteWorkflow(workflowObject, onSuccessFunction);
}
This is the function that ties it all together and actually executes the workflow. As an example I would execute the workflow with
var recId = formContext.data.entity.getId();
runWorkflow(recId,"6a874c9f-fd00-42ca-85c9-e2713bcc15cf",function(){ alert("just finished");});
This passes in the function to show an alert box when the workflow has completed, or been set to start if it is a background workflow. Normally I would use the native Dynamics365 alert but this is just example code.
This is the code you will need to include :-
function MakeWorkflowRequest(recId, workflowId) {
this.EntityId = {
"guid": recId
};
this.entity = {
id: workflowId,
entityType: "workflow"
};
this.getMetadata = function () {
return {
boundParameter: "entity",
parameterTypes: {
"entity": {
"typeName": "Microsoft.Dynamics.CRM.workflow",
"structuralProperty": 5
},
"EntityId": {
"typeName": "Edm.Guid",
"structuralProperty": 1
}
},
operationType: 0,
operationName: "ExecuteWorkflow",
};
};
};
function ExecuteWorkflow(requestObject, onSuccessFunction) {
Xrm.WebApi.online.execute(requestObject).then(
onSuccessFunction
,
function (error) {
console.log(error.message);
});
}
function runWorkflow(recId, workflowId, onSuccessFunction) {
var workflowObject = new MakeWorkflowRequest(recId, workflowId);
ExecuteWorkflow(workflowObject, onSuccessFunction);
}
Hope you find it useful.
In this one, could you please let me know the details of what is onsuccessfunction.
Here is an example function I have used in the past that gets the values returned from the action.
The values that are marked as output on the action get returned in the response object that gets passed to the success function.
hope this helps.
function ExecuteReadAllOptionSets(requestObject,recId) {
Xrm.WebApi.online.execute(requestObject).then(function (result) {
if (result.ok) {
result.json().then(
function (response) {
sessions = response.Sessions;
years = response.Years;
examboards = response.Examboards;
grades = response.Grades;
levels = response.Levels;
getOrderData(recId);
}
)
};
},
function (error) {
debugger;
console.log(error.message);
});
}