Below is another example of a Booking Rule as well as an interesting find.

This new Booking rule fetches the Characteristics from both the Resource and the Work Order and compares them to see if the Resource is valid to do the job.

First of all it will check if the Resource matches the Characteristics needed for the job and then will it check if their proficiency rating is equal or higher to the Work Order Requirement.

Full Code below:

function newBookingRule(sbContext) {

var resourceSkills = [];
var jobSkills = [];

var ruleResult = {
IsValid: false,
Message: '',
Type: 'error'
};
var resourceReqId = sbContext.newValues.ResourceRequirementId.replace(/[{}]/g, "");
if (resourceReqId != null) {
var req = new XMLHttpRequest();
req.open("GET", encodeURI(Xrm.Page.context.getClientUrl() + "/api/data/v8.2/msdyn_requirementcharacteristics?$select=_msdyn_characteristic_value,_msdyn_ratingvalue_value&$expand=msdyn_ratingvalue($select=value)&$filter=_msdyn_resourcerequirement_value eq " + resourceReqId), false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json;charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Prefer", "odata.include-annotations=OData.Community.Display.V1.FormattedValue");
req.send();
if (req.readyState === 4) {
req.onreadystatechange = null;
if (req.status === 200) {
var results = JSON.parse(req.response);
for (var i = 0; i < results.value.length; i++) {
var _msdyn_characteristic_value = results.value[i]["_msdyn_characteristic_value"];
var msdyn_ratingvalue_NextLink = results.value[i]["msdyn_ratingvalue"].value;
jobSkills.push({ skill: _msdyn_characteristic_value, rating: msdyn_ratingvalue_NextLink });
}
}
else {
Xrm.Utility.alertDialog(req.statusText);
}
}
}

var resourceId = sbContext.newValues.ResourceId.replace(/[{}]/g, "");
if (resourceId != null) {
var req2 = new XMLHttpRequest();
req2.open("GET", encodeURI(Xrm.Page.context.getClientUrl() + "/api/data/v8.2/bookableresourcecharacteristics?$select=_characteristic_value,_ratingvalue_value&$expand=RatingValue($select=value)&$filter=_resource_value eq " + resourceId), false);
req2.setRequestHeader("Accept", "application/json");
req2.setRequestHeader("Content-Type", "application/json;charset=utf-8");
req2.setRequestHeader("OData-MaxVersion", "4.0");
req2.setRequestHeader("OData-Version", "4.0");
req2.setRequestHeader("Prefer", "odata.include-annotations=OData.Community.Display.V1.FormattedValue");
req2.send();
if (req2.readyState === 4) {
req2.onreadystatechange = null;
if (req2.status === 200) {
var results2 = JSON.parse(req2.response);
for (var j = 0; j < results2.value.length; j++) {
var _characteristic_value = results2.value[j]["_characteristic_value"];
var ratingValue_NextLink = results2.value[j]["RatingValue"].value;
resourceSkills.push({ skill: _characteristic_value, rating: ratingValue_NextLink });
}
}
else {
Xrm.Utility.alertDialog(req2.statusText);
}
}
}

check_characteristics(resourceSkills, jobSkills);

if (jobSkills.length == 0) {
ruleResult.IsValid = true;
ruleResult.Message = "Success";
ruleResult.Type = 'success';
}
else {
ruleResult.IsValid = false;
ruleResult.Message = 'Resource is not qualified for this job';
ruleResult.Type = 'error';
}
return ruleResult;
}

function check_characteristics(a, b) {
for (var i = 0, len = a.length; i < len; i++) {
for (var j = 0, len2 = b.length; j < len2; j++) {
if (a[i].skill === b[j].skill && a[i].rating >= b[j].rating) {
b.splice(j, 1);
len2 = b.length;
}
}
}
}

 

An interesting thing that I found out is that you can also trigger the booking alert from the Schedule Assistant. Nothing that Interesting I know! But I found an interesting difference between how the sbContext.newValues.ResourceRequirementId brings back its Id.

When you drag and drop a Work Order on to the Schedule Board it brings back the ResourceRequirementId without curly braces. But if you use the Schedule Assistant it will bring it back with curly braces! Its important to know that this happens as if its not handled appropriately within the JavaScript it will cause an error when trying to Schedule a Work Order.

 

Schedule Board – (No Curly Braces)

 

Schedule Assistant – (Curly Braces)

So please make sure that you handle this by removing the braces by using this:

sbContext.newValues.ResourceRequirementId.replace(/[{}]/g, "");

My previous blog on Booking Rules for reference – http://www.kentom.co.uk/?p=455

Hopefully this has been helpful!

Leave a Reply

Your email address will not be published. Required fields are marked *