0% found this document useful (0 votes)
364 views

URS Overview

The document provides an overview of Universal Resource Scheduling (URS) in Dynamics 365. URS allows scheduling of any entity using tools for quick scheduling, multi-resource and multi-day scheduling, and more. It discusses enabling scheduling for entities, creating resource requirements, and using the schedule assistant to match requirements to available and qualified resources based on location, skills, and other attributes. The schedule assistant recommends resources and projected travel times to help dispatchers efficiently assign work orders and book time on technicians' schedules.

Uploaded by

robin69h
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
364 views

URS Overview

The document provides an overview of Universal Resource Scheduling (URS) in Dynamics 365. URS allows scheduling of any entity using tools for quick scheduling, multi-resource and multi-day scheduling, and more. It discusses enabling scheduling for entities, creating resource requirements, and using the schedule assistant to match requirements to available and qualified resources based on location, skills, and other attributes. The schedule assistant recommends resources and projected travel times to help dispatchers efficiently assign work orders and book time on technicians' schedules.

Uploaded by

robin69h
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 280

Contents

Overview of Universal Resource Scheduling (URS)


Scheduling
Schedule assistant overview
Quick scheduling
Travel time and distance
Multi-resource scheduling
Multi-day scheduling
Fulfillment preferences
Resource crew scheduling
Facility scheduling
Resource pools
Time constraints
Advanced filters
Schedule board configuration
Enable an entity for scheduling
Share schedule board tabs
Utilization
Schedule board custom resource attribute
Edit booking template
Booking alerts
Schedule board tab settings
Preview the new schedule board
Extensibility
Extensibility updates
Preferred geospatial data provider
Use your preferred geospatial data provider
Create custom plug-in to use your preferred geospatial data provider
Register and deploy custom plug-in to use your preferred geospatial data provider
Sample: Custom plug-in to use Google Maps API as geospatial data provider
Customizing resource matching
Understanding and customizing resource matching
Find resources by language - A step by step guide
Universal FetchXML
Bug fixes
Overview of Universal Resource Scheduling in
Dynamics 365
2/14/2020 • 4 minutes to read • Edit Online

Schedule anything in Dynamics 365 using Universal Resource Scheduling (URS). You can enable scheduling for any
entity in Dynamics 365 Sales, Field Service, Customer Service, and Project Service Automation, including custom
entities.
For organizations that use:
Dynamics 365 Field Service, you can use scheduling tools to assign work orders to the closest field
technicians in the area. More information: Dynamics 365 Field Service Help
Dynamics 365 Customer Service, you can use scheduling tools to book cases to customer service reps in the
right department and time zone. More information: Dynamics 365 Customer Service - Service Scheduling
Dynamics 365 Project Service Automation, you can use scheduling tools to staff projects with consultants
who have availability and the appropriate skillset. More information: Dynamics 365 Project Service
Automation Help

Prerequisites
Before you can use Universal Resource Scheduling, make sure you have:
Dynamics 365 Field Service, Project Service, or Customer Service.
A license for Resource Scheduling. More information: Onboard your organization and users to Dynamics
365 (online)
User credentials with the Universal Resource Scheduling security role, in order to manage the solution once
it has been deployed.

Enable scheduling for an entity


When scheduling is enabled for an entity, the system creates a resource requirement record for the entity. This way,
when you create a resource requirement, the system automatically checks which entity the resource requirement is
for.
1. From the main menu, click Resource Scheduling > Administration .
2. Click Enable Resource Scheduling for Entities .
3. On the Setup Wizard - Enable Scheduling , click Add Entity and select the entity that you want to enable
scheduling for.
4. Click Booking Relationship and select Create New Relationship .
5. Click Requirement Relationship and select Create New Relationship .

NOTE
If you already have relationships created then you can select form an existing relationship.
6. Click Publish Customization .
7. On the BOOKING SETUP METADATA: INFORMATION form, use the tooltips to edit the default opens.

NOTE
To update the Booking Status Field Logical Name, you will first need to customize the system to add additional
statuses. More information: Customize your Dynamics 365 system - define status reasons
In attribute settings sections field, can be mapped from entity that was enabled for scheduling to fields on booking
requirement. For example, from Date, to Date, Territory, Duration and others.

8. When you’re done, click Save on the lower right corner.

Edit or turn off scheduling for an entity


1. From the main menu, click Resource Scheduling > Administration > Enable Schedulable for
Entities .
2. From the list of Enable Entities , double click on the entity that you want to edit.
3. When the BOOKING SETUP METADATA: INFORMATION form opens, do one of the following:
To turn off scheduling for the entity, on the command bar, click DEACTIVATE . On the Confirm
Deactivation dialog box, click Deactivate .
Or, you can edit the form and when you’re done, click Save on the lower right corner.

Schedule something
Step 1: Create a resource requirement
1. From the main menu, click Sales , Ser vice , or Marketing .
2. Choose an entity that has scheduling turned on. For example, let’s say it’s turned on for the Leads entity. In
this case, from the main menu you would choose Marketing > Leads .
3. From the list of leads choose an existing lead.
4. When the form opens, go to the sub-grid menu, and click Resource Requirement .
5. Under the Resource Requirement Associated View , click New .
6. On the Resource Requirement form, use the tooltips to fill in the inform required information.
7. When you’re done, click Save .
A plugin runs and checks the relationships and automatically sets the booking set-up metadata relationship
appropriately.
Step 2: Schedule the booking requirement
To learn more about the schedule board, Configure the schedule board.
There a few different ways to schedule a booking requirement:
Option 1 : Right click on an unscheduled booking and find available resources.
1. From the main menu, click Resource Scheduling > Schedule Board .
2. From the Booking Requirement list, right click on an unscheduled booking and choose one of the
following:
Choose Find availability - Current Resources to find available resource from the list of resources
on the schedule board.
-Or-
Choose Find availability -Current Resources , to find available resource from resources in the
system.

NOTE
When you do this, the filters will show the options for the selected booking requirement. If you can't find a
available resource for the book, try adjusting the filters.

3. When you see the available slot right click on the time slot on the schedule board and choose Book
Here . Or, drag and drop the booking requirement to the available time slot.
Option 2 : Drag an unscheduled booking requirement from list view to the schedule board.
1. From the main menu, click Resource Scheduling > Schedule Board .
2. Select an unscheduled booking requirement from the list at the bottom.
3. Drag the item to an available resource/time slot on the schedule board.
Option 3 : Schedule a booking requirement form the entity form.
1. From the main menu, click Sales , Ser vice , or Marketing .
2. Choose and entity that as scheduling turned on.
For example, let’s say it’s turn on for the Leads entity. In this case, from the main menu you would
choose Marketing > Leads .
3. From the list of leads, choose the lead that you want to schedule a booking for.
4. When the lead form opens, on the command bar, click Book .
5. Use the schedule assistant to book the requirement.
See also
Install Dynamics 365 Field Service
Install Dynamics 365 Project Service Automation
Overview of the Universal Resource Scheduling
schedule assistant
6/18/2020 • 5 minutes to read • Edit Online

NOTE
In this article, we take a high-level tour of the schedule assistant. For a more in-depth tutorial, check out this full video
walkthrough of the schedule assistant, which includes some practical examples.

The schedule assistant is a semi-automated feature in Dynamics 365 Field Service that helps dispatchers assign
work orders and other jobs to the closest and most appropriate resources.
When triggered by a dispatcher, the schedule assistant will recommend resources that match relevant
requirements, like time windows or skills needed. The system will also then show projected travel time for the
recommended resources, which helps dispatchers plan work accordingly.
When the dispatcher identifies the right resource for the job, they can then book the work to the resource, who can
then see it on their schedule.
In this article, we'll take a tour of the schedule assistant in Field Service.

Prerequisites
The schedule assistant is a part of the Universal Resource Scheduling solution, which is included and installed with
Dynamics 365 Field Service, Project Service Automation, and Customer Service.
Matching requirements and resources
The schedule assistant's primary objective is to match up work with the right resources. In Field Service, work is
typically represented by a work order, which includes information like:
Location
Time
Territory
Time windows

When a work order is created, a resource requirement is automatically generated. From the work order form, go to
Related > Requirements . On the requirement, you can add more details about the work, like:
Characteristics
Roles
Business units
Resource preferences
The schedule assistant uses these details on work orders and requirements to filter resources.

Trigger schedule assistant


When your work order or requirement has relevant details and you're ready to schedule, there are a few ways to
trigger the schedule assistant:
Directly from the schedule board, as seen in the following screenshot:
From the top of the work order form
From the top of the requirement form
From the list after selecting a work order record

Schedule assistant filters


Once the schedule assistant runs, the details from the work order and requirement are filters in the left pane.
Dispatchers can fine-tune results by adjusting filters to meet their scheduling needs.
The filter pane includes work-related options, including:
Work location
Work start and end
Characteristics
Roles
Territories
Organizational units
Resource types
Resource pool types
Preferred resources
Location
Based on both the locations of the work order and the bookable resource, the schedule assistant filters resources
outside of the defined radius, and then shows estimated driving time for each resource.

These same travel time estimates are shown in the grid view of the schedule assistant, as seen in the following
screenshot.
Rescheduling work
Need to rebook work? From the schedule board, just right-click the booked work, and then Rebook . This will
trigger the schedule assistant.

Book the same work order again


You can also schedule the same job to multiple resources with the schedule assistant.
Trigger the schedule assistant for a given work order and book it to a resource's time slot; however, before exiting
the search, select another resource's time slot and select Book again.

Book entities other than work orders


You can book several other entity types via the schedule assistant - Dynamics 365 Sales leads, for example.

For more information, see the article on how to enable an entity for scheduling.

Multi-resource scheduling (Requirement groups)


Need a group of resources to perform work? Use the schedule assistant to book multiple resources at once using
requirement groups. Go to the Field Service app, then to Requirement Groups .

After using the grid format to create multiple requirements, select Book at the top of the form to trigger the
schedule assistant.
The schedule assistant will find different combinations of resources that meet the different requirements and can all
arrive at the job location at the same time.
For more information on setting up requirement groups, see the article Multi-resource scheduling with
Requirement groups.

Learn more about the schedule assistant


To learn more about the schedule assistant and the many ways it can be put to use, check out the following articles.
Schedule with travel time and distance: Explore how travel time and distance are calculated and visualized
for dispatchers during manual scheduling, semi-automated scheduling with the schedule assistant, and
automated scheduling with Resource Scheduling Optimization (RSO)
Schedule within time constraints: When scheduling a work order, case, quote, or any entity enabled for
scheduling, you can set date and time parameters to control when the requirement is booked.
Resource preferences: Resource preferences allow dispatchers to give preference to specific resources over
others when scheduling with the schedule assistant or resource scheduling optimization.
Quick scheduling in Field Service: Quick scheduling (sometimes referred to as "quick book") simplifies the
schedule assistant experience to make scheduling easier and quicker.
Schedule work over multiple days: Work orders and scheduling requirements can be scheduled across
multiple days and weeks. This article explores a few common scenarios.
Resource crew scheduling: Resource crews allow dispatchers to search and schedule multiple resources at
once. This can include a group of employees, subcontractors, equipment, facilities, or any combination
thereof who will perform the same work during a period of time. This article walks through how to set up
resource crews.
Resource pool scheduling: Resource pool scheduling allows you to assemble groups of similar resources to
manage capacity and give schedulers the option to assign specific resources at a later time. This article walks
through two common scenarios.
Facility scheduling: For scenarios where a customer is expected to travel to the company's location, the
facility scheduling feature can coordinate physical spaces and related resources.
Configuration considerations
Time zone for schedule assistant search results

NOTE
As of August 2020, this feature is available as early access. For more information, see the article on how to opt-in to early
access features.

You can view and edit the time zone the schedule assistant's search results are displayed in by triggering the
schedule assistant and selecting the gear icon in the top-right corner.

The time zone value is derived from the time zone on the requirement being scheduled. Go to the requirement,
then Modify Calendar to view and edit the requirement time zone.

The requirement time zone is derived from the following values in the following order:
1. The time zone of the work hours template noted on both the requirement and the related work order, if
applicable.
2. The time zone of the user that created the requirement (the owner). If the owner is changed, the time zone is not
changed. The user's time zone is defined in Personalization Settings .
3. The time zone of the default schedule board tab of the system.
Quick scheduling in Universal Resource Scheduling
8/14/2019 • 7 minutes to read • Edit Online

Quick scheduling (sometimes referred to as “quick book”) simplifies the schedule assistant experience to make
scheduling easier and quicker.
Within the same window of a work order, a single click brings up a pane showing available booking time slots.

This is useful in several scenarios:


Organizations with a high volume of bookings that they need to quickly schedule.
Organizations with call-center workers who might need to schedule while they are on the phone with a
customer, and need to do so quickly to respect the caller's time.
Organizations with schedulers who don't need to see the extra details provided by the schedule assistant or
manipulate the filters to make a resource assignment.
People for whom scheduling is not their primary job. For example, customer service representatives spend most
of their time handling customer issues, and the few times they need to schedule, it should be quick and easy.
When quick scheduling is not enabled, the Book button defaults to the full schedule assistant experience, which
displays additional information and filter options for more comprehensive resource assigning.
Prerequisites
Dynamics 365 Field Service version 8.7 or later. See the “Additional notes” section at the end of this article
for more details.
Quick scheduling must be enabled:
Go to Resource Scheduling > Settings > Administration > Enable Resource Scheduling for
Entities .
Select an entity to display the entity's Booking Setup Metadata .
Set Enable Quick Book to Yes .
In the preceding example, we enabled quick book for the work order entity, meaning quick book will trigger from
the work order form and requirements created by work orders. The process is the same for enabling quick booking
for other entities you have enabled for scheduling.
However, not all scheduling relates to other entities. Some organizations use requirements on their own for
scheduling. Organizations like this should enable quick book for the Default Metadata Settings (none) option.

Quick book a single resource


1. Create a work order
First, create a work order or another entity that is enabled for scheduling and quick booking.

Then, go to the related requirement and add additional attributes.


In this example screenshot, we are looking for a resource who is available within the specified date range, who has
the "Assembly Repair" skill, and who is part of the "Seattle" organizational unit.
2. Select Book
From the requirement or the work order, select Book in the top ribbon. This opens the quick book pane. If quick
book is not enabled, the Book button triggers the schedule assistant interface.
Next, select a time slot, and then select Book in the lower-right side of the pane.
In the background, the system chooses an available resource that also meets requirement criteria like skills and
organizational unit.
If the requirement is location-based, as in the case of onsite work orders or facilities, the system chooses the closest
resource. The closest resource is determined based on the resource's starting location or previous work order
location.
For location-agnostic requirements, the system chooses the first available resource based on alphabetical order of
the resource's first name.
3. Filter options
Although quick scheduling is designed for quick and easy scheduling, there are a few simple filters in the quick
book pane.
The date range is taken from the requirement date range and can be changed.

NOTE
Time parameters on the work order like Date Window Star t and End are passed down to requirements and are factored
into quick booking.

The Filters option allows you to search through all resources (meaning all resources that meet the requirement
criteria) or select a specific resource to quick book (only if the selected resource meets the criteria).
Additionally, you can select the resource icon next to a time slot to see a simple list of applicable resources for that
time slot. See the following screenshot for reference.
This displays more details like travel time and distance, but still has a simpler interface with fewer details than the
full schedule assistant. The schedule assistant can still be triggered by selecting the Open Schedule Assistant link
at the bottom of the quick book pane.
Quick book multiple resources
Quick scheduling also works with requirement groups, which allow organizations to schedule multiple resources at
once.
1. Create a requirement group
Go to Resource Scheduling > Requirement Groups > New .
Use the requirement group control to define the multiple resources needed. Each row represents a resource
requirement.
In the following screenshot example, we need two resources, each with different skills but part of the same Seattle
organizational unit, and we need them for two hours.
For further details, see the topic on requirement groups.
Select a row, and open the form to edit more fields.

These requirements call for resource types contact , user , and account and have a work location of Onsite with a
defined location (latitude and longitude). This means we are sending resources to the customer's location.

Next, from the requirement group control, select Book to trigger quick book.
Again, you can select a time slot and then Book to assign the requirement group to multiple resources, or you can
select the resource icon to see different combinations of resources that fulfill the requirement group.

The results are displayed in order of average travel time and distance. Because each resource might be traveling
from a different location, travel time and distance are calculated as averages.
Lastly, as discussed in the requirement groups topic, requirement groups can include different option sets, and
quick book will respect these. In the following example, we want to schedule a single resource with both required
skills or two resources, each with one of the required skills.
To use requirement groups as part of the work order process, associate a requirement group template to an
incident type. See more details in the requirement groups for work orders section of the requirement groups topic.
Additionally, you can use requirement groups for customer service scenarios. Visit the customer service scheduling
topic to learn more.

Configuration considerations
After quick booking a single requirement, selecting Book again for the same requirement creates an
additional booking and will not rebook the previous one. Selecting Book again for a requirement group will
trigger the rebook process, which cancels previous bookings.
If you have enabled quick book, you enable it for your entire organization; it can't be enabled only for
specific users or security roles.
Quick Scheduling does not support fulfillment preferences with time groups.
Consider using fulfillment preferences with quick scheduling
The purpose of quick scheduling is to simplify the scheduling process. Fulfillment preferences further simplify
scheduling by organizing quick book (or schedule assistant) results in neat time blocks. By default, quick scheduling
uses a fulfillment preference with 30-minute intervals for single requirements, and 30-minute intervals with 10
results per interval for requirement groups. To apply a custom fulfillment preference and override the default:
1. Create a fulfillment preference. In this example, we created a fulfillment preference with 1-hour intervals.

2. Add the fulfillment preference to a requirement and quick book. The quick book results will appear in hourly
intervals.
See our topic on fulfillment preferences for more information.

Additional notes
The confirmation message shown after quick book is currently not configurable.
When quick book is enabled and applicable to the schedulable entity, it triggers wherever the Book button is
displayed.
Quick book is disabled by default in Dynamics 365 Field Service version 8.7 (Universal Resource Scheduling
version 3.7) but is enabled by default in Field Service versions 8.8 and later (Universal Resource Scheduling
versions 3.8 and later).
With Field Service version 8.7 (Universal Resource Scheduling version 3.7), quick book is not applicable to onsite
requirements. With Field Service version 8.8 and later and Universal Resource Scheduling version 3.8 and later,
quick book is applicable to onsite, facility, and location-agnostic requirements.
When quick scheduling an entity that does not have a related requirement, the time zones of search results
appear in GMT (UTC) timezone. For example, if you enable the leads entity for scheduling, you'll see a book
button at the top of the leads form. The leads record will not have a related requirement record by default, but
you can still book it with quick scheduling. The timezone of recommended timeslots will be in GMT (UTC). If you
create a requirement for the leads record and then quick book, the search results will appear in the timezone
noted on the requirement based on the requirement calendar. If there is no timezone on the requirement
calendar, quick book will use the timezone of the user who created the requirement. If the user doesn't have an
associated timezone, then GMT (UTC) timezone will be used.
Schedule with travel time and distance
8/14/2019 • 11 minutes to read • Edit Online

Field service organizations often perform preventative maintenance, inspections, repairs, and other types of
services by sending field technicians to multiple customer sites, and they must actively manage locations and
routes. This makes understanding and minimizing travel time critical for a field service organization's success.
Using Bing Maps API by default, Dynamics 365 Field Service calculates the driving travel time and distance as field
technicians travel:
From their personal address to a work order location.
From a company address to a work order location.
From their current work order location to the next work order location.
From their current location to a work order location (typically for high-priority emergencies).
In this article, we will explore how travel time and distance are calculated and visualized for dispatchers during
manual scheduling, semi-automated scheduling with the schedule assistant, and automated scheduling with
Resource Scheduling Optimization (RSO).

Prerequisites
1. Connect your Dynamics 365 environment to Bing Maps. For more information, see our article on setting this
up. This allows you to locate resources (field technicians) and work orders, and later calculate the travel time
and distances between them.
2. Set auto geocode addresses to Yes . For more information, see our article on setting this up. This allows you
to automatically geocode accounts and work orders when addresses are entered. Geocoding an account or
work order record populates latitude and longitude values, which are required for travel time and distance
calculations.
3. After connecting your environment to Bing Maps, make sure your resources have defined starting and
ending locations. Resources must have geocoded start and end locations in order to calculate travel times
and distances. See the articles on setting up bookable resources and using resource types to locate
resources.
4. Understand that only requirements for which Work Location is set to Onsite and for which latitude and
longitude values are specified are eligible for travel time calculations.
In the following screenshot, a work order has Work Location set to Onsite ; this is passed to the related
work order requirement. When that work order requirement is scheduled to a resource, the system will look
at the work location field, the location of the requirement, and the location of the resource in order to
calculate travel time.
Visualize travel time on the schedule board
After a requirement is scheduled to a resource, the booking appears on the schedule board, and, if applicable, travel
time displays preceding the booking.
In the following screenshot, the travel time to the customer's location is 23 minutes, and the estimated duration of
the work order is 2 hours, giving the booking a total duration of 2 hours and 23 minutes.

If you don't want travel time displayed as separate from the working duration, clear Show Travel Duration in the
schedule board configuration. This makes it so the travel time and working duration appear as a single solid block,
as seen in the following screenshot.
As field technicians complete work, they can update the booking status to Traveling . The system tracks the
duration of time the booking status is set to traveling and updates the Actual Travel Duration accordingly,
though this will not be displayed on the schedule board.

When field technicians arrive onsite, they can update the booking status to In progress , indicating work has
begun. The system tracks the duration of time the booking status is set to In progress and updates the Total
Duration In Progress booking field. Finally, when the booking is complete (in other words, the booking status is
set to Completed ), the booking End Time is updated, and the booking length is updated visually on the schedule
board.
Add travel time with manual scheduling
By default, manually scheduling a requirement by dragging and dropping on the schedule board will not calculate
travel time and distance. This can be helpful for field service organizations that are not concerned with managing or
optimizing their field technicians' travel but simply need to manage appointment start times. Imagine a scenario
where an emergency work order arises, and the dispatcher simply wants to communicate the time that a field
technician will arrive.
For example, a work order requirement that is manually scheduled to a resource at 9:00 AM implies that the field
technician should arrive at the customer's location at 9:00 AM; in this scenario, it's the field technician's
responsibility to manage travel arrangements. In the following screenshot, an unscheduled work order requirement
was dragged from the lower requirement pane to 9:00 AM for a resource. No travel time is calculated or added to
the duration of the booking, implying that all 4 hours make up the working duration.
Organizations that operate in small contained geographic areas can add a generic 30 minutes to the work order
durations either manually or by inflating the incident durations to roughly estimate travel but still utilize manual
scheduling.

NOTE
As of Dynamics 365 Field Service version 8.6, travel time and distance calculations can be added to bookings that are
manually scheduled .

In addition to completing the tasks mentioned earlier in this article, you need to go to Resource Scheduling >
Settings > Administration > Scheduling Parameters and set Auto Update Booking Travel to Enabled .

This will add a travel time to the booking visualization on the schedule board, displayed by a line preceding the
booking, and populate the Miles Traveled booking field (though this is not visualized on the schedule board).
In the following screenshot, an unscheduled work order requirement was dragged from the lower requirement
pane to a resource at 10:00 AM. Similarly to before, this implies that the field technician should arrive onsite at
10:00 AM; the only difference is that the travel time to get there from a home, office, or previous job location is
displayed before that time.
The auto-update booking travel feature will update travel time calculations as new bookings are made beyond the
initial schedule. In the following screenshot, you see two onsite work order requirements scheduled back-to-back
on the schedule board.

If a third onsite requirement is scheduled in between the original two, the travel time calculations are updated
accordingly, based on the new route order. The order of the bookings is decided by the estimated arrival time, not
the travel start time.

NOTE
When updates (like in the preceding screenshot) take place, the booking start and end times are not cascaded for the rest of
the day, as is evident by the overlap. Only the travel times and distances are updated. To ensure that the remaining bookings
cascade, correct overlapping times, and fit inside working hours after changes, organizations should consider using Resource
Schedule Optimization (RSO).

For more information on the Auto Update Booking Travel feature, see the additional notes section of this article.

Add travel time with schedule assistant


The schedule assistant is designed to help dispatchers make better scheduling decisions based on travel times and
distances.
Consider a scenario where a dispatcher wants to schedule a work order requirement to the field technician who is
closest to the work- order location based on travel time.
When triggered from the schedule board, the schedule assistant shows resources within the distance radius filter,
along with the travel time estimates from their location (home, office, previous job, or real-time location) to the
work-order location.

This is predicated on the following conditions:


The work order requirement has a work location of Onsite .
The work order requirement has a location (latitude and longitude).
The resources displayed have defined locations.
This is also true when the schedule assistant is not triggered from the schedule board but by the Book button from
a requirement.
In the following screenshot, travel time and distance calculations appear in the columns.
NOTE
If the work order requirement has a work location of Location Agnostic or if the schedule assistant work-location filter is
changed to Location Agnostic, then resources without locations will also be displayed, along with resources that do have
locations, except that the booking will not calculate travel time.

In the following screenshot, the work location is location agnostic, and no travel times are displayed in results.

Additionally, the Auto Update Booking Travel feature (Field Service version 8.6 and later) updates subsequent
bookings when using the schedule assistant.
In the following screenshot, you'll see a resource's schedule with time available at the beginning of the day, which
may have been due to a cancellation.
When the schedule assistant is triggered, it finds the available time slot.

After it's booked, the travel time of the subsequent booking is updated as the location has changed.

Add travel time with Resource Scheduling Optimization


While the schedule assistant can help dispatchers make better scheduling decisions for individual requirements,
Resource Scheduling Optimization (RSO) helps dispatchers make smarter scheduling decisions across many or all
requirements at once. With regard to travel, this is the difference between reducing travel times and distances and
minimizing them.
When the optimization runs and automatically schedules work orders or other requirements, the travel times
display on the schedule board the same as with other booking methods. See the following screenshot for reference.
However, to better understand how RSO minimizes overall travel time, each RSO run (called a "request") displays a
graph comparing total working minutes scheduled to total travel minutes for those optimized bookings. This can be
compared to the same graph for requirements scheduled manually or with the schedule assistant.

NOTE
If the RSO is set to schedule within working hours, it will calculate time to leave at the end of the day for resources to travel
to their ending location, generally a home or office.
Travel outside working hours
Many organizations want to allow technicians to begin traveling before their working hours up to a limit. Configure
resource scheduling optimization to allow travel time before or after working hours as seen in the following
screenshot. For more information, see the article on allowing travel time outside of working hours with resource
scheduling optimization.

Consider traffic when scheduling


To help with scheduling decisions, current traffic patterns and accidents can be displayed on the schedule-board
map alongside technician routes. To do this, select the traffic light icon at the top of the schedule board map. See
the following screenshot for reference.
NOTE
Travel time calculations do not reflect traffic patterns or historical travel times based on the time of day or year.

Scheduling based on real-time traffic is not applicable because most organizations schedule days or weeks in
advance, and you can't predict real-time traffic ahead of time.
Bing Maps and other mapping providers can provide real-time and historical travel-time calculations, and this
information can be called with Power Automate to calculate whether the current travel time is greater than the
estimated travel time and automatically update the booking status accordingly.
If a field technician begins travel to their next work order and sees that the travel time is much longer than
estimated by the system, they should indicate this with a custom booking status of "running late," so dispatchers
can plan accordingly.

Predictive travel times with historical traffic information


When using resource scheduling optimization, you can take historical traffic information into account to better plan
for travel times.
For more information, see our article on predictive travel with resource scheduling optimization.

Configuration considerations
By adding a travel charge to the service account of the work order, you can charge the customer a fee for travel
time and distance as work orders are completed. For more information, see the article on adding account-
related details to work orders.
A field technician's current location as derived from their mobile device running the Field Service Mobile app
can be used for travel time and distance calculations with the scheduling assistant. This is called Real-Time
Mode . For more information, see the article on enabling and testing location auditing.
Field Service uses the Bing Maps API for travel time and distance calculations, but other APIs such as Google
Maps can be used as well.
By default, work order requirements have a work location of Onsite , but default work location can be edited for
each schedulable entity by going to Resource Scheduling > Settings > Enable Resource Scheduling for
Entities > , and then selecting Enabled Entity .

Additional notes
The out-of-the-box functionality supports travel time and distance calculations only for driving, not walking or
flying.
If Auto Geocode Addresses is turned on, imported records will be geocoded, as will updates to the Address
1 field.
Auto Update Booking Travel for Field Service version 8.6 and later**
The Auto Update Booking Travel feature for manual scheduling needs two locations to work. For example, if a
resource has a starting location, and the first requirement scheduled to the resource has a location (for instance, the
work location is Onsite ), then the travel time will be calculated and visualized. If the resource does not have a
starting location (for instance, if the resource start location is Location Agnostic ), the first onsite requirement
scheduled will not have a travel time. However, if an onsite requirement is scheduled after another onsite
requirement, then the feature has two known locations, and the travel time between the two requirements will be
calculated even if the resource is location agnostic .
Here are a few more notes about the Auto Update Booking Travel feature:
The feature cannot be enabled or disabled based on specific users, schedule board tabs, or specific
schedulable entities.
The feature only applies to the Hours view of the schedule board, and travel time and distances are not
updated if the bookable resource booking form is edited manually, edited with a workflow, or if the bookings
are imported.
If you have an existing onsite booking, the subsequent onsite booking calculates travel time from the
previous booking up until the beginning of the next day's working hours, even if there are multiple hours in
between the two onsite bookings.
The time that the requirement is dragged to the schedule board is the time that the resource will arrive
onsite, and the travel time is added before that time. This is not configurable. For example, if you schedule
an onsite work order requirement at 10:00 AM by dragging the requirement to the 10:00 AM time slot, and
the feature calculates 20 minutes of travel time, then the travel will begin at 9:40 AM, and the resource will
arrive by 10:00 AM.
Multiresource scheduling with requirement groups
8/14/2019 • 7 minutes to read • Edit Online

Requirement groups allow you to define groups of resources that would be appropriate for a job and to then
schedule all those resources with a single search. With requirement groups, you can mix and match the different
types of resources—such as individual field technicians, a whole crew, equipment, or facilities—needed for a job.
For example, you might use a requirement group to find resources for a work order requiring:
One field technician with skill A and skill B
-or-
Two field technicians, one with skill A and the other with skill B.
You might also use a requirement group to find resources for a sales demonstration requiring:
Two people in the same sales territory, with both working onsite.
Two people in the same sales territory, with one onsite and one working remotely.
You can also use a requirement group to find resources for a project that can be done by any resource with the
right piece of equipment, who is available at 9:00 AM during a selected week.
To schedule multiple resources with requirement groups, follow these steps:
1. Create a requirement group template.
2. Create a new requirement group.
3. Book the requirement with the scheduling assistant.

1. Create a requirement group template


1. Go to Universal Resource Scheduling > Settings > Requirement Group Templates , and then select
New .
2. Enter a name for the requirement group, and set the Is Template field to Yes . Select Save . You will see a
grid view of requirement details with a root requirement named after the template.
3. In the root, set a duration for all related requirements. Note that changing the duration for the root or an
individual requirement changes the duration for all requirements in the group.
4. Select the root, and then select Add Requirements . Fill the fields across the columns. If you need to add
details that aren't displayed in the columns, select the requirement, and then select Open Form to add
details in the requirement form.
5. Set the All or Any option. Setting All means that all requirements must be fulfilled, so that the system
searches for resources for each requirement. Setting Any means that the system searches for resources that
can fulfill any requirement and that fulfilling one requirement fulfills the entire requirement group.
6. Save the requirement group template.

NOTE
The All or Any setting is powerful when you need to add multiple option sets to a requirement group, which is done
by adding subgroups.
In the following screenshot example, the root requirement is set to Any , but each option within the root is set to All.
This means that when attempting to book the requirement group, the system searches for either all of option 1 or
all of Option 2 . The system searches for two resources, each with one required skill (characteristic), or searches for
one resource with two required skills.

2. Create a new requirement group


1. Navigate to Universal Resource Scheduling > Requirement Group > New .
2. Enter a name.
3. Select a template from the drop-down list, and then select Save .
4. If needed, edit the requirements, and then select Book .
The requirement group is noted on all related requirements.

3. Book the requirement group


Select Book from a requirement group, which triggers the schedule assistant, as shown in the following screenshot.

The schedule assistant displays different options to fulfill the requirement group, noting the particular requirement
it is fulfilling in the Requirement column.
By default, it recommends options with fewer resources first, in an attempt to minimize travel time and/or cost. You
can also sort by Earliest Time First in the left pane.
Selecting and booking an option for multiple requirements creates multiple bookings reflected on the schedule
board.
If multiple bookings are created when scheduling a requirement group, you can use the split view feature on the
schedule board to view all related bookings.

In the preceding screenshot, the lower split view shows all bookings scheduled from the requirement group.

Requirement groups for work orders


For field service scenarios, requirement group templates are designed to work with incident types. An incident type
is a way of automatically adding duration, service tasks, products, services, and other attributes to a work order.
Adding an incident type to a work order can also automatically add requirement groups. This is achieved by
associating a requirement group template to an incident type:
1. Create a requirement group template.
2. Associate an incident type to the requirement group template.
3. Add the incident type to a work order.
4. Book the work order.
1. Create a requirement group template
Refer to the first section of this topic for instructions.
2. Associate an incident type to the requirement group template
1. Navigate to Field Ser vice Settings > Incident Types .
2. Select an incident type, or create a new one.

NOTE
Incident types with characteristics cannot relate to requirement group templates.

3. Select Requirement Group under related entities, and select add a new one .
4. Select a requirement group template from the drop-down menu to associate the template with the incident
type, and then select Save .

3. Add the incident type to a work order


1. Navigate to Field Ser vice > Work Orders > New .
2. Fill out required work order details, and add the incident type before saving .
This is done by choosing an incident type for the Primar y Incident Type field or navigating to Work
Order Incident Types .

NOTE
When an incident type with a requirement group template is added to a work order, the number of work order
incidents is limited to one.

3. Navigate to Work Order > Requirement Groups to verify that requirements have been added to the
work order according to the requirement group template.
4. Book the work order
Select Book to schedule the work order.

Tips for using templates for requirement groups


A template is not required . A requirement group can be created and booked without a template being
created first. Templates are recommended for repeatable scenarios.
Order matters . By default, the schedule assistant results will favor requirements within a requirement
group with fewer resources. If options within a requirement group require the same number of resources,
the schedule assistant results will favor the requirements listed first.
Duration must be equal . All requirements within a requirement group must have the same duration.
Changing the duration of the root/subgroups or any of the requirements will change the duration of all
requirements within a requirement group. Duration of individual bookings can be changed after the fact,
depending on cascade settings.
You can book directly from a template because creating a template automatically creates related
requirements in the background. The actual template is not scheduled. This increases efficiency for scenarios
where you want to schedule a requirement group and create a template at the same time. However, editing
star t time and end time is not available through the template, only through resulting requirements.
The following fields are kept in sync between requirements in a requirement group. Editing these fields for
one requirement will update all requirements:
Duration
Start
End
Fulfillment preference
Booking Setup Metadata
Work location
Latitude
Longitude
Schedulable entity (for example, work order, Project, or custom entity)
Updating a requirement group template does not update previously created requirements from that
template, only new requirements.
Crews can be an option for fulfilling requirement groups. However, a crew might have more resources than
required by the requirement group and will therefore rank lower in schedule assistant search results.

Tips for using requirement groups to schedule work orders


When requirement groups are related to onsite work with a location (work orders), the schedule assistant
looks for groups of resources that can arrive at the same time, not resources that can begin traveling at the
same time.
If an incident type has a characteristic associated with it, it is not possible to add a requirement group
template, and vice versa.
After scheduling multiple requirements to multiple resources and thus creating multiple bookings, the work
order status is driven by the same logic as scheduling crews or pools or manually scheduling the same work
order multiple times. This means that if at least one booking has a status of In Progress , then the related
work order will have a status of Open-In Progress . Additionally, the work order status becomes Open-
Completed only if all related bookings have a status of Completed (not including canceled bookings).

