다음을 통해 공유


예약 규칙 설정

Field Service의 예약 규칙은 사용자 지정 조건에 따라 리소스 예약 레코드를 생성하거나 편집할 때 사용자에게 표시되는 경고 또는 오류 메시지를 생성합니다. 예를 들어, 사용자가 작업에 필요한 기술이 없는 일정 게시판의 리소스에게 작업 주문을 예약하려고 할 때 경고하도록 예약 규칙을 만들 수 있습니다.

예약 규칙은 작성 중이거나 편집 중인 예약 가능한 리소스 예약 레코드 이전에 실행되는 사용자 지정 JavaScript 메서드입니다. JavaScript 메서드는 작성 중인 예약 가능한 리소스 예약 레코드에 대한 정보를 포함하는 매개 변수를 승인할 수 있으며 필수 특성이 있는 JavaScript 개체를 반환해야 합니다.

예약을 만들거나 수정할 때 예약을 검사하는 예약 규칙을 설정합니다.

노트

  • 예약 규칙은 시간별 보기에만 적용되며, 일정 게시판 및 일정 도우미의 일별, 주별, 월별 보기에는 적용되지 않습니다. 예약 가능한 리소스 예약 양식을 통해 예약이 생성되거나 업데이트될 때도 사용할 수 있습니다.
  • 양식에서 비즈니스 프로세스 흐름이 사용된 경우 예약 가능한 리소스 예약 양식에서 예약 규칙을 사용할 수 없습니다.
  • 예약 규칙은 예약 게시판의 재할당 기능에서 사용할 수 없습니다.
  • 각 사용자 지정 예약 규칙은 하나의 오류/경고만 반환할 수 있습니다. 여러 메시지를 반환하려면 각 확인에 대해 개별 예약 규칙을 설정하세요.

솔루션 만들기

예약 규칙을 설정하는 첫 번째 단계는 사용자 지정 JavaScript 웹 리소스를 만드는 것입니다. CRM에서 솔루션을 만들어 사용자 지정 JavaScript 웹 리소스를 추가하거나 사용자 지정에 사용할 수 있는 기존 솔루션을 사용하는 것이 좋습니다.

CRM 솔루션 만들기

  1. 설정>솔루션에서 예약 규칙 JavaScript 웹 리소스에 대한 새 솔루션을 만듭니다.

다음 스크린 샷은 새로 생성된 솔루션을 보여줍니다. 솔루션에서 기본 게시자가 아닌 고유 게시자를 사용하는 것이 좋습니다.

Field Service 예약 규칙의 스크린샷

  1. 솔루션을 만든 후 웹 리소스 구성 요소를 선택하고 새 웹 리소스를 만듭니다.
  2. 새 웹 리소스 양식에 다음 정보를 입력합니다. a. 이름 b. 표시 이름 c. 스크립트(Jscript)를 유형으로 선택합니다.
  3. 예약 규칙에 대한 JavaScript 코드를 입력하려면 텍스트 편집기 옵션을 선택하십시오.
  4. 저장을 선택하여 웹 리소스를 저장합니다.
  5. 게시를 선택하여 예약 규칙 웹 리소스가 게시되었는지 확인합니다.

새로운 웹 리소스의 스크린샷

예약 규칙 설정

  1. 메인 메뉴에서 Field Service>리소스를 선택한 다음 예약 설정에서 예약 규칙을 선택합니다.

    Field Service 활성 예약 규칙 목록의 스크린샷

  2. 새 규칙을 만들려면 새로 만들기를 선택합니다.

  3. 예약 규칙 양식에서 다음 정보를 입력합니다. a. 이름 b. 웹 리소스(최근에 생성한 웹 리소스 선택). c. JavaScript에서 정의한 메소드 이름을 입력하십시오.

    예약 규칙 스크린샷.

  4. 예약 규칙을 저장합니다. 예약 규칙을 저장하면 일정 게시판 및 일정 도우미 또는 엔터티 양식의 시간별 보기에서 사용됩니다. 예약 규칙 레코드를 비활성화하여 일정 게시판, 일정 도우미 또는 예약 엔터티 양식이 규칙을 실행하지 못하도록 할 수 있습니다.

