Sunday, October 28, 2018

Dynamics 365 Workflow Scope - User or Organization

Hello mobile world,

Now this is something I didn't pay much attention until QA reported a bug. Workflow doesn't get fired when record create is synced using CRM Resco Mobile.

Workflow scope defines the level of records the workflow will be triggered on. This is something you must pay attention to as  much as the user role security. When you create a workflow in Dynamics 365 V9, by default it's set to User Scope. Workflows with user scope will trigger only for the records that user is privileged to. 


1. User
Choosing this scope means the workflow will run only on the records owned by the same user as the workflow user. This is more like a private workflow of the user.
2. Business Unit
This means the workflow will run on all records owned by the users of the same business unit as the workflow user. 
3. Parent: Child Business Unit
With this, the workflow will run on the records owned by the users of the same business unit as the workflow user as well as any child business units. 
4. Organization
The workflow will run on records owned by any user in CRM. Since it will trigger for all records, organization scope is the most used scope option.

For automatically triggered workflows, they are executed in the security context of the workflow process’s owner and not according to the user who performed the action on the record, that might trigger the workflow (if workflow scope supports).

No matter which Administrative privileges you have on your CRM User, you won't be able to trigger a workflow set to User Scope and Owned by other user. :P

And also this scope applies to all the records and logic in the workflow steps too. For example, imagine you triggered the workflow (Scope = user) on Contact record update (which your user owns) and then you are going to update the Primary Account of the Contact. To update, your User should own the relevant Account record too. Otherwise the workflow will give error.

Now, for the issue I got with CRM Resco Mobile, I had to set the workflow Scope to Organization, to allow it to trigger on Mobile data sync event.

Hope this will be useful to somebody.

Wednesday, October 24, 2018

Dynamics 365 Custom Actions - Bound and Unbound with Xrm.WebApi.online.execute()

Hello World,

It all started when I tried to use Xrm.WebApi.online.execute() method to call CRM Custom Action from Custom Web Resource.
https://docs.microsoft.com/en-gb/dynamics365/customer-engagement/developer/clientapi/reference/xrm-webapi/online/execute.
Instead calling the CRM actions by manually making XmlHttpRequests, below seems to be easy to code.

Xrm.WebApi.online.execute(request).then(successCallback, errorCallback);

Isn't it obvious to select above instead of below hazzard,

var req = new XMLHttpRequest();
req.open("POST", actionUrl, false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.onreadystatechange = function () {
req.setRequestHeader("OData-Version", "4.0");
    if (this.readyState == 4 /* complete */) {
   req.onreadystatechange = null;
        if (this.status == 200 || this.status == 204) {
   // get output
  }
 }
}

Xrm.WebApi that came with V9 provides number of methods like, createRecord, deleteRecord, retrieveRecord, retrieveMultipleRecords, updateRecord, execute and executeMultiple. Create/Update and Retrive was quiet easy to use.

To call custom actions, we can use Xrm.WebApi.online.execute() method, and below is where I got stuck.



In making the request object, how to specify the bound parameter? First of all what's bound/ unbound action?

Unbound Action is nothing but, the Global Action, which is not bound to any Entity :D. Therefore Bound Actions are Actions with a specific Entity.

Now below is an Action bound to Contact Entity.



Now calling Unbound Actions is easy, just use boundParameter: null


For Bound Actions, how to specify the BoundParameter?


To understand how your Action actually takes it's boundParameter and other Input/Output parameters, download the OData Metadata file from Customizations --> Developer Resources. And below is what we get for above sample action.

<Action Name="msdyn_GDPROptoutContact" IsBound="true">
    <Parameter Name="entity" Type="mscrm.contact" Nullable="false" />
    <Parameter Name="optout" Type="Edm.Boolean" Nullable="false" />
</Action>

Now you can see that in-addition to Input/Output parameters, we have a parameter named as "entity". Actually this is documented here in https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/webapi/use-web-api-actions, but we tend to miss it, first time we read.

So now when making your request object for Xrm.WebApi.online.execute() method, treat "entity" as a parameter.

For example below is how you should code the request object for above action.

var target = { entityType: "contact", id: "69DA0233-2D96-W891-B93F-207D7B3BF6C8" }; var reqObject = {}; reqObject.entity = target; reqObject.optout = true; reqObject.getMetadata = function () { return { boundParameter: "entity", operationType: 0, operationName: "msdyn_GDPROptoutContact", parameterTypes: { "entity": { typeName: "mscrm.contact", structuralProperty: 5 }, "optout":{typeName: "Edm.Boolean", structuralProperty: 1} } } };

For me this is a life saving solution :)

Thanks for reading this long.