Regras de negócio clássicas
Uma regra de negócio é um script do lado do servidor que é executado quando um registro é exibido, inserido, atualizado ou excluído, ou quando uma tabela é consultada.
Como as regras de negócio funcionam
Para configurar regras de negócio, primeiro você precisa determinar quando a regra de negócio deve ser executada e qual ação ela deve realizar.
Quando as regras de negócio são executadas
- Quando executar a regra de negócio em relação a uma operação de banco de dados.
- A qual operação de registro a regra de negócio se aplica.
| Opção | Quando a regra é executada |
|---|---|
| Antes | Depois que o usuário envia o formulário, mas antes que qualquer ação seja realizada no registro no banco de dados. |
| Após | Depois que o usuário envia o formulário e depois que qualquer ação é realizada no registro no banco de dados. |
| Assíncrono | Depois que o usuário envia o formulário e o programador executa o trabalho agendado criado a partir da regra de negócio. O sistema cria um trabalho agendado a partir da regra de negócio depois que o usuário envia o formulário, mas antes que qualquer ação seja realizada no registro no banco de dados. Nota: As regras de negócio recém-criadas serão executadas durante os upgrades. Se um registro tiver uma regra de negócio assíncrona que toma decisões com base nos dados no registro, várias atualizações no registro em rápida sucessão podem fazer com que a regra de negócio seja executada fora de ordem ou incorretamente. Se várias regras de negócio assíncronas atualizarem o mesmo registro, as atualizações realizadas por um script poderão ser substituídas por outro script ou feitas em uma sequência inesperada porque a ordem de execução não é garantida. Você pode usar a opção Após para regras de negócio ou System Events como alternativa nessas situações. |
| Exibição | Antes de o formulário ser apresentado ao usuário, logo após os dados serem lidos do banco de dados. |
- Regras de negócio assíncronas não têm acesso à versão anterior de um registro. Portanto, os métodos changes(), changesTo()e changesFrom() GlideElement não funcionam com o script de regra assíncrona. No entanto, o construtor de condição e o campo de condição (exibição avançada) são compatíveis com os métodos changes(), changesTo()e changesFrom().
- As regras de negócio não respeitam as ACLs até que você queira que elas sejam respeitadas. Para obter mais informações, consulte Relação entre regras de negócio e regras de controle de acesso (ACLs)
| Opção | Quando a regra é executada |
|---|---|
| Inserir | Quando o usuário cria um novo registro e o sistema o insere no banco de dados. |
| Atualizar | Quando o usuário modifica um registro existente. |
| Consulta | Quando o usuário envia uma consulta de um registro ou lista de registros para o banco de dados. Normalmente, você deve usar a operação de consulta para regras de negócio anteriores. |
| Excluir | Quando o usuário exclui um registro. |
Ações de regra de negócio
- Alterar valores de campo em um formulário que o usuário está atualizando. Os valores de campo podem ser definidos como valores específicos disponíveis para esse campo, valores copiados de outros campos e valores relativos determinados pela função do usuário.
- Exibição de mensagens informativas para o usuário.
- Alterando valores de tarefas secundárias com base em mudanças nas tarefas primárias.
- Impedindo que os usuários acessem ou modifiquem determinados campos em um formulário.
- Anular a transação do banco de dados atual. Por exemplo, se determinadas condições forem atendidas, impeça que o usuário salve o registro no banco de dados.
Impedir regras de negócio recursivas
Evite usar current.update() em um script de regra de negócio. O método update() aciona regras de negócio para serem executadas na mesma tabela para operações de inserção e atualização, levando a uma regra de negócio chamando a si mesma repetidamente. As mudanças feitas em antes das regras de negócio são salvas automaticamente quando todas as regras de negócio anteriores são concluídas e as regras de negócio posteriores são usadas para atualizar objetos relacionados, não atuais. Quando uma regra de negócio recursiva é detectada, o sistema a interrompe e registra o erro no log do sistema. No entanto, current.update() causa problemas de desempenho do sistema e nunca é necessário.
Você pode impedir regras de negócio recursivas usando o método setWorkflow() com o parâmetro falso. A combinação dos métodos update() e setWorkflow() só é recomendada em circunstâncias especiais em que as diretrizes normais de antes e depois mencionadas acima não atendem aos seus requisitos.
Regras de negócio em aplicações com escopo
Cada regra de negócio é atribuída a um escopo de aplicação privada ou ao escopo global.
Regras de negócio em tabelas específicas
A maioria das regras de negócio é executada em uma tabela específica, que é definida no campo Tabela. Você pode criar regras de negócio em tabelas no mesmo escopo e em tabelas que permitem registros de configuração de outro escopo da aplicação.
Para tabelas que estão em um escopo diferente do registro de regra de negócio, os tipos de regras são limitados.
- Você pode criar uma regra em que Quando é assíncrono com qualquer uma das seguintes opções:
- Operações de banco de dadosInserir, Atualizare Excluir. Não é possível selecionar Consulta.
- Definir ações e scripts de valores de campo (o campo Script ).
- Você pode criar uma regra em que Quando é anterior com qualquer uma das seguintes opções:
- Operações de banco de dadosInserir, Atualizare Excluir. Não é possível selecionar Consulta.
- Definir valores de campo somente ações. Você não pode escrever scripts e não pode anular a transação do banco de dados.
- Você não pode criar outros tipos de regras de negócio em tabelas em um escopo diferente.
Regras de negócio em tabelas específicas não podem ser acessadas por outras regras de negócio ou scripts.
Regras de negócio globais
Regras de negócio globais são regras de negócio em que o campo Tabela está definido como Global. As regras de negócio globais podem ser acessadas em várias tabelas e de outros scripts, dependendo da proteção do escopo. Para uma regra de negócio global, defina a proteção do escopo definindo o campo Acessível de :
- Somente este escopo da aplicação: evita que aplicações em um escopo diferente da regra de negócio chamem esta regra de negócio.
- Todos os escopos da aplicação: permite que qualquer aplicação chame esta regra de negócio.Nota:As regras de negócio globais não são compatíveis com Domain Separation.
Scripts em regras de negócio com escopo
Ao gravar um script em uma regra de negócio, você pode acessar:
- Qualquer inclusão de script e regras de negócio globais no mesmo escopo da regra de negócio.
- Inclusões de script e regras de negócio globais que permitem que aplicações em um escopo diferente as chamem. Para chamar funções de outro escopo, você deve especificar o escopo da função.
- Para regras de negócio em um escopo exclusivo, você pode acessar somente as APIs do sistema com escopo.
Criar uma regra de negócio
Você pode criar qualquer tipo de regra de negócio a ser executada quando um registro for exibido, inserido, atualizado ou excluído ou quando uma tabela for consultada.
Por Que e Quando Desempenhar Esta Tarefa
Procedimento
Variáveis globais em regras de negócio
Variáveis globais predefinidas estão disponíveis para uso em regras de negócio.
Use as seguintes variáveis globais predefinidas para fazer referência ao sistema em um script de regra de negócio.
| Variável global | Descrição |
|---|---|
| atual | Estado atual do registro sendo referenciado. Consulte "Impedir exceções de ponteiro nulo" abaixo para verificar se há nulos antes de usar esta variável. |
| anterior | Estado do registro referenciado antes de quaisquer atualizações feitas durante o contexto de execução, em que o contexto de execução começa com a primeira operação de atualização ou exclusão e termina após a execução do script e de quaisquer regras de negócio referenciadas. Se várias atualizações forem feitas no registro em um contexto de execução, anterior continuará a manter o estado do registro antes da primeira operação de atualização ou exclusão. Disponível somente em operações de atualização e exclusão. Não disponível em operações assíncronas. Consulte "Impedir exceções de ponteiro nulo" abaixo para verificar se há nulos antes de usar esta variável. |
| g_scratchpad | O objeto Bloco de anotações está disponível nas regras de exibição e é usado para passar informações para o cliente a serem acessadas de client scripts. |
| gs | Referências a funções GlideSystem. |
As variáveis atual, anteriore g_scratchpad são globais em todas as regras de negócio executadas para uma transação.
Impedir exceções de ponteiro nulo
if (current == null) // to prevent null pointer exceptions.
return; Definir variáveis
As variáveis definidas pelo usuário têm escopo global por padrão. Se uma nova variável for declarada em uma regra de negócio de pedido 100, a regra de negócio que é executada em seguida na ordem 200 também terá acesso à variável. Isso pode apresentar um comportamento inesperado.
Para evitar esse comportamento inesperado, sempre encapsule o código em uma função. Isso protege suas variáveis contra conflitos com variáveis do sistema ou variáveis globais em outras regras de negócio que não estão encapsuladas em uma função. Além disso, variáveis como current devem estar disponíveis quando uma função é invocada para serem usadas.
var now_GR = new GlideRecord('incident');
now_GR.query();
while(now_GR.next()) {
//do something
}myFunction();
function myFunction() {
var now_GR = new GlideRecord('incident');
now_GR.query();
while(now_GR.next()) {
//do something
} }Use regras de negócio e scripts de cliente para controlar valores de campo
Implemente regras de negócio e scripts de cliente para um campo para permitir que os usuários definam valores de registro corretamente usando formulários e listas e vejam mudanças imediatas nos valores em formulários conforme as edições são feitas.
O problema de usar apenas um client script ou uma regra de negócio para controlar atualizações em um campo é que os campos podem ser alterados em um formulário ou em uma lista. Client scripts e políticas de IU são executados somente em formulários (lado do cliente) e não se aplicam à edição de lista. Permitir a edição de lista com client scripts em execução em campos de um formulário pode resultar no salvamento de dados incorretos no registro. Para sistemas nos quais scripts de cliente ou políticas de IU se aplicam a formulários, desabilite a edição de lista ou crie regras de negócio apropriadas ou controle de acesso para controlar a configuração de valores no editor de lista. Um efeito colateral disso é que as medidas de segurança implementadas em client scripts são fáceis de contornar. O usuário só precisa editar o campo em uma lista.
As regras de negócio em um formulário não são dinâmicas, o usuário deve atualizar o registro para que a mudança seja vista. Isso torna o uso de client scripts o método preferencial para controlar valores de campos em formulários.
Ao usar uma regra de negócio e um client script para controlar valores de campos, o comportamento de atualização é o mesmo em todo o sistema. Isso significa que os valores atualizados não são diferentes dependendo se uma lista de formulário é usada para fazer a mudança. Isso significa que a mesma funcionalidade deve ser implementada duas vezes, uma vez em um client script e uma vez em uma regra de negócio ou controle de acesso.
Exemplo: usar uma regra de negócio para criar endereços de e-mail durante a importação de registro de usuário
Uma organização tem um client script que define o endereço de e-mail de um usuário como first.last@company.com. Os administradores fazem isso para que possam ver o endereço de e-mail imediatamente ao inserir as informações do usuário. O administrador executa uma importação em massa de usuários de uma planilha que contém o nome e o sobrenome dos usuários. A expectativa é que o endereço de e-mail de cada usuário seja definido automaticamente, como acontece quando eles editam o formulário. Como o script do cliente é executado somente no formulário (a interface para o registro), ele não tem efeito nos dados importados para o registro de fora dessa interface e nenhum endereço de e-mail é criado. Para resolver esse problema, o administrador implementa uma regra de negócio que é executada quando ocorre a importação e cria os endereços de e-mail.
Exemplo: impedir a edição de lista de um campo que não é editável no formulário
Uma organização deseja ocultar o campo Prioridade em um formulário de incidente se o grupo de atribuição for Desenvolvimento. Eles criam uma política de IU no formulário de incidente para fazer isso, mas os usuários ainda podem ver e editar o campo Prioridade usando o editor de lista. Para corrigir isso, aplique um controle de acesso para impedir o acesso de leitura ao campo Prioridade quando o grupo de atribuição for Desenvolvimento.
Usando NULO como um valor de campo
A cadeia de caracteres NULL tem uma função específica em scripts e é uma palavra reservada.
A palavra reservada é NULO em letras maiúsculas. Um campo com o valor Null ou null, por exemplo, é aceitável. Use somente NULO para limpar um campo específico.
Todos os valores de campo NULO obtidos de uma fonte de dados de conjunto de importação são inseridos na tabela de preparação como valores de campo vazios. Você não deve usar o termo NULO como um valor de campo em mapas de transformações do conjunto de importação ou em qualquer lugar nos campos Nome ou Sobrenome. Além disso, não use NULL em campos de referência, pois o sistema interpreta o valor como uma cadeia de caracteres que contém a palavra NULL, não como uma palavra reservada.
Exibir regras de negócio
As regras de exibição são processadas quando um usuário solicita um formulário de registro.
Os dados são lidos do banco de dados, as regras de exibição são executadas e o formulário é apresentado ao usuário. O objeto atual está disponível e representa o registro recuperado do banco de dados. Todas as mudanças de campo são temporárias, pois ainda não foram enviadas para o banco de dados. Para o cliente, os valores do formulário parecem ser os valores do banco de dados; não há indicação de que os valores foram modificados de uma regra de exibição. Este é um conceito semelhante aos campos calculados.
O objetivo primário das regras de exibição é usar um objeto de bloco de anotações compartilhado, g_scratchpad, que também é enviado ao cliente como parte do formulário. Isso pode ser útil quando você precisa criar scripts de cliente que exigem dados do servidor que normalmente não fazem parte do registro que está sendo exibido. Na maioria dos casos, isso exigiria um client script fazendo uma chamada de retorno para o servidor. Se os dados puderem ser determinados antes da exibição do formulário, será mais eficiente fornecer os dados ao cliente no carregamento inicial. O objeto de bloco de anotações do formulário é um objeto vazio por padrão e é usado somente para armazenar pares de dados nome:valor.
// From display business rule
g_scratchpad.someName = "someValue";
g_scratchpad.anotherName = "anotherValue";
// If you want the client to have access to record fields not being displayed on the form
g_scratchpad.created_by = current.sys_created_by;
// These are simple examples, in most cases you will probably perform some other
// queries to test or get data// From client script
if(g_scratchpad.someName == "someValue") {
//do something special
}Regra de negócio Gestão de estados ativos de tarefa
Esta regra de negócio determina se o valor do campo ativo precisa ser alterado com base nas mudanças no campo Estado.
A regra de negócio Gestão de estados ativos da tarefa é executada quando o estado é alterado para um registro de tarefa. Sua ordem de execução é 50 e é executada antes da maioria das outras regras de negócio de tarefa.
- Se o estado mudar de ativo para inativo, o campo Ativo será definido como falso.
- Se o estado mudar de um estado inativo para um estado ativo, o campo Ativo será definido como verdadeiro, reativando ou reabrindo efetivamente a tarefa.
É recomendável que você aproveite a ação (current.active.changesTo([true/false]) em sua regra de negócio, em vez de criar regras em cada tabela de tarefas que marque as tarefas como inativas ou ativas.
Exemplo de scripts de regra de negócio
Encontre um exemplo de script de regra de negócio que ajude você com um requisito da sua organização.
Comparar campos de data em uma regra de negócio
É possível comparar dois campos de data ou dois campos de data e hora em uma regra de negócio e anular uma inserção ou atualização de registro se eles não estiverem corretos.
Por exemplo, você pode desejar que uma data de início seja anterior a uma data de término. A seguir está um script de exemplo:
if ((!current.u_date1.nil()) && (!current.u_date2.nil())) {
var start = current.u_date1.getGlideObject().getNumericValue();
var end = current.u_date2.getGlideObject().getNumericValue();
if (start > end) {
gs.addInfoMessage('start must be before end');
current.u_date1.setError('start must be before end') ;
current.setAbortAction(true);
} }Este exemplo foi testado em scripts globais e pode precisar de mudanças para funcionar em scripts com escopo. Além de possivelmente precisar de mudanças de API, a segurança é mais rígida em scripts com escopo.
- u_date1 e u_date2 são os nomes dos dois campos de data. Substitua esses nomes pelos seus próprios nomes de campo.
- A primeira linha verifica se ambos os campos realmente têm um valor.
- As próximas duas linhas criam variáveis que têm os valores numéricos das datas.
- As próximas duas linhas criam mensagens de alerta diferentes para o usuário final: uma na parte superior do formulário e uma no campo u_date1 no formulário.
- A última linha anula a inserção ou a atualização se os campos de data não estiverem corretos.
// Enter all start and end date fields you wish to check, as well as the previous values
// Make sure that you keep the placement in the sequence the same for all pairs
var startDate = new Array(current.start_date,current.work_start);
var prevStartDate = new Array(previous.start_date,previous.work_start);
var endDate = new Array(current.end_date,current.work_end);
var prevEndDate = new Array(previous.end_date,previous.work_end);
// The text string below is added to the front of ' start must be before end'
var userAlert = new Array('Planned','Work');
// Set the number of Previous Days you want to check
var pd = 30;
// Set the number of Future Days you want to check
var fd = 365;
// You shouldn't have to modify anything below this line
var nowdt = new GlideDateTime();
nowdt.setDisplayValue(gs.nowDateTime());
var nowMs = nowdt.getNumericValue();
var pdms = nowMs;
// Subtract the product of previous days to get value in milliseconds
pdms -= pd * 24 * 60 * 60 * 1000;
var fdms = nowMs;
// Add the product of future days to get value in miliseconds
fdms += fd * 24 * 60 * 60 * 1000;
var badDate = false;
// Iterate through all start and end date / time fields
for (x = 0; x < startDate.length; x ++) {
if ((!startDate[x].nil()) && (!endDate[x].nil())) {
var start = startDate[x].getGlideObject().getNumericValue();
var end = endDate[x].getGlideObject().getNumericValue();
if (start > end) {
gs.addInfoMessage(userAlert[x] + ' start must be before end');
startDate[x].setError(userAlert[x] + ' start must be before end');
badDate = true; }
else if ((prevStartDate[x]) != (startDate[x])) {
if (start < pdms) {
gs.addInfoMessage(userAlert[x] + ' start must be fewer than ' + pd + ' days ago');
startDate[x].setError(userAlert[x] + ' start must be fewer than ' + pd + ' days ago');
badDate = true; } }
else if ((prevEndDate[x]) != (endDate[x])) {
if (end > fdms) {
gs.addInfoMessage(userAlert[x] + ' end must be fewer than ' + fd + ' days ahead');
endDate[x].setError(userAlert[x] + ' end must be fewer than ' + fd + ' days ahead');
badDate = true ;
} } } }
if (badDate == true ) {
current. setAbortAction ( true ) ; }Analisar cargas XML
Campos no formato XML podem ser analisados com a função getXMLText do sistema.
ecc_event, podem ser analisados com a função getXMLText do sistema. A função getXMLText usa uma cadeia de caracteres e uma expressão XPATH. Por exemplo:var name = gs.getXMLText("<name>joe</name>", "//name");retorna a cadeia de caracteres "joe".
var name = gs.getXMLText(current.payload, "//name");Para obter informações sobre o XPATH, visite w3escolas.
Anular uma ação de banco de dados em uma regra de negócio anterior
Em um script de regra de negócio anterior, você pode cancelar ou anular a ação do banco de dados atual usando o método setAbortAction().
Por exemplo, se a regra de negócio anterior for executada durante uma ação de inserção e você tiver uma condição no script que chama current.setAbortAction(true), o novo registro armazenado em current não será criado no banco de dados. A regra de negócio continua a ser executada após a chamada de setAbortAction() e todas as regras de negócio subsequentes serão executadas normalmente. Chamar este método somente evita que a ação do banco de dados no objeto atual ocorra.
Você pode usar o método isActionAborted() para determinar se a ação do banco de dados atual (inserir, atualizar, excluir) será anulada. isActionAborted() é inicializado para novos threads e o método next() define explicitamente seu valor como falso.
current.setAbortAction não será respeitado se executado em uma regra de negócio definida em um escopo diferente.Determinar a operação que acionou a regra de negócio
Você pode gravar um script para uma regra de negócio que é acionada em mais de uma ação de banco de dados.
if(current.operation() == "update") {
current.updates ++; }
if(current.operation() == "insert") {
current.updates = 0; }Usar uma condição OR em uma regra de negócio
Uma condição OR pode ser adicionada a qualquer parte da consulta em uma regra de negócio.
var inc = new GlideRecord('incident');
var qc = inc.addQuery('priority','1');
qc.addOrCondition('priority','2');
inc.query();
while(inc.next()) {
// processing for the incident goes here
}(prioridade = 1 OU prioridade = 2) E (impacto = 2 OU impacto = 3). Os resultados da condição OR são executados com duas variáveis, qc1 e qc2. Isso permite que você manipule o objeto de condição de consulta posteriormente no script, como dentro de uma condição IF ou loop WHILE.var inc = new GlideRecord('incident');
var qc1 = inc.addQuery('priority','1');
qc1.addOrCondition('priority','2');
var qc2 = inc.addQuery('impact','2');
qc2.addOrCondition('impact','3');
inc.query();
while(inc.next()) {
// processing for the incident goes here
}Referenciar uma lista do Glide a partir de uma regra de negócio
Um campo definido como uma lista de glide é uma matriz de valores armazenados em um único campo.
Aqui estão alguns exemplos de como processar um campo glide_list ao escrever regras de negócio. Geralmente, um campo glide_list contém uma lista de valores de referência para outras tabelas.
Exemplos
Por exemplo, o campo Lista de observação em tarefas é um glide_list que contém referências a registros de usuário.
O código abaixo mostra como fazer referência ao campo.
// list will contain a series of reference (sys_id) values separated by a comma
// array will be a javascript array of reference values
var list = current.watch_list.toString();
var array = list.split(",");
for (var i=0; i < array.length; i++) {
gs.print("Reference value is: " + array[i]);
}*** Script: Reference value is: 62826bf03710200044e0bfc8bcbe5df1
*** Script: Reference value is: c2826bf03710200044e0bfc8bcbe5d45
*** Script: Reference value is: 5f74e421c0a8010e01ec0d74a7ee2cc6
*** Script: Reference value is: 06826bf03710200044e0bfc8bcbe5d57Você também pode obter os valores de exibição associados aos valores de referência usando o método getDisplayValue(), conforme mostrado abaixo.
// list will contain a series of display values separated by a comma
// array will be a javascript array of display values
var list = current.watch_list.getDisplayValue();
var array = list.split(",");
for (var i=0; i < array.length; i++) {
gs.print("Display value is: " + array[i]);
}*** Script: Display value is: Abel Tuter
*** Script: Display value is: Ashley Leonesio
*** Script: Display value is: Charles Beckley
*** Script: Display value is: Cherie FuhriUse indexOf("searchString") para encontrar uma cadeia de caracteres em uma lista do Glide
Use indexOf("searchString") para retornar o local da cadeia de caracteres passada para o método se o campo de lista do glide, como uma lista de observação, tiver pelo menos um valor.
Se o campo estiver vazio, ele retornará undefined. Para evitar o retorno de um valor indefinido, siga um destes procedimentos:
- Forçar o campo a uma cadeia de caracteres, como: watch_list.toString().indexOf("searchString")
- Verifique se há um campo de lista Glide vazio com uma condição antes de usar indexOf(), como: if (watch_list.nil() || watch_list.indexOf("searchString") == -1)
Bloquear contas de usuário
Você pode bloquear contas de usuário se o usuário não estiver ativo.
// Lock accounts if bcNetIDStatus != active in LDAP and user does not
// have self-service, itil or admin role
var rls = current.accumulated_roles.toString();
if(current.u_bcnetidstatus == 'active' && (rls.indexOf(',itil,') > 0 ||
rls.indexOf(',admin,') > 0 ||
rls.indexOf(',ess,') > 0 )) {
current.locked_out = false; }
else {
current.locked_out = true; }
var now_GR = new GlideRecord("sys_user");
now_GR.query();
while(now_GR.next()) {
now_GR.update();
gs.info("updating " + gr.getDisplayValue());
}Regra de negócio antes da consulta padrão
Você pode usar uma regra de negócio de consulta que é executada antes que uma consulta ao banco de dados seja feita.
- Nome: consulta de incidente
- Tabela: incidente
- Quando: antes, consulta
- Script:
if(!gs.hasRole("itil") && gs.isInteractive()) {
var u = gs.getUserID();
var qc = current.addQuery("caller_id",u).addOrCondition("opened_by",u).addOrCondition("watch_list","CONTAINS",u);
gs.print("query restricted to user: " + u); }