Thank you for providing the resources to check for save mode.
I updated the code to check for the save mode and I started adding a new rule to our script that:
However, while testing rule1 & rule2 only I noticed an issue when you click the save button:
The first time the button is clicked it throws the error which is expected. However, if you click the same button again after you close the popup of the dialog the form gets saved and skip the validation process.
In addition, the error dialog does not appear at all when the button was pushed the second time.
var isValidationNeeded = true;
var SaveMode = {
Save: 1,
SaveAndClose: 2,
SaveAndNew: 59,
Autosave: 70
};
function preventSave(executionContext) {
debugger;
//getting save mode from event
var saveMode = executionContext.getEventArgs().getSaveMode();
//if savemode is not one of listed - just quit the execution and let the record to be saved
if (saveMode !== SaveMode.Save &&
saveMode !== SaveMode.SaveAndClose &&
saveMode !== SaveMode.SaveAndNew &&
saveMode !== SaveMode.Autosave) {
return;
}
if (!isValidationNeeded) {
isValidationNeeded = true;
return;
}
var boolRule1 = false;
var formContext = executionContext.getFormContext();
var status = formContext.getAttribute("msdyn_systemstatus").getValue(); // getting the status the value
console.log(status);
// 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) {
isValidationNeeded = false;
ruleOne = data;
if (!ruleOne) {
if (saveMode === SaveMode.Save || saveMode === SaveAndClose){
executionContext.getEventArgs().preventDefaultOnError();
Xrm.Navigation.openAlertDialog({
text: "Current work order can't be saved because of canceled agreement"
});
return;
}
} else {
if (saveMode === SaveMode.Save || saveMode === SaveAndClose){
formContext.data.save().then(function() {
alert("Form saved successfully");
}, function(error) {
var errorMessage = error.message;
console.log(errorMessage);
});
}
}
}, function(errorMessage) {
Xrm.Navigation.openAlertDialog({
text: errorMessage
});
});
}
if (status === 690970003) {
rule2(executionContext).then(function(data) {
isValidationNeeded = false;
ruleTwo = data;
if (!ruleTwo) {
Xrm.Navigation.openAlertDialog({
text: "current work order can't be closed because not all the service tasks are done"
});
return;
} else {
alert(2);
formContext.data.save().then(function() {
alert("Form saved successfully");
}, function(error) {
var errorMessage = error.message;
console.log(errorMessage);
});
}
}, function(errorMessage) {
Xrm.Navigation.openAlertDialog({
text: errorMessage
});
});
}
}
if(incType == "Visit"){
var ruleThree= false;
rule3(executionContext).then(function(data) {
isValidationNeeded = false;
ruleThree = data;
if (!ruleThree) {
Xrm.Navigation.openAlertDialog({
text: "current work order can't be closed because the incident type is visit and contains products!"
});
return;
} else {
alert(3);
formContext.data.save().then(function() {
alert("Form saved successfully");
}, function(error) {
var errorMessage = error.message;
console.log(errorMessage);
});
}
}, function(errorMessage) {
Xrm.Navigation.openAlertDialog({
text: errorMessage
});
});
}
}
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) { //2.Prevent the user from completing the work order if not all the service tasks are done.
executionContext.getEventArgs().preventDefault();
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);
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;
}
function rule3(executionContext){ // Prevent Closing WO if primary incident is visit and WO contains products
executionContext.getEventArgs().preventDefault();
var promiseRule3 = new Promise(function (resolve, reject) {
var boolRule3 = true;
var woProdValidation = true;
var formContext = executionContext.getFormContext();
var woID = formContext.data.entity.getId().replace("{", "").replace("}", "");
var valInc = formContext.getAttribute("msdyn_primaryincidenttype").getValue();
if(valInc != null && valInc.length >0){
var id = valInc[0].id;
Xrm.WebApi.retrieveRecord("msdyn_incidenttype",id,"?$select=msdyn_name").then(
function success(result){
alert(valInc);
if(result.msdyn_name == "Visit"){
var incType = result.msdyn_name;
Xrm.WebApi.retrieveMultipleRecords("msdyn_workorderproduct","?$select=msdyn_name&$filter=msdyn_workorder/_msdyn_workorder_value eq " + woID).then(
function success(result) {
// perform operations on on retrieved records
if(result.entities.length == 0){
alert("no data");
}else{
for (var i = 0; i < result.entities.length; i++) {
woProdValidation = false;
console.log(result.entities[i].msdyn_name);
break;
}
if (!woProdValidation) {
boolRule3 = false;
}
resolve(boolRule3);
}
},
function (error) {
reject(error.message);
// handle error conditions
}
);
}
},function (error){
Xrm.Navigation.openAlertDialog({ text: error.message });
// handle error conditions
}
);
}
});
return promiseRule3;
}
What are the changes that should be done in the code to avoid those issues? Could you please provide the updated version?
Looking forward to your response.