No artigo de hoje, vamos demonstrar em como substituir o bloco bCommit com um InstallEvent.
Ao passar os códigos pelo Code Analysis, os fontes em MVC que possuem o bloco de código no Commit das operações é acusado de que isso não é recomendado.
Até podemos criar um ponto de entrada com o nome do MPFormModel e usar os pontos MODELCOMMITTTS ou MODELCOMMITNTTS.
Mas a intenção desse artigo é demonstrar em como utilizar o recurso InstallEvent, que é o recomendado pela TOTVS.
Primeiro, iremos ver, como que esta o fonte de forma original, usando o bCommit:
//Bibliotecas #Include "Totvs.ch" #Include "FWMVCDef.ch" //Variveis Estaticas Static cTitulo := "Artistas (com Commit Manual)" Static cAliasMVC := "ZD1" /*/{Protheus.doc} User Function zMVC01b Cadastro de Artistas @author Daniel Atilio @since 21/01/2022 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ User Function zMVC01b() Local aArea := GetArea() Local oBrowse Private aRotina := {} //Definicao do menu aRotina := MenuDef() //Instanciando o browse oBrowse := FWMBrowse():New() oBrowse:SetAlias(cAliasMVC) oBrowse:SetDescription(cTitulo) oBrowse:DisableDetails() //Ativa a Browse oBrowse:Activate() RestArea(aArea) Return Nil /*/{Protheus.doc} MenuDef Menu de opcoes na funcao zMVC01b @author Daniel Atilio @since 21/01/2022 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function MenuDef() Local aRotina := {} //Adicionando opcoes do menu ADD OPTION aRotina TITLE "Visualizar" ACTION "VIEWDEF.zMVC01b" OPERATION 1 ACCESS 0 ADD OPTION aRotina TITLE "Incluir" ACTION "VIEWDEF.zMVC01b" OPERATION 3 ACCESS 0 ADD OPTION aRotina TITLE "Alterar" ACTION "VIEWDEF.zMVC01b" OPERATION 4 ACCESS 0 ADD OPTION aRotina TITLE "Excluir" ACTION "VIEWDEF.zMVC01b" OPERATION 5 ACCESS 0 Return aRotina /*/{Protheus.doc} ModelDef Modelo de dados na funcao zMVC01b @author Daniel Atilio @since 21/01/2022 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function ModelDef() Local oStruct := FWFormStruct(1, cAliasMVC) Local oModel Local bPre := Nil Local bPos := Nil Local bCommit := {|| fFazCommit()} Local bCancel := Nil //Cria o modelo de dados para cadastro oModel := MPFormModel():New("zMVC01bM", bPre, bPos, bCommit, bCancel) oModel:AddFields("ZD1MASTER", /*cOwner*/, oStruct) oModel:SetDescription("Modelo de dados - " + cTitulo) oModel:GetModel("ZD1MASTER"):SetDescription( "Dados de - " + cTitulo) oModel:SetPrimaryKey({}) Return oModel /*/{Protheus.doc} ViewDef Visualizacao de dados na funcao zMVC01b @author Daniel Atilio @since 21/01/2022 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function ViewDef() Local oModel := FWLoadModel("zMVC01b") Local oStruct := FWFormStruct(2, cAliasMVC) Local oView //Cria a visualizacao do cadastro oView := FWFormView():New() oView:SetModel(oModel) oView:AddField("VIEW_ZD1", oStruct, "ZD1MASTER") oView:CreateHorizontalBox("TELA" , 100 ) oView:SetOwnerView("VIEW_ZD1", "TELA") Return oView Static Function fFazCommit() Local aArea := FWGetArea() Local oModel := FWModelActive() Local lRet := .T. //Aqui você pode fazer as operações antes de gravar //Aciona o commit dos dados preenchidos no formulário FWFormCommit(oModel) //Aqui você pode fazer as operações após gravar //Exibe uma mensagem, caso não esteja sendo executado via job ou ws If ! IsBlind() ShowLog("Passei pelo Commit de forma manual (antiga)") EndIf FWRestArea(aArea) Return lRet
Notaram que no ModelDef tem um bloco bCommit com uma função chamada fFazCommit.
Agora como podemos adaptar isso sem utilizar mais esse bloco? Abaixo iremos detalhar o procedimento.
O primeiro passo é no fonte em MVC, remover o bCommit, remover a função fFazCommit, e no seu ModelDef adicionar o método InstallEvent apontando para uma classe customizada (aqui chamamos ela de zSuaClasse).
//Bibliotecas #Include "Totvs.ch" #Include "FWMVCDef.ch" //Variveis Estaticas Static cTitulo := "Artistas (com FWModelEvent)" Static cAliasMVC := "ZD1" /*/{Protheus.doc} User Function zMVC01c Cadastro de Artistas @author Daniel Atilio @since 21/01/2022 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ User Function zMVC01c() Local aArea := GetArea() Local oBrowse Private aRotina := {} //Definicao do menu aRotina := MenuDef() //Instanciando o browse oBrowse := FWMBrowse():New() oBrowse:SetAlias(cAliasMVC) oBrowse:SetDescription(cTitulo) oBrowse:DisableDetails() //Ativa a Browse oBrowse:Activate() RestArea(aArea) Return Nil /*/{Protheus.doc} MenuDef Menu de opcoes na funcao zMVC01c @author Daniel Atilio @since 21/01/2022 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function MenuDef() Local aRotina := {} //Adicionando opcoes do menu ADD OPTION aRotina TITLE "Visualizar" ACTION "VIEWDEF.zMVC01c" OPERATION 1 ACCESS 0 ADD OPTION aRotina TITLE "Incluir" ACTION "VIEWDEF.zMVC01c" OPERATION 3 ACCESS 0 ADD OPTION aRotina TITLE "Alterar" ACTION "VIEWDEF.zMVC01c" OPERATION 4 ACCESS 0 ADD OPTION aRotina TITLE "Excluir" ACTION "VIEWDEF.zMVC01c" OPERATION 5 ACCESS 0 Return aRotina /*/{Protheus.doc} ModelDef Modelo de dados na funcao zMVC01c @author Daniel Atilio @since 21/01/2022 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function ModelDef() Local oStruct := FWFormStruct(1, cAliasMVC) Local oModel Local bPre := Nil Local bPos := Nil Local bCommit := Nil Local bCancel := Nil //Cria o modelo de dados para cadastro oModel := MPFormModel():New("zMVC01cM", bPre, bPos, bCommit, bCancel) oModel:AddFields("ZD1MASTER", /*cOwner*/, oStruct) oModel:SetDescription("Modelo de dados - " + cTitulo) oModel:GetModel("ZD1MASTER"):SetDescription( "Dados de - " + cTitulo) oModel:SetPrimaryKey({}) //Instala um evento no modelo de dados que irá ficar "observando" as alterações do formulário oModel:InstallEvent("VLD_ARTISTA", , zClassArtistas():New(oModel)) Return oModel /*/{Protheus.doc} ViewDef Visualizacao de dados na funcao zMVC01c @author Daniel Atilio @since 21/01/2022 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function ViewDef() Local oModel := FWLoadModel("zMVC01c") Local oStruct := FWFormStruct(2, cAliasMVC) Local oView //Cria a visualizacao do cadastro oView := FWFormView():New() oView:SetModel(oModel) oView:AddField("VIEW_ZD1", oStruct, "ZD1MASTER") oView:CreateHorizontalBox("TELA" , 100 ) oView:SetOwnerView("VIEW_ZD1", "TELA") Return oView
Agora iremos criar a classe herdando a FWModelEvent, sendo que nessa classe teremos o construtor e os métodos para antes, durante e após o commit.
//Bibliotecas #Include "TOTVS.ch" /*/{Protheus.doc} zClassArtistas Declara a Classe vinda da FWModelEvent e os métodos que serão utilizados @author Atilio @since 27/01/2023 @version version @see https://tdn.totvs.com/pages/releaseview.action?pageId=269552294 /*/ Class zClassArtistas From FWModelEvent Method New() CONSTRUCTOR Method BeforeTTS() Method InTTS() Method AfterTTS() EndClass /*/{Protheus.doc} New Método para "instanciar" um observador @author Atilio @since 27/01/2023 @version version @param oModel, Objeto, Objeto instanciado do Modelo de Dados /*/ Method New(oModel) CLASS zClassArtistas Return /*/{Protheus.doc} BeforeTTS Método acionado antes de fazer as gravações da transação @author Atilio @since 27/01/2023 @version version @param oModel, Objeto, Objeto instanciado do Modelo de Dados /*/ Method BeforeTTS(oModel) Class zClassArtistas //Aqui você pode fazer as operações antes de gravar Return /*/{Protheus.doc} InTTS Método acionado durante as gravações da transação @author Atilio @since 27/01/2023 @version version @param oModel, Objeto, Objeto instanciado do Modelo de Dados /*/ Method InTTS(oModel) Class zClassArtistas //Aqui você pode fazer as durante a gravação (como alterar campos) Return /*/{Protheus.doc} AfterTTS Método acionado após as gravações da transação @author Atilio @since 27/01/2023 @version version @param oModel, Objeto, Objeto instanciado do Modelo de Dados /*/ Method AfterTTS(oModel) Class zClassArtistas //Aqui você pode fazer as operações após gravar //Exibe uma mensagem, caso não esteja sendo executado via job ou ws If ! IsBlind() ShowLog("Passei pelo Commit de forma nova (FWModelEvent)") EndIf Return
Referências:
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Bom dia e parabéns pelo trabalho!
Opa, nós que agradecemos pelo comentário Everson.
Forte abraço.
Existem várias formas de fazer algo no desenvolvimento. Essa forma para dar manutenção foi matadora. Agora, se você vai escrever uma tela MVC nova, acredito que o modelo mais adequado seja de escrever a tela e o ponto de entrada.
Opa, obrigado pelo comentário e adendo João.
Apesar de fazer o ponto de entrada ser mais fácil e simples, até inclusive eu cito isso no terceiro parágrafo (“Até podemos criar um ponto de entrada com o nome do MPFormModel e usar os pontos MODELCOMMITTTS ou MODELCOMMITNTTS.”).
Acontece que ao passar um fonte no code analysis, quando se usa o bCommit, a TOTVS indica a substituição pela interceptação com o InstallEvent ( https://tdn.totvs.com/pages/releaseview.action?pageId=269552294 ), ai por isso a montagem desse artigo de exemplo.
Um grande abraço.
Sempre aprendo com suas publicações!!
Opa, obrigado pelo comentário e feedback Ana. É bondade sua.
Grande abraço.
No exemplo serão chamados todos os eventos e eu tenho que ver se é pra executar algo? Ou como que coloco para chamar um método especifico após certa ação do usuário?
Boa tarde Alexandre, tudo joia?
No fonte original, note que tem um trecho das linhas 110 até 128, onde pode ter tratativas antes, durante e após o commit.
Então na classe que você for criar, ela terá também os 3 métodos, o antes (BeforeTTS), o durante (o InTTS) e o depois (AfterTTS).
Ai você transporta suas customizações para esses métodos (igual fizemos no exemplo com o AfterTTS).
Agora no caso, se você quiser apenas o AfterTTS, ai você ignorar os outros, e nem precisa criar eles dentro do seu fonte que terá a classe.
Grande abraço.