Introdução
Este artigo pretende ajudar na transição da framework de PHC CS para a framework de addons de PHC GO, nomeadamente criar regras de negócio para novos ecrãs e tabelas de
utilizador, assim como regras para a customização de ecrãs e tabelas existentes na aplicação.
Existem vários artigos da série Usa PHC CS com o intuito de facilitar a transição da
programação da framework PHC CS em Visual FoxPro para a framework PHC GO em .NET
Framework, utilizando Visual Basic.
Recomenda-se a leitura dos artigos pela ordem indicada, de forma a apresentar as diversas
tecnologias e técnicas de programação em sequência crescente de complexidade e
funcionalidade.
Regras de Negócio
No PHC GO, na opção GO Studio – Toolbox – Regras de Negócio, é possível adicionar código de
backend associado a diferentes momentos de interação com uma entidade. Por exemplo, pode
definir código para ser executado ao criar, alterar ou eliminar um registo, ou até mesmo para
realizar ações baseadas nesse registo sem que os seus dados sejam alterados. Um caso comum
é a criação de uma fatura com base num cliente específico.
Os momentos (eventos) disponíveis estão listados no campo Tipo de Código, sendo que esta
lista pode variar consoante a tabela selecionada no campo Entidade. A maioria destes eventos
corresponde a uma rota, semelhante a um URL, que representa uma possível navegação no
browser onde a aplicação está a ser executada.
Isto significa que, para começar a criar um novo registo, é possível, no ecrã correspondente,
acionar o botão Novo Registo, localizado no topo da página. Em alternativa, pode também
introduzir diretamente no browser a rota correspondente, como se estivesse a escrever um
endereço de internet.
Rotas
As rotas começam com o endereço de internet de uma instalação específica do PHC GO, que,
no nosso exemplo, será:
A seguir deve ser acrescentada a rota desejada, essa a rota começa pela gateway HTML e, se
pretendemos navegar para um ecrã, acrescentamos o código MAINFORM, seguido do nome da
entidade sem o prefixo VO. No caso de entidades do utilizador, deve ser adicionado o código
CUSTOM antes do nome da entidade.
Para abrir um ecrã existem duas rotas, uma para abrir em modo de lista e outra rota para abrir
em modo de consulta. Estas duas rotas não estão associadas a eventos específicos e existem
apenas como navegações de frontend.
- Abrir um ecrã em modo de lista
http://localhost/GO/html/mainform/custom/u0000_album
* Código PHC CS – Visual FoxPro
=doread("CL","SCL")
=dobytimer(" do usrform with 'u_album' ")
' Código PHC GO – Typescript
' the SDK function <navigateToMainform> only needs the entity name
' and can understand whether it is a system entity or a user entity
' http://localhost/GO/html/mainform/cl
sdk.navigateToMainform('CL')
' http://localhost/GO/html/mainform/custom/u0000_album
sdk.navigateToMainform('u0000_album')
- Abrir um ecrã em modo de consulta
http://localhost/GO/html/mainform/custom/u0000_album/view;stamp=
Z_20240505155423284756456
' Código PHC GO – Typescript
sdk.navigateToMainform('CL',0,'view','Z_20240505155423284756456')
sdk.navigateToMainform('u0000_album',0,'view','Z_20240505155423284756456')
Nota: No PHC GO, existe o conceito de a aplicação memorizar o estado anterior. Isto significa
que, por exemplo, se o utilizador esteve anteriormente no ecrã de clientes a consultar um
determinado registo, mais tarde, quando o código da aplicação solicitar uma navegação para o
ecrã de clientes no modo de lista, o ecrã abrirá ainda no modo de consulta.
Rotas - Security
A configuração de perfis de acesso para os utilizadores da aplicação consiste, na prática, em
negar o acesso a determinadas rotas presentes na lista da aplicação. Por exemplo, se for
negado o acesso à funcionalidade de introdução no ecrã de clientes, quando o utilizador tentar
abrir esse ecrã, o botão de introdução ficará desativado ou invisível.
Contudo, essa restrição visual não é suficiente para impedir o acesso. É essencial negar
explicitamente a rota de introdução para o ecrã de clientes, garantindo que mesmo que o
utilizador tente inserir manualmente o endereço no browser, a aplicação continue a negar essa
navegação.
Além disso, é fundamental implementar as mesmas restrições do lado do backend. As
chamadas aos serviços também utilizam rotas, e é necessário impedir o acesso a essas rotas
por parte de aplicações externas que possam usar a rota de introdução de clientes.
Esta abordagem assegura uma camada adicional de segurança e evita acessos indevidos tanto
no frontend quanto no backend.
Resumindo, as rotas podem ser ativadas de quatro formas:
- Escrevendo diretamente um endereço no browser.
- Através da interação do utilizador com a aplicação frontend.
- Execução de código em add-ons utilizando o SDK de frontend.
- Uma aplicação externa efetuar um pedido HTTP ao backend.
Eventos ao nível do ecrã
No PHC CS, existem diversos eventos associados ao trabalho com o ecrã de uma entidade,
permitindo implementar lógica personalizada em várias fases da interação do utilizador com o
ecrã. No entanto, devido à natureza distinta da aplicação no PHC GO, a correspondência desses
eventos pode variar:
- Alguns eventos do PHC CS têm uma correspondência direta no PHC GO, permitindo
implementar funcionalidades equivalentes.
- Outros eventos são realizados no PHC GO através de eventos com nomes ou
comportamentos diferentes, que oferecem resultados semelhantes, mas adaptados à
arquitetura e funcionalidades da nova plataforma.
- Por fim, existem eventos que não estão disponíveis no PHC GO, devido a limitações ou
diferenças na abordagem da framework.
Estes fatores devem ser considerados ao planear a transição de personalizações do PHC CS
para o PHC GO.
- Evento Introduzir (Check)
- Evento Introduzir
Estes dois eventos são representados num único em PHC GO, o evento: Ao Introduzir,
se for retornado uma mensagem de erro a criação de novo registo é cancelada, neste
caso será o equivalente ao (Check).
- Evento Alterar (Check)
Corresponde ao evento: Ao Alterar, se for retornado uma mensagem de erro o ecrã
não entra em modo de alteração, ficando em modo de consulta.
- Evento Apagar (Check)
- Evento Apagar
Estes dois eventos são representados num único em PHC GO, o evento: Ao Apagar, se
for retornado uma mensagem de erro o apagar do registo é cancelado, neste caso será
o equivalente ao (Check).
- Evento Apagar (Fim)
Corresponde ao evento: Após Gravar, no PHC GO o apagar é na realidade uma
gra que o registo está marcado como Deleted.
- Evento Gravar (Check)
- Evento Gravar
Estes dois eventos são representados num único em PHC GO, o evento: Ao Gravar, se
for retornado uma mensagem de erro a gravação do registo não é efetuada,
continuando o mesmo em modo de alteração no frontend, neste caso será o
equivalente ao (Check).
- Evento Gravar (Fim)
Corresponde ao evento: Após Gravar, este evento ocorre após a gravação com sucesso
do registo, quer este esteja inicialmente marcado como Inserted, Updated ou Deleted.
- Evento Refrescar
É um evento apenas de frontend, explicado no manual: Usa PHC – Ecrãs e Tabelas no
tópico Dados Gerais – Comportamento.
' Código PHC GO – Typescrip
function updateConfig(currentRecord: GenericVO): void {
sdk.setReadonly('rarity', !sdk.User.esa);
}
- Evento Init
- Evento Ativar
- Evento Clique
- Evento Duplo Clique
- Evento Dimensionar
- Evento Mover
- Evento Desativar
- Evento Cancelar
- Evento Fim
Não existe correspondência destes eventos do PHC CS com os eventos disponíveis no
PHC GO.
Evento - Ao Introduzir
Este evento é acionado quando o backend recebe um pedido para criar um novo registo numa
entidade de sistema ou de utilizador.
http://localhost/GO/html/mainform/custom/u0000_album/new
* Código PHC CS – Visual FoxPro
m.mb_clorigem = "INTRO"
=doread("CL","SCL")
m.mb_u_albumorigem = "INTRO"
=dobytimer(" do usrform with 'u_album' ")
' Código PHC GO – Typescript
sdk.navigateToMainform('CL',0,'new')
sdk.navigateToMainform('u0000_album',0,'new')
' Código PHC GO – VB.NET
Function OnAdding(itemVO As U0000_AlbumVO,
duplicating As Boolean) As List(Of MessageVO)
Dim listMsg As New List(Of MessageVO)
Return listMsg
End Function
O evento também ocorre quando é solicitado um novo registo a partir de um já existente na
base de dados (Duplicação), nesta situação o parâmetro duplicating tem o valor true.
html/mainform/custom/u0000_album/new;stamp=Z_20240505155423284756456
* Código PHC CS – Visual FoxPro
m.mb_clorigem = "DUPLI"
=doread("CL","SCL")
m.mb_u_albumorigem = "DUPLI"
=dobytimer(" do usrform with 'u_album' ")
' Código PHC GO – Typescript
sdk.navigateToMainform('u0000_album',0,'new','Z_20240505155423284756456')
' Código PHC GO – VB.NET
Function OnAdding(itemVO As U0000_AlbumVO,
duplicating As Boolean) As List(Of MessageVO)
Dim listMsg As New List(Of MessageVO)
Return listMsg
End Function
Após a execução do pedido no backend, e em caso de sucesso, é retornado o novo registo que
existe apenas em memória, ou seja, ainda não foi gravado na base de dados. Este momento é
ideal para atribuir valores por defeito ao registo, caso sejam necessários.
No caso de customização de uma tabela existente na aplicação (ou seja, uma tabela de sistema
e não uma tabela criada pelo utilizador), o processo ocorre em duas etapas:
- Primeiro, é executado o evento de sistema correspondente (Introduzir ou Duplicar).
- Se não forem geradas mensagens de erro durante a execução do evento de sistema, o
>evento do utilizador (este evento) é então acionado.
Neste evento não é necessário criar o registo, ele é fornecido no parâmetro itemVO. O registo
já está preparado para introdução (Operation = Inserted), com o valor único (STAMP) já
preenchido, neste caso no campo u0000_albumstamp.
Evento - Ao Introduzir com Referência
http://localhost/GO/html/mainform/ft/99/new;sourceEntityName=
u0000_album;sourceStamp=Z_20240505155423284756456
Este evento é acionado quando o backend recebe um pedido para criar um novo registo numa
entidade de sistema ou de utilizador, tendo como origem outro registo de uma entidade
diferente, já existente na base de dados.
' Código PHC GO – Typescript
sdk.createRecordFromReference('u0000_album','Z_20240505155423284756456','Ft',99,[{line1:
'esta é a primeira linha'}, {Line2: 'esta é a segunda linha'}])
Quando este evento é acionado, é possível enviar informações adicionais. Neste caso,
enviamos um array com duas posições, em que cada posição contém um objeto com uma
propriedade e o respetivo valor.
Estas informações adicionais ficam disponíveis no parâmetro payload, na propriedade com o
mesmo nome. Para aceder facilmente a este objeto, pode ser utilizado o método utilitário
GetValue(Of T).
' Código PHC GO – VB.NET
Function OnFromReference(itemVO As FtVO,
oriItemVO As U0000_AlbumVO,
payload As InstanceFromReference) As List(Of MessageVO)
Dim listMsg As New List(Of MessageVO)
' itemVO.ndoc = 99 (serie)
' oriItemVO.u0000_albumstamp = 'Z_20240505155423284756456'
' payload.GetValue(Of String)("origin") = u0000_album
' payload.GetValue(Of String)("originstamp") = Z_20240505155423284756456
' payload.GetValue(Of Decimal)("docid") = 99
' payload.GetValue(Of String)("destination") = FT
'
' Dim myPayload as Object = payload.GetValue(Of Object)("payload")
' myPayload.line1 = esta é a primeira linha
' myPayload.line2 = esta é a segunda linha
Return listMsg
End Function
Estrutura da classe InstanceFromReference.
' Código PHC GO – VB.NET
Class InstanceFromReference
Property origin As String
Property originstamp As String
Property docid As Decimal
Property destination As String
Property payload As Object
Function GetValue(Of T)(key As String) As T
End Class
Quando este evento ocorre, o evento Ao Introduzir é executado primeiro, seguido deste
evento. Assim, para o parâmetro ItemVO, já foram aplicadas todas as operações descritas
anteriormente no evento ao introduzir.
Uma particularidade é que, quando a origin e destination do parâmetro Payload são os
mesmos, o evento Ao Introduzir, é executado no modo de duplicação.
Na chamada, no código de frontend, indicamos apenas o nome da entidade de origem e o
respetivo stamp único. Neste ponto, a aplicação fornece, no parâmetro oriItemVO, o registo
correspondente, já retornado da base de dados.
Com origem no ecrã de Álbuns criar um novo Artigo:
' Código PHC GO – Typescript
function runAction(currentRecord: GenericVO, currentSeries?: GenericVO): void {
sdk.createRecordFromReference("u0000_album",currentRecord.u0000_albumstamp,"st",0)
}
function isActionAvailable(currentRecord: GenericVO, currentSeries?: GenericVO): boolean {
return (currentRecord.stref === "")
}
' Código PHC GO – VB.NET
Function OnFromReference(itemVO As STVO, oriItemVO As U0000_ALBUMVO,
payload As InstanceFromReference) As List(Of MessageVO)
Dim listMsg As List(Of MessageVO) = New List(Of MessageVO)
itemVO.u0000_st_album.albumstamp = oriItemVO.u0000_albumstamp
itemVO.design = String.Format("Álbum: {0} ({1})",oriItemVO.nome,oriItemVO.singername)
Return listMsg
End Function
Com origem no ecrã de Álbuns criar uma nova Fatura:
' Código PHC GO – Typescript
function runAction(currentRecord: GenericVO, currentSeries?: GenericVO): void {
const ftserie = sdk.readParameter("u0000album_ft_serie");
if (ftserie !== null && ftserie !== "")
{
sdk.createRecordFromReference("u0000_album",
currentRecord.u0000_albumstamp,
"ft", Number(ftserie))
}
}
function isActionAvailable(currentRecord: GenericVO, currentSeries?: GenericVO): boolean {
const ftserie = sdk.readParameter("u0000album_ft_serie");
return (currentRecord.stref !== "" && ftserie !== null && ftserie !== "")
}
' Código PHC GO – VB.NET
Public Function OnFromReference(itemVO As FTVO, oriItemVO As U0000_ALBUMVO,
payload As InstanceFromReference) As List(Of MessageVO)
Dim listMsg As List(Of MessageVO) = New List(Of MessageVO)
Dim itemFt as FtVO = DirectCast(itemVO,FtVO)
Dim itemFi as FiVO = itemFt.AddChild(Of FiVO)()
itemFi.ref = oriItemVO.stref
ActEntity(itemFt)
Return listMsg
End Function
Evento - Ao Alterar
http://localhost/GO/html/mainform/custom/u0000_album/edit;stamp=Z_2024050515542328
4756456
Este evento é acionado quando o backend recebe um pedido para entrar em modo de
alteração de um registo, numa entidade de sistema ou de utilizador.
' Código PHC GO – Typescript
sdk.navigateToMainform('u0000_album',0,'edit','Z_20240505155423284756456')
' Código PHC GO – VB.NET
Function OnEditing(itemVO As U0000_AlbumVO,
runWarningRules As Boolean) As List(Of MessageVO)
Dim listMsg As New List(Of MessageVO)
Return listMsg
End Function
Evento - Ao Apagar
http://localhost/GO/html/mainform/custom/u0000_album/delete;stamp=Z_20240505155423
284756456
Este evento é acionado quando o backend recebe um pedido para eliminar um registo de uma
entidade de sistema ou de utilizador.
Caso a eliminação seja permitida, o registo é imediatamente excluído da base de dados, ou
seja, não é necessário acionar o evento Ao Gravar.
A tarefa de eliminar o registo da base de dados, é realizada automaticamente neste evento. No
entanto, se a eliminação for bem-sucedida, o evento Após Gravar é executado.
' Código PHC GO – VB.NET
Public Function OnDelete(itemVO As U0000_AlbumVO,
runWarningRules As Boolean) As List(Of MessageVO)
Dim listMsg As List(Of MessageVO) = New List(Of MessageVO)
If itemVO.rarity
If not SDK.User.getCurrentInfo.esa
listMsg.Add(new MsgError("Only administrators have access to delete rare albums."))
End If
End If
Return listMsg
End Function
Public Function OnDelete(itemVO As U0000_SINGERVO,
runWarningRules As Boolean) As List(Of MessageVO)
Dim listMsg As List(Of MessageVO) = New List(Of MessageVO)
If SDK.Query.ExistRecord("u0000_album",
New FilterItem("singerstamp='"+itemVO.singerstamp+"'"))
listMsg.Add(New MsgError("Cannot delete because exists in albums."))
End If
Return listMsg
End Function
Evento - Ao Gravar
Este evento é acionado quando o backend recebe um pedido para gravar um registo de uma
entidade de sistema ou de utilizador na base de dados.
Importa referir que esta rota não está disponível no frontend. O evento ocorre
automaticamente quando, através de código, é chamado o serviço de gravação no backend ou,
de forma interativa, quando é acionada a ação do botão de gravação no ecrã.
' Código PHC GO – VB.NET
Function OnSave(itemVO As U0000_AlbumVO,
runWarningRules As Boolean) As List(Of MessageVO)
Dim listMsg As New List(Of MessageVO)
Return listMsg
End Function
Evento - Ao executar Trigger na gravação
Este evento é acionado automaticamente pela aplicação após a execução bem-sucedida das
regras de negócio associadas ao evento Ao Gravar.
Posteriormente, o evento é executado em memória, ou seja, os triggers da aplicação PHC GO
são processados em memória e não diretamente na base de dados. Apenas após a execução
bem-sucedida deste processo é iniciada a fase de gravação na base de dados.
Importa referir que esta rota não está disponível no frontend. O evento ocorre
automaticamente quando, através de código, é chamado o serviço de gravação no backend ou,
de forma interativa, quando é acionada a ação do botão de gravação no ecrã.
' Código PHC GO – VB.NET
Function OnTriggers(itemVO As U0000_AlbumVO) As List(Of MessageVO)
Dim listMsg As New List(Of MessageVO)
Return listMsg
End Function
Evento - Após Gravar
Este evento é acionado automaticamente pela aplicação após a execução bem-sucedida das
regras de negócio associadas ao evento Ao Gravar, e após execução bem sucedida do evento:
Ao executar Trigger na gravação.
Importa referir que esta rota não está disponível no frontend. O evento ocorre
automaticamente quando, através de código, é chamado o serviço de gravação no backend ou,
de forma interativa, quando é acionada a ação do botão de gravação no ecrã.
' Código PHC GO – VB.NET
Function OnAfterSave(itemVO As U0000_AlbumVO) As List(Of MessageVO)
Dim listMsg As New List(Of MessageVO)
Return listMsg
End Function
Na gravação de um novo artigo, verificamos se essa ação teve origem na criação por referência
da entidade de álbuns, para atualizar os campos desnormalizados na entidade álbum
referentes ao artigo criado.
' Código PHC GO – VB.NET
Function OnAfterSave(itemVO As STVO) As List(Of MessageVO)
Dim listMsg As List(Of MessageVO) = New List(Of MessageVO)
Dim itemSt as FrameworkStVO = DirectCast(itemVO, FrameworkStVO)
' create the album controller
Dim albumBiz as SDKBiz = SDK.Business.CreateBiz("u0000_album")
If albumBiz Is Nothing
' After recording, the error messages can no longer cancel
' the previous recording moment, which is why we chose
' to save this situation in the error log.
SDK.Debug.LogError("The album business is not available.")
Return listMsg
End If
If itemSt.Operation = OperationEnum.Inserted
' we will only update the denormalized fields
' in the album if one was chosen for the reference
If Not itemSt.u0000_st_album.albumstamp.isVoid()
' get the album
Dim albumItem as u0000_albumVO = SDK.Query.GetEntityByStamp(Of
u0000_albumVO)(itemSt.u0000_st_album.albumstamp)
' update
If albumItem IsNot Nothing
albumItem.stref = itemSt.ref
albumItem.stdesign = itemSt.ref + " - " + itemSt.design
' save
If albumBiz.Save(albumItem).HasErrors
SDK.Debug.LogError("Error saving the album.")
End If
End If
End If
End If
Return listMsg
End Function
Evento - A Pedido
Este evento é acionado quando o backend recebe um pedido para executar código a partir de
um ID único associado ao código.
Esta rota não está disponível no frontend. Para executar o código pretendido, é necessário
chamar o serviço correspondente no backend.
- SDK de frontend: sdk.runBusinessRuleOnDemand
- SDKBiz de backend: SDKBiz.RunCode
' Código PHC GO – VB.NET
Function OnRunCode(itemVO As U0000_AlbumVO,
payload As Object,
Optional runWarningRules As Boolean) As List(Of MessageVO)
Dim listMsg As New List(Of MessageVO)
Return listMsg
End Function
Eventos ao nível do componente
Além dos eventos ao nível do ecrã, que são desencadeados por ações gerais do utilizador
(como introduzir, alterar ou apagar), existem também eventos ao nível dos componentes. Estes
eventos são ativados quando o utilizador interage diretamente com um componente específico
incluído no desenho do ecrã de uma entidade.
No PHC CS, existem diversos eventos associados ao trabalho com componentes, permitindo
implementar lógica personalizada em várias fases da interação do utilizador com o
componente. No entanto, devido à natureza distinta da aplicação no PHC GO, a
correspondência desses eventos pode variar:
- Alguns eventos do PHC CS têm uma correspondência direta no PHC GO, permitindo
implementar funcionalidades equivalentes.
- Outros eventos são realizados no PHC GO através de eventos com nomes ou
comportamentos diferentes, que oferecem resultados semelhantes, mas adaptados à
arquitetura e funcionalidades da nova plataforma
- Por fim, existem eventos que não estão disponíveis no PHC GO, devido a limitações ou
diferenças na abordagem da framework.
Estes fatores devem ser considerados ao planear a transição de personalizações do PHC CS
para o PHC GO.
- Evento Tecla Pressionada
Corresponde ao evento: Ao Sincronizar, existe uma particularidade em relação a este
evento: Tecla Pressionada, apenas existe para componentes que não sejam colunas de
grelha
- • Evento Após Atualizar
- Evento Após não Atualizado
Corresponde ao evento: Ao Sincronizar, existe uma particularidade em relação a este
evento: Após Atualizar, apenas existe para componentes que sejam colunas de grelha.
Em relação ao evento: Após não Atualizado, não existe correspondência com eventos
do PHC GO.
- Evento Refrescar
No PHC GO, o evento refrescar existe apenas ao nível do ecrã, e pode ser usado para
colocar o código que em PHC CS se usava no refrescar do componente. É um evento
apenas de frontend, explicado no manual: Usa PHC – Ecrãs e Tabelas no tópico Dados
Gerais – Comportamento.
' Código PHC GO – Typescript
function updateConfig(currentRecord: GenericVO): void {
sdk.setReadonly('rarity', !sdk.User.esa);
}
- Evento Init
- Evento ao Entrar
- Evento ao Sair
- Evento MouseEnter
- Evento MouseMove
- Evento MouseWheel
- Evento MouseLeave
- Evento Clique
- Evento Clique Direito
- Evento Duplo Clique
Não existe correspondência destes eventos do PHC CS com os eventos disponíveis no
PHC GO.
Para o componente Grelha do PHC CS existe mais alguns eventos específicos, que são:
- Evento Apagar (Check)
- Evento Apagar
Estes dois eventos são representados num único em PHC GO, o evento: Ao Apagar na
Grelha,
- Evento Introduzir (Check)
- Evento Introduzir
Estes dois eventos são representados num único em PHC GO, o evento: Ao Sincronizar,
- Evento Antes mudar Linha/Coluna
- Evento Depois mudar Linha/Coluna
Não existe correspondência destes eventos do PHC CS com os eventos disponíveis no
PHC GO.
Evento - Ao Sincronizar
No PHC GO quando existe uma alteração num componente presente no ecrã, ou numa grelha
de edição, o evento executado no backend é uma sincronização entre os valores em cache no
backend e os valores que estão a ser modificados no frontend.
' Código PHC GO – VB.NET
Function OnSync(masterVO As U0000_AlbumVO,
changedItems As List(Of EntityChangeOperation)) As List(Of MessageVO)
No parâmetro masterVO é sempre recebido a entidade principal do ecrã, independente se a
alteração foi efetuada num componente do ecrã ou num componente de uma grelha também
presente nesse ecrã.
Este parâmetro é fornecido quando queremos rapidamente consultar algo da entidade
principal do ecrã, embora se consiga obter a mesma informação através da entidade que foi
alvo de modificação no frontend, essa entidade é obtida através do parâmetro changedItems.
O parâmetro changedItems é uma lista de alterações efetuadas no frontend, tendo a seguinte
estrutura:
' Código PHC GO – VB.NET
Class EntityChangeOperation
#Region "Properties"
''' <summary>
''' Contains the type of the changed entity, e.g.: FrameworkClVO
''' </summary>
ReadOnly Property entityType() As Type
''' <summary>
''' Contains the base type of the changed entity, e.g.: ClVO
''' </summary>
ReadOnly Property baseType() As Type
''' <summary>
''' Indicates whether it is a user entity.
''' </summary>
ReadOnly Property isUserType() As Boolean
''' <summary>
''' Record changed.
''' </summary>
Property entity() As GenericVO
''' <summary>
''' Changed field name.
''' </summary>
Property field() As String = ""
''' <summary>
''' Original value of the field.
''' </summary>
Property oldValue() As Object
''' <summary>
''' Current value of the field.
''' </summary>
Property newValue() As Object
#End Region
#Region "Methods"
''' <summary>
''' Returns the original value of the field in typed format.
''' </summary>
Function GetOldValue(Of T)() As T
#End Region
End Class
Este evento é executado quando a alteração é efetuada num componente disponível no ecrã
(entidade principal) e também quando a alteração é efetuada num componente de uma grelha
de edição presente no ecrã (entidade de coleção).
Deste modo, no caso de entidade principal conter coleções, devemos neste código utilizar uma
estrutura para identificar em primeiro lugar qual a entidade que foi alvo de alteração.
' Código PHC GO – VB.NET
Function OnSync(masterVO As U4902_AlbumVO,
changedItems As List(Of EntityChangeOperation)) As List(Of MessageVO)
Select Case changedItems.First.baseType
Case GetType(u4902_AlbumVO)
Case GetType(u4902_MusicaVO)
End Select
End Function
Se ocorrer modificações em duas entidades no frontend, e for chamado o evento do backend
com todas as alterações efetuadas, a aplicação encarrega-se, neste caso, de correr esta função
duas vezes, assim temos a garantia que todos os registos da lista changedItems são do mesmo
tipo de entidade.
Podemos assim aplicar: First á lista recebida, tendo a garantia que o tipo do primeiro item é
igual a todos os outros que possam existir na lista. Ficando ao critério do programador, se
coloca a lógica deste evento dentro dos Case respetivos, ou se aqui, por questões de
organização do código, coloca apenas chamadas a funções criadas em bibliotecas de servidor,
explicadas mais à frente neste manual no Tópico: Bibliotecas de Servidor.
' Código PHC GO – VB.NET
Function OnSync(masterVO As U0000_AlbumVO,
changedItems As List(Of EntityChangeOperation)) As List(Of MessageVO)
' result
Dim listMsg As New List(Of MessageVO)
' change item
Dim changedItem As EntityChangeOperation = Nothing
' what was changed?
Select Case changedItems.First.baseType
' was it the main entity?
Case GetType(u0000_AlbumVO)
' current item
Dim myAlbum As u0000_AlbumVO = Nothing
' verify that the name field was changed in this interaction
changedItem = changedItems.GetChangedItemByField(myAlbum, "nome")
' if the changedItem object is different from Nothing
' indicates that there was a change to the name field
' myAlbum become the the record being changed in the frontend
If changedItem IsNot Nothing Then
If myAlbum.nome.isVoid()
listMsg.add(new MsgError("The album name must be filled."))
End If
End If
' was it the music collection?
Case GetType(u0000_MusicaVO)
' current item
Dim myMusic As u0000_MusicVO = Nothing
' verify that the name field was changed in this interaction
changedItem = changedItems.GetChangedItemByField(myMusic, "nome")
If changedItem IsNot Nothing Then
If myMusic.nome.isVoid()
listMsg.add(new MsgError("The name of the music must be filled."))
End If
End If
End Select
Return listMsg
End Function
Existe extensões que facilitam o trabalho das listas de EntityChangeOperation:
' Código PHC GO – VB.NET
Function GetChangedItemByField(field As String) As EntityChangeOperation
Function GetChangedItemByField(Of T)(ByRef entity As T, field As String) As
EntityChangeOperation
Function GetChangedItemByFields(Of T)(ByRef entity As T, ParamArray fields() As String) As
EntityChangeOperation
Function RemoveChanged(field As String) As List(Of EntityChangeOperation)
Existe situações em que após termos verificado que determinado campo for alterado,
recorrendo à extensão GetChangedItemByField, é necessário remover da lista a alteração que
possa existir a outro campo específico, recorrendo á extensão: RemoveChanged.
Na sincronização da entidade de faturação, existe dois blocos de código, um para a alteração
do número de cliente, e outro para a alteração do nome do cliente, nesses blocos, após a
busca do cliente pelo valor alterado, ambos chamam o mesmo código de atualização da fatura
com o novo cliente.
Acontece que no frontend da aplicação do PHC GO, quando se altera o número de cliente na
fatura, ainda no frontend, é também alterado o nome do cliente, e após estas duas alterações
á chamado o evento do backend: Ao Sincronizar.
Assim, no backend, após a execução do bloco de código da alteração do número do cliente,
limpamos a alteração do nome de cliente, porque nesse momento o novo cliente já se
encontra atualizado na fatura, com os IVAs e descontos definidos na sua ficha, não existindo
por isso, necessidade de correr o bloco de alteração do nome.
' Código PHC GO – VB.NET
' no / estab
changedItem = changedItems.GetChangedItemByFields(itemVO, "no", "estab")
If changedItem IsNot Nothing Then
...
changedItems.RemoveChanged("nome")
End If
' nome
changedItem = changedItems.GetChangedItemByField(itemVO, "nome")
If changedItem IsNot Nothing Then
...
End If
No PHC GO quando se apaga um registo numa grelha de coleção da entidade principal do ecrã,
é executado o evento: Ao Apagar na Grelha, mas quando se cria um registo nessa mesma
grelha é este evento: Ao Sincronizar que é executado. Existe uma técnica de distinguir uma
alteração de uma criação de registo.
Essa técnica consiste em perguntar á lista de alterações, se o campo que identifica unicamente
o registo na base de dados (stamp) foi alterado, pois só no momento de criação, esse campo
devolve true para alterações.
Após isso, se for alterado outro campo na entidade da coleção, o nome da música por exemplo,
na segunda chamada ao evento, o campo de stamp vai retornar false para alterações.
' Código PHC GO – VB.NET
Function OnSync(masterVO As U0000_AlbumVO,
changedItems As List(Of EntityChangeOperation)) As List(Of MessageVO)
' result
Dim listMsg As New List(Of MessageVO)
' change item
Dim changedItem As EntityChangeOperation = Nothing
' what was changed?
Select Case changedItems.First.baseType
' was it the music collection?
Case GetType(u0000_MusicaVO)
' current item
Dim myMusic As u0000_MusicVO = Nothing
' was a new line created?
changedItem = changedItems.GetChangedItemByField(myMusic, "u0000_musicstamp")
If changedItem IsNot Nothing Then
' option 1
listMsg.add(new MsgInfo("Congratulations, you are adding a new song to the
album: " + myMusic.ParentVO.nome))
' option 2
listMsg.add(new MsgInfo("Congratulations, you are adding a new song to the
album: " + masterVO.nome))
End If
End Select
Return listMsg
End Function
Neste exemplo podemos observar outro pormenor, o uso de ParentVO ou masterVO, as duas
técnicas resultam na mesma ação, aceder á entidade principal do ecrã, há situações em que
pode ser preferível usar masterVO.
Por exemplo, no caso da coleção de linhas de uma fatura, cada linha tem outra coleção de
impostos. Supondo que o estávamos a trabalhar com a entidade de impostos, fica mias fácil
escrever masterVO.nome do que impostosVO.ParentVO.ParentVO.nome.
Evento - Ao Apagar na Grelha
No PHC GO quando se apaga um registo numa grelha de coleção da entidade principal do ecrã,
o frontend chama automaticamente o evento Ao Sincronizar, enviando a entidade principal,
com todas as suas coleções, contendo todos os registos menos os que foram removidos.
Desta forma, permite ao backend identificar os registos apagados e executar este evento
apenas para esses registos removidos, caso nessa chamada também exista alterações a registos
ainda existentes nas coleções, também é executado o evento Ao Sincronizar para os registos
correspondentes.
span style="color: #75715e">' Código PHC GO – VB.NET
Function OnSyncDelete(masterVO As U0000_AlbumVO,
changedItems As List(Of EntityChangeOperation)) As List(Of MessageVO)
Este evento é executado sempre que ocorre a eliminação de registos em qualquer tipo de
coleção. Durante a sua execução, o parâmetro changedItems contém todos os registos
eliminados da respetiva coleção. Embora o frontend não envie diretamente estes registos, eles
são recuperados da cache existente no backend.
Como os registos foram eliminados, e não modificados, não há necessidade de utilizar as
funções de extensão anteriormente descritas. A única ação requerida é percorrer a lista de
registos e aceder aos seus valores para realizar a operação desejada.
Exemplo de utilização:
Se a operação pretendida for uma validação que determine que o registo não pode ser
eliminado, deve-se alterar a propriedade Operation para None. Esta ação impede que o registo
seja removido, mantendo-o na cache do backend e devolvendo-o ao frontend.
Caso seja permitido eliminar o registo, não é necessário efetuar qualquer modificação, uma vez
que este já está marcado com a propriedade Operation = Deleted.
span style="color: #75715e">' Código PHC GO – VB.NET
Function OnSyncDelete(masterVO As U0000_AlbumVO,
changedItems As List(Of EntityChangeOperation)) As List(Of MessageVO)
' result
Dim listMsg As New List(Of MessageVO)
' what type was changed?
Select Case changedItems.First.baseType
' was it the music collection?
Case GetType(u0000_MusicaVO)
' deleted item - option 1
For Each musicItem in (From pk In changedItems Select DirectCast(pk.entity, FiVO))
' option 1
If musicItem.nome.EqualsWithIgnoreCase() = "Not Deleted"
listMsg.add(new MsgError("You can't delete this song"))
End If
' option 2
If musicItem.nome.ToLower() = "not deleted"
listMsg.add(new MsgError("You can't delete this song"))
End If
' option 3
If musicItem.nome.ToUpper() = "NOT DELETED"
listMsg.add(new MsgError("You can't delete this song"))
End If
' option 4
Select Case musicItem.nome.ToUpper()
Case "NOT DELETED"
listMsg.add(new MsgError("You can't delete this song"))
Case Else
listMsg.add(new MsgInfo("you deleted the song: " + musicItem.nome))
End Select
Next
' deleted item - option 2
For Each changeItem in changedItems
Dim musicItem as u0000_MusicaVO = DirectCast(changeItem.entity, FiVO)
…
Next
End Select
Return listMsg
End Function
Regras do Utilizador
No PHC CS esta funcionalidade está disponível em: Supervisor – Framework PHC – Regras do
Utilizador, que permite programar uma regra para correr ao gravar ou ao apagar um registo
numa determinada entidade.
É semelhante aos eventos, nos ecrãs de PHC CS, Evento Gravar (Check), Evento Gravar, Evento
Apagar (Check) e Evento Apagar, na aplicação PHC GO como já referenciado estes momentos
são mapeados para as regras de negócio do tipo Ao Gravar e Ao Apagar.
Portanto o código programado nesta opção do PHC CS deve ser migrado para os respetivos
eventos do PHC GO.
Bibliotecas de Servidor
No PHC CS, existe uma funcionalidade acessível através de: Supervisor - Framework PHC -
Funções de Utilizador. Esta funcionalidade permite criar e gerir diversas funções
personalizadas, constituindo uma biblioteca de funções utilitárias que podem ser reutilizadas
na programação das restantes funcionalidades da framework.
No PHC GO, a funcionalidade equivalente encontra-se acessível através de: GO Studio -
Toolbox - Bibliotecas de Servidor. Esta ferramenta permite não só criar funções utilitárias,
como também organizá-las em classes que agrupam funcionalidades específicas.
Principais características:
- Organização em Classes: As funções podem ser agrupadas em classes para facilitar a
organização e a reutilização de código, promovendo uma estrutura mais limpa e
eficiente.
- Namespace exclusivo: Todas as classes e funções residem no espaço de utilizador
u0000_Space, sendo que cada desenvolvedor de Add-Ons tem o seu próprio
namespace exclusivo.
- Este isolamento elimina colisões de nomes entre funções ou classes criadas por
diferentes desenvolvedores, bem como com as funções nativas da aplicação PHC GO.
- Reutilização segura: O namespace individual garante que cada conjunto de
funcionalidades personalizadas pode ser implementado sem interferir com outros AddOns ou com a aplicação base.
As bibliotecas de utilizador são especialmente úteis para:
- Centralizar lógica comum que pode ser invocada em diferentes contextos.
- Reduzir redundância no código, promovendo uma manutenção mais simples e
eficiente
- Implementar cálculos, validações ou outras operações específicas de forma consistente
em toda a aplicação.
Esta biblioteca torna-se uma ferramenta poderosa para personalizar e estender as
funcionalidades da framework PHC GO, adaptando-a às necessidades específicas de cada
cliente ou projeto.
Eventos do Utilizador
No PHC CS esta funcionalidade está disponível em: Supervisor – Framework PHC – Eventos do
Utilizador, que permite programar um evento para um determinado ecrã.
Na aplicação PHC GO, esta funcionalidade é suportada nas: Bibliotecas de Servidor, onde a
classe criada deve herdar da classe nativa da aplicação: EntityEvents.
Esta classe suporta os eventos do PHC CS: Introduzir, Alterar, Apagar e Consultar, e
disponibiliza outros existentes na aplicação PHC GO.
No caso do PHC GO, o código aqui programado é totalmente de backend e, consoante o evento
escutado, pode funcionar:
- Sincronamente: Neste modo, é possível cancelar a ação original através de mensagens
de erro.
- Assincronamente: O evento corre num thread separado, sem impactar a performance
da operação.
Quando o evento é executado de forma assíncrona, não existe qualquer meio de retornar
feedback para o utilizador através de mensagens. Por esse motivo, também não é possível
cancelar a ação original.
Esta classe escuta eventos com origem no frontend ou no backend. Por exemplo, através de
código de backend, numa outra funcionalidade da framework, pode-se criar um registo numa
entidade. Como a classe EntityEvents está permanentemente a escutar eventos que ocorrem
no backend, o código desta classe será executado também nesse contexto.
Outra característica da classe EntityEvents é a sua capacidade de escutar eventos de todas as
entidades existentes na aplicação. Em cada função, é possível identificar o tipo de entidade
que acionou o evento e atuar de forma adequada, conforme a lógica necessária.
Public Class EntityEvents
Inherits Pnp
#Region "Business"
Public Overridable Sub OnAdding(itemVO As BusinessVO,
duplicating As Boolean,
lstMsg As List(Of MessageVO))
End Sub
Public Overridable Sub OnDuplicating(itemVO As BusinessVO,
lstMsg As List(Of MessageVO))
End Sub
Public Overridable Sub OnFromReference(itemVO As BusinessVO,
oriItemVO As Object,
valuesItem As InstanceFromReference,
lstMsg As List(Of MessageVO))
End Sub
Public Overridable Sub OnEditing(itemVO As BusinessVO,
runWarningRules As Boolean,
lstMsg As List(Of MessageVO))
End Sub
Public Overridable Sub OnDelete(itemVO As BusinessVO,
runWarningRules As Boolean,
lstMsg As List(Of MessageVO))
End Sub
Public Overridable Sub OnSave(itemVO As BusinessVO,
runWarningRules As Boolean,
lstMsg As List(Of MessageVO))
End Sub
Public Overridable Sub OnAfterSave(itemVO As BusinessVO,
triggersVOs As List(Of BusinessVO))
End Sub
Public Overridable Sub OnRequery(itemVO As BusinessVO)
End Sub
Public Overridable Sub OnAction(entityType As Type,
actionItem As ActionVO,
filter As ActionFilterVO,
recordItem As BusinessVO)
End Sub
#End Region
#Region "SlVO"
Public Overridable Sub OnSlUpdate(slMovements As List(Of SlVO))
End Sub
#End Region
End Class
A classe monitoriza os eventos mencionados anteriormente, funcionando da seguinte forma:
no arranque do backend da aplicação, é construída uma lista interna com todas as classes que
herdam de EntityEvents (Inherits EntityEvents), sejam elas classes nativas do PHC GO ou
criadas por Add-Ons instalados.
Por exemplo, quando ocorre o evento: Ao Introduzir, a aplicação percorre essa lista, inicializa
cada uma das classes, e verifica se estas contêm o método correspondente ao evento em
questão, devidamente marcado como: Overrides.
Caso o método exista, o respetivo código é executado. Após a execução, a instância da classe é
enviada para o garbage collector, garantindo a sua destruição e libertação de recursos da
aplicação.
Deste modo, o programador apenas precisa de criar a classe e implementar o Overrides
apenas nos eventos desejados. A partir daí, é a própria aplicação PHC GO que se encarrega de
monitorizar os eventos base, instanciar as classes, executar o código e finalizar o processo
automaticamente.
Esta classe utiliza a técnica de plug and play (Inherits Pnp), permitindo ao programador
centralizar o seu código de inicialização e finalização. Para isso, pode usar o método Pluging
para executar o código de inicialização e o método UnPluging para o código de finalização.
Desta forma, este tipo de lógica fica concentrado num único local, evitando repetições no início
e no final de cada método marcado como Overrides.
Public Class Pnp
#Region "Methods"
Public Overridable Function Pluging() As Boolean
Return True
End Function
Public Overridable Sub UnPluging()
End Sub
#End Region
End Class
Por exemplo, podemos verificar se a instalação onde o Add-On está a ser executado, está numa
edição superior ou igual a: Advanced, utilizando a função do SDK de backend para esse fim.
Este código é fornecido a título de exemplo, já que na construção dos Add-Ons se pode
configurar estes requisitos mínimos para que o Add-On possa ser instalado numa aplicação
PHC GO do cliente final.
Public Class MyEntityEvents
Inherits EntityEvents
#Region "Pnp"
Public Overrides Function Pluging() As Boolean
Return SDK.System.IsEditionAvailable(Gamas.Advanced)
End Function
#End Region
End Class
EntityEvents - Ao Introduzir
Public Class MyEntityEvents
Inherits EntityEvents
''' <summary>
''' Occurs when the process of creating a record of a new entity is started,
''' this moment also occurs when duplicating an existing record in the database,
''' since duplication is understood as a creation,
''' with the difference that certain values of the registration
''' are already filled out.
''' </summary>
'''
''' <para name="itemVO">
''' It is the new instance to be created in the database.
''' </para>
'''
''' <para name="duplicating">
''' Indicates whether we are in the presence of a duplication or not.
''' </para>
'''
''' <para name="lstMsg">
''' If we want to cancel the operation in progress, we must add an error
''' message to this parameter,
''' if instead of the type of error, we add an information message for example,
''' the operation will continue to execute and the message will be shown
''' in the frontend to the user who triggered it the operation
''' </para>
'''
''' <remarks>
''' This event is synchronous type
''' </remarks>
Public Overrides Sub OnAdding(itemVO As BusinessVO,
duplicating As Boolean,
lstMsg As List(Of MessageVO))
' option 1
Select Case itemVO.GetType
Case GetType(u4902_AlbumVO)
Case GetType(u0000_SingerVO)
End Select
' option 2
If TypeOf itemVO Is u4902_AlbumVO Then
End If
End Sub
End Class
EntityEvents – Ao Introduzir com Referência
Public Class MyEntityEvents
Inherits EntityEvents
''' <remarks>
''' This event is synchronous type
''' </remarks>
Public Overrides Sub OnFromReference(itemVO As BusinessVO,
oriItemVO As Object,
valuesItem As InstanceFromReference,
lstMsg As List(Of MessageVO))
' option 1
Select Case itemVO.GetType
Case GetType(u4902_AlbumVO)
Case GetType(u0000_SingerVO)
End Select
' option 2
If TypeOf itemVO Is u4902_AlbumVO Then
End If
End Sub
End Class
EntityEvents – Ao Duplicar
Public Class MyEntityEvents
Inherits EntityEvents
''' <summary>
''' Occurs when the process of duplicate a record from an existing entity is started.
''' </summary>
'''
''' <para name="itemVO">
''' It is the new instance to be created in the database,
''' with the values filled in from the record already existing in the database
''' from which the duplication operation was started
''' </para>
'''
''' <para name="lstMsg">
''' If we want to cancel the operation in progress, we must add an error
''' message to this parameter,
''' if instead of the type of error, we add an information message for example,
''' the operation will continue to execute and the message will be shown
''' in the frontend to the user who triggered it the operation
''' </para>
'''
''' <remarks>
''' This event is synchronous type
''' </remarks>
Public Overrides Sub OnDuplicating(itemVO As BusinessVO,
lstMsg As List(Of MessageVO))
' option 1
Select Case itemVO.GetType
Case GetType(u4902_AlbumVO)
Case GetType(u0000_SingerVO)
End Select
' option 2
If TypeOf itemVO Is u4902_AlbumVO Then
End If
End Sub
End Class
EntityEvents – Ao Alterar
Public Class MyEntityEvents
Inherits EntityEvents
''' <summary>
''' Occurs when the process of change a record from an existing entity is started.
''' </summary>
'''
''' <para name="itemVO">
''' It is the record of the entity in the database from which the
''' change operation was started.
''' </para>
'''
''' <para name="runWarningRules">
''' Indicates whether we want to run warning type rules, which are
''' shown in the frontend as a yes or no question.
''' </para>
'''
''' <para name="lstMsg">
''' If we want to cancel the operation in progress, we must add an error
''' message to this parameter,
''' if instead of the type of error, we add an information message for example,
''' the operation will continue to execute and the message will be shown
''' in the frontend to the user who triggered it the operation
''' </para>
'''
''' <remarks>
''' This event is synchronous type
''' </remarks>
Public Overrides Sub OnEditing(itemVO As BusinessVO,
runWarningRules As Boolean,
lstMsg As List(Of MessageVO))
' option 1
Select Case itemVO.GetType
Case GetType(u4902_AlbumVO)
Case GetType(u0000_SingerVO)
End Select
' option 2
If TypeOf itemVO Is u4902_AlbumVO Then
End If
End Sub
End Class
EntityEvents – Ao Apagar
Public Class MyEntityEvents
Inherits EntityEvents
''' <summary>
''' Occurs when the process of delete a record from an existing entity is started.
''' </summary>
'''
''' <para name="itemVO">
''' It is the record of the entity in the database from which the
''' delete operation was started.
''' </para>
'''
''' <para name="runWarningRules">
''' Indicates whether we want to run warning type rules, which are shown
''' in the frontend as a yes or no question.
''' </para>
'''
''' <para name="lstMsg">
''' If we want to cancel the operation in progress, we must add an error
''' message to this parameter,
''' if instead of the type of error, we add an information message for example,
''' the operation will continue to execute and the message will be shown
''' in the frontend to the user who triggered it the operation
''' </para>
'''
''' <remarks>
''' This event is synchronous type
''' </remarks>
Public Overrides Sub OnDelete(itemVO As BusinessVO,
runWarningRules As Boolean,
lstMsg As List(Of MessageVO))
' option 1
Select Case itemVO.GetType
Case GetType(u4902_AlbumVO)
Case GetType(u0000_SingerVO)
End Select
' option 2
If TypeOf itemVO Is u4902_AlbumVO Then
End If
End Sub
End Class
EntityEvents – Ao Gravar
Public Class MyEntityEvents
Inherits EntityEvents
''' <summary>
''' Occurs when the process of save a record from an entity is started,
''' the result of this operation may be the creation of a new entity in the database
''' or the updating of some values of an entity that already exists in the database.
''' </summary>
''' <para name="itemVO">
''' It is the record of the entity in the database from which the save
''' operation was started.
''' </para>
'''
''' <para name="runWarningRules">
''' Indicates whether we want to run warning type rules, which are shown
''' in the frontend as a yes or no question.
''' </para>
''' <para name="lstMsg">
''' If we want to cancel the operation in progress, we must add an error
''' message to this parameter,
''' if instead of the type of error, we add an information message for example,
''' the operation will continue to execute and the message will be shown
''' in the frontend to the user who triggered it the operation
''' </para>
''' <remarks>
''' This event is synchronous type
''' </remarks>
Public Overrides Sub OnSave(itemVO As BusinessVO,
runWarningRules As Boolean,
lstMsg As List(Of MessageVO))
' option 1
Select Case itemVO.GetType
Case GetType(u4902_AlbumVO)
Case GetType(u0000_SingerVO)
End Select
' option 2
If TypeOf itemVO Is u4902_AlbumVO Then
End If
End Sub
End Class
EntityEvents – Após Gravar
Public Class MyEntityEvents
Inherits EntityEvents
''' <summary>
''' Occurs after a Insert, Update or Delete operation has been
''' successfully performed on the database.
''' </summary>
'''
''' <para name="itemVO">
''' It is the record of the entity in the database from which
''' the operation was finished,
''' the Operation property of itemVO indicates what kind
''' of previous operation happened,
''' Insert, Update or Delete
''' </para>
'''
''' <para name="triggersVOs">
''' These are the records that were created or modified in the triggers
''' the Operation property of itemVO indicates what kind
''' of previous operation happened,
''' Insert, Update or Delete
''' </para>
'''
''' <remarks>
''' This event is asynchronous type
'''
''' The reason for this is to gain performance on the
''' operation performed previously in the database.
''' </remarks>
Public Overrides Sub OnAfterSave(itemVO As BusinessVO,
triggersVOs As List(Of BusinessVO))
' option 1
Select Case itemVO.GetType
Case GetType(u4902_AlbumVO)
Case GetType(u0000_SingerVO)
End Select
' option 2
If TypeOf itemVO Is u4902_AlbumVO Then
End If
End Sub
End Class
Public Class MyEntityEvents
Inherits EntityEvents
''' <summary>
''' Occurs after a Query operation, from frontend, has executed on the database.
''' </summary>
'''
''' <remarks>
''' This event is synchronous type
''' </remarks>
Public Overrides Sub OnRequery(itemVO As BusinessVO)
' option 1
Select Case itemVO.GetType
Case GetType(u4902_AlbumVO)
Case GetType(u0000_SingerVO)
End Select
' option 2
If TypeOf itemVO Is u4902_AlbumVO Then
End If
End Sub
End Class
EntityEvents – Ao executar Ação
Public Class MyEntityEvents
Inherits EntityEvents
''' <summary>
''' Occurs after a Action operation has executed on the entity.
''' </summary>
'''
''' <remarks>
''' This event is synchronous type
''' </remarks>
Public Overridable Sub OnAction(entityType As Type,
actionItem As ActionVO,
filter As ActionFilterVO,
recordItem As BusinessVO)
' option 1
Select Case itemVO.GetType
Case GetType(u4902_AlbumVO)
Case GetType(u0000_SingerVO)
End Select
' option 2
If TypeOf itemVO Is u4902_AlbumVO Then
End If
End Sub
End Class
EntityEvents – Ao atualizar Stock
Public Class MyEntityEvents
Inherits EntityEvents
''' <summary>
''' Occurs after an update of stock movements (SlVO)
''' which normally occurs in an asynchronous process after
''' saving a document that moves stocks.
''' </summary>
'''
''' <para name="slMovements">
''' Is the list of records of type SlVO that were updated in this process,
''' note that the Operation property of the record is always equal to (0) - None,
''' it is not possible to know in this event if the stock movement
''' was created or updated, we only have access to the current values
''' recorded in the database.
''' </para>
'''
''' <remarks>
''' This event is asynchronous type.
''' </remarks>
Public Overrides Sub OnSlUpdate(slMovements As List(Of SlVO))
End Sub
End Class