Skip to main content

Notifications

Microsoft Dynamics 365 | Integration, Dataverse...
Suggested answer

Async OnSave event - Saving in progress error message

(0) ShareShare
ReportReport
Posted on by 873

Hello,

I have two JS codes that trigger the onSave event of the Work Order form. Each script includes some logic to validate the data before saving the work order, including Web API calls from different tables, and I have no problems with either script.  

However, when I press the Save button on the form, I got the following error message, and the form does not save from the first attempt: 

Save-in-progress-error.png

The form will be saved successfully on the second attempt. This error causes confusion for the end-user, who thinks the form has been saved.

Code 1:

var isValidationNeeded = true;
var preventEventSave = 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();
    var formContext = executionContext.getFormContext();
    var formType = formContext.ui.getFormType();  
    console.log(formType); 
    // let flagtosave = false;


if(formType !== 1){

    //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 ruleThree = false;

    rule3(executionContext).then(function(data) {
        ruleThree = data;
        if (!ruleThree) {
            if (saveMode === SaveMode.Save || saveMode === SaveMode.SaveAndClose) {
                Xrm.Navigation.openAlertDialog({
                    text: "Current work order can't be closed because the incident type is visit and contains products!"
                });
                return;

            }
        } else {
            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) {

                        ruleOne = data;

                        if (!ruleOne) {

                            if (saveMode === SaveMode.Save || saveMode === SaveAndClose) {
                                Xrm.Navigation.openAlertDialog({
                                    text: "Current work order can't be saved because it's linked to canceled agreement!"
                                });
                                return;

                            }

                        } else {
                            isValidationNeeded = false;
                            // flagtosave= true;
                            Xrm.Page.data.entity.save().then(function() {
                            }, function(error) {
                                var errorMessage = error.message;
                                console.log(errorMessage);
                            });
                            
                            

                        }
                    }, function(errorMessage) {
                        Xrm.Navigation.openAlertDialog({
                            text: errorMessage
                        });
                    });
                }


                if (status === 690970003) {

                    rule2(executionContext).then(function(data) {

                        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 {
                            isValidationNeeded = false;
                            // flagtosave = true;
                            Xrm.Page.data.entity.save().then(function() {
                            }, function(error) {
                                var errorMessage = error.message;
                                console.log(errorMessage);
                            });

                            
                        }
                    }, function(errorMessage) {
                        Xrm.Navigation.openAlertDialog({
                            text: errorMessage
                        });
                    });
                }

            } else {
                isValidationNeeded = false;
                console.log(preventEventSave);
                // setTimeout(()=> {
                    
                if (preventEventSave) {
                    Xrm.Page.data.entity.save().then(function() {
                    }, function(error) {
                        var errorMessage = error.message;
                        console.log(errorMessage);
                    });                }
                // }, 1000);

                
            }
        }
    }, function(errorMessage) {
        Xrm.Navigation.openAlertDialog({
            text: errorMessage
        });
    });
}
    // if(flagtosave){
    //     setTimeout(()=> {
            
    //         }, 600);
    // }
    // else{
    //     try{
    //         
    //     }catch(e){
    //         console.log(e);
    //     }
    // }
    // executionContext.getEventArgs().preventDefault();


}
    // if rule1 is passed then check rule3


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();
    
    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.
        
        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();
            var woType = formContext.getAttribute("msdyn_workordertype").getValue();
            //close the WO or not
            //console.log(valInc);
            if (woType != null && woType.length > 0) {
                var woTypeName = woType[0].name;
            }
            if (woStatus != null && woStatus === 690970003 && woTypeName === "Installation" ) { // If the System status is equal to Completed

                //get active related service task
                Xrm.WebApi.retrieveMultipleRecords("msdyn_workorderservicetask", "?$select=msdyn_name,msdyn_percentcomplete,statecode,haceb_responsevalueyesno&$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);
                            console.log(result.entities[i].haceb_responsevalueyesno);
    
                            if (result.entities[i].haceb_responsevalueyesno == false) {
                                serviceTaskValidation = false;
                                break;
                            }
                        }
                        if (!serviceTaskValidation) {
                            boolRule2 = false;
                        }
                        resolve(boolRule2);
                    },
                    function(error) {
                        reject(error.message);
                    }
                )
            }else{
				resolve(boolRule2);
			}
    
        });
        return promiseRule2;
    }

    function rule3(executionContext) { // Prevent Closing WO if primary incident is visit and WO contains products
        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 name = valInc[0].name;
                if (name == "Visit") {
                    
                    Xrm.WebApi.retrieveMultipleRecords("msdyn_workorderproduct", "?$select=msdyn_name&$filter=msdyn_workorder/msdyn_workorderid eq "   woID   " and statecode eq 0").then(
                        function success(result) {
                            console.log(result);
                            // perform operations on on retrieved records
                            if (result.entities != null && result.entities.length > 0) {
                                woProdValidation = false;
                            } else {
                            }
                            if (!woProdValidation) {
                                boolRule3 = false;
                            }
                            resolve(boolRule3);
                        },
                        function(error) {
                            reject(error.message);
                            // handle error conditions
                        }
                    )
                } else {
                    preventEventSave = false;
                    resolve(boolRule3);
                }
            } else {
                preventEventSave = false;
                resolve(boolRule3);
            }
        });
        return promiseRule3;
    }

Code 2:

var WorkOrderForm = (function () {
    var SaveMode = {
      Save: 1,
      SaveAndClose: 2,
      SaveAndNew: 59,
      Autosave: 70,
    };
  
    //this is variable that shows if validation was successfully passed or not
    var isValidationNeeded = true;
  
    function OnSave(executionContext) {
        // let flagtosave= false;
      //so if there are several save handlers and one of previous already called preventDefault
      //there is no need to do any validations anymore
      if (executionContext.getEventArgs().isDefaultPrevented()) {
        return;
      }
  
      //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;
      }
  
      //so if validation was successfully passed - flag is reset
      //and code just leaves the form alone and allows changes to be saved
      if (!isValidationNeeded) {
        isValidationNeeded = true;
        return;
      }
  
      //getting of the form context from execution context object
      //@ts-ignore
      var formContext = executionContext.getFormContext();
  
      //getting of "Account Number" value from field
      var worktype = formContext.getAttribute("msdyn_workordertype").getValue();
  
      let status = formContext.getAttribute("msdyn_systemstatus").getValue();
      console.log("status", status);

      let id = formContext.data.entity.getId();
      console.log("id", id);
      if (status === "690970004" || 690970004) {
        
        Xrm.WebApi.retrieveMultipleRecords(
          "haceb_assetdetail",
          `?$filter=(_haceb_workorder_value eq ${id.slice(1, id.length-1).toUpperCase()})`
        ).then(
          function success(result) {
            if (result.entities.length > 1) {
              Xrm.Navigation.openAlertDialog({
                confirmButtonLabel: "Close",
                text: "You can't save because you are only allowed to have 1 panel reading, delete the other one in order to save.",
                title: "Error Message",
              });
            }
            // perform additional operations on retrieved records
          },
          function (error) {
            console.log(error.message);
            // handle error conditions
          }
        );
      }
      //if field is blank there is no need to do any checks - code just leaves form
      if (worktype !== null) {
        console.log("workordertype ", worktype);
        if (worktype[0].name !== "Site inspection") {
          let serviceAccount = formContext
            .getAttribute("msdyn_serviceaccount")
            .getValue();
          if (serviceAccount !== null) {
            let asset = formContext.getAttribute("msdyn_customerasset");
            if (asset.getValue() === null) {
              //@ts-ignore
              Xrm.Navigation.openAlertDialog({
                title: "Validation Message",
                confirmButtonLabel: "Close",
                text: `Please make sure the ${serviceAccount[0].name} has a customer asset. Otherwise, please create your WO from the customer asset table or the sub-grid from the account.`,
              });
            } else {
            //    flagtosave= true;  
               isValidationNeeded = false;
            if (saveMode === SaveMode.Save || saveMode === SaveMode.Autosave) {
                formContext.data.entity.save();
              } else if (saveMode === SaveMode.SaveAndClose) {
                formContext.data.entity.save("saveandclose");
              } else {
                formContext.data.entity.save("saveandnew");
              }   
            // }, 1000);

            }
            //@ts-ignore
          } else {
            // raise error ...
            //@ts-ignore
            Xrm.Navigation.openAlertDialog({
              title: "Validation Message",
              confirmButtonLabel: "Close",
              text: "The OW not have service account.",
            });
          }
        } else {
            
            isValidationNeeded = false;
            if (saveMode === SaveMode.Save || saveMode === SaveMode.Autosave) {
                formContext.data.entity.save();
              } else if (saveMode === SaveMode.SaveAndClose) {
                formContext.data.entity.save("saveandclose");
              } else {
                formContext.data.entity.save("saveandnew");
              }
        
        }
        // if(flagtosave){
            

        //     // setTimeout(()=> {
              
  
        //     //   // setTimeout(()=> {
  
        //     // //and save event is called again
            
        //     // }   
        //     // }, 600);
        // }
        
        // else{
        //     try{
                executionContext.getEventArgs().preventDefault();
    
        //     }catch(e){
        //         console.log(e);
        //     }
        // }
      }
      
      
      //preventing of the save operation before async operation is started
    }
  
    return {
      OnSave: OnSave,
    };
  })();
  

I believe I am getting the above error because of the multiple async events for the API calls inside both of the scripts.

What will be the updated code for both of them to handle and solve this issue?

  I would highly appreciate your input and any help is highly appreciated.

Thank you,
EBMRay

  • Suggested answer
    Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Async OnSave event - Saving in progress error message

    Hi EBMRay,

    This error is caused by that you save the form's data again when it is saving. In your case, both Code1 and Code2 execute the form.data.save() function which leads to this error. 

    The best practise is that merge two code and execute Code2 after Code1 is succeed.

  • EBMRay Profile Picture
    EBMRay 873 on at
    RE: Async OnSave event - Saving in progress error message

    Hi  ,
    Thank you for your reply.

    I disabled Code 2 that I provided on the main post and tried to save a work order and as a result, the "Save in progress" disappeared.

    It seems that the issue is from code 2 because when I execute the save and Code 1 is enabled I don't get this message.

    What are the changes that should be applied to handle the async operation and make it work as Code 1 without doing the merge? Or the merge is recommended to make it work?

    Awaiting your response.

    Best regards,
    EBMRay

  • Suggested answer
    Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Async OnSave event - Saving in progress error message

    Hi EBMRay,

    Please check if both of them can execute independently(Disable one event to run another one).

    If so, you need to merge the two events to one. And then click your button to try again.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

News and Announcements

Announcing Category Subscriptions!

Quick Links

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Tips for Writing Effective Verified Answers

Best practices for providing successful forum answers ✍️

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,359 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,370 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Product updates

Dynamics 365 release plans