Dynamics 365 Field Services, Field service, Microsoft Dynamics 365 Field Service, Microsoft Dynamics CRM

Scheduling dependent requirements using RSO in Dynamics 365 Field Service

As part of the April 2020 wave 1 release for Dynamics 365 Field Service you can now have dependent requirements and these can be scheduled in sequence using RSO (Yes this feature is not available for manual or any bookings done using schedule assistant).

You can define relationship between requirements using the successor relationship of a resource requirement

Once you define the the relationship between the requirements and run RSO, RSO is going to schedule the requirements in sequence and the same would reflect on the schedule board too. This is how it’s going to look like on the schedule board:

Dynamics 365 Field Services, Microsoft CRM Dynamics, Microsoft Dynamics 365, Microsoft Dynamics 365 Field Service, Microsoft Dynamics CRM, Resco Field service Mobile

Connecting to your D365 Field Service instance from Field service mobile app

If you are trying to connect to your Field service instance using the FS mobile app you need to first setup the Field service mobile configuration tool (a.k.a. woodford) , install the Default base mobile template project and then derive a customizations project which would hold your Mobile customizations.

This can be setup following the guide on Microsoft docs:


But even after following the guide if you try connecting to FS mobile, you may end up getting few errors.

Your organization has not created a Bookable Resource for your account and set it to be “Enabled for Field service Mobile”

The issue here is that if you want to access FS mobile app, your user account should have a corresponding Bookable Resource with “Enabled for Field service Mobile” flag checked.

Here I have created a Bookable resource and enabled it for FS mobile:

Once you setup the Bookable resource, try to connect to FS mobile app again, you may get another error message:

Your organization needs to configure Field Service Mobile. There may not be a published mobile project or the mobile project is not configured for a security role assigned to you.

If you remember while setting up the FS Mobile project in woodford, the project was enabled for Field Service related Security roles, you need to make sure the User trying to login to the FS mobile app has at least one of those security roles. Once you give FS related security role to the user you should be able to access FS mobile app.

Happy Field servicing 🙂

Dynamics 365 Field Services, Field service, Microsoft Dynamics 365 Field Service, Microsoft Dynamics CRM

Not able to see Requirement groups on the schedule board – Dynamics 365 Field service

If you are working with Requirement groups and want to schedule them using the schedule board and not able to find them on the board, you are at the right place.

Resource requirements don’t appear on the Schedule board by default, it has to be configured from the Schedule board settings area.

Let’s see how to do it:

If you see the default Schedule board, there’s no view configured for Requirement groups. Click on the Schedule board settings icon:

Go to Requirement Panels settings area:

Add a view by selecting View type = Requirement Group

You should now see another view for scheduling Resource Requirements

Microsoft CRM Dynamics, Microsoft Dynamics 365, Microsoft Dynamics 365 Field Service, Microsoft Dynamics CRM

Restricting resources for customers in Dynamics 365 Field service

I have used Preferred Resource for Accounts in Field services a lot many times, which basically means that you can configure if the customer has some preferred resources and it helps the dispatcher to schedule those resources (if available) for a better customer experience.

Recently I came across how to configure if the customer doesn’t want a Resource to be allocated for their work orders.

How we do it is using the same Resource Preferences records but instead of choosing “Preferred ” preference type we use “Restricted”.

Adding Resource preferences:

Create a Resource preference of type “Restricted”

On schedule assistant, the restricted preferences will be applied and the resources would be filtered on the scheduled board if they are Restricted for a customer.

Dynamics 365 Field Services, Field service, Microsoft CRM Dynamics, Microsoft Dynamics 365 Field Service

Cannot find Scheduling settings for Field Service in the new UCI app

I recently installed Field service in a new Trial instance to play with the new UCI interface and the Microsoft Field Service Mobile app.

There’s definitely a learning curve moving from standard UI which has Field services related menu items in the same sitemap but with the new Field service version, Field service related entities can only be accessed from the UCI app. See below screenshot on how to access the APP:

Now, once you click on the app, you can change the area from the bottom in order to configure FS (the Settings area)

I think it’s more confusing if you have used Field service 7.x with standard UI. Once you browse the settings area, you will quickly realize that the Scheduling settings like Scheduling parameters (to enable maps) are missing. The FS settings area looks like this:

In order to access scheduling related configuration settings, there’s another App called (Universal Resource Scheduling) which now sits outside Field services and can be accessed in the following manner:

Once you are in the Universal Resource Scheduling app, you can access the Settings area from the “change Area” dropdown at the bottom and then you will see all Scheduling related configuration settings.

Hope it helped 🙂

Field service, Microsoft Dynamics 365, Microsoft Dynamics 365 Field Service

