共用方式為


設定預約規則

Field Service 中的預約規則根據自訂條件建立使用者會在建立或編輯資源預約記錄時看見的警告或錯誤訊息。 例如,可以建立預約規則來警告使用者,當他們嘗試在排程面板上對資源預約工單,但該資源未具備工作所需的技能時。

預約規則是在建立或編輯可預約資源預約記錄之前執行的自訂 JavaScript 方法。 JavaScript 方法可以接受包含建立中可預約資源預約記錄資訊的參數,並且傳回的一定是包含必要屬性的 JavaScript 物件。

設定預約規則,以在建立或修改時驗證預約。

注意

  • 預約規則只適用於每小時檢視表,對於排程面板和排程小幫手的每日、每週或每月檢視表則無法使用。 這些規則在透過可預約資源預約表單建立或更新預約時也能使用。
  • 如果可預約資源預約表單上已啟用商務程序流程,則無法在該表單上使用預約規則。
  • 無法在排程面板的重新指派功能中使用預約規則。
  • 每個自訂預約規則只能傳回一個錯誤/警告。 若要傳回多個訊息,請設定每項驗證的個別預約規則。

建立解決方案

設定預約規則的第一個步驟是建立自訂 JavaScript Web 資源。 建議您在 CRM 中建立解決方案以新增自訂 JavaScript Web 資源,或使用您現有的解決方案來進行自訂。

建立 CRM 解決方案

  1. 設定>解決方案,為您的預約規則 JavaScript Web 資源建立新的解決方案。

下列螢幕擷取畫面顯示新建立的解決方案。 建議您的解決方案使用特有發行者,而不是預設發行者。

Field Service 預約規則的螢幕擷取畫面。

  1. 建立解決方案之後,選取 Web 資源元件,並建立新的 Web 資源。
  2. 在 Web 資源表單中輸入下列資訊:a. 名稱 b. 顯示名稱 c. 選取 Script (JScript) 做為類型
  3. 選取文字編輯器選項以輸入預約規則的 JavaScript 程式碼。
  4. 選取儲存以儲存 Web 資源。
  5. 選取發佈,確保預約規則 Web 資源已發佈。

Web 資源的螢幕擷取畫面。

設定預約規則

  1. 從主要功能表移至 Field Service>資源,然後選擇預約設定底下的預約規則

    Field Service 的使用中預約規則清單螢幕擷取畫面。

  2. 選取 +新增以建立新的預約規則。

  3. 在預約規則表單中輸入下列資訊:a. 名稱 b. Web 資源 (選取您最近建立的 Web 資源)。 c. 輸入您在 JavaScript 中定義的方法名稱。

    預約規則的螢幕擷取畫面。

  4. 儲存預約規則。 儲存預約規則之後,排程面板和排程小幫手的每小時檢視表或實體表單就會使用該規則。 您可以停用預約規則記錄,來避免排程面板、排程小幫手或預約實體表單執行規則。

注意

目前只有在排程面板和排程小幫手的每小時檢視表中,才會支援預約規則。 使用可預約資源預約表單建立或更新預約時,也會支援預約規則。 預約規則不會在刪除預約記錄時執行。 使用多重編輯時,預約規則不適用於表單。

建立 CRM 動作

在此區段中,我們將查看範例,告訴您如何使用自訂 CRM 動作,將驗證做為預約規則的一部分來執行。

使用 CRM 動作進行預約規則驗證時,您仍然需要建立以上所定義的自訂 Web 資源。 您在自訂 Web 資源中定義的 JavaScript 會呼叫自訂 CRM 動作,並評估自訂 CRM 動作產生的結果。 如需可用來呼叫自訂 CRM 動作的範例程式碼,請參閱本文件結尾的「附件 A」。

自訂 CRM 動作必須是在 CRM 中建立。 建議您使用自訂 Web 資源已定義的 CRM 解決方案,新增自訂 CRM 動作。

自訂 CRM 動作應有下列輸入及輸出參數。 您可以依案例需求新增更多輸入和輸出參數。 您必須確保您定義用來呼叫自訂 CRM 動作的 JavaScript 已更新,才能支援其他輸入及輸出參數。

輸入參數:

  • originalScheduleStart – 日期時間
  • originalScheduleEnd – 日期時間
  • originalBookableResource – EntityReference
  • originalScheduleSource – 挑選清單
  • newScheduleStart – 日期時間
  • newScheduleEnd – 日期時間
  • isCreate – 布林值
  • isUpdate – 布林值

輸出參數:

  • isError – 布林值
  • isWarning – 布林值
  • errorMessage – 字串
  • warningMessage - 字串