노트

예약 규칙은 현재 일정 게시판 및 일정 도우미의 시간별 보기에서만 지원됩니다. 예약 가능한 리소스 예약 양식을 사용하여 예약을 생성하거나 업데이트할 때도 예약 규칙이 지원됩니다. 예약 규칙은 예약 기록 삭제 시 실행되지 않습니다. 다중 편집을 사용할 때 양식에서 예약 규칙이 작동하지 않습니다.

CRM 작업 만들기

이 섹션에서는 사용자 지정 CRM 작업을 사용하여 예약 규칙의 일부로 유효성 검사를 수행하는 방법을 보여주는 예를 살펴보겠습니다.

예약 규칙 유효성 검사에 CRM 작업을 사용하는 경우 위에서 정의한 대로 사용자 지정 웹 리소스를 만들어야 합니다. 사용자 지정 웹 리소스에서 정의할 JavaScript는 사용자 지정 CRM 작업을 호출하고 사용자 지정 CRM 작업의 결과를 평가합니다. 사용자 지정 CRM 작업을 호출하는 데 사용할 수 있는 샘플 코드는 이 문서 끝에 있는 첨부 파일 A를 참조하십시오.

CRM에서 사용자 지정 CRM 작업을 만들어야 합니다. 사용자 지정 웹 리소스에 대해 정의한 CRM 솔루션을 사용하여 사용자 지정 CRM 작업을 추가하는 것이 좋습니다.

사용자 지정 CRM 작업에는 다음과 같은 입력 및 출력 매개 변수가 있어야 합니다. 시나리오에 따라 추가 입력 및 출력 매개 변수를 추가할 수 있습니다. 사용자 지정 CRM 작업을 호출하기 위해 정의한 JavaScript가 다른 입력 및 출력 매개 변수를 지원하도록 업데이트되었는지 확인해야 합니다.

입력 매개 변수:

  • originalScheduleStart – DateTime
  • originalScheduleEnd – DateTime
  • originalBookableResource – EntityReference
  • originalScheduleSource – Picklist
  • newScheduleStart – DateTime
  • newScheduleEnd – DateTime
  • isCreate – Boolean
  • isUpdate – Boolean

출력 매개 변수:

  • isError – Boolean
  • isWarning – Boolean
  • errorMessage – String
  • warningMessage - String

다음 스크린 샷은 사용자 지정 CRM 작업의 예를 보여줍니다. 이 샘플은 newBookableResource가 작업 주문의 기본 리소스와 일치하는지 여부와 newScheduleStart약속 시작 시간약속 종료 시간 내에 있는지 확인합니다. 약속된 기간의 날짜는 단일 날짜인 것으로 가정합니다. 예: 약속 시작 시간: 01/01/2016 8:00AM / 약속 종료 시간: 01/01/2016 12:00PM.

사용자 지정 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 정의를 갖습니다.

노트

예약 규칙에 대한 사용자 지정 웹 리소스에 이 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 개체를 반환해야 합니다.

노트

예약 규칙에 대한 사용자 지정 웹 리소스에 이 JavaScript 코드를 포함할 필요가 없습니다.

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

JavaScript 함수 정의 예. 다음 JavaScript 코드는 사용자 지정 웹 리소스에 포함해야 하는 유일한 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를 사용합니다. 따라서 onSaveevent에 결합된 비즈니스 프로세스 흐름 및 기타 사용자 지정 스크립트는 예약 규칙이 활성화된 예약 가능한 리소스 예약 엔터티에서 사용할 수 없습니다.

그러나 사용자가 비즈니스 프로세스 흐름을 사용할 수 있도록 아래 설정을 활성화하여 예약 양식 저장 시 예약 규칙 처리를 비활성화할 수 있습니다. 클라이언트 측 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})