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 e validação do modelo MVC, permitindo uma melhor separação das operações pós gravação de modelo ( integrações com o ERP por exemplo) e validação de modelo, além de permitir o reuso dessas 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
Data Model definition
@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
 
//-oModel:getModel('ZC3MASTER'):SetDescription('Pedido')
oModel:getModel('ZC4DETAIL'):SetDescription('Item do pedido')
oModel:AddCalc( 'Totalizador', 'ZC3MASTER', 'ZC4DETAIL', 'ZC4_TOTAL', 'ZC__TOTALPED', 'SUM', /*bCondition*/, /*bInitValue*/,'Total do Pedido' /*cTitle*/, /*bFormula*/)
Return oModel
 
//-------------------------------------------------------------------
/*/{Protheus.doc} MLOC003Com
Função de Commit
Commit Function
@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 //Standard entries to be configured on CT5
Local nTotal 		:= 0 							//  Variável totalizadora da contabilizacao //Variable with accounting total
Local aFlagCTB		:= {} 							// Array com as informações para a gravação do flag de contabilização do registro//Array with informations for accounting flag record
Local nHdlPrv		:= 0 							// Handle (numero do arquivo de trabalho) utilizado na contabilizacao//Handler (working file number) used on accounting
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 //Temporary file used on accounting
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 
// Function which verify if the accounting entry was configured by customer
If VerPadrao(cPadrao)
	// Rotina que abre o capa do lote contábil ( Inicio da Contabilização)
	// Accounting beginning
	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(// Function which interpret all sequences of the standard entries and creates the accounting entries.
			// Executed once for each record which will be accounted for.
			
			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
		// Function that closes the accounting lot
		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,// Function that shows the account dialog, performs the grouping if needed and records the accounting document ( CT2 )	
		cA100Incl(cArquivo,nHdlPrv,3,cLote,lMostra,lAglutina)
	Endif	
EndIf
End Transaction

Return .T.






 

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 as operações de integração.
  • O controle de transação fica por conta do desenvolvedor.
  • Em um fonte localizado não é possível estender o comportamento do commit, incluindo novas operações. 

O padrão Observer

O Observer é um padrão de projeto de software que define uma dependência um-para-muitos entre objetos de modo que quando um objeto muda o estado, todos seus dependentes são notificados e atualizados automaticamente. Permite que objetos interessados sejam avisados da mudança de estado ou outros eventos ocorrendo num outro objeto.(https://pt.wikipedia.org/wiki/Observer)


O padrão Observer no MVC Protheus - Utilizando a classe FWModelEvent

Em um fomulário MVC esse padrão é aplicado utilizando os seguintes passos:

  • Desenvolver uma classe que herde da classe FWModelEvent.
  • Inscrever um objeto dessa classe no modelo.
 


Desenvolvendo uma classe FWModelEvent

Essa classe será responsável pela a operação que complementa a persistência do modelo e a validação e será chamada toda vez que o formulário onde ele foi inscrito realize o commit ou realize alguma validação

Essa classe deve herdar da classe FWModelEvent e implementar os seguintes métodos:

 

Aviso
Painel
titleNew

Sintaxe

FWModelEvent ():New()-> Objeto FWModelEvent 

 

Descrição

Construtor da classe

 

Painel
titleGetName

Sintaxe

FWModelEvent ():GetName()-> Nome do Objeto

 

Descrição

Nesse método deverá ser retornado o nome do objeto(ID).

Essa informação é utilizada para realizar a troca do evento (ver método ChangeEvent)

 

Importante
  • É possível inscrever mais de um Evento ao formulário, permitindo a separação de comportamentos em classe diferentes ( classe para a contabilização, classe para a integração fiscal e etc)
  • Não é possível executar o bloco de commit e o padrão FwModelEvent ao mesmo tempo, caso aconteça o sistema irá gerar um erro de execução.
  • A função de entrada de um fonte MVC (chamada de menu) da rotina padrão deve ter no máximo 7 caracteres, pois a rotina localizada tem o seu nome somado a sigla do país.
  • Para o filtro de campos funcionar corretamente, na definição da view deve ser utilizada a função FwLoadModel para carregar o modelo. Não utilize ModelDef()

Essa classe deve herdar da classe FWModelEvent e implementar os seguintes métodos:


Painel
titleNew
Painel
titleAfter

Sintaxe

FWModelEvent ():After(oSubModel, cModelId, cAlias, lNewRecord)New()-> Objeto FWModelEvent 


Descrição

Construtor da classe. Método Obrigatório para ser implementado


Painel
titleDestroy

Sintaxe

FWModelEvent ():Destroy()


Descrição

Destrutor da classe
Caso o evento utilize atributos como array,objetos é boa prática o desenvolvedor
limpar esses atributos da memória.

Utilize para limpar atributos que são array ou objetos.

Exemplo

Limpeza de array:

aSize(aArray, 0)

aArray := Nil

Limpeza de objeto

oObject := Nil



 
Painel
titleAfter

Sintaxe

FWModelEvent ():After(oSubModel, cModelId, cAlias, lNewRecord)


Descrição

Método que é chamado pelo MVC quando ocorrer as ações do commit
depois da gravação de cada submodelo (field ou cada linha de uma grid)


Parâmetros


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oSubModel

Objeto

Sub modelo




cModelId

Caracter

Id do submodelo




cAliasCaracter

Alias do submodelo

 

Descrição

Método que é chamado pelo MVC quando ocorrer as ações do commit
depois da gravação de cada submodelo (field ou cada linha de uma grid)

 

Parâmetros

 

Nome

Tipo

Descrição

Default

Obrigatório

Referência

oSubModel

Objeto

Sub modelo

 

 

 

cModelId

Caracter

Id do submodelo

 

 

 

cAliasCaracter

Alias do submodelo

  




lNewRecordLógicoIndica se é um registro novo.
   



 
Painel
titleBefore

Sintaxe

FWModelEvent ():Before(oSubModel, cModelId, cAlias, lNewRecord) 


Descrição

Método que é chamado pelo MVC quando ocorrer as ações do commit
antes da gravação de cada submodelo (field ou cada linha de uma grid)

 


Parâmetros

 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oSubModel

Objeto

Sub modelo

 

 




cModelId

Caracter

Id do submodelo

 

 

 




cAliasCaracter

Alias do submodelo

   




lNewRecordLógicoIndica se é um registro novo.
  
 



 
Painel
titleAfterTTS

Sintaxe

FWModelEvent ():AfterTTS(oModel, cModelId)

 


Descrição

Método que é chamado pelo MVC quando ocorrer as ações do  após a transação.

 

Parâmetros

Esse evento ocorre uma vez no contexto do modelo principal.


Parâmetros 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oModel

Objeto

Modelo principal

 

 




cModelId

Caracter

Id do submodelo

 

 

 




 
Painel
titleBeforeTTS

Sintaxe

FWModelEvent ():BeforeTTS(oModel, cModelId) 


Descrição

Método que é chamado pelo MVC quando ocorrer as ações do commit antes da transação.

 Esse evento ocorre uma vez no contexto do modelo principal.


Parâmetros 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oModel

Objeto

Modelo principal

 

 




cModelId

Caracter

Id do submodelo

 

 

 




Painel
titleInTTS

Sintaxe

FWModelEvent ():InTTS(oModel, cModelId) 


Descrição

Método que é chamado pelo MVC quando ocorrer as ações do commit Após as gravações porém
antes do final da transação.

Esse evento ocorre uma vez no contexto do modelo principal. 


Parâmetros 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oModel

Objeto

Modelo principal

 

 

 




cModelId

Caracter

Id do submodelo

 

 

 




Painel
titleModelPreActivate

Sintaxe

FWModelEvent ():ModelPreActivate(oModel, cModelIdlCopy) -> lOK 


Descrição

Método que é chamado pelo MVC quando ocorrer as ações de pre validação a ativação do Model

 

Parâmetros

.

Esse evento ocorre uma vez no contexto do modelo principal.


Parâmetros 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oModel

Objeto

Modelo principal

 




lCopy

 

 

cModelId

Caracter

Id do submodelo

 

 

Lógico

Informa se o model deve carregar os dados do registro posicionado em operações de inclusão.
Essa opção é usada quando é necessário fazer uma operação de cópia.

 




Painel
titleModelPosDeActivate

Sintaxe

FWModelEvent FWModelEvent (): ModelPosDeActivate(oModel, cModelId) -> lOK 


Descrição

Método que é chamado pelo MVC quando ocorrer as ações de pos validação a desativação do Model.

Esse evento ocorre uma vez no contexto do modelo principal. 


Parâmetros 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oModel

Objeto

Modelo principal

 




   
Painel
title
VldActivate

cModelId

Caracter

Id do submodelo

 

 

 

Painel
titleGridPre

Sintaxe

FWModelEvent (): VldActivate(oModel, cModelId

Sintaxe

FWModelEvent ():GridPre(oSubModel, cModelID, nLine, cAction, cId, xValue, xCurrentValue) -> lOK 


Descrição

Método que é chamado pelo MVC quando ocorrer as ações de pre validação do GridModel.

Esse evento ocorre uma vez no contexto do modelo principal. 


Parâmetros

 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oSubModel

oModel

Objeto

Modelo principal

 

 




cModelIdCaracterId do submodelo
 



  
Painel
title
ModelPreVld
nLineNuméricoLinha do grid   
cActionCaracterAção executada no grid, podendo ser: ADDLINE, UNDELETE, DELETE   
cIdCaracternome do campo   
xValueVariávelNovo valor do campo   
xCurrentValueVariávelValor atual do campo   

Sintaxe

FWModelEvent ():ModelPreVld(oModel, cModelId) -> lOK


Descrição

Método que é chamado pelo MVC quando ocorrer as ações de pre validação do Model

Esse evento ocorre uma vez no contexto do modelo principal.


Parâmetros


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oModel

Objeto

Modelo principal




cModelId

Caracter

Id do submodelo




 
Painel
titleModelPosVld
Painel
titleGridPos

Sintaxe

FWModelEvent ():GridPosModelPosVld(oSubModeloModel, cModelIDcModelId) -> lOK 


Descrição

Método que é chamado pelo MVC quando ocorrer as ações de pós pos validação do Grid

 

Parâmetros

Model

Esse evento ocorre uma vez no contexto do modelo principal.


Parâmetros 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oSubModel

oModel

Objeto

Modelo principal

 

 




cModelId

Caracter

Id do submodelo




Painel
titleGridPosVld

Sintaxe

FWModelEvent ():GridPosVld(oSubModel, cModelID) -> lOK


Descrição

Método que é chamado pelo MVC quando ocorrer as ações de pós validação do Grid


Parâmetros


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oSubModel

Objeto

Modelo principal




cModelId

Caracter

Id do submodelo

 

 

 




Painel
titleGridLinePreGridLinePreVld

Sintaxe

FWModelEvent ():GridLinePreGridLinePreVld(oSubModel, cModelID, nLine, cAction, cId, xValue, xCurrentValue) -> lOK 


Descrição

Método que é chamado pelo MVC quando ocorrer as ações de pre validação da linha do Grid 


Parâmetros

 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oSubModel

Objeto

Modelo principal

 

 

 

nLine




cModelId

Caracter

Id do submodelo

 

 

 




nLine
NuméricoLinha do grid
   



cActionCaracterAção executada no grid, podendo ser:
ADDLINE,
UNDELETE, DELETE, SETVALUE, CANSETVALUE
, ISENABLE
   



cIdCaracternome do campo
   



xValueVariávelNovo valor do campo
   



xCurrentValueVariávelValor atual do campo
   



 
Painel
titleGridLinePosGridLinePosVld

Sintaxe

FWModelEvent ():GridLinePosGridLinePosVld(oSubModel, cModelID, nLine) -> lOK

 


Descrição

Método que é chamado pelo MVC quando ocorrer as ações de pos validação da linha do Grid 


Parâmetros 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oSubModel

Objeto

Modelo principal

 

 




cModelId

Caracter

Id do submodelo

 

 

 




nLineNuméricoLinha do grid
   



Painel
titleFieldPreFieldPreVld

Sintaxe

FWModelEvent ():FieldPreFieldPreVld(oSubModel, cModelID, cAction, cId, xValue) -> lOK 


Descrição

Método que é chamado pelo MVC quando ocorrer a ação de pos pré validação do Field 


Parâmetros 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oSubModel

Objeto

Modelo principal

 

 

 




cModelId

Caracter

Id do submodelo

 

 

 




cActionCaracterAção executada no grid, podendo ser: SETVALUE, CANSETVALUE
 
  



cIdCaracternome do campo
 



xValue
  xValueCaracter
CaracterNovo
Novo
valor do campo
   



 
Painel
titleFieldPosFieldPosVld

Sintaxe

FWModelEvent ():FieldPosFieldPosVld(oSubModel, cModelID) -> lOK

 


Descrição

Método que é chamado pelo MVC quando ocorrer a ação de pre pós validação do Field 


Parâmetros 


Nome

Tipo

Descrição

Default

Obrigatório

Referência

oSubModel

Objeto

Modelo principal

 

 




cModelId

Caracter

Id do submodelo

 




  
Painel
title
GetEvent

Sintaxe

FWModelEvent ():GetEvent(cIdEvent) -> oEvent


Descrição

Método que retorna um evento superior da cadeia de eventos.
Através do método InstallEvent, é possível encadear dois eventos que estão relacionados, como por exemplo um
evento de negócio padrão e um evento localizado que complementa essa regra de negócio.
Caso o evento localizado, necessite de atributos da classe superior, ele irá utilizar esse método para recuperá-lo.


Parâmetros


Nome

Tipo

Descrição

Default

Obrigatório

Referência

cIdEvent

Caracter

Id do Evento Superior.




Bloco de código
languagecpp
themeEclipse
firstline1
titleExemplo de classe FwModelEvent (Simples)
linenumberstrue
collapsetrue
Bloco de código
languagecpp
themeEclipse
firstline1
titleExemplo de classe FwModelEvent (Simples)
linenumberstrue
collapsetrue
#Include 'Protheus.ch'
#Include 'FWMVCDef.ch'
//-------------------------------------------------------------------
/*/{Protheus.doc} ML003PRORUS
Classe interna implementando o ObserverFWModelEvent
Intern doclass Commitinherited para atualização de saldo no produtofrom FWModelEvent.
@author alvaro.camillo
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Class ML003PRORUS FROM FWModelEvent
	Method NewAfter()
	Method AfterNew()
	End Class