Keyboard shortcuts
You can use keyboard shortcuts when creating requirement groups, shown in the following table.

C OMMAND K EY S

Expand collapsed row SHIFT ALT +

Collapse expanded row SHIFT ALT -

Indent task SHIFT ALT right arrow

Outdent task SHIFT ALT left arrow

Move task up SHIFT ALT up arrow

Move task down SHIFT ALT down arrow

Add new row SHIFT ALT insert

Delete row SHIFT ALT delete


C OMMAND K EY S

Refresh SHIFT ALT F5

Edit SHIFT ALT F2


Schedule work over multiple days
10/21/2019 • 7 minutes to read • Edit Online

Work orders and scheduling requirements can be scheduled across multiple days and weeks. A common example
is scheduling a 40-hour work order across an entire work week where the field technician is expected to perform
more detailed work at the same location each day.
Dispatchers can schedule multi-day work in between existing bookings, by double-booking existing schedules, or
as a continuous block of time.
When scheduling multi-day work orders or requirements, dispatchers can choose an allocation method that
dictates how the duration is split up throughout the days and weeks.
Allocation methods include:
Full capacity
Percentage capacity
Distribute evenly
Front load
For more information, see the topic on allocation methods.
Let's explore multi-day scheduling and allocation methods by configuring 3 scenarios:
1. Schedule a 30-hour installation work order manually from the schedule board.
2. Schedule a 30-hour requirement with the schedule assistant.
3. Schedule and divide a 30-hour requirement among 2 resources with the schedule assistant.

Prerequisites
If the work you wish to schedule spans multiple weeks or has dependencies on previous steps and milestones,
consider using Dynamics 365 Project Service, which has Gantt chart functionality.

Scenario 1: Schedule a multi-day work order manually on the schedule


board
Create a work order with a duration longer than 1 day.
This can be done in the following ways:
Adding a primary incident type with a long duration (in the following screenshot, 1.25 days = 30 hours).
Adding multiple incident types where the sum of each incident duration adds up to more than 1 day.
Not adding any incident types but entering a duration on the related resource requirement after the work order
is created and saved.
After the work order is saved, a resource requirement is automatically created. Access it by going to Related >
Requirement from the work order section menu.
If you have not done so, enter a multi-day duration in the Duration field, along with From Date and To Date ,
which describes the date range the multi-day work should be spread across.

The requirement From Date and To Date will populate with the Date Window Star t and Date Window End
work order field values.
Next, go to the Hours view of the schedule board and select the multi-day work order requirement in the lower
pane.
Then select a resource on the board for which you would like to schedule the multi-day work order requirement.
Do not drag and drop.

NOTE
Dragging and dropping a multi-day requirement onto the Hours view will create a long continuous booking through non-
working hours.

A Create Resource Booking pane will display on the right where you can confirm or edit:
Star t Date and End Date : populated from the requirement's From Date and To Date fields.
Booking Status : Work order requirements are typically given a booking status of Scheduled by default
but you can choose from your organization's statuses here.
Booking Method : Select the Allocation Method to define the pattern of how the requirement should be
spread across the start and end dates.

After selecting Book , the system will create multiple bookings across multiple days.
On the Days view of the schedule board, you can more easily see the booking pattern. In our example, we chose
Front Load Hours as our booking method, so the bookings filled the resource's available time with the leftover
duration on the last day.

NOTE
Using Front Load Hours as the booking method creates multiple bookings around the resource's existing schedule in
instances where other bookings exist for the scheduled resource.

Dragging and dropping a multi-day requirement on the Days view will trigger the Create Resource Booking
side panel to schedule multi-day bookings like above.
Scenario 2: Schedule a multi-day requirement with the schedule
assistant
Unlike the previous scenario, rather than starting by creating a work order, we will start by creating a resource
requirement.
Go to Resource Scheduling > Resource Requirements > +New .
Enter a Name .
The From Date and To Date fields represent the date range the multi-day requirement should be spread across.
For Allocation Method , select one of the following:
Full capacity
Percentage capacity
Distribute evenly
Front load
For more details on each of these, see the topic on Allocation methods.

NOTE
You need to set an allocation method before saving.

For Duration , enter a multi-day duration. In our example, it's 30 hours.


Save .
Next, enter other requirement details such as skills, roles, resource preferences, and service territory. These will help
define the eligible resources.
From the newly created requirement, go to Related > Requirement Details .
Requirement details are automatically created to split up the requirement into time segments and are based on the
duration and the allocation method. In our example in the following screenshot, a 30-hour requirement split up
between 5 days is 6 hours, or 360 minutes each day.

The requirement details are based on the requirement's calendar, which you can edit by selecting Modify
Calendar in the top ribbon of the requirement.
Then select Book to trigger the schedule assistant for this multi-day requirement.
Resources with availability and that meet the other attributes will show as results. Simply select a resource, the
dates, and then Book . This will create multiple bookings across the date range according to the pattern of the
allocation method.

Once booked, you'll see the resource's availability decrease and the fulfilled duration increase. In our example, 30
hours of duration were fulfilled, 6 of 6 hours booked each day; and the resource's 8 hours of availability was
reduced to 2 hours each day.
NOTE
This scenario scheduled a requirement without a related work order. To schedule a multi-day work order with the schedule
assistant, you'll need to manually add a related requirement with an allocation method to a work order and delete or
disregard the automatically created one. Alternatively, you can manually create requirement detail records with Specify
Pattern for the auto-created requirement. This is because you need to set an allocation method before saving and the
requirements that are automatically created by work orders have an allocation method of None by default.

Scenario 3: Schedule a multi-day requirement to multiple resources


Like scenario 2, you'll first need to manually create a multi-day requirement. The requirement can exist on its own
or be related to a work order.
From the newly created requirement, go to Related > Requirement Details then choose Specify Pattern from
the top ribbon.
This allows you to edit and override the requirement details pattern created by the allocation method.

Select Book .
Select a resource and specific days for just that resource, then choose Book (not Book & Exit , as that will close the
schedule assistant)

Then choose another resource and specific days for only that resource. Then choose Book again.

Bookings are created for each resource on the days selected. Availability for each scheduled resource is updated as
well.
Configuration considerations
Each requirement has its own calendar that you can view and edit from the Modify Calendar option in the top
ribbon menu. The calendar is important because it allows you to edit the time zone of the requirement and how
the schedule assistant results should be displayed.

The Booking Methods Full Capacity , Percent Capacity , and Remaining Capacity reflect the Bookable
Resource's working hours calendar. For example, if the Bookable Resource's working hours calendar is 9:00 AM -
5:00 PM, Monday - Friday, and you select Full Capacity as the allocation method, it will assume Full Capacity
means the total time of the resource's calendar (which can be less than the requirement duration).
Availability does not need to be continuous. For example, if a dispatcher needs to schedule a resource for 4
hours one day, that resource will show as available as long as there is 4 total hours of availability, not necessarily
in a single block.
You can manually create requirement details as needed to schedule multi-day work according to a custom
pattern.
You cannot schedule more hours than are available in a defined week. For example, if the calendar is 9:00 AM -
5:00 PM, Monday - Friday, which equates to 40 hours per week, you cannot schedule more than 40 hours in one
week. This would have to be done manually.
Front load versus full capacity allocation methods: Front load will schedule around existing bookings, and full
capacity will schedule in addition to existing bookings, overbooking as needed.

Additional notes
Requirement groups cannot be scheduled for multiple days.
The schedule assistant will filter available resources for multi-day work by their location, but travel time will not
be calculated and added to the resulting bookings.
As you book requirements, multi-day or otherwise, the system tracks fulfilled duration and remaining duration.
These field values compare total booked time with the duration of the requirement.
See also
Allocation methods
Multi-resource scheduling
Fulfillment preferences
8/14/2019 • 8 minutes to read • Edit Online

Fulfillment preferences are customizable entities that let you choose how schedule assistant results are displayed,
like with neat hourly appointments or morning and afternoon time windows.
By default, the schedule assistant displays results based entirely on resource schedules and the earliest available
time, such as 10:39 AM. With fulfillment preferences set to hourly, the same resource's availability shows as
11:00 AM . This makes it simpler for the scheduler to view and understand availability and communicate it to the
customer.

Overview
Fulfillment preferences break down into two features: inter vals and time groups . Note that both are designed for
work done in a single day, not multiday work.
Intervals
Intervals display schedule assistant results in neat time slots that dictate start time of subsequent bookings. When
configured as 30-minute intervals, the schedule assistant will display a resource available at 9:27 AM as available at
9:30 AM and will book the start time (arrival time) for 9:30 AM. This includes travel time for onsite requirements
and work orders, meaning travel time will begin before 9:30 AM, and a field resource will arrive and start work at
9:30 AM.
For example, a hair salon may want to offer appointments every hour because 1-hour intervals are a good time
estimate for their work, which is mostly consistent and predictable. It's also easier to communicate 1-hour
appointments to customers when scheduling.
Time groups
Time groups enable schedulers to search and view results as blocks of time when using the schedule assistant.
Typical examples include mornings, afternoon, nights, and 2-hour windows. Unlike intervals, time groups do not
dictate the star t time of subsequent bookings . Time groups organize results, but leave the start time/arrival
time as-is, based on the particular resource's schedule.
When a time group is created for morning (8:00 AM to 12:00 PM) the schedule assistant will display a resource's
earliest availability within the defined morning bucket. Results will show a list of possible resources to start at 8:32
AM, 9:07 AM, and 11:23 AM, and all results will appear within the "morning" time group because the start times fall
within the 8:00 AM to 12:00 PM time group.
For example, a heating and cooling company wants to group air-conditioning installations into morning (8:00 AM
to 12:00 PM) and afternoon (1:00 PM to 5:00 PM) windows, with a 1-hour break for lunch in between. Because
installations are dependent on many variables, schedulers aren't comfortable committing to an exact time; they
would rather communicate to customers a morning or afternoon time range when installation resources will arrive
to begin working.
Inter vals and time groups can be combined to offer predefined intervals within a predefined time block, such as
grouping 1-hour appointments within morning and afternoon groups. This allows a scheduler to first identify
whether morning or afternoon works better for the customer, and then offer an appointment. This further simplifies
the scheduler experience and communication to the customer.
The following sections give instructions on setting up intervals and time groups and also how to set them up to
work together. Note that Universal Resource Scheduling version 3.1+ is required.
Interval setup
To set up intervals, you need to:
Create a fulfillment preference.
Associate the fulfillment preference to a requirement.
Book the requirement with the schedule assistant.
Create a fulfillment preference
1. Navigate to Universal Resource Scheduling > Fulfillment preferences > +New . Enter a name and save.

2. Navigate to the Inter val tab.

3. Enter a duration for Inter val . This is the duration between available time slots. Typical examples include 30
minutes, 45 minutes, 1 hour, and 2 hours.
4. Enter a time for Inter vals Begin , which defines when to begin counting the interval. So if this is set to 12:00
AM, the available options are 12:00 AM, 12:30 AM, 1:00 AM, and so on; however, results will also depend on
resource availability and working hours. If left blank, the interval will begin at the beginning of the search.
For example, if your interval is 30 minutes and Interval Begins is blank, when you attempt to book at 11:13
AM, your time slot options are 11:13 AM, 11:43 AM, 12:13 PM, and so on.
5. Enter a number for Results per inter val . This dictates how many options a scheduler will receive for each
interval. If left blank, the system defaults to 1.
The results per interval value determines how many options for a given time slot will appear in schedule
assistant results. So if you have 85 resources all available at 9:30 AM, and results per interval is set to 85,
then all resources will show. If results per interval is set to 5, then only the 5 best will show.
6. Save and close.
Associate fulfillment preference to a requirement
Navigate to the requirement you want to schedule and specify the fulfillment preference.

You can also associate the fulfillment preference from the requirement group entity, as seen in the following
screenshot:
Book the requirement with the schedule assistant
Select Book from the requirement ribbon. Note that the start times in the scheduling assistant appear in 30-minute
intervals.

For field service examples where resources perform multiple appointments each day, a shorter 15-minute interval
is recommended. This makes for the most efficient use of resources with simplified start times.

Time group setup


To set up time groups, you need to:
Add time group details to a new fulfillment preference.
Specify fulfillment preference on the resource requirement.
Book the requirement with the schedule assistant.
Add time group details to a new fulfillment preference
1. Navigate to Universal Resource Scheduling > Fulfillment preferences > +New . Enter a name and save.
2. Navigate to the Details tab on the fulfillment preference record.

3. Select +Add New Time Group .


4. Add the following information to the fields:
Name - "Morning," for example
Star t Time - 8:00 AM
End Time - 12:00 PM
Another time group might be "afternoon," between 1:00 PM and 5:00 PM (this leaves 12:00 PM to 1:00 PM
unavailable, allowing for lunch).

Specify fulfillment preference on the resource requirement


Navigate to the resource requirement you want to schedule, and specify the fulfillment preference.
Book the requirement with the schedule assistant
Navigate to a resource requirement. Select Book from the ribbon menu to initiate the schedule assistant.
The schedule assistant results show a column detailing the start and end times of the associated time group. These
results can be sorted.

Right-clicking on the column header allows schedulers to group by time group details (by selecting "Group"). This
comes in handy when focusing on a specific time block that a customer prefers.
NOTE
Time group details ensure the start time of the booking falls within the start and end time of the time group; however, the
end time can fall beyond that range. In the preceding screenshot, a resource available at 11:59 AM appears in the "morning"
time group, and the duration of the booking will spill over into the lunch/afternoon time group.

Using intervals and time groups together


You can add both an interval and a time group to a single fulfillment preference, but this requires a few important
considerations.
Using both an interval and time group means that you cannot add a value for Inter val Begins . The interval
will begin at the time of the earliest time group.
If the Reset Inter val per Time Group Detail option is set to Yes , the intervals will reset once a new time
group detail overlaps with an interval.
Consider the following scenario:
A traditional brick-and-mortar business offers appointments every 90 minutes, so intervals are set to 90
minutes. Additionally, they separate into morning and afternoon time groups of 8:00 AM to 12:00 PM and
1:00PM to 5:00 PM, with a 1-hour lunch in between. Therefore, both intervals and time groups are useful for
this business.
If the Reset Inter val per Time Group Detail is set to No , the appointments would be:
8:00 AM, 9:30 AM, 11:00 AM (not 12:30 PM because this is blocked for lunch), 2:00 PM, and 3:30 PM.
If the Reset Inter val per Time Group Detail is set to Yes , the appointments would be:
8:00 AM, 9:30 AM, 11:00 AM, (not 12:30 PM because this is blocked for lunch), 1:00 PM (resetting for
the next time group detail), 2:30 PM, and 4:00 PM.

Configuration notes
Intervals can also be set for requirement groups. All requirements within that requirement group will inherit
the same fulfillment preferences. The fulfillment preferences entity was originally named "time groups," and
therefore, the actual schema name for this entity is msdyn_timegroup , although the display name is
Fulfillment Preferences .
Time group details are only compatible for individual requirements.
Fulfillment preferences apply to location-agnostic and onsite requirements.
There is an attribute on the booking entity called Time Group Detail Selected
(msdyn_timegroupdetailselected ), which points to the time group detail entity. This value is
automatically populated when a booking is created through the schedule assistant. For example, if a
requirement is scheduled and the results fall into the time group “9 to 12,” the booking created through the
schedule assistant will have the value “9 to 12” in the time group detail selected field.
The Inter vals Begin time is dependent on the time zone of the requirement calendar when triggered from
the requirement; however, when triggered from the schedule board, it depends on the user's time zone.
Quick Scheduling does not support fulfillment preferences with time groups.
Supported vs. not supported functionality
In v3.1 of Universal Resource Scheduling (URS), some features will work when scheduling both individual
requirements and groups of requirements, and some features will not work for both. Please use the following table
for guidance.

C O M PAT IB L E W IT H SC H EDUL IN G A C O M PAT IB L E W IT H SC H EDUL IN G A


F UL F IL L M EN T P REF EREN C E F EAT URE SIN GL E REQ UIREM EN T ? REQ UIREM EN T GRO UP ?

View results by interval Yes Yes

Change interval on schedule board Yes Yes

Change results per interval on schedule Yes Yes


board

Results per interval Yes Yes

Intervals begin Yes Yes

Show results by time group detail Yes No

Reset intervals per time group detail Yes N/A

Display top X results per time group Yes N/A


detail

Hide Booking Time Yes (Time Group Detail) N/A


Resource crew scheduling
8/14/2019 • 11 minutes to read • Edit Online

Resource crews allow dispatchers to search and schedule multiple resources at once. This can include a group of
employees, subcontractors, equipment, facilities, or any combination thereof who will perform the same work
during a period of time. Crews speed up and simplify the scheduling process and allow team members to work
together more consistently.
Crews are ideal for scenarios where:
a group of resources will work together for a set number of days, weeks, or months.
a crew meets at a location in the morning, shares a vehicle, and is together all day from job to job.
a new employee is shadowing a veteran to learn new skills.
The primar y use case for booking crews is scheduling a requirement group with multiple requirements to
multiple resources, though single requirements can be manually scheduled to crews as well.
Without crews , dispatchers can schedule the same requirements multiple times manually by using the schedule
board (or with the schedule assistant), but that takes more time. If your scenario involves assembling resources
together for one job, and then disbanding everyone, crew scheduling is not applicable.
Scheduling a crew automatically creates bookings for all crew members; rescheduling bookings will reschedule all
crew bookings according to cascading settings on the bookings.
In this topic, we'll walk through how to use resource crews, and then explore a few additional considerations.

Prerequisites
Field Service v8.0+
Universal Resource Scheduling v3.0+

Instructions
1. Create a "crew" resource type
A crew consists of a crew resource. The crew resource serves as a container for the crew, and child resources who
are the members of the crew for a given time frame.
To create a crew resource, navigate to Universal Resource Scheduling > Resources > +New and set the
resource type to Crew .
On the General tab, assign a Name .
You can also assign a Crew Strategy. Crew strategy determines how the crew manages its work. There are 3
options:
Cascade and Accept Cascade Completely : All resources on a crew can manage all the work. This is useful
when a crew is made up of one user and the rest of the crew is equipment.
Crew Leader Management : A designated person (or persons) can manage the work of a crew. This is useful
when a crew is made up of multiple users. You can designate more than one person to be a leader and manage
the work.
Crew Member Self-Management : Resources can manage their own work. This is useful when a crew is made
up of users who regularly work together, but may not always work together at the same place or time. Self-
management also means better time capturing, which is good for organizations who bill for time spent on work.

NOTE
Crew strategies affect if and how a crew booking is rescheduled. For instance, if a crew leader's bookings are moved, then all
bookings are moved.

On the Common tab, set the Star t and End Locations .


Note that start and end location must be the same and can be set to either:
Location Agnostic , meaning the crew only appears as a schedule assistant option for location agnostic
requirements; related bookings will not include any travel time.
Organizational Unit Address , meaning the crew shows as available for onsite work; however, routing and
travel times are calculated at the individual level based on each crew member's start and end location. The
organizational unit must be geocoded.
2. Add resource children to the crew
Now that the crew resource exists, we will relate other bookable resources to the crew as crew members. First,
create the bookable resources and set up the profile to include working hours, characteristics, start/end location,
etc.
Then from the crew header, navigate to Related > Resource Children to link each bookable resource as a child
resource to the crew.
This is set up on the bookableresourcegroup entity.

Add a Date Range to indicate when each resource will be part of the crew. It can be variable for each resource.
3. Add the crew to the schedule board
Crew members are also visualized on the schedule board as any resource would be.
Add crews to the schedule board by manipulating schedule board filters to match the service territory, roles,
business unit, characteristics etc. of the crew header. Or, manually add the crew to the board from Options >
Select Resources .

For example, if a schedule board is filtered to show resources for the Washington territory, and the crew header
resource is part of that territory, it will be displayed. This is true even if resource children are not part of that
territory.

Crew resources have a different resource cell layout on the schedule board. You will notice a different icon and a
resource count indicating how many resources are in the crew during the range displayed on the schedule board.
On the hourly list view, you can expand the crew resource to see the members of the crew.

For the time range a resource is part of a crew, there is a grey area displayed on the board. This serves to:
1. Remind dispatchers and resource managers that the resource is part of a crew.
2. Understand that moving their bookings will likely affect other bookings because crew bookings are kept in sync
unless specified otherwise.
3. Understand that scheduling a job to the resource without the crew will likely affect the crew’s ability to be
matched for future jobs.
4. Manually schedule the crew
Dragging a single requirement to the crew header resource will create a booking for the crew header resource,
along with all child resources that are associated to the crew during that time and are working for the full duration
of the booking. Bookings will not be created for child resources that are not working.
Note that requirement groups can't be manually scheduled to crews; only single requirements can be manually
scheduled.

5. Schedule the crew with the schedule assistant (single requirement)


When using the schedule assistant, each crew member can appear in results as non-crew individuals; if booked,
only that single resource will have a booking. The crew resource can also return in the results if the working hours
and other constraints match up. If a crew resource is booked though the schedule assistant, all crew members will
be booked along with the crew.
If you select the crew resource itself and book the crew, the crew and its members will all be booked.
6. Schedule the crew with the schedule assistant (requirement group)
The primary use case for scheduling crews is when you have a set of requirements that need to be done together.
Therefore, a crew, which consists of multiple resources, may be a perfect fit.
The schedule assistant can return a both a group of individual resources and a crew to complete a requirement
group.

When the schedule assistant searches, it assembles a team of resources in which there is a relevant resource for
every requirement in the requirement group. The crew resource itself is just a container and is not considered a
resource when it comes to matching. Each individual resource needs to match with a requirement in the
requirement group.
The ideal scenario would be matching three requirements to a crew of three resources.
As you can see in the preceding screenshot, the entire crew is presented as an option to book, along with additional
non-crew options like teams.
If you expand the crew, you will see that each member of the crew matched with a requirement within the
requirement group being scheduled.
When the crew is selected and booked, each booking for each crew member will relate to the requirement that they
were matched to, and will also relate to the requirement group. The crew resource gets a booking as well to make it
easy to manage the crew as a single unit.

NOTE
Scheduling a crew can be better than scheduling a collection of individual resources because crew members work with each
other frequently; this can boost productivity.

More crew members than requirements


A crew with more resources than needed by the requirement group will show as a result in the schedule assistant,
but lower in the search results because it is less optimal.
For example, the requirement group may have two requirements, but there are no combinations of resources that
can be assembled to handle the work. Therefore, a crew of three resources can be presented as an option to book.
Below are the results showing a crew with more resources than required.
Additionally, there's a column called Excess resources that shows how choosing this team will book more
resources than you need.
When you expand the crew, it separates the resources that are not matched for any requirement into a separate
section called Non-Matching Resources , making it easy to separate the required resources and those who will be
considered extra for that job.
By default, the schedule assistant results are sorted by Fewest Resources First , followed by earliest start time. If
there are teams that can be assembled for the requirement group that only consist of two resources, the crew will
not show until the end of the results.
You can change the sort order in the schedule assistant filter panel by choosing Earliest Time First , creating a
higher likelihood of seeing a crew with excess resources.
NOTE
When you book a team or crew with excess resources, all of the bookings will link to the requirement group, but the
bookings for non-matching resources will not have a link to a requirement.

Fewer crew members than requirements


Sometimes when searching for availability, the crew may need additional resources in order to meet the
requirements. For example, the crew may have three resources, but the requirement group has four requirements.
The crew can be combined with resources outside the crew.
The schedule assistant will combine crews and individual resources to fulfill a requirement group and even note
which resources are part of the crew.
7. View crews and related bookings on the schedule board
Once a crew has been scheduled, there are scenarios where you may want to drill in and see the entire crew
together at once. By default, each resource is still listed individually on the schedule board. If you want to drill into a
crew, right-click the crew resource and select View Crew Resources in Split View .

This will split the schedule board into two boards. The top board is the same board you were on before, and the
bottom schedule board shows only the crew and crew members.

Filtering and sorting with split view


Filtering only applies to the main schedule board and not the Split View. Sorting will apply within each schedule
board. However, the crew header resource will always remain on top in the split view regardless of the sort.

Configuration considerations
Location of crew and crew members
The schedule assistant needs to understand the starting and ending location of resources when it books onsite
requirements for Field Service. Crew member locations are taken from their individual resource profiles and not
from the parent crew. It's important that you change the location of the crew member resource if a resource jumps
between crews. For example, if you want a crew to meet at a central location in the morning to travel together,
specify start/end location as organization unit address for the crew header resource and the resource children crew
members.
Resource type filter on requirements
The resource type filter on a requirement controls which resources can be searched as part of the schedule
assistant search. If no values are set, then all resources can be searched. If only “Crew” is selected, then only
members of a crew can return in the results. The option “Crew” will be renamed to “Crew Member” in an update to
help articulate the meaning better. This also applies to Resource Scheduling Optimization.
If both crew and user are selected, then only resources that are set to resource type “User” or are a member of a
crew can be searched.

Auto group type


Scheduling single requirements to crews
When a single requirement is booked to a crew (regardless if manually or with the schedule assistant), a
requirement group is auto created and all bookings are related to the requirement group. This ensures that crew
bookings are in sync when moved/rescheduled/canceled.
However, only the crew header resource is linked to the single requirement in the newly created requirement
group.

Additionally, the newly created requirement group is tagged with an Auto Group Type of “Crew” .
Rescheduling crews
Consider the crew strategy when rescheduling or editing crew bookings:
Cascade and Accept Cascade Completely : any change to the booking affects everyone's bookings.
Crew Leader Management : only the designated leader or leaders can make changes on bookings. If a leader
changes a booking, everyone's booking changes. Individual team members cannot change bookings.
Crew Member Self-Management : All crew bookings are independent of one another, and bookings are not
kept in sync across the crew. When the crew is scheduled, each crew member gets scheduled, but can change
their own bookings regardless of others' work.

Additional notes
Attempting to book a resource that is par t of a crew
If you select a resource that is part of a crew, a warning message will be presented warning the scheduler that this
resource is part of a crew, so it may impact the crews ability to handle future jobs.
Multiday schedule boards not suppor ted for crews
Daily, weekly, and monthly schedule boards do not have specific support for crew scenarios.
Facility scheduling with Universal Resource
Scheduling
8/14/2019 • 18 minutes to read • Edit Online

Universal Resource Scheduling (URS) enables organizations to schedule interactions between customers and
company resources. For scenarios where the customer is expected to travel to the company's location, the facility
scheduling feature can coordinate physical spaces and related resources.
Typical examples include:
Reser ving a physical space
Reserve a room for an event or party
Reserve a room for an exercise class
Reserve a bay at a mechanic shop
Reserve a boat
Reser ving an appointment with a person at a facility
Laptop repair at a Microsoft retail store
Wealth management consultation at bank branch
Doctor's office with related nurse and doctor
In this topic, we'll explore a few example scenarios using facility scheduling, and describe how it's used in each.

Prerequisites
Universal Resource Scheduling (URS) v3.0
Field Service v8.0 (for work orders, if applicable)
In general, to use facility scheduling, an administrator must create a facility resource (with or without additional
related resources), configure a requirement that calls for facility resources, book the requirement, and view facility
resources and booking(s) on the schedule board.
Let's consider five scenarios to describe facility scheduling:
1. Schedule a facility
2. Schedule a facility with 5 generic rooms
3. Schedule a facility and related resource
4. Schedule a facility with 5 specific rooms
5. Schedule a facility with 5 specific rooms and 5 related resources

Scenario 1: Schedule a facility


In this scenario, schedulers want to search for nearby doctors' offices and schedule an appointment for a patient to
arrive at the doctor's office.
We will configure this scenario by creating a facility resource to represent the doctor's office, creating a
requirement to represent the patient's request for an appointment at a nearby facility, and then booking the
appointment and viewing the facility and booking on the schedule board.
1. Create a facility resource
First, navigate to Universal Resource Scheduling > Resources and create a facility resource with the following
attributes.

1. Resource Type = Facility


2. Star t/end location = Organizational Unit Address
a. Since a facility represents a physical space, the fields "start location" and "end location" must be set to
Organizational Unit Address.
b. The parent organizational unit must have a latitude and longitude that represents the location of the
facility. This allows the schedule assistant to consider the Facility’s location when displaying available
results.
3. Display on Schedule Board = Yes
4. Enable for Availability Search = Yes
5. (Optional) Enter working hours
6. (Optional) Add related characteristics, territory, resource roles, etc. to distinguish facility resources from other
facilities and resources. For example, if a doctor's office has X-ray equipment, "X-Ray" can be added as a
characteristic to the facility resource. This can influence which facility resources are filtered and displayed on the
schedule board or which facility resources are returned during a schedule assistant search.

2. Create a requirement for a facility


Next, create a requirement that calls for a facility resource.
Navigate to Universal Resource Scheduling > Requirement Groups > +New . Configure the following fields.
1. Enter a Name
2. Enter From and To dates
3. Set a Duration
4. Highlight the requirement and select Open Form , then set the Resource Type field to Facility , which
accomplishes the following:
a. It filters schedule assistant results by only showing resources with the chosen types (User, Account,
Contact, Equipment, Pool, Crew, or in this case, Facility ).
b. This means the requirement requires a facility resource to be fulfilled and ensures the schedule assistant
search results return facility type resources (as opposed to personnel or equipment).
c. It maps to the resource type field on the resource entity.
d. Note that if this field is left empty, all resources are searched.

5. Set Work Location to Facility , which means:


a. The interaction will take place at the scheduled facility and factors into travel time and distance
calculations. Find more details in the configuration considerations section of this article.
6. Enter latitude and longitude .
a. These values are typically entered manually or through workflows.
b. These values represent the customer's location and are used to display facilities relative to the customer's
location in schedule assistant results. This is not the facility's location, as that is taken from the
organizational unit of the facility type resource.

3. Book the requirement


After creating a facility resource and a requirement that calls for a facility, you can schedule the facility.
Requirements that are part of a group can be scheduled via the Book button to trigger the schedule assistant, but
not through drag and drop. Facility requirements not part of a group (single requirements) can be manually
dragged and dropped to a facility on the schedule board or by using the schedule assistant.
The schedule assistant considers availability of resources as well as other set requirement constraints, such as
characteristics, organizational units, categories, etc.
Select Book from the requirement or requirement group form, as seen in the following screenshot.
Facility travel time and distance calculations in the preceding schedule assistant example represent the time
and distance between the facility resource (as defined by the location of the related organizational unit) and the
customer's location (as defined by the latitude and longitude values on the requirement). The schedule assistant's
radius filter filters based on this travel calculation.

Filtering work location to location agnostic will remove travel time and distance calculations from schedule
assistant results.
4. Add the facility resource to the schedule board
Scheduling a facility is just like scheduling any other resource. You can drag and drop requirements to create
bookings; you can drag existing bookings to change the time or resource; or you can use the schedule assistant to
help sift through the list of facilities based on availability and other constraints.
To view facility resources on the schedule board, filter by resource type and/or organizational units.
Facility resources will also be displayed on the schedule board map based on the location of the related
organizational unit.

Scenario 2: Schedule a facility with 5 generic rooms


In this scenario, a doctor's office has 5 identical rooms and schedulers don't need to book each room specifically.
They must, however, ensure that no more than 5 patients are booked across all rooms during any one time slot.
We will configure this scenario by adding a capacity to a facility resource.
1. Create a facility resource
See scenario 1 in this article to create a facility resource, or select an existing facility resource record.
From the facility resource record, select Show Work Hours in the top ribbon.
2. Set the capacity of the facility resource
When choosing hours, select Show Capacity and enter 5 . By default, the capacity is set to 1.

Setting the capacity to 5 means that when booking a facility with the schedule assistant, the facility resource will
show as available and can be double-booked up to the capacity limit (in this case, 5 times).

In the preceding screenshot, two separate requirements for a facility were both scheduled to the same facility
during the same time slot. Without increasing the capacity, once a timeslot at a facility is booked, it will no longer
show in schedule assistant results.
NOTE
Capacity scheduling is not intended for booking the same requirement multiple times, but rather to book multiple
requirements. Rebooking a previously booked requirement will cancel the existing booking and create a new one.

Scenario 3: Schedule a facility and related resource


In this scenario, schedulers want to schedule a doctor's office and a related doctor at the same facility during the
same timeslot.
This scenario is configured by creating a facility resource, creating a doctor resource (a resource with resource type
= user/contact/account), associating the doctor resource to the facility resource, and then creating a requirement
group that calls for both a facility and a doctor.
In order to schedule groups of resources to perform a task together at a facility, non-facility resources can be
associated to facility/facility pool resources through the Resource Associations entity
(msdyn_bookableresourceassociations) .
Resources such as people, equipment, or pool resources may be associated to a facility or facility pool with date
effectivity. This means resources will perform work at the facility location during the expressed date range, and they
are not eligible for “onsite” work for which they would have to leave the facility and travel to a customer's location.
This is extremely important as it relates to using the option Same Resource Tree .
1. Create a facility resource
First, create a resource to represent the doctor's office. The resource type should be set to Facility . The following
screenshot shows an example of a facility resource.

2. Create a doctor resource


Create a resource to represent a doctor. Set the resource type to User, Account, or Contact , based on your
business needs.

NOTE
The user resource type is typically designated for employees who access Dynamics 365 data; contact and account resource
types are typically for contractors who need to be scheduled but don't access data.

Start/end location should be set to Organizational Unit Address and the organizational unit should be set to the
same organizational unit of the facility resource (in this case, the doctor's office). This is recommended but not
required .
3. Associate the doctor resource to the facility resource
From the facility resource, navigate to Related > Bookable Resource Association (Resource 2) . This related
entity is called Resource Associations (msdyn_bookableresourceassociations ).
From here, associate the resource that represents the doctor.
In the following screenshot, Abraham McCormick represents a doctor and is associated to "Doctors Office North
Seattle," which represents the doctor's office.

4. Create a requirement group


Next, create a requirement group with one requirement that calls for a doctor's office (Resource Type = Facility), and
another requirement that calls for a doctor (Resource Type = User/Contact/Account).

Set the Work Location on each requirement to Facility , indicating the work will take place at the doctor's office.

NOTE
Using the Select > All option in the requirement group means that both requirements need to be fulfilled.
Set Par t of Same to Resource Tree . This ensures resources from different locations are not recommended for
work taking place at a facility. As an example, a doctor associated with Facility B should not be paired with Facility A.
Find more details about this setting in the configuration considerations section of this article.

Scheduling the requirement group creates a booking for the facility resource and the doctor resource.

NOTE
As in scenario 1, travel time and distance are calculated as the time and distance for the customer to travel to the facility.
There is no travel calculation considered for the doctor resource, as it's assumed he/she will be at the facility at the required
time.
Scenario 4: Schedule a facility with 5 specific rooms
In this scenario, schedulers want to track all rooms within a doctor's office and schedule each individual room to
patients.
This scenario is configured by creating a pool of facilities to represent the doctor's office and each individual room.
1. Create a facility pool resource
First, create a resource to represent the overall doctor's office where Resource Type = Pool and Pool Type =
Facility .
In this example, we call it "Health Clinic," as seen in the following screenshot.

2. Create facility resources to represent each room


Next, create multiple facility resources to represent each room.
Set Resource Type to Facility on each resource.
Set the Star t/End Location to Organizational Unit Address and select an organizational unit to represent the
location of the rooms.

3. Add each room resource as a child resource to the doctor's office resource pool
Navigate to the doctor's office facility pool resource, and go to Related > Resource Children .
Add each room resource as a child record to the parent facility pool (health clinic), as seen in the following
screenshot.
4. Create a requirement group
Create a requirement that calls for one or more facilities. In this example, we're looking for 2 specific rooms within
the same doctor's office (health clinic).
Set Par t of Same to Same Location to ensure each room is at the same physical address.

Each requirement should call for facility resource types, as seen in the following screenshot.
Again, the Work Location of each requirement should be set to Facility and the latitude and longitude fields of
the requirements should correspond to the customer's (or patient's) location.

NOTE
Latitude and longitude fields on all requirements within a group must be equal; updating the values on one requirement will
update the others.

5. Book the requirement group


