Search resource availability and create bookings for requirement groups

Use the Search Resource Availability for Requirement Group API and the Create Requirement Group Bookings API to book the resources that meet the needs you identify in your requirement groups.

You pass the details of a requirement group in your API calls and retrieve a list of available resources and their open time slots. This list is helpful for self-scheduling scenarios where a user wants to view the availability of resources, or for portal scheduling scenarios where a customer wants to view resource availability from a website or app.

Prerequisites

  • Dynamics 365 version 9.0 or above with Universal Resource Scheduling version 3.12.x.x

Search Resource Availability for Requirement Group API

Use the following input and output parameters for the Search Resource Availability for Requirement Group (msdyn_SearchResourceAvailabilityForRequirementGroup) API.

Parameters

Name Type Required Description
Version String Yes The version number of the API. The version number identifies the version of the API that should be invoked. The version number is a semantic version number of the format major.minor.patch. The request doesn't have to contain the complete version number.
RequirementGroup Yes An entity reference to the requirement group entity.
RequirementSpecification Integer No If left null, respects the targeting requirement group duration by default.
Settings Entity<InputSettings> No Sets the settings for the request.

Inputsettings

Name Type Required Description
ConsiderSlotsWithLessThanRequiredDuration Boolean No Specifies if a time slot with less than the required remaining duration should be considered when computing potential time slots. It's false by default.
ConsiderSlotsWithOverlappingBooking Boolean No Specifies if time slots with overlapping bookings should be considered when computing potential time slots. It's false by default.
ConsiderSlotsWithProposedBooking Boolean No Specifies if time slots with proposed bookings should be considered when computing potential time slots. It's false by default.
MaxResourceTravelRadius Distance No Specifies the maximum travel radius for resources when computing available time slots.
SortOrder Integer No Specifies the requirement group order for the response.
PageSize Integer No Numbers of item returned in a page. It's 20 by default.
PagingCookie String No Paging cookie retrieved from previous searching result.
OrganizationUnits List<Guid> No A collection of organization unit IDs. A qualified resource must be a member of one of the specified organization units.
MustChooseFromResources List<Guid> No Evaluate and select results from resources in this list.
RequiredResources List<Guid> No Evaluate all resources, filter the results based on this list. In general, use MustChooseFromResources instead for improved performance.
IgnoreTimeSlots Boolean No Specifies if the returned time slots should be ignored. When true, list of time slots returned is empty. It's false by default.
ConsiderAppointments Boolean Set to True for search resource availability API to respect existing Dataverse appointments as bookings on the resource, provided the organization and resource level settings are set. Appointments with busy or completed statuses are considered as unavailable for scheduling operations.

Output

Returns Name(Type) Description
TimeSlots (List<OutputTimeSlot>) StartTime (DateTime) The start time.
EndTime (DateTime) The end time.
ArrivalTime (DateTime) The arrival time.
Travel(OutputTimeSlotTravel)

OutputTimeSlotTravel
  • Distance (Double)
  • TravelTime (Double)
  • DistanceFromStartLocation (Double)
  • TravelTimeToEndLocation (Double)
The time slot travel information. Is only present if the resource requirement contains values for latitude and longitude.
Effort (Double) The effort/capacity.
IsDuplicate (Boolean)   A Boolean value indicating if the time slot is a duplicate.
Resource(OutputResource)

OutputResource
  • Resource (BookableResource)
  • TotalAvailableTime (Double)
The Resource entity as explained in this article.
Location(OutputTimeSlotLocation)

OutputTimeSlotLocation:
  • WorkLocation (Enum):
    • Onsite (0)
    • Facility (1)
    • Location agnostic (2)

  • LocationSourceSlot (Enum):
    • Common (1)
    • Custom GPS entity (2)
    • Mobile audit (3)
The entity contains details about the location of a time slot. For more information, see TimeSlotLocation in this article.
TimeGroup(TimeSlotTimeGroup)

OutputTimeSlotTimeGroup:
  • TimeGroupId (Guid)
  • TimeGroupDetail (EntityReference)
  • TimeGroupDetailStartTime (DateTime)
  • TimeGroupDetailEndTime (DateTime)