Method GetNameNew() Class 
End Class
//-------ML003PRORUS
Return
Method After(oModel, cModelId, cAlias, lNewRecord) Class ML003PRORUS
If cAlias == "ZC4" .And. lNewRecord
	ZL1->(dbSetOrder(1))//ZL1_FILIAL+ZL1_COD
	If ZL1->(MsSeek(xFilial("ZL1") + ZC4->ZC4_PROD ))
		RecLock("ZL1",.F.)
			ZL1->ZL1_QTVEND += ZC4->ZC4_QUANT  
		MsUnLock()
	EndIf
EndIf		
Return



 
Bloco de código
languagecpp
themeEclipse
firstline1
titleExemplo de classe FwModelEvent (Contabilização)
linenumberstrue
collapsetrue
 #Include 'Protheus.ch'
#Include 'FWMVCDef.ch'
//-------------------------------------------------------------------
/*/{Protheus.doc} getName
Retorna um nome unico para esse objetoML003CTB
Classe interna implementando o FWModelEvent
Intern class inherited from FWModelEvent.
@author Rodrigo Antonioalvaro.camillo
@since 06/09/2016
@version P111.80
/*/
//-------------------------------------------------------------------
MethodClass GetName()ML003CTB FROM Class ML003PRORUS
Return "ML003PROCOMMIT"
Method After(oModel, cModelId, cAlias, lNewRecord) Class ML003PRORUS
If cAlias == "ZC4" .And. lNewRecord
	ZL1->(dbSetOrder(1))//ZL1_FILIAL+ZL1_COD
	If ZL1->(MsSeek(xFilial("ZL1") + ZC4->ZC4_PROD ))
		RecLock("ZL1",.F.)
			ZL1->ZL1_QTVEND += ZC4->ZC4_QUANT  
		MsUnLock()
	EndIf