Select Book from the requirement group to trigger the schedule assistant.
In the preceding screenshot's results, two specific rooms are recommended at the same location. The travel time
and distance is calculated from the customer's location (latitude and longitude values on the requirement records)
and the location of the facility resources (resource children organizational units).

Scenario 5: Schedule a facility with 5 specific rooms and 5 related


resources
In this scenario, schedulers want to schedule specific rooms within a doctor's office to a pool of available pediatric
doctors who work at the health clinic.
This scenario is configured by creating a pool of facilities and a pool of doctors, and associating them together with
Resource Associations (msdyn_bookableresourceassociations ).
1. Create a facility pool
Using the same process we used in scenario 4, create a facility pool resource to represent the doctor's office.

2. Create facility resources for each room


Next, create facility resources to represent each room in the doctor's office facility pool.
Then add each room as a resource child to the doctor's office (health clinic) facility pool resource. The
organizational unit of the office facility pool and the room facilities should be the same.

3. Create a pool of pediatric doctors


Create a new resource pool to represent the pediatric doctors.
Set Resource Type to Pool and set Pool Type to Contacts, Users, Accounts , as doctors are personnel.
As is true of all resource records, you can add characteristics to define and distinguish differences among resources.
In this example, "pediatrics" could be a skill to add to a doctor resource.
Set Derive Capacity from Group Members to Yes . This means the capacity of the pool is based on how many
doctors are associated to it.

Create resources to represent doctors and add them as resource children to the pediatric doctors pool.
5. Associate doctor pool to facility pool
Next, navigate to the original facility pool (health clinic), and go to Related > Bookable Resource Association .
Set the Resource 2 field to the pediatric doctor pool resource, as seen in the following screenshot.

6. Create a requirement group for rooms and doctors


Navigate to Universal Resource Scheduling > Requirement Groups > +New .
In this example, we created a requirement group that calls for two rooms (facilities) and a pediatric doctor.
Setting Par t of Same to Resource Tree ensures rooms and pediatricians are related to same facility resource
through resource children or resource association.
For each room requirement, set the resource type to facility.
The resource types you choose for the pediatrician doctor requirement will affect schedule assistant results.
On the requirement, if Resource Type = Pool and Pool Type = Users, Accounts, Contacts , the
pediatrician pool resource will be displayed in the results, as seen in the following screenshot.

This allows you to book the pediatrician pool and assign a specific pediatric doctor at a later time. Whether
pediatricians show as results will depend on capacity (as derived from the number of doctors in the pool). Using the
pool allows schedulers to book appointments based on capacity without having to assign a specific doctor at the
time of scheduling.
On the requirement, if Resource Type = Users, Accounts, Contacts, (Not Pools) , specific doctor resources
will show in results, as seen in the following screenshot.
NOTE
Use fulfillment preferences to display schedule assistant results in neat hourly timeslots.

Configuration considerations
Choosing the right work location on requirements
Let's take a look at the following work location types:
Facility
On Site
Location Agnostic

Facility work location implies the interaction takes place at the facility and travel time is calculated as the
distance between the customer location and the facility location. The requirement's latitude and longitude
fields are used as the customer location. It also means at least one facility or facility pool must return in
schedule assistant search results in order for a resource(s) to be returned.
On Site work location implies the interaction takes place at the customer location and travel time is
calculated as the distance between the customer location and the resource (typically field technician)
location, which is variable based on the resource's schedule that day. The requirement's latitude and
longitude fields are used as the customer location. As a result, facility resources and facility pools will be
excluded from the results.
Location Agnostic work location implies the interaction takes place remotely and the location of the
customer nor the resource is considered for scheduling. Travel time is not applicable and is not calculated.
Facility resources can still be returned as part of the schedule assistant search, but travel time will not be
displayed or considered in ranking.
"Part of Same" options on requirement groups
Same Location : Same location means that only teams of resources working at the same location will be
returned. This uses the logic expressed in this document to determine the location, using the Resource
Associations (msdyn_bookableresourceassociations) and the Bookable Resource Group
(bookableresourcegroup) entities. Using this option, regardless of which specific facility or facility pool other
non-facility resources may be associated to, all that matters is that the resources are at the same physical
location (organizational unit).
Same Resource Tree : This option adds an extra layer of stringency to the search. It means that the teams
assembled must actually be associated to the same facility or facility pool in order to be returned as a team.
For example, let’s assume there is one physical location, Location A.
There are 2 facilities at location A: facility 1 and facility 2. If resource 1 is associated to facility 1, and "Same
Resource Tree" is selected, the one team that can be assembled is facility 1 + resource 1. Facility 2 and
resource 1 cannot be returned. This combo could however be returned if “Same Location” is the only option
selected.
It works the same with facility pools. Let’s assume there is one physical location, Location A. At location A are
2 facilities, facility 1 and facility 2, as well as a facility pool (facility pool 1). If resource 1 is associated to
facility pool 1, and “Same Resource Tree” is selected, the one team that can be assembled is facility pool 1 (or
one of it’s child facilities) + resource 1.

NOTE
If neither of these two options are selected on the requirement relationship (msdyn_requirementrelationship), and work
location is set to facility, the schedule assistant search will execute as if “Same Resource Tree” was selected.

Same Organizational Unit : An even more stringent option is same organizational unit. This option
ensures that the parent organizational unit of the resources are the same. It does not check the bookable
resource group or the bookable resource association entity. It only checks the parent organizational unit.
If your implementation uses requirements that are location agnostic, this option may be used without either
of the other two options; however, it completely ignores the two aforementioned entities (associations and
groups). This could work in a simple implementation where resources are always staffed at the same
location, and you do not need the advanced location search functionality of the work location “facility.”

NOTE
The Par t of Same field schema name is msdyn_requirementrelationship

When to use "facility with capacity," "multiple facilities," and "facility pool"
Facility with capacity : this option is configured by adding a capacity to a single facility. It's most useful
when schedulers care most about not overbooking, and either don't need to schedule specific facilities or can
handle coordination in person when customers arrive at the facility.
Multiple facilities : this option is configured by creating multiple facility resources and relating them to
each other through an organizational unit. This option makes the most sense when each facility needs to be
scheduled individually.
Facility pool : this option is configured by creating a facility pool and adding facilities as pool members. This
option makes the most sense when schedulers want to (1) utilize capacity scheduling by having the facility
pool capacity increase and decrease as facilities are added or removed and (2) use local scheduling where
bookings are first assigned to the facility pool and then later assigned to pool members. Example: a hotel
(facility pool) is first scheduled for a weekend and travelers are assigned specific rooms (facility pool
members) at a later date when they arrive.
When upgrading from Field Service v7.x to v8.x, facility type resources may not appear in schedule assistant
results due to default filter settings. To fix this, go to Field Ser vice > Schedule Board . Double-click on a
schedule board tab, and then Open Default Settings in the upper right. Scroll down to Other Settings .
Set Retreive Resources Quer y to 3.0.0.0 as seen in the following screenshot. Filter Layout and
Resource Cell Template should also be set to 3.0.0.0.

Additional notes
For requirements that are not part of a requirement group, only facility or facility pool resources can return in
the schedule assistant if Work Location is set to Facility .
A resource can't be related to two facilities (child or association) at the same time.
There is currently no specific way to visualize every resource related to a facility on the schedule board. The
closest way to achieve this is to filter by organizational units.
Manually scheduling a single requirement to a facility will not create records for all resources related to the
facility.
Facility pool location
The location for a facility pool is taken from the parent organizational unit. If a facility resource is a member of a
facility pool, the location of the facility is taken from the pool resource. For example, if you create a facility with a
location/organizational unit of location A , and you add this facility to a pool, which is located at location B , the
facility will be considered as located at location B for as long as it remains in the pool.
Booking location
When a team is selected and booked, the latitude and longitude of the booked facility/facility pool's location will be
stored on the booking record. The work location will also be set based on the work location used when booking in
the schedule assistant. In the following conditions, the work location, latitude, and longitude will still be set on the
booking:
If bookings are created without using the schedule assistant
If the requirement's work location is set to facility
There are latitude and longitude values on the requirement
Resource pools
8/14/2019 • 18 minutes to read • Edit Online

Resource pool scheduling allows you to assemble groups of similar resources to manage capacity and give
schedulers the option to assign specific resources at a later time.
Resource pool scheduling is useful for several scenarios, including:
To avoid being forced to book specific resources up front, and instead book the “resource pool” while
ensuring no over-commitment. For example, a hotel must search for generic room availability, but travelers
are not assigned a specific room until they arrive at the hotel.
To shield central schedulers from details, and leave those details to a local resource manager. For example,
customers make laptop repair appointments by calling a central dispatch service, who books appointments
at Microsoft Retail stores countrywide. Each morning, the manager of the local store assigns specific
specialists.
Specific resources may not yet be named, but capacity of the pool is established. Schedulers can still
schedule since capacity of the pool can be set as if all the resources were named. For example, a tradeshow
offers different booth options to sponsors. Capacity of booths is considered when booking, but specific
booths will be confirmed later. Organizers can take reservations well in advance of having a defined floor
layout; the layout may even be decided based on how many reservations there are.
To deliberately enable overbooking for expected cancellations. For example, a doctor's office has a fixed
number of rooms to help patients, but may inflate capacity and schedule more appointments than rooms in
order to account for cancellations.
In this topic, we'll walk through 2 hypothetical scenarios to explain resource pool scheduling:
1. Schedule a pool, then assign specific resources later
2. Overbook a pool for expected cancellations

Prerequisites
To use resource pool scheduling, you'll need Universal Resource Scheduling (URS) v3.0.

Scenario 1: Schedule a pool; assign specific resources later


In our first scenario, the office staff at a health clinic wants to book patient appointments with pediatricians. Because
there are five pediatricians working each day, the office staff must ensure that no more than five appointments are
scheduled during any single time slot. However, though appointments are booked weeks or even months in
advance, specific pediatricians are not assigned to an appointment until the day before because of variable
schedules.
To accommodate this scenario, we will create a pool to represent the pediatricians, schedule appointments to the
pediatrician pool, and then reassign appointments to specific doctors within the pool.
Step 1: Create a resource pool
1. From either the Field Service or Universal Resource Scheduling solution, go to Resources > Active Bookable
Resources view > select +New .
2. Set Resource Type to Pool . A new field will appear called “Pool Type.”
3. Set Pool Type to Account, Contact, User because this pool will consist of people resources (pediatricians, in
our example).
a. Note that pool types can either be set to: Facility, Equipment, or any combination of
Account/Contact/User.
b. We recommended creating homogeneous pools. Since you may not be naming specific resources at all,
set up pools in a way that the resources who are named later can actually fulfill the backlog of work
scheduled to the pool. For example, if you schedule a “facility” requirement to a pool, the pool should
consist of of facility resources who can later be assigned.
4. Enter a Name .
5. Select a Time Zone .

6. Set Star t Location and End Location to Organizational Unit Address , and assign an organizational unit
with latitude and longitude values because the pediatricians work at a defined health clinic.
a. Start and End Locations can be set to either Organizational Unit Address to represent a physical
location where the pool works, or Location Agnostic for a pool of resources that will perform work
remotely (for example, customer service phone calls). Resource address is not an option, as pools are
currently excluded from Onsite scheduling (requirements where Work Location is set to Onsite).
7. Set Derive Capacity From Group Members to Yes .
a. Setting to Yes : Capacity will increase and decrease as pool members are added to or removed from the
pool. In our example scenario, we set to "yes" because it allows us to add 5 pediatricians to the pool in the
next step. This also allows the pediatrician pool to be booked up to 5 times for any single time slot.
b. Setting to No : The capacity of the pool will default to one and can be manually edited. Pool members
can still be added and removed. See scenario 2 in this article for more details.
8. Add more pool resource attributes.
a. You can add any additional information about the pool that you would like considered when it comes to
scheduling. Consider the pool as a standard resource as it relates to adding skills, roles, organizational
units, territories, and so on. For example, if you have a requirement that requires “skill A,” when searching
for availability using the schedule assistant, only pools with “skill A” will be considered.
Step 2: Add pool members
Members can be added to a pool through the bookable resource group entity (bookableresourcegroup).
1. From the pool you just created, go to Related > Resource Children .
2. Select +Add New Bookable Resource Group , and:
a. Assign a Name .
b. In the Resource 2 field, select the resource you would like to add to the pool.
c. Select a Date Range during which the resource will be part of the pool. This will effect capacity if the
pool is set to derive capacity from pool members.
d. Repeat these steps for each pool member.

NOTE
Resources can be associated as children of the pool with date effectivity. For example, on Monday, Resources 1, 2, and 3 can
make up the pool, while on Tuesday, resources 4, 5, and 6 can make up the pool. To do this:
1. Create a new bookable resource group record.
2. Set the parent resource to the pool, and the child resource to the resource that is in that pool.
3. Set the From Date to the date and time that the resource is part of the pool and set the To Date to the date and time
when the resource is no longer associated to the pool.

Step 3: Add the pool to the schedule board


1. Next up, go to Universal Resource Scheduling > Schedule Board .
2. Add the pool resource by adjusting the schedule board filters the same way you would add any resource to the
schedule board.
a. In this example, we select Resource Types of Pool and Pool Types of Account, Contact, User
because this matches our pediatrician resource pool.
3. Right-click the resource pool and select View Resources in Split View to see the pool and pool members.
4. Select Options > Save Current Filters as Default to save the changes made to the schedule board tab for
the next time you visit.
Step 4: Create a single requirement
Now we will schedule a requirement to our newly created resource pool.
1. Go to Universal Resource Scheduling > Resource Requirements > +New .
2. Enter a Name .
3. Select a From Date and To date . These values become Search Star t and Search End dates in the schedule
assistant.
4. Enter a Duration .
5. Set resource type to Pool and Pool Types to Account, Contact, User . This ensures our pediatrician pool
shows in results.
a. This also allows you to decide which types of resources should be searched when searching for
availability using the schedule assistant on a requirement. If this field is left empty, all resource types are
searched. If certain values are selected, then only those resource types are considered.
6. Add other constraints like as characteristics. In this example, we want resources with "Pediatric" skills, as seen in
the following screenshot.

NOTE
In our example, the requirement group field on the requirement record is blank. This means that this is a single requirement
intended to be scheduled to one resource. One benefit of single requirements is that they can be scheduled and rescheduled
by manual drag and drop. This is useful if dispatchers want to manually reschedule bookings from a pool to a pool member.
Step 5: Book the pool
1. Select Book at the top of the requirement form to trigger the schedule assistant.

2. When searching for availability for a requirement or requirement group, both the pool and its child
resources (pool members) can be returned in the results.
3. Select the pool resource and a time slot (in this example, our pediatrician pool and the 9AM - 10AM time
slot), and select Book & Exit .
Step 6: Book more requirements to the pool
Since a pool can be booked multiple times up to defined capacity, now we'll create another requirement and book it
to the same time slot.
The following screenshot shows a near identical requirement for another pediatrician that we will book to our pool.

We will select the same resource pool as we did in step 5, and the same time slot at 9 AM to 10 AM.
The resource pool will show as a result in the schedule assistant for the 9 AM time slot up to five times since five
pediatric resources were added to the pool making the capacity five.
Next, head to the schedule board and then to the schedule board tab where your pool resource is displayed.
Load the Hourly Schedule Board and find your pool resource. Right click the Pool Resource and choose to View
Pool Resources in Split View . This will split the Schedule Board and a new dedicated Schedule Board will be
displayed showing just the Pool and its members. Based on the dates being displayed on the Schedule Board, only
the members of the pool with membership during that date range will appear in the Pool Schedule Board. If a
resource is part of the pool for only some of the days being displayed on the Schedule Board, they will be
displayed, and there will be a mask showing the days where they are not part of the pool.
Here we see five bookings at the 9:00am time slot.
NOTE
The Schedule Board sor ting functionality applies to the split view, but the Schedule Board filtering functionality does not.

Step 7. Reassign pool bookings to specific pool members


Fulfilling our scenario, the health clinic office staff members want to assign specific pediatric doctors as an
appointment nears.
From the schedule board split view, we will accomplish this three ways:
1. Manually drag and drop : Select and drag a booking from the resource pool and drag it to one of the pool
members.
2. Substitution : Right-click a booking for the resource pool, select substitute resource, then select a pool member.
3. Rebook : Right-click a pool booking and select Rebook . Edit the filter criteria to no longer search for pools, but
to search for Contact, User, and Account type resources.
When rebooking a previously fulfilled booking, the duration will default to the default booking duration as defined
in Universal Resource Scheduling > Settings > Administration > Enable Resource Scheduling for
Entities > Booking Setup Metadata .
Therefore, as seen in the following screenshot, you must edit the end time to match the original duration.

Finally, cancel the original pool booking.


NOTE
You can also create a custom booking status to match your business needs, rather than changing the status to cancelled.

As an alternative to rebooking from the schedule board, go to the requirement record, edit the resource types, and
book again.
Scenario 2: Overbook a pool for expected cancellations
In our second scenario, hotel managers want to make reservations for travelers by first checking for specific date
range availability, and then assigning the traveler a specific room when she arrives. Furthermore, hotel managers
want to overbook the hotel to account for expected cancellations.
To accommodate this scenario, we will create a pool of facilities with extra capacity to represent the hotel rooms,
schedule reservations to the hotel pool, and finally reassign reservations to specific rooms within the hotel pool.
Step 1. Create a pool resource
First we will create a pool resource to represent the hotel.
1. From the Field Service or Universal Resource Scheduling solutions, go to Resources > Active Bookable
Resources view > and select +New .
2. Set Resource Type to Pool .
3. Set Pool Type to Facility .
4. Enter a Name.
5. Set Star t Location and End Location to Organizational Unit Address .
6. Assign an Organizational Unit from the lookup to represent the location of the hotel.
a. The selected organizational unit must have latitude and longitude values.
7. Set Derive Capacity from Group Members to No .
a. This time, we manually override capacity to allow for overbooking, rather than have the number of
facilities in the pool (for instance, the number of rooms in the hotel) dictate capacity.
Step 2. Create and add pool members
1. Create resources with Resource Type set to Facility to represent each room in the hotel.
2. Go to the hotel pool resource you created in the previous step and add each room resource as a child by
selecting Related > Resource Children .
Step 3. Manually add additional capacity
1. While on the hotel pool resource, go to Show Working Hours at the top of the form.
2. Select Show Capacity .
3. Enter the desired capacity. In this example, we use a capacity of six though our pool has only five child resources
(in other words, five rooms).

Step 4. Create requirement


Now we will create a requirement to represent a reservation for a traveler.
1. Go to Universal Resource Scheduling > Resource Requirements > +New .
2. Fill out Name , Date Range , Duration , and any other constraints.
3. Set Resource Type to Pool .
4. Set Pool Type to Facility .
a. This ensures our hotel pool will be considered in schedule assistant results.
5. Set Work Location :
a. In our hotel booking example, work location is set to Facility , which means the requirement takes place
at a physical space (the hotel). In order to show facilities relative to the customer's (traveler's) location, a
latitude and longitude can be entered on the requirement to represent the customer's location. As a
reminder, we set the hotel's location when we set up the pool resource. These settings are useful in
scenarios where the hotel may have many locations and the scheduler wants to use time and distance
calculations when communicating to the customer.
b. If schedulers don't need travel or distance information about the customer, set to Location Agnostic
and leave latitude and longitude blank.
c. For more information on the Work Location field, visit our topic on facility scheduling.

Step 5. Book requirement


Select Book at the top of the requirement form to trigger the schedule assistant. Up to six requirements
(reservations) can be booked for a single time slot.
The schedule assistant results in the following screenshot assume five reservations have already been scheduled to
the hotel, and the scheduler is attempting to book a sixth reservation as extra capacity.

Step 6. View overbooking on the schedule board


1. Go to Universal Resource Scheduling > Schedule Board .
2. Expose the hotel pool to the schedule board by filtering for Resource Types of Pool and Pool Types of
Facility .
3. View the hotel pool and all related pool members (rooms) by right-clicking the hotel pool resource and selecting
View Pool Resources in Split View .

Step 7. Reassign bookings


Reassign the hotel pool bookings to specific rooms with the three methods described in scenario 1:
1. Manually drag and drop
2. Substitution
3. Rebook

Configuration considerations
Resource pools will not display in schedule assistant results for requirements where Work Location =
Onsite . By default, work order-related requirements are set to onsite. Only requirements with a Work
Location = Facility or Location Agnostic will show up in schedule assistant results.
Crew resources and pool resources cannot be made children of a pool.
Location of Pool Members : If a resource is the child of a pool through a bookable resource groups
(bookableresourcegroup) record, the location of the child resource is taken from the pool. Additionally, if a
resource pool is related to a facility or facility pool resource through bookable resource association
(msdyn_bookableresourceassociation), the location is taken from the facility or facility pool.
When a pool resource has Derive Capacity from Group Members set to Yes , the pool's capacity for a
given time slot is effected by:
the number of pool members
the dates the pool members are part of the pool and
the working hours of the pool members
Choosing the right resource type
Whether the pool resource, pool members, or both show in schedule assistant results depends on the resource
types selected on a requirement record. If the resource type Pool is selected, and if the resource pool has
availability along with all other matching constraints expressed on the requirement, the pool itself can return as an
option to book. If the resource type Pool is not selected on the requirement, pool members can still return in the
results, presuming that the pool member’s resource type is checked off on the requirement. If no resource types are
selected, all resource types are considered.
For example, consider a requirement that only has resource type Account selected, a resource with resource type
Pool , and pool type of Account, Contact, User . In this example, the pool resource itself will not be returned in the
schedule assistant search, but the child pool members (with resource type Account ) will be returned by the
schedule assistant.
Using characteristics with pools
The same logic that is applied to the requirement resource type attribute applies to all constraints. Consider the
following example: a requirement has a required characteristic called Electric Vehicle Mechanic . There is a pool
that has the characteristic Mechanic , but not Electric Vehicle Mechanic . The pool has a child member that has
both the characteristics Mechanic and Electric Vehicle Mechanic .
When running the schedule assistant on the requirement, presuming availability, the pool resource itself will not be
presented to book since it is missing the required characteristic (Electric Vehicle Mechanic ), but the pool
member will be presented since the resource has the necessary characteristic for this job. The reason for this is that
the pool members should have all the attributes expressed on the pool, but they may have additional attributes as
well if they have specialties. Since not all the pool members have these additional attributes, like the Electric
Vehicle Mechanic , if this requirement gets booked to the pool and the one pool member who has this
characteristic is not available as the appointment time nears, what happens? Who will be assigned to this booking
currently booked to the pool? You may not have other resources to pickup the work. Therefore, the idea is to book
the actual resource itself to ensure that this unique job has coverage.

Additional notes
Requirement groups can't be dragged and dropped or substituted
When changing the working hours of a resource, capacity is not recalculated
Pool availability affects member availability and vice versa
Being part of a pool can severely limit a resource's ability to be scheduled. Resources cannot be expected to operate
as part of a pool and independently at the same time. If a pool resource itself is booked to capacity for a given time
slot, pool members will not show as available for that time slot and vice versa. If all pool members are booked for a
given time slot, the pool will not show as available for that time slot.
Example 1: Pool resource only
When searching for availability, the schedule assistant will look at the pool capacity set on the pool resource, and
will subtract existing bookings that are booked to the pool resource itself, or any of the pool’s child resources.
Consider a pool's capacity is set to 10. Let’s also assume there are no child resources for this pool. When finding
availability using the schedule assistant, the pool will be looked at as if there are 10 resources associated to the
pool.
For example, let’s say you are searching for a 30-minute requirement. If the pool has 10 bookings from 10 to 10:30,
the pool will not be recommended for the requirement between 10 AM and 10:30 AM. This is because the total
capacity of the pool at 10 AM is 10, but there are 10 bookings scheduled to this pool resource at 10 AM. However, if
the pool only has 9 bookings between 10 AM and 10:30 AM, then the pool can be recommended.
Example 2: Pool resource and child resources
If the bookings for the pool and its members exceed the total capacity established on the pool, every resource in
the pool and the pool itself is considered unavailable. But if there is overall aggregate availability, then each
resource still has its own availability calculation. For example, consider if a pool resource has a capacity of 10, and
there are 9 bookings between 10 AM and 10:30 AM on the pool resource, and the child resource has one booking
from 10 to 10:30. In this case, since in aggregate the pool and its children have as many or more bookings (10)
than the capacity on the Pool (10), the entire pool and its child resources are considered unavailable for that
timeframe (10:00 AM to 10:30 AM).
However, if the pool resource has 8 bookings and the child resource has 1 booking, since this is a total of 9
bookings, the pool and its child resources will not be removed between 10 and 10:30. In this case, the pool itself
will show as available, however the child resource will not return as available since there is already a booking at 10
AM for the child resource.
Pools vs. crews: when to use each?
One main difference between pools and crews is crews are expected to do work together and bookings cascade (at
least by default). This means scheduling a crew will create bookings for crew members, whereas booking a pool
does not create bookings for pool members. Additionally, crews can be a compilation of different types of resources
such as a person and a piece of equipment. In contrast, pools are designed to be homogeneous meaning entirely
people, equipment, or facilities.
Schedule within time constraints
10/14/2019 • 7 minutes to read • Edit Online

When scheduling a work order, case, quote, or any entity enabled for scheduling, you can set date and time
parameters to control when the requirement is booked.
This is done by entering date and time values on the work order form in the preference section, or similar fields on
the requirement form if you're scheduling entities other than work orders.

For instance, we will consider the following scheduling scenarios throughout this topic:
Scenario 1: Schedule between two dates
An installation work order must be scheduled and is expected to be completed this week.
Example: 9/10/2019 - 9/15/2019
Enter Date window star t and Date window end
Considered by schedule assistant and Resource Scheduling Optimization (RSO)
Scenario 2: Schedule between two times of day
A diagnosis and repair work order must be scheduled before the end of the day tomorrow.
Example: 9:00 AM - 5:00 PM
Enter Time window star t and Time window end
Considered by RSO
Scenario 3: Schedule between two dates and times
An inspection work order should be automatically scheduled for completion in the afternoon some day within the
next two weeks.
Example: 9/10/2019 9:00 AM - 9/11/2019 5:00 PM
Enter Time from promised and Time to promised
Considered by the schedule board, schedule assistant, and RSO
Let's configure these 3 scenarios to understand how dispatchers can schedule work orders within time constraints.

Prerequisites
Any version of Dynamics 365 Field Service.
Understand that Resource Scheduling Optimization considers all date and time parameters, but the schedule
board and schedule assistant do not. See the scenarios at the beginning of this topic to understand which
scheduling methods consider which date and time parameters.

Scenario 1: Schedule between 2 dates


In this scenario, an installation work order must be scheduled and needs to be completed this week.
From the work order, complete the Date Window Star t and Date Window End fields to represent the week the
work order should be scheduled and completed within.

This will automatically populate the From Date and To Date fields on the related work order resource
requirement and vice versa. This is true for the other fields in the Preferences section as well, such as Time
Promised and Time Window .
When attempting to schedule this work order with the schedule assistant - from either the Book button on the
form or from the Find Availability search on the schedule board - these date values will populate the Search
Star t and Search End filters. Resources that are available for the entire duration of the work order within the date
range will display as options.

NOTE
If the current time (time of scheduling) is later than the search start, search start will become the current time because you
cannot schedule a work order in the past.
Scenario 2: Schedule between two times of day
In this next scenario, a diagnosis and repair work order must be scheduled before the end of the day tomorrow.
To schedule based on a date and time, simply complete Time From Promised and Time To Promised on the
work order.

These values will be passed to the related requirement and appear as new filters when the schedule assistant is
triggered.
Time From Promised and Time To Promised implies that the estimated arrival time must fall within the time
range for which the resource has availability for the duration of the work order. This is based on the resource's
working hours, and is not necessarily completed before the end of Time To Promised . This differs from date
window start and end.

Furthermore, when manually dragging and dropping a requirement on the schedule board, a popup will warn the
dispatcher if the estimated arrival time falls within the promised time window or not.

NOTE
Time From Promised and Time To Promised is a continuous time range that does not consider the service organization's
or the customers' working hours. For example, if the time from and to promised is set to 9/10/2019 9:00 AM - 9/15/2019
5:00 PM, then any time during this range is eligible as long as resources are working.

Finally, setting up service level agreements (SLAs) for work orders will populate the time from and time to
promised fields in order to help dispatchers schedule to meet the SLAs.

Scenario 3: Automated scheduling with time parameters (RSO)


In our next scenario, an inspection work order needs to automatically be scheduled in the afternoon within a date
range.
To automatically schedule work orders and other entities, you must use the Resource Scheduling Optimization app
(RSO). Unlike the schedule assistant and the schedule board, RSO will consider all 3 time parameters when
automatically booking work orders to resources.
First, on the work order, set a date range in the Date Window Star t and Date Window End .
Next, set a Time Window Star t and Time Window End that represents a time of day the work order should be
automatically scheduled.
NOTE
For this scenario, we recommend using Date Window along with Time Window rather than Time Promised , as Time
Promised will take priority over the other parameters during optimization.

When setting up RSO, make sure Scheduling Windows is a constraint in the optimization goal you are running
RSO with. For more information, see the topic on RSO configuration. If you're new to RSO, see the RSO quickstart
guide.
After running RSO, you'll see the results on the schedule board. In our example, the work order could have been
scheduled for either 9/12 or 9/13 based on the date window of the work order; whichever day it is scheduled, it
should be scheduled in the afternoon between 12:00 PM and 5:00 PM.

Configuration considerations
Modify calendar
You can define a time zone on the requirement to help dispatchers view schedule assistant results in the time zone
of the customer, and it allows for dispatchers to work in different time zones than the resources. From the
requirement, select Modify Calendar in the ribbon menu, then choose a Time Zone from the dropdown, then
save and close.
When you book the requirement, the start times of the schedule results will reflect the chosen time zone.
Booking rules
Dynamics 365 Field Service can perform custom booking rule validations, called Booking Rules , when creating a
booking with the schedule board or schedule assistant. Booking rules are custom JavaScript functions that run prior
to the Bookable Resource Booking record being created. The JavaScript function can accept a parameter that
will contain information for the Bookable Resource Booking record and must return a JavaScript object with the
required properties.
In the context of scheduling within time parameters, you can create a Booking Rule that performs custom
validation on the date and time fields or even custom date and time fields you create. For example, you could create
a rule that checks if a booking starts on a Monday, Wednesday, or Friday, and if it does not, display an error
message to the dispatcher on the schedule board. For more information, see the topic on booking rules
Scheduling lock options
Scheduling lock options prevent RSO from rescheduling a booking to a different time or resource. From the
booking, simply set a value in the scheduling lock options field.
Fulfillment preferences
Fulfillment preferences let you choose how schedule assistant results are displayed, like with neat hourly
appointments or morning and afternoon time windows. They can help dispatchers schedule work orders during
times that are convenient for the customer. For more information, see the topic on fulfillment preferences.
Booking setup metadata
You can define which fields on the entity enabled for scheduling should serve as the start and end dates for the
related requirement. This is done in booking setup metadata. Go to Resource Scheduling > Settings >
Administration > Enable Resource Scheduling for Entities , then double click an enabled entity.
In the attribute mapping section, you can choose any date and time fields on the entity.
For example, imagine you enable Leads for scheduling. You can choose two date fields on the Lead entity (either
existing or custom fields) that will automatically be the from and to dates when you attempt to schedule the Lead.

Additional notes
NOTE
Using Date Window Star t and Date Window End means the work order must be completed during the date range based
on the total duration of the requirement. For example, if you expect a work order to take 25 hours, but the date range is 1
day (24 hours), then no resources will return as results because no one can complete the 25 hour work order in 1 day, even if
he or she works 24 hours each day as working hours.

Variable calendars : Out of the box, Dynamics 365 Field Service cannot consider variable calendars where
certain days and times are restricted or required for scheduling. For example, imagine a customer who
requires on-site service would like the work order to be scheduled on Mondays, Wednesdays, or Fridays
between 12:00 PM and 5:00 PM each day. This can't be achieved with the out-of-the-box date and time
preference fields or calendar. As a possible workarounds, use notes to inform the dispatcher of the
customer's time preferences, or to use Booking Rules to create custom logic with JavaScript.
Scheduling entities other than work orders : The time parameter fields on the work order - Date
Window Star t and Date Window End , Time From Promised and Time To Promised , and Time
Window Star t and Time Window End - all exist on the resource requirement entity. This means you can
use these fields when scheduling entities other than work orders, such as cases, quotes, and custom entities.
Advanced filters for the schedule assistant in
Universal Resource Scheduling
7/7/2020 • 2 minutes to read • Edit Online

Beyond the standard filters exposed within the schedule assistant's filter panel, you'll find a few advanced filters that
provide additional granularity for scheduling needs.

In this article, we'll take a look at the schedule assistant's advanced filters:
Real-time mode
Ignore travel time
Allow overlapping
Ignore duration
Ignore proposed bookings

NOTE
For more information, see the video Schedule Assistant: advanced filters.

Prerequisites
The schedule assistant is a part Universal Resource Scheduling, which is included and installed with Dynamics 365
Field Service, Project Service Automation, and Customer Service.

Real-time mode
Filtering by real-time mode can be useful in emergency scenarios where a dispatcher needs to book the closest
possible resource, so that they can arrive onsite more quickly.
The schedule assistant will use the location of the technician's mobile device when calculating the estimated travel
time to arrive at the work order location. The "real time" location is displayed on the schedule board map as a truck
icon.

The mobile device's location is collected from the time of the last sync to a defined threshold in the past. The time
threshold for when the acceptable location of a previous sync is defined in the Geo Location Expires After X
Minutes field found in Resource Scheduling app > Settings > Administration > Scheduling parameters .
See the article on geofencing to learn how to set up location auditing and sharing.

Ignore travel time


Sometimes, a dispatcher may want to ignore the travel time when finding available resources. One example is if the
resource can work overtime or if the job location is exceptionally far away.
For cases when the calculated travel time is not needed, selecting Ignore travel time in the schedule assistant's
advanced filters will produce results that ignore the estimated travel time when determining if a resource has
enough time available in their schedule.
Ignore duration
The schedule assistant will ignore the requirement duration when determining if a resource has enough time
available in their schedule.

Ignore proposed bookings


Many organizations will mark their bookings with a booking status of Proposed until a customer or client commits
to the schedule. In such cases, dispatchers may want to view those time slots as available for other work that is
more important or ready to be committed.
With the Ignore proposed bookings advanced filter, the schedule assistant will ignore bookings where the
Booking status is Proposed , and will treat that time slot as available.
Allow overlapping
The schedule assistant will double book on top of bookings where the Allow Overlap field is set to Yes .
.
This filter is similar to the Ignore proposed bookings filter, except it's unrelated to the booking status because
any booking can be set to allow overlapping.

Configuration considerations
Default values and sorting
When the schedule assistant is triggered, you'll see that some fields have default values. For example, schedule
assistant search results are listed in alphabetical order by default. These default values can be changed in the
Schedule Assistant Retrieve Constraints Quer y .
To get there, double-click on the schedule board tab. Open default settings in the top right. Under the schedule
types section, select the gear icon next to Default Retrieve Constraints Quer y .
From here, you can edit the XML to define how the schedule assistant searches for each entity that is available for
scheduling.

Additional notes
Do not edit the schedule assistant Retrieve Constraints Quer y for the territory shown below. It can damage the
schedule assistant logic.
<Territories ufx:select="lookup-to-list(Requirement/msdyn_territory)" />
Enable an entity for scheduling in Universal Resource
Scheduling
8/14/2019 • 6 minutes to read • Edit Online

