Criar regras para o Assistente de otimização
Este artigo explica como criar novas regras para o Assistente de otimização. Por exemplo, pode criar uma nova regra que identifique quais os casos de Pedidos de Cotação (RFQ) que têm um título vazio. Utilizar títulos em casos torna-os facilmente identificáveis e pesquisáveis. Embora muito simples, este exemplo mostra o que pode ser conseguido com regras de otimização.
Uma regra é uma verificação dos dados da aplicação. Se a condição que a regra avalia for cumprida, são criadas oportunidades para otimizar processos ou melhorar os dados. As oportunidades podem ser aproveitadas e, opcionalmente, o impacto das ações pode ser medido.
Para criar uma nova regra para o Assistente de otimização, adicione uma nova classe que expanda a classe abstrata SelfHealingRule, implementa a interface DiagnosticsRule e é decorada com o atributo DiagnosticRule. A classe também tem de ter um método decorado com o atributo DiagnosticsRuleSubscription. Por convenção, isso é feito com o método opportunityTitle, que será discutido mais adiante. Esta nova classe pode ser adicionada a um modelo personalizado com uma dependência do modelo SelfHealingRules. No exemplo seguinte, a regra que está a ser implementada chama-se RFQTitleSelfHealingRule.
[DiagnosticsRule]
public final class RFQTitleSelfHealingRule extends SelfHealingRule implements IDiagnosticsRule
{
…
}
A classe abstrata SelfHealingRule tem métodos abstratos que têm de ser implementados em classes que herdam. O núcleo é o método de avaliação, que devolve uma lista das oportunidades identificadas pela regra. As oportunidades podem ser por entidade legal ou podem aplicar-se a todo o sistema.
protected List evaluate()
{
List results = new List(Types::Record);
DataArea dataArea;
while select id from dataArea
where !dataArea.isVirtual
{
changecompany(dataArea.id)
{
container result = this.findRFQCasesWithEmptyTitle();
if (conLen(result) > 0)
{
SelfHealingOpportunity opportunity = this.getOpportunityForCompany(dataArea.Id);
opportunity.EvaluationState = SelfHealingEvaluationState::Evaluated;
opportunity.Data = result;
opportunity.OpportunityDate = DateTimeUtil::utcNow();
results.addEnd(opportunity);
}
}
}
return results;
}
O método mostrado efetua um ciclo sobre as empresas e seleciona casos de RFQ com títulos vazios no método findRFQCasesWithEmptyTitle. Se pelo menos um desses casos for encontrado, será criada uma oportunidade específica da empresa com o método getOpportunityForCompany. Note que o campo Dados na tabela SelfHealingOpportunity é do tipo Contentor, podendo, portanto, conter quaisquer dados relevantes para a lógica específica desta regra. Definir OpportunityDate com o carimbo de data/hora atual regista a hora da última avaliação da oportunidade.
As oportunidades também podem ser transversais à empresa. Neste caso, o ciclo sobre as empresas não é necessário e a oportunidade deve ser criada com o método getOpportunityAcrossCompanies.
O código seguinte mostra o método findRFQCasesWithEmptyTitle, que devolve os IDs dos casos de RFQ que têm títulos vazios.
private container findRFQCasesWithEmptyTitle()
{
container result;
PurchRFQCaseTable rfqCase;
while select RFQCaseId from rfqCase
where rfqCase.Name == ''
{
result += rfqCase.RFQCaseId;
}
return result;
}
Mais dois métodos que têm de ser implementados são opportunityTitle e opportunityDetails. O primeiro devolve um título curto para a oportunidade, o último devolve uma descrição detalhada da oportunidade, que também pode incluir dados.
O título devolvido por opportunityTle aparece na coluna Oportunidade de otimização na área de trabalho do Assistente de otimização. Também aparece como o cabeçalho do painel lateral, mostrando mais informações sobre a oportunidade. Por convenção, este método é decorado com o atributo DiagnosticRuleSubscription, que utiliza os seguintes argumentos:
Área de diagnóstico – Uma enumeração do tipo DiagnosticArea que descreve a qual área do aplicativo a regra pertence, como DiagnosticArea::SCM.
Nome da regra – Uma cadeia de caracteres com o nome da regra. Isto aparecerá na coluna Nome da regra no formulário Regra de validação do diagnóstico (DiagnosticsValidationRuleMaintain).
Frequência de execução– Uma enumeração do tipo DiagnosticRunFrequency que descreve a frequência com que a regra deve ser executada, como DiagnosticRunFrequency::Daily.
Descrição da regra– Uma cadeia de caracteres com uma descrição mais detalhada da regra. Isto aparecerá na coluna Descrição da regra no formulário Regra de validação do diagnóstico (DiagnosticsValidationRuleMaintain).
Nota
O atributo DiagnosticRuleSubscription é necessário para que a regra funcione. Normalmente é utilizado em opportunityTitle, mas pode decorar qualquer método da classe.
Segue-se um exemplo de implementação. São utilizadas cadeias em bruto para maior simplicidade, mas uma implementação correta requer etiquetas.
[DiagnosticsRuleSubscription(DiagnosticsArea::SCM,
'Assign titles to Request for Quotation cases',
DiagnosticsRunFrequency::Daily,
'This rule detects Requests for Quotation with empty titles.')]
public str opportunityTitle()
{
return 'Assign titles to Request for Quotation cases';
}
A descrição devolvida por opportunityDetails aparece no painel lateral, mostrando mais informações sobre a oportunidade. Isto requer o argumento SelfHealingOpportunity, que é o campo Dados que pode ser utilizado para fornecer mais detalhes sobre a oportunidade. No exemplo, o método devolve os IDs dos casos de RFQ com um título vazio.
public str opportunityDetails(SelfHealingOpportunity _opportunity)
{
str details = '';
container opportunityData = _opportunity.Data;
int affectedRFQCasesCount = conLen(opportunityData);
if (affectedRFQCasesCount != 0)
{
details = 'The following Request for Quotation cases have an empty title:\n';
for (int i = 1; i <= affectedRFQCasesCount ; i++)
{
PurchRFQCaseId rfqCaseId = conPeek(opportunityData, i);
details += rfqCaseId + '\n';
}
}
return details;
}
Os dois métodos abstratos restantes para implementação são provideHealingAction e securityMenuItem.
provideHealingAction retorna true se uma ação de cura é fornecida, caso contrário, ela retorna false. Se for devolvido verdadeiro, o método performAction tem de ser implementado ou será gerado um erro. O método performAction requer um argumento SelfHealingOpportunity, no qual os dados podem ser utilizados para a ação. No exemplo, a ação abre PurchRFQCaseTableListPage para correção manual.
public boolean providesHealingAction()
{
return true;
}
protected void performAction(SelfHealingOpportunity _opportunity)
{
new MenuFunction(menuItemDisplayStr(PurchRFQCaseTableListPage), MenuItemType::Display).run();
}
Dependendo das especificidades da regra, pode ser possível tomar uma ação automática utilizando os dados da oportunidade. Neste exemplo, o sistema poderia gerar títulos para casos de RFQ automaticamente.
securityMenuItem retorna o nome de um item de menu de ação de forma que a regra só fique visível para os utilizadores que podem aceder o item de menu de ações. A segurança pode exigir que regras e oportunidades específicas sejam acessíveis apenas a utilizadores autorizados. No exemplo, apenas utilizadores com acesso a PurchRFQCaseTitleAction podem ver a oportunidade. Note que este item do menu de ação foi criado para este exemplo e foi adicionado como um ponto de entrada para o privilégio de segurança PurchRFQCaseTableMaintain.
Nota
O item de menu deve ser um item do menu de ação para que a segurança funcione corretamente. Outros tipos de itens de menu, tais como Apresentar itens de menu não funcionarão corretamente.
public MenuName securityMenuItem()
{
return menuItemActionStr(PurchRFQCaseTitleAction);
}
Depois de compilada a regra, execute o trabalho seguinte para ser apresentado na interface do utilizador (IU).
class ScanNewRulesJob
{
public static void main(Args _args)
{
SysExtensionCache::clearAllScopes();
var controller = new DiagnosticsRuleController();
controller.runOperation();
}
}
A regra será apresentada no formulário Regra de validação de diagnóstico, disponível a partir de Administração do sistema>Tarefas periódicas>Manter regra de validação de diagnóstico. Para a regra ser avaliada, aceda a Administração do sistema>Tarefas periódicas>Agendar regra de validação de diagnóstico e selecione a frequência da regra, como Diária. Clique em OK. Aceda a Administração do sistema>Assistente de otimização para ver a nova oportunidade.
O exemplo seguinte é um fragmento de código com o esqueleto de uma regra, incluindo todos os métodos e atributos necessários. Ajuda-o a começar a escrever novas regras. As etiquetas e os itens do menu de ação que são utilizados no exemplo são utilizados apenas para fins de demonstração.
[DiagnosticsRuleAttribute]
public final class SkeletonSelfHealingRule extends SelfHealingRule implements IDiagnosticsRule
{
[DiagnosticsRuleSubscription(DiagnosticsArea::SCM,
"@SkeletonRuleLabels:SkeletonRuleTitle", // Label with the title of the rule
DiagnosticsRunFrequency::Monthly,
"@SkeletonRuleLabels:SkeletonRuleDescription")] // Label with a description of the rule
public str opportunityTitle()
{
// Return a label with the title of the opportunity
return "@SkeletonRuleLabels:SkeletonOpportunityTitle";
}
public str opportunityDetails(SelfHealingOpportunity _opportunity)
{
str details = "";
// Use _opportunity.data to provide details on the opportunity
return details;
}
protected List evaluate()
{
List results = new List(Types::Record);
// Write here the core logic of the rule
// When creating an opportunity, use:
// * this.getOpportunityForCompany() for company specific opportunities
// * this.getOpportunityAcrossCompanies() for cross-company opportunities
return results;
}
public boolean providesHealingAction()
{
return true;
}
protected void performAction(SelfHealingOpportunity _opportunity)
{
// Place here the code that performs the healing action
// To open a form, use the following:
// new MenuFunction(menuItemDisplayStr(SkeletonRuleDisplayMenuItem), MenuItemType::Display).run();
}
public MenuName securityMenuItem()
{
return menuItemActionStr(SkeletonRuleActionMenuItem);
}
}
Para mais informações, veja o breve vídeo do YouTube: Assistente de otimização no Dynamics 365 Finance