Páginas filhas
  • Interceptação do Commit e Validação MVC - FWModelEvent

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

Conceito

Nesse artigo é apresentado o novo recurso para interceptação do commit do modelo MVC, permitindo uma melhor separação das operações pós gravação de modelo ( integrações com o ERP por exemplo), além de permitir o reuso dessa operações em localizações de formulários MVC.

Sobrescrevendo o bloco de Commit.

Atualmente quando é preciso realizar outras operações além da gravação do modelo no Commit do MVC (contabilização, integração fiscal, financeira e etc.) são utilizados os seguintes passos:

  • Criação do bloco de commit.
  • Dentro da função do bloco é executada a função FWFormCommit, para persistir o modelo.
  • Abre as tabelas do modelo e executa a leitura (novamente) do modelo, executando as operações de integração

 

Bloco de código
languagecpp
themeEclipse
firstline1
titleExemplo bloco de commit
linenumberstrue
collapsetrue
//-------------------------------------------------------------------
/*/{Protheus.doc} ModelDef
Definição do modelo de Dados
@author alvaro.camillo
@since 05/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Static Function ModelDef()
Local oModel
Local oStr1		:= FWFormStruct(1,'ZC3')
Local oStr2		:= FWFormStruct(1,'ZC4')
//Bloco a ser executado no Commit
Local bCommit	:= {|oModel| MLOC003Com(oModel) }
oModel := MPFormModel():New('MLOC003Old', /*bPre*/, /*bPost*/, bCommit, /*bCancel*/)
oModel:SetDescription('Pedidos')
oModel:addFields('ZC3MASTER',,oStr1)
oModel:addGrid('ZC4DETAIL','ZC3MASTER',oStr2)
oModel:SetRelation('ZC4DETAIL', { { 'ZC4_FILIAL', 'xFilial("ZC4")' }, { 'ZC4_COD', 'ZC3_COD' } }, ZC4->(IndexKey(1)) )
Return oModel
 
//-------------------------------------------------------------------
/*/{Protheus.doc} MLOC003Com
Função de Commit
@author alvaro.camillo
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Static Function MLOC003Com(oModel)
Local cPadrao 		:= "005" 						// Lançamento padrão a ser configurado no CT5
Local nTotal 		:= 0 							//  Variável totalizadora da contabilizacao
Local aFlagCTB		:= {} 							// Array com as informações para a gravação do flag de contabilização do registro
Local nHdlPrv		:= 0 							// Handle (numero do arquivo de trabalho) utilizado na contabilizacao
Local cLote	  		:= LoteCont("FIN")				// Lote Contábil do lançamento, cada módulo tem o seu e está configurado na tabela 09 do SX5
Local cArquivo		:= "" 							// Arquivo temporario usado para contabilizacao
Local lMostra		:= .T. 							// Verifica se mostra ou nao tela de contabilização
Local lAglutina 	:= .F. 							// Verifica se aglutina lançamentos com as mesmas entidades contábeis
Begin Transaction
FWFormCommit( oModel )
// Função que verifica se o lançamento padrão foi configurado pelo cliente 
If VerPadrao(cPadrao)
	// Rotina que abre o capa do lote contábil ( Inicio da Contabilização)
	nHdlPrv := HeadProva(cLote,FunName(),Substr(cUsername,1,6),@cArquivo)
EndIf
ZC4->(dbSetOrder(1))//ZC4_FILIAL+ZC4_COD+ZC4_ITEM
ZC0->(dbSetOrder(1))//ZC0_FILIAL+ZC0_COD+ZC0_LOJA
ZC1->(dbSetOrder(1))//ZC1_FILIAL+ZC1_COD
ZC0->(MsSeek(xFilial("ZC0") + ZC3->(ZC3_CLIENT + ZC3_LOJA) ))
If ZC4->(dbSeek( xFilial("ZC4") + ZC3->ZC3_COD ))
	While ZC4->(!EOF()) .And. ZC4->(ZC4_FILIAL+ZC4_COD) == xFilial("ZC4") + ZC3->ZC3_COD 
		ZC1->(MsSeek(xFilial("ZC4") + ZC4->ZC4_PROD ))
		
		If nHdlPrv > 0  
			aAdd(aFlagCTB,{"ZC4_LA","S","ZC4",ZC4->(Recno()),0,0,0})	
			// Função que interpreta todas as sequencias de lançamento configurada pelo usuário e cria as linhas de lançamento contábil
			// Executada uma vez para cada registro que quer ser contabilizado
			nTotal += DetProva(nHdlPrv,cPadrao,FunName(),cLote,,,,,,,,@aFlagCTB)
		Endif
				
		ZC4->(dbSkip())
	EndDo
	If nHdlPrv > 0 .And. ( nTotal > 0 )
		// Função que fecha o lote contábil
		RodaProva(nHdlPrv, nTotal)         
		// Função que apresenta a tela de contabilização, realiza aglutinação caso necessária e grava o documento contábil ( CT2 )
		cA100Incl(cArquivo,nHdlPrv,3,cLote,lMostra,lAglutina)
	Endif	
EndIf
End Transaction

Return .T.


 

Utilizando o formulário contínuo

Com esse método você pode incluir novos componentes (Grids e Fields) incluindo abaixo dos componentes originais num formulário contínuo como uma página web.

Para isso é preciso configurar o FwFormView com o método SetContinuousForm (FWFormView). 

Importante salientar que a definição dessa propriedade deve ser feita somente no novo formulário. Não é preciso configurar o formulário contínuo no fonte original.

Bloco de código
languagecpp
themeEclipse
firstline1
titleExemplo de herança de interface (formulário continuo)
linenumberstrue
//-------------------------------------------------------------------
/*/{Protheus.doc} ViewDef
Definição do interface
@author alvaro.camillo
@since 05/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Static Function ViewDef()
Local oView	:= FWLoadView("MLOC001")
Local oStr2	:= FWFormStruct(2, 'ZL0')
oStr2:RemoveField( 'ZL0_LOJA' )
oStr2:RemoveField( 'ZL0_COD' )
//Formulário Continuo 
oView:SetContinuousForm(.T.)
oView:AddGrid('FORM3' , oStr2,'ZL0DETAIL') 
//Criação da box com tamanho 00 pois o formulario continuo irá calcular o tamanho da tela. 
oView:CreateHorizontalBox( 'BOXFORM3', 00)
oView:SetOwnerView('FORM3','BOXFORM3')
oView:AddIncrementField('FORM3' , 'ZL0_ITEM' ) 
oView:EnableTitleView('FORM3' , 'Endereço Russo' ) 
Return oView

 

