Escolar Documentos
Profissional Documentos
Cultura Documentos
Manual ADVPL Utilizando MVC Maio 2015 PDF
Manual ADVPL Utilizando MVC Maio 2015 PDF
Verso 4.0
1
Manual ADvPl utilizando o MVC
Sumrio
Verso 4.0
2
Manual ADvPl utilizando o MVC
Verso 4.0
3
Manual ADvPl utilizando o MVC
Verso 4.0
4
Manual ADvPl utilizando o MVC
Verso 4.0
5
Manual ADvPl utilizando o MVC
Verso 4.0
6
Manual ADvPl utilizando o MVC
Verso 4.0
7
Manual ADvPl utilizando o MVC
Verso 4.0
8
Manual ADvPl utilizando o MVC
1 para Pesquisar
2 para Visualizar
3 para Incluir
4 para Alterar
5 para Excluir
6 para Imprimir
7 para Copiar
5. Nvel de acesso;
6. Habilita Menu Funcional;
Exemplo
Local aRotina := {}
Return aRotina
Manual ADvPl utilizando o MVC
Verso 4.0
9
Manual ADvPl utilizando o MVC
Note que o 2 parmetro utiliza a chamada direta de uma aplicao, ela faz referncia a uma ViewDef
de um determinado fonte (PRW). A estrutura deste 2 parmetro tem o formato:
ViewDef.<nome do fonte>
Sempre referenciaremos a ViewDef de um fonte, pois ela a funo responsvel pela a interface da aplicao.
Local aRotina := {}
Return aRotina
O resultado final o mesmo, o que difere apenas a forma de construo, mas recomendado a 2
forma que utiliza o formato de comandos e no posies de um vetor, pois uma eventual manuteno se
tornar mais fcil. A MenuDef deve ser uma Static Function dentro da aplicao. Utilizando-se a funo
FWMVCMenu, obtm-se um menu padro com as opes: Visualizar, Incluir, Alterar, Excluir, Imprimir e Copiar.
Deve ser informado como parmetro no nome do fonte.
Exemplo:
Verso 4.0
10
Manual ADvPl utilizando o MVC
Definimos a tabela que ser exibida na Browse utilizando o mtodo SetAlias. As colunas, ordens, etc.
A exibio obtida pelo metadados (dicionrios).
oBrowse:SetAlias('ZA0')
Verso 4.0
11
Manual ADvPl utilizando o MVC
Exemplo:
Exemplo
Verso 4.0
12
Manual ADvPl utilizando o MVC
Se na aplicao foi definido que s sero exibidos clientes que so pessoas jurdicas, se usurio fizer
um filtro para exibir apenas clientes do estado de So Paulo, sero exibidos os clientes pessoa jurdica do
estado de So Paulo. Foi executado o filtro do usurio e ainda respeitado o filtro original da aplicao.
Observao
O filtro da aplicao no poder ser desabilitado pelo usurio
oBrowse:DisableDetails()
Local oBrowse
oBrowse := FWMBrowse():New()
oBrowse:SetAlias('ZA0')
// Definio da legenda
Verso 4.0
13
Manual ADvPl utilizando o MVC
// Definio de filtro
oBrowse:SetFilterDefault( "ZA0_TIPO=='1'" )
// Titulo da Browse
oBrowse:SetDescription('Cadastro de Autor/Interprete')
//oBrowse:DisableDetails()
// Ativao da Classe
oBrowse:Activate()
Return NIL
Verso 4.0
14
Manual ADvPl utilizando o MVC
Onde:
nTipo: Tipo da construo da estrutura: 1 para Modelo de dados (Model) e 2 para interface (View);
cAlias: Alias da tabela no metadado;
Exemplo
No exemplo, o objeto oStruZA0 ser uma estrutura para uso em um modelo de dados (Model). O
primeiro parmetro (1) indica que a estrutura para uso no modelo e o segundo parmetro indica qual a tabela
dos metadados ser usada para a criao da estrutura (ZA0).
Local oStruZA0 := FWFormStruct( 2, 'ZA0' )
No exemplo dado, o objeto oStruZA0 ser uma estrutura para uso em uma interface (View). O primeiro
parmetro (2) indica que a estrutura para uso em uma interface e o segundo parmetro indica qual a tabela
dos metadados ser usada para a criao da estrutura (ZA0).
Mais adiante veremos como criar estruturas manualmente e como selecionar os campos que faro
parte das estruturas e outros tratamentos especficos da estrutura.
Importante
Para modelo de dados (Model), a funo FWFormStruct, traz para a estrutura todos os campos que
compem a tabela independentemente do nvel, uso ou mdulo. Considera tambm os campos virtuais.
Para a interface (View) a funo FWFormStruct, traz para a estrutura os campos conforme o nvel,
uso ou mdulo.
Verso 4.0
15
Manual ADvPl utilizando o MVC
Construindo o Model
oModel := MPFormModel():New( 'COMP011M' )
Verso 4.0
16
Manual ADvPl utilizando o MVC
oModel := MPFormModel():New('COMP011M' )
Return oModel
Verso 4.0
17
Manual ADvPl utilizando o MVC
A interface (View) sempre trabalha baseada em um modelo de dados (Model). Criaremos um objeto
de modelo de dados baseado no ModelDef que desejamos.
Com a funo FWLoadModel obtemos o modelo de dados (Model) que est definido em um fonte,
no nosso caso o prprio fonte, mas nada impediria que usssemos o modelo de qualquer outro fonte em
MVC, com isso podemos reaproveitar um mesmo modelo de dados (Model) em mais de uma interface (View).
Local oModel := FWLoadModel( 'COMP011_MVC' )
FWFormView a classe que dever ser usada para a construo de um objeto de interface (View).
Definimos qual o modelo de dados (Model) que ser utilizado na interface (View).
oView:SetModel( oModel )
1 Determinada rea definida pelo desenvolvedor para agrupar componentes visuais, por exemplo, Panel, Dialog, Window, etc
Verso 4.0
18
Manual ADvPl utilizando o MVC
Desta forma o componente VIEW_ZA0 ser exibido na tela utilizando o box TELA.
Local oView
oView := FWFormView():New()
oView:SetModel( oModel )
// (antiga Enchoice)
Verso 4.0
19
Manual ADvPl utilizando o MVC
Return oView
6.1 Construo de estruturas para uma aplicao MVC com duas ou mais entidades
Como descrevemos, a primeira coisa que precisamos fazer criar a estrutura utilizada no modelo de
dados (Model). Temos que criar uma estrutura para cada entidade que participar do modelo. Se forem 2
entidades, 2 estruturas, se forem 3 entidades, 3 estruturas e assim por diante.
Mostraremos uma aplicao onde temos 2 entidades em uma relao de dependncia de Master-
Detail (Pai-Filho), como por exemplo um Pedido de Venda, onde temos o cabealho do pedido seria o Master
(Pai) e os itens seriam o Detail (Filho)
A construo das estruturas seria:
Local oStruZA1 := FWFormStruct( 1, 'ZA1' )
No exemplo anterior o objeto oStruZA1 ser uma estrutura para ser utilizada em um Modelo de dados
(Model) para a entidade Master (Pai) e oStruZA2 para a entidade Detail (Filho).
O primeiro parmetro (1) indica que a estrutura para ser utilizada em um modelo de dados (Model)
e segundo indica qual a tabela ser usada para a criao da estrutura.
Verso 4.0
20
Manual ADvPl utilizando o MVC
No exemplo acima o objeto oStruZA1 ser uma estrutura para ser utilizada em uma interface (View)
para a entidade Master (Pai) e oStruZA2 para a entidade Detail (Filho). O primeiro parmetro (2) indica que
a estrutura para ser utilizada em uma interface (View) e o segundo indica qual tabela ser usada para a
criao da estrutura.
Observe que no cdigo, houve a criao de 2 estruturas uma para cada entidade. Comeamos a
construo do Model
oModel := MPFormModel():New( 'COMP021M' )
Devemos dar um identificador (ID) para o Modelo de dados (Model) e para cada componente do
Model.
COMP021M o identificador (ID) dado ao Modelo de dados (Model).
Verso 4.0
21
Manual ADvPl utilizando o MVC
Verso 4.0
22
Manual ADvPl utilizando o MVC
oModel: SetPrimaryKey( {} )
Note que desta vez definimos uma descrio para modelo e uma para cada componente do modelo.
Verso 4.0
23
Manual ADvPl utilizando o MVC
Return oModel
oView := FWFormView():New()
FWFormView a classe que dever ser usada para a construo de um objeto de interface (View).
Definimos qual o Modelo de dados (Model) que ser utilizado na interface (View).
Verso 4.0
24
Manual ADvPl utilizando o MVC
Devemos dar um identificador (ID) para cada componente da interface (View). VIEW_ZA1 o
identificador (ID) dado ao componente da interface (View), oStruZA1 a estrutura que ser usada e
ZA1MASTER identificador (ID) do componente do Modelo de dados (Model) vinculado a este componente
da interface (View).
Cada componente da interface (View) deve ter um componente do Modelo de dados (Model)
relacionado, isso equivale a dizer que os dados do ZA1MASTER sero exibidos na interface (View) no
componente VIEW_ZA1.
Verso 4.0
25
Manual ADvPl utilizando o MVC
Devemos dar um identificador (ID) para cada componente da interface (View). SUPERIOR o
identificador (ID) dado ao box e nmero 15 representa o percentual da tela que ser utilizado pelo box.
Como teremos dois componentes precisamos definir mais um box para o segundo componente
oView:CreateHorizontalBox( 'INFERIOR', 85 )
INFERIOR o identificador (ID) dado ao box e nmero 85 representa o percentual da tela que ser
utilizado por ele.
Observao
A soma dos percentuais dos boxes de mesmo nvel dever ser sempre 100%.
Desta forma o componente VIEW_ZA1 ser exibido na tela pelo box SUPERIOR e o componente
VIEW_ZA2 ser exibido na tela pelo box INFERIOR.
Observao
Note que os dados da entidade Pai ocuparo 15% da tela e da entidade Filho 85%, pois:
Verso 4.0
26
Manual ADvPl utilizando o MVC
Local oView
oView := FWFormView():New()
oView:SetModel( oModel )
oView:CreateHorizontalBox( 'INFERIOR', 85 )
Return oView
Verso 4.0
27
Manual ADvPl utilizando o MVC
Se a necessidade for a construo de uma aplicao com mais de 2 entidades o processo ser o
mesmo que o mostrado para 2. A diferena ser somente a quantidade de cada componente ou objeto que
sero criados.
Para o modelo de dados (Model) se a aplicao tem 3 entidades, sero necessrias 3 estruturas, 3
componentes AddFields ou AddGrid e 2 relacionamentos. Se a aplicao tem 4 entidades, sero necessrias
4 estruturas, 4 componentes AddFields ou AddGrid e 3 relacionamentos e assim por diante.
Para a interface (View) se a aplicao tem 3 entidades, sero necessrias 3 estruturas, 3
componentes AddField ou AddGrid e 3 boxes. Se a aplicao tem 4 entidades, sero necessrias 4
estruturas, 4 componentes AddField ou AddGrid e 4 boxes e assim por diante.
O modelo de dados e a interface crescem na medida em que cresce a quantidade de entidades
relacionadas. Porm a forma bsica de construo sempre a mesma.
O bloco de cdigo recebe como parmetro um objeto que o modelo e que pode ser passado
funo que far a validao.
Static Function COMP011POS( oModel )
Return lRet
A funo chamada pelo bloco de cdigo deve retornar um valor lgico, onde se, .T. (verdadeiro) a
operao realizada e .F. (falso) no realizada.
Validaes;
Permisses;
Movimentao em linhas;
Obter e atribuir valores;
Persistncia dos dados;
Criar botes;
Criar folders; etc.
Verso 4.0
28
Manual ADvPl utilizando o MVC
EndIf
Supondo que a mensagem de erro foi acionada porque o preo unitrio 0 (zero), neste momento
no ser exibido nada ao usurio, isso pode ser observado ao debugar o fonte. Voc ver que ao passar pela
funo Help nada acontece, porm, quando o controle interno volta para a interface, a mensagem exibida.
Esse tratamento foi feito apenas para a funo help, funes como MsgStop, MsgInfo, MsgYesNo,
Alert, MostraErro, etc. no podero ser utilizadas.
Verso 4.0
29
Manual ADvPl utilizando o MVC
8.3 Validaes
Dentro do modelo de dados existentes vrios pontos onde podem ser inseridas as validaes
necessrias regra de negcio. O modelo de dados (Model) como um todo tem seus pontos e cada
componente do modelo tambm.
Para isso utilizaremos as funes FWSaveRows para salvar o posicionamento das linhas dos grids
do modelo de dados (Model) e o FWRestRows para restaurar esses posicionamentos.
Exemplo:
Local nI := 0
For nI := 1 To oModelZA2:Length()
oModelZA2:GoLine( nI )
// Segue a funo
Next
Verso 4.0
30
Manual ADvPl utilizando o MVC
Observao
O FWSaveRows guarda o posicionamento de todos os grids do modelo de dados (Model) e o
FWSaveRows restaura o posicionamento de todos os grids do model.
O bloco de cdigo recebe como parmetro um objeto que a parte do modelo correspondente apenas
ao grid e que pode ser passado para a funo que far a validao.
A funo chamada pelo bloco de cdigo deve retornar um valor lgico, onde se, .T. (verdadeiro) a
troca de linha realizada e .F. (falso) no realizada .
No exemplo anterior o campo ZA2_AUTOR no poder ter seu contedo repetido no grid. Tambm
pode ser informado mais de um campo, criando assim um controle com chave composta.
oModel:GetModel( 'ZA2DETAIL' ):SetUniqueLine( { 'ZA2_AUTOR', 'ZA2_DATA' } )
Verso 4.0
31
Manual ADvPl utilizando o MVC
ZA2_AUTOR ZA2_DATA
001 01/01/11 OK
001 02/01/11 OK
002 02/01/11 OK
001 01/01/11 No permitido
lRet := .F.
EndIf
Return lRet
Verso 4.0
32
Manual ADvPl utilizando o MVC
O bloco de cdigo recebe como parmetro um objeto que o do modelo correspondente, porm, o
modelo ainda no tem os dados carregados, pois a carga dos dados feita aps a sua ativao.
A funo chamada pelo bloco de cdigo deve retornar um valor lgico, onde se .T. (verdadeiro) a
ativao realizada e .F. (falso) no realizada.
Local nI := 0
For nI := 1 To oModelZA2:Length()
Next nI
Se for passado um parmetro no mtodo Length, o retorno ser apenas a quantidade de linhas no
apagadas da grid.
nLinhas := oModelZA2:Length( .T. ) // Quantidade linhas no apagadas
Verso 4.0
33
Manual ADvPl utilizando o MVC
Local nI := 0
For nI := 1 To oModelZA2:Length()
oModelZA2:GoLine( nI )
Next nI
Local nI := 0
Local nCtInc := 0
Local nCtAlt := 0
Local nCtDel := 0
For nI := 1 To oModelZA2:Length()
oModelZA2:GoLine( nI )
If oModelZA2:IsDeleted()
Verso 4.0
34
Manual ADvPl utilizando o MVC
ElseIf oModelZA2:IsInserted()
nCtInc++
ElseIf oModelZA2:IsUpdated()
nCtAlt++
EndIf
Next
, 1, 0)
Mas de um mtodo de status pode retornar .T. (verdadeiro) para a mesma linha. Se uma linha foi
includa, o IsInserted retornar .T. (verdadeiro), em seguida ela foi alterada, o IsUpdated retornar .T.
(verdadeiro) e em seguida a mesma linha foi apagada, IsDeleted tambm retornar .T. (verdadeiro).
If oModelZA2:AddLine() == nLinha
// Segue a funo
EndIf
O mtodo AddLine retorna a quantidade total de linhas da grid. Se a grid j possui 2 linhas e tudo
correu bem na adio da linha, o AddLine retornara 3, se ocorreu algum problema retornar 2, pois a nova
linha no foi inserida.
Os motivos para a insero no ser bem sucedida poder ser algum campo obrigatrio no informado,
a ps-validao da linha retornou .F. (falso), atingiu a quantidade mxima de linhas para o grid, por exemplo.
Verso 4.0
35
Manual ADvPl utilizando o MVC
Local nI := 0
For nI := 1 To oModelZA2:Length()
oModelZA2:GoLine( nI )
If !oModelZA2:IsDeleted()
oModelZA2:DeleteLine()
EndIf
Next
O mtodo DeleteLine retorna .T. (verdadeiro) se a deleo foi bem sucedida. Um motivo para que
no seja a pr-validao da linha retornar .F. (falso).
Se quisermos recuperar uma linha da grid que est apagada utilizamos o mtodo UnDeleteLine.
Local oModel := FWModelActive()
Local nI := 0
For nI := 1 To oModelZA2:Length()
oModelZA2:GoLine( nI )
If oModelZA2:IsDeleted()
oModelZA2:UnDeleteLine()
EndIf
Next
O mtodo UnDeleteLine retorna .T. (verdadeiro) se a recuperao foi bem sucedida. Um motivo para
que no seja a pr-validao da linha retornar .F. (falso).
Verso 4.0
36
Manual ADvPl utilizando o MVC
Se um grid for opcional e na estrutura houver campos obrigatrios, s ser validado se estes campos
foram informados e somente se a linha sofrer alguma alterao em qualquer campo.
O mtodo IsOptional pode ser utilizado para saber se o componente de grid tem ou no esta
caracterstica. Se retornar .T. (verdadeiro) o componente permite que no existam linhas digitadas. Este
mtodo pode ser til em validaes.
Verso 4.0
37
Manual ADvPl utilizando o MVC
SetValue: Atribui um dado ao modelo de dados (Model). Podemos atribuir o dado a partir do modelo
completo ou a partir de uma parte dele.
A partir do modelo de dados (Model) completo
oModel:SetValue( 'ZA1MASTER', 'ZA1_MUSICA', '000001' )
Verso 4.0
38
Manual ADvPl utilizando o MVC
oModelZA2:SetValue('ZA1_MUSICA', '000001' )
Quando utilizamos o SetValue para atribuir um dado a um campo as validaes deste campo so
executadas e tambm so disparados os seus gatilhos.
O SetValue retorna .T. (verdadeiro) se a atribuio foi bem sucedida, os motivos para que no seja
podem ser que o dado no satisfez a validao ou o modo de edio (WHEN) no foi satisfeito, etc.
LoadValue:Atribui um dado ao modelo de dados (Model). Podemos atribuir o dado a partir do modelo
completo ou a partir de uma parte dele. A partir do modelo de dados (Model) completo
...
oModelZA2:LoadValue('ZA1_MUSICA', '000001' )
8.6 Comportamento
Veremos como alterar alguns dos comportamentos padres do modelo de dados (Model).
Verso 4.0
39
Manual ADvPl utilizando o MVC
lRet := .F.
EndIf
Return lRet
No MVC foram criadas vrias diretivas de compilao #DEFINE para facilitar o desenvolvimento e
tornar a leitura de uma aplicao mais fcil. Para utilizar este #DEFINE preciso incluir a seguinte diretiva no
fonte:
#
INCLUDE 'FWMVCDEF.CH'
Verso 4.0
40
Manual ADvPl utilizando o MVC
O bloco de cdigo recebe como parmetro um objeto que o modelo e que pode ser passado
funo que far a gravao. Diferentemente dos blocos de cdigo definidos no modelo de dados (Model) para
validao que complementam a validaes feitas pelo MVC, o bloco de cdigo para gravao substitui a
gravao dos dados. Ento ao ser definido um bloco de cdigo para gravao, passa ser responsabilidade da
funo criada, a gravao de todos os dados inclusive os dados do modelo de dados em uso.
Para facilitar o desenvolvimento foi criada a funo FWFormCommit que far a gravao dos dados
do objeto de modelo de dados (Model) informado.
Static Function COMP011GRV ( oModel )
FWFormCommit( oModel )
// no so do model
Importante
No devem ser feitas atribuies de dados no modelo (Model) dentro da funo de gravao.
Conceitualmente ao se iniciar a gravao, o modelo de dados (Model) j passou por toda a validao, ao tentar
atribuir um valor, esse valor pode no satisfazer a validao do campo tornando o modelo de dados (Model)
invalidado novamente e o que ocorrer a gravao de dados inconsistentes.
Verso 4.0
41
Manual ADvPl utilizando o MVC
Por exemplo, podemos definir que o campo Cdigo da Loja de uma entidade, s pode ser preenchido
aps o preenchimento do campo Cdigo do Cliente.
As regras de preenchimento podem ser de 3 tipos:
Tipo 1 Pr-Validao
Adiciona uma relao de dependncia entre campos do formulrio, impedindo a atribuio de valor
caso os campos de dependncia no tenham valor atribudo. Por exemplo, o preenchimento do campo Cdigo
da Loja s pode ser preenchido aps o preenchimento do campo Cdigo do Cliente.
Tipo 2 Pos-Validao
Adiciona uma relao de dependncia entre a referncia de origem e destino, provocando uma
reavaliao do destino em caso de atualizao da origem. Por exemplo, aps o preenchimento do campo
Cdigo da Loja a validao reavaliado caso o Cdigo do Cliente, seja alterado.
Tipo 3 Pr e Ps-Validao
So os tipos 1 e 2 simultaneamente
Exemplo
O ZA3MASTER o identificador (ID) do componente do modelo de dados (Model) onde esta o campo
de destino, ZA3_LOJA o campo destino, o segundo ZA3MASTER do componente do modelo de dados
(Model) onde est o campo de origem, ZA3_DATA o campo de origem.
9.Tratamentos de interface
Veremos alguns tratamentos que podem ser feitos na interface (View) conforme a necessidade.
Criao de botes;
Criao de pastas;
Agrupamento de campos;
Incremento de campos;
Etc.
Verso 4.0
42
Manual ADvPl utilizando o MVC
Importante
Esse comportamento s acontece quando a aplicao est sendo usada por sua interface (View).
Quando o modelo de dados usado diretamente (Web Services, rotinas automticas, etc.) o campo
incremental tem que ser informado normalmente.
Verso 4.0
43
Manual ADvPl utilizando o MVC
Onde o Inclui Autor, o texto que ser apresentado no boto, CLIPS o nome da imagem do RPO 2
que ser usada para o boto e o 3 parmetro o bloco de cdigo que ser executado ao acionar o boto.
Visualmente temos:
Verso 4.0
44
Manual ADvPl utilizando o MVC
oView:EnableTitleView('VIEW_ZA2','Musicas')
Onde VIEW_ZA2 o identificador (ID) do componente da interface (View), e MSICAS o titulo que
deseja para o componente
Podemos ainda usar:
oView:EnableTitleView('VIEW_ZA2')
Onde o titulo que ser exibido o que foi definido no mtodo SetDescription do modelo de dados
(Model) para o componente.
Visualmente temos:
Verso 4.0
45
Manual ADvPl utilizando o MVC
Onde VIEW_ZA2 o identificador (ID) do componente da interface (View), onde se encontra o campo
e ENABLEDGRIDDETAIL a diretiva que habilita o comportamento. {60} o percentual que o formulrio de
edio ocupar do tamanho que o componente de grid ocupa atualmente. Exemplificando numericamente, se
para o componente de grid foi definido que ele utilizar 50% da tela, ao se colocar 60 (60%) no parmetro,
quer se indicar que dos 50% destinados ao componente de grid, 60% sero usados para o formulrio de edio.
Visualmente temos:
oView:CreateFolder( 'PASTAS' )
Verso 4.0
46
Manual ADvPl utilizando o MVC
Onde PASTAS o identificador (ID) da pasta, e ABA01 e ABA02 so os IDs dados a cada aba e
Cabealho e Item so os ttulos de cada aba. Para que possamos colocar um componente em uma aba,
precisamos criar um box, um objeto, para receber os elementos da interface (View). A forma para se criar um
box em uma aba :
oView:CreateHorizontalBox( 'SUPERIOR', 100,,, 'PASTAS', 'ABA01' )
Resumindo
oView:CreateFolder( 'PASTAS' )
Verso 4.0
47
Manual ADvPl utilizando o MVC
Verso 4.0
48
Manual ADvPl utilizando o MVC
Visualmente temos
Importante
Os agrupamentos sero exibidos na interface (View) na ordem de sua criao.
Verso 4.0
49
Manual ADvPl utilizando o MVC
Onde:
cActionlID:ID do ponto onde a ao ser executada que podem ser:
REFRESH: executa a ao no Refresh da View;
BUTTONOK: executa a ao no acionamento do boto confirmar da View;
BUTTONCANCEL:executa a ao no acionamento do boto cancelar da View;
DELETELINE: executa a ao na deleo da linha da grid;
UNDELETELINE: executa a ao na restaurao da linha da grid;
BAction: bloco com a ao a ser executada. Recebe como parmetro:
REFRESH: recebe como parmetro o objeto de View;
BUTTONOK: recebe como parmetro o objeto de View;
BUTTONCANCEL: recebe como parmetro o objeto de View;
DELETELINE: recebe como parmetro o objeto de View, identificador (ID) da View e nmero da linha.
UNDELETELINE: recebe como parmetro o objeto de View, identificador (ID) da View e nmero da
linha
Exemplo
Importante
Essas aes so executadas apenas quando existe uma interface (View). O que no ocorre quando
temos o instnciamento direto do modelo, rotina automtica ou Web Service. Deve-se evitar ento colocar
nestas funes aes que possam influenciar a regra de negcio, pois na execuo da aplicao sem interface
essas aes no sero executadas.
Verso 4.0
50
Manual ADvPl utilizando o MVC
Onde:
cIDField: ID do campo (nome):
bAction: bloco com a ao a ser executada, recebe como parmetro:
Objeto De View
O identificador (ID) Da View
O identificador (ID) Do Campo
Contedo Do Campo
Exemplo
Importante
Essas aes so executadas aps a validao do campo.
Essas aes so executadas apenas quando existe uma interface (View). O que no ocorre
quando temos o instnciamento direto do modelo, rotina automtica ou Web Service.
Deve-se evitar ento colocar nestas funes aes que possam influenciar a regra de negcio,
pois na execuo da aplicao sem interface essas aes no sero executadas.
Verso 4.0
51
Manual ADvPl utilizando o MVC
Note que o 2 parmetro recebe como parmetro um objeto que o container onde o desenvolvedor
deve colocar seus objetos. Abaixo segue um exemplo do uso do mtodo, onde colocamos em pedao da
interface (View) 2 botes. Observe os comentrios no fonte:
oView := FWFormView():New()
oView:SetModel( oModel )
oView:CreateHorizontalBox( 'EMCIMA' , 20 )
oView:CreateHorizontalBox( 'MEIO' , 40 )
oView:CreateHorizontalBox( 'EMBAIXO', 40 )
oView:EnableTitleView( 'VIEW_ZA3' )
// AddOtherObject(cFormModelID,bBloco)
// cIDObject - Id
Verso 4.0
52
Manual ADvPl utilizando o MVC
oView:SetOwnerView("OTHER_PANEL",'EMBAIXODIR')
Return oView
//-------------------------------------------------------------------
Return NIL
Verso 4.0
53
Manual ADvPl utilizando o MVC
Visualmente temos:
Verso 4.0
54
Manual ADvPl utilizando o MVC
If cCampo == 'ZA0_QTDMUS'
lRet := .F.
EndIf
Return lRet
Verso 4.0
55
Manual ADvPl utilizando o MVC
oStruZA0: RemoveField('ZA0_QTDMUS')
Verso 4.0
56
Manual ADvPl utilizando o MVC
Verso 4.0
57
Manual ADvPl utilizando o MVC
Os nomes de propriedades citados nas tabelas dadas so na verdade diretivas de compilao do tipo
#DEFINE. Para utilizar este #DEFINE preciso incluir a seguinte diretiva no fonte:
#INCLUDE 'FWMVCDEF.CH'
Tambm possvel atribuirmos uma propriedade para todos os campos da estrutura de s vez
utilizando no nome do campo o asterisco "*"
oStruZA0:SetProperty( '*' , MODEL_FIELD_WHEN,'INCLUI')
Verso 4.0
58
Manual ADvPl utilizando o MVC
Verso 4.0
59
Manual ADvPl utilizando o MVC
Verso 4.0
60
Manual ADvPl utilizando o MVC
Observao
Os campos do tipo lgico sero exibidos como um checkbox na interface (View)
Onde o 1 parmetro indica qual a propriedade a ser construda e o 2 o contedo a ser atribudo. O
2 parmetro deve sempre ser ou retornar um dado do tipo caracter. As propriedades que precisam ser tratadas
com esta funo so:
STRUCT_FEATURE_VALID: para a validao
STRUCT_FEATURE_WHEN: para o modo de edio
STRUCT_FEATURE_INIPAD: para o inicializador padro
STRUCT_FEATURE_PICTVAR: para PictureVar
Os nomes de propriedades citados acima so na verdade #DEFINE. Para utilizar este #DEFINE
preciso incluir a seguinte diretiva no fonte:
#INCLUDE 'FWMVCDEF.CH'
Observao
Utilize sempre est a funo FWBuildFeature para a construo das propriedades do contrrio
podero ocorrer erros na aplicao, tal como a no atualizao das variveis de memria para os componentes
de formulrio.
Verso 4.0
61
Manual ADvPl utilizando o MVC
Para estes campos MEMO sempre deve haver outro campo que conter o cdigo com que o campo
MEMO foi armazenado na tabela auxiliar No exemplo, oStruZA1 a estrutura que contm os campos MEMO
e o segundo parmetro um vetor bidimensional onde cada par relaciona o campo da estrutura que contm o
cdigo do campo MEMO com o campo MEMO propriamente dito. Se a tabela auxiliar a ser utilizada no for a
SYP, um parmetro dever ser passado no vetor bidimensional, como o alias da tabela auxiliar.
FWMemoVirtual( oStruZA1, { { 'ZA0_CDSYP1' , 'ZA0_MMSYP1', 'ZZ1' } , {
'ZA0_CDSYP2' , 'ZA0_MMSYP2' , 'ZZ1'} } )
Observao
Tanto o campo MEMO quanto o campo que armazenar seu cdigo devem fazer parte da estrutura.
Onde
cIdField: nome (ID) do campo de origem;
cTargetIdField: nome (ID) do campo de destino;
bPre: bloco de cdigo de validao da execuo do gatilho;
bSetValue: bloco de cdigo de execuo do gatilho;
Os blocos de cdigo deste mtodo pendem uma construo especfica. Ao se atribuir ou manipular
essas propriedades devem ser informadas no padro que o MVC espera.
Para facilitar a construo do gatilho foi criada a funo FwStruTrigger, ela retorna um array com 4
elementos j formatados para uso no AddTrigger.
Sua sintaxe :
FwStruTrigger: ( cDom, cCDom, cRegra, lSeek, cAlias, nOrdem, cChave, cCondic )
Onde
cDom: campo domnio
cCDom: campo de contradomnio
3 SYP Tabela do Microsiga Protheus que armazena os dados dos campos do tipo MEMO virtuais
Verso 4.0
62
Manual ADvPl utilizando o MVC
Local aAux := {}
aAux := FwStruTrigger(;
'ZA2_AUTOR' ,;
'ZA2_NOME' ,;
'ZA0->ZA0_NOME'..,;
.T...............,;
'ZA0'........ ,;
1............ ,;
'xFilial("ZA0")+M->ZA2_AUTOR')
oStruct:AddTrigger( ;
oStruZA0:SetNoFolder()
Verso 4.0
63
Manual ADvPl utilizando o MVC
oStruZA0:SetNoGroups()
Recebe como parmetros: o objeto do modelo, o valor da atual do campo frmula, o contedo do
campo do componente de grid, campo lgico indicando se uma execuo de soma (.T. (verdadeiro)) ou
subtrao (.F. (falso)). O valor retornado ser atribudo ao campo calculado
Exemplo
{ |oModel, nTotalAtual, xValor, lSomando| Calculo( oModel, nTotalAtual, xValor, lSomando ) };
nTamanho: tamanho do campo calculado (Se no for informado usa o tamanho padro). Os
tamanhos padres para as operaes so:
SUM: ser o tamanho do campo do componente de grid + 3;
Verso 4.0
64
Manual ADvPl utilizando o MVC
Observao
Para as operaes de SUM e AVG o campo do componente de grid tem de ser do tipo numrico.
Exemplo
Static Function ModelDef()
...
...
Onde
...
Verso 4.0
65
Manual ADvPl utilizando o MVC
...
Verso 4.0
66
Manual ADvPl utilizando o MVC
If lOk
Else
EndIf
...
FWModelActive( oModelBkp )
oView:Refresh()
...
FWViewActive(oViewBkp)
Verso 4.0
67
Manual ADvPl utilizando o MVC
Exemplo
//----------------------------------------
Ser criado um menu padro com as opes: Visualizar, Incluir, Alterar, Excluir, Imprimir e Copiar.
Verso 4.0
68
Manual ADvPl utilizando o MVC
Definimos a tabela que ser exibida na Browse pelo mtodo SetAlias. As colunas, ordens, etc. para
a exibio sero obtidos atravs do metadados (dicionrios )
oMark:SetAlias('ZA0')
Com esta estrutura bsica construmos uma aplicao com Browse. Mas por enquanto temos apenas
o Browse com coluna de marcao, precisamos definir uma ao para os itens marcados. Para isso, podemos
colocar no MenuDef da aplicao a funo que tratar os marcados.
ADD OPTION aRotina TITLE 'Processar' ACTION 'U_COMP25PROC()' OPERATION 2 ACCESS 0
Na funo que tratar os marcados ser preciso identificar se um registro est ou no marcado. Para
sabermos a marca que est sendo utilizado no momento usamos o mtodo Mark.
Local cMarca := oMark:Mark()
E para saber se o registro est marcado usamos o mtodo IsMark passando como parmetro a marca.
If oMark:IsMark(cMarca)
possvel tambm colocar outras opes como visualizar ou alterar no menu de opes (MenuDef),
mas ser preciso criar tambm o modelo de dados (Model) e a interface (View). Todas as outras caractersticas
da FWMBrowse tambm se aplicam a FWMarkBrowse como legendas, filtros, detalhes, etc. Um recurso que
a FWMarkBrowse tem o controle de marcao exclusiva do registro pelo usurio.
Verso 4.0
69
Manual ADvPl utilizando o MVC
Onde se 2 usurios abrirem o mesmo FWMarkBrowse e tentarem marcar o mesmo registro o prprio
FWMarkBrowse permitir que apenas um deles execute a marcao. Para habilitar esta caracterstica usamos
o mtodo SetSemaphore.
Abaixo, segue um exemplo da utilizao do FWMarkBrowse
User Function COMP025_MVC()
Private oMark
// Instanciamento do classe
oMark := FWMarkBrowse():New()
oMark:SetAlias('ZA0')
oMark:SetFieldMark( 'ZA0_OK' )
// Define a legenda
oMark:SetFilterDefault( "ZA0_TIPO=='1'" )
// Ativacao da classe
oMark:Activate()
Return NIL
Verso 4.0
70
Manual ADvPl utilizando o MVC
//-------------------------------------------------------------------
Local aRotina := {}
Return aRotina
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------
Local nCt := 0
ZA0->( dbGoTop() )
If oMark:IsMark(cMarca)
nCt++
EndIf
Verso 4.0
71
Manual ADvPl utilizando o MVC
ZA0->( dbSkip() )
End
RestArea( aArea )
Return NIL
Visualmente teremos:
Verso 4.0
72
Manual ADvPl utilizando o MVC
//
//
oFWLayer := FWLayer():New()
//
//
Verso 4.0
73
Manual ADvPl utilizando o MVC
//
// Painel Inferior
//
Feito isso criamos as 3 Browses conforme o descrito no captulo 3 Aplicaes com Browses
(FWMBrowse). Este o 1 Browse.
//
//
oBrowseUp:= FWmBrowse():New()
//componente de tela
oBrowseUp:SetDescription( "Albuns" )
oBrowseUp:SetAlias( 'ZA3' )
// Sair
oBrowseUp:Activate()
Verso 4.0
74
Manual ADvPl utilizando o MVC
oBrowseLeft:SetOwner( oPanelLeft )
oBrowseLeft:SetDescription( 'Musicas' )
oBrowseLeft:DisableDetails()
oBrowseLeft:SetAlias( 'ZA4' )
oBrowseLeft:SetProfileID( '2' )
oBrowseLeft:Activate()
oBrowseRight:= FWMBrowse():New()
oBrowseRight:SetOwner( oPanelRight )
oBrowseRight:SetDescription( 'Autores/Interpretes' )
oBrowseRight:DisableDetails()
oBrowseRight:SetAlias( 'ZA5' )
oBrowseRight:SetProfileID( '3' )
oBrowseRight:Activate()
Note que nestes Browses utilizamos o mtodo SetMenuDef com uma referncia vazia, como
queremos que apenas o Browse principal tenha botes de ao, se no definimos o SetMenuDef,
automaticamente, o Browse busca no prprio fonte onde ele se encontra e com a referncia vazia no so
exibidos botes. Agora que definimos os Browses precisamos fazer o relacionamento entre eles, para que ao
efetuar o movimento em um, automaticamente os outros sejam atualizados. Para criar o relacionamento
utilizaremos a classe FWBrwRelation. Similarmente ao que relacionamento entre entidades feito no modelo
de dados (Model) preciso dizer quais as chaves de relacionamento do filho para o pai.
Instanciaremos o FWBrwRelation e usaremos seu mtodo AddRelation.
A sintaxe deste mtodo do FWBrwRelation :
AddRelation( <oBrowsePai>, <oBrowseFilho>, <Vetor com os campos de relacionamento> )
Manual ADvPl utilizando o MVC
Verso 4.0
75
Manual ADvPl utilizando o MVC
oRelacZA4:Activate()
oRelacZA5:= FWBrwRelation():New()
oRelacZA5:Activate()
Private oDlgPrinc
//
//
oFWLayer := FWLayer():New()
//
//
Verso 4.0
76
Manual ADvPl utilizando o MVC
//
// Painel Inferior
//
//
//
oBrowseUp:= FWmBrowse():New()
oBrowseUp:SetOwner( oPanelUp )
oBrowseUp:SetDescription( "Albuns" )
oBrowseUp:SetAlias( 'ZA3' )
oBrowseUp:SetMenuDef( 'COMP024_MVC' )
oBrowseUp:SetProfileID( '1' )
oBrowseUp:ForceQuitButton()
oBrowseUp:Activate()
//
Verso 4.0
77
Manual ADvPl utilizando o MVC
//
oBrowseLeft:= FWMBrowse():New()
oBrowseLeft:SetOwner( oPanelLeft )
oBrowseLeft:SetDescription( 'Musicas' )
oBrowseLeft:SetMenuDef( '' )
oBrowseLeft:DisableDetails()
oBrowseLeft:SetAlias( 'ZA4' )
oBrowseLeft:SetProfileID( '2' )
oBrowseLeft:Activate()
//
//
oBrowseRight:= FWMBrowse():New()
oBrowseRight:SetOwner( oPanelRight )
oBrowseRight:SetDescription( 'Autores/Interpretes' )
oBrowseRight:SetMenuDef( '' )
oBrowseRight:DisableDetails()
oBrowseRight:SetAlias( 'ZA5' )
oBrowseRight:SetProfileID( '3' )
oBrowseRight:Activate()
//
oRelacZA4:= FWBrwRelation():New()
oRelacZA4:Activate()
Verso 4.0
78
Manual ADvPl utilizando o MVC
oRelacZA5:= FWBrwRelation():New()
oRelacZA5:Activate()
Return NIL
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------
Verso 4.0
79
Manual ADvPl utilizando o MVC
Visualmente teremos:
Verso 4.0
80
Manual ADvPl utilizando o MVC
//-------------------------------------------------------------------
Local aSay := {}
Local aButton := {}
Local nOpc := 0
If nOpc == 1
Verso 4.0
81
Manual ADvPl utilizando o MVC
If lOk
Else
EndIf
EndIf
Return NIL
//-------------------------------------------------------------------
//-------------------------------------------------------------------
Local aCampos := {}
aCampos := {}
lRet := .F.
EndIf
aCampos := {}
Verso 4.0
82
Manual ADvPl utilizando o MVC
lRet := .F.
EndIf
aCampos := {}
lRet := .F.
EndIf
Return lRet
//-------------------------------------------------------------------
//-------------------------------------------------------------------
Local nI := 0
Local nPos := 0
Local aAux := {}
dbSelectArea( cAlias )
dbSetOrder( 1 )
Verso 4.0
83
Manual ADvPl utilizando o MVC
oModel:SetOperation( 3 )
oModel:Activate()
oStruct := oAux:GetStruct()
aAux := oStruct:GetFields()
lRet := .F.
Exit
EndIf
EndIf
Next nI
If lRet
Verso 4.0
84
Manual ADvPl utilizando o MVC
// "rotinas automticas"
If ( lRet := oModel:VldData() )
oModel:CommitData()
EndIf
EndIf
If !lRet
aErro := oModel:GetErrorMessage()
Verso 4.0
85
Manual ADvPl utilizando o MVC
MostraErro()
EndIf
// Desativamos o Model
oModel:DeActivate()
Return lRet
Neste outro exemplo, temos a importao para um modelo de dados onde h uma estrutura de
Master-Detail (Pai-Filho). Tambm o que faremos instanciar o modelo de dados (Model) que desejamos,
atribuir os valores ele e fazer a validao, s que faremos isso para as duas entidades.
Observe os comentrios:
//-------------------------------------------------------------------
//-------------------------------------------------------------------
Local aSay := {}
Local aButton := {}
Local nOpc := 0
Verso 4.0
86
Manual ADvPl utilizando o MVC
If nOpc == 1
If lOk
Else
EndIf
EndIf
Return NIL
//-------------------------------------------------------------------
//-------------------------------------------------------------------
Local aCposCab := {}
Local aCposDet := {}
Local aAux := {}
// Criamos um vetor com os dados de cabealho e outro para itens para facilitar
o manuseio dos dados
aCposCab := {}
aCposDet := {}
Verso 4.0
87
Manual ADvPl utilizando o MVC
aAux := {}
aAux := {}
lRet := .F.
EndIf
aCposCab := {}
aCposDet := {}
aAux := {}
aAux := {}
lRet := .F.
EndIf
Verso 4.0
88
Manual ADvPl utilizando o MVC
aCposCab := {}
aCposDet := {}
aAux := {}
aAux := {}
lRet := .F.
EndIf
Return lRet
//-------------------------------------------------------------------
//-------------------------------------------------------------------
Local nI := 0
Local nJ := 0
Local nPos := 0
Verso 4.0
89
Manual ADvPl utilizando o MVC
Local aAux := {}
Local aC := {}
Local aH := {}
Local nItErro := 0
dbSelectArea( cDetail )
dbSetOrder( 1 )
dbSelectArea( cMaster )
dbSetOrder( 1 )
oModel:SetOperation( 3 )
oModel:Activate()
oStruct := oAux:GetStruct()
aAux := oStruct:GetFields()
If lRet
Verso 4.0
90
Manual ADvPl utilizando o MVC
lRet := .F.
Exit
EndIf
EndIf
Next
EndIf
If lRet
oStruct := oAux:GetStruct()
aAux := oStruct:GetFields()
nItErro := 0
If nI > 1
Verso 4.0
91
Manual ADvPl utilizando o MVC
lRet := .F.
Exit
EndIf
EndIf
lRet := .F.
nItErro := nI
Exit
EndIf
EndIf
Next
If !lRet
Exit
EndIf
Next
EndIf
If lRet
Verso 4.0
92
Manual ADvPl utilizando o MVC
If ( lRet := oModel:VldData() )
// dados (commit)
oModel:CommitData()
EndIf
EndIf
If !lRet
aErro := oModel:GetErrorMessage()
Verso 4.0
93
Manual ADvPl utilizando o MVC
If nItErro > 0
EndIf
MostraErro()
EndIf
// Desativamos o Model
oModel:DeActivate()
Return lRet
Uma situao que poder ser encontrada, nos casos em que se est convertendo uma aplicao j
existente para a estrutura de MVC, o fato da aplicao j estar preparada para trabalhar com rotina
automtica e consequentemente pode haver vrias outras aplicaes que j utilizam essa rotina automtica.
A funo FWMVCRotAuto foi criada para que no seja necessrio que estas aplicaes, que hoje
usam a chamada da rotina padro, mudem sua forma de trabalhar, j a aplicao foi convertida para MVC.
A funo utiliza os parmetros passados no formato anterior de rotina automtica (MSEXECAUTO) e
faz o instanciamento do model, atribuio de valores e validao no formato MVC, garantindo os programas
legados.
Sua sintaxe :
FWMVCRotAuto( oModel, cAlias, nOpcAuto, aAuto, lSeek, lPos )
Onde
OModel: objeto com o modelo do formulrio de dados;
cAlias: alias do Browse principal;
nOpcAuto: cdigo de identificao do tipo de processamento da rotina automtica;
Verso 4.0
94
Manual ADvPl utilizando o MVC
Local oMBrowse
If xRotAuto == NIL
oBrowse := FWMBrowse():New()
oBrowse:SetAlias('SA1')
oBrowse:SetDescription("Cadastro de Clientes")
oBrowse:Activate()
Else
aRotina := MenuDef()
FWMVCRotAuto(ModelDef(),"SA1",nOpcAuto,{{"MATA030_SA1",xRotAuto}})
Endif
Return NIL
Verso 4.0
95
Manual ADvPl utilizando o MVC
Em MVC, no desta forma. Em MVC criamos um nico ponto de entrada e este chamado em vrios
momentos dentro da aplicao desenvolvida. Este ponto de entrada nico deve ser uma User Function e ter
como nome o identificador (ID) do modelo de dados (Model) do fonte. Peguemos de exemplo um fonte do
Modulo Jurdico: JURA001. Neste fonte o identificador (ID) do modelo de dados (definido na funo ModelDef)
tambm JURA001, portanto ao se escrever o ponto de entrada desta aplicao, faramos:
User Function JURA001()
...
Return xRet
O ponto de entrada criado recebe via parmetro (PARAMIXB) um vetor com informaes referentes
aplicao. Estes parmetros variam para cada situao, em comum todos eles tm os 3 primeiros elementos
que so listados abaixo, no quadro seguinte existe a relao de parmetros para cada ID:
Posies do array de parmetros comuns a todos os IDs:
Verso 4.0
96
Manual ADvPl utilizando o MVC
Parmetros Recebidos:
3 C ID do formulrio.
Retorno:
Parmetros Recebidos:
3 C ID do formulrio.
Retorno:
Parmetros Recebidos:
3 C ID do formulrio.
Retorno:
Verso 4.0
97
Manual ADvPl utilizando o MVC
Parmetros Recebidos:
3 C ID do formulrio.
Retorno:
Parmetros Recebidos:
3 C ID do formulrio.
FORMLINEPRE
4 N Nmero da Linha da FWFORMGRID.
5 C Ao da FWFORMGRID.
6 C Id do campo.
Retorno:
Parmetros Recebidos:
Retorno:
Verso 4.0
98
Manual ADvPl utilizando o MVC
Parmetros Recebidos:
3 C ID do formulrio.
Retorno:
No espera retorno.
Parmetros Recebidos:
3 C ID do formulrio.
Retorno:
No espera retorno.
Parmetros Recebidos:
Retorno:
No espera retorno.
Verso 4.0
99
Manual ADvPl utilizando o MVC
Parmetros Recebidos:
Retorno:
No espera retorno.
No cancelamento do boto.
Parmetros Recebidos:
3 C ID do formulrio.
Retorno:
Na ativao do modelo
Parmetros Recebidos:
3 C ID do formulrio.
Retorno:
Verso 4.0
100
Manual ADvPl utilizando o MVC
4 C ToolTip (Opcional).
BUTTONBAR
Parmetros Recebidos:
3 C ID do formulrio.
Retorno:
Observaes
Quando o modelo de dados possui vrios componentes (por exemplo, de grid), a 3 posio do
vetor trar o identificador (ID) deste componente;
Quando o tipo de retorno de um determinado momento de execuo no for passado ou for
passado com o tipo errado ser exibida uma mensagem no console avisando sobre isso. Todos IDs que
esperam retorno devem ser tratados no ponto de entrada.
Importante
Ao se escrever um fonte em MVC que ser uma User Function, cuidado ao se atribuir o identificador
(ID) do modelo de dados (Model), pois ele no poder ter o mesmo nome do fonte (PRW). Se o fonte tiver o
nome FONT001, o identificador (ID) do modelo de dados (Model) no poder ser tambm FONT001, pois no
ser possvel criar outra User Function com o nome de FONT001 (ID do modelo de dados) para os pontos de
entrada.
Exemplo
Verso 4.0
101
Manual ADvPl utilizando o MVC
Local nLinha := 0
Local nQtdLinhas := 0
oObj := aParam[1]
cIdPonto := aParam[2]
cIdModel := aParam[3]
If lIsGrid
nQtdLinhas := oObj:GetQtdLine()
nLinha := oObj:nLine
EndIf
If cIdPonto == 'MODELPOS'
EndIf
If cClasse == 'FWFORMGRID'
EndIf
Verso 4.0
102
Manual ADvPl utilizando o MVC
If aParam[5] == 'DELETE'
EndIf
EndIf
EndIf
Verso 4.0
103
Manual ADvPl utilizando o MVC
EndIf
'Continua ?'
EndIf
EndIf
EndIf
Return xRet
17.1 Web Service para modelos de dados que possuem uma entidade
Veremos como construir uma aplicao que utilize o Web Service FWWSMODEL com um modelo de
dados (Model) que possui apenas uma entidade.
Verso 4.0
104
Manual ADvPl utilizando o MVC
<ID do Model>
<ID de Componente>
<ID de Campo>
Contedo...
</ID de Campo
</ID do Model>
A tag <ID do Model> o que identificador (ID) foi definido no modelo de dados (Model) da aplicao
MVC.
Exemplo
...
</COMP011M>
A operao que ser realizada incluso (3), alterao (4) ou excluso (5) tambm dever ser
informada nesta tag, no atributo Operation. Assim se quisermos fazer uma operao de incluso teremos
<COMP011M Operation="3">
As tags <ID de Componente> so IDs dos componentes de formulrios ou componente de grids que
foram definidos no modelo de dados (Model) da aplicao.
Verso 4.0
105
Manual ADvPl utilizando o MVC
Exemplo
Se na aplicao temos:
oModel:AddFields( 'ZA0MASTER' )
...
</ZA0MASTER>
O tipo do componente (de formulrio ou de grid) tambm deve ser informados nesta tag no atributo
modeltype. Informe FIELDS para componentes de formulrios e os componentes de grid.
Teramos ento:
<ZA0MASTER modeltype="FIELDS">
As tags <ID de Campo> sero os nomes dos campos da estrutura do componente, seja formulrio ou
grid Assim se na estrutura tivermos os campos ZA0_FILIAL, ZA0_ CODIGO e ZA0_NOME, por exemplo,
teremos:
<ZA0_FILIAL>
...
</ZA0_FILIAL>
<ZA0_CODIGO>
...
</ZA0_CODIGO>
<ZA0_NOME>
...
</ZA0_NOME>
A ordem dos campos tambm deve ser informada nestas tags, no atributo order.
<ZA0_FILIAL order="1">
...
</ZA0_FILIAL>
<ZA0_CODIGO order="2">
...
</ZA0_CODIGO >
<ZA0_NOME order="3">
...
</ZA0_NOME>
Verso 4.0
106
Manual ADvPl utilizando o MVC
<value>01</value>
</ZA0_FILIAL>
<ZA0_CODIGO order="2">
<value>001000</value>
</ZA0_CODIGO >
<ZA0_NOME order="3">
<value>Tom Jobim</value>
</ZA0_NOME>
<COMP011M Operation="1">
<ZA0_FILIAL order="1">
<value>01</value>
</ZA0_FILIAL>
<ZA0_CODIGO order="2">
<value>01000</value>
</ZA0_CODIGO>
<ZA0_NOME order="3">
<value>Tom Jobim</value>
</ZA0_NOME>
</ZA0MASTER>
</COMP011M>
oMVCWS:GetXMLData()
cXMLEstrut := oMVCWS:cGetXMLDataResult
Manual ADvPl utilizando o MVC
Verso 4.0
107
Manual ADvPl utilizando o MVC
<COMP011M Operation="1"
<ZA0_FILIAL order="1"><value></value></ZA0_FILIAL>
<ZA0_CODIGO order="2"><value></value></ZA0_CODIGO>
<ZA0_NOME order="3"><value></value></ZA0_NOME>
</ZA0MASTER>
</COMP011M>
EndIf
If oMVCWS:lPutXMLDataResult
Else
EndIf
Else
Verso 4.0
108
Manual ADvPl utilizando o MVC
EndIf
If oMVCWS:GetSchema()
cXMLEsquema := oMVCWS:cGetSchemaResult
EndIf
Verso 4.0
109
Manual ADvPl utilizando o MVC
Local oMVCWS
oMVCWS := WsFwWsModel():New()
oMVCWS:_URL := http://127.0.0.1:8080/ws/FWWSMODEL.apw
//If oMVCWS:GetDescription()
// MsgInfo( oMVCWS:cGetDescriptionResult )
//Else
//EndIf
If oMVCWS:GetXMLData()
// Retorno da GetXMLData
cXMLEstrut := oMVCWS:cGetXMLDataResult
// Retorna
// <ZA0_CODIGO order="2"><value></value></ZA0_CODIGO>
// <ZA0_NOME order="3"><value></value></ZA0_NOME>
// </ZA0MASTER>
//</COMP011M>
If oMVCWS:GetSchema()
Verso 4.0
110
Manual ADvPl utilizando o MVC
EndIf
// Cria o XML
cXML += '</COMP011M>'
oMVCWS:cModelXML := cXML
If oMVCWS:PutXMLData()
If oMVCWS:lPutXMLDataResult
Else
EndIf
Else
EndIf
Verso 4.0
111
Manual ADvPl utilizando o MVC
17.10 Web Services para modelos de dados que possuem duas ou mais entidades
Para a construo de Web Services que possuam duas ou mais entidades o que ser diferente
apenas o XML recebido que ter mais nveis. Observe o fonte exemplo:
#INCLUDE 'PROTHEUS.CH'
#INCLUDE 'XMLXFUN.CH'
#INCLUDE 'FWMVCDEF.CH'
//-------------------------------------------------------------------
/*/{Protheus.doc} COMPW021
@since 05/10/2009
@version P10
/*/
//-------------------------------------------------------------------
Local oMVCWS
Verso 4.0
112
Manual ADvPl utilizando o MVC
RpcSetType( 3 )
oMVCWS := WsFwWsModel():New()
oMVCWS:_URL := "http://127.0.0.1:8080/ws/FWWSMODEL.apw"
oMVCWS:cUserLogin := 'admin'
oMVCWS:cUserToken := 'admin'
oMVCWS:cPassword := ''
If oMVCWS:GetXMLData()
If oMVCWS:GetSchema()
cXMLEsquema := oMVCWS:cGetSchemaResult
EndIf
cXMLEstrut := oMVCWS:cGetXMLDataResult
//<ZA1_FILIAL order="1"><value></value></ZA1_FILIAL>
//<ZA1_MUSICA order="2"><value></value></ZA1_MUSICA>
//<ZA1_TITULO order="3"><value></value></ZA1_TITULO>
//<ZA1_DATA order="4"><value></value></ZA1_DATA>
Verso 4.0
113
Manual ADvPl utilizando o MVC
// <struct>
// <ZA2_FILIAL order="1"></ZA2_FILIAL>
// <ZA2_MUSICA order="2"></ZA2_MUSICA>
// <ZA2_ITEM order="3"></ZA2_ITEM>
// <ZA2_AUTOR order="4"></ZA2_AUTOR>
// </struct>
// <items>
// <ZA2_FILIAL></ZA2_FILIAL>
// <ZA2_MUSICA></ZA2_MUSICA>
// <ZA2_ITEM></ZA2_ITEM>
// <ZA2_AUTOR></ZA2_AUTOR>
// </item>
// </items>
// </ZA2DETAIL>
//</ZA1MASTER>
//</COMP021MODEL>
If oMVCWS:GetSchema()
cXMLEsquema := oMVCWS:cGetSchemaResult
EndIf
cXML := ''
Verso 4.0
114
Manual ADvPl utilizando o MVC
cXML += </ZA2DETAIL>'
cXML += '</ZA1MASTER>'
cXML += '</COMP021MODEL>'
oMVCWS:cModelXML := cXML
If oMVCWS:PutXMLData()
If oMVCWS:lPutXMLDataResult
Else
Verso 4.0
115
Manual ADvPl utilizando o MVC
EndIf
Else
EndIf
Else
EndIf
RpcClearEnv()
Return NIL
//-------------------------------------
Verso 4.0
116
Manual ADvPl utilizando o MVC
Verso 4.0
117
Manual ADvPl utilizando o MVC
AFTERLINE <bAfterLine>
BEFOREGRID <bBeforeGrid>
AFTERGRID <bAfterGrid>
LOADGRID <bGridLoad>
RELATION <aRelation>
ORDERKEY <cOrder>
UNIQUELINE <aUniqueLine>
AUTOINCREMENT <cFieldInc>
OPTIONAL
Onde:
TYPE <nType>
Tipo Numrico - Obrigatrio
Tipo de Estrutura
1 = 1 Tabela
2 = 1 Tabela Master/Detail
3 = 2 Tabelas Master/Detail
DESCRIPTION <cDescription>
Tipo Caracter - Obrigatrio
Descrio da Rotina
BROWSE <oBrowse>
Tipo Objeto - Obrigatrio
Objeto de Browse que ser utilizado
SOURCE <cSource>
Tipo Caracter - Obrigatrio
Nome do Fonte
MODELID <cModelID>
Tipo Caracter - Obrigatrio
Identificador (ID) do Model
FILTER <cFilter>
Tipo Caracter - Opcional
Filtro para Browse
CANACTIVE <bSetVldActive>
Tipo Bloco - Opcional
Bloco para validao da ativao do Model. Recebe como parmetro o Model
Ex. { |oModel| COMP011ACT( oModel ) }
Verso 4.0
118
Manual ADvPl utilizando o MVC
BEFORE <bBeforeModel>
Tipo Bloco - Opcional
Bloco de Pr Validao do Model. Recebe como parmetro o Model.
Ex. { |oModel| COMP011PRE( oModel ) }
AFTER <bAfterModel>
Tipo Bloco - Opcional
Bloco de Ps Validao do Model Recebe como parmetro o Model.
Ex. { |oModel| COMP011POS( oModel ) }
COMMIT <bCommit>
Tipo Bloco - Opcional
Bloco de persistncia dos dados (Commit) do Model. Recebe como parmetro o Model.
Ex. { |oModel| COMP022CM( oModel ) }
CANCEL <bCancel>
Tipo Bloco - Opcional
Bloco acionado no boto de cancelar. Recebe como parmetro o Model.
Ex. { |oModel| COMP011CAN( oModel ) }
BEFOREFIELD <bBeforeField>
Tipo Bloco - Opcional
Bloco de Pr Validao da FORMFIELD da tabela Master. Recebe como parmetro o ModelField,
identificador (ID) do local de execuo e identificador (ID) do Formulrio
Ex. { |oMdlF,cId ,cidForm| COMP023FPRE( oMdlF,cId ,cidForm) }
AFTERFIELD <bAfterField>
Manual ADvPl utilizando o MVC
Verso 4.0
119
Manual ADvPl utilizando o MVC
DETAIL <cDetailAlias>
Tipo Caracter - Obrigatrio para TYPE = 2 ou 3
Tabela Detail
BEFORELINE <bBeforeLine>
Tipo Bloco - Opcional
Bloco de Pr Validao da linha da FORMGRID da tabela Detail. Recebe como parmetro o
ModelGrid, o nmero da linha do FORMGRID, a ao e o campo da FORMGRID.
Ex. { |oMdlG,nLine,cAcao,cCampo| COMP023LPRE( oMdlG, nLine, cAcao, cCampo ) }
Usado apenas para TYPE = 2 ou 3
AFTERLINE <bAfterLine>
Tipo Bloco - Opcional
Bloco de Ps Validao da linha da FORMGRID da tabela Detail. Recebe como parmetro o
ModelGrid e o nmero da linha do FORMGRID.
Ex. { |oModelGrid, nLine| COMP022LPOS( oModelGrid, nLine ) }
Usado apenas para TYPE = 2 ou 3
BEFOREGRID <bBeforeGrid>
Tipo Bloco - Opcional
Bloco de Pr Validao da FORMGRID da tabela Detail. Recebe como parmetro o ModelGrid
Usado apenas para TYPE = 2 ou 3
AFTERGRID <bAfterGrid>
Tipo Bloco - Opcional
Bloco de Pr Validao da FORMGRID da tabela Detail. Recebe como parmetro o ModelGrid
Usado apenas para TYPE = 2 ou 3
LOADGRID <bGridLoad>
Verso 4.0
120
Manual ADvPl utilizando o MVC
//
//
#INCLUDE "PROTHEUS.CH"
#INCLUDE "FWMVCDEF.CH"
Local oBrowse
Verso 4.0
121
Manual ADvPl utilizando o MVC
NEW MODEL ;
TYPE 1 ;
BROWSE oBrowse ;
SOURCE "COMP041_MVC" ;
MODELID "MDCOMP041" ;
FILTER "ZA0_TIPO=='1'" ;
MASTER "ZA0" ;
Return NIL
Return .T.
FWFormCommit( oModel )
Return NIL
Verso 4.0
122
Manual ADvPl utilizando o MVC
//
//
#INCLUDE "PROTHEUS.CH"
#INCLUDE "FWMVCDEF.CH"
Local oBrowse
NEW MODEL ;
TYPE 2 ;
BROWSE oBrowse ;
SOURCE "COMP042_MVC" ;
Verso 4.0
123
Manual ADvPl utilizando o MVC
MODELID "MDCOMP042" ;
MASTER "ZA2" ;
{ 'ZA2_MUSICA', 'ZA2_MUSICA' } } ;
UNIQUELINE { 'ZA2_AUTOR' } ;
AUTOINCREMENT 'ZA2_ITEM'
Return NIL
O Resultado :
Verso 4.0
124
Manual ADvPl utilizando o MVC
//
//
#INCLUDE "PROTHEUS.CH"
#INCLUDE "FWMVCDEF.CH"
Local oBrowse
NEW MODEL ;
TYPE 3 ;
DESCRIPTION "Musicas" ;
BROWSE oBrowse ;
SOURCE "COMP043_MVC" ;
MODELID "MDCOMP043" ;
MASTER "ZA1" ;
Verso 4.0
125
Manual ADvPl utilizando o MVC
DETAIL "ZA2" ;
{ 'ZA2_MUSICA', 'ZA1_MUSICA' } } ;
UNIQUELINE { 'ZA2_AUTOR' } ;
AUTOINCREMENT 'ZA2_ITEM'
Return NIL
O Resultado :
Verso 4.0
126
Manual ADvPl utilizando o MVC
//
//
#INCLUDE "PROTHEUS.CH"
#INCLUDE "FWMVCDEF.CH"
Local oBrowse
NEW MODEL ;
TYPE 1 ;
BROWSE oBrowse ;
SOURCE "COMP044_MVC" ;
MENUDEF "COMP044_MVC" ;
Verso 4.0
127
Manual ADvPl utilizando o MVC
MODELID "MDCOMP044" ;
FILTER "ZA0_TIPO=='1'" ;
MASTER "ZA0"
Return NIL
//-------------------------------------------------------------------
Local aRotina := {}
Return aRotina
O Resultado :
Verso 4.0
128
Manual ADvPl utilizando o MVC
Return oModel
Return oModel
Nos exemplos acima a nova aplicao usar os mesmos componentes da aplicao j existente, no
caso, o que est definido na ModelDef do fonte COMP011_MVC.
Exemplo
#INCLUDE 'PROTHEUS.CH'
#INCLUDE 'FWMVCDEF.CH'
//-------------------------------------------------------------------
Local oBrowse
oBrowse := FWMBrowse():New()
oBrowse:SetAlias('ZA0')
Manual ADvPl utilizando o MVC
Verso 4.0
129
Manual ADvPl utilizando o MVC
oBrowse:SetDescription('Cadastro de Autor/Interprete')
oBrowse:DisableDetails()
oBrowse:Activate()
Return NIL
//-------------------------------------------------------------------
//-------------------------------------------------------------------
Return oModel
//-------------------------------------------------------------------
Return oView
Verso 4.0
130
Manual ADvPl utilizando o MVC
No nosso exemplo, acrescentaremos um novo formulrio, ver cap. 0 5.3 Criao de um componente
de formulrios no modelo de dados (AddFields) para detalhes.
Note que em nossa nova aplicao no usamos o MPFormModel, pois estamos apenas
acrescentando entidade. O MPFormModel foi usado na aplicao original.
// Adiciona a nova FORMFIELD
Com isso criamos um modelo a partir de outro e acrescentamos um novo componente de formulrio.
Veremos agora como reutilizar a interface (View), tambm acrescentando um novo componente.
O primeiro passo criar a estrutura da nova entidade, ver cap. 0 5.1 Construes de uma estrutura
de dados (FWFormStruct).
// Cria a estrutura a ser acrescentada na View
Instanciaremos o modelo utilizado pela interface, note que no instanciaremos o modelo original e sim
o modelo da nova aplicao que j tem o novo componente acrescido em seu modelo de dados.
// Cria um objeto de Modelo de Dados baseado no ModelDef do fonte informado
Verso 4.0
131
Manual ADvPl utilizando o MVC
Adicionamos o novo componente da view e associamos ao criado no modelo, ver cap. 0 5.8 Criao
de um componente de formulrios na interface (AddField) para detalhes.
// Adiciona no nosso View um controle do tipo FormFields(antiga enchoice)
Temos que criar um box para o novo componente. preciso criar sempre um box vertical dentro de
um horizontal e vice-versa como na COMP011_MVC o box j existente horizontal, cria-se um vertical
primeiro, para detalhes ver cap. 0 6.13 Exibio dos dados na interface (CreateHorizontalBox /
CreateVerticalBox).
// 'TELANOVA' o box existente na interface original
// Novos Boxes
Com isso criamos uma interface a partir de outra e acrescentamos um novo componente.
Um exemplo de aplicao para este conceito seria a internacionalizaco, onde poderamos ter um
modelo bsico e o incrementaramos conforme a localizao. Para entender melhor a internacionalizao, veja
o Apndice A. Abaixo temos o exemplo completo da aplicao que reutiliza componentes.
Verso 4.0
132
Manual ADvPl utilizando o MVC
#INCLUDE 'FWMVCDEF.CH'
//-------------------------------------------------------------------
Local oBrowse
oBrowse := FWMBrowse():New()
oBrowse:SetAlias('ZA0')
oBrowse:Activate()
Return NIL
//-------------------------------------------------------------------
Local aRotina := {}
Return aRotina
Verso 4.0
133
Manual ADvPl utilizando o MVC
//-------------------------------------------------------------------
Return oModel
//-------------------------------------------------------------------
oView:SetModel( oModel )
Verso 4.0
134
Manual ADvPl utilizando o MVC
// Novos Boxes
Return oView
Apndice A
O Framework MVC do Microsiga Protheus e a internacionalizao. Internacionalizao (I18N) e
localizao (L10N) so processos de desenvolvimento e/ou adaptao de softwares, para uma lngua e/ou
cultura de um pas. A internacionalizao de um software no fornece um novo Sistema, somente adapta as
mensagens do Sistema lngua e cultura locais. A localizao por sua vez, adiciona novos elementos do
pas ao Sistema, como processos, aspectos legais, entre outros. O Framework MVC auxilia a localizao do
Sistema, componentizando o software de forma que a parte comum a todos os pases seja desagregada da
parte no-comum, incluindo-se interface e regra de negcio.
Por exemplo, tome como base o formulrio Nota Fiscal/Invoice. Este formulrio tem como
caracterstica comum em todos os pases os elementos: Origem, Destino, Lista de produtos, Transporte e
Faturas.
Em certos pases como o Brasil, necessrio registrar elementos legais, como impostos,
escriturao, cdigos de classificao, entre outros. A alternativa que se tem duplicar o cdigo ou alterar
o cdigo inserindo linhas de cdigo dos elementos localizados. Apesar de esta alternativa funciona r bem no
incio, ao longo do tempo mostra-se impraticvel devido ao volume de implementaes diferentes para cada
pas, causando grandes transtornos e um alto custo para a sustentao do Sistema.
Manual ADvPl utilizando o MVC
Verso 4.0
135
Manual ADvPl utilizando o MVC
O Framework MVC traz uma luz racional e simples para este problema. A herana de formulrios.
possvel construir um formulrio comum para a Nota Fiscal/Invoice que no tenha nenhum elemento de
localizao e utiliz-lo pela herana, como base para os formulrios localizados.
Neste modelo, garante-se a evoluo da localizao e da parte comum do formulrio sem que uma
implementao afete a outra reduzindo o custo de sustentao do produto.
A herana do framework MVC pode ocorrer no Model e View ou somente no View. Neste momento
vocs devem estar se perguntado como isto pode ser feito. A resposta est no par de funes FWLoadModel
e FWLoadView, como poder ser visto no cdigo abaixo:
#INCLUDE MATA103BRA.CH
oModel:AddField(....)
oModel:AddGrid(....)
Return(oModel)
oView:AddField()
oView:AddGrid()
Return (oView)
Verso 4.0
136
Manual ADvPl utilizando o MVC
ndice Remissivo
Verso 4.0
137
Manual ADvPl utilizando o MVC
Verso 4.0
138