EndIf		
Return
Method new() Class ML003PRORUS
Return


 
Bloco de código
languagecpp
themeEclipse
firstline1
titleExemplo de classe FwModelEvent (Contabilização)
linenumberstrue
collapsetrue
#Include 'Protheus.ch'
#Include 'FWMVCDef.ch'
//-------------------------------------------------------------------
/*/{Protheus.doc} ML003CTB
Classe interna implementando o Observer do Commit
@author alvaro.camillo
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Class ML003CTB FROM FWModelEvent
	DATA cPadrao 							// Lançamento padrão a ser configurado no CT5
	DATA nTotal 							//  Variável totalizadora da contabilizacao
	DATA aFlagCTB							// Array com as informações para a gravação do flag de contabilização do registro
	DATA nHdlPrv							// Handle (numero do arquivo de trabalho) utilizado na contabilizacao
	DATA cLote			
	DATA cArquivo							// Arquivo temporario usado para contabilizacao


	//Métodos sobrescritos da classe FWModelEvent	
	Method new()
	Method After()
	Method AfterTTS()
	Method BeforeTTS()
	Method getName()
	Method ModelPos()
	Method GridLinePre()
	
	//Métodos específicos da classe
	Method openCTB()
	Method closeCTB()
	Method writeLineCTB()
End Class

FWModelEvent
	//Lançamento padrão a ser configurado no CT5
	//Standard entries to be configured on CT5
	DATA cPadrao
	//Variável totalizadora da contabilizacao 
	//Variable with accounting total
	DATA nTotal
	//Array com as informações para a gravação do flag de contabilização do registro 
	//Array with informations for accounting flag record
	DATA aFlagCTB
	//Handle (numero do arquivo de trabalho) utilizado na contabilizacao 
	//Handler (working file number) used on accounting
	DATA nHdlPrv
	//Arquivo temporario usado para contabilizacao  
	//Temporary file used on accounting
	DATA cArquivo
	DATA cLote
	
	Method new()
	Method After()
	Method AfterTTS()
	Method BeforeTTS()
	
	Method ModelPosVld()
	Method GridLinePreVld()
	Method openCTB()
	Method closeCTB()
	Method writeLineCTB()
	
	Method Destroy()
End Class
Method new ()  Class ML003CTB
	self:cPadrao 		:= "005" 						
	self:nTotal 		:= 0 							
	self:aFlagCTB		:= {} 							
	self:nHdlPrv		:= 0 							
	self:cLote			:= ""
	self:cArquivo		:= ""
Return
 
Method Destroy()  Class ML003CTB		
	self:aFlagCTB := aSize(self:aFlagCTB,0)
	self:aFlagCTB := Nil					
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} getName
Retorna um nome unico para esse objeto. BeforeTTS
Inicio da transação com a abertura do lote contabil
Transaction beginning and the oppening of lot accounting
@author Rodrigo Antonio
@version P11.8P12
/*/
//-------------------------------------------------------------------
Method getNameBeforeTTS(oModel, cModelId)  Class ML003CTB
Return "ML003CTBCOMMIT"	self:openCTB(oModel)	
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} BeforeTTSAfter
InicioExecutado daapós transaçãoa com a abertura do lote contabilgravaçao de cada linha para realizar lançamento contábil
Runs after every line recording to execute the accounting entries
@author Rodrigo Antonio
@version P12
/*/
//-------------------------------------------------------------------
Method BeforeTTSAfter(oModel, cModelId, cAlias, lNewRecord)  Class ML003CTB
	self:openCTBwriteLineCTB(oModel)	,cModelId,cAlias,lNewRecord) 
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} AfterAfterTTS
ApósFechamento gravaçao de cada linha para realizar detprovada contabilização.
Accounting closing.
@author Rodrigo Antonio
@version P12
/*/
//-------------------------------------------------------------------
Method AfterAfterTTS(oModel, cModelId, cAlias, lNewRecord)  Class ML003CTB
	self:writeLineCTBcloseCTB(oModel,cModelId,cAlias,lNewRecord)	