The entity contains details about a time group. For more information, see TimeSlotTimeGroup in this article.
AvailableIntervals (List<<Guide>OutputTimeSlot>) A collection of available intervals.
Resources (List<OutputResource>) Resource (EntityReference) An entity reference to the bookable resource.
BusinessUnit (EntityReference) An entity reference to the bookable resource group.
OrganizationalUnit (EntityReference) An entity reference to the organizational unit.
ResourceType (Int) The resource type. See the resourcetype attribute on the BookableResource entity for possible values.
PoolId (Guid) The ID of the pool that the resource is a member of during the time slot.
CrewId (Guid) The ID of the crew that the resource is a member of during the time slot.
Email (String) The resource’s email address.
Phone (String) The resource’s phone number.
ImagePath (String) The path to the resource’s image.
Requirements (List<OutputRequirements>) Requirement (EntityReference) An entity reference to the Resource Requirement record.
ConstraintBag (String) Requirement constraint in ufx bag(internal)
Resources (List<<EntityReference>EntityReference>) Entity reference list of resource that is available to the requirements.
ProposalResourceAssignmentSets (List<OutputProposalResourceAssignmentSet>) IntervalStart (DateTime) Start time for each proposal resource assignment set.
ProposalResourceAssignments (List<OutputProposalResourceAssignments>

OutputProposalResourceAssignments:
  • RequirementId (Guid)
  • ResourceId (Guid)
List of Resources assigned to Requirement.
PagingInfos (OutputPagingInfo) MoreResults (Boolean) If there are more results or not.
PagingCookie (String) Paging cookie that can be used in the future search.

Example

{
  "RequestName": "msdyn_SearchResourceAvailabilityForRequirementGroup",
  "Parameters": [
    {
      "Key": "Version",
      "Value": "1"
    },
    {
      "Key": "RequirementGroup",
      "Value": {
        "Id": "6927721a-0137-42be-8092-26995625a9d9",
        "LogicalName": "msdyn_requirementgroup",
        "Name": null,
        "KeyAttributes": [],
        "RowVersion": null
      }
    }
  ],
  "RequestId": null
}

Response

{
  "ResponseName": "msdyn_SearchResourceAvailabilityForRequirementGroup",
  "Results": [
    {
      "Key": "TimeSlots",
      "Value": {....}
    },
    {
      "Key": "Requirements",
      "Value": {....}
    },
    {
      "Key": "ProposalResourceAssignmentSets",
      "Value": {....}
    },
    {
      "Key": "PagingInfos",
      "Value": {....}
    }]
}

Create Requirement Group Bookings API

Use the following input and output parameters for the Create Requirement Group Bookings (msdyn_CreateRequirementGroupBookings) API.

Parameters

Name Type Required Description
Version String Yes The version number of the API. The version number identifies the version of the API that should be invoked. The version number is a semantic version number of the format major.minor.patch. The request doesn't have to contain the complete version number.
RequirementGroup EntityReference Yes An entity reference to the requirement group entity, usually is a GUID, as shown in the following sample.
Start DateTime Yes Start time of the Timeslot.
Duration Integer Yes The Duration of the Booking to be created.
ResourceAssignments EntityCollection Yes It's an entity collection of the Resource Assignments that are to be made for the Bookings to be created. Look at the Resource Assignment entity table for more details

Resource Assignments

Name Type Required Description
RequirementId Guid Yes The resource requirement ID of the Requirement for which the booking record is to be created.
ResourceId Guid Yes The bookable resource ID of the Resource for which you want to create the booking.
BookingStatusId Guid Yes The booking status ID of the booking to be created.
Effort Integer No The capacity of the Bookable Resource that this booking consumes.
TravelTime Integer No The travel time in minutes.

Output

Returns HandlerExecuted that is of Boolean type.

Using the Requirement Group API

In the following scenario, you schedule a requirement group via API. You need a service created with resources before you can schedule a booking. Follow these steps to create a service activity.

Service configuration 

Service configuration.

  1. In the site map, under Scheduling, select Service.
  2. Go to Resource Requirements.
  3. Create a service activity. For this example, we created Test Requirement Group.

Service Activity configuration 

Service Activity configuration.

  1. In the site map, under Scheduling, select Service Activities.
  2. Go to Service Activities.
  3. For Subject, select Test Requirement Group.
  4. For Service, select Test Requirement Group.

Note

This configuation automatically creates a resource requirement group that has the same name as the service activity.

Now you have a requirement group automatically created that has one technician (resource) to be scheduled to perform service at your customer's location.

Resource Requirement Group grid

The following image is an example configuration of the Resource Requirement Group page.

Active Requirements Group.

Note

To access the Requirement Group page from the Customer Service Hub app, you need to navigate there via a URL.

Important

Use the following URL to reach the Resource Requirements Group page: <<YourOrgURL>YourOrgURL>?appid=guid&pagetype=entitylist&etn=msdyn_requirementgroupr.

Test Requirements Group.

  1. Go to General.
  2. Name field Test Requirement Group.
  3. Enter name in Owner field.
  4. Template field.
  5. Template Required, select No.

Search against your organization

In this next scenario, we show how to pass values for a specific requirement group (Entity Reference - GUID), Required Resources to complete work and match the resource to the organizational unit.     

Important

  • To run the Requirement Group API, you need GUIDs for:
    • Requirement group
    • Bookable resources
    • Organizational unit (which can be retrieved by using the Web API)
  • If the API is called from a client (browser or canvas app) based on JavaScript, you need to have the extended SOAP SDK. The extended SOAP SDK is not an official Microsoft release, but you can is provided in the downloadable sample files for guidance.
  • We recommend that you test this search in your development or test environments to validate your scenarios and results before running it in your production environment.
  • This API uses the complex object type in the input and output, so it only supports the SOAP endpoint. It doesn't support the OData endpoint.

To execute this search against your organization, you need to download the sample files, and then complete the following steps.  

  1. Modify the hard-coded input parameters in the msdyn_SearchResourceAvailabilityForRequirementGroupSample.js file to reflect the GUIDs of records in your org. (Example: requirement group, resources, organizational unit).   

Modify the hard-coded input parameters to reflect record GUIDs.

Sample Search Requirement Group

  1. Add the files in the sample folder as web resources in your organization 

Modify the hard-coded input parameters to add the files in the sample folder.

Modify the hard-coded input parameters for the sample folder.

  1. Navigate to the newly added new_msdyn_SearchResourceAvailabilityForRequirementGroupSample.htm page. Example: <<YourOrgURL>>//WebResources/new_msdyn_SearchResourceAvailabilityForRequirementGroupSample.htm  

Navigate to the newly added page.

  1. Open the browser's developer tools by using the F12 function key. Set breakpoints as needed, and inspect the request/responses in the developer tool's console.  

Open the browser developer tools.

We can see that there are multiple sets of time slots that are returned with each set, corresponding to a matching available resource that's mapped to the underlying requirement of the requirement group.   

After the time slot Sets are returned by the API, you can display them on your custom web portal, app, or a Power App (model/canvas).   

  1. After you choose a specific time slot set (Set number 1 in this example), update your new_msdyn_CreateRequirementGroupBookingsSample.js web resource in your org to pass the resource assignments (Requirement guid, Resource guid) and the Requirement Group, as shown in the following example.   

Update web resource to pass resource assignments.

Important

Find the complete sample code here: Create Requirement Group.

Find the sample code.

  1. Navigate to the newly added new_ msdyn_CreateRequirementGroupBookingsSample.htm page. (Example: <<YourOrgURL>>//WebResources/new_msdyn_CreateRequirementGroupBookingsSample.htm) to invoke a call to the Booking API and create the booking.

Invoke a call to the Booking API.

  1. Open the browser's developer tools by using the F12 function key. Here, you see that the handler executed value is set to true, indicating that the bookings were created successfully.   

Handler executed value set to True.

We can also verify this value by going back into the organization and checking the associated bookings of the Service/Requirement group we created, as shown in the following images.   

Check the associated bookings.

Verify bookings were created successfully.

Other possible scenarios that might use these APIs are:  

  • Build a custom web app or a Dynamics 365 portal to provide appointment scheduling for users. The app shows available time slots for the service or product being offered by using multiresource requirements (requirement groups).
  • Build a Power Apps canvas app to support self-scheduling scenarios for line-of-business apps.   

See the Additional resources section for links to more help resources.

Sample code

The following sample code shows how to implement msdyn_SearchResourceAvailabilityForRequirementGroup message.

        { 
            // Authentication  
            String machineName = "contoso?????"; 
            String orgName = "?????"; 
            String domain = $"{machineName}dom.extest.microsoft.com"; 
            String uri = $"http://{machineName}.{domain}/{orgName}/XRMServices/2011/Organization.svc"; 
            String username = "?????"; 
            String password = "?????"; 

            OrganizationServiceManager osm = new 
            OrganizationServiceManager(new Uri(@uri), username, password, domain); 
            _serviceProxy = osm.GetProxy(); 
            _service = (IOrganizationService)_serviceProxy; 
            searchResourceAvailabilityForRequirementGroup(); 
            createRequirementGroupBookings(); 
        } 

        static void searchResourceAvailabilityForRequirementGroup() 
        { 
            var req = new OrganizationRequest() 
            { 
                RequestName = "msdyn_SearchResourceAvailabilityForRequirementGroup" 
            }; 

            //Version  
            req["Version"] = "1"; 
            req["RequirementGroup"] = new EntityReference("msdyn_requirementgroup", Guid.Parse("e5e4f033-150d-eb11-a822-000d3aaf102a")); 

            Entity requirementSpecification = new Entity(); 
            requirementSpecification.Attributes.Add("msdyn_fromdate", DateTime.Today.AddDays(1)); 
            requirementSpecification.Attributes.Add("msdyn_todate", DateTime.Today.AddDays(3)); 
            req["RequirementSpecification"] = requirementSpecification; 

            try 
            { 
                var response = _service.Execute(req); 
                Console.WriteLine("Response from search: {0}", JsonConvert.SerializeObject(response)); 
            } 
            catch (Exception e) 
            { 

                Console.WriteLine("msdyn_SearchResourceAvailabilityForRequirementGroup failed with the following error: {0}", e.Message); 
            } 
        } 

        static void createRequirementGroupBookings() 
        { 
            var req = new OrganizationRequest() 
            { 
                RequestName = "msdyn_createRequirementGroupBookings" 
            }; 

            req["Version"] = "1"; 
            req["RequirementGroup"] = new EntityReference("msdyn_requirementgroup", 
            Guid.Parse("d74260ee-180d-eb11-a822-000d3aaf102a")); 
            req["Start"] = DateTime.Today.AddDays(1); 
            req["Duration"] = 60; 
            EntityCollection resourceAssignment = new EntityCollection(); 
            var entity = new Entity(); 
            entity["RequirementId"] = Guid.Parse("df4260ee-180d-eb11-a822-000d3aaf102a"); 
            entity["ResourceId"] = Guid.Parse("268e3d0d-5e0c-eb11-a822-000d3aaf102a"); 
            entity["BookingStatusId"] = Guid.Parse("10de5842-cf5e-4092-9006-d0aa9f9c1f74"); 
            resourceAssignment.Entities.Add(entity); 
            req["ResourceAssignments"] = resourceAssignment; 

            try 
            { 
                var response = _service.Execute(req); 
                Console.WriteLine("Response JSON : " + JsonConvert.SerializeObject(response)); 
            } 
            catch (Exception e) 
            { 
                Console.WriteLine("msdyn_createRequirementGroupBookings request failed with the following exception: {0}", e.Message); 
            } 
            Console.ReadKey(); 
        }  

How to migrate from the legacy API to Universal Resource Scheduling

To migrate from the legacy Search API and Book API to the Universal Resource Scheduling API, use the following required input and output fields to map the APIs.

Input mapping data for the Search API

Legacy input Universal Resource Scheduling input Description
ServiceId Requirement group Service/requirement group GUID
SearchWindowStart Start date Start date for the appointment search
SearchWindowEnd End date End date for the appointment search
Duration Duration Appointment duration
No of results Page size Total number of proposals or number of appointments on a page
Sites OrganizationUnits Site/OU GUID
RequiredResource Preferred Resources Resources the customer prefers to schedule
Constraints Constraints Customer entity(ufx)
RecurrenceDuration In a recurrence appointment search, the duration of the appointment
RecurrenceTimeZoneCode Time zone for a recurring request
SearchDirection Forward or backward search for slots, based on the dates given
AnchorOffSet Offset in hours from midnight
UserTimeZoneCode Time zone set for the user
SearchRecurrenceRule Frequency, interval, count, and so on
Resource Types Type of resource
Restricted Resources Restricted for scheduling the appointment

Output mapping for the Search API

Legacy output Universal Resource Scheduling output
Appointment proposals ProposalsResourceAssignmentSet
TraceInfo
ExtensionDataObject
Time Slots
Requirements(constraintbag)
PagingInfos

Example scenarios for migrating from the legacy scheduling API to Universal Resource Scheduling

The scenario-based examples in this section add more details about mapping from the legacy API to the new Universal Resource Scheduling API.

Scenario 1: Get two resources for each schedule proposal

The following screenshot from the legacy API is provided for reference in this scenario.

Legacy setup screenshot for reference for scenario 1.

  1. Create one site (Site1), one user (User1), and one equipment resource (Facility/Equipment tab), with the name Eq1, with the site set to Site1.

  2. Create the business closure and work hours for the user (8:00 AM to 6:00 PM) and the equipment (8:00 AM to 6:00 PM).

  3. Create a new service (Service1), and then add required resources as Choose 2 from User1, Eq1. Save and close the service.

Schedule Service Activity screenshot for scenario 1.

  1. Go to the homepage and schedule a service activity and then, select Service1, and then select Schedule > Find available slots.

  2. Verify that each proposal returns the two resources in accordance with the criteria you set.

Universal Resource Scheduling API code for scenario 1

void searchRequirementgroup(Microsoft.Pfe.Xrm.OrganizationServiceManager osm)
{ 
var req = new Microsoft.Xrm.Sdk.OrganizationRequest() 
{ 
RequestName = "msdyn_SearchResourceAvailabilityForRequirementGroup"
};

  req["Version"] = "1"; 
  Entity requirementSpecification = new Entity();

  //Setting from date 

  requirementSpecification.Attributes.Add("msdyn_fromdate", DateTime.Parse("2019-12-  
  26T18:30:00.000Z"));

  //Setting to date 

  requirementSpecification.Attributes.Add("msdyn_todate", DateTime.Parse("2019-12- 
  27T18:29:00.000Z"));

  //Requirement group GUID 
  req["RequirementSpecification"] = requirementSpecification; 
  req["RequirementGroup"] = new   
  Microsoft.Xrm.Sdk.EntityReference("msdyn_requirementgroup", Guid.Parse("XXXXXXXX"));

  //Executing the request and getting response
  var response = osm.GetProxy().Execute(req); 
  response.ToString(); 
  response.Dump();
} 	 

Scenario 2: Verify that search results are correct for scheduling

The following screenshot from the legacy API is provided for reference in this scenario.

Legacy setup screenshot for reference for scenario 2.

  1. Create the following sites and users:
  • Two sites: Micr0s0ftSite1 and Site2
  • Two users: User1 and User2 (Site2)
  • Go to Settings> Service management tab and create a site(with the name Site1), two resources on the Facility/Equipment tab (namely, Eq1 and Eq2) and go to setting> Security and create a user(User1). Two equipment resources on the Facility/Equipment tab (Eq1, Eq2), where Eq1 belongs to Site1 and Eq2 belongs to Site2
  1. Create the business closure and work hours for the user (8:00 AM to 6:00 PM) and the equipment (8:00 AM to 6:00 PM).

  2. Create a new service with status Reserved and required resources as Choose 2 from same site from User1, User2, Eq1, Eq2. Save and close the service.

Service Activity screenshot for scenario 2.

  1. Go to the homepage > Service Activity > Schedule, and then select the service you created in step 3. Select the site as Site1, and then click on Find available time.

  2. Verify that the search results that are returned are correct for the site selected in the search criteria.

Universal Resource Scheduling API code for scenario 2

void searchRequirementgroup(Microsoft.Pfe.Xrm.OrganizationServiceManager osm)
{
  var req = new Microsoft.Xrm.Sdk.OrganizationRequest()
  {
  RequestName = "msdyn_SearchResourceAvailabilityForRequirementGroup"
  };
req["Version"] = "1"; 
Entity requirementSpecification = new Entity();

//Setting from date
requirementSpecification.Attributes.Add("msdyn_fromdate", DateTime.Parse("2019-12-26T18:30:00.000Z"));

//Setting to date
requirementSpecification.Attributes.Add("msdyn_todate", DateTime.Parse("2019-12-27T18:29:00.000Z")); 

req["RequirementSpecification"] = requirementSpecification;

//Requirement group GUID      
req["RequirementGroup"] = new EntityReference("msdyn_requirementgroup", Guid.Parse("XXXXXX"));

var response = osm.GetProxy().Execute(req);
response.ToString();
response.Dump();

}

Scenario 3: Get proposed schedules that occur within the working hours for an equipment resource

Legacy setup screenshot for reference for scenario 3.

  1. Create two sites (Site1, Site2), and then create three equipment resources (Eq1, Eq2, Eq3).

  2. Create the business closure and work hours for all equipment (3:00 PM to 6:00 PM).

  3. Create a new service (Service1) Choose 1 from (Random) Eq1, Eq2, #q3.

Service Activity screenshot for scenario 3.

  1. In the Schedule Service Activity dialog box, search for proposals for Service1 by adding a required resource as Eq1 for a specific date range.

  2. Verify that the proposed schedules that are returned occur within the working hours of the equipment for that date.

Universal Resource Scheduling API code for scenario 3

void searchRequirementgroup(Microsoft.Pfe.Xrm.OrganizationServiceManager osm)
{
var req = new Microsoft.Xrm.Sdk.OrganizationRequest() 
{
RequestName = "msdyn_SearchResourceAvailabilityForRequirementGroup"
};
req["Version"] = "1"; 
Entity requirementSpecification = new Entity();

//Setting start date          
requirementSpecification.Attributes.Add("msdyn_fromdate", DateTime.Parse("2019-12-26T18:30:00.000Z"));
//Setting end date
requirementSpecification.Attributes.Add("msdyn_todate", DateTime.Parse("2019-12-27T18:29:00.000Z"));

//Setting the eq1 as required resource	 	

requirementSpecification.Attributes.Add("msdyn_resourcerequirementid",Guid.Parse("XXXXXX")); 
req["RequirementSpecification"] = requirementSpecification; 

//Setting the requirement group GUID
req["RequirementGroup"] = new EntityReference("msdyn_requirementgroup", Guid.Parse("XXXXX"));

//Executing the request and getting response. 
var response = osm.GetProxy().Execute(req); 
response.ToString(); 
response.Dump(); 
} 

More resources

Resource Description
Service Scheduling Guide Read how you can plan and schedule service activities for your customers.
Service scheduling FAQ Frequently asked questions on service scheduling
Multiresource scheduling with requirement groups Use requirement groups to mix and match different types of resources.
Search Resource Availability API for single resource requirements Blog on how to use the Search resource availability API
Documentation for resource scheduling Get started with using Universal Resource Scheduling.
Learning path for resource scheduling Learn how to use Universal Resource Scheduling in Microsoft Dynamics 365 for Field Service
Dynamics 365 application ideas Use this portal to contribute product feedback and ideas for resource scheduling.
Community forum Use the community forum to ask questions, find answers, and see upcoming events.
Dynamics 365 blog Read the Dynamics 365 blog for release notes and posts from the product team.