Criando uma nova box (horizontal ou vertical).

Esse método pode ser utilizado quando existe a necessidade de personalizar ainda mais a tela, podendo alterar inclusive a disposição dos componentes da tela.

Porém esse método possui as seguintes desvantagens:

  • O analista precisa conhecer os detalhes da implementação do fonte de origem, pois é preciso saber o nome do painel(box) do fonte original.
  • Porém essa implementação tem limitações como:

    • Uso excessivo de bloco de código com gasto de memória e baixa performance. 
    • É preciso realizar a leitura novamente dos registros para a realização das operações.
    • O controle de transação fica por conta do desenvolvedor.
    • Em um fonte localizado 

    Sobrescrevendo o bloco de Commit.

    Atualmente quando é preciso realizar outras operações além da gravação do modelo no Commit do MVC (contabilização, integração fiscal, financeira e etc.) são utilizados os seguintes passos:

    Caso o mantenedor do fonte de origem resolva mudar a disposição ou refatorar os nomes do elementos, o fonte derivado deverá ser alterado para continuar funcionando.

    Para realizar essa operação, é preciso criar um novo box para o novo componente.É preciso criar sempre um box vertical dentro de um horizontal e vice-versa.

    Nesse ponto é preciso verificar no fonte de origem qual é o ID do box e qual é a sua orientação.

    Bloco de código
    languagecpp
    themeEclipse
    firstline1
    titleExemplo de herança de interface (criando um novo box)
    linenumberstrue
    //------------------------------------------------------------------- /*/{Protheus.doc} ViewDef Definição do interface @author alvaro.camillo @since 05/09/2016 @version 1.0 /*/ //------------------------------------------------------------------- Static Function ViewDef() // Cria um objeto de Modelo de Dados baseado no ModelDef do fonte informado Local oModel := FWLoadModel( 'MLOC001View' ) // Cria a estrutura a ser acrescentada na View Local oStr2 := FWFormStruct(2, 'ZL0') // Inicia a View com uma View ja existente Local oView := FWLoadView("MLOC001") oStr2:RemoveField( 'ZL0_LOJA' ) oStr2:RemoveField( 'ZL0_COD' ) // Altera o Modelo de dados quer será utilizado oView:SetModel( oModel ) // Adiciona no nosso View um controle do tipo grid oView:AddGrid('VIEW_ZL0' , oStr2,'ZL0DETAIL') // É preciso criar sempre um box vertical dentro de um horizontal e vice-versa // como na MLOC001 o box é horizontal, cria-se um vertical primeiro // Box existente na interface original oView:CreateVerticallBox( 'TELANOVA' , 100, 'BOXFORM1' ) // Novos Boxes oView:CreateHorizontalBox( 'SUPERIOR' , 50, 'TELANOVA' ) oView:CreateHorizontalBox( 'INFERIOR' , 50, 'TELANOVA' ) // Relaciona o identificador (ID) da View com o "box" para exibicao oView:SetOwnerView( 'FORM1', 'SUPERIOR' ) oView:SetOwnerView( 'VIEW_ZL0', 'INFERIOR' )   Return oView



    Status do documentoDesenvolvimento
    Data 
    Versão1.0
    Autores

    Alvaro Camillo Neto

    Índice
    Índice
    outlinetrue
    indent10px

    ...