Return

//-------------------------------------------------------------------
/*/{Protheus.doc} AfterTTSopenCTB
FechamentoMetodo da contabilização.
@author Rodrigo Antonio
@version P12para ser executado antes da transação para abrir o header de contabilização
Method to be executed before the accounting header openning transaction
@author alvaro.camillo
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Method AfterTTSopenCTB(oModel, cModelId)  Class ML003CTB
	self:closeCTB(oModel)
Return

Method new ()  Class ML003CTB
	self:cPadrao 		:= "005" 						
	self:nTotal//Lançamento padrão a ser configurado no CT5
//Standard entries to be configured on CT5
self:cPadrao 		:= 0 							
	self:aFlagCTB		:= {} 							
	self:nHdlPrv		:= 0 							
	self:cLote			:= ""
	self:cArquivo "005"
//Variável totalizadora da contabilizacao 
//Variable with accounting total
self:nTotal 		:= ""0
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} openCTB
Bloco para ser executado antes da transação para abrir o header de contabilização
@author alvaro.camillo
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Method openCTB(oModel) Class ML003CTB
Local lRet	:= .T. 							
self:cPadrao 		:= "005" 						// Lançamento padrão a ser configurado no CT5
self:nTotal 		:= 0 							//  Variável totalizadora da contabilizacao
self:aFlagCTB		:= {} 							// Array com as informações para a gravação do flag de contabilização do registro
self:nHdlPrv		:= 0 							// Handle (numero do arquivo de trabalho) utilizado na contabilizacao
self:cLote	  		:= LoteCont("FIN")				// Lote Contábil do lançamento, cada módulo tem o seu e está configurado na tabela 09 do SX5
self:cArquivo		:= "" 							// Arquivo temporario usado para contabilizacao
// Função que verifica se o lançamento padrão foi configurado pelo cliente 
If VerPadrao(self:cPadrao)
	// Rotina que abre o capa do lote contábil ( Inicio da Contabilização)//Array com as informações para a gravação do flag de contabilização do registro 
//Array with informations for accounting flag record
self:aFlagCTB		:= {}
//Handle (numero do arquivo de trabalho) utilizado na contabilizacao 
//Handler (working file number) used on accounting
self:nHdlPrv		:= 0
// Lote Contábil do lançamento, cada módulo tem o seu e está configurado na tabela 09 do SX5
//accounting lot. Each model has a corresponding lot configured on the table 09 of SX5 
self:cLote	  		:= LoteCont("FIN")
//Arquivo temporario usado para contabilizacao  
//Temporary file used on accounting
self:cArquivo		:= ""
// Função que verifica se o lançamento padrão foi configurado pelo cliente 
// Function which verify if the accounting entry was configured by customer
If VerPadrao(self:cPadrao)
	// Rotina que abre o lote contábil ( Inicio da Contabilização)
	// Accounting beginning
	self:nHdlPrv := HeadProva(self:cLote,FunName(),Substr(cUsername,1,6),@self:cArquivo)
EndIf
Return lRet
//-------------------------------------------------------------------
/*/{Protheus.doc} writeLineCTB
BlocoMetodo para ser executado depois da gravação.
Method to be executed after the data recording
@author alvaro.camillo
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Method writeLineCTB(oModel,cModelId,cAlias,lNewRecord) Class ML003CTB
	Local lRet aArea:= .T.