Dynamics 365 Field Service uses Universal Resource Scheduling to schedule work orders to the most appropriate
resources by enabling the work order entity for scheduling by default. Considering your business processes, other
entities may also be enabled for scheduling, including custom entities.
Enabling an entity for scheduling allows dispatchers to schedule that entity through the schedule board, the
schedule assistant, and even resource scheduling optimization (RSO).
In this article, we'll look at how to enable an entity for scheduling and show how it works on the schedule board.
For the purposes of this article, let's consider an example. A solar energy company must perform consultations over
the phone and on site at their customers' homes before a solar panel installation can take place because details
regarding the home's structure, location, and local laws need to be discussed as part of the qualification process.
The solar panel company would like to use the schedule board and other scheduling tools to assign leads to
appropriate sales resources in order to perform the consultation and qualification process with potential customers.
To configure this scenario, we will enable the Lead entity for scheduling and add a new requirement view to the
schedule board that specifically relates to lead resource requirements.

Prerequisites
Field Service v6.1+
Must be logged in as a user with Field Ser vice - Administrator or System Administrator security roles

Enable an entity for scheduling


To enable an entity for scheduling, go to Resource Scheduling > Administration > Enable Resource
Scheduling for Entities .

You will see a list of entities that have been enabled for scheduling. Appointments , Projects , and Work Orders
are enabled for scheduling by default if you have Dynamics 365 Field Service or Project Service Automation
solutions installed.
You will see a section called Setup Wizard - Enable Scheduling that lets you set up a new entity for
scheduling. For the following fields:
Add Entity: Select the entity from the list of entities in your Dynamics 365 organization. For our example,
we will choose the Lead entity.
Booking Relationship: Select Create New Relationship .
Requirement Relationship: Select Create New Relationship .

NOTE
If you have previously created relationships from the entity to the bookable resource booking or resource requirement
entities, then they can be selected here as well.

Next, select Publish Customization .


To edit settings for how leads are booked, double-click Leads once it appears in the Enabled Entities section. For
example, default booking statuses and whether the entity is enabled for quick scheduling can be edited.
You have successfully enabled an entity for scheduling when:
1. Resource Requirements shows as a related entity.
2. The Book button appears in the top ribbon.

Before scheduling a lead, a related resource requirement must be created. These can be created manually or
created by a custom workflow.
To create a resource requirement, go to the Related tab on the entity and choose Resource Requirements .

NOTE
As part of the Field Service solution, requirements are automatically created when work orders are created.

Select New to create the new resource requirement.

Enter the information that will provide details on what requirements are needed for a resource to be scheduled to
this lead. Details might include dates, duration, priority, and territory.
Once the requirement is created, you can book the lead to resources by selecting the Book button.

This will trigger the schedule assistant and display available resources that meet the criteria on the requirement.
If quick book is enabled for the entity, the Book button will trigger the quick scheduler panel, which also shows
available resources that meet the criteria on the requirement.
Once the lead is booked, a new Bookable Resource Booking record is created and is also shown as a related
entity.

Next, let's talk about scheduling lead requirements from the schedule board.  

Add a requirement view to the schedule board


After creating a requirement for the lead, it will appear in the Open Requirements view in the lower pane of the
schedule board that shows all open requirements related to any schedulable entity. This is a default view for
resource scheduling.

However, the views in the lower pane of the schedule board are simply system views and can be edited and added
to. It's common to add custom resource requirements views for work orders (or leads in our example). Let's create a
schedule board view that shows only leads to be scheduled.
Go to Settings > Customizations > Entities > Resource Requirement > Views .

Create a new view and add fields to the view that provide details for what you are scheduling. Use the drop-down
to capture fields from the entity (in this case, Lead ).

Name the view using the properties or Save As functions. In this example, we will call it our new view
"Unscheduled Leads."
Most importantly, edit the filter criteria to show the appropriate records. To ensure only the lead resource
requirements will be displayed, select the Lead entity and filter the records appropriately.

Save , then Close & Publish .


Finally, we'll need to edit the schedule board we will be using in order to schedule the entity.
Go to the schedule board and select the plus sign icon (+) to add a new tab.
In the Requirement Panels section, add a Title and select the new view.
Select the plus sign icon (+) to add the view.
Select Hide default requirement panels if you don’t want to display the other tabs.

NOTE
You may have many lead records in the system, but if there are no requirements related to the leads, then no records will
show on the schedule board. Resource requirements will need to be created for each lead you want to schedule either
manually or through a workflow to auto create upon creation of a lead.

Appointment scheduling with Universal Resource Scheduling


Appointments are enabled for scheduling by default when Universal Resource Scheduling is installed.
You can configure the system to automatically create a booking when an appointment is created.
Go to Settings > Administration > System Settings > Calendar and set Scheduling Engine to Universal
Resource Scheduling .

Create an appointment and add relevant details.


In the Required field, enter a user record. If the user record has an associated bookable resource, a booking will be
created for that resource with the same start and end time as the appointment.
Once saved, you can see the related booking on the appointment form by going to Related > Bookable
Resource Bookings . Like all bookings, it's visible on the schedule board for the right time slot and resource.
Unlike other entities enabled for scheduling, the appointment form will not have a Book button in the top ribbon
nor will there be an associated resource requirement. Creating an appointment is inherently like creating a booking.

Configuration considerations
Onsite leads
If resources must perform work on site at the customer's location, travel time and distances should be considered
when scheduling. In these cases, we recommend using the work order entity, as it is designed for on-site service.
However, if you would like to schedule leads to be performed on site:
1. Create a lead.
2. Create a related resource requirement.
3. On the requirement, set Work Location to Onsite .
4. On the requirement, add Latitude and Longitude values. These serve as the lead location and can be
compared to the locations of resources in the system during scheduling.
1. (Optional) Consider going to the Lead Booking Setup Metadata and adding a default Work Location for
when lead requirements are related and mapping requirement latitude and longitude fields to lead latitude and
longitude fields for auto population.

Additional notes
If the entity you want to enable for scheduling is not displayed in the Add Entity list, go to the managed
properties of the entity (Settings > Customizations ) and set the Can be customized setting to True . For
more information, see our article on managed properties.
To turn off scheduling for a previously enabled entity, select Deactivate in the ribbon on the Booking
Setup Metadata record.
Share a schedule board tab
8/14/2019 • 3 minutes to read • Edit Online

You can have multiple schedule board tabs, each showing different resources and requirements. Typically, these are
divided by territory or lines of business.
A schedule board tab can be shared:
publicly, available to all schedule board viewers (mostly dispatchers),
privately for just the person who created it
only to specified people
By default, there exists a schedule board tab called Initial Public View that includes all resources and
requirements.
In this topic, we'll explore creating a new schedule board tab and sharing it with specific users.

Prerequisites
Field Service v6.1+
Universal Resource Scheduling v1.0.2+

Instructions
First we will walk through how to create a public and private schedule board tab, but then focus on sharing one
with specific people.
Go to Field Ser vice > Schedule Board and select the + in the top right to create a new tab.

The schedule board tab settings form will appear where you can choose various configurations for the tab.
The Shared With field controls who can see the tab.
Select Specific People .
Selecting Ever yone will expose the schedule board tab to all users who can access the schedule board. Selecting
Just Me will expose the schedule board to only the user who creates it.
Next, give appropriate security access to the users you want to share the schedule board tab with.
Go to Settings > Security and make sure each user has at least minimum user access to the Schedule Board
Settings entity as seen in the following screenshot. This can be achieved by manually editing the users' security
role or by assigning the users a copy of the Field Ser vice - Resource security role.

NOTE
We recommend giving relevant users minimum security level privileges for read, write, and create. Then use the Shared
With option (Everyone, Specific People, Just Me) on the schedule board tab settings to share appropriately. This is better
than using the Dynamics 365 security model, as that could lead to oversharing.

Next you'll need to choose the specific users to share the schedule board tab with.
Go to Advanced Find and look for Schedule Board Settings , then select Results. All schedule board tabs are
saved as records in the Schedule Board Settings entity.
This shows all schedule board tab records and you should see the one you just created. In our example, it's
"Schedule Board #3".

Double-click the record to go to the form, and select Share on the top ribbon.

Finally, use the pop-up screen to add users and teams to share the schedule board with. Any user or team added
here can see the schedule board tab, given they also have access to the schedule board.

Link to specific schedule board


Sometimes, you may need a link to a specific schedule board tab that dispatchers can use as a browser shortcut, to
share with teammates and managers, and to reduce the load time by not having to load the entire board.
First get the GUID for the specific schedule board tab you want to link to.
A GUID is a 32-digit number in the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX and each record in
Dynamics 365 has a GUID as a unique identifier, including schedule board tabs.
You can find the GUID of a schedule board tab with an advanced find of the Schedule Board Settings entity.
Select the record that corresponds with the schedule board tab you want to share and use the Email a link button
to get the GUID.
Finally, copy and paste the GUID into the template link below.

https://[dynamics org name].crm.dynamics.com/webresources/msdyn_/fps/ScheduleBoard/scheduleboard.html?#tab=[32


digit GUID].

See the following for an example of an acceptable URL to a specific schedule board tab.

https://fieldservice.crm.dynamics.com/webresources/msdyn_/fps/ScheduleBoard/scheduleboard.html?#tab=AE595A88-
A57C-E911-A95A-000D3A3B9A2B

Be sure to test the link by entering it into a browser. Note that people who follow the link will be prompted to log in
to Dynamics 365 Field Service if they aren't already logged in.

Additional notes
Even if a schedule board tab is shared with a specific user, that user must have the minimum user permissions
on the Schedule Board Settings entity to view it. Minimum permissions are included with the Field Ser vice
- Administrator , Field Ser vice - Dispatcher , and Field Ser vice - Resource security roles.
We recommend giving relevant users minimum security level privileges for read, write, and create. Then use the
Shared With option (Everyone, Specific People, Just Me) on the schedule board tab settings to share
appropriately. This is better than using the Dynamics security model, as that could lead to oversharing.
You can share a schedule board tab with a team for convenience.
To edit a schedule board, it must be shared with you and you must have write privileges.
Resource utilization on the schedule board in
Universal Resource Scheduling
8/14/2019 • 2 minutes to read • Edit Online

Dispatchers and service managers need to understand resource utilization to make better scheduling decisions,
whether those decisions entail assigning work orders to field technicians or reserving equipment for customer jobs.
Utilization is the amount of time a resource is scheduled to work. It is calculated as the percentage of booked time
versus working hours. In all schedule board views, utilization is automatically calculated and displayed in each
resource's cell.

In this topic, we will look at how resource utilization is calculated and displayed in both the Hours and Days views
of the schedule board.

Prerequisites
Utilization is calculated and displayed on the schedule board for all versions of Field Service.

Hours view
For each resource, utilization percentage is derived from Total Booked Hours divided by Total Working Hours
in the schedule board timeframe.
Total Booked Hours is the sum of the hours booked to the resource.
Total Working Hours is the sum of the resource's working hours.

NOTE
Working hours are defined on each Bookable Resource record. Go to Resource Scheduling > Resources . See the topic
on setting up bookable resources for more details.

These values will change based on how many hours, days, and weeks you are viewing, and these are edited by
selecting a view, a date range, and how many days to display.
This is because as you view more days, the bookings and working hours will vary.
In the hourly view, the total working hours will be the sum of the hours seen on the schedule board as you scroll
from the far left to the far right.

In the previous screenshot example, Matthew works a 12-hour shift from 9 AM to 9 PM, and this shift repeats for
5 days . Users will see this as they scroll from left to right across the schedule board.
Therefore, Matthew’s total working hours in this hourly view are 12 multiplied by 5, resulting in 60 hours.
If Matthew is booked for a single 6-hour work order, then his utilization is 6 divided by 60, resulting in 10 percent,
as shown in his resource card.
If the duration of the work order is increased to 12 hours, then his utilization is 12 divided by 60, resulting in 20
percent, as shown in the following screenshot.

Days view
In the Days view, the total working hours will be the sum of the hours seen on the schedule board.
In our example case, we see 10 days, so Matthew’s total working hours are 12 multiplied by 10, resulting in 120
hours.
Matthew already has a 12-hour booking for one day, so his utilization percentage becomes 12 divided by 120,
resulting in 10 percent.

Configuration considerations
Proposed and canceled bookings do not contribute to utilization
Though the field service process uses many field service booking statuses such as traveling, in progress, on break,
and completed, each of those relate to a booking status of either Committed , Proposed , or Canceled . The
purpose of a proposed status is to suggest work that needs to be confirmed, while the canceled status is used to
notify stakeholders that the booking is no longer scheduled.
For example, the In Progress status is categorized as Committed through the status field on the booking status
entity, as seen in the following screenshot.

Bookings that have a Proposed or Canceled booking status are ignored for utilization.
As seen in the following example, Brady was assigned a Proposed booking, but his utilization remained at 0
percent.
Sort schedule assistant results by utilization
When using the schedule assistant to book requirement groups, dispatchers have the option to sort results by
utilization.
Customize the schedule board with a custom
resource attribute
8/14/2019 • 6 minutes to read • Edit Online

The schedule board can be customized and extended to help you reach your business needs. Common examples
include customizing:
1. the resource cells where the resources' names, pictures, and utilization are listed by default
2. the fields in the filter pane where dispatchers choose the resources in a view
3. the sort options (also located in the filter pane) allowing dispatchers to sort the current resources on the the
schedule board based on various criteria.
Consider the following customization scenario:
Each bookable resource (field technician) has a cost based on factors like seniority and certification level.
Dispatchers would like to see the general cost of their resources, along with the ability to filter and sort by cost. This
is common for scenarios where an organization prioritizes scheduling internal employees over external contracting
parties, who are usually more expensive. Rather than use an exact resource cost, this scenario uses a score of 1
(lowest resource cost) to 10 (highest resource cost) and exposes the score:
In the resource cell, for viewing the cost with a graphical element
In the filter panel, to filter a by a maximum cost level for the desired resources
In the sort options, to sort from lowest to highest cost or vice versa
In this topic, we'll walk through how to configure this common example scenario.

Prerequisites
Field Service v6.2.1+
Universal Resource Scheduling v1.1.1+

Step 1: Add the new attribute to the bookable resource entity


Go to Customizations > Customize the System > Bookable Resource > Fields and add a new field named
Resource Cost with the schema name tsp_resourcecost . If your organization has a different schema prefix such
as new_ , it can be used if the code snippets (which you will find below) are updated to reflect this.
Use the data type Option Set and select the existing option set Level of Impor tance . This is simply to have a list
of 1 to 10, where the underlying numeric values are also 1 to 10.
Add the newly created field to the form to be able to administrate your resources. Publish the changes .

Step 2: Create a new schedule board (or modify an existing one)


