Hello everyone,
I have two different functions that validates the Work order form when the OnSave event is triggered and those two functions are about the below logic:
- Prevent the user to close posted the work order if the linked agreement is canceled.
-
Prevent the user from completing the work order if not all the service tasks are done.
Please find below the JS code based on the above:
function preventSave(executionContext) { debugger; if (executionContext.getEventArgs().isDefaultPrevented()) { return; } var boolRule1 = false; var formContext = executionContext.getFormContext(); var status = formContext.getAttribute("msdyn_systemstatus").getValue(); // getting the status the value // Completed Status // status is not close posted if (status === 690970004 || status === 690970003) { var ruleOne = false; var ruleTwo = false; if (status === 690970004) { rule1(executionContext).then(function (data) { ruleOne = data; console.log(ruleOne); // return rule1(executionContext); }, function (errorMessage) { Xrm.Navigation.openAlertDialog({ text: errorMessage }); // return rule2(executionContext); }).then(function (data) { if (!ruleOne) { Xrm.Navigation.openAlertDialog({ text: "Current work order can't be saved because of canceled agreement" }); return; } else { formContext.data.save().then(function () { alert("Form saved successfully"); }, function (error) { // failure // you get more information about why saving data failed in error argument: var errorMessage = error.message; console.log(errorMessage); }); } }); } if (status === 690970003) { executionContext.getEventArgs().preventDefault(); rule2(executionContext).then(function (data) { ruleTwo = data; console.log(ruleTwo); //return rule2(executionContext); }, function (errorMessage) { Xrm.Navigation.openAlertDialog({ text: errorMessage }); // return rule2(executionContext); }).then(function (data) { if (!ruleTwo) { Xrm.Navigation.openAlertDialog({ text: "current work order can't be closed because not all the service tasks are done" }); return; } else { formContext.data.save().then(function () { alert("Form saved successfully"); }, function (error) { // failure // you get more information about why saving data failed in error argument: var errorMessage = error.message; console.log(errorMessage); }); } }); } } else { formContext.data.save().then(function () { console.log("Form saved successfully"); }, function (error) { // failure // you get more information about why saving data failed in error argument: var errorMessage = error.message; console.log(errorMessage); }); return; } } function rule1(executionContext) { // 1. Prevent the user to close posted the work order if the linked agreement is canceled. var formContext = executionContext.getFormContext(); var agreement = formContext.getAttribute("msdyn_agreement").getValue(); executionContext.getEventArgs().preventDefault(); var promiseRule1 = new Promise(function (resolve, reject) { var boolRule1 = true; if (agreement != null && agreement.length > 0) { var id = agreement[0].id; var result = Xrm.WebApi.retrieveRecord("msdyn_agreement", id, "?$select=msdyn_systemstatus").then( function success(result) { if (result["msdyn_systemstatus"] === 690970003) { //Xrm.Navigation.openAlertDialog({text:"Current work order can't be saved because of Cancelled agreement"}); boolRule1 = false; } resolve(boolRule1); }, function (error) { //Xrm.Navigation.openAlertDialog({ text: error.message }); reject(error.message); } ); } else { resolve(boolRule1); } }) return promiseRule1; } function rule2(executionContext) { //3. Prevent the user from completing the work order if not all the service tasks are done. var promiseRule2 = new Promise(function (resolve, reject) { var boolRule2 = true; var serviceTaskValidation = true; var formContext = executionContext.getFormContext(); //get current WO id var workOrderId = formContext.data.entity.getId().replace("{", "").replace("}", ""); //var valInc = formContext.getAttribute("msdyn_primaryincidenttype").getValue(); var woStatus = formContext.getAttribute("msdyn_systemstatus").getValue(); //close the WO or not //console.log(valInc); executionContext.getEventArgs().preventDefault(); if (woStatus != null && woStatus === 690970003) { // If the System status is equal to Completed //get active related service task var result = Xrm.WebApi.retrieveMultipleRecords("msdyn_workorderservicetask", "?$select=msdyn_name,msdyn_percentcomplete,statecode&$filter=statecode eq 0 and msdyn_workorder/msdyn_workorderid eq " workOrderId).then( function success(result) { for (var i = 0; i < result.entities.length; i ) { console.log(result.entities[i].msdyn_name); console.log(result.entities[i].msdyn_percentcomplete); if (result.entities[i].msdyn_percentcomplete != 100) { serviceTaskValidation = false; break; } } if (!serviceTaskValidation) { boolRule2 = false; resolve(boolRule2); } }, function (error) { reject(error.message); } ) } }); return promiseRule2; }
The issues that I am facing while debugging are:
- The APIs are returning the expected result, but when it comes to check if the form should be saved or not, if the condition is met that means it should save the new values and when I try to save the form it is not saving.
- If the condition is not met that means it should not save the values. However, it is saving the form and the same function goes into an infinite loop knowing that I turned off the autosave feature.
I believe this is because whenever I am defining the formcontext inside the function its triggering the autosave but I already used preventDefault() to strict it and I think that preventDefault is causing some issue in promise function.
Could you please check what I am doing wrong in the code and provide the corrected version?
Any help is highly appreciated.
Thank you!