Local aArea:= GetArea()
	If cAlias == "ZC4"
		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) ))
		ZC1->(MsSeek(xFilial("ZC4") + ZC4->ZC4_PROD ))
		
		If self:nHdlPrv > 0  
			aAdd(self: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
			// Function which interpret all sequences of the standard entries and creates the accounting entries.
			// Executed once for each record which will be accounted for.
			self:nTotal += DetProva(self:nHdlPrv,self:cPadrao,FunName(),self:cLote,,,,,,,,@self:aFlagCTB)
		Endif
	Endif
	RestArea(aArea)
Return lRet
//-------------------------------------------------------------------
/*/{Protheus.doc} closeCTB
BlocoMetodo para ser executado depois da transação.
@author alvaro.camillo
@since 06/Method to be executed after the transaction.
@author alvaro.camillo
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Method closeCTB(oModel) Class ML003CTB
Local lRet := .T.
Local lMostra	:= .T. 							// Verifica se mostra ou nao tela de contabilização
// Verify if accounting dialog will to be shown
Local lAglutina lMostra	:= .F. 							T.
// Verifica se aglutina lançamentos com as mesmas entidades contábeis
If self:nHdlPrv > 0 .And. ( self// Verify if it's needed to group entries with the same accounting entities'
Local lAglutina := .F.
If self:nHdlPrv > 0 .And. ( self:nTotal > 0 )
	// Função que fecha o lote contábil
	// Function that closes the accounting lot
	RodaProva(self:nHdlPrv, self:nTotal)         
	// Função que apresenta a tela de contabilização, realiza aglutinação caso necessária e grava o documento contábil ( CT2 )
	cA100Incl(self:cArquivo,self:nHdlPrv,3,self:cLote,lMostra,lAglutina)
Endif

Return lRet
//----// Function that shows the account dialog, performs the grouping if needed and records the accounting document ( CT2 )
	cA100Incl(self:cArquivo,self:nHdlPrv,3,self:cLote,lMostra,lAglutina)
Endif
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} ModelPos
BlocoMetodo de pos validação do modelo.
Model post validation method.
@author Guilherme Spadaccia
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Method ModelPosModelPosVld(oModel, cModelId) Class ML003CTB
Local lRet := .T.
lRet := _Super:ModelPos(oModel, cModelId)
//Defino o model que irei validar
If//Define cModelIdwhich == model will be validated
If cModelId == 'MLOC003'
	If oModel:GetValue('ZC3MASTER','ZC3_COD') == "000000"
		lRet := .F.
		//Help("",1,"VALID",,"Ops,Code código000000 000000is reservado!reserved",1,0)
		oModel:SetErrorMessage( , , ,  ,, "Ops, código 000000 reservado!" )
	EndIf
EndIf
Return lRet

//-------------------------------------------------------------------
/*/{Protheus.doc} GridLinePre
BlocoMetodo de pré validação da linha da Grid.
Grid line pre validation method.
@author Guilherme Spadaccia
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Method GridLinePreGridLinePreVld(oSubModel, cModelID, nLine, cAction, cId, xValue, xCurrentValue) Class ML003CTB
Local lRet := .T.
lRet := _Super:GridLinePre(oSubModel, cModelID, nLine, cAction, cId, xValue, xCurrentValue)
If cModelID == "ZC4DETAIL"
	If cAction == "SETVALUE" .And. cId == "ZC4_QUANT"
		If xValue%2 > 0
			lRet := .F.
			//HelpHelp("",1,"VALID",,"Ops,Only pair podemosquantities vender quantidades pares!are accepted",1,0)
			oSubModel:Getmodel():SetErrorMessage( , , ,  ,, "Ops, só podemos vender quantidades pares!" )
		EndIf
	EndIf
EndIf
Return lRet
 
Bloco de código
languagecpp
themeEclipse
firstline1
titleExemplo de classe FwModelEvent herdando de outra classe derivada de outro evento já implementado (Localização)
linenumberstrue
collapsetrue
#Include 'Protheus.ch'
#Include 'FWMVCDef.ch'
//-------------------------------------------------------------------
/*/{Protheus.doc} ML003CTBRUS
Classe interna implementando o Observer do Commit de contabilizacao no padrão Russo FWModelEvent localizando para  padrão Russo
Intern class inherited from FWModelEvent for russian Standard.
@author alvaro.camillo
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Class ML003CTBRUS FROM ML003CTBFWModelEvent
	Method writeLineCTB()
	Method New()
	Method ModelPosAfter()
	Method GridLinePreModelPosVld()
	Method GridLinePreVld()
End Class

Method newNew() Class ML003CTBRUS
	_Super:new()
Return
//-------------------------------------------------------------------
/*/{Protheus.doc} writeLineCTBAfter
BlocoMétodo para ser executado depois da gravação. sobrescrito de ML003CTB
Method to be executed after the data recording
@author alvaro.camillo
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Method writeLineCTBAfter(oModel,cModelId,cAlias,lNewRecord) Class ML003CTBRUS
Local lRet aArea:= .T.GetArea()
Local oEventCtb aArea:= GetArea()
_Super:writeLineCTB(oModel,cModelId,cAlias,lNewRecordself:GetEvent("ML003CTB")
If cAlias == "ZL4"
	If selfoEventCtb:nHdlPrv > 0  
		aAdd(selfoEventCtb:aFlagCTB,{"ZL4_LA","S","ZL4",ZL4->(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
		self:nTotal += DetProva(self:nHdlPrv,"006",// Function which interpret all sequences of the standard entries and creates the accounting entries.
		// Executed once for each record which will be accounted for.
		oEventCtb:nTotal += DetProva(oEventCtb:nHdlPrv,"006",FunName(),selfoEventCtb:cLote,,,,,,,,@self@oEventCtb:aFlagCTB)
	Endif
Endif
RestArea(aArea)
Return lRet
//-------------------------------------------------------------------
/*/{Protheus.doc} ModelPos
BlocoMetodo de pos validação do modelo.
Model Essepost metódo sobrescreve o método da classe ML003CTBvalidation method.
@author Guilherme Spadaccia
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Method ModelPosModelPosVld(oModel, cModelId) Class ML003CTBRUS
Local lRet := .T.
lRet := _Super:ModelPos(oModel, cModelId)
//Defino o model que irei validar
If cModelId == 'MLOC003'
	If oModel:GetValue('ZC3MASTER','ZC3_COD') == "000001"
		lRet := .F.
		//Help("",1,"VALID",,"Ops,Code código 000001 reservadois parareserved ain Russia!.",1,0)
		oModel:SetErrorMessage( , , ,  ,, "Ops, código 000001 reservado para a Russia!" )
	EndIf
EndIf
Return lRet
//-------------------------------------------------------------------
/*/{Protheus.doc} GridLinePre
BlocoMetodo de pré validação da linha da Grid.
Grid Esseline metódopre sobrescreve o método da classe ML003CTBvalidation method.
@author Guilherme Spadaccia
@since 06/09/2016
@version 1.0
/*/
//-------------------------------------------------------------------
Method GridLinePreGridLinePreVld(oSubModel, cModelID, nLine, cAction, cId, xValue, xCurrentValue) Class ML003CTBRUS
Local lRet := .T.
lRetIf cModelID :== _Super:GridLinePre(oSubModel, cModelID, nLine, cAction, cId, xValue, xCurrentValue)
If cModelID == "ZC4DETAIL"
	If cAction == ""ZC4DETAIL"
	If cAction == "SETVALUE" .And. cId == "ZC4_QUANT"
		If xValue > 10
			lRet := .F.
			//Help("",1,"VALID",,"Ops,Only naquantities Russiaunder 10 podemos vender até 10 unidades!are accepted",1,0)
			oSubModel:Getmodel():SetErrorMessage( , , ,  ,, "Ops, na Russia só podemos vender até 10 unidades!" ) 
		EndIf
	EndIf
EndIf
Return lRet

Inscrever um objeto no modelo.

Nessa etapa, no formulário MVC é preciso inscrever o objeto pelo método InstallEvent:

Painel
titleInstallEvent

Sintaxe

MPFormModel():InstallEvent(oEvent)

 

Descrição

Método de inscrição de objeto FwModelEvent

 

Parâmetros

 

Nome

Tipo

Descrição

Default

Obrigatório

Referência

oEvent

Objeto

Objeto que herde da classe FwModelEvent()

 

Sim 

 

Painel
titleChangeEvent

Sintaxe

MPFormModel():ChangeEvent(cName oEvent)

 

Descrição

Método que troca um determinado evento inscrito no modelo

 

Parâmetros

 

Nome

Tipo

Descrição

Default

Obrigatório

Referência

cName CaracterIdentificador da classe Sim 

oEvent

Objeto

Objeto que herde da classe FwModelEvent()

 

Sim

 

 

 

 

InstallEvent:

Painel
titleInstallEvent

Sintaxe

MPFormModel():InstallEvent(cIdEvent, cOwner, oEvent)


Descrição

Método de inscrição de objeto FwModelEvent

Através do método InstallEvent, é possível encadear dois eventos que estão relacionados, como por exemplo um
evento de negócio padrão e um evento localizado que complementa essa regra de negócio.


Parâmetros


Nome

Tipo

Descrição

Default

Obrigatório

Referência

cIdEvent

Carácter

Id do Evento


Sim 


cOwner Carácter Id do Evento Superior
 Não
oEventObjetoEvento do Modelo
Sim
Aviso
titleImportante
  • É possível inscrever mais de um Evento ao formulário, permitindo a separação de comportamentos em classe diferentes ( classe para a contabilização, classe para a integração fiscal e etc)
  • Não é possível executar o bloco de commit e o padrão FwModelEvent ao mesmo tempo, caso aconteça o sistema irá gerar um erro de execução.
  • Para todos os métodos sobrescritos da classe FwModelEvent, é aconselhado chamar o método da classe superior utilizando o comando _Super:Metodo()



    Bloco de código
    languagecpp
    themeEclipse
    firstline1
    titleExemplo de inscrição de evento
    linenumberstrue
    collapsetrue
    //-------------------------------------------------------------------
    /*/{Protheus.doc} ModelDef
    Definição do modelo de Dados
    Data Model definition
    @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')
    Local oEvent  := ML003CTB():New()
    oModel := MPFormModel():New('MLOC003', /*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)) )
    oModel:getModel('ZC3MASTER'):SetDescription('Pedido')
    oModel:getModel('ZC4DETAIL'):SetDescription('Pedido'Item do pedido')
    oModel:getModel('ZC4DETAIL'):SetDescriptionSetUseOldGrid('Item do.T. pedido')
    oModel:AddCalc( 'Totalizador', 'ZC3MASTER', 'ZC4DETAIL', 'ZC4_TOTAL', 'ZC__TOTALPED', 'SUM', /*bCondition*/, /*bInitValue*/,'Total do Pedido' /*cTitle*/, /*bFormula*/)
    oModel:InstallEvent("ML003CTB", /*cOwner*/, oEvent)
    Return oModel
    
    
     
    Bloco de código
    languagecpp
    themeEclipse
    firstline1
    titleExemplo de inscrição de evento em um fonte localizado
    linenumberstrue
    collapsetrue
    //-------------------------------------------------------------------
    /*/{Protheus.doc} ModelDef
    Definição do modelo de Dados
    Data Model definition
    @author alvaro.camillo
    @since 05/09/2016
    @version 1.0
    /*/
    //-------------------------------------------------------------------
    Static Function ModelDef()
    Local oModel		:= FWLoadModel('MLOC003')
    Local oStr2		:= FWFormStruct(1,'ZL4')
    Local oObsCTB		:= ML003CTBRUS():New()
    Local oObsProduto	:= ML003PRORUS():New()
    oModel:addGrid('ZL4DETAIL','ZC4DETAIL',oStr2)
    oModel:SetRelation('ZL4DETAIL', { { 'ZL4_FILIAL', 'xFilial("ZL4")' }, { 'ZL4_COD', 'ZC3_COD' }, { 'ZL4_ITEM', 'ZC4_ITEM' } }, ZL4->(IndexKey(1)) )
    oModel:getModel('ZL4DETAIL'):SetDescription('Rateio do Item Russo')
    oModel:getModel('ZL4DETAIL'):SetOptional(.T.)
    //Limpa os observer poisInstala o observerevento dade contabilizaçãoatualização seráde herdado saldo
    //InstalaInstall oBalance evento de contabilizao Russaupdate Event
    oModel:ChangeEventInstallEvent("ML003CTBCOMMITML00PRORUS", , oObsCTBoObsProduto)
    //Instala o evento de atualização de saldo contabilizao Russa
    //Install Russian Accounting Event
    oModel:InstallEvent(oObsProduto"ML003CTBRUS", "ML003CTB", oObsCTB)
    
    Return oModel
    
    
    
    
    
     



    Status do documentoDesenvolvimento
    Data
     
    Versão1.0
    Autores

    Alvaro Camillo Neto

     
    Índice
    Índice
    outlinetrue
    indent10px