Go to the schedule board that you want to add the new resource cost attribute to. In the following example
screenshot, you'll see a schedule board titled "DE#2". You'll also find the 3 areas highlighted on the schedule board
that we will customize with the new resource cost attribute.
1. add resource cost indicator in the resource cells
2. define a maximum cost score when filtering and searching for resources
3. allow sorting by cost score
Step 3: Modify the resource cell template
The resource cost indicator should be displayed in the resource cell (1). Font Awesome can be used to display icons,
such as €, $, £.
The HTML first draws 5 gray icons as a background, then 5 yellow icons as foreground. Then the number of the
foreground icons is limited to the value of the resource cost; in other words, a resource cost value of 2 is converted
to 20%, which means only 20% of the 5 yellow Euro icons (1 icon) will be displayed. A resource cost value of 5
shows 50% of the 5 yellow Euro icons (2.5 icons).
Double-click the tab of your schedule board (DE#2 in our example). Scroll down to resource cell template. You can't
(and shouldn't) modify the standard templates. Use the button and Save As to create a custom template.

NOTE
If you want to set these changes as the default for all schedule boards, after double-clicking a schedule board tab, select
Open Default Settings in the top right and make the code changes to Resource Cell Template , Filter Layout , and
Retrieve Resources Quer y .
Below is the new code snippet to copy and paste into the resource cell template, followed by an image that shows
the delta (highlighted in yellow) that can be used to modify an existing template. Replace fa-euro if you need a
symbol different from the euro.
<div class='resource-card-wrapper {{iif ResourceCellSelected "resource-cell-selected" ""}} {{iif
ResourceUnavailable "resource-unavailable" ""}} {{iif IsMatchingAvailability "availability-match" ""}}'>
{{#if imagepath}}
<img class='resource-image' src='{{client-url}}{{imagepath}}' />
{{else}}
<div class='resource-image unknown-resource'></div>
{{/if}}
<div class='resource-info'>
<div class='resource-name primary-text ellipsis' title='{{name}}'>{{name}}</div>

<div class='secondary-text ellipsis'>


<div class="back-stars" style="color: #EEEEEE; position: relative; display: inline-block;">
<i class="fa fa-euro" aria-hidden="true"></i>
<i class="fa fa-euro" aria-hidden="true"></i>
<i class="fa fa-euro" aria-hidden="true"></i>
<i class="fa fa-euro" aria-hidden="true"></i>
<i class="fa fa-euro" aria-hidden="true"></i>

<div class="resourcecost" style="width: {{resourcecost}}0%; color: #FFBC0B; position: absolute; top: 0;


left:0; display: inline-block; overflow: hidden;">
<i class="fa fa-euro" aria-hidden="true"></i>
<i class="fa fa-euro" aria-hidden="true"></i>
<i class="fa fa-euro" aria-hidden="true"></i>
<i class="fa fa-euro" aria-hidden="true"></i>
<i class="fa fa-euro" aria-hidden="true"></i>
</div>
</div>
</div>

<div class='secondary-text ellipsis'>


{{#if (eq (is-sa-grid-view) false) }}
<div class='booked-duration'>{{BookedDuration}}<div class='fo-sch-clock'></div></div>
<div class='booked-percentage'>{{BookedPercentage}}%</div>
{{/if}}
</div>
{{#if (eq (is-sa-grid-view) false) }}
<div class='matching-indicator'></div>
{{/if}}
</div>
{{#if (eq (is-sa-grid-view) false) }}
{{> resource-map-pin-template this }}
{{/if}}
</div>
Step 4: Modify the filter layout
Our next goal is to define a maximum cost score when filtering and searching for resources (2) and also allow
sorting by cost score (3) .
To accomplish this, from the same schedule board tab setting where you edited the resource cell template, scroll to
Filter Layout . Use the gear button and Save As to create a custom template.
Copy and paste the following code snippet into the Filter Layout. The following image shows the delta (highlighted
in yellow) that can be used to modify an existing template.
<?xml version="1.0" encoding="utf-8" ?>
<filter>
<controls>
<control type="characteristic" key="Characteristics" label-id="ScheduleAssistant.West.Skills" />

<control type="combo" source="optionset" key="ResourceCost" label-id="Resource Cost Limit"


entity="bookableresource" attribute="tsp_resourcecost" multi="false">
</control>

<control type="combo" source="entity" key="Roles" inactive-state="1" label-id="ScheduleAssistant.West.Roles"


entity="bookableresourcecategory" multi="true" />
<control type="combo" source="entity" key="Territories" unspecified-key="UnspecifiedTerritory" label-
id="ScheduleAssistant.West.Territories" entity="territory" multi="true" />
<control type="combo" source="entity" key="OrganizationalUnits" label-
id="SB_FilterPanel_OrganizationalUnitsFilter_Title" inactive-state="1" entity="msdyn_organizationalunit"
multi="true" />
<control type="combo" source="optionset" key="ResourceTypes" label-
id="SB_FilterPanel_ResourceTypesFilter_Title" entity="bookableresource" attribute="resourcetype" multi="true">
<data>
<value id="2" />
<value id="3" />
<value id="4" />
<value id="5" />
</data>
</control>
<control type="combo" source="entity" key="Teams" label-id="SB_FilterPanel_TeamsFilter_Title" entity="team"
multi="true" />
<control type="combo" source="entity" key="BusinessUnits" label-id="SB_FilterPanel_BusinessUnitsFilter_Title"
entity="businessunit" multi="true" />
<control type="order" key="Orders" label-id="FilterControl_OrderLabel">
<order name="name" entity="bookableresource" attribute="name" />

<order name="resourcecost" entity="bookableresource" attribute="tsp_resourcecost" />

<order name="proficiencyscore" entity="bookableresourcecharacteristic" attribute="ratingvalue" />


</control>
</controls>
</filter>
Step 5: Modify the query
Finally, we'll modify the actual query and include the new filter (the “le” operator only leaves resources with a cost
score less than or equal to the one selected in the filter panel). Scroll to Retrieve Resources Quer y .
Use the gear button and Save As to create a custom template. The existing code is lengthy, so below are only the
code snippets to paste within an existing resource query.
After this line:

<entity name="bookableresource">:

Paste the following:

<attribute name="tsp_resourcecost" alias="resourcecost" groupby="true"/>

See the following image for reference:


After the ending:

</filter> tag of the <!-- Territory filter -->

Paste the following:

<filter type="or" ufx:if="$input/ResourceCost">


<condition attribute="tsp_resourcecost" operator="le">
<ufx:value select="$input/ResourceCost" attribute="value" />
</condition>
</filter>

See the following image for reference:


Step 6: Test your new schedule board
Back on the schedule board we've been working on, you'll see that we have defined a maximum cost factor of 5 and
ascending sort order based on cost. See the following screenshot for reference.
Additional notes
At this time, resource cards can't be extended for custom layouts and fields. Resource cards are displayed when
hovering over or right-clicking the resource's name on the schedule board.

For further context on schedule board extensibility, visit our topic that provides a deep overview of scheduling
extensibility.
See also
A sample walkthrough to help you learn how to implement extensibility.
Extensibility language syntax (UFX).
Extensibility-specific release notes.
Edit schedule board booking template
8/14/2019 • 4 minutes to read • Edit Online

When a requirement is scheduled to a resource, a booking record is created and displayed on the schedule board
during the respective resource's time slot. The fields displayed in the schedule board booking is called a Booking
Template and is editable.

In this topic, we'll discuss how to edit the booking template.

Prerequisites
Field Service v6.1+

Edit work order booking template


Each schedule board and each scheduling-enabled entity (such as work orders, projects, cases, or custom entities)
can have a different booking template. When a work order requirement is scheduled, the booking template shows
the Bookable Resource Booking record's Name and Duration values as seen in the following screenshot.

The HTML that displays these values is:

<div>{SchedulableEntityDisplayName} - {name}<br />Duration: <strong class="bold">{duration}</strong></div>

To edit the HTML that controls the booking template, double-click the name of the schedule board tab, then scroll
down to the Schedule Types section and select the entity on the left for which you would like to change the
booking template.

In this example, we will choose work order, and then find the Booking Template field at the end of the form.
Next, modify the booking template by deleting the existing value and entering HTML and CSS that can reference
fields from the Bookable Resource Booking entity and linked entities, such as the work order.
Here is an example that pulls values from the work order that relates to the booking.

<div style="line-height: 11px !important; width: 99%; overflow: hidden; display: block; text-overflow:
ellipsis;">
WO:
<B>{msdyn_msdyn_workorder_bookableresourcebooking_WorkOrder.msdyn_name}</B><br/>
Account: <b>
{msdyn_msdyn_workorder_bookableresourcebooking_WorkOrder.msdyn_account_msdyn_workorder_ServiceAccount.name}</b>
<br/>
Incident: <b>{msdyn_msdyn_workorder_bookableresourcebooking_WorkOrder.msdyn_primaryincidenttype}</b><br/>
Duration: <b>{duration} minutes</b><br/>
</div>

Enter the sample text above and select Apply .


Refresh the schedule board and bookings related to work order requirements will appear as the following:

[Note!] To avoid typing mistakes, go to Customization > Entities > Bookable Resource Bookings and
copy the field names. Fields from the Bookable Resource Booking entity can be referenced directly using the
field name in curly brackets. Example: {duration} .

If you want to display a field from a linked entity, find the name of the N:1 relationship - for the work order entity,
it's msdyn_msdyn_workorder_bookableresourcebooking_WorkOrder - and add a period (.) followed by the
field name of the target entity. For example, the primary incident type field on the work order has a schema name
of msdyn_primar yincidenttype ; simply add this after the relationship schema and enclose the whole string with
curly brackets, as follows:
{msdyn_msdyn_workorder_bookableresourcebooking_WorkOrder.msdyn_primar yincidenttype}
Linking to yet another entity (like from work order to account) is also possible - simply connect the entities with
period, like in our previous example.
Following these instructions will edit the booking template for work order requirements displayed on this schedule
board tab. If you would like to edit the default booking template for all schedule board tabs, then select Open
Default Settings and edit the Booking Template field there.

NOTE
When < Default > is displayed in a schedule board tab setting field, this means the value is being dictated by the default
settings.

Advanced booking template styling using CSS


In this scenario, let's add customer rating and service call icons to the booking template based on conditional
values on the account and work order records.
Let’s assume that there is a customer rating that the dispatcher should see on the schedule board to prioritize jobs.
The customizer has added a field new_customerrating on the Account entity and propagates that field to the
work order entity with an integer range from 1 to 10. Using the approach above, this field could easily be added to
the booking template, though it won't look to good.
Instead, in our scenario, we want the booking template to show the customer rating as 5 grey stars, which
represent the range. To represent the actual customer rating, we will overlay 5 orange stars, but only show a
percentage of these, corresponding to the 1-10 customer rating.
For example: let's say the customer rating is 4 out of 10, so we only show 40% of the orange stars, which is 2 out of
5. See the following screenshot for an example.

We also want our dispatcher to see whether a work order is a service call or another type of job. The customizer
has created a field new_isser vicecall on the work order entity, values are 0 or 1. Using the same approach as
above, we first draw a gray wrench as background, put an orange wrench on top and limit its size to 0%
(new_isservicecall = 0) or 100% (new_isservicecall = 1).
Go to Resource Scheduling > Administration > Scheduling Parameters and set Disable Sanitizing HTML
Templates to Yes . This is required to be able to include CSS statements into the booking templates.
Next, add the following HTML and CSS text to Booking Template field in Schedule Board Tab Settings .

<div style="line-height: 11px !important; width: 99%; overflow: hidden; display: block; text-overflow:
ellipsis;">
<div class="back-stars" style="color: #AAAAAA; position: relative; display:inline-block;">
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<div class="customerrating" style="width:
{msdyn_msdyn_workorder_bookableresourcebooking_WorkOrder.msdyn_account_msdyn_workorder_ServiceAccount.new_custo
merrating}0%; color: #FFBC0B; position: absolute; top: 0; left:0; overflow: hidden; display:-webkit-box">
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
</div>
</div>
<div class="repair-back" style="color: #AAAAAA; position: relative; display:inline-block; padding-left:10px;
vertical-align:text-top;">
<i class="fa fa-wrench" aria-hidden="true"></i>
<div class="repair" style="width:
{msdyn_msdyn_workorder_bookableresourcebooking_WorkOrder.new_isservicecall}00%; color: #FFBC0B; position:
absolute; top: 0; left:0; padding-left:10px; overflow: hidden; display:-webkit-box">
<i class="fa fa-wrench" aria-hidden="true"></i>
</div>
</div>
<br/>
WO:
<b>{msdyn_msdyn_workorder_bookableresourcebooking_WorkOrder.msdyn_name}</b><br/>
Account: <b>
{msdyn_msdyn_workorder_bookableresourcebooking_WorkOrder.msdyn_account_msdyn_workorder_ServiceAccount.name}</b>
<br/>
Incident: <b>{msdyn_msdyn_workorder_bookableresourcebooking_WorkOrder.msdyn_primaryincidenttype}</b><br/>
Duration: <b>{duration} minutes</b><br/>
</div>

See the result of the change in the following screenshot.

When building these advanced booking templates, make sure to test on multiple browsers and also consider
accessibility.
See also
Add custom resource attributes to the schedule board
Booking alerts in Universal Resource Scheduling
8/14/2019 • 3 minutes to read • Edit Online

While managing resources and scheduling, dispatchers must be aware of important updates and status changes to
ensure accurate schedules and timely job completion. For example, a dispatcher needs to know if a field technician
is running late or that prerequisites for a job have not been met so that they can take appropriate actions. Beyond
scheduling, dispatchers may also need to ensure billing and customer satisfaction concerns are handled.
In Dynamics 365 Field Service and in Universal Resource Scheduling, Booking Aler ts bring attention to important
notifications so that dispatchers can schedule with confidence. Booking alerts display notes and reminders on the
schedule board, and can relate to bookings, work orders, users, and other entities. They can be triggered based on
timers, set alarms, or workflows.

There are three significant additional benefits:


1. A booking alert has a start time after which it will be shown.
2. A booking alert can be assigned to one or many users.
3. By using the Snooze button, the alert will disappear and re-appear after the desired time. This helps dispatchers
handle multiple issues in parallel.
Though the goal of a modern business application is to introduce automation for routine tasks, booking alerts can
help remind dispatchers to perform the remaining manual processes - or notify them of automated process that
have taken place.
In this article, we'll take a look at how to create and view booking alerts.

Prerequisites
Field Service v6.1+
Field Ser vice - Dispatcher security privileges

Create a booking alert


Let's say a dispatcher wants to set herself a reminder. On the schedule board, select the Actions button and select
New Booking Aler t . See the following screenshot for reference.

The New Booking Aler t window pops up.

Subject and Description define the message that appears on the alert.
Priority can be used for additional logic, but won't trigger any specific behavior.
Regarding allows the user to link the alert to a specific record. For any entity, the booking alert will
immediately show up on the record's timeline. However, only upon reaching the Due Date , the alert will
also show up on the schedule board's detail pane Aler ts tab.
Assignees is the field where you can assign one or more people. Each assignee can choose to snooze or
dismiss the alert.

NOTE
When setting the Regarding field, pay attention to the entity type that you select. By default, the work order, the associated
resource requirement, and the booking have the same name. On top of the Regarding field, you can use a filter to limit
results to the desired entity.

View the booking alert


Once the due date is reached and the alert appears on the schedule board side pane, here is what the alert will look
like and how a dispatcher can put an alert on hold by selecting Snooze . The dispatcher can also select how long
the snooze should last.

Booking alerts for bookings


Alerts for Bookable Resource Bookings will not only appear in the booking’s timeline and the details panel, but
also in the schedule board alongside a booking time slot, specifically in the upper left-hand corner of the booking.
See the following screenshot for reference.

The icon indicates the number of active alerts for that booking; clicking it expands or collapses the details. Snooze
and Dismiss work the same way as in the panel.

Additional notes
By creating the booking alert, the system automatically creates one Booking Aler t Status record for every
assignee. This allows the affected users to individually snooze (there is a field called Next Time To Show )
or dismiss alerts. When a user dismisses the alert, the Booking Aler t Status records are deactivated. When
every assignee dismisses the alert, its Activity Status field is set to Completed .
In most situations, the user will not create the alert manually. Instead, Power Automate or a workflow can be
used to automate the record creation upon certain events.
When deleting records, keep the relationship Booking – Booking Aler t – Booking Aler t Status in mind.
By default, you can't remove a booking that has booking alerts associated to it.
You can edit the fields inside a booking alert by editing the Booking Aler t Template in the schedule board
tab settings. For more information, visit the topic on schedule board tab settings.
Schedule board tab settings
8/14/2019 • 12 minutes to read • Edit Online

Schedule board tab settings allow you to define the layout and functions of schedule board tabs.
There are 3 ways to access a schedule board's tab settings:
1. Double-click the name of the schedule board tab.
2. While viewing the schedule board tab, select the gear icon in the top right of the schedule board.
3. While viewing the schedule board tab, select the settings icon > Open Tab Settings - see the following
screenshot for reference.

When you access the schedule board tab settings, you'll see the following:
Name: This is the name displayed at the top of the schedule board.
Shared With: Decides which users can view the schedule board tab
Everyone
Specific People: after choosing this option, you can select the specific people to share the schedule board
with by doing an advanced find of the Schedule Board Settings entity and sharing the related schedule
board record with the specific users.
Just Me

NOTE
Users with Field Ser vice - Administrator , Field Ser vice - Dispatcher , and Field Ser vice - Resource security roles can
edit schedule board tab settings of schedule boards they create or are shared with them (meaning the Shared With field =
Ever yone or Specific People AND the schedule board is shared with their user record).
Open Default Settings: Lets you choose the default tab settings when new schedule boards are created. When
values in a particular schedule board tab setting show < Default View > , this means the value is coming from
the default tab settings. As seen the following screenshot, when the Open Default Settings button is selected,
the < Default View > values are replaced by the actual values and you are now editing default schedule board
tab settings.

Reset to Default: This will reset the current tab setting values to the values outlined in the default settings.

Map settings
The Map Settings section is where you specify the placement of the map and the views displayed when selecting
or hovering over map records.
Map view tab placement
When set to Filter Pane , the map will be placed on the left-hand side. This allows schedulers to see both the map
and the details of the selected record at the same time.
When set to Details Pane , the map will be placed on the right-hand side. This allows schedulers to see both the
filter pane and the map at the same time.

Requirement map filter view


This view defines the resource requirement records displayed on the map. The setting lists public views related to
the resource requirement entity for selection. Resource requirements need to have a latitude and longitude to
display it on the map. We strongly recommend making a copy of the default view and applying your changes to the
copy.
Resource tooltips view
This view defines the fields displayed in a tooltip that appears when a scheduler hovers over a resource map pin.
The setting lists views that are based on the bookable resource entity; only public views are available for selection.
Even though you can change existing views, it's better to copy the default view and apply changes to the copy.
Resource details view
This view defines the fields displayed in the details pane when a resource map pin is selected. The details pane is on
the right-hand side of the schedule board and may need to be expanded. The setting lists public views related to the
bookable resource entity for selection.

Organizational unit tooltips view


This view defines the fields displayed in a tooltip that appears when a scheduler hovers over a organizational unit
map pin. The setting lists public views related to the organizational unit entity for selection. Even though you can
change existing views, it's better to copy the default view and apply changes to the copy.

Organizational unit details view


This view defines the fields displayed in the details pane when an organizational unit map pin is selected. The
details pane is on the right-hand side of the schedule board and may have to be expanded. The setting lists public
views related to the organizational unit entity for selection.
Custom web resource
Web resources represent files that can be used to extend the Microsoft Dynamics 365 web application, such as
HTML files, JavaScript, and Silverlight applications. This section allows you to access web resources from the
schedule board, which can help dispatchers perform more functions and increase utilization.
Tab Name: the chosen web resource will be displayed in the details pane on the right-hand side of the
schedule board. A new tab with the name entered here will appear next to the alerts tab. In the following
example screenshot, "Web Resource" was entered for the tab name.
Web Resource: select a web resource from your Dynamics 365 organization.

Schedule board colors


The colors that represent a resource's utilization on the days, weeks, and months view of the schedule board are
configurable here by entering HTML hex color codes. See an example of colors chosen and the effects in the
following screenshot.

To illustrate how these colors affect the schedule board, see the following example. In our example, we have a day
view of the schedule board where each resource works 12 hours each day, and the range is 2 days. The colors are
configured as follows:
Fully Booked: Blue because the total booking duration (12 hours) equals the working hours for that
particular resource's day.
Par tially Booked: Light Blue diagonal lines because the total booking duration (7 hours) is less than the
working hours for that particular resource's day.
Overbooked: Red because the total booking duration (14 hours) exceeds the working hours for that
particular resource's day.
Not booked: White because no bookings exist for that resource for that day.

Schedule assistant
Search for
This setting decides the default value for the Search For field in the schedule assistant filter pane.
Set to All resources to search for all applicable resources in the system that meet the schedule assistant
filters for the requirement.
Set to Resources visible on board to search for resources that meet the schedule assistant filters for that
requirement and meet the current schedule board resource filters. This schedule assistant filter value can still
be manually changed by the dispatcher at the time of scheduling. If a scheduler is responsible for a specific
schedule board and specific resources, then we recommend Resources visible on board because this
ensures the scheduler cannot schedule requirements to other resources he or she is not responsible for.
For smaller organizations or organizations with less rigid resource and line of business divisions, the All
resources setting will allow schedulers to search across all applicable resources across the entire
organization.
Unavailable resources
This setting determines how unavailable resources appear when the schedule assistant is triggered.
Set to Unavailable resources do not appear to ensure that resources who do not meet schedule
assistant filter criteria are temporarily removed from the view of available resources.
Set to Unavailable resources appear dimmed (when searching for resources visible on board) to
ensure that resources who do not meet schedule assistant filter criteria remain on the schedule board, but
appear dimmed. For schedule boards with many resources, using the Unavailable resources do not
appear setting can reduce the need to scroll and make it easier for scheduler to compare available
resources.
Book based on
Though booking an onsite requirement (typically a work order) will always have a total duration that equals travel
time plus requirement duration, this setting changes the schedule assistant visualization to make it easier to
understand when travel time starts and when the estimated arrival time is.
Set to Star t of Travel to visualize the booking start as when travel begins.
Set to Estimated Arrival to visualize the booking start as when the resource is estimated to arrive on site.
Consider whether the scheduler is communicating with the customer in real time; customers are typically
more interested in when the resource will arrive at their location, so administrators should make it easier for
the scheduler to communicate this time by selecting the Estimated Arrival . See this blog post for more
details.
Available Color, Partially Available Color, Unavailable Color
The colors selected in the schedule assistant section represent how resource availability (or unavailability) appears
when the schedule assistant is triggered from the days, weeks, or months view.

Available Icon, Partially Available Icon, Unavailable Icon


The icons selected in the Schedule Assistant section also apply when the schedule assistant is triggered from the
days, weeks, or months view and are displayed along with the colors chosen in the previous settings to represent if
resources are available or unavailable.
If the Default Available Icon , Default Par tially Available Icon , or Default Unavailable Icon boxes are
unchecked, then no icons will appear.
The icons can be customized by uploading new image files in Customizations > Customize the System >
Web Resources and referencing the path in tab settings.

Other settings
Requirement Page Count
This controls the maximum number of resource requirement records displayed on a single page in the lower pane
of the schedule board. See the following screenshot for reference.

Non-Working Hours Color


This controls the color of the shaded area when a resource is not working, as defined by the resource's working
hours and time off requests.
Current Timeline Color
This controls the color of the vertical line that runs down the schedule board to indicate the current time of that
particular schedule board.

Booking Alerts View


This is a system view that can filter which booking alerts records are eligible to show up in the Alerts view in the
right-hand Details pane of the schedule board.
For example, consider a scenario where the business has booking alerts being triggered based on events related to
work orders, projects, and cases. What if the particular schedule board tab only deals with work order requirements
and the dispatcher should only see booking alerts related to work orders? In this case, a booking alert system view
can be used to filter to only booking alerts related to work orders to be eligible in the right-hand alerts pane. Note
that booking alerts still need to be triggered based on an alarm or workflow, but the view chosen here can further
filter.

Booking Alerts Template


Given a booking alert shows in the alerts pane, the HTML entered here dictates the fields in the alert box.
For reference, the default HTML is as follows:
<b class="bold">Subject: </b>{msdyn_msdyn_bookingalert_msdyn_bookingalertstatus_BookingAlert.subject}<br />
<b class="bold">Due: </b>{msdyn_nexttimetoshow}<br />
<b class="bold">Description: </b><br />
{msdyn_msdyn_bookingalert_msdyn_bookingalertstatus_BookingAlert.description}

Filter Layout
This controls the fields displayed in the filter pane on the left-hand side of the schedule board. These fields are used
to filter which resources are displayed on the board.

Resource Cell Template


This controls the images, values, fields displayed in the box that holds the resource's name and utilization on the
schedule board.
Retrieve Resources Query
Here you will find XML that defines how resource records are fetched, filtered, and sorted when the schedule board
loads. Retrieve Resources Quer y can use filter layout and resource cell templates to perform filtering and
sorting in the background.
One scenario this enables is filtering resources without having to expose the filter field in the filter layout. Instead,
the filtering happens in the background as the schedule board loads, without additional input from the dispatcher.
Disable Default Extensions
Using the Schedule Board Client Extension framework, you can modify the CSS, add your own JavaScript files, and
localize the schedule board. This means that you can change labels and wording on certain supported areas of the
board. You can always exclude certain boards from inheriting client extensions applied to the default board by
disabling default extensions on that board.
For more details on editing filter layouts, resource cell templates, and client extensions, see this blog post and this
topic on schedule board extensibility.

Schedule types
The following settings are dependent on the entity being scheduled. Though requirement records are always
scheduled, the requirement can be related to work orders, cases, custom entities, or related to nothing at all. First,
select the scheduleable entity on the left to edit the settings for when that entity is scheduled. Select None to edit
default settings and the settings for when a requirement is scheduled by itself, unrelated to a work item such as
work orders or projects.
Booking Tooltips View
Select the system view that dictates the fields displayed when hovering your mouse over a booking.

Booking Details View


Select the system view that dictates the fields displayed in the details pane when a booking is selected.
Schedule Assistant Requirement View
Select the system view that dictates the fields displayed in the lower pane when the schedule assistant is triggered
for an individual requirement from the schedule board.
Requirement Details View
Select the system view that dictates the fields displayed in the details pane when a requirement is selected in the
lower pane of the schedule board.

Requirement Map Pin Tooltips View


Select the system view that dictates the fields displayed when hovering your cursor over a requirement map pin.

Booking Template
HTML and CSS that controls the fields inside a booking time slot on the schedule board.
Here is the default work order HTML:

<div>{SchedulableEntityDisplayName} - {name}<br />Duration: <strong class="bold">{duration}</strong></div>

This HTML results in the following:


NOTE
The following schedule types settings can only be edited from the default settings.

Schedule Assistant Filter Layout


This controls the fields displayed in the filter pane on the left-hand side of the schedule assistant. These fields are
used to filter which resources are displayed in schedule assistant results. A common example is the default values
for Search Star t and Search End .

Schedule Assistant Resource Cell Template


This controls the images, values, and fields displayed in the box that holds the resource's name and utilization in the
schedule assistant.
Schedule Assistant Retrieve Resources Query
Here you will find XML that defines how resource records are fetched, filtered, and sorted when the schedule
assistant is triggered. Schedule Assistant Retrieve Resources Quer y can use schedule assistant filter layout
and schedule assistant resource cell templates to perform filtering and sorting in the background.
One scenario this enables is performing additional resource filtering when the schedule assistant is triggered
without input from the dispatcher.
Schedule Assistant Retrieve Constraints Query
Here you will find XML that defines how resource records are filtered based on attributes from the requirement.
Whereas the Schedule Assistant Retrieve Resources query can filter schedule assistant resources based on
Resource attributes, the Schedule Assistant Retrieve Constraints query can use Requirement attributes to
further filter resource results.

Requirement Panels
Use this section to control the requirement views at the bottom of the schedule board. Select a requirement system
view, enter a name, select the plus icon (+) to add it, then select Apply. After adding views, you can change the order
in which they appear on the schedule board with the up and down arrows.

It will then appear in the lower panel.

Field Service and Universal Resource Scheduling come with default requirement views such as "Open
Requirements" and "Unscheduled Work Orders". Select the Hide default requirement panels to remove them
from the lower pane.

Additional notes
Some of the extensible schedule board settings are only available on the hourly view, and not on the daily, weekly,
and monthly views. The following configuration settings are only available in the hourly view:
Non-working hours color.
Booking details view.
Booking tooltips view.
Booking template.
Preview the new and improved schedule board in
Universal Resource Scheduling
4/1/2020 • 3 minutes to read • Edit Online

A fully redesigned schedule board is available as a public preview in the April 2020 release of Dynamics 365 Field
Service. In this article, we'll take a look at what's new, and how to preview the new schedule board in your
environment.
The new schedule board is faster, with better usability, and it lays the foundation for new capabilities for multi-day
scheduling and intelligent interactions.

Performance
The new schedule board is faster and more responsive when:
Loading the schedule board
Selecting schedule board tabs
Dragging and dropping work orders
Rescheduling bookings
Usability and accessibility
The new schedule board is a Power Apps Component Framework (PCF) control built on the Unified Client Interface,
making it more flexible, supportable, and accessible. The new schedule board will work better on different screen
sizes and across form factors.
New color schemes and ways of depicting travel time make it easier for dispatchers to see statuses and details.

For instance, the previous screenshot shows a new "ghost booking" feature that helps dispatchers know if a
booking will fit into a schedule before the booking is even scheduled.
Foundation for new capabilities
The new schedule board provides the foundation for future releases that will provide dispatchers insights and
recommendations to improve schedules.

Prerequisites
NOTE
The new schedule board is released as a public preview in April 2020. It has limited capabilities during the preview period.

Enable new schedule board preview


Once you enable the new schedule board, you'll see it in your environment alongside the current schedule board.
Once the new schedule board functionality matches the current schedule board, the new will replace the current.
To enable the new schedule board, sign in as a system administrator.
Go to Resource Scheduling > Settings > Administration > Modify Schedule Board Settings .

1. Go to Controls tab.
2. Enable it for web experience.
3. Select the edit button then Enable Preview .
4. Publish changes.
Go to the schedule board and use the toggle button in the top right of the schedule board to switch between the
current and preview schedule boards.

Configuration considerations
During preview, the new schedule board is only available in English.
The new schedule board will currently only appear within the Universal Resource Scheduling app - not yet
available in other apps.
After enabling the preview, if you uninstall the Universal Resource Scheduling solution, you'll have to disable the
schedule board again.
The new schedule board is currently supported on Microsoft Edge, Chrome, and Firefox browsers. Currently,
Internet Explorer 11 is not supported.
When to use the new versus current schedule board
Users who perform simple drag and drop scheduling or users who only need to view the schedule board can use
the new schedule board during preview. Other users should continue to use the current schedule board.
Continue to use the current schedule board for common functions like:
Creating and deleting schedule board tabs.
Schedule board tab settings.
Schedule board configurations like number of days in a view or applying filter territories.
Map view and scheduling.
Days, weeks, and months view.
Add new schedule board to custom sitemap area
When using a custom sitemap or an app module, you'll need to update the sitemap to consume the new schedule
board preview.
The following snippet is what it looks like before:
<SubArea Id="msdyn_ScheduleBoardSubArea" ResourceId="SitemapDesigner.NewSubArea"
VectorIcon="$webresource:msdyn_/Icons/SVG/Calendar.svg"
Url="$webresource:msdyn_/fps/ScheduleBoard/ScheduleBoard.html"
Client="All,Outlook,OutlookLaptopClient,OutlookWorkstationClient,Web" AvailableOffline="true" PassParams="false"
Sku="All,OnPremise,Live,SPLA">

The next snippet is what it looks like after:


<SubArea Id="msdyn_ScheduleBoardSubArea" ResourceId="SitemapDesigner.NewSubArea"
VectorIcon="$webresource:msdyn_/Icons/SVG/Calendar.svg" Url="/main.aspx?
pagetype=entitylist&amp;etn=msdyn_scheduleboardsetting"
Client="All,Outlook,OutlookLaptopClient,OutlookWorkstationClient,Web" AvailableOffline="true" PassParams="false"
Sku="All,OnPremise,Live,SPLA">
URL:
/main.aspx?pagetype=entitylist&etn=msdyn_scheduleboardsetting

ID:
msdyn_scheduleboardtoggle

Additional notes
The schedule board is only supported in Unified Client Interface web (Field Service v8.x+) and not in tablets or
phones.
Uninstall schedule board preview
To uninstall the new schedule board preview solution ("Resource Scheduling Controls"), perform the following
steps.
1. Go to the Schedule Board Settings entity customization form.
2. Remove the new schedule board preview control from the grid.
3. Save and publish the changes.
4. Go to the resource scheduling app, clear the browser's cache, and reload schedule board. The old schedule
board will load without the preview toggle in the top right of the screen.
5. Once the solution is uninstalled, the new schedule board will not be available for the environment until you
upgrade your Field Service app to the latest available version.
URS extensibility updates
10/1/2019 • 4 minutes to read • Edit Online

October 2018
May 2018
April 2018
February 2018
December 2017
July 2017

October 2018
Intervals
The schedule assistant now supports a feature called intervals. When searching for availability using a single
requirement (or a requirement group), the requirement can be related to a fulfillment preference ( msdyn_timegroup
) record, through the lookup field on the requirement called fulfillment preference ( msdyn_timegroup ). On the
fulfillment preference record, there are settings to define what intervals ( msdyn_interval ) the results should be
rounded to, and how many results a scheduler should see per interval ( msdyn_resultsperinterval ) when using the
schedule assistant list view. There are also other settings related to intervals, such as ( msdyn_intervalsbegin ) and (
msdyn_resetpertimegroupdetail ), but there isn't support to change these values in the filter control of the schedule
assistant.

When scheduling a requirement group, the filter control is not yet extensible. Therefore, this feature will be
available to everyone out of the box when scheduling requirement groups even if the schedule assistant filter
layout was customized.

Schedule assistant filter layout


The default schedule assistant filter layout shipped in this update includes two new duration controls to allow you
to adjust the interval and the results per interval. If you have a custom schedule assistant filter layout, you can add
the below new controls to the control section in your schedule assistant filter layout configuration record.
The added Interval property:

<control type="duration" key="Requirement/msdyn_interval" label-id="Interval" min="1" default-value="1" />

The added ResultsPerInterval property:

<control type="number" key="Requirement/msdyn_resultsperinterval" label-id="FilterControl_ResultsPerInterval"


min="0" default-value="0" />

Retrieve constraints query


The default retrieve constraints query shipped in this update includes the query to retrieve the Interval and
ResultsPerInterval values. To change the default value for this parameter, or if you have a custom retrieve
constraints query, update or add the below to your retrieve constraints query configuration record.
<link-entity name='msdyn_timegroup' from='msdyn_timegroupid' to='msdyn_timegroup' link-type='outer'
alias="tg">
<attribute name='msdyn_interval' alias="msdyn_interval" />
<attribute name='msdyn_resultsperinterval' alias="msdyn_resultsperinterval" />
</link-entity>

May 2018
Resource cell template
Hide resource image
The default resource cell template shipped in this update includes support for automatically hiding the resource
image if the resource row in the Schedule Board is configured to a small height. If you have a custom resource cell
template, add the below template updates to your resource cell template configuration record.
The first and last line are newly introduced to light up the functionality. The updated markup to hide the resource
image:

{{#if (or (eq (is-sa-grid-view) true) (eq (is-row-small) false)) }}


{{#if imagepath}}
<img class='resource-image' src='{{client-url}}{{imagepath}}' />
{{else}}
<div class='resource-image unknown-resource'></div>
{{/if}}
{{/if}}

The first line is new. The updated markup to hide the second row of text in the template:

{{#if (and (eq (is-sa-grid-view) false) (eq (is-row-small) false)) }}


<div class='booked-duration'>{{BookedDuration}}<div class='fo-sch-clock'></div></div>
<div class='booked-percentage'>{{BookedPercentage}}%</div>
{{/if}}

For more context, see this article - https://docs.microsoft.com/business-applications-release-


notes/april18/dynamics365-field-service/removed-resource-image

April 2018
Retrieve Constraints Query
Ignore proposed bookings
The default Retrieve Constraints Query shipped in this update includes a default value for the Ignore Proposed
Bookings parameter used by the Schedule Assistant. To change the default value for this parameter, or if you have a
custom Retrieve Constraints Query, update or add the below new property to the Requirement bag transformation
part in your Retrieve Constraints Query configuration record.
The added IgnoreProposedBookings property:

<IgnoreProposedBookings ufx-type="bool">true</IgnoreProposedBookings>

Here is a link to an article with more context on ignore proposed functionality -


https://docs.microsoft.com/business-applications-release-notes/april18/dynamics365-field-service/ignore-
proposed-bookings
February 2018
Schedule Assistant Filter Layout
Ignore proposed bookings
The default Schedule Assistant Filter Layout shipped in this update includes a new checkbox control to set the
Ignore Proposed Bookings parameter used by the Schedule Assistant. If you have a custom Schedule Assistant
Filter Layout, add the below new control to the last fieldset control section in your Schedule Assistant Filter
Layout configuration record.
The new IgnoreProposedBookings control

<control type="boolean" key="Requirement/IgnoreProposedBookings" label-


id="ScheduleAssistant.West.settingsform.IgnoreProposedBookings" />

Here is a link to an article with more context on ignore proposed functionality -


https://docs.microsoft.com/business-applications-release-notes/april18/dynamics365-field-service/ignore-
proposed-bookings

December 2017
Retrieve Resources Query
Schedule Board visible date range
Included in this update, the Retrieve Resources Query gets as input the visible date range of the Schedule Board.
This lets the query use the board's date range in its database queries. The default Retrieve Resources Query
shipped in this update has not changed. However, you can now customize the query to depend on the board's
visible date range.
The updated input parameters available in the XPath $input variable are ScheduleBoard/StartDate and
ScheduleBoard/EndDate .

The below snippet (not shipped) shows how the new input parameters can be used to query the total number of
bookings per resource in the date range visible on the board.

<!-- Booking join -->


<link-entity name="bookableresourcebooking" from="resource" to="bookableresourceid" link-type="outer">
<attribute name="name" aggregate="countcolumn" alias="bookingcount" />

<filter>
<condition attribute="statecode" operator="eq" value="0" />
<condition attribute="starttime" operator="le">
<ufx:value select="$input/ScheduleBoard/EndDate" attribute="value" />
</condition>
<condition attribute="endtime" operator="ge">
<ufx:value select="$input/ScheduleBoard/StartDate" attribute="value" />
</condition>
</filter>
</link-entity>

The below snippet (not shipped) shows how the Resource Cell Template can then be customized to show the total
number of bookings.

<div>Booking Count: {{bookingcount}}</div>

When changing the dates on the Schedule Board, the Resource Query is not automatically executed again.
Rather, you must click the search button to re-execute the search using the new Schedule Board visible dates.
For more context, here is a blog post on the subject - https://blogs.msdn.microsoft.com/crm/2017/12/15/new-
use-schedule-board-date-ranges-in-custom-queries-in-universal-resource-scheduling/

Schedule Assistant Filter Layout


Sort by total availability
The default Schedule Assistant Filter Layout shipped in this update includes a new order option to sort the result of
the Schedule Assistant by a resource's total availability. If you have a custom Schedule Assistant Filter Layout, add
the below new order option to the order control in your Schedule Assistant Filter Layout configuration record.
The new sort option

<order name="totalavailabletime" entity="bookableresource" attribute="totalavailabletime" label-


id="ScheduleAssistant.Center.slotsgrid.TotalAvailableTime" />

For more context on the scenario, here is a blog post -


https://blogs.msdn.microsoft.com/crm/2017/12/15/sort-available-resources-by-total-available-time-in-
universal-resource-scheduling/

July 2017
The July 2017 update for URS was the initial release for extensible queries, custom filter layouts, and resource cell
template
Extend Universal Resource Scheduling actions to use
your preferred geospatial data provider (Field
Service, Project Service Automation)
10/1/2019 • 2 minutes to read • Edit Online

You can create a custom plug-in and register on the Universal Resource Scheduling actions that provide geospatial
functionality to use data from a data provider of your choice instead of the default Bing Maps API.
The following Universal Resource Scheduling actions provide geospatial functionality in Dynamics 365 Field
Service and Dynamics 365 Project Service Automation:
msdyn_GeocodeAddress for geocoding addresses
msdyn_RetrieveDistanceMatrix for calculating travel times and distances between two locations.
The Field Service and Project Service Automation solutions contain a plug-in registered on these two actions that,
by default, uses the data provided by Bing Maps API to perform geospatial operations.
Create custom plug-in to use your preferred geospatial data provider
See also
Register and deploy custom plug-in to use your preferred geospatial data provider
Sample: Custom plug-in to use Google Maps API as geospatial data provider
Universal Resource Scheduling
Create custom plug-in to use your preferred
geospatial data provider
10/1/2019 • 5 minutes to read • Edit Online

This topic provides information about the two geospatial actions in Universal Resource Scheduling, how to create a
custom plug-in for the two geospatial actions, and provides examples from a sample custom plug-in on using
Google Maps API for geospatial data.

Input and output parameters for geospatial actions


While writing your custom plug-in, you will have to consider the input and output parameters for the geospatial
actions in so that you know what data to pass in and the expected output data in your plug-in code.
There are two ways in which you can view the input and output parameters for the two geospatial actions:
Web API action reference content : View reference information about the geospatial actions in Universal
Resource Scheduling.
<xref:Microsoft.Dynamics.CRM.msdyn_GeocodeAddress>
msdyn_RetrieveDistanceMatrix
Action definition : You can view the action definition in Dynamics 365 for information about the
input/output prameters, including information whether a parametr is required or optional.
To view an action definition, select Settings > Processes . Next, search for the action name: Resource
Scheduling - Geocode Address or Resource Scheduling - Retrieve Distance Matrix , and then select
the action in the grid to display its definition. For example, here is the definition of the Resource
Scheduling - Geocode Address (msdyn_GeocodeAddress ) action where the highlighted area provides
information about the input and output parameters:
Write your custom plug-in
Plug-ins are custom classes that implement the IPlugin interface. For detailed information about creating a plug-in,
see Plug-in development
A custom plug-in sample is provided for your reference that demonstrates how to use the Google Maps API to
provide geospatial data for field operations instead of the default Bing Maps API. More information: Sample:
Custom plug-in to use Google Maps API as geospatial data provider.
The following code in each sample plug-in uses data from the Google API:
ExecuteGeocodeAddress method in the msdyn_GeocodeAddress.cs plug-in file

public void ExecuteGeocodeAddress(IPluginExecutionContext pluginExecutionContext, IOrganizationService


organizationService, ITracingService tracingService)
{
//Contains 5 fields (string) for individual parts of an address
ParameterCollection InputParameters = pluginExecutionContext.InputParameters;
// Contains 2 fields (double) for resultant geolocation
ParameterCollection OutputParameters = pluginExecutionContext.OutputParameters;
//Contains 1 field (int) for status of previous and this plugin
ParameterCollection SharedVariables = pluginExecutionContext.SharedVariables;

tracingService.Trace("ExecuteGeocodeAddress started. InputParameters = {0}, OutputParameters = {1}",


InputParameters.Count().ToString(), OutputParameters.Count().ToString());

try
{
// If a plugin earlier in the pipeline has already geocoded successfully, quit
if ((double)OutputParameters[LatitudeKey] != 0d || (double)OutputParameters[LongitudeKey] != 0d)
return;

// Get user Lcid if request did not include it


int Lcid = (int)InputParameters[LcidKey];
int Lcid = (int)InputParameters[LcidKey];
string _address = string.Empty;
if (Lcid == 0)
{
var userSettingsQuery = new QueryExpression("usersettings");
userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid");
userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal,
pluginExecutionContext.InitiatingUserId);
var userSettings = organizationService.RetrieveMultiple(userSettingsQuery);
if (userSettings.Entities.Count > 0)
Lcid = (int)userSettings.Entities[0]["uilanguageid"];
}

// Arrange the address components in a single comma-separated string, according to LCID


_address = GisUtility.FormatInternationalAddress(Lcid,
(string)InputParameters[Address1Key],
(string)InputParameters[PostalCodeKey],
(string)InputParameters[CityKey],
(string)InputParameters[StateKey],
(string)InputParameters[CountryKey]);

// Make Geocoding call to Google API


WebClient client = new WebClient();
var url = $"https://{GoogleConstants.GoogleApiServer}{GoogleConstants.GoogleGeocodePath}/json?address=
{_address}&key={GoogleConstants.GoogleApiKey}";
tracingService.Trace($"Calling {url}\n");
string response = client.DownloadString(url); // Post ...

tracingService.Trace("Parsing response ...\n");


DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(GeocodeResponse));
// Deserialize response json
object objResponse = jsonSerializer.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(response)));
// Get response as an object
GeocodeResponse geocodeResponse = objResponse as GeocodeResponse; // Unbox into our data
contracted class for response

tracingService.Trace("Response Status = " + geocodeResponse.Status + "\n");


if (geocodeResponse.Status != "OK")
throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application error
(Status {geocodeResponse.Status}).");

tracingService.Trace("Checking geocodeResponse.Result...\n");
if (geocodeResponse.Results != null)
{
if (geocodeResponse.Results.Count() == 1)
{
tracingService.Trace("Checking geocodeResponse.Result.Geometry.Location...\n");
if (geocodeResponse.Results.First()?.Geometry?.Location != null)
{
tracingService.Trace("Setting Latitude, Longitude in OutputParameters...\n");

// update output parameters


OutputParameters[LatitudeKey] = geocodeResponse.Results.First().Geometry.Location.Lat;
OutputParameters[LongitudeKey] = geocodeResponse.Results.First().Geometry.Location.Lng;

}
else throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application
error (missing Results[0].Geometry.Location)");
}
else throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application error
(more than 1 result returned)");
}
else throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application error
(missing Results)");
}
catch (Exception ex)
{
// Signal to subsequent plugins in this message pipeline that geocoding failed here.
OutputParameters[LatitudeKey] = 0d;
OutputParameters[LongitudeKey] = 0d;
OutputParameters[LongitudeKey] = 0d;

//TODO: You may need to decide which caught exceptions will rethrow and which ones will simply signal
geocoding did not complete.
throw new InvalidPluginExecutionException(string.Format("Geocoding failed at {0} with exception --
{1}: {2}"
, GoogleConstants.GoogleApiServer, ex.GetType().ToString(), ex.Message), ex);
}

ExecuteDistanceMatrix method in the msdyn_RetrieveDistanceMatrix.cs plug-in file

public void ExecuteDistanceMatrix(IPluginExecutionContext pluginExecutionContext, IOrganizationService


organizationService, ITracingService tracingService)
{
//Contains 2 fields (EntityCollection) for sources and targets
ParameterCollection InputParameters = pluginExecutionContext.InputParameters;
// Contains 1 field (EntityCollection) for results
ParameterCollection OutputParameters = pluginExecutionContext.OutputParameters;
//Contains 1 field (int) for status of previous and this plugin
ParameterCollection SharedVariables = pluginExecutionContext.SharedVariables;

tracingService.Trace("ExecuteDistanceMatrix started. InputParameters = {0},OutputParameters = {1}",


InputParameters.Count().ToString(), OutputParameters.Count().ToString());

try
{
// If a plugin earlier in the pipeline has already retrieved a distance matrix successfully, quit
if (OutputParameters[MatrixKey] != null)
if (((EntityCollection)OutputParameters[MatrixKey]).Entities != null)
if (((EntityCollection)OutputParameters[MatrixKey]).Entities.Count > 0) return;

// Make Distance Matrix call to Google API


WebClient client = new WebClient();
var url = String.Format($"https://{GoogleConstants.GoogleApiServer}
{GoogleConstants.GoogleDistanceMatrixPath}/json"
+ "?units=imperial"
+ $"&origins={string.Join("|", ((EntityCollection)InputParameters[SourcesKey]).Entities.Select(e
=> e.GetAttributeValue<double?>("latitude") + "," + e.GetAttributeValue<double?>("longitude")))}"
+ $"&destinations={string.Join("|",
((EntityCollection)InputParameters[TargetsKey]).Entities.Select(e => e.GetAttributeValue<double?>("latitude")
+ "," + e.GetAttributeValue<double?>("longitude")))}"
+ $"&key={GoogleConstants.GoogleApiKey}");
tracingService.Trace($"Calling {url}\n");
string response = client.DownloadString(url); // Post ...

tracingService.Trace("Parsing response ...\n");


DataContractJsonSerializer jsonSerializer = new
DataContractJsonSerializer(typeof(DistanceMatrixResponse)); // Deserialize response json
object objResponse = jsonSerializer.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(response)));
// Get response as an object
DistanceMatrixResponse distancematrixResponse = objResponse as DistanceMatrixResponse; // Unbox
as our data contracted class for response

tracingService.Trace("Response Status = " + distancematrixResponse.Status + "\n");


if (distancematrixResponse.Status != "OK")
throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application error
(Status={distancematrixResponse.Status}). {distancematrixResponse.ErrorMessage}");

tracingService.Trace("Checking distancematrixResponse.Results...\n");
if (distancematrixResponse.Rows != null)
{
tracingService.Trace("Parsing distancematrixResponse.Results.Elements...\n");

// build and update output parameter


var result = new EntityCollection();
result.Entities.AddRange(distancematrixResponse.Rows.Select(r => ToEntity(r.Columns.Select(c =>
result.Entities.AddRange(distancematrixResponse.Rows.Select(r => ToEntity(r.Columns.Select(c =>
ToEntity(c.Status, c.Duration, c.Distance)).ToArray())));
OutputParameters[MatrixKey] = result;

}
else throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application error
(missing Rows)");
}
catch (Exception ex)
{
// Signal to subsequent plugins in this message pipeline that retrieval of distance matrix failed
here.
OutputParameters[MatrixKey] = null;

//TODO: You may need to decide which caught exceptions will rethrow and which ones will simply signal
geocoding did not complete.
throw new InvalidPluginExecutionException(string.Format("Geocoding failed at {0} with exception --
{1}: {2}"
, GoogleConstants.GoogleApiServer, ex.GetType().ToString(), ex.Message), ex);
}

// For debugging purposes, throw an exception to see the details of the parameters
CreateExceptionWithDetails("Debugging...", InputParameters, OutputParameters, SharedVariables);
}

After you have written your custom plug-in code, build the project to generate a plug-in assembly (.dll), which will
be used to register the plug-in on the Universal Resource Scheduling geospatial actions.
Register and deploy custom plug-in to use your preferred geospatial data provider
Register and deploy custom plug-in to use your
preferred geospatial data provider
10/1/2019 • 5 minutes to read • Edit Online

Before a plug-in can be used, it must be registered and deployed on the server.
Building your plug-in project will result in a plug-in assembly (.dll). This topic provides information on how you
can register and deploy the plug-in assembly for the two geospatial actions to use your preferred geospatial data
provider. For information about writing a plugin, see Create custom plug-in to use your preferred geospatial data
provider

Execution order considerations while registering your custom plug-in


When you register multiple plug-ins for the same entity and message, the execution sequence of plug-ins is
defined by the Execution Order of individual plug-ins. The one with a lower execution order value executes first
followed by the one with a higher execution order value.
The execution order value of the default plug-in in Field Service and Project Service that uses Bing Maps for the
geocode and distance matrix actions is set to 1 . You can set the execution order of your custom plug-in to execute
before (less than 1) or after (greater than 1) the default plug-in.
The following table depicts how you may want your custom plug-in to be treated depending on the execution
order specified while plug-in registration and parameter conditions.

Primar y If you want to treat your custom plug-in as primary and the
default Bing plug-in as secondary, set the execution order of
your plug-in to 0 . This will result in your plug-in getting
executed prior to the Bing plug-in. The Bing plug-in will
examine the "latitude" and "longitude" values that your
custom plug-in returns, and only proceeds to geocode with
Bing if both the returned values are 0. This would be the
preferred way if your custom plug-in is expected to provide
the majority of your geocoding needs.

Secondar y If you want to treat your custom plug-in as secondary to Bing


plug-in by providing the geocoding service only when Bing
fails to geocode, set the execution order of your plugin to 2 .
You would also write your custom plug-in code such that it
first examines the "latitude" and "longitude" values that Bing
plug-in returns, and proceeds only if both the returned values
are 0. This would be the preferred execution way if Bing is
expected to provide the majority of your geocoding needs.

Completely override If you always want your custom plug-in to be the source of
geocoding and completely override Bing from geocoding even
when your custom plug-in fails to geocode, you will need to
always return something other than 0,0 for "latitude" and
"longitude" values. You may want to decide which exception
conditions throw a .NET exception and which ones simply do
not return a result. To not return a result and not allow any
subsequent plug-in to return a result, your custom plug-in
needs to return something like 0.0001, 0.0001.
Register and deploy your custom plug-in
You can register and deploy plug-ins using the Plug-in Registration Tool or programmatically by writing
registration code using certain SDK classes. More information: Register and Deploy Plug-ins.
For this section, we will use the Plug-in Registration tool, which provides a graphical user interface to easily
register and deploy plug-ins. Also, this section contains information based on the assumption that you are working
with the sample custom plug-in, and have built the sample project to generate the CustomPlugin-FS-
Geospatial.dll assembly. If you have developed your own custom plug-in, the name of the assembly and plug-ins
will differ, but the overall instructions to register the plug-in will remain the same.

TIP
For detailed information about how to use Plug-in Registration Tool in general, see Walkthrough: Register a plug-in using the
plug-in registration tool

1. Get the Plug-in Registration Tool. To get the Plug-in Registration Tool, see Download tools from NuGet.
2. Navigate to the [Your folder]\Tools\PluginRegistration folder, and double-click the
PluginRegistration.exe file to run the tool.
3. Click CREATE NEW CONNECTION .
4. In the Login dialog, specify the credentials to connect to your Dynamics 365 instance, and click Login .
5. If you have access to multiple organizations in the Dynamics 365 instance, you are prseneted with a list of
organizations to choose to connect to. Otherwise, your default organization is used.
6. You should see a collapsed list of registered plug-in or custom workflow activity assemblies. Select
Register > Register New Assembly .
7. In the Register New Assembly dialog box:
Under the Step 1 section, click the ellipses […] button to select the CustomPlugin-FS-
Geospatial.dll assembly.
Under the Step 2 section, select both the plug-ins.
Under the Step 3 section, select the Sandbox option.
Under the Step 4 section, select the Database option.
Select Register Selected Plugins .
The CustomPlugin-FS-Geospatial.dll assembly and the two plug-ins for the
msdyn_GeocodeAddress and msdyn_RetrieveDistanceMatrix are now registered and deployed to the
server.
8. The next step is to register a step for each action. A step refers to the SDK message processing step entity
that is used to configure when and how the plug-in is to be executed.
In the Registered Plug-ins & Custom Workflow Activities tree view, expand the (Assembly)
CustomPlugin-FS-Geospatial node, and select a registered plug-in, say
Microsoft.Crm.Sdk .Samples.msdyn_RetrieveDistanceMatrix .
9. Right-click Microsoft.Crm.Sdk .Samples.msdyn_RetrieveDistanceMatrix , and select Register New
Step .
10. In the Register New Step dialog box, specify the following:
Message : msdyn_RetrieveDistanceMatrix
Execution Order : As required. See Execution order considerations while registering your custom plug-
in earlier in this topic.
Event Pipeline Stage of Execution : PostOperation
Execution Mode : Synchronous
Leave the rest of the fields with their default values. Click Register New Step .

11. Next, right-click the Microsoft.Crm.Sdk .Samples.msdyn_GeocodeAddress plug-in, and select


Register New Step .
12. In the Register New Step dialog box, specify the following:
Message : msdyn_GeocodeAddress
Execution Order : As required. See Execution order considerations while registering your custom plug-
in earlier in this topic.
Event Pipeline Stage of Execution : PostOperation
Execution Mode : Synchronous
Leave the rest of the fields with their default values. Click Register New Step .

You are now done with registering steps to call your custom plug-in for the both the geospatial actions.
If you view any of the Universal Resource Scheduling geospatial actions in the Plug-in Registration tool, you will
see both the default and your custom plug-in registered for the action. For example, see the plug-ins for the
mdyn_GeocodeAddress action.

See also
Sample: Custom plug-in to use Google Maps API as geospatial data provider
Sample: Custom plug-in to use Google Maps API as
geospatial data provider
4/1/2020 • 8 minutes to read • Edit Online

You can use a custom plug-in to use geospatial data from a data provider of your choice instead of using the
default Bing Maps API in Field Service and Project Service.
Sample is available here: Custom plug-in to use Google Maps API as geospatial data provider (Dynamics 365)

Prerequisites
Internet connection is required to download the sample project and to restore the NuGet packages used in the
sample project.

Requirements
Dynamics 365 Field Service solution must be installed on your Dynamics 365 (online) instance. More
information: Install and setup Field Service
Provide your own Google API key in the GoogleDataContracts.cs file in the sample:
public const string GoogleApiKey = "<PROVIDE YOUR GOOGLE API KEY";

Demonstrates
This sample shows how to create a custom plug-in for the msdyn_GeocodeAddress and
msdyn_RetrieveDistanceMatrix actions in Universal Resource Scheduling to use Google Maps API for
geospatial data instead of using the default Bing Maps API.

Run the sample


This sample generates a plug-in assembly file: CustomPlugin-FS-Geospatial.dll .
1. Download or clone the samples repo.
2. Navigate to the loaction where you downloaded or cloned the repo on your computer, go to the field-
ser vice/CustomPlugin-FS-Geospatial folder, and double-click the CustomPlugin-FS-Geospatial.sln file
to open the solution in Visual Studio.
3. In Visual Studio, select Build > Build Solution . The NuGet packages used in the solution will download
automatically if the option to restore NuGet packages automatically on building a project is enabled in Visual
Studio. More information: Enabling and disabling package restore

After running the sample


After you have succesfully run (build) the sample, a custom plug-in assembly file, CustomPlugin-FS-
Geospatial.dll , will become available in the <Project>\bin\debug folder. You must register the sample custom
plug-in assembly on your Dynamics 365 (online) instance to be able to use the plug-in to use the Google Maps
API instead of the default Bing Maps API. More information: Register and deploy your custom plug-in

Plug-in sample code for msdyn_GeocodeAddress action


using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using Microsoft.Crm.Sdk.Samples.GoogleDataContracts;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace Microsoft.Crm.Sdk.Samples
{

/// <summary>
/// msdyn_GeocodeAddress Plugin.
/// </summary>
public class msdyn_GeocodeAddress : IPlugin
{
const string PluginStatusCodeKey = "PluginStatus";
const string Address1Key = "Line1";
const string CityKey = "City";
const string StateKey = "StateOrProvince";
const string PostalCodeKey = "PostalCode";
const string CountryKey = "Country";
const string LatitudeKey = "Latitude";
const string LongitudeKey = "Longitude";
const string LcidKey = "Lcid";

public void Execute(IServiceProvider serviceProvider)


{
if (serviceProvider == null)
{
throw new InvalidPluginExecutionException("serviceProvider");
}

// Obtain the execution context service from the service provider.


IPluginExecutionContext PluginExecutionContext =
(IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

// Obtain the organization factory service from the service provider.


IOrganizationServiceFactory factory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

// Use the factory to generate the organization service.


IOrganizationService OrganizationService =
factory.CreateOrganizationService(PluginExecutionContext.UserId);

// Obtain the tracing service from the service provider.


ITracingService TracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));

ExecuteGeocodeAddress(PluginExecutionContext, OrganizationService, TracingService);

/// <summary>
/// Retrieve geocode address using Google Api
/// </summary>
/// <param name="pluginExecutionContext">Execution context</param>
/// <param name="organizationService">Organization service</param>
/// <param name="tracingService">Tracing service</param>
/// <param name="notificationService">Notification service</param>
public void ExecuteGeocodeAddress(IPluginExecutionContext pluginExecutionContext, IOrganizationService
organizationService, ITracingService tracingService)
{
//Contains 5 fields (string) for individual parts of an address
ParameterCollection InputParameters = pluginExecutionContext.InputParameters;
// Contains 2 fields (double) for resultant geolocation
// Contains 2 fields (double) for resultant geolocation
ParameterCollection OutputParameters = pluginExecutionContext.OutputParameters;
//Contains 1 field (int) for status of previous and this plugin
ParameterCollection SharedVariables = pluginExecutionContext.SharedVariables;

tracingService.Trace("ExecuteGeocodeAddress started. InputParameters = {0}, OutputParameters =


{1}", InputParameters.Count().ToString(), OutputParameters.Count().ToString());

try
{
// If a plugin earlier in the pipeline has already geocoded successfully, quit
if ((double)OutputParameters[LatitudeKey] != 0d || (double)OutputParameters[LongitudeKey] !=
0d) return;

// Get user Lcid if request did not include it


int Lcid = (int)InputParameters[LcidKey];
string _address = string.Empty;
if (Lcid == 0)
{
var userSettingsQuery = new QueryExpression("usersettings");
userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid");
userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal,
pluginExecutionContext.InitiatingUserId);
var userSettings = organizationService.RetrieveMultiple(userSettingsQuery);
if (userSettings.Entities.Count > 0)
Lcid = (int)userSettings.Entities[0]["uilanguageid"];
}

// Arrange the address components in a single comma-separated string, according to LCID


_address = GisUtility.FormatInternationalAddress(Lcid,
(string)InputParameters[Address1Key],
(string)InputParameters[PostalCodeKey],
(string)InputParameters[CityKey],
(string)InputParameters[StateKey],
(string)InputParameters[CountryKey]);

// Make Geocoding call to Google API


WebClient client = new WebClient();
var url = $"https://{GoogleConstants.GoogleApiServer}{GoogleConstants.GoogleGeocodePath}/json?
address={_address}&key={GoogleConstants.GoogleApiKey}";
tracingService.Trace($"Calling {url}\n");
string response = client.DownloadString(url); // Post ...

tracingService.Trace("Parsing response ...\n");


DataContractJsonSerializer jsonSerializer = new
DataContractJsonSerializer(typeof(GeocodeResponse)); // Deserialize response json
object objResponse = jsonSerializer.ReadObject(new
MemoryStream(Encoding.UTF8.GetBytes(response))); // Get response as an object
GeocodeResponse geocodeResponse = objResponse as GeocodeResponse; // Unbox into our data
contracted class for response

tracingService.Trace("Response Status = " + geocodeResponse.Status + "\n");


if (geocodeResponse.Status != "OK")
throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application
error (Status {geocodeResponse.Status}).");

tracingService.Trace("Checking geocodeResponse.Result...\n");
if (geocodeResponse.Results != null)
{
if (geocodeResponse.Results.Count() == 1)
{
tracingService.Trace("Checking geocodeResponse.Result.Geometry.Location...\n");
if (geocodeResponse.Results.First()?.Geometry?.Location != null)
{
tracingService.Trace("Setting Latitude, Longitude in OutputParameters...\n");

// update output parameters


OutputParameters[LatitudeKey] =
geocodeResponse.Results.First().Geometry.Location.Lat;
geocodeResponse.Results.First().Geometry.Location.Lat;
OutputParameters[LongitudeKey] =
geocodeResponse.Results.First().Geometry.Location.Lng;

}
else throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer}
application error (missing Results[0].Geometry.Location)");
}
else throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application
error (more than 1 result returned)");
}
else throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application
error (missing Results)");
}
catch (Exception ex)
{
// Signal to subsequent plugins in this message pipeline that geocoding failed here.
OutputParameters[LatitudeKey] = 0d;
OutputParameters[LongitudeKey] = 0d;

//TODO: You may need to decide which caught exceptions will rethrow and which ones will simply
signal geocoding did not complete.
throw new InvalidPluginExecutionException(string.Format("Geocoding failed at {0} with
exception -- {1}: {2}"
, GoogleConstants.GoogleApiServer, ex.GetType().ToString(), ex.Message), ex);
}

}
}
}

Plug-in sample code for msdyn_RetrieveDistanceMatrix action


using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using Microsoft.Crm.Sdk.Samples.GoogleDataContracts;
using Microsoft.Xrm.Sdk;
using static Microsoft.Crm.Sdk.Samples.GoogleDataContracts.DistanceMatrixResponse.CResult.CElement;

namespace Microsoft.Crm.Sdk.Samples
{

/// <summary>
/// msdyn_RetrieveDistanceMatrix Plugin.
/// </summary>
public class msdyn_RetrieveDistance : IPlugin
{
const string PluginStatusCodeKey = "PluginStatus";
const string SourcesKey = "Sources";
const string TargetsKey = "Targets";
const string MatrixKey = "Result";

/// <summary>
/// Initializes a new instance of the msdyn_RetrieveDistance class
/// </summary>
/// <param name="unsecure"></param>
/// <param name="secure"></param>
public msdyn_RetrieveDistance(string unsecure, string secure)
{
// TODO: Implement your custom configuration handling.
}

/// <summary>
/// <summary>
/// Execute the plugin
/// </summary>
/// <param name="serviceProvider"></param>
public void Execute(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
{
throw new InvalidPluginExecutionException("serviceProvider");
}

// Obtain the execution context service from the service provider.


IPluginExecutionContext PluginExecutionContext =
(IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

// Obtain the organization factory service from the service provider.


IOrganizationServiceFactory factory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

// Use the factory to generate the organization service.


IOrganizationService OrganizationService =
factory.CreateOrganizationService(PluginExecutionContext.UserId);

// Obtain the tracing service from the service provider.


ITracingService TracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));

ExecuteDistanceMatrix(PluginExecutionContext, OrganizationService, TracingService);

public void ExecuteDistanceMatrix(IPluginExecutionContext pluginExecutionContext, IOrganizationService


organizationService, ITracingService tracingService)
{
//Contains 2 fields (EntityCollection) for sources and targets
ParameterCollection InputParameters = pluginExecutionContext.InputParameters;
// Contains 1 field (EntityCollection) for results
ParameterCollection OutputParameters = pluginExecutionContext.OutputParameters;
//Contains 1 field (int) for status of previous and this plugin
ParameterCollection SharedVariables = pluginExecutionContext.SharedVariables;

tracingService.Trace("ExecuteDistanceMatrix started. InputParameters = {0},OutputParameters =


{1}", InputParameters.Count().ToString(), OutputParameters.Count().ToString());

try
{
// If a plugin earlier in the pipeline has already retrieved a distance matrix successfully,
quit
if (OutputParameters[MatrixKey] != null)
if (((EntityCollection)OutputParameters[MatrixKey]).Entities != null)
if (((EntityCollection)OutputParameters[MatrixKey]).Entities.Count > 0) return;

// Make Distance Matrix call to Google API


WebClient client = new WebClient();
var url = String.Format($"https://{GoogleConstants.GoogleApiServer}
{GoogleConstants.GoogleDistanceMatrixPath}/json"
+ "?units=imperial"
+ $"&origins={string.Join("|",
((EntityCollection)InputParameters[SourcesKey]).Entities.Select(e => e.GetAttributeValue<double?>("latitude")
+ "," + e.GetAttributeValue<double?>("longitude")))}"
+ $"&destinations={string.Join("|",
((EntityCollection)InputParameters[TargetsKey]).Entities.Select(e => e.GetAttributeValue<double?>("latitude")
+ "," + e.GetAttributeValue<double?>("longitude")))}"
+ $"&key={GoogleConstants.GoogleApiKey}");
tracingService.Trace($"Calling {url}\n");
string response = client.DownloadString(url); // Post ...

tracingService.Trace("Parsing response ...\n");


DataContractJsonSerializer jsonSerializer = new
DataContractJsonSerializer(typeof(DistanceMatrixResponse)); // Deserialize response json
DataContractJsonSerializer(typeof(DistanceMatrixResponse)); // Deserialize response json
object objResponse = jsonSerializer.ReadObject(new
MemoryStream(Encoding.UTF8.GetBytes(response))); // Get response as an object
DistanceMatrixResponse distancematrixResponse = objResponse as DistanceMatrixResponse;
// Unbox as our data contracted class for response

tracingService.Trace("Response Status = " + distancematrixResponse.Status + "\n");


if (distancematrixResponse.Status != "OK")
throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application
error (Status={distancematrixResponse.Status}). {distancematrixResponse.ErrorMessage}");

tracingService.Trace("Checking distancematrixResponse.Results...\n");
if (distancematrixResponse.Rows != null)
{
tracingService.Trace("Parsing distancematrixResponse.Results.Elements...\n");

// build and update output parameter


var result = new EntityCollection();
result.Entities.AddRange(distancematrixResponse.Rows.Select(r =>
ToEntity(r.Columns.Select(c => ToEntity(c.Status, c.Duration, c.Distance)).ToArray())));
OutputParameters[MatrixKey] = result;

}
else throw new ApplicationException($"Server {GoogleConstants.GoogleApiServer} application
error (missing Rows)");
}
catch (Exception ex)
{
// Signal to subsequent plugins in this message pipeline that retrieval of distance matrix
failed here.
OutputParameters[MatrixKey] = null;

//TODO: You may need to decide which caught exceptions will rethrow and which ones will simply
signal geocoding did not complete.
throw new InvalidPluginExecutionException(string.Format("Geocoding failed at {0} with
exception -- {1}: {2}"
, GoogleConstants.GoogleApiServer, ex.GetType().ToString(), ex.Message), ex);
}

// For debugging purposes, throw an exception to see the details of the parameters
CreateExceptionWithDetails("Debugging...", InputParameters, OutputParameters, SharedVariables);
}

private Entity ToEntity(string status, CProperty duration, CProperty meters)


{
var e = new Entity("organization");
e["status"] = status;
if (status.ToUpper() == "OK")
{
e["miles"] = meters.Value * 0.000621371d; // Convert to miles
e["duration"] = duration.Value;
}
else
{ // either NOT_FOUND or ZERO_RESULTS
e["miles"] = 0d;
e["duration"] = 0d;
}
return e;
}

private Entity ToEntity(params Entity[] entities)


{
var c = new EntityCollection();
c.Entities.AddRange(entities);
var e = new Entity("organization");
e[MatrixKey] = c;
return e;
}

private void CreateExceptionWithDetails(string message, ParameterCollection inputs,


private void CreateExceptionWithDetails(string message, ParameterCollection inputs,
ParameterCollection outputs, ParameterCollection shareds)
{
StringBuilder sb = new StringBuilder(message + "\n");
sb.AppendLine("InputParameters -- ");
foreach (var item in inputs)
{
sb.AppendLine("\t" + item.Key + " : '" + item.Value + "' ");
if (((EntityCollection)item.Value).Entities != null)
((EntityCollection)item.Value).Entities.ToList().ForEach(e => sb.AppendLine("\t\t" +
e.GetAttributeValue<double>("latitude").ToString() + "," + e.GetAttributeValue<double>
("longitude").ToString()));
}
if (outputs != null)
{
sb.AppendLine("OutputParameters -- ");
foreach (var item in outputs)
{
sb.AppendLine("\t" + item.Key + " : '" + item.Value + "' ");
if (item.Value != null)
if (((EntityCollection)item.Value).Entities != null)
((EntityCollection)item.Value).Entities.ToList().ForEach(r => {
sb.AppendLine("\t\t" + r.GetAttributeValue<EntityCollection>
(MatrixKey).ToString());
if (r.GetAttributeValue<EntityCollection>(MatrixKey).Entities != null)
r.GetAttributeValue<EntityCollection>
(MatrixKey).Entities.ToList().ForEach(e => sb.AppendLine("\t\t" + e.GetAttributeValue<double>
("distance").ToString() + "," + e.GetAttributeValue<double>("duration").ToString()));

});
}
}
sb.AppendLine("SharedVariables -- ");
foreach (var item in shareds) sb.AppendLine("\t" + item.Key + " : '" + item.Value + "' ");
throw new InvalidPluginExecutionException(sb.ToString());
}
}
}

Privacy notice disclaimer


You may use sample code to interact with third party services whose privacy and security practices may differ
from those of Microsoft Dynamics 365. IF YOU SUBMIT DATA TO THIRD PARTY SERVICES, SUCH DATA IS
GOVERNED BY THEIR RESPECTIVE PRIVACY STATEMENTS. For the avoidance of doubt, data shared outside of
Microsoft Dynamics 365 is not covered by your Microsoft Dynamics 365 agreement(s) or the Microsoft Dynamics
365 Trust Center. We encourage you to review these other privacy statements.
See also
Create custom plug-in to use your preferred geospatial data provider
Register and deploy custom plug-in to use your preferred geospatial data provider
Understanding and customizing resource matching in
Universal Resource Scheduling (URS)
10/1/2019 • 12 minutes to read • Edit Online

Universal Resource Scheduling (URS), the scheduling engine underlying Field Service and Project service, ships
with extensive resource matching capabilities to book the right resources for a job. While the URS solution ships
with Field and Project service, URS can also be used to schedule any workstream in Dynamics 365. In this article
we'll take a look at how the built-in resource constraints are implemented and how to customize URS with custom
resource constraints.

Resources, Requirements and Constraints


Resources
Core to Universal Resource Scheduling (URS) is the Resource ( bookableresource ) entity. When Booking (
bookableresourcebooking ) records are created, they are associated with a Resource record. To ensure the correct
resource is selected, URS ships with many built-in filters and constraints to categorize resources by. Examples are:
Resource Type, indicating if the resource is a User, Contact, Account, Equipment, etc., Characteristic, to filter
resources by skills they are proficient in, Territory, to assign resources to specific regions, Organizational Unit to
model an organization hierarchy, and many more.
A Resource record and its associated constraints are modeled through attributes or relationships to other entities.
For example, Name and Resource Type are attributes on the Resource entity. Resource Characteristics and Resource
Territories are child relationships since a resource can be associated with more than one of them. These entities are
child relationships to both the Resource AND the Characteristic/Territory entity. Organizational Unit is a lookup
attribute on the Resource entity to the Organizational Unit entity.
Requirements
Another important entity in URS is the Resource Requirement ( msdyn_resourcerequirement ) entity. The Requirement
entity records a requirement for work to be done. It captures parameters about the demanded work, such as the
From and To date fields, restricting the time period in which the work can be done; the Duration field for how long
the job is expected to take; the Work Location indicating the location of the required work. The Requirement entity
also captures resource constraints to restrict which resources can fulfill and be booked for this requirement. Like
the Resource entity, resource constraints are expressed as attributes on the Requirement entity or as relationships
to other entities. Territory is a lookup attribute from the Requirement entity to the Territory entity indicating the
territory the work is to be done in and, therefore, we must find a resource from the same territory. Requirement
Characteristic is a child relationship relating the Requirement to the Characteristic entity expressing the skills
required to complete the job and, therefore, the requirement can be matched to only resources with matching
skills.
Constraints shipped in URS
Following is the list of constraints that ship with URS:
Characteristics - Can be used to model skills a resource has. It also supports optional ratings values to rate how
proficient a resource is at each skill
Categories - Resources can be associated to categories
Territories - To assign resources to territorial regions
Organizational Units - To model an organization hierarchy
Resource Type - Defines the type of the resource
Teams - The teams a resource is a member of
Business Units - Which business unit the resource is part of
Filtering in the Schedule Board
The Schedule Board shows a list of resources and the bookings assigned to them. The Filter panel in the Schedule
Board lets you filter the list of resources by their constraints - e.g. selecting a resource type of User in the Resource
Type dropdown will filter the resource list to those which are of type User. Similarly, you can filter resources by
matching characteristics or territories.
Using the Filter panel to filter resources is one method of finding matching resources. This method is used when
you want to manually show a list of resources matching a specific set of constraints.
Finding available resources with the Schedule Assistant
In the bottom of the Schedule Board you'll find a list of Requirement records. You can select one of them and
choose to find availability. This action opens the Schedule Assistant. The Schedule Assistant uses the constraints
captured on the selected Requirement record to find matching resources that are available to be booked. Only
resources matching the constraints on the Requirement and which are available in the requested time period
specified on the Requirement are shown on the board.
A similar experience is available through a "Book" ribbon button available on the Requirement entity and other
schedulable entities in Dynamics 365 list views or forms. When "Book" is clicked, the Schedule Assistant is opened
showing resources matching the constraints of the selected Requirement record.
Unlike the previously mentioned Schedule Board mode, where you use the Filter panel to manually filters
resources, in Schedule Assistant mode, the Filter panel automatically fills in the resource constraints from the
Requirement record and only matching resources are shown.

How constraints matching works


Constraints entities
Some constraints are specified as attributes directly on the Resource entity while others are defined through
relationships. Relationships are needed when a constraint is referencing a 2nd, master entity.
Let's consider a Resource record and its associated Territory and Characteristic constraints.
First, the master records. We have territories stored in the Territory entity:

T ERRITO RY

New York

New Jersey

Seattle

We also have characteristics in the Characteristic entity:

C H A RA C T ERIST IC

Project Manager

Designer

Financial Analyst
Organizational Unit entity:

O RGA N IZ AT IO N A L UN IT

Contoso US

Contoso EU

Finally, we have the Resource entity:

RESO URC E RESO URC E T Y P E O RGA N IZ AT IO N A L UN IT

Jorge Galt User Contoso US

Abraham McCormick Contact Contoso EU

While a single Resource record works to capture single-valued constraints, like the Resource Type and
Organizational Unit above. If we want to associate a Resource to multiple Territory or Characteristic records, we
must use a 3rd entity, a many-to-many (N:N) relationship, to store these associations.
We use the Resource Territory entity to associate multiple territories for a resource.
Resource Territory Records:

RESO URC E T ERRITO RY

Jorge Galt New York

Jorge Galt New Jersey

Abraham McCormick Seattle

and the Resource Characteristic entity to store multiple characteristics for a resource.
Resource Characteristic Records:

RESO URC E C H A RA C T ERIST IC

Jorge Galt Designer

Abraham McCormick Project Manager

Abraham McCormick Financial Analyst

Similar to Resource, a Requirement record captures single-valued constraints and child records store multi-valued
constraints.
Here is the Requirement entity:

REQ UIREM EN T DURAT IO N T ERRITO RY

Job 1 1 hr New York

Job 2 1 hr Seattle
The Requirement Characteristic entity:
Requirement Characteristic Records:

REQ UIREM EN T C H A RA C T ERIST IC

Job 1 Designer

Job 2 Project Manager

Job 2 Financial Analyst

Sometimes, the requirement may have a constraint modeled as a lookup attribute, while the resource may store
the matching attributes on the N:N table. For example, In the case of Requirement, the Territory constraint is a
lookup attribute to the Territory entity. A Requirement captures a demand for work and the territory the work will
be done in. A Resource record, however, can be associated to many Territory records.
Constraints property bags
When the user selects values in the Filter panel and clicks the Search button, the values are sent to the Resource
Matching API. For multi-valued constraints, the Filter panel shows the data from the master entities Territory and
Characteristic and includes the selected values in the constraints property bag.
Here is a sample property bag with constraints sent to the Resource Matching API:

NAME VA L UE

ResourceType User

Territories New York


New Jersey

This tells the Resource Matching API to find resources of type User that are associated with the New York or
New Jersey territories.
When in the Schedule Assistant, the constraints are first retrieved from a Requirement record through the Retrieve
Requirement Constraints API . The retrieved constraints are then pre-filled in the Filter panel and sent to the
Resource Matching API.
The Retrieve Requirement Constraints API queries the Requirement record and all related child constraints (e.g.
Requirement Characteristic). It responds with a constraints property bag expressing all the resource constraints
captured on the selected Requirement.
Here's a sample response from the Retrieve Requirement Constraints API:

NAME VA L UE

Requirement Job 2

Duration 1 hr

Territories Seattle

Characteristics Project Manager


Financial Analyst
The Resource Matching API receives as input the constraints property bag and queries for matching resources. The
matching resources are then shown in the Schedule Board or Schedule Assistant.
Summarizing the entities used for resource matching
Sample master entities
Territory - Referenced as a constraint
Characteristic - Referenced as a constraint
Resource - Assigned to Bookings
Resource Territory - Associates Resources to Territories
Resource Characteristic - Associates Resources to Characteristics
Sample transactional entities
Requirement - Captures a demand for work and references Territory
Requirement Characteristic - Associates Requirements to Characteristics
Summarizing the resource matching flows
Manual filtering. Filter Panel > Resource Matching API
1. A user manually adds constraints in the Filter panel
2. The constraints are sent to the Resource Matching API
3. The filtered list of resources is shown
Requirement filtering. Retrieve Requirement Constraints API > Filter Panel > Resource Matching API
1. A user finds availability for a Requirement record (from within the Schedule Board or from the Book
button in the ribbon).
2. The constraints are retrieved through the Retrieve Requirement Constraints API and shown in the Filter
panel.
3. The constraints are sent to the Resource Matching API
4. The filtered list of resources is shown

Extending URS with custom constraints


URS can be extended with custom resource constraints. Extending constraints work the same way as the ones build
into URS, they are modeled as attributes and relationships in Dynamics 365.

A step by step guide with code samples needed for each step is described in Extending URS: Find resources by
language - a step by step guide

Custom constraints
We'll use "language" as an example scenario. An organization wants to filter resources by the language they speak.
They also want to capture on the Requirement record the language required for a job. This constraint follows a
similar pattern to the built-in Territory constraint. A new master entity Language stores the different languages a
resource can speak. A Resource record can be associated to many Languages through a many-to-many
relationship entity. On the Requirement entity, we'll create two new lookup attributes: Required Language and
Secondary Language . When finding available resources for a requirement, only resources associated with either the
Required Language or the Secondary Language will be shown.

Since extensible constraints work fully with the relational model of Dynamics 365, any structure used to express
constraints can be used in URS. Here's a more powerful example of custom constraints. Let's assume an
organization picks up products from a location and delivers them to a customer's location. The Resource entity is
extended with a Maximum Weight attribute describing the maximum weight it can carry, in case of a vehicle
resource. The Requirement entity is related to the Dynamics 365 Product entity with a many-to-many relationship;
each Product gets a new Weight attribute, too. When a Requirement record is created to capture required work, it
is related to all the products required to complete the job. When a user finds availability for a Requirement, the
total weight of all related Product records is retrieved and only resources that can carry this weight, defined in the
Maximum Weight attribute, are returned.

Here, we'll describe the custom language constraint. First, we have our new Language entity:

L A N GUA GE

English

Spanish

and our new Resource Language many-to-many child entity:

RESO URC E L A N GUA GE

Jorge Galt English

Abraham McCormick English

Abraham McCormick Spanish

Here is the Requirement entity with our two new attributes, Required Language and Secondary Language
representing the languages the resource needs to speak to be matched with this requirement:

SEC O N DA RY
REQ UIREM EN T DURAT IO N T ERRITO RY REQ UIRED L A N GUA GE L A N GUA GE

Job 1 1 hr New York English ---

Job 2 1 hr Seattle Spanish English

Extensibility points
Based on the resource matching flows described above, these are the extensibility points we need to modify for our
custom constraints to work:
1. Retrieve Requirement Constraints API
The API needs to read our new Required Language and Secondary Language attributes so when a user finds
availability for a Requirement our new constraints are retrieved.
2. Filter panel
A user should be able to select from a list of Language records in the Filter panel to filter for matching
resources. When finding availability for a Requirement, the Filter panel should show the Required Language
and Secondary Language from the Requirement record pre-selected in the list of Languages.
3. Resource Matching API
The API will get as input the new Language constraints; it needs to return only resources speaking the
selected languages.
Extensible queries
Internally, the Retrieve Requirement Constraints API (#1 above) and the Resource Matching API (#3 above) use
FetchXML to query data from Dynamics 365. The Retrieve Requirement Constraints API issues multiple queries to
retrieve the Requirement record and its child constraints (e.g. Requirement Characteristic etc.) The Resource
Matching API, based on the resource constraints passed to it as input, will dynamically construct the correct
FetchXML query so only Resource records matching the specified FetchXML criteria are returned from Dynamics
365.
In the July 2017 update for URS, to support extensible resource matching, Universal FetchXML (UFX) was
introduced. Two important features UFX adds to FetchXML are: 1) Multiple result sets, a single UFX Query can
return results from multiple entities, and 2) Dynamic FetchXML, a UFX Query can dynamically construct FetchXML
based on input data.
With UFX, a single query can be constructed to query for a Requirement record and all its child records. The
Retrieve Requirement Constraints API executes a customizable UFX Query to retrieve a Requirement and its child
constraints. The query can be customized to retrieve custom constraint records as well.
The constraints property bag returned from the Retrieve Requirement Constraints API is passed as input to the
Resource Matching API. The API executes a customizable UFX query. With UFX, the query uses the input constraints
to dynamically construct the correct FetchXML to find matching resources. This UFX query, too, can be modified to
construct the proper FetchXML to only return resources matching the custom constraints.
Extensible Filter Layout and Resource Template
In the July 2017 update for URS, the Filter panel (#2 above) was updated to support customization through an XML
layout definition. The new layout supports dropdown controls to show a list of records from master entities and
the typical number , datetime and checkbox controls. The layout can be modified to allow users to select records
from custom constraint entities. The custom constraints, like the ones shipped with URS, are then passed as input
to the Resource Matching API.
Another client side extensibility point made available in the July 2017 update is the resource cell. The resource cell
is rendered through a customizable Handlebars.js template. The results from the Resource Matching API is made
available to the template. Therefore, by customizing the query executed by the Resource Matching API, custom data
can be rendered in the resource cell.
A step by step guide with code samples needed for each step is described in Extending URS: Find resources by
language - a step by step guide
See also
Universal Fetch XML
URS extensibility release notes
Extending URS: Find resources by language - a step
by step guide
1/16/2020 • 18 minutes to read • Edit Online

This step by step guide is a companion to Understanding and customizing resource matching in Universal
Resource Scheduling (URS)

In this step-by-step guide, we'll extend URS resources with a Language constraint. Consider an organization that
wants to filter resources by the languages they speak. They also want to capture on the Requirement record the
language required for the job. This constraint follows a similar pattern to the built-in Territory constraint. A new
master entity Language will store the different languages a resource can speak. A Resource record can then be
associated to many Languages through a many-to-many relationship entity. On the Requirement entity, we'll
model this by creating two new lookup attributes: Primary Language and Secondary Language . When finding
available resources for a requirement, only resources associated with either the Primary Language or the
Secondary Language will be shown.

Creating the new entities and relationships


In this section we'll create the new schema for the master Language entity and update the Resource and
Requirement entities with the corresponding relationships to the new Language entity.

Create a new Publisher


1. In Dynamics 365, under Customizations, create a new Publisher
2. Fill out the New Publisher form with the below details:

F IEL D VA L UE

Display Name Language

Name language

Prefix lang

3. Click Save and Close


Create a new Solution
1. In Dynamics 365, under Customizations, create a new Solution
2. Fill out the New Solution form with the below details:

F IEL D VA L UE

Display Name Language

Name Language

Publisher Language
F IEL D VA L UE

Version 1.0.0.0

3. Click Save
Create the Language entity
1. In the Language solution, create a new Entity
2. Fill out the New Entity form with the below details:

F IEL D VA L UE

Display Name Language

Plural Name Languages

Name lang_language (The lang_ prefix will be auto-filled and


read-only)

3. Click Save
Create the many-to -many relationship from the Resource entity to the Language entity
1. In the Language entity, create a new Many-to-Many Relationship
2. Fill out the New Relationship form with the below details:

F IEL D VA L UE

Current Entity

Display Option Use Plural Name

Other Entity

Entity Name Bookable Resource

3. Click Save and Close


4. Close the Language entity form
Create the relationships from the Requirement entity to the Language entity
1. In the Language solution, add the existing Resource Requirement entity to the solution (If presented with a
Missing Required Components dialog, select No, do not include required components.)
2. In the Resource Requirement entity, create a new Field
3. Fill out the New Field form with the below details:

F IEL D VA L UE

Display Name Primary Language

Data Type Lookup


F IEL D VA L UE

Target Record Type Language

4. Click Save and Close


5. In the Resource Requirement entity, create a new Field
6. Fill out the New Field form with the below details:

F IEL D VA L UE

Display Name Secondary Language

Data Type Lookup

Target Record Type Language

7. Click Save and Close


Update the Requirement main form
1. In the Resource Requirement entity, add the existing Information form to the entity's subcomponents (If
presented with a Missing Required Components dialog, select No, do not include required components.)
2. In the Information form, use the Field Explorer to add the two new attributes, Primary Language and Secondary
Language to the form so users can enter this information as they create requirements
3. Click Save
4. Click Publish
5. You can close the form editor
Summary
In the above steps, we created the new Language entity. We then added new relationships with the Resource and
Requirement entities. Resources can be related to multiple languages, since we added a many to many relationship
between Language and Resource. Requirements can be related to two Languages since we added two lookup
attributes on Requirement entity pointing to the new Language entity.
Adding data
Use Advanced Find to add new records to the Language entity. You can then associate Resource records to the new
Language records by opening a Resource record and navigating to the Language relationship in the navigation bar.
For Requirement records, you can fill in the new Primary Language and Secondary Language fields on the
Requirement form.

Customizing the Schedule Board


To filter resources in the Schedule Board with the new Language constraint, we'll update the Retrieve Resources
Query and the Filter Layout configuration records.
Filter Layout Configuration

TIP
For the below steps, it is helpful to use a text editor that supports XML syntax highlighting to make your changes, and then
paste your changes back into the Universal Resource Scheduling editor.

The Filter Layout configuration is an XML layout definition to customize the layout of the Filter panel.
NOTE
For this exercise, we'll remove all default filters shipped with URS from the Filter panel and add Languages as the only
available filter.

<control type="combo" source="entity" key="Languages" inactive-state="1" label-id="Languages"


entity="lang_language" multi="true" />

The control element adds a new control to the Filter panel. Here is the description of each attribute:

NAME DESC RIP T IO N

type The type of filter control. A combo control renders a


dropdown with values to choose from

source The source of the values for the dropdown control. An


entity source shows entity records in the dropdown

key The key to use to store the selected values in the constraints
property bag

inactive-state The inactive statecode for this entity. This is used to exclude
inactive records from the dropdown

label-id The localized label to use for this control

entity This entity's records will be displayed in the dropdown

multi Configures the dropdown to allow selecting a single record or


multiple records

Filter Layout:

<?xml version="1.0" encoding="utf-8" ?>


<filter>
<controls>
<control type="combo" source="entity" key="Languages" inactive-state="1" label-id="Languages"
entity="lang_language" multi="true" />
</controls>
</filter>

Create a new Languages board


In order to keep these changes isolated, we will create a brand new separate Schedule Board and implement the
changes, but you can always make these changes on the default Schedule Board so that other Schedule Boards can
automatically inherit these changes.
1. In Dynamics 365, in the top navigation bar, go to Resource Scheduling > Schedule Board
2. In the top right, click the + sign to create a new board
3. Name the new board Language
4. At the bottom of the dialog, click Add. The new board will be created.
Update the Schedule Board Filter Layout
Next, we will create a new configuration record which stores filter layouts and queries used by the Schedule Board,
and then we will link the newly created Schedule Board to the new configuration record. There are multiple ways to
do this, but here is the quickest:
1. In the top right, double click the Language tab
2. Scroll down to General Settings > Other Settings
3. Locate the Filter Layout field, click the button to the right to open the editor
4. Update the Value field with the Filter Layout code above and click Save As.
5. Enter "Language Filter Layout" in the Name field and click Save. This creates a new configuration record and
links this Schedule Board to the record.
6. At the bottom of the dialog, click Apply
The board will reload and you will see the Filter panel in the left with the new layout; only the Languages filter will
be available. Filtering will not work yet, as we need to update the Retrieve Resources Query to take advantage of
the new filter.
Retrieve Resources Query Configuration

TIP
For the below steps, it is helpful to use a text editor that supports XML syntax highlighting to make your changes, and then
paste your changes back into the Universal Resource Scheduling editor.

The Retrieve Resources Query configuration is a UFX Query used by the Resource Matching API. It takes as input
the values entered in the Filter panel and dynamically constructs the correct FetchXML to find matching resources.

Below are the new snippets added to the Retrieve Resources Query to match and order by the Resources'
Languages.

Adding the joins from bookableresource to lang_language


<link-entity name="lang_lang_language_bookableresource" from="bookableresourceid" to="bookableresourceid"
alias="lang_primary" link-type="outer" ufx:if="$input/Languages/bag[1]">
<attribute name="lang_languageid" alias="lang_primary" groupby="true" />

<filter>
<condition attribute="lang_languageid" operator="eq">
<ufx:value select="$input/Languages/bag[1]/@ufx-id" attribute="value" />
</condition>
</filter>
</link-entity>

<link-entity name="lang_lang_language_bookableresource" from="bookableresourceid" to="bookableresourceid"


alias="lang_secondary" link-type="outer" ufx:if="$input/Languages/bag[2]">
<attribute name="lang_languageid" alias="lang_secondary" groupby="true" />

<filter>
<condition attribute="lang_languageid" operator="eq">
<ufx:value select="$input/Languages/bag[2]/@ufx-id" attribute="value" />
</condition>
</filter>
</link-entity>

<link-entity name="lang_lang_language_bookableresource" from="bookableresourceid" to="bookableresourceid"


alias="lang_others" link-type="outer" ufx:if="$input/Languages/bag[position() > 2]">

<filter>
<condition attribute="lang_languageid" operator="in">
<ufx:apply select="$input/Languages/bag[position() > 2]">
<value>
<ufx:value select="@ufx-id" />
</value>
</ufx:apply>
</condition>
</filter>
</link-entity>

<filter type="or">
<condition entityname="lang_primary" attribute="lang_languageid" operator="not-null"
ufx:if="$input/Languages/bag[1]" />
<condition entityname="lang_secondary" attribute="lang_languageid" operator="not-null"
ufx:if="$input/Languages/bag[2]" />
<condition entityname="lang_others" attribute="lang_languageid" operator="not-null"
ufx:if="$input/Languages/bag[position() > 2]" />
</filter>

The values selected in the Filter panel is passed as input to the query and is available in the XPath $input
variable

The Retrieve Resources Query uses FetchXML to query the Resource (bookableresource) entity. We are using the
FetchXML link-entity element to only return resources associated with the Language records selected in the
Filter panel. To support showing the matched languages and ordering by primary or secondary language,
described later in the section Resource Cell Template, we are using multiple link-entity joins.
Here is the description of each element and attribute :

NAME DESC RIP T IO N

link-entity Create a join to the many-to-many relationship between the


Resource and Language entities
NAME DESC RIP T IO N

ufx:if Only emit this FetchXML element ( link-entity ) if the XPath


expression in this attribute returns a value

attribute Return the primary or secondary language matched

filter and condition Filter the many-to-many relationship records to only the ones
that match the specified Language IDs

ufx:value and select Outputs the result of the XPath expression in the select
attribute

ufx:apply and select Emit the child FetchXML elements for each result returned
from the XPath expression in the select attribute

value Contains the ID of a Language record

Determining a Resource's sort order


After we retrieve the matching resources, based on each resource's assigned languages, we assign a new
lang_order property to determine its sort order.

<bag>
<lang_order ufx:select="iif(lang_primary and lang_secondary, 1, iif(lang_primary, 2, iif(lang_secondary, 3,
4)))" />
</bag>

Here is the description of each element and attribute :

NAME DESC RIP T IO N

lang_order Create a new property in each Resource returned from the


FetchXML query named lang_order

ufx:select Assign the result of the XPath expression in this attribute to


the lang_order property. The lang_primary and
lang_secondary properties, retrieved earlier in the query, is
used together with the XPath iif function to determine the
resource matching order.

Ordering the results

<Resources ufx:select="order(Resources, 'lang_order')" />

UFX Queries are processed in sequential order. After the resources are retrieved through FetchXML, the results are
assigned to the Resources property. We are sorting the results based on the lang_order property added earlier
and re-assigning the sorted results to the Resources property.
Here is the description of each element and attribute :

NAME DESC RIP T IO N

Resources Re-assign the Resources property


NAME DESC RIP T IO N

ufx:select Assign the result of the XPath expression in this attribute to


the Resources property. The XPath order function is used
to order the Resources list on its lang_order property.

NOTE
The default Retrieve Resources Query shipped with URS is a large query that supports all the resource constraints included
with URS. For this exercise, we'll use only a subset of the default query and add Languages as the only filter.

<?xml version="1.0" encoding="utf-8" ?>


<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
<Resources ufx:source="fetch">
<fetch mapping="logical" aggregate="true">
<entity name="bookableresource">
<attribute name="bookableresourceid" alias="bookableresourceid" groupby="true"/>
<attribute name="name" alias="name" groupby="true"/>
<attribute name="calendarid" alias="calendarid" groupby="true"/>
<attribute name="resourcetype" alias="resourcetype" groupby="true"/>
<attribute name="msdyn_startlocation" alias="startlocation" groupby="true"/>

<!-- Language join -->


<link-entity name="lang_lang_language_bookableresource" from="bookableresourceid"
to="bookableresourceid" alias="lang_primary" link-type="outer" ufx:if="$input/Languages/bag[1]">
<attribute name="lang_languageid" alias="lang_primary" groupby="true" />

<filter>
<condition attribute="lang_languageid" operator="eq">
<ufx:value select="$input/Languages/bag[1]/@ufx-id" attribute="value" />
</condition>
</filter>
</link-entity>

<link-entity name="lang_lang_language_bookableresource" from="bookableresourceid"


to="bookableresourceid" alias="lang_secondary" link-type="outer" ufx:if="$input/Languages/bag[2]">
<attribute name="lang_languageid" alias="lang_secondary" groupby="true" />

<filter>
<condition attribute="lang_languageid" operator="eq">
<ufx:value select="$input/Languages/bag[2]/@ufx-id" attribute="value" />
</condition>
</filter>
</link-entity>

<link-entity name="lang_lang_language_bookableresource" from="bookableresourceid"


to="bookableresourceid" alias="lang_others" link-type="outer" ufx:if="$input/Languages/bag[position() > 2]">

<filter>
<condition attribute="lang_languageid" operator="in">
<ufx:apply select="$input/Languages/bag[position() > 2]">
<value>
<ufx:value select="@ufx-id" />
</value>
</ufx:apply>
</condition>
</filter>
</link-entity>

<filter type="or">
<condition entityname="lang_primary" attribute="lang_languageid" operator="not-null"
ufx:if="$input/Languages/bag[1]" />
<condition entityname="lang_secondary" attribute="lang_languageid" operator="not-null"
ufx:if="$input/Languages/bag[2]" />
ufx:if="$input/Languages/bag[2]" />
<condition entityname="lang_others" attribute="lang_languageid" operator="not-null"
ufx:if="$input/Languages/bag[position() > 2]" />
</filter>

<link-entity name="systemuser" from="systemuserid" to="userid" link-type="outer">


<attribute name="systemuserid" alias="systemuserid" groupby="true" />
<attribute name="entityimage_url" alias="userimagepath" groupby="true"/>
</link-entity>

<link-entity name="contact" from="contactid" to="contactid" link-type="outer">


<attribute name="contactid" alias="contactid" groupby="true"/>
<attribute name="entityimage_url" alias="contactimagepath" groupby="true"/>
</link-entity>

<link-entity name="account" from="accountid" to="accountid" link-type="outer">


<attribute name="accountid" alias="accountid" groupby="true"/>
<attribute name="entityimage_url" alias="accountimagepath" groupby="true"/>
</link-entity>
</entity>
</fetch>

<bag>
<imagepath ufx:select="accountimagepath | contactimagepath | userimagepath" />

<accountimagepath ufx:select="$null" />


<contactimagepath ufx:select="$null" />
<userimagepath ufx:select="$null" />

<lang_order ufx:select="iif(lang_primary and lang_secondary, 1, iif(lang_primary, 2, iif(lang_secondary,


3, 4)))" />
</bag>
</Resources>

