Compartilhar via


Definir as regras de reserva

As regras de reserva no Field Service criam mensagens de aviso e erro que os usuários visualizam ao criar ou editar um registro de reserva de recurso, com base em condições personalizadas. Por exemplo, uma regra de reserva pode ser criada para avisar um usuário quando ele tenta reservar uma ordem de trabalho para um recurso no quadro de agendamento que não tem as características necessárias para o trabalho.

As regras de reserva são métodos JavaScript personalizados que são executados antes de o registro de Reserva de Recurso Reservável ser criado ou editado. O método JavaScript pode aceitar um parâmetro que contém informações do registro Reserva de Recurso Reservável que está sendo criado e deverá retornar um objeto JavaScript com as propriedades necessárias.

Defina regras de reserva para validar um agendamento quando ele é criado ou modificado.

Observação

  • As regras de reserva estão disponíveis apenas para a exibição por hora, e não para exibições diárias, semanais ou mensais do painel de agendamento e do assistente de agendamento. Elas também estão disponíveis quando uma reserva é criada ou atualizada no formulário de reserva de recurso reservável.
  • As regras de reserva não estão disponíveis no formulário de reserva de recursos reserváveis, se o fluxo do processo empresarial estiver ativado no formulário.
  • As regras de reserva não estão disponíveis na função de reatribuição no painel de agendamento.
  • Cada regra de reserva personalizada pode retornar apenas um erro ou aviso. Para retornar várias mensagens, configure regras de reserva individuais para cada validação.

Criar uma solução

Crie um recurso Web JavaScript personalizado. Recomendamos que você crie uma solução no Microsoft Power Apps para adicionar seu recurso JavaScript da Web personalizado ou use uma solução existente que você usa para personalizações.

  1. Crie uma nova solução para os recursos da Web JavaScript da regra de reserva. Recomendamos que sua solução use um editor exclusivo em vez do editor padrão.

  2. Depois de criar a solução, crie um novo recurso da Web.

  3. Selecionar JavaScript (JS) como o tipo.

  4. Insira o código JavaScript para a regra de reserva.

  5. Selecione Salvar e Publicar.

Configurar uma regra de reserva

  1. Acesse Field Service e selecione a área Recursos.

  2. Em Configurações de Reserva, selecione Regras de Reserva e selecione Novo.

    Captura de tela de uma nova regra de reserva.

  3. Insira as seguintes informações:

    • O nome da regra de reserva.
    • O recurso da Web que você criou recentemente.
    • O nome do método que você definiu em seu JavaScript.
  4. Selecione Salvar & Fechar. A regra de reserva é usada pela exibição por hora do painel de agendamento e do assistente de agendamento ou o formulário de entidade.

Observação

As regras de reserva são compatíveis apenas na exibição por hora do painel de agendamento e do assistente de agendamento. As regras de reserva também são compatíveis quando as reservas são criadas ou atualizadas usando o formulário de reserva de recursos reserváveis. As regras de reserva não são executadas na exclusão de um registro de reserva. As regras de reserva não funcionam em formulários ao usar a edição múltipla. Para interromper a execução da regra, desative a regra de reserva.

Criar uma ação de processo personalizada

Crie uma ação de processo personalizada para executar a validação como parte de uma regra de reserva. No JavaScript do recurso da Web personalizado, chame a ação de processo personalizado e avalie os resultados da ação. Vá para o código de exemplo para ver como chamar uma ação de processo personalizada.

Recomendamos que você use a solução de CRM que definiu para seu recurso da Web personalizado para adicionar a ação de processo personalizada.

Use os seguintes parâmetros de entrada e saída. Você pode adicionar mais parâmetros de entrada e de saída conforme o cenário exigir. Você precisará garantir que o JavaScript definido para chamar a ação do processo personalizada esteja atualizado para dar suporte a outros parâmetros adicionais de entrada e saída.

Parâmetros de entrada:

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

Parâmetros de Saída:

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

A captura de tela a seguir mostra um exemplo de ação do processo personalizada. Este exemplo está verificando se newBookableResource corresponde ao recurso preferencial na ordem de serviço e se newScheduleStart está entre a Hora Inicial Prometida e a Hora Final Prometida. Supõe-se que as datas do período especificado sejam para uma única data. Exemplo: Hora Inicial Prometida: 01/01/2016 8:00/Hora Final Prometida: 01/01/2016 12:00.

Captura de tela de uma ação de CRM personalizada.

Código de exemplo

A função JavaScript que você criou pode aceitar um único parâmetro, que é considerado o contexto de reserva. O parâmetro de contexto da reserva passado não é um contexto de CRM típico usado no script do lado do cliente.

Esquema do contexto de reserva:

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

O parâmetro de contexto de reserva terá a definição JavaScript a seguir.

Observação

Não é necessário incluir esse código JavaScript no recurso da Web personalizado para a regra de reserva.

Os valores possíveis para ResourceScheduleSource vêm do conjunto de opções global de origem de agenda de recurso. Você pode utilizar essa propriedade para saber se a regra de reserva está sendo disparada do painel de agendamento ou do assistente de agendamento.

    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
    };

Seu método de validação deve retornar um objeto JavaScript com a definição a seguir.

Observação

Não é necessário incluir esse código JavaScript no recurso da Web personalizado para a regra de reserva.

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

Definição de função JavaScript de exemplo. O código JavaScript a seguir é o único código JavaScript que você precisará incluir em seu recurso da Web personalizado.


    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;
    }

O JavaScript a seguir pode ser usado para chamar uma ação de CRM personalizada que tem os mesmos parâmetros de entrada e saída do exemplo anterior.

No registro da regra de reserva, o Nome do Método precisa ser: MSFSAENG.ScheduleBoard.Validate. Para referência, consulte a captura de tela na seção "Configuração de uma regra de reserva" deste artigo.


    /// <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 = {}));

Observações adicionais

A reserva de recurso reservável está habilitada para usar regras de reserva a fim de criar mensagens de aviso ou erro que os usuários veem ao criar ou editar um registro de reserva de recurso, com base em condições personalizadas. O sistema usa preventDefault em regras de reserva. Por isso, os fluxos do processo empresarial e outros scripts personalizados estão vinculados ao evento onSave não podem ser usados na entidade de reserva de recursos reserváveis com regras de reserva habilitadas.

No entanto, o processamento das regras de reserva pode ser desativado ao salvar o formulário de Reserva, habilitando a configuração abaixo, que permitiria aos usuários usar os fluxos do processo de negócios. As APIs do lado do cliente podem ser usadas para habilitar essa configuração em um nível de ambiente.

Leia o valor atual da configuração msdyn_DisableProcessBookingRulesOnSaveBookingForm.

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

Habilite a configuração msdyn_DisableProcessBookingRulesOnSaveBookingForm.

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

Desabilite a configuração **msdyn_DisableProcessBookingRulesOnSaveBookingForm**.

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