Na framework de add-ons, é possível reagir a determinados momentos (eventos) que ocorrem nas diversas entidades da aplicação. Essas entidades podem ser nativas, como o cliente (ClVO) ou os documentos de faturação (FtVO), ou podem ser entidades definidas por um add-on, cuja definição é feita em GO Studio – Toolbox – Ecrãs e Entidades ou em GO Studio – Toolbox – Extensões de Ecrã e Entidades.
Esses momentos correspondem aos tipos de código definidos na opção GO Studio – Toolbox – Regras de Negócio. A principal diferença é que, através da nova abordagem descrita neste tópico, é possível escrever código apenas uma vez, e reagir aos eventos de todas as entidades, em vez de o fazer apenas para uma entidade específica, como acontece nas regras de negócio (onde a entidade é indicada no campo Entidade).
Nesta nova abordagem, quando o momento ocorre, a aplicação fornece qual foi a entidade que originou esse evento. O developer pode então consultar o valor desse parâmetro, e decidir se deve executar código específico ou não, permitindo assim filtrar, entre as entidades existentes na aplicação, aquelas em que se pretende intercetar determinado momento, e aplicar comportamento personalizado.
Para utilizar esta nova forma de intercetar vários momentos associados às entidades, recorre-se à opção já existente GO Studio – Toolbox – Bibliotecas de Servidor.
Dentro do Namespace associado à instalação de developer de add-ons, cria-se uma classe com um nome à escolha do developer, mas que deve obrigatoriamente herdar da classe da framework de add-ons chamada EntityEvents.
Exemplo:
OnAdding
Este momento é idêntico à opção
GO Studio – Toolbox – Regras de Negócio quando o tipo de código é
Ao Adicionar, a sua assinatura é a seguinte:
Código em VB.NET
Public Overrides Sub OnAdding(itemVO As BusinessVO, duplicating As Boolean, lstMsg As List(Of MessageVO))
End Sub
É executado quando o utilizador realiza a ação de criar um novo registo no ecrã de uma determinada entidade, ou quando cria um novo registo a partir de outro já existente na base de dados (ação de duplicação). Quando a ação é de criação, o parâmetro
duplicating tem o valor
False; quando é de duplicação, o valor é
True.
Neste último caso, o momento
OnDuplication já foi executado anteriormente e não gerou nenhuma mensagem de erro, caso contrário, este momento
OnAdding não seria executado, pois a aplicação teria cancelado o processo.
O parâmetro
itemVO representa o novo registo da entidade, que existe apenas em memória e ainda não foi gravado na base de dados. A gravação ocorre mais tarde, quando o utilizador pressiona o botão
Gravar no ecrã correspondente e o momento
OnSave é executado com sucesso. Este parâmetro já contém os valores por defeito atribuídos pela aplicação, bem como os valores por defeito definidos em código de add-ons existentes.
Como este método é síncrono, além de poder cancelar o momento adicionando uma mensagem de erro ao parâmetro
lstMsg, qualquer alteração feita aos valores de
itemVO é refletida de imediato no frontend, no ecrã da entidade, e mantida para gravação na base de dados, a menos que o utilizador altere esses valores antes de gravar.
Dado que este método é executado em duas situações distintas (criação e duplicação), é importante respeitar o valor do parâmetro
duplicating para decidir se devem ser atribuídos valores por defeito a determinados campos da entidade. No caso de duplicação, esses campos podem já vir preenchidos, e poderá não ser desejável sobrepôr esses valores.
De seguida apresentamos alguns exemplos:
1. Preencher valores por defeito.
Código em VB.NET
If TypeOf itemVO Is ClVO Then
Dim myClient As ClVO = DirectCast(itemVO, ClVO)
´ Pretendemos que todas as fichas de clientes tenham uma zona predefinida.
´ Assim, se o campo da zona estiver vazio, atribuímos uma zona por defeito.
´ Antes disso, verificamos se o campo já tem valor, caso tenha, preservamos esse valor,
´ pois pode ter sido definido pelos valores por defeito do sistema ou de um Add-on,
´ ou podemos estar perante uma duplicação (duplicating = True).
If myClient.zona.IsVoid() Then
myClient.zona = "Centro"
End If
End If
2. Registrar a atividade num log.
Código em VB.NET
If TypeOf itemVO Is FtVO Then
Dim myLogBiz As SDKBiz = SDK.Business.CreateBiz("u8882_ActivityLog")
If myLogBiz IsNot Nothing Then
Dim newEntry As u8882_ActivityLogVO = myLogBiz.GetNewInstance().GetResult(Of u8882_ActivityLogVO)()
If newEntry IsNot Nothing Then
newEntry.activity = String.Format("Inicio de {0} de documento de faturação", {If(duplicating, "duplicação", "criação")})
myLogBiz.Save(newEntry)
End If
End If
End If
OnDuplication
Este momento é idêntico á opção
GO Studio – Toolbox – Regras de Negócio quando o tipo de código é
Ao Duplicar, a sua assinatura é a seguinte:
Código em VB.NET
Public Overrides Sub OnDuplicating(itemVO As BusinessVO, lstMsg As List(Of MessageVO))
End Sub
É executado quando o utilizador realiza a ação de criar um novo registo com os dados já preenchidos a partir de outro registo existente na base de dados, ou seja, a ação de duplicação. Após este momento ser executado, a aplicação inicia a execução do método
OnAdding, enviando para esse método o mesmo
itemVO que possa ter sido manipulado durante a duplicação.
O parâmetro
itemVO representa o novo registo da entidade, que existe apenas em memória, ou seja, ainda não foi gravado na base de dados. A gravação ocorre mais tarde, quando o utilizador pressiona o botão
Gravar no respetivo ecrã e o momento
OnSave é executado com sucesso.
O valor do parâmetro
itemVO recebido contém os valores do registo original da base de dados, a partir do qual foi executada a ação de duplicação. Alguns desses valores podem ter sido limpos automaticamente pela aplicação antes da execução deste método.
Isto acontece devido a possíveis regras de negócio aplicadas à entidade, ou a definições de customização feitas por um add-on, quando, na opção
GO Studio – Toolbox – Ecrãs e Entidades ou
GO Studio – Toolbox – Extensões de Ecrã e Entidades, se acede à propriedade de um campo e se ativa a opção
Não duplica.
Este momento é útil para realizar operações de limpeza em determinados campos que, pela sua natureza, só devem ser tratados em casos específicos. Nessas situações, não é conveniente usar a opção automática
Não duplica, já que esta aplica-se a todos os casos, enquanto aqui é possível decidir pontualmente, por exemplo, com base nos valores de outros campos do registo.
Como este método é síncrono, além de poder cancelar o momento adicionando uma mensagem de erro ao parâmetro
lstMsg, qualquer alteração feita aos valores de
itemVO é refletida de imediato no frontend, no ecrã da entidade, e mantida para gravação na base de dados, a menos que o utilizador altere esses valores antes de gravar.
De seguida apresentamos alguns exemplos:
1. Limpar valores de campos que não permitem duplicação.
Código em VB.NET
If TypeOf itemVO Is ClVO Then
Dim myClient As ClVO = DirectCast(itemVO, ClVO)
´ A decisão de limpar o campo "zona" depende do valor existente
´ noutro campo da ficha do cliente. Por isso, verificamos primeiro
´ essa condição e apenas efetuamos a limpeza se a condição for verdadeira.
If myClient.clivd Then
myClient.nome = ""
End If
End If
OnFromReference
Este momento é idêntico à opção
GO Studio – Toolbox – Regras de Negócio quando o tipo de código é
Ao Criar com Referência, a sua assinatura é a seguinte:
Código em VB.NET
Public Overrides Sub OnFromReference(itemVO As BusinessVO, oriItemVO As Object, valuesItem As InstanceFromReference, lstMsg As List(Of MessageVO))
End Sub
É executado quando o utilizador, a partir do ecrã de uma entidade, realiza uma ação para criar um registo de outra entidade, levando como referência os dados da origem, para que possam ser utilizados no novo registo. Por exemplo, a partir do ecrã de clientes, ao consultar o cliente “Alberto”, o utilizador executa a ação
Criar documento de faturação. Nesse caso, é aberto o ecrã de documentos de faturação com um novo registo, já com os dados do cliente “Alberto” preenchidos.
Este momento pode comportar-se de forma idêntica ao método
OnAdding ou ao método
OnDuplication, dependendo da relação entre as entidades envolvidas. Quando o momento é iniciado pela aplicação, é verificado se a entidade contida no parâmetro
itemVO é a mesma que está contida no parâmetro
oriItemVO.
- Se forem iguais (por exemplo, ambos dizem respeito à entidade de cliente, ClVO):
Antes da execução deste método, é executado o método OnDuplication.
- Se forem diferentes:
Antes da execução deste método, é executado o método OnAdding.
O parâmetro itemVO representa o novo registo da entidade, que existe apenas em memória, ainda não foi gravado na base de dados. A gravação só ocorre mais tarde, quando o utilizador pressiona o botão Gravar no respetivo ecrã, e o momento OnSave é executado com sucesso.
O parâmetro oriItemVO é o registo de origem. No exemplo anterior, corresponde ao cliente “Alberto”, enquanto o valor do parâmetro itemVO representa o novo documento de faturação, que nesta fase já contém os dados do cliente preenchidos. Isto acontece porque, além da execução dos métodos anteriores, já foi também executado o método interno da aplicação associado a este momento, bem como qualquer código de add-on relacionado com regras de negócio associadas ao mesmo.
Como este método é síncrono, além de poder cancelar o momento adicionando uma mensagem de erro ao parâmetro lstMsg, qualquer alteração feita aos valores de itemVO é refletida de imediato na interface do utilizador e mantida para gravação na base de dados, a menos que o utilizador altere esses valores antes de gravar.
De seguida apresentamos alguns exemplos:
1. Preencher valores por defeito.
Código em VB.NET
If TypeOf itemVO Is FtVO Then
Dim myInvoice As FtVO = DirectCast(itemVO, FtVO)
If TypeOf oriItemVO Is ClVO Then
Dim myClient As ClVO = DirectCast(itemVO, ClVO)
myInvoice.zona = myClient.zona
End If
End If
2. Registrar a atividade num log.
Código em VB.NET
If TypeOf itemVO Is FtVO Then
Dim myLogBiz As SDKBiz = SDK.Business.CreateBiz("u8882_ActivityLog")
If myLogBiz IsNot Nothing Then
Dim newEntry As u8882_ActivityLogVO = myLogBiz.GetNewInstance().GetResult(Of u8882_ActivityLogVO)()
If newEntry IsNot Nothing Then
Dim duplicating As Boolean = (itemVO.GetType() Is oriItemVO.GetType())
newEntry.activity = String.Format("Inicio de {0} de documento de faturação", {If(duplicating, "duplicação", "criação")})
myLogBiz.Save(newEntry)
End If
End If
End If
OnEditing
Este momento é idêntico à opção
GO Studio – Toolbox – Regras de Negócio quando o tipo de código é
Ao Editar, a sua assinatura é a seguinte:
Código em VB.NET
Public Overrides Sub OnEditing(itemVO As BusinessVO, runWarningRules As Boolean, lstMsg As List(Of MessageVO))
End Sub
É executado quando o utilizador, a partir do ecrã de uma entidade, realiza uma ação para iniciar a edição ou alteração dos dados do registo que está a consultar. Este momento permite analisar os valores recebidos no parâmetro
itemVO, de modo a determinar se a operação de edição é permitida ou se deve ser cancelada, devolvendo uma mensagem de erro no parâmetro
lstMsg. Caso isso ocorra, o ecrã permanece em modo de consulta e não entra em modo de alteração.
Antes da execução deste método, todas as regras existentes para a entidade, associadas a este momento, já foram executadas, sejam regras da aplicação ou de add-ons. Se alguma dessas regras impedir a edição, este método não será chamado.
O parâmetro
itemVO representa o registo que o utilizador estava a consultar no momento em que executou a ação de alteração. No entanto, os valores dos campos podem não corresponder exatamente aos que o utilizador visualizou no ecrã.
Primeiro, porque quando o pedido do frontend chega ao backend, é enviado apenas o ID único do registo em consulta; o backend usa esse ID para obter novamente o registo diretamente da base de dados, ignorando qualquer cache em memória, garantindo assim a versão mais atual dos dados.
Segundo, porque as regras de negócio associadas a este momento, tanto da aplicação como de add-ons, são executadas antes deste método, podendo alterar novamente alguns valores do registo. Assim, o conteúdo de
itemVO pode conter dados ainda mais recentes, eventualmente não persistidos na base de dados.
Isto significa que o valor do parâmetro
itemVO já foi preparado pela aplicação para aceitar e persistir qualquer alteração feita durante este momento. Por isso, o método pode ser usado não apenas para validar ou cancelar a operação, mas também para ajustar dados imediatamente antes de o ecrã entrar em modo de alteração.
Como este método é síncrono, além de poder cancelar o momento adicionando uma mensagem de erro ao parâmetro
lstMsg, qualquer alteração feita aos valores de
itemVO é refletida na interface do utilizador e mantida para gravação na base de dados, a menos que o utilizador altere esses valores antes de gravar.
De seguida apresentamos um exemplo:
1. Preencher valor de número de alterações.
Código em VB.NET
If TypeOf itemVO Is ClVO Then
Dim myClient As ClVO = DirectCast(itemVO, ClVO)
´ A entidade de clientes foi extendida pela entidade u8882_clext,
´ adicionando um campo inteiro (changeCount) que guarda o número de alterações efetuadas no registo.
´ Usamos a função IsFieldChanged para verificar se, desde o início deste momento até o controlo
´ da execução chegar a este método, algum código da aplicação ou de add-ons alterou o campo changeCount.
´ Nesse caso, não queremos incrementar o valor do campo duas vezes.
If Not myClient.u8882_clext.IsFieldChanged(NameOf(myClient.u8882_clext.changeCount)) Then
myClient.u8882_clext.changeCount += 1
End If
End If
OnDelete
Este momento é idêntico à opção
GO Studio – Toolbox – Regras de Negócio quando o tipo de código é
Ao Apagar, a sua assinatura é a seguinte:
Código em VB.NET
Public Overrides Sub OnDelete(itemVO As BusinessVO, runWarningRules As Boolean, lstMsg As List(Of MessageVO))
End Sub
É executado quando o utilizador, a partir do ecrã de uma entidade, realiza uma ação para apagar o registo que está a consultar. Este momento permite analisar os valores recebidos no parâmetro
itemVO para determinar se a operação de eliminação é permitida ou se deve ser cancelada, devolvendo uma mensagem de erro no parâmetro
lstMsg. Nesse caso, o registo não é removido da base de dados.
Antes da execução deste método, todas as regras associadas a este momento, já foram executadas, quer sejam da aplicação, quer de add-ons. Se alguma dessas regras impedir a eliminação, este método não será chamado.
O parâmetro
itemVO representa o registo que o utilizador estava a consultar no momento em que executou a ação de apagar. No entanto, os valores dos seus campos podem não corresponder exatamente aos que o utilizador visualizou no ecrã, porque quando o pedido chega ao backend, é enviado apenas o
ID único do registo. O backend utiliza esse ID para obter novamente o registo diretamente da base de dados, ignorando qualquer cache existente, garantindo assim a versão mais atual dos dados.
Como este método é síncrono, é possível cancelar o momento adicionando uma mensagem de erro ao parâmetro
lstMsg. No entanto, quaisquer alterações feitas aos valores de
itemVO serão descartadas, uma vez que esta operação tem como objetivo eliminar o registo da base de dados.
OnSave
Este momento é idêntico à opção
GO Studio – Toolbox – Regras de Negócio quando o tipo de código é
Ao Gravar, a sua assinatura é a seguinte:
Código em VB.NET
Public Overrides Sub OnSave(itemVO As BusinessVO, runWarningRules As Boolean, lstMsg As List(Of MessageVO))
End Sub
É executado quando o utilizador, a partir do ecrã de uma entidade que está em modo de inserção ou alteração, pressiona o botão
Gravar, para que as alterações sejam persistidas na base de dados. Como este momento ocorre tanto na inserção como na alteração, caso seja necessário diferenciar o comportamento entre ambas as situações, deve-se consultar o valor do campo
Operation do parâmetro
itemVO.
Se
itemVO.Operation = OperationEnum.Inserted, trata-se de um novo registo da entidade que existe apenas em memória, sendo gravado na base de dados no fim da execução deste momento. Se
itemVO.Operation = OperationEnum.Updated, trata-se de um registo já existente que está a ser alterado, e as modificações serão gravadas também no final da execução.
O parâmetro
itemVO representa o registo que o utilizador estava a inserir ou alterar no ecrã quando pressionou o botão
Gravar. No entanto, os valores dos seus campos podem não corresponder exatamente aos que o utilizador observou, pois antes da execução deste método, todas as regras associadas a este momento, tanto da aplicação como de add-ons, já foram processadas e podem ter alterado alguns valores.
O parâmetro
runWarningRules está ligado à funcionalidade que permite que, neste método específico, as mensagens de aviso
MsgWarning sejam apresentadas no frontend como perguntas, solicitando confirmação do utilizador para prosseguir ou cancelar a operação. Como o frontend e o backend são aplicações distintas, é necessário um mecanismo que permita pausar a execução para essa interação.
O processo funciona assim: quando o utilizador pressiona o botão
Gravar, o frontend pede ao backend para executar este momento, enviando o valor
True no parâmetro
runWarningRules. O developer deve verificar este valor e, apenas nesse caso, executar blocos de código que possam gerar mensagens de aviso. Se uma mensagem desse tipo for gerada, a execução do momento é interrompida e a mensagem é enviada ao frontend.
O frontend, ao receber a mensagem de aviso, apresenta uma pergunta ao utilizador. Se a resposta for
Não, o frontend cancela a operação e regressa ao modo anterior (geralmente de consulta). Se a resposta for
Sim, o frontend volta a pedir ao backend para executar novamente o momento, desta vez com o parâmetro
runWarningRules = False. Como o developer deve condicionar a execução de mensagens de aviso a este valor, evita-se assim a criação de ciclos infinitos.
Como este método é síncrono, além de permitir cancelar o momento através de mensagens de erro adicionadas ao parâmetro
lstMsg, todas as alterações efetuadas no parâmetro itemVO são refletidas na gravação final do registo na base de dados.
De seguida apresentamos um exemplo:
1. Validar alterações.
Código em VB.NET
If TypeOf itemVO Is ClVO Then
Dim myClient As ClVO = DirectCast(itemVO, ClVO)
If myClient.Operation = OperationEnum.Updated Then
If myClient.IsFieldChanged(NameOf(myClient.zona)) Then
lstMsg.Add(New MsgError("Não é permitido alterar a zona de um cliente existente"))
End If
End If
If runWarningRules Then
If myClient.morada.IsVoid() Then
lstMsg.Add(New MsgWarning("Atenção a morada do cliente está vazia"))
End If
End If
End If