<Resources ufx:select="order(Resources, 'lang_order')" />


</bag>

Update the Schedule Board Retrieve Resources Query


1. In the top right, double click the Language tab
2. Scroll down to General Settings > Other Settings
3. Locate the Retrieve Resources Query field, click the button to the right to open the editor
4. Update the Value field with the Retrieve Resources Query code above and click Save As
5. Enter "Language Resources Query" in the Name field and click Save. This creates a new configuration record
and links this Schedule Board to the record.
6. At the bottom of the dialog, click Apply
The board will reload with the updated configuration. Filtering will now work. If you created Language records and
associated them with Resource records, you will now be able to filter resources by their associated languages.
Summary
In the above steps we modified the Filter panel to show a filter control for the Language entity. We also modified
the Retrieve Resources Query to match resources associated with the selected Language records. When a user
selects values in the filter control and clicks Search, the values are passed into the query and the FetchXML query
returns only matching resources.

Customizing the Schedule Assistant


We need to customize the Schedule Assistant Filter Layout and Retrieve Constraints Query configurations to use
the new Language constraints in the Schedule Assistant.
Unlike the Schedule Board customizations, where each board can be individually customized, the Schedule
Assistant customizations affects all boards where the Schedule Assistant is used. The Schedule Assistant
customizations can be specific to a schedulable type or for all types. In this example we will customize the Schedule
Assistant for all types.
Schedule Assistant Filter Layout Configuration

TIP
For the below steps, it is helpful to use a text editor that supports XML syntax highlighting to make your changes, and then
paste your changes back into the Universal Resource Scheduling editor.

The Schedule Assistant Filter Layout configuration, like the Schedule Board Filter Layout, defines the layout of the
controls in the Filter panel. Since the Schedule Assistant uses more filters than the Schedule Board, like Start Time,
End Time, Duration, etc., a different layout is used.

NOTE
For this exercise, we'll reuse only a subset of the default filters shipped in URS from the Schedule Assistant Filter Layout
configuration and add the Languages dropdown as the only available filter.

The filter we are adding to the layout is the same as above in Filter Layout Configuration. The other controls are
needed to modify the Schedule Assistant search parameters.
The complete Schedule Assistant Filter Layout

<?xml version="1.0" encoding="utf-8" ?>


<filter>
<controls>
<control type="twocolumn">
<control type="combo" source="optionset" key="Requirement/msdyn_worklocation" label-
id="ScheduleAssistant.West.settingsform.WorkLocation" entity="msdyn_resourcerequirement"
attribute="msdyn_worklocation">
<bind property="disabled" to="Requirement/InitialWorkLocation" operator="eq" value="690970002" />
<data>
<value id="690970000" />
<value id="690970001" />
<value id="690970002" />
</data>
</control>
<control type="duration" key="Requirement/msdyn_remainingduration" label-
id="ScheduleAssistant.West.settingsform.AvailableDuration" />
</control>
<control type="distance" key="Requirement/Radius" label-id="ScheduleAssistant.West.settingsform.Radius"
min="1">
<bind property="disabled" to="Requirement/msdyn_worklocation" operator="eq" value="690970002" />
</control>
<control type="datetime" key="Requirement/msdyn_fromdate" label-
id="ScheduleAssistant.West.settingsform.StartDay">
<bind property="disabled" to="Requirement/RealTimeMode" operator="eq" value="true" />
<bind property="max" to="Requirement/msdyn_todate" operator="eq" />
</control>
<control type="datetime" key="Requirement/msdyn_todate" label-
id="ScheduleAssistant.West.settingsform.EndDay">
<bind property="min" to="Requirement/msdyn_fromdate" operator="eq" />
</control>
<control type="combo" source="entity" key="Languages" inactive-state="1" label-id="Languages"
entity="lang_language" multi="true" />
</controls>
</filter>

Update the Schedule Assistant Filter Layout


1. In the top right, double click the Language tab
2. In the top right, click Open Default Settings
3. Scroll to the Schedule Types section and select None in the left list
4. Locate the Schedule Assistant Filter Layout field, click the button to the right to open the editor
5. Update the Value field with the Schedule Assistant Filter Layout code above and click Save As
6. Enter "Language Schedule Assistant Filter Layout" in the Name field and click Save. This creates a new
configuration record and links this Schedule Board to the record.
7. At the bottom of the dialog, click Apply
The board will reload. Next, we need to change the Retrieve Constraints Query before we can use the Schedule
Assistant with our new Language constraints, so that the Languages set on the Requirement are part of the
Schedule Assistant search.
Retrieve Constraints Query Configuration

TIP
For the below steps, it is helpful to use a text editor that supports XML syntax highlighting to make your changes, and then
paste your changes back into the Universal Resource Scheduling editor.

The Retrieve Constraints Query configuration is a UFX Query used by the Retrieve Requirement Constraints API. It
takes as input the ID of a Requirement record (selected in the UI) and returns the Requirement record and all its
child records.

NOTE
The default Retrieve Constraints Query shipped with URS is a large query that supports all the requirement constraints
included with URS. For this exercise, we'll use only a subset of the default query and add Languages as the only filter.

<Languages ufx:select="lookup-to-list(Requirement/lang_primarylanguage, Requirement/lang_secondarylanguage)"


/>

UFX Queries are processed in sequential order. The Retrieve Constraints Query uses FetchXML to query the
Requirement (msdyn_resourcerequirement) entity and assigns the result, a Requirement record, to the Requirement
property. We are adding to the constraints property bag a new property Languages that combines both attributes,
the Primary Language and Secondary Language, into a single list of entities (EntityCollection). This is required
since we are showing the Languages control in the Filter panel as a list of records. An alternative would be to
create two separate controls in the Filter panel for the two attributes.
Here is the description of each element and attribute :

NAME DESC RIP T IO N

Languages Create a new property in the result constraints property bag


named Languages

ufx:select Assign the result of the XPath expression in this attribute to


the Languages property. The lang_primarylanguage and
lang_secondarylanguage properties, retrieved earlier in the
query and available in the Requirement property, is passed
to the lookup-to-list XPath function which converts
multiple lookup properties to a single
list (EntityCollection)
Retrieve Constraints Query:

<?xml version="1.0" encoding="utf-8" ?>


<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
<Requirement ufx:source="fetch" ufx:select="bag[1]">
<fetch top="1">
<entity name="msdyn_resourcerequirement">
<all-attributes />

<filter>
<condition attribute="statecode" operator="eq" value="0" />
<condition attribute="msdyn_resourcerequirementid" operator="eq">
<ufx:value select="$input/@ufx-id" attribute="value" />
</condition>
</filter>
</entity>
</fetch>

<bag>
<InitialWorkLocation ufx:select="msdyn_worklocation" />
</bag>
</Requirement>

<Languages ufx:select="lookup-to-list(Requirement/lang_primarylanguage, Requirement/lang_secondarylanguage)"


/>
</bag>

Update the Retrieve Constraints Query


1. In the top right, double click the Language tab
2. In the top right, click Open Default Settings
3. Scroll to the Schedule Types section and select None in the left list
4. Locate the Schedule Assistant Retrieve Constraints Query field, click the button to the right to open the editor
5. Update the Value field with the Retrieve Resources Query code above and click Save As
6. Enter "Language Constraints Query" in the Name field and click Save. This creates a new configuration record
and links this Schedule Board to the record.
7. Locate the Schedule Assistant Retrieve Resources Query field and select the Languages Resources Query we
created earlier for the Schedule Board Customizations
8. At the bottom of the dialog, click Apply
The board will reload with the updated configuration. Schedule Assistant filtering will now work. If you created
Language records and associated them with Requirement records, you will now be able to select a Requirement
record in the bottom of the Schedule Board, click Find Availability to launch the Schedule Assistant, and see only
resources matching the languages saved on the requirement.
Resource Cell Template Configuration

TIP
For the below steps, it is helpful to use a text editor that supports HTML syntax highlighting to make your changes, and
then paste your changes back into the Universal Resource Scheduling editor.

The Resource Cell Template configuration is a Handlebars template used to render content in the resource cell. The
output from the Retrieve Resources Query is available to the template.
We are modifying the default resource template to show a green ✔✱ indicator if the resource matched the
primary and secondary languages, a green ✔ indicator if the resource only matched the primary language, and a
yellow ✔ indicator if the resource matched only the secondary language.
{{#if lang_primary}}
<span style='color:green;'>&#10004;{{#if lang_secondary}} &#10033;{{/if}}</span>
{{else if lang_secondary}}
<span style='color:#ffe700;'>&#10004;</span>
{{/if}}

The lang_primary and lang_secondary properties are returned from our custom Retrieve Resources Query we
setup above. Consult the Handlebars website for documentation on the templating syntax.
Resource Cell Template:

<div class='resource-card-wrapper {{iif ResourceCellSelected "resource-cell-selected" ""}} {{iif


ResourceUnavailable "resource-unavailable" ""}} {{iif IsMatchingAvailability "availability-match" ""}}'>
{{#if imagepath}}
<img class='resource-image' src='{{client-url}}{{imagepath}}' />
{{else}}
<div class='resource-image unknown-resource'></div>
{{/if}}
<div class='resource-info'>
<div class='resource-name primary-text ellipsis' title='{{name}}'>{{name}}</div>
<div class='secondary-text ellipsis'>
{{#if (eq (is-sa-grid-view) false) }}
<div class='booked-duration'>{{BookedDuration}}</div>
<div class='booked-percentage'>
{{BookedPercentage}}%

{{#if lang_primary}}
<span style='color:green;'>&#10004;{{#if lang_secondary}} &#10033;{{/if}}</span>
{{else if lang_secondary}}
<span style='color:#ffe700;'>&#10004;</span>
{{/if}}
</div>
{{/if}}
</div>
{{#if (eq (is-sa-grid-view) false) }}
<div class='matching-indicator'></div>
{{/if}}
</div>
{{#if (eq (is-sa-grid-view) false) }}
{{> resource-map-pin-template this }}
{{/if}}
</div>

Update the Resource Cell Template


1. In the top right, double click the Language tab
2. In the top right, click Open Default Settings
3. Scroll to the Schedule Types section and select None in the left list
4. Locate the Schedule Assistant Resource Cell Template field, click the button to the right to open the editor
5. Update the Value field with the Resource Cell Template code above and click Save As
6. Enter "Language Resource Cell Template" in the Name field and click Save. This creates a new configuration
record and links this Schedule Board to the record.
7. At the bottom of the dialog, click Apply
The board will reload with the updated configuration. The resource cell will now indicate how a resource matched
the language constraint in the Filter panel.
Summary
In the above steps we modified the Filter panel in the Schedule Assistant to show a filter control for the Language
entity. We also modified the Retrieve Constraints Query to query the new Language attributes related to the
Requirement entity, and shape them into a list. When a user selects to find availability for a Requirement record,
the Filter panel will show the captured Language constraints. The values from the Filter panel are passed into the
Retrieve Resources query and the FetchXML query returns only matching resources.
See also
Universal Fetch XML
URS extensibility release notes
Universal FetchXML
1/16/2020 • 6 minutes to read • Edit Online

UFX is an advanced query language that allows you to query data using dynamic FetchXML, shape and prepare
the resulting data for consumption by the Universal Resource Scheduling (URS) solution. This query language
enables you to create custom queries to customize and extend the schedule board and schedule assistant filters to
meet the unique business needs of the organization.
UFX consists of two components UFX Bag and UFX Query.

Simple UFX Bag


A UFX Bag contains static typed data. In memory, it's represented as a dictionary with keys and values. It can be
serialized to JSON and XML. Having the data typed allows a UFX Quer y to query data from it, and client UI to
bind to it.

For practical and performance reasons the in-memory bag is implemented on top of the Dynamics 365 apps
SDK Entity object.

Sample bag containing two values.


In memory:

K EY VA L UE TYPE

name John string

age 36 int

In JSON:

{
"name": "John",
"age": 36
}

In XML:

<bag>
<name ufx-type="string">John</name>
<age ufx-type="int">36</age>
</bag>

UFX supported types


A UFX Bag can contain values of many types. They are categorized in 3 type classes:

C AT EGO RY VA L UE
C AT EGO RY VA L UE

Simple types bool (Boolean) , int (Int32) , long (Int64) ,


double (Double) , decimal (Decimal) ,
datetime (DateTime) , guid (Guid) , string (String)
Dynamics 365 specific simple types: money (Money) ,
option (OptionSet) , lookup (EntityReference)

Other Bags bag (Entity)

List of Bags list (EntityCollection)

Here's a sample JSON bag containing more types:

{
"citizen": true, // implicit bool

"age": 36, // explicit int


"age@ufx-type": "int",

"name": { // nested bag


"first": "John",
"last": "Doe"
},

"children": [ // list of bags


{ "name": "Sam" },
{ "name": "Judy" }
]
}

The same bag in XML:

<bag>
<citizen ufx-type="bool">true</citizen>

<age ufx-type="int">36</age>

<name ufx-type="bag">
<first ufx-type="string">John</first>
<last ufx-type="string">Doe</last>
</name>

<children ufx-type="list">
<bag>
<name ufx-type="string">Sam</name>
</bag>
<bag>
<name ufx-type="string">Judy</name>
</bag>
</children>
</bag>

Introduction to UFX Queries


UFX Queries are written as XML-based UFX Bags . Properties in the bag can contain UFX directives to query data
dynamically. A UFX Query executes on in-memory objects, not XML. Only the directives are written in XML. It's
output can be serialized to JSON or XML.
The following UFX Query defines the accounts property in the bag with the source UFX directive. This results in
the inline FetchXML to be executed by Dynamics 365 and the accounts property to become a list of bags, or an
EntityCollection , with each bag being an instance of an account record from Dynamics 365.

<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
<accounts ufx:source="fetch">
<fetch top="10">
<entity name="account" />
</fetch>
</accounts>
</bag>

A UFX Query is processed sequentially and can contain many FetchXML queries.
Here's a snippet of the result of the previous UFX Query serialized to XML. Observe some values have metadata
further describing them.

<bag>
<accounts ufx-type="list">
<bag ufx-id="166e39dd-34a1-e611-8111-00155d652f01" ufx-logicalname="account">
<accountid ufx-type="guid">166e39dd-34a1-e611-8111-00155d652f01</accountid>
<accountnumber ufx-type="string">ABSS4G45</accountnumber>
<name ufx-type="string">Fourth Coffee (sample)</name>
<statecode ufx-type="option" ufx-formatvalue="Active">0</statecode>
<websiteurl ufx-type="string">https://www.fourthcoffee.com/</websiteurl>
<primarycontactid ufx-type="lookup" ufx-formatvalue="Yvonne McKay (sample)" ufx-
logicalname="contact">7c6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>
...
</bag>
<bag ufx-type="bag" ufx-id="186e39dd-34a1-e611-8111-00155d652f01" ufx-logicalname="account">
<accountid ufx-type="guid">186e39dd-34a1-e611-8111-00155d652f01</accountid>
<accountnumber ufx-type="string">ACTBBDC3</accountnumber>
<name ufx-type="string">Litware, Inc. (sample)</name>
<statecode ufx-type="option" ufx-formatvalue="Active">0</statecode>
<websiteurl ufx-type="string">https://www.litwareinc.com/</websiteurl>
<primarycontactid ufx-type="lookup" ufx-formatvalue="Susanna Stubberod (sample)" ufx-
logicalname="contact">7e6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>
...
</bag>
...
</accounts>
</bag>

The select UFX directive takes an XPath expression that selects values from the current bag.

<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
<accounts ufx:source="fetch">
<fetch top="10">
<entity name="account" />
</fetch>
</accounts>

<first_account_name ufx:select="accounts/bag[1]/name" />

<!-- null values remove properties from the bag -->


<accounts ufx:select="$null" />
</bag>

The resulting bag in XML:


<bag>
<first_account_name ufx-type="string">Fourth Coffee (sample)</first_acount_name>
</bag>

Certainly the most powerful aspect of a UFX Query is its ability to dynamically generate FetchXML based on input
data.
In the sample below, we search for accounts by a value supplied by the user and available as a UFX Bag through
the XPath $input variable. Notice the UFX if and value directives on the condition element.

<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
<accounts ufx:source="fetch">
<fetch top="10">
<entity name="account">
<filter>
<condition attribute="name" operator="like" ufx:if="$input/NameFilter">
<ufx:value select="$input/NameFilter" attribute="value" />
</condition>
</filter>
</entity>
</fetch>
</accounts>
</bag>

If the NameFilter property in the input bag contained %city% the produced FetchXML condition executed by
Dynamics 365 would look like this.

<condition attribute="name" operator="like" value="%city%" />

Keys, values, and metadata


A UFX Bag contains keys and values, with some values having additional metadata further describing them.
An example might be a value of type lookup (EntityReference) . When queried from Dynamics 365 through
FetchXML, it will return the logical name of the entity as well as the formatted display name of the record. The UFX
Bag perserves these additional information as metadata attached to the primary value.
Serialized to JSON, a lookup with metadata looks like this:

{
"primarycontactid": "7e6e39dd-34a1-e611-8111-00155d652f01",
"primarycontactid@ufx-type": "lookup",
"primarycontactid@ufx-logicalname": "contact",
"primarycontactid@ufx-formatvalue": "Susanna Stubberod (sample)"
}

In XML:

<primarycontactid ufx-type="lookup" ufx-formatvalue="Susanna Stubberod (sample)" ufx-


logicalname="contact">7e6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>

XPath over Dynamics 365 data


Having the data in a UFX Bag typed, allows a UFX Query to see it in a structured format and use XPath to traverse
over the data and select values from it.
An XPath expression specified in a UFX directive sees the data in the bag very similar to the structure of the bag in
XML-serialized form. However, the data is stored in in-memory .NET objects (in instances of Entity and
EntityCollection types) and not in XML documents.

Appendix A: UFX type reference


Note: All UFX Types support the ufx-type and ufx-formatvalue metadata. Additional metadata are described
next to each type in the table below.

UF X N A M E AT T RIB UT E T Y P E C O DE . N ET N A M E UF X M ETA DATA

bool Boolean Boolean

int Integer Int32

long BigInt Int64

double Double Double

decimal Decimal Decimal

datetime DateTime DateTime

guid Uniqueidentifier Guid

string Memo String

money Money Money

option Picklist OptionSetValue

lookup Lookup EntityReference ufx-logicalname

bag N/A Entity ufx-id


ufx-logicalname

list N/A EntityCollection

N/A N/A AliasedValue ufx-aliasentity


ufx-aliasattribute

Appendix B: UFX Query directives


UFX directives can be used on bag properties and on XML elements of a FetchXML query.
UFX Bag directives

AT T RIB UT E VA L UE DESC RIP T IO N

ufx:if XPath Tests the XPath expression and only


processes the property if the test
returns true
AT T RIB UT E VA L UE DESC RIP T IO N

ufx:source fetch Executes the inline <fetch> XML


element and assigns the result to the
property

ufx:select XPath Executes the XPath expression and


assigns the result to the property
When querying for a bag or list an
optional child bag in XML form can be
specified to transform the result of the
XPath expression

UFX FetchXML directives

EL EM EN T AT T RIB UT E VA L UE DESC RIP T IO N

All elements ufx:if XPath Tests the XPath expression


and only emits the XML
element if the tests succeeds

ufx:apply select XPath Loops over the nodeset


returned by the XPath
expression and outputs the
child XML elements once for
each node

ufx:value select XPath Executes the XPath


expression and outputs the
result in the current XML
element

ufx:value attribute attribute name Assigns the XPath


expression result to the
specified attribute name on
the current XML element

Appendix C: UFX XPath functions


UFX adds a number of new functions in addition to the ones available natively in XPath.
datetime ()
datetime(): Returns the current time in UTC
list()
list(bag | list, ...[bag | list]): Takes a number of bag or list values as input and flattens them into a single list

lookup-to -list()
lookup-to-list(lookup, ...[lookup]): Takes a number of lookup values, converts each of them to a bag with the
ufx-id and ufx-logicalname metadata set, and flattens them into a single list

option-to -list()
option-to-list(option, ...[option]): Takes a number of option values, converts each of them to a bag with a
single option property, and flattens them into a single list
order()
order(list, string, bool): Orders a list by a property in each bag. The property is specified in argument 2,
descending is specified in argument 3.
order(list, list): Order a list by multiple sort orders specified as a list in argument 2. Each bag in the second list
can have a name and descending property
iif()
iif(any, any, any): If argument 1 is true, returns argument 2, otherwise returns argument 3

Appendix D: UFX XPath variables


NAME DESC RIP T IO N

$input A bag available to the UFX Query with input values

$null A null constant. Selecting $null on a property removes the


property from the bag

$current Reference to the current bag being processed by the UFX


Query

See also
Understanding and customizing resource matching in Universal Resource Scheduling (URS)
URS extensibility release notes
Bug fixes for Universal Resource Scheduling
5/19/2020 • 50 minutes to read • Edit Online

Version 3.12.25.5
On the daily view mode of the schedule assistant, when Ignore Duration advanced setting is selected, all
eligible resources were not returned regardless of their availability. This bug is now fixed in this update.
Fixed a bug where quick book is used on a requirement group, and resources work in a different time zone than
the time zone of the calendar of the requirements in the group, only a part of the available timeslots were
returned. With the fix, all available time slots are returned in this scenario.
When searching for resources in the daily view of the schedule board: once the searched Resources are
returned, bookings of the resources are not returned on the center area, until the board is refreshed. This bug is
now fixed in this update.
When a default search radius unit of kilometers is used and no available resources are returned, the schedule
assistant crashes. This bug is now fixed, and users can expand the filter panel, even when no resources were
returned to change the filters on the filter pane.
When quick book is used on a work order with an associated requirement group, and a resource is booked,
Booking Status selected is invalid for Work Order error is thrown. This issue is now fixed.
When looking for available resources on a service activity record and Least Busy sort is selected, no available
resources were returned. This is now fixed on the schedule assistant.
Quick book will honor the default resource search radius defined on the booking setup metadata record of the
schedulable entity (for example, work order, case, resource requirement, and so on).
When any changes are made to a booking (like moving the booking or reassigning the booking), the custom
booking rules defined by the user would get triggered. But extending existing booking would not trigger the
booking rule. This bug is now fixed.
When fulfillment preferences (intervals) are used with a requirement group, the start date of the schedule
assistant filter pane is populated incorrectly, which is now fixed in the update.
Schedule board center-area grid is misaligned when browser zoom is changed to 80 percent or 110 percent on
Microsoft Edge and Google Chrome browsers. With this fix, the misalignment of the grid is fixed.
Fixed a bug where a custom entity cannot be enabled for scheduling, when the name of the entity has more than
100 characters. With this fix, any entity that has a name with more than 100 characters can also be enabled for
scheduling.

Version 3.12.30.11 (2020 wave 2 early access update 1)


The release is only applied when an environment is opted into early access and introduces the resource scheduling
2020 wave 2 new and updated features.
In addition, this release includes the following changes that have the potential to change the existing system
behavior or interface:
When searching for resources in the daily view of the schedule board: Once the searched resources are
returned, bookings of the resources are not returned on the center area, until the board is refreshed. This bug is
now fixed in this update.
When different capacities are used for a resource before and after a break, (for example 11 AM to 12 PM,
working with capacity is 1; 12 PM to 1 PM is a break, and 1 PM to 2 PM, working with capacity 2) then the break
time is shown as working time on the schedule board. This bug is fixed in this update.
Fixed a bug where quick book is used on a requirement group, and resources work in a different time zone than
the time zone of the calendar of the requirements in the group, only a part of the available time slots were
returned. With the fix, all available time slots are returned in this scenario.
Fixed a bug where the search time window of the resource requirement is greater than the time range displayed
on the schedule board and schedule assistant, the resource booked hours capacity on the resource cell were not
displayed. The expand and collapse button next to the resource in daily, weekly, and monthly views were also not
displayed.
When you enable any entity for scheduling (for example, case, lead, account), enable quick book feature on the
booking setup metadata record of this schedulable entity, and set Disable Requirement Auto Creation for
Bookings to yes. The resource requirement records will not be generated post the creation of the booking
record.

Version 3.12.29.5 (2020 wave 2 early access)


The release is only applied when an environment is opted into early access and introduces the resource scheduling
2020 wave 2 new and updated features.
In addition, this release includes the following changes that have the potential to change the existing system
behavior or interface:
Fixed a bug where a booking rule is used and throws a custom notification on the schedule assistant’s Create
Resource Booking pane, the Booking created successfully was not being displayed. Now with the fix, even
when booking rules are defined, the booking creation success notification will be displayed.
When a custom date format (for example, dd/mm/yyyy) is used, the booking tooltip's displayed start time and
end time are displayed incorrectly. This bug is now fixed.
Use openWebResource API to open schedule assistant in the client-side tools like Unified Service Desk, so that
no custom actions need to be called to open the schedule assistant.
For organizations using Japanese language, in the schedule board’s date picker control now shows the right
string in Japanese for the months displayed.
For organizations using right-to-left languages like Arabic as their base language, the short weekday names are
now displayed on the date picker of the schedule board. Also fixed tooltip positioning issue for different
components of the schedule board.
Fixed navigation using keyboard tab key on the move bookings to a different Day dialog of the schedule board,
to move the focus from the booking statuses picker to the ok button, after a booking status is selected.
When a requirement status record is used as a default requirement status in the booking setup metadata record
of a schedulable entity, the deletion of the requirement status record will not be restricted.
On the schedule board, the fields on the booking tooltip with long strings were truncated. With this fix, the long
strings will be word wrapped into a new line.
When an open area is selected on the schedule board, a pane opens with a lookup for the resource requirement
record. Fixed a bug where the default view on this lookup was not changeable. With this fix, the resource
requirement view can be changed to any other active view of the resource requirement entity.
On the client extension entity form, the lookup field for the web resource is fixed to show all the WebResource
lookup views for CSS, JavaScript, and RESX views.
Fixed a bug when requirement groups are used with the work orders; on the schedule assistant, the booking
status drop-down on the Create Resource Booking pane shows not just the booking statuses of the work
order, but also related to other entities. With this fix, the booking status drop-down now only shows the booking
statuses of the work order.
When a resource requirement record and a bookable resource are selected on the schedule board, and the book
button is selected, the Create Resource Booking pane opens up with the start and end dates populated based
on the requirement selected. When the resource selection is changed, the selected start date and end date are
being reset. This bug is now fixed.
Improved the tooltip description of the field Actual Travel Duration field on the scheduling tab of the
bookable resource booking to Shows the total travel duration. Calculated based on the difference
between the Bookable Resource Booking's Star t Time and Actual Arrival Time.
The edit button on the business closure ribbon is hidden, as this button had no action on the business closure
records in the view.
Removed unnecessary debug console messages for the business closure entity views.
When a new business closure record is created, the duration field is calculated incorrectly by adding an
additional day. This bug is now fixed, and the duration field is calculated based on the start time and end time
selected.
When a requirement status record is created and saved, the requirement status lookup field is read-only, so that
this value cannot be changed once the record is saved.
When a requirement has multiple booking records associated, and one of the booking’s resources is not active,
the deactivated resource is filtered, and the uncaught exception is handled.
Fixed a bug with the timeslot selection on the create resource Booking pane. With this fix, when Book Based on
setting is set to Estimated Arrival , and the user selects a suggested time in the schedule assistant, the time
they select is populated as the estimated arrival time in the booking panel. When Book based on setting is set
to Star t Time , and the user selects a suggested time in the schedule assistant, the time they select is populated
as the start time in the booing panel.
Added additional checks on the schedule board default settings to prevent schedule board crash with the
Object reference not set to an instance of an object error.
Fixed a bug where the focus on the resource search control on the weekly view of the list view type of the
schedule assistant is lost when typing the resource name.
The custom date format is now supported on the quick book pane.
When a booking is created on the schedule board with duration of zero minutes, Duration must be greater
than 0 minutes is displayed in English on non-English orgs. This bug is fixed, and the string is now localized.

3.12.24.5
Fixed a bug where the search time window of the resource requirement is greater than the time range displayed
on the schedule board and schedule assistant, the resource booked hours capacity on the resource cell were not
displayed. The expand and collapse button next to the resource in daily, weekly, and monthly views were also not
displayed.

3.12.24.4
When you enable any entity for scheduling (for example, case, lead, account), enable Quick Book feature on the
Booking Setup Metadata record of this schedulable entity, and set Disable Requirement Auto Creation
for Bookings to yes. The resource requirement records will not be generated post the creation of the booking
record.
The bug where there are multiple pages of available resources suggested on the schedule assistant, only the
resources in the first page set were shown and resources on higher pages were not shown. This bug is fixed, and
paging through to next pages, resources will be shown as expected.
When there are multiple work hours are entered on the same day for a resource (for example, 8 AM to 3:30 PM
and 2 PM to 5 PM), there was a bug where the resource work hours calendar was only showing work hours as 2
PM to 5 PM. With this fix, the calendar for the resource would show that the resource is working 8 AM to 5 PM.
Also, the same should be reflected on the schedule board.
When a resource has working hours (for instance, 9 AM to 5 PM on a day) and has time off 12 PM to 1 PM,
there is a bug where schedule board shows that the resource has no working hours on that day, though the time
off is for only one hour. This bug is fixed, and with this fix, the resource should show as working from 9 AM to 12
PM and 1 PM to 5 PM on the schedule board.
When creating a resource requirement using a work hours template, performance improvements are made to
reduce the time of creation for the resource requirement record.
When the resource work hours are entered by using non-recurrence patterns for a large number of days, and
large number of resources (for instance, more than 2000 resources in the org), when looking for available
resources, the schedule assistant takes almost 40 seconds to load resources. Performance improvements are
pushed as part of this fix, where in this case, the schedule assistant loads much faster (around five to ten
seconds, largely based on the amount of data).

3.12.23.71
The issue with the filtering on the lookup type fields on the schedule board's requirement panel is fixed.
When hovered on the bookings on the schedule board, the tooltip was shown instantly, which sometimes
blocked the view or blocked using right-click on the bookings. This issue is now fixed by adding a hover delay.
When hovered on the booking, tooltip will be displayed with a delay.

3.12.23.27
The rendering issue for tooltips on bookings of the schedule board is now fixed, by making the tooltip scrollable
when the height of the tooltip is larger than the browser size. The hyperlinks on the tooltip can also be selected
to open them in a new browser window.
The text Hide default requirement panels is now made visible on the schedule board tab settings under the
Requirement Panels section, which was previously only partially visible.
Fixed an issue where entering a comma on the filter control of the filter panel was clearing the input on the filter
control. With the fix, the comma will not influence the autocomplete, which was causing issues for customers
who have a comma in their filter options.
If the work hours tab is renamed or removed from a custom bookable resource form, when you select the
Show work hours button, an error will be displayed: The Work Hours tab has been renamed or
removed from this form. Please update this form to include the Work Hours tab. Update so that the
work hours tab can be added back to the form.
Fixed an issue on the Create resource booking panel on the schedule board. With the fix, the Star t Date and
End Date on the panel will always reflect the From Date and To Date of the requirement selected in the
Requirement Panel at the bottom of the board.
The map pins of the resource requirement records are loaded on the map view of the filter panel on the
schedule board, based on the view that is defined on Requirement Map Filter View on schedule board
settings. We fixed the issue where, if the view used here has no filters on the view definition, the map panel
never completes loading. With this fix, the map panel would load, regardless of the filters on the view used.
Fixed an issue where Universal Resource Scheduling is used as the scheduling engine; users who are not
system administrators were unable to complete the appointment records. With the fix, any user with privileges
to complete the appointment record can mark the appointment as complete.

3.12.22.9
For organizations that have schedule board preview enabled, the schedule board preview can be accessed from
Field Ser vice application sitemap along with Universal Resource Scheduling application sitemap.
Fixed an issue where booking tooltip blinks when the height of the tooltip is greater than the height of the
visible center Gantt area, where bookings are displayed on the schedule board. With this fix, the tooltip would
not blink and the user would be able to select the hyperlinks on the tooltip to open the respective record in a
new window.
Fixed the issue where intervals functionality of fulfillment preferences was not working on the schedule
assistant.
Resolved the issue of duplicated time slots for the resources on the list view type of the days view of the
schedule board.
Multiple calls to retrieve data in the list view type of the days view are reduced to one call, in order to improve
schedule board performance.
Fixed the issue where available time slots of resources are displayed differently on schedule assistant and the
quick scheduling pane for the schedulable entities that do not have an associated resource requirement record.
The horizontal and vertical view types are now hidden from the requirement group's find availability or
schedule assistant screen.
Fixed the error The star t address and end address cannot be empty , which is incorrectly thrown on the
Get Driving Directions functionality on the schedule board, due to an uncaught exception.
Advanced find on the business closures entity is now supported.
When using the schedule assistant/find availability functionality, the available time slots should be shown in the
same timezone of the requirement calendar; however, if a schedulable entity like case doesn't have a
requirement record associated, then the results need to be shown in the timezone of the CRM user preference.
The issue of resource name truncation in the days view of the schedule board is now fixed.
Fixed the focus shifting issue on the schedule board, where focus is shifted to a previous booking in focus, when
booking status of the bBooking assigned to a resource at the bottom of the resource list. With this fix, the focus
would stay on the booking in context.
Fixed a translation issue on requirement groups in Japanese, where the name of the requirement or subgroups
changes from Japanese to English when the record is saved.
Quick scheduling now supports and handles different date format styles like English (South Africa).
Fixed an issue with the Allow Overlapping functionality on the bookings. With this fix, when a booking is
marked as Allow Overlapping set to yes, the schedule assistant (find availability) will show the above booking
as an available time slot if the Allow Overlapping advanced setting on the filter view is selected.

3.12.21.9
The following Universal resource Scheduling 2020 Wave 1 features in GA and preview planned are included in
this release:
Next generation schedule board experience (preview)
Enhanced work hours calendar for resources
requirement dependency for efficient workflow
resource scheduling dashboard
This release also includes all fixes included in the 3.12.9.76 EA package.
Fixed an issue where the booking method on booking panel was not selectable on the list view of the days view
in schedule board.
Fixed a caching issue on the Get Driving Directions pop-up functionality of the schedule board, where
previously cached values were being used for calculating the route.
Resolved the incorrect location displayed for the booking on the map view of the schedule board, due to the
incorrect formatting issue in conversion of the latitude and longitude on the map in languages like German.
Fixed the issue where bookings of some schedulable entities cannot be moved to a different day in multiday
views like days and weeks views on the schedule board.
Fixed the issue when a requirement is dragged on to a crew resource on schedule board, a booking is only
created for the crew resource and not the underlying active crew resources.
Fixed an issue where a custom JavaScript is used in the schedule board client extensions to set the default filter
values, but the prepopulated default values are only displayed when the respective filter control is selected.
Fixed an issue where quick scheduling is used on a schedulable entity without associated resource requirement
record, and search start and search end dates are passed as the same day; available time slots were displayed
for three days rather than one passed in day. With the fix, the available will only be displayed for the date passed
in.
Fixed an issue where booking tooltips are not displayed on hover, when network latency is high.
Fixed a null reference exception for booking status metadata checks during the upgrade to improve upgrade
experience.

3.12.5.13
resource location can be displayed on the map view of the schedule board's daily view, using the custom entity
using the custom geo data settings in the scheduling parameters.
Fixed the issue with the action msdyn_SearchResourceAvailability was not taking the ConsiderTravelTime
parameter into consideration when providing the available time slots.
Fixed upgrade errors while generating the booking setup metadata records and a few other upgrade
improvements.
Fixed the issue where filters were not saved on the resource utilization view.
Booking created Successfully notification on the schedule assistant is only shown when the booking is
created successfully.
Fixed the incorrect booking time offset on daylight savings time dates for GMT + 1 timezone on the booking
and resource requirement forms.
Fixed null reference issues on the requirement group form.
Improved error handling on the copy function of the resource requirement form.
Resource name handling is improved in the search resources lookup on the days view of the schedule board.
Resource and grid alignment issues are fixed in the hourly view of the schedule board.
Calendar performance improvements are made for the generation of resource requirements from the project
form.
Improved error handling on the booking rules.
Schedule board scrolling issues are fixed, when moving the bookings of the resources at the bottom of the list.
Fixed the issue with the booking tooltip: when there are only two resources displayed on the schedule board, the
tooltip masks the booking itself.
Fixed the issue of the visual duplication of the bookings on the days, weeks, and months views of the schedule
board.
Improved error handling when creating bookings on the schedule board, by adding additional null checks.
Performance on the schedule board improved by just loading the requirements that are not location agnostic on
the map view.
Fixed the filter panel crash when using the fetch-based filter value and saved as default value.
Fixed the issue with the schedule assistant filter layout when a filter is changed from multi combo field to non-
multi combo filter.
When Double book if needed option is checked on the schedule assistant booking panel, even though the
resource does not have enough availability for the requested hours, the resource can be double booked up to 24
hours in one day.

3.12.9.76 - April 2020 Wave 1 Early Access


Fixed a performance issue when upgrading from Field Service version 7.x to version 8.x.
Fixed an issue with printing the get driving directions action on the schedule board.
When quick scheduling is used to schedule an entity that doesn't have an associated resource requirement,
results were always shown in UTC timezone, which is now fixed. The results should always be shown in the
user's timezone if there is no requirement calendar.
Tooltips are now supported on the sort options of the schedule board.
A new warning message is now introduced on editing the schedule board settings records: "Modifying these
settings has the potential to break the corresponding schedule board tab in a way that cannot be automatically
undone".
Fixed the bug with displaying the resource details in the list view of the schedule board.
A new warning message is now supported that the minimum duration needed to create a bookable resource
booking is 1 minute.
The field Status is now renamed to requirement Status on the requirement status entity.
Fixed the bug where schedule board crashes when a user record is deleted from the Azure Active Directory,
which has an associated bookable resource on the schedule board tab.
A select all check box is now supported on the select resources pop-up window on the filter panel sort options.
Min rating value now must be less than the max rating value on the rating model entity form.
When quick scheduling is enabled on a schedulable entity, the retrieve resources and retrieve constraints
queries of the underlying BSM record are called instead of the default queries.
Quick scheduling supports the requirement groups with one requirement that has work location type as facility.
The all/any option labels of the requirement group are now fixed in Danish language.
Auto apply territory filter field in scheduling parameters form is now deprecated and hidden.
Start and end date time fields on the business closures entity form and the grid view are displayed in the same
time zones.
When a work hours template is applied on multiple resources, a spinner is now added while the work hours are
being applied.
The from and to date fields on the requirement group form now reflect the timezone from the user's
preferences.
Details tab on the fulfillment preferences entity form will now only be displayed once.
Added a warning on the set work hours template pop-up dialog, that "Applying this work template will
overwrite the existing work hours, including time-off".
When the map panel on the schedule board is loaded, the map should be zoomed enough to show all the map
pins in the requirement map filter view definition.
XML syntax validation is now added on editing the schedule assistant filter layout.

3.12.4.9
Fixed an upgrade issue related to the timezone conversion of the TimeGroupDetail record.
Fixed incorrect booking time offset on daylight savings time dates for Auckland timezone.
Fixed the issue where some resources show unavailable on the schedule board, due to the number of calendar
rules on all the resources on the schedule board.
When there are characteristics on the filter panel that are paged, the rating value of the selected characteristic is
lost in the filter, which is now fixed.
Fixed the flickering issue on the second page of the open requirements tab of the requirement panel.
Fixed the alignment of the available time on the days view of the schedule assistant.
The filters on the filter panel now support text fields.

3.12.3.9
The one hour offset issue for the bookings created on the schedule board is fixed in the Brazil daylight savings
time.
The caching issue with the schedule assistant's default availability view setting is set to board is now fixed.
When a new booking is created on the days view of the schedule board, the board will be refreshed
automatically.
resource requirement map pins are loaded, only when the map view is opened on the filter panel of the
schedule board.
Fixed an upgrade issue due to bad data in the filter values.

3.12.2.114
When the schedule board map view is opened, the map automatically zooms out to show all the map pins.
The resource lookup is displayed on the schedule board in Arabic.
On the schedule assistant results list view, work start time aligns with the estimated arrival time values on the
create resource booking pane.
Added additional handling to avoid the corruption of the booking setup metadata and the schedule board
settings records.
Bookings can be edited in the days view of the schedule board by right-clicking on the booking and selecting
Edit .
The select resources dialog opens and loads successfully on the filter view of the schedule board, even when
there are more than 100 resources enabled to be displayed on the schedule board.
When Turkish language is enabled on the org, resource requirement records load under the Unscheduled
Work orders tab of the requirement pane of the schedule board.
When double-clicking on the save button the new bookable resource booking form, would not create duplicate
records.
Resources can be searched on the schedule board by their name in the search resources search box.
map view on the schedule board only shows the pins for the requirements that are returned from the
requirement view configured for requirement map filer view setting on the map settings of the schedule board
tab settings.
When Hebrew language is enabled on the org, schedule board loads in the Chrome with browser zoom at 90%.
The requirement demand pie chart on the schedule assistant information at the bottom is accessible, via screen
readers.

3.12.1.158
Workflows can be triggered when resource requirements are created with any allocation method.
When upgrading URS from version 2.x to version 3.x, resource filters on the schedule board tabs are preserved.

3.12.0.448
Grid alignment issues while scrolling on the schedule board for right-to-left languages (like Hebrew, Arabic) are
fixed.
When a new route is created for a map pin selected on the map panel, the route will stay on top of other routes,
even after the auto refresh, which happens when a booking is created or modified.
On the list view of the schedule board, any linked entity record can be opened by using keyboard, by hitting on
the space bar when focused on the linked entity.
The warning message notification on the schedule assistant is made user-friendly, when Maps are not enabled
for a resource requirement when work location is onsite.
The selected values of the filter "pool type" are also saved along with other filters, when the current filters are
saved as default filters.
When a crew type resource is booked, only the working members of the crew will be booked, crew members,
who are not working, will not get booked.
Custom date fields added to the filter panel as custom filters, will also respect the time zone of the schedule
board tab (under Scheduler settings)
When schedule board settings are opened from the booking setup metadata record of the Schedulable entity, by
clicking the Cancel button on the schedule board settings, the form will be closed.
The scrolling issues on the vertical view of the schedule assistant are fixed.
On the list view type of days, weeks, and month views of schedule board, the focus will stay on the resource
Search box until the typing is complete until focus is moved to a different area of the schedule board.
The quick scheduling experience will search for available resources in the date range provided in the
requirement group and displays available resources on the book resources panel in the date range.
On successful creation of bookable resource booking record in the offline mode, no unintended warnings will be
displayed on the form.
When looking for a substitute resource on a booking using the "Find Substitution" via schedule assistant, the
resource can be substituted on the suggested time slot by clicking on the "Substitute" button, when hovered on
the suggested time slot.
When there are more than 30 suggested resources on the schedule assistant, there will be paging of resources
and more suggested resources can be reached by scrolling to the next page.
When a map pin is selected for a booking on the schedule board, after editing the selected booking, (by
dragging and extending the booking), the map pin stays selected.
Schedule board will support booking alerts are in large number (~200).
Only active booking statuses will be displayed on the booking status dropdown field on the booking panel of
schedule board, when creating bookings.
When searching for available resources for a requirement group, suggested resources will always be shown in
list view only.
Resources on the schedule board tab can be selected via Select resources under the filter Options on the Internet
Explorer Version 11.
When calling the msdyn_SearchResourceAvailability action using a requirement with a fulfillment preference for
time group as input, the output time slot of the action will contain valid TimeGroupDetails.
Bookable resource bookings can be created on the daylight saving days (entering and exiting daylight savings
time).
Enhancements
Accessibility improvements are made on the schedule board and schedule assistant.

3.11.0.421
Columns in the list view of the schedule board resize based on the size of the browser (Internet Explorer)
A few accessibility issues on the schedule board and quick scheduling panel are fixed.
Days/weeks/month views on the schedule board support the bookings for the schedulable entities without
resource requirements.
When viewing the bookings of requirement group in Split view, the bookings in the Split view will be shown in
the same timeline as of the requirement group bookings in the top half of the grid.
work hours of a resource with capacity greater than 1 in a day, will reflect on the schedule board accordingly.
Resource capacity booked percentage reflects the resource's bookings in the days, weeks, and month views of
the schedule assistant.
The focus remains on the selected date when a resource is selected from the resource dropdown filter after
selecting a date on the calendar of the quick scheduling panel.
When a resource requirement with a characteristic and rating is booked, the characteristic filter will be
populated with the characteristic and rating value from the resource requirement in the filter view of the
schedule assistant.
The search start/search end and time from promised/time to promised date time filters on the filter view of the
schedule assistant reflect the from date/to date and time from promised/time to promised from the resource
requirement records.
The membership of the members of a crew type resource on the schedule board is shown in the timezone of the
schedule board.
Only one resource can be selected from the recommended resources on the list view of the schedule assistant.
When searching for available resources for an onsite requirement group, and a suggested time slot is selected,
the estimated arrival time and start fields in the create resource booking panel are filled with the start time and
travel start time values from the list view.
When hovered on the bookings on the schedule board, booking card is displayed with a delay.
A booking can be created for a work order in the days, weeks, or month views of the schedule assistant.
Schedule board loads bookings of resources, even with resources who have no calendar or have multiple
calendars.
Rebook for bookings would work even with null values of the filters passed to the schedule assistant.
The schedule board and schedule assistant will load booking and resource availability on the Internet Explorer
Version 11.
Enhancements
Support for preferred and mandatory resource in finding available resources.
Usability improvements to the facility search scenarios via quick scheduling experience.

3.10.0.239
Only valid hex characters can be entered on the status color field on booking status form.
The overlapping bookings in the vertical view of the schedule board are separated by 1-px spacing.
Non-working hours color name is consistent across the schedule board tab settings and the schedule board
settings configuration record.
Long names will be wrapped inside the booking tooltip.
Deletion of a resource is not allowed if it has any group memberships active or inactive, parent, or child, has any
associations active or inactive, resource 1 or resource 2.
When default sorting is added to the schedule assistant retrieve constraints UFX query in the default schedule
board settings, the sort by filter of the schedule assistant is pre-filled with the field by which sorting is done and
the returned resources are sorted accordingly.
A few accessibility issues on the schedule board are fixed.
Schedule board to load the resources in days, weeks, and month views with resources having a valid calendar
and wouldn't fatally fail if a resource has an invalid calendar.
Combo control filter with multiset to false, the selected value will show in the filter.
Active resource requirements view is sorted on created on by descending order.
Derive capacity from group members field on the pool resource form can be set to yes or no as required.
Search resources can be used to search resources in the suggested resources in the list view of the schedule
assistant.
Custom booking template with fields from linked entities of bookings is supported.
Resource type filter on the schedule assistant will not remember the previously selected values, once unselected.
The schedule assistant loads as expected when clicked on book button on a work order form in Arabic.
When a booking is created by schedule assistant, the booking method field on the booking form is populated as
schedule assistant.

3.9.0.42
The filter is not enabled for the owner column on the unscheduled work orders requirements view in the
requirement grid of the schedule board.
The refresh button on the requirement grid is disabled while the grid is refreshing the data.
Alignment for resource icons and the zoom slider on the schedule board are fixed for Arabic language.
When searching for resources in one view like horizontal, when switched to another view, like list view, the
search is still retained along with the search text and results.
The bookings can be moved to a different time or resource by dragging and dropping the booking on days,
weeks, and month views of the schedule board.
Quick scheduling would be using the "As The Crow Flies" approximations to calculate travel time if Bing maps
integration is not enabled.
Improved error messaging on the schedule assistant when looking for available resources and on the schedule
board when displaying the bookings.
When auto update booking travel is enabled, and onsite bookings are created by the quick scheduling, the travel
time to the subsequent bookings is updated based on the location of the previous booking.
The schedule assistant search for available resources will be successful with continuous multiple associations on
a single day for a resource type facility.
When an onsite requirement is selected in the requirement grid, the location pin is selected and focused in the
map view. Once clicked on "Find Availability," the location pin on the map view will stay selected entering and
exiting the schedule assistant.
Alignment of the fields on the fulfillment preferences form is fixed.
Alignment of the sort arrows on the sort options control on the schedule board is fixed.
Time out issues request to msdyn_RetrieveResourceAvailability is posted from a web app are fixed.
Enhancements
FetchXML query is replaced by query expression for the action that fetches work order bookings to improve the
performance.

3.8.0.105
The date selector on the schedule assistant list view is dimmed because it has no effect on the resources
displayed when searching for availability of a requirement or a work order.
When booking a schedulable entity record, only the booking status that is mapped to the booking status field
logical name of the booking setup metadata record of the schedulable entity will be on the schedule assistant.
For example, when scheduling a work order, only the option set values of the field msdyn_fieldservicestatus will
be displayed in the booking status drop-down on the schedule assistant,
When searching for availability of resources on a requirement, the number of matching resources returned in
the search on the schedule assistant is limited to the value set on the field resource availability retrieval limit on
the default metadata settings of the booking setup metadata record. The default value of resource availability
retrieval limit is 100.
Only one booking setup metadata for an entity can be created.
For German locale, on the schedule assistant, remaining duration does not overlap with the pie chart visual next
to it.
Only Active resources can be added to a resource pool or resource crew's children.
A few accessibility issues on the schedule board are fixed.
The resource requirement form can be customized to remove optional fields like resource type from the form.
Selected sort on the schedule board is determined by the Sort result by filter on filters.
The booking alerts template field on the default schedule board settings shows the default HTML template
value.
Book and Book & Exit buttons on the schedule assistant are enabled only when at least one eligible resource is
returned on the schedule assistant.
Multiple characteristics can be selected on the filters on the schedule board.
A booking cannot be deleted when it has an associated booking alert.
When booking a requirement in the weekly view or monthly view of the schedule assistant, if the availability
search start date is today and is not the first day of the week or month, the start date will correctly default to
today, so that the book button is enabled.
The work location filter on the schedule assistant will show all three possible values: onsite, facility, and location
agnostic.
The filters on the schedule board will show the right values in the drop-down even when the user manually
types in the filter.
When Auto Update booking travel is enabled in the scheduling parameters, travel time of the adjacent bookings
is updated when a booking is created in the list view of the schedule assistant.
Correct search results are displayed on the quick scheduling panel for all timezone values set on the resource
requirement form.
A multi resource work order, that is, a work order associated with a requirement group, can be booked via quick
scheduling.
Requirement group bookings can be viewed in split view.
The Timeline header on the schedule board will be shown even after exiting the schedule assistant by selecting
exit search.
The rating values on the rating model form are ordered by rating values, not the names.
The resource card can be opened by right-clicking the resource, even when the resource has characteristics with
no rating values.
When booking a requirement group via the schedule assistant, selecting a time slot on the list view opens up the
Create resource booking Panel on all browsers.
When booking a requirement group or the requirements under that requirement group, the same results are
displayed on the schedule assistant.
Facility requirements can be booked via quick scheduling with the correct duration of the booking.
You can book work orders on the days view of the schedule assistant.
Multiple issues preventing upgrade.
Enhancements
Performance improvements to schedule board refresh times when multiple crew type resources are present on
the schedule board.
Performance improvements to searching for resource availability for requirement Groups.
Reduced unnecessary calls to retrieve the resource requirements name and booking setup metadata. Other
duplicated calls are also reduced when searching for availability.
Self-service scheduling API is now available to schedule the single resource requirement, with a corrected
process name Resource Scheduling – Search Resource Availability and unique name
msdyn_searchresourceavailability.
From and to date fields on the resource requirement entity are restricted to have only the User Local behavior to
avoid Time Zone functionality loss on the schedule assistant and loss of the time zone data on resource
requirements.
Added a suggestion to service health diagnostics to show the suggestion/fix with manual steps when resource
booking sync job is disabled but the feature synchronize resource bookings with outlook is enabled.
When using URS on Unified Service Desk, the schedule board can be loaded without having to pass the full
Unified Interface context.
Quick scheduling now supports scheduling of onsite requirements.

3.7.0.70
Requirement group control loads in the service form on the customer service scheduling app.
When a schedulable entity without a resource requirement is booked via the schedule assistant (pop-out
schedule board) days, weeks, or months views, the booking status is populated to the default status.
The resource routes are optimized by listing using the schedule board driving directions in the sort order of a
booking's start time.
Optimized rebooking in the schedule board by fixing a client-side console error.
Map view icon is no longer displayed in the schedule assistant view.
Changes on the default schedule board settings form are saved when accessed from booking setup metadata
record.
Drag and drop the bookings from one resource to another or from one time to another of the same resource in
days, weeks, or months views.
Resource names with apostrophes, like O'Brien, can be searched on the schedule board resources.
Booking a resource requirement for the facility resource type now populates the resource filter field as a facility
in the schedule assistant (pop-out schedule board).
Book based on setting for the schedule board shows how the time slot suggestions are displayed in the Hourly
view of the schedule assistant, and more details on how to use book based on are included.
Duration filter on the schedule assistant for Hebrew is fixed when the value of the duration is 1.
Travel start time on the schedule assistant list view shows as travel time subtracted from the work start time.
Drag and drop multiple open requirements to an expanded resource in days, weeks, or months view to create
multiple bookings.
Rendering of the resources on the schedule board is improved.
View resource cards in the schedule assistant for requirement groups availability.
Schedule assistant minimizes the number of resources necessary to fulfill a requirement group when the Sort
result by field is set to Fewest resources first.
Multiple issues preventing upgrade.
Drag resource route on the map to a requirement pin to create a booking for the resource.
The Select resources filter can be used to select the resources to be displayed on the schedule board.
Only active members of the crew with valid crew membership will be booked when a crew is booked.
Driving directions and the map view on the schedule board have the same traffic icon.
The position of the hover book button on the suggested time slots is adjusted when the preceding booking is
extended beyond the suggested time slot.
When a requirement is selected and the requirements panel is refreshed, the requirement selection persists.
Enhancements
Made improvements to uptake new endpoint Bing distance matrix APIs.
Self-service scheduling API is now available to schedule the single resource requirement.
The work location for new requirements added to a requirement group is now inherited from the work location
of the existing requirements in the requirement group, and is kept in sync.
The calendars of the requirements of a requirement group are kept in sync and share the same calendar.
Changing a calendar or time zone for one requirement updates it for all the requirements of the requirement
group.
When booking a requirement group, the schedule assistant is launched in the time zone of the requirement
group's requirements because they all share the same requirement.
Performance improvements to searching for resource availability, viewing bookings on the schedule board,
creating bookings for crews, creating bookings in the hourly views of the schedule board, and when using other
URS plug-ins.

3.6.0.18
On the schedule assistant, the radius unit behavior reflects kilometers or miles as per the preferred unit of
distance when "Search for" field is changed.
The zoom level on the "Map View" on the "Filter Panel" will be preserved after entering or exiting the Schedule
assistant search.
Only activated members of a crew get booked when a crew is booked.
On the schedule board setting for schedule assistant, the unavailable resources field can be changed from
"Unavailable resources do not appear" to "Unavailable resources appear dimmed" to show the unavailable
resources on the schedule assistant.
Alignment of scheduler settings controls.
On a schedule assistant search for available resources on a location agnostic resource requirement, the "Time
From Promised" and "Time to Promised" time window precedes over the "Search Start" and "Search End" time
window, and the recommendations will be presented to make sure the technician can start work in the "Time
From Promised" and "Time To Promised" window.
Onsite multi-resource requirements will be presented with travel time in the schedule assistant
recommendations.
The filter panel's characteristic field on the schedule assistant is populated with the characteristic from the
resource requirement or work order.
Multiple issues preventing upgrade.
Resource utilization of a resource on non-working day, along with the color code of the non-working day.
Dragging the technician travel route to a requirement pin to schedule the booking in the maps view on the filter
panel of schedule board.
The schedule board setting "Order Number" default maximum value is increased to 1000 from 100.
Duration field value text in Hebrew on schedule assistant.
Enhancements
When inserting a booking between two bookings or reassigning a booking to another resource, the travel time
of all associated bookings will be recalculated and updated on hourly schedule board and schedule assistant.
This feature can be enabled by "Auto Update booking travel" field under Resource Scheduling > Settings >
Administration > Scheduling Parameters .
When the Book button is used on the resource requirement and the timezone on the pop-out schedule board is
updated, the date time fields on the bottom requirement info panel will reflect the changed timezone.
All the date and times in the filter panel and requirements panel on the schedule board are updated when the
time zone is changed in the scheduler settings on the schedule board.
Various performance improvements when searching for resource availability.

3.5.0.107
Booking status on the create resource booking panel is always defaulted to either front load or the last used
value on the schedule board.
On the schedule assistant, a new booking can be created in custom time, by clicking and dragging in the
demand panel, which opens the create resource booking panel for confirmation of booking details.
A resource requirement record can be created by quick create forms on the schedule board, even there are no
resources on the schedule board tab are working.
When the start and end locations of the bookable resource are set to organizational unit address, the
organizational unit field becomes mandatory field.
The row height and column width slider tooltip value is now localized.
The location of the tooltip, when dragging and dropping an existing booking on the board is corrected in the
Hebrew language orgs.
Slider controls on the scheduler settings of the schedule board are aligned in the orgs with right-to-left
languages.
Error handling improvements on the schedule board.
Resource requirement details associated view of resource requirements includes additional details like duration,
from and to fields.
The skills subgrid in the resource requirement form will only show relevant data and hide the redundant data
like the resource requirement name field.
On the schedule board, bookings can be created with the start/end dates in the past.
Contains solution upgrade improvements.
Select resources dialog opens for selection of resources to be shown under the schedule board tab
The working time of the schedule board tab can be configured by using the start time and end time slider
controls under the scheduler settings of the schedule board tab.
Duplicate booking creation on the schedule board, due to network race conditions is now fixed.
The availability cells in the days view of the schedule board are appropriately aligned on the daylight savings
days at 12:00 AM.
The duration of the bookings on the multi-day views of the schedule board can be decreased by dragging the
right end of the booking to left or left end of the booking to right.
The pre-filled characteristic-Rating value in the filter view, can be selected to view it the filter view.
Booking rules dialog respects the cancel button and wouldn't create a booking.
When looking for available resources using a resource requirement for resource type facility, in the list view of
the schedule assistant, organizational unit column shows the appropriate string values.
When clicked on maintain bookings for a team member, opens up the schedule board with the project bookings
for the selected team member.
Book button is displayed on the resource requirement form for the users only with appropriate read/write
privileges to the entity.
Resource requirement for facility type pool can be searched for available resources using the schedule assistant
or find availability.
Enhancements
Improvements are made to the date time controls by leveraging the Office fabric UI control on the resource
requirement, fulfillment preferences, and time group detail forms.
Scheduling Health Diagnostics provides capabilities to detect and suggest self-healing options with regards to:
Unsupported customizations on internal use only web resources.
Actions and workflows that are in draft state.
Essential SDK message processing rules that are in disabled state.
Missing metadata records such as booking setup metadata records, default UFX query values.
Improvements are made to the icons on the booking right-click menu.
If Connect to Maps is disabled, the travel times will be calculated based on the "Crow fly" approximations.
Performance improvements for the retrieve resource availability action calls on the multi-resource requirements
with fulfillment preferences (intervals).

3.4.0.141
Custom date and time fields now display properly on schedule board panels.
Issues opening and saving schedule board resource picker under options in filter control.
Paging issues when using schedule board resource picker under options in the filter panel.
When "Time From Promised" on the requirement is in the past and you search for availability, the value is now
moved to the current time and the search button is enabled.
Changing the schedule board working time no longer immediately closes the settings dropdown.
Book button now appears on views and forms when using USD.
Resources associated to a facility with a parent Organization Unit that is different from the associated facility
correctly use facility organizational unit when it comes to schedule assistant facility search.
Miles/kilometers default properly from scheduling parameters entity.
Generic resource type is removed from resource picker under the select resources dialog.
Auto focus on characteristic rating value in filter control when entering schedule assistant on certain devices.
Overbooked requirements no longer show a negative duration in booking panel when in schedule assistant
Facility searched properly group results by organizational unit, regardless of the value in the "part of same" field
on the requirement group control.
Resources that are location agnostic, yet are associated to a facility, will return in facility searches for the time
they are associated to the facility.
Issue selecting pool type on schedule board filter panel while using Firefox browser.
Selecting cells in daily, weekly, and monthly boards while in schedule assistant now passes information to the
booking panel properly.
Schedule boards that have characteristics with rating values saved no longer prompt user to enter a rating
value.
Issue on certain devices where current timeline bar on schedule board wasn't showing correct time.
Work location on booking is now set properly when using drag and drop on schedule board.
Misaligned labels for languages that read right to left.
Issue loading schedule board in Internet Explorer 11.
Issue creating schedule alerts from certain places.
Enhancements
Various performance improvements when creating bookings.
Dragging to extend a booking on multi-day schedule boards opens booking panel instead of booking dialog.

3.2.0.405
If a booking has the work location field set to location agnostic, the booking will be treated as location agnostic
even if there is a latitude and longitude value on the booking.
Issue with schedule board list view refreshing when changing between hourly and daily.
When searching for a resource in the resource search bar on the schedule board list view, if no resources can be
found, the board properly removes all resources.
Issue dragging a requirement from the map to the schedule board while using Firefox browser.
Changing "derive capacity" field on a pool resource from no to yes now triggers the calendar to be calculated
based on the child resources of the pool.
Issues when changing between horizontal and vertical schedule board while in split view.
Issue loading schedule board with many explicitly saved resources.
Resource's location is now properly taken from the facility it is associated to.
When using a language that reads from right to left, the resource name is now properly rendered on the
schedule board.
When launching the schedule assistant from a schedulable entity, the user now lands back on the same form
after clicking book and exit.
Schedule board no longer shows resource with a capacity greater than 1 as available all day.
When booking a requirement group using the schedule assistant, the booking status dropdown now properly
filters to the booking statuses for that schedulable entity.
Issues loading requirement group control in the Microsoft Edge browser.
When using the schedule assistant to schedule a requirement group for a facility, there is no longer a travel time
conflict between the facility and the resources.
Double booking option in schedule assistant on daily, weekly, and monthly boards now properly books the
resource even if the resource has no remaining capacity.
Appointment schedule board settings are now generated properly.
Issues in certain scenarios where schedule board had issues loading in Internet Explorer.
"Supplied DateTime represents an invalid time" error.
Error message when scheduling a single requirement to a crew resource.
Enhancements
Resources associated to facilities will no longer return in onsite schedule assistant searches. This prevents
customers from accidentally scheduling a resource that should be stationed at a facility from going to a
customer location.
Resources that are not associated or related to a facility will no longer return in facility searches. Currently, when
a resource is set up to work at a facility through an association or as a child resource of a pool, URS does not
account for travel to the facility.
When using the schedule assistant to schedule a requirement group, if the requirement's work location is set to
facility, and there are no options selected under the "part of same" attribute, the search will execute as if part of
same "resource Tree" is selected.
Saving a filter on the schedule board now shows a green confirmation check mark instead of a yellow warning
symbol.
Warning message will now be displayed when trying to change the latitude or longitude field on a booking.
Added validation to check that if a resource is associated to a facility, then it should not be allowed to be a child
resource of a pool associated to a facility or facility pool for the same time frame.

3.1.0.166
If a booking has the work location field set to location agnostic, the booking will be treated as location agnostic
even if there is a latitude and longitude value on the booking.
Issue with schedule board list view refreshing when changing between hourly and daily.
When searching for a resource in the resource search bar on the schedule board list view, if no resources can be
found, the board properly removes all resources.
Issue dragging a requirement from the map to the schedule board while using Firefox browser.
Changing "derive capacity" field on a pool resource from no to yes now triggers the calendar to be calculated
based on the child resources of the pool.
Issues when changing between horizontal and vertical schedule board while in split view.
Issue loading schedule board with many explicitly saved resources.
resources location is now properly taken from the facility it is associated to.
When using a language that reads from right to left, the resource name is now properly rendered on the
schedule board.
When launching the schedule assistant from a schedulable entity, the user now lands back on the same form
after clicking book and exit.
Schedule board no longer shows resource with a capacity greater than 1 as available all day.
When booking a requirement group using the schedule assistant, the booking status dropdown now properly
filters to the booking statuses for that schedulable entity.
Issues loading requirement group control in the Microsoft Edge browser
When using the schedule assistant to schedule a requirement group for a facility, there is no longer a conflict of
travel time between the facility and the resources.
Double booking option in schedule assistant on daily, weekly, and monthly boards now properly books the
resource even if the resource does not have any remaining capacity.
Appointment schedule board settings are now generated properly.
Issues in certain scenarios where schedule board had issues loading in Internet Explorer.
"Supplied DateTime represents an invalid time" error.
Error message when scheduling a single requirement to a crew resource.
Enhancements
Resources associated to facilities will no longer return in onsite schedule assistant searches. This prevents
customers from accidentally scheduling a resource that should be stationed at a facility from going to a
customer location.
Resources that are not associated or related to a facility will no longer return in facility searches. Currently, when
a resource is set up to work at a facility through an association or as a child resource of a pool, URS does not
account for travel to the facility. Therefore, only resources set to work at a facility will return in facility searches.
When using the schedule assistant to schedule a requirement group, if the requirement's work location is set to
facility, and there are no options selected under "part of same" attribute, the search will execute as if part of
same "Resource Tree" is selected.
Saving a filter on the schedule board now shows a green confirmation check mark instead of a yellow warning
symbol.
Warning message will now be displayed to a user if they try to change the latitude or longitude field on a
booking.
Added validation to check if a resource is associated to a facility then it should not be allowed to be a child
resource of a pool that is associated to a facility or facility pool for the same time frame.

2.4.11.59
Read a blog post about the bug fixes.

2.4.10.56
Read a blog post about the bug fixes.

2.1
Read a blog post about the bug fixes.

You might also like