In this step-by-step guide, we extend Universal Resource Scheduling 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 main entity Language stores 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 model this by creating two new lookup attributes: Primary Language and Secondary Language. When the system looks for available resources for a requirement, only resources associated with either the Primary Language or the Secondary Language show.
Creating the new entities and relationships
In this section, we create the new schema for the main Language entity and update the Resource and Requirement entities with the corresponding relationships to the new Language entity.
Create a new Publisher
In Dynamics 365, under Customizations, create a new Publisher.
Fill out the New Publisher form with the below details:
Field
Value
Display Name
Language
Name
language
Prefix
lang
Select Save and Close.
Create a new Solution
In Dynamics 365, under Customizations, create a new solution.
Fill out the New Solution form with the below details:
Field
Value
Display Name
Language
Name
Language
Publisher
Language
Version
1.0.0.0
Select Save.
Create the Language entity
In the Language solution, create a new entity.
Fill out the New Entity form with the below details:
Field
Value
Display Name
Language
Plural Name
Languages
Name
lang_language (The lang_ prefix will be autofilled and read-only)
Select Save.
Create the many-to-many relationship from the Resource entity to the Language entity
In the Language entity, create a new Many-to-Many Relationship.
Fill out the New Relationship form with the below details:
Field
Value
Current Entity
Display Option
Use Plural Name
Other Entity
Entity Name
Bookable Resource
Select Save and Close.
Close the Language entity form.
Create the relationships from the Requirement entity to the Language entity
In the Language solution, add the existing Resource Requirement entity to the solution. If presented with a Missing Required Components dialog, select No, don't include required components.
In the Resource Requirement entity, create a new field.
Fill out the New Field form with the below details:
Field
Value
Display Name
Primary Language
Data Type
Lookup
Target Record Type
Language
Select Save and Close.
In the Resource Requirement entity, create a new field.
Fill out the New Field form with the below details:
Field
Value
Display Name
Secondary Language
Data Type
Lookup
Target Record Type
Language
Select Save and Close.
Update the Requirement main form
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, don't include required components.
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.
Select Save.
Select Publish.
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 update the Retrieve Resources Query and the Filter Layout configuration records.
Note
These schedule board customizations will apply to all tabs uniformly and cannot be set individually per tab. This applies to Schedule Assistant Filter Layout, "Schedule Assistant Retrieve Resources Query, Schedule Assistant Resource Cell Template, and Schedule Assistant Retrieve Constraints Query.
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 Universal Resource Scheduling from the Filter panel and add Languages as the only available filter.
In order to keep these changes isolated, we 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.
In Dynamics 365, in the top navigation bar, go to Resource Scheduling > Schedule Board.
In the top right, select the + sign to create a new board.
Name the new board language.
At the bottom of the dialog, select Add. The new board will be created.
Update the Schedule Board Filter Layout
Next, we create a new configuration record, which stores filter layouts and queries used by the Schedule Board, and then we link the newly created Schedule Board to the new configuration record. There are multiple ways to do this, but here's the quickest:
Select the Language tab.
Scroll down to General Settings > Other Settings.
Locate the Filter Layout field, select the button to the right to open the editor
Update the Value field with the Filter Layout code above and select Save As.
Enter "Language Filter Layout" in the Name field and select Save. This creates a new configuration record and links this Schedule Board to the record.
At the bottom of the dialog, select Apply
The board will reload and you see the Filter panel in the left with the new layout; only the Languages filter will be available. Filtering won't 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
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're 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're using multiple link-entity joins.
Here's the description of each element and attribute:
Name
Description
link-entity
Create a join to the many-to-many relationship between the Resource and Language entities
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.
Here's the description of each element and attribute:
Name
Description
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.
UFX Queries are processed in sequential order. After the resources are retrieved through FetchXML, the results are assigned to the Resources property. We're sorting the results based on the lang_order property added earlier and reassigning the sorted results to the Resources property.
Here's the description of each element and attribute:
Name
Description
Resources
Reassign the Resources property
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 Universal Resource Scheduling is a large query that supports all the resource constraints included with Universal Resource Scheduling. For this exercise, we'll use only a subset of the default query and add Languages as the only filter.
Update the Schedule Board Retrieve Resources Query
In the top right, double-click the Language tab
Scroll down to General Settings > Other Settings
Locate the Retrieve Resources Query field, select the button to the right to open the editor
Update the Value field with the Retrieve Resources Query code above and select Save As
Enter "Language Resources Query" in the Name field and select Save. This creates a new configuration record and links this Schedule Board to the record.
At the bottom of the dialog, select 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'll 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 select 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 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 Universal Resource Scheduling from the Schedule Assistant Filter Layout configuration and add the Languages dropdown as the only available filter.
The filter we're 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.
Scroll to the Schedule Types section and select None in the left list
Locate the Schedule Assistant Filter Layout field, select the button to the right to open the editor
Update the Value field with the Schedule Assistant Filter Layout code above and select Save As
Enter "Language Schedule Assistant Filter Layout" in the Name field and select Save. This creates a new configuration record and links this Schedule Board to the record.
At the bottom of the dialog, select 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 Universal Resource Scheduling is a large query that supports all the requirement constraints included with Universal Resource Scheduling. For this exercise, we'll use only a subset of the default query and add Languages as the only filter.
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're 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's the description of each element and attribute:
Name
Description
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)
Scroll to the Schedule Types section and select None in the left list
Locate the Schedule Assistant Retrieve Constraints Query field, select the button to the right to open the editor
Update the Value field with the Retrieve Resources Query code above and select Save As
Enter "Language Constraints Query" in the Name field and select Save. This creates a new configuration record and links this Schedule Board to the record.
Locate the Schedule Assistant Retrieve Resources Query field and select the Languages Resources Query we created earlier for the Schedule Board Customizations
At the bottom of the dialog, select 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'll now be able to select a Requirement record in the bottom of the Schedule Board, select 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're 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.
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.
Scroll to the Schedule Types section and select None in the left list
Locate the Schedule Assistant Resource Cell Template field, select the button to the right to open the editor
Update the Value field with the Resource Cell Template code above and select Save As
Enter "Language Resource Cell Template" in the Name field and select Save. This creates a new configuration record and links this Schedule Board to the record.
At the bottom of the dialog, select 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 shows 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.
Demonstrate how to configure a Microsoft Dynamics 365 for Field Service implementation to maximize tools and features available while managing a mobile work force.