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, um registro de regra tenha sido criado para alertar o usuário quando tentam registrar uma ordem de serviço a um recurso no painel de agendamento que não possui as habilidades necessárias para o trabalho.

As regras de reserva são métodos JavaScript personalizados que serã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 conterá 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 por meio do formulário de reserva de recurso que pode ser reservado.
  • As regras de reserva não estão disponíveis no formulário de reserva de recursos reserváveis, se o fluxo do processo de negócios estiver ativado no formulário.
  • As regras de reserva não estão disponíveis na funcionalidade de reatribuição no quadro de agendamento.
  • Cada regra de reserva personalizada só pode retornar um erro/aviso. Para retornar várias mensagens, configure regras de reserva individuais para cada validação.

Criar uma solução

A primeira etapa para configurar sua regra de reserva é criar um recurso JavaScript da Web personalizado. Recomendamos que você crie uma solução no CRM para adicionar seu recurso JavaScript da Web personalizado ou use uma solução existente que possa ter para personalizações.

Criar solução CRM

  1. Em Configurações>Soluções, crie uma nova solução para seus recursos JavaScript da Web de regra de reserva.

A captura de tela a seguir mostra uma solução recém-criada. Recomendamos que sua solução use um editor exclusivo em vez do editor padrão.

Captura de tela das regras de reserva do Field Service.

  1. Depois de criar a solução, selecione o componente Recursos da Web e crie um novo recurso da Web.
  2. No novo formulário de recurso da Web, insira as informações a seguir: a. Nome b. Nome de exibição c. Selecionar Script (Jscript) como o tipo
  3. Selecione a opção do editor de texto para inserir seu código JavaScript para a regra de reserva.
  4. Selecione Salvar para salvar seu recurso da Web.
  5. Selecione Publicar para certificar-se de que o recurso da Web da regra de reserva foi publicado.

Captura de tela de um novo recurso da Web.

Configurar uma regra de reserva

  1. No menu principal, acesse Field Service>Recursos e escolha Regras de Reserva em Configurações de Reserva.

    Captura de tela das regras de reserva ativas no Field Service.

  2. Selecione +Novo para criar uma nova regra de reserva.

  3. No formulário de regra de reserva, insira as informações a seguir: a. Nome b. Recurso da Web (selecione o recurso da Web que você criou recentemente). c. Insira o nome do método que você definiu em seu JavaScript.

    Captura de tela das regras de reserva.

  4. Salve sua regra de reserva. Depois de salvar a regra de reserva, ela será usada pela exibição por hora do painel de agendamento e do assistente de agendamento ou o formulário de entidade. Você pode desativar seu registro de regra de reserva para impedir que o painel de agendamento, o assistente de agendamento ou o formulário de entidade de reserva execute a regra.

Observação

As regras de reserva são atualmente 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.

Criar uma ação de CRM

Nesta seção, veremos um exemplo que mostra como você pode usar uma ação de CRM personalizada para realizar a validação como parte de uma regra de reserva.

Ao usar uma ação de CRM para a validação de regra de reserva, você ainda precisará criar um recurso da Web personalizado como definido acima. O JavaScript que você definirá no recurso da Web personalizado chamará a Ação de CRM personalizada e avaliará os resultados nessa ação. Consulte o Anexo A ao final deste documento para obter o código de exemplo que poderá ser usado para chamar uma ação de CRM personalizada.

Uma ação de CRM personalizada deverá ser criada no CRM. Recomendamos que você use a solução de CRM que definiu para o recurso da Web personalizado para adicionar a ação de CRM personalizada.

A ação de CRM personalizada deverá ter 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 de CRM personalizada esteja atualizado para dar suporte aos demais parâmetros 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 de CRM 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})