A generic Sync filter for Customer Assets in Field services

As we know the Microsoft Field service app has offline capability but there are few design decisions that can help you and your customers in long run.

One important aspect is to decide upon the sync filters which drive what data is available for Users while they work in offline mode.

In this post I would be focussing on Sync filter for Customer assets and it becomes even more important if your customer has a lot of Assets in the field.

Deciding upon sync filters should be a continuous improving/ agile process rather than spending time on thinking  the best solution for the very first time.

Here was our Sync filter journey for Customer assets:

  • We started with No sync filter. This is because we weren’t sure how many assets would the customer have/create over the period
  • Next step was to at least filter out inactive assets
  • Now when the asset number started growing, we deciding upon just showing the Assemblies which are nothing but Asset containers at each site. This worked for a while but then technicians had no insight when at a site that this assembly had what assets.
  • We finalised upon showing all Assets (Parent/ Child) in the territories that the User works in. This was great, now the User could see every asset that he/she deals with.
  • After a while this also starting blowing apart as few Users were catering to multiple territories and by default there’s a hard limit of 10000 records that you can sync for an entity in offline mode.
  • The business then decided to re do their territories and create new territories for overlapping areas.

The point here is that no one solution will fit all customers and solution for today may become obsolete tomorrow.

One good thing with woodford sync filters is that we can use fetchxml to build them,

Here’s the sync filter fetch xml we finalised upon:

<?xml version="1.0" encoding="utf-8"?>
<fetch xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1.0">
<entity name="msdyn_customerasset">
<filter type="and">
<condition attribute="statecode" operator="eq" value="0" />
<link-entity name="account" alias="L0" from="accountid" to="msdyn_account" link-type="inner">
<link-entity name="territory" alias="L1" from="territoryid" to="msdyn_serviceterritory" link-type="inner">
<link-entity name="msdyn_resourceterritory" alias="L2" from="msdyn_territory" to="territoryid" link-type="inner">
<link-entity name="bookableresource" alias="L3" from="bookableresourceid" to="msdyn_resource" link-type="inner">
<filter type="and">
<condition attribute="userid" operator="eq-userid" />
Microsoft Dynamics 365 Field Service, Resco Field service Mobile

Activating field service mobile licenses for D365

If your customer has D365 FS licenses and you were using Woodford solution to customize the Microsoft FS mobile app or Resco FS app, the woodford trial would eventually expire after a period of 30 days.

However for each D365 FS license you can activate a FS mobile app license as well, how to do it is explained in detail on the following URL:





Dynamics 365 Field Services, Resco Field service Mobile

Resco Field service mobile app – Error loading woodford solution – CRM metadata failed to refresh

If you are trying to make any customizations to the Resco Field service Mobile app, you would encounter few strange issues at times which can block development.

Note: In case you are unaware, the silverlight based woodford solution just works in IE(Tested in IE11) and that too in non-incognito mode i.e. if you are working in incognito mode, the solution will fail to load.

Also many times the solution gets loaded but towards the end it gives you error saying CRM metadata failed to refresh and then all you can access is your Profile tab (and other non dev related tabs).

I haven’t been able to find a solution to the above problem except for restarting IE again, seems like a caching issue.

Dynamics 365 Field Services, Microsoft Dynamics 365 Field Service

How to sync Resource Bookings in Field service with MS Outlook

A very basic Field service use case is that bookings should show as appointments in MS outlook so that users can keep track of bookings and other office tasks in one single view.

Fortunately this is configurable in D365 FS, however there are few prerequisites:

  • Dynamics 365 Field Service licenses
  • Office 365 Enterprise E3 licenses

Here are the steps to enable synchronization of bookings with User’s calendar:       To be done by Dynamics 365 Administrator

  • From the main menu, click Settings -> Administration.
  • Click System Settings -> Synchronization.
  • Under Select whether to enable syncing of resource booking with, check the Synchronize resource booking with Outlook.


1.png       To be done by each User(Bookable Resource)

  • Click the Settings button in the upper-right corner of the screen.
  • Click Options and then Synchronization tab.



  • Under Resource booking sync with Outlook, check the Synchronization resource booking with Outlook.


CRM, Dynamics 365 Field Services, Microsoft CRM Dynamics, Microsoft Dynamics 365, Microsoft Dynamics 365 Field Service

Creating Booking Rules in Microsoft Dynamics 365 Field Services

Booking Rules are Javascript validations that you can attach to the Booking creation event which is triggered when a booking is created on the schedule board or the schedule assistant.

To create a Booking Rule,  Field Service > Administration, and then choose Booking Rules.


What we need to do is attach a JS web resource with the Booking rule. The JS web resource should have a function which takes in the context and is called when a Resource requirement is dragged and dropped on to the Schedule board or the assistant.

Let’s see some code, in this example we are restricting creating of a Booking on the basis of how many bookings are already being created for a Resource.

function validateRules(sbContext) {
var ruleResult = {};
var resourceReqId = '';
if (sbContext.newValues.ResourceRequirementId != undefined) {
resourceReqId = sbContext.newValues.ResourceRequirementId;
else if (sbContext.newValues.ResourceScheduleSource != undefined && sbContext.newValues.ResourceScheduleSource == 690970004) {//SA
var rr = Xrm.Page.getAttribute('msdyn_resourcerequirement');
if (rr != null && rr.getValue() != null && rr.getValue().length > 0) {
resourceReqId = rr.getValue()[0].id;
if (resourceReqId == '') {
console.log('RR is null. Exiting..');

ruleResult.IsValid = true;
ruleResult.Message = “No RR”;
ruleResult.Type = ‘success’;
return ruleResult;

resourceReqId = resourceReqId.replace(‘{‘, ”).replace(‘}’, ”);
var resourceId = sbContext.newValues.ResourceId;
var startTime = sbContext.newValues.StartTime;
var endTime = sbContext.newValues.EndTime;
var hearingType = ”;

var req = new XMLHttpRequest();
req.open(“GET”, encodeURI(Xrm.Page.context.getClientUrl() + ‘/api/data/v8.2/msdyn_resourcerequirements?$filter=msdyn_resourcerequirementid eq ‘ + resourceReqId + ‘&$expand=new_wa_case($select=wa_hearingtype)’), false);
req.setRequestHeader(“Accept”, “application/json”);
req.setRequestHeader(“Content-Type”, “application/json;charset=utf-8”);
req.setRequestHeader(“OData-MaxVersion”, “4.0”);
req.setRequestHeader(“OData-Version”, “4.0”);
req.setRequestHeader(“Prefer”, “odata.include-annotations=OData.Community.Display.V1.FormattedValue”);
if (req.readyState === 4) {
req.onreadystatechange = null;
if (req.status === 200) {
var result = JSON.parse(req.response);
hearingType = result.value[0].new_wa_case[‘wa_hearingtype’];

if (hearingType == null) {
hearingType = 953860001; // Motion as default
console.log(‘motion set as default’);

var dt = new Date(startTime).toISOString();
var st = dt.substr(0, dt.indexOf(‘T’)) + ‘T00:00:00Z’;
var et = dt.substr(0, dt.indexOf(‘T’)) + ‘T23:59:59Z’; //2018-07-17T11:59:59Z
console.log(dt); // today’s date
var req = new XMLHttpRequest();
encodeURI(Xrm.Page.context.getClientUrl() +
‘/api/data/v8.2/bookableresourcebookings?$select=bookableresourcebookingid,starttime,endtime&$expand=Resource($select=wa_jurytrialhearinglimit,wa_motion)&$filter=_resource_value eq ‘ +
resourceId +
‘ and wa_hearingtype eq ‘ +
hearingType +
‘ and starttime gt (‘ + st + ‘) and endtime lt (‘ + et + ‘)’),
req.setRequestHeader(“Accept”, “application/json”);
req.setRequestHeader(“Content-Type”, “application/json;charset=utf-8”);
req.setRequestHeader(“OData-MaxVersion”, “4.0”);
req.setRequestHeader(“OData-Version”, “4.0”);
req.setRequestHeader(“Prefer”, “odata.include-annotations=OData.Community.Display.V1.FormattedValue”);
if (req.readyState === 4) {
req.onreadystatechange = null;
if (req.status === 200) {
var res = JSON.parse(req.response);
var data = res.value;

ruleResult.IsValid = true;
ruleResult.Message = “Validation succeeded”;
ruleResult.Type = ‘success’;

if (data.length > 0 && data[0].Resource != null) { // Court Room
var juryLimit = data[0].Resource.wa_jurytrialhearinglimit;
var motionLimit = data[0].Resource.wa_motion;
console.log(data, data.length, juryLimit, motionLimit);
var isDone = false;
for (var i = 0; i = new Date(data[i].starttime) && startTime = juryLimit) {
ruleResult.IsValid = false;
ruleResult.Message = ‘Jury Hearing capacity reached. Bookings not allowed.’;
ruleResult.Type = ‘error’;
} else if (hearingType == 953860001 && data.length >= motionLimit) {
ruleResult.IsValid = false;
ruleResult.Message = ‘Motion Hearing capacity reached. Bookings not allowed.’;
ruleResult.Type = ‘error’;
} else {
else {
return ruleResult;