下列螢幕擷取畫面顯示範例自訂 CRM 動作。 此範例要檢查 newBookableResource 是否與工單上的偏好資源相符,以及 newScheduleStart 是否在承諾發出時間承諾兌現時間的範圍內。 這假設的是承諾時間範圍的日期是單一日期的時間範圍。 範例:承諾發出時間:2016/01/01 上午 8:00 / 承諾兌現時間:2016 /01/01 下午 12:00。

自訂 CRM 動作的螢幕擷取畫面。

範例指令碼

您所建立的 JavaScript 函數可以接受視為預約內容的單一參數。 傳遞的預約內容參數並非用戶端指令碼中所使用的一般 CRM 內容。

預約內容結構描述:

export type BookingRuleContext = {
    oldValues: BookingRuleBookingRecord;
    newValues: BookingRuleBookingRecord;
    isCreate: boolean;
    isUpdate: boolean;
};
 
export type BookingRuleBookingRecord = {
    ResourceRequirementId?: string;
    ResourceId?: string;
    StartTime?: Date;
    EndTime?: Date;
    ResourceScheduleSource?: string;
};

預約內容參數會有下列 JavaScript 定義。

注意

需要在預約規則的自訂 Web 資源中加入此 JavaScript 程式碼。

ResourceScheduleSource 的可能值來自資源排程來源全域選項組。 您可以使用此屬性來了解是否要從排程面板或排程小幫手中觸發預約規則。

    var sbContext = {
    oldValues: {
        StartTime: "01/01/2016 08:00AM",
        EndTime: "01/01/2016 05:00PM",
        ResourceId: "00000000-0000-0000-0000-00000000",
        ResourceScheduleSource: 690970001
    },
    newValues: {
        StartTime: "01/01/2016 08:00AM",
        EndTime: "01/01/2016 05:00PM",
        ResourceId: "00000000-0000-0000-0000-00000000",
        ResourceScheduleSource: 690970001
    },
    isCreate: true,
    isUpdate: false
    };

您的驗證方法必須傳回具有下列定義的 JavaScript 物件。

注意

需要在預約規則的自訂 Web 資源中加入此 JavaScript 程式碼。

    var ruleResult = {
    IsValid: false,
    Message: "Some Message Here",
    Type: "error" // this can be either "error" or "warning"
};

JavaScript 函數定義範例。 下列 JavaScript 程式碼是唯一需要在自訂 Web 資源中加入的 JavaScript 程式碼。


    function Validate(ctx) {
      var url = Xrm.Page.context.getClientUrl();
      var ruleResult = {
  	IsValid: false,
       Message: '',
       Type: 'error'
      };

      //
      // perform some lookups or other validation logic here.
      //
  
      ruleResult.IsValid = false;
      ruleResult.Message = 'Some Error Message Here.';
      ruleResult.Type = 'error';

      return ruleResult;
    }

下列 JavaScript 可以用來呼叫自訂 CRM 動作,此動作與先前範例具有相同的輸入和輸出參數。

在預約規則記錄中,方法名稱必須是:MSFSAENG.ScheduleBoard.Validate。 如需參考資料,請參閱本文「設定預約規則」一節中的螢幕擷取畫面。


    /// <reference path="xrm.d.ts" />
    function brErrorCallback(sb) {
    // Add custom error handeling here if desired.
     return;
    }
    function brWarningCallback(sb) {
    // Add custom warning handeling here if desired.
    return;
    }
    function brSuccessCallback(sb) {
    // add custom sucess handeling here if desired.
    return;
    }
    var MSFSAENG;
    (function (MSFSAENG) {
    MSFSAENG.ScheduleBoard = {
        url: Xrm.Page.context.getClientUrl() + "/api/data/v8.1/",
        actionName: "msfsaeng_MSFSAScheduleBoardRuleActionSample",
        actionInputParameters: function (ctx) {
            var inputParameters = {};
            if (ctx.isUpdate) {
                inputParameters = {
                    "originalScheduleStart": ctx.oldValues.StartTime,
                    "originalScheduleEnd": ctx.oldValues.EndTime,
                    "originalBookableResource": {
                        "@odata.type": "Microsoft.Dynamics.CRM.bookableresource",
                        "bookableresourceid": ctx.oldValues.ResourceId,
                        "name": ""
                    },
                    "originalScheduleSource": ctx.oldValues.ResourceScheduleSource,
                    "newScheduleStart": ctx.newValues.StartTime,
                    "newScheduleEnd": ctx.newValues.EndTime,
                    "newBookableResource": {
                        "@odata.type": "Microsoft.Dynamics.CRM.bookableresource",
                        "bookableresourceid": ctx.newValues.ResourceId,
                        "name": ""
                    },
                    "newScheduleSource": ctx.newValues.ResourceScheduleSource,
                    "isCreate": ctx.isCreate,
                    "isUpdate": ctx.isUpdate
                };
            }
            else {
                inputParameters = {
                    "newScheduleStart": ctx.newValues.StartTime,
                    "newScheduleEnd": ctx.newValues.EndTime,
                    "newBookableResource": {
                        "@odata.type": "Microsoft.Dynamics.CRM.bookableresource",
                        "bookableresourceid": ctx.newValues.ResourceId,
                        "name": ""
                    },
                    "newScheduleSource": ctx.newValues.ResourceScheduleSource,
                    "isCreate": ctx.isCreate,
                    "isUpdate": ctx.isUpdate
                };
            }
            return JSON.stringify(inputParameters);
        },
        ctx: null,
        ruleResult: {
            IsValid: true,
            Message: "",
            Type: ""
        },
        outputParameters: {
            isError: false,
            isWarning: false,
            errorMessage: "",
            warningMessage: ""
        },
        Validate: function (context) {
            this.ctx = context;
            ScheduleBoardHelper.callActionWebApi(this);
            return this.ruleResult;
        },
        errorCallback: brErrorCallback,
        warningCallback: brWarningCallback,
        successCallback: brSuccessCallback
    };
    var ScheduleBoardHelper = (function () {
        function ScheduleBoardHelper() {
        }
        ScheduleBoardHelper.callActionWebApi = function (sb) {
            var oDataEndpoint = sb.url + sb.actionName;
            var req = new XMLHttpRequest();
            req.open("POST", oDataEndpoint, 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.onreadystatechange = function () {
                if (req.readyState == 4) {
                    req.onreadystatechange = null;
                    if (req.status == 200) {
                        sb.outputParameters = JSON.parse(req.response);
                        if (sb.outputParameters.isError) {
                            sb.ruleResult.IsValid = false;
                            sb.ruleResult.Message = sb.outputParameters.errorMessage;
                            sb.ruleResult.Type = 'error';
                            if (sb.errorCallback)
                                sb.errorCallback(sb);
                            return;
                        }
                        else if (sb.outputParameters.isWarning) {
                            sb.ruleResult.IsValid = false;
                            sb.ruleResult.Message = sb.outputParameters.warningMessage;
                            sb.ruleResult.Type = 'warning';
                            if (sb.warningCallback)
                                sb.warningCallback(sb);
                            return;
                        }
                        else {
                            sb.ruleResult.IsValid = true;
                            sb.ruleResult.Message = '';
                            sb.ruleResult.Type = '';
                            if (sb.successCallback)
                                sb.successCallback(sb);
                            return;
                        }
                    }
                    else {
                        alert('Error calling Rule Action. Response = ' + req.response + ', Status = ' + req.statusText);
                    }
                }
            };
            req.send(sb.actionInputParameters(sb.ctx));
        };
        return ScheduleBoardHelper;
    }());
    })(MSFSAENG || (MSFSAENG = {}));

其他注意事項

啟用可預約資源預約是為了要使用預約規則,根據自訂條件來建立使用者會在建立或編輯資源預約記錄時看見的警告或錯誤訊息。 系統使用預約規則中的 preventDefault。 因此,無法對已啟用預約規則的可預約資源預約實體使用商務程序流程或其他繫結至 onSave 事件的自訂指令碼。

不過,您可以啟用下列可讓使用者使用商務程序流程的設定,在儲存預約表單時停用預約規則處理。 用戶端 API 可以用來在環境層級啟用此設定。

讀取 msdyn_DisableProcessBookingRulesOnSaveBookingForm 設定的目前值。

Xrm.Utility.getGlobalContext().getCurrentAppSettings()["msdyn_DisableProcessBookingRulesOnSaveBookingForm"]

啟用 msdyn_DisableProcessBookingRulesOnSaveBookingForm 設定。

Xrm.Utility.getGlobalContext().saveSettingValue("msdyn_DisableProcessBookingRulesOnSaveBookingForm",true,).then(() => {a = "success"}, (error) => {a = error})

停用 **msdyn_DisableProcessBookingRulesOnSaveBookingForm** 設定。

Xrm.Utility.getGlobalContext().saveSettingValue("msdyn_DisableProcessBookingRulesOnSaveBookingForm",false,).then(() => {a = "success"}, (error) => {a = error})