You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dynamics 365中JavaScript点击Finished按钮标记约会为Completed失效求助

Fix: Appointment Reverts to Original Status After Marking as Completed via JavaScript in Dynamics 365

Let's break down why your code is causing the status to revert and fix it step by step.

Root Causes of the Issue

  1. Missing Form Save: Your code sets the statecode and statuscode values but never saves the form. Without saving, the changes are only temporary and will revert when the form refreshes or system processes run.
  2. Event Timing Conflict: When you click the "Finished" button, Dynamics 365 runs its own internal logic to update the process status. Your code might be executing before this logic completes, leading to your changes being overwritten.
  3. Deprecated API Usage: Xrm.Page is deprecated in newer Dynamics 365 versions—using the modern formContext API is more reliable and avoids potential compatibility issues.

Updated Code Solutions

Option 1: Modern API (Recommended)

This uses formContext (the supported replacement for Xrm.Page) and adds proper saving + delay to avoid conflicts:

function OnLoad(executionContext) {
    const formContext = executionContext.getFormContext();
    formContext.data.process.addOnProcessStatusChange(statusOnChange, formContext);
}

function statusOnChange(executionContext) {
    const formContext = executionContext.getFormContext();
    const processStatus = formContext.data.process.getStatus();

    if (processStatus === "finished") {
        // Delay execution to let system process the status change first
        setTimeout(() => markAsComplete(formContext), 500);
    }
}

function markAsComplete(formContext){
    const stateCodeAttr = formContext.getAttribute("statecode");
    const statusCodeAttr = formContext.getAttribute("statuscode");

    if (stateCodeAttr && statusCodeAttr) {
        // Optional: Verify your status codes match your environment's configuration
        // console.log("State Code options:", stateCodeAttr.getOptions());
        // console.log("Status Code options:", statusCodeAttr.getOptions());

        stateCodeAttr.setValue(1);
        stateCodeAttr.setSubmitMode("always");
        
        statusCodeAttr.setValue(3);
        statusCodeAttr.setSubmitMode("always");

        // Save the form to persist changes
        formContext.data.save().then(
            () => console.log("Appointment marked as completed successfully!"),
            (error) => {
                console.error("Save failed:", error);
                alert("Failed to mark appointment as completed. Check logs for details.");
            }
        );
    } else {
        alert("State Code or Status Code fields are missing from the form.");
    }
}

Option 2: Legacy API (For Older Environments)

If you're stuck using Xrm.Page, this modified version fixes the core issues:

function OnLoad() {
    Xrm.Page.data.process.addOnProcessStatusChange(statusOnChange);
}

function statusOnChange() {
    const processStatus = Xrm.Page.data.process.getStatus();
    if (processStatus === "finished") {
        setTimeout(markAsComplete, 500);
    }
}

function markAsComplete(){
    const stateCodeAttr = Xrm.Page.getAttribute("statecode");
    const statusCodeAttr = Xrm.Page.getAttribute("statuscode");

    if (stateCodeAttr && statusCodeAttr) {
        stateCodeAttr.setValue(1);
        stateCodeAttr.setSubmitMode("always");
        
        statusCodeAttr.setValue(3);
        statusCodeAttr.setSubmitMode("always");

        // Save to persist changes
        Xrm.Page.data.save().then(
            () => console.log("Appointment saved as completed."),
            (error) => {
                console.error("Error saving:", error);
                alert("Failed to update appointment status.");
            }
        );
    } else {
        alert("State Code or Status Code fields are not on the form.");
    }
}

Key Fixes Explained

  • Form Save: Calling formContext.data.save() (or Xrm.Page.data.save()) ensures your status changes are written to the database instead of being temporary.
  • Delay Execution: The setTimeout gives Dynamics 365 time to finish its internal process status updates before your code runs, preventing your changes from being overwritten.
  • Status Code Validation: Uncomment the console.log lines to check if your statecode=1 and statuscode=3 actually map to the "Completed" status in your environment—some customizations might change these values.

Additional Checks

  • User Permissions: Make sure the user has permission to update the appointment's status (check security roles for "Write" access to the Appointment entity and status transitions).
  • Conflicting Scripts/Plugins: Verify no other form scripts or plugins are modifying the appointment status after your code runs.
  • Event Registration: Ensure the OnLoad function is properly registered on the appointment form's OnLoad event (and passes the execution context if using the modern API).

内容的提问来源于stack exchange,提问作者MswatiLomnyama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:21:04