Olá pessoal…
Hoje vou mostrar uma aula em MVC para alterar as validações padrões bPre, bPos, bCommit e bCancel.
Abaixo o código fonte completo usado na aula:
//Bibliotecas #Include 'Protheus.ch' #Include 'FWMVCDef.ch' //Variáveis Estáticas Static cTitulo := "Artista" Static cDefault := "NOME DO ARTISTA" /*/{Protheus.doc} zMod1b Exemplo de Modelo 1 para cadastro de Artistas com validações @author Atilio @since 03/09/2016 @version 1.0 @return Nil, Função não tem retorno @example u_zMod1b() /*/ User Function zMod1b() Local aArea := GetArea() Local oBrowse Local cFunBkp := FunName() SetFunName("zMod1b") //Instânciando FWMBrowse - Somente com dicionário de dados oBrowse := FWMBrowse():New() //Setando a tabela de cadastro de Autor/Interprete oBrowse:SetAlias("ZZ1") //Setando a descrição da rotina oBrowse:SetDescription(cTitulo) //Ativa a Browse oBrowse:Activate() SetFunName(cFunBkp) RestArea(aArea) Return Nil /*---------------------------------------------------------------------* | Func: MenuDef | | Autor: Daniel Atilio | | Data: 03/09/2016 | | Desc: Criação do menu MVC | *---------------------------------------------------------------------*/ Static Function MenuDef() Local aRot := {} //Adicionando opções ADD OPTION aRot TITLE 'Visualizar' ACTION 'VIEWDEF.zMod1b' OPERATION MODEL_OPERATION_VIEW ACCESS 0 //OPERATION 1s ADD OPTION aRot TITLE 'Incluir' ACTION 'VIEWDEF.zMod1b' OPERATION MODEL_OPERATION_INSERT ACCESS 0 //OPERATION 3 ADD OPTION aRot TITLE 'Alterar' ACTION 'VIEWDEF.zMod1b' OPERATION MODEL_OPERATION_UPDATE ACCESS 0 //OPERATION 4 ADD OPTION aRot TITLE 'Excluir' ACTION 'VIEWDEF.zMod1b' OPERATION MODEL_OPERATION_DELETE ACCESS 0 //OPERATION 5 Return aRot /*---------------------------------------------------------------------* | Func: ModelDef | | Autor: Daniel Atilio | | Data: 03/09/2016 | | Desc: Criação do modelo de dados MVC | *---------------------------------------------------------------------*/ Static Function ModelDef() //Blocos de código nas validações Local bVldPre := {|| u_zM1bPre()} //Antes de abrir a Tela Local bVldPos := {|| u_zM1bPos()} //Validação ao clicar no Confirmar Local bVldCom := {|| u_zM1bCom()} //Função chamadao ao cancelar Local bVldCan := {|| u_zM1bCan()} //Função chamadao ao cancelar //Criação do objeto do modelo de dados Local oModel := Nil //Criação da estrutura de dados utilizada na interface Local oStZZ1 := FWFormStruct(1, "ZZ1") //Editando características do dicionário oStZZ1:SetProperty('ZZ1_COD', MODEL_FIELD_WHEN, FwBuildFeature(STRUCT_FEATURE_WHEN, '.F.')) //Modo de Edição oStZZ1:SetProperty('ZZ1_COD', MODEL_FIELD_INIT, FwBuildFeature(STRUCT_FEATURE_INIPAD, 'GetSXENum("ZZ1", "ZZ1_COD")')) //Ini Padrão oStZZ1:SetProperty('ZZ1_DESC', MODEL_FIELD_OBRIGAT, Iif(RetCodUsr()!='000000', .T., .F.) ) //Campo Obrigatório oStZZ1:SetProperty('ZZ1_DESC', MODEL_FIELD_INIT, FwBuildFeature(STRUCT_FEATURE_INIPAD, "'"+cDefault+"'")) //Ini Padrão //Instanciando o modelo, não é recomendado colocar nome da user function (por causa do u_), respeitando 10 caracteres oModel := MPFormModel():New("zMod1bM", bVldPre, bVldPos, bVldCom, bVldCan) //Atribuindo formulários para o modelo oModel:AddFields("FORMZZ1",/*cOwner*/,oStZZ1) //Setando a chave primária da rotina oModel:SetPrimaryKey({'ZZ1_FILIAL','ZZ1_COD'}) //Adicionando descrição ao modelo oModel:SetDescription("Modelo de Dados do Cadastro "+cTitulo) //Setando a descrição do formulário oModel:GetModel("FORMZZ1"):SetDescription("Formulário do Cadastro "+cTitulo) //Pode ativar? oModel:SetVldActive( { | oModel | fAlterar( oModel ) } ) Return oModel /*---------------------------------------------------------------------* | Func: ViewDef | | Autor: Daniel Atilio | | Data: 03/09/2016 | | Desc: Criação da visão MVC | *---------------------------------------------------------------------*/ Static Function ViewDef() Local aStruZZ1 := ZZ1->(DbStruct()) //Criação do objeto do modelo de dados da Interface do Cadastro de Autor/Interprete Local oModel := FWLoadModel("zMod1b") //Criação da estrutura de dados utilizada na interface do cadastro de Autor Local oStZZ1 := FWFormStruct(2, "ZZ1") //pode se usar um terceiro parâmetro para filtrar os campos exibidos { |cCampo| cCampo $ 'SZZ1_NOME|SZZ1_DTAFAL|'} //Criando oView como nulo Local oView := Nil //Criando a view que será o retorno da função e setando o modelo da rotina oView := FWFormView():New() oView:SetModel(oModel) //Atribuindo formulários para interface oView:AddField("VIEW_ZZ1", oStZZ1, "FORMZZ1") //Criando um container com nome tela com 100% oView:CreateHorizontalBox("TELA",100) //Colocando título do formulário oView:EnableTitleView('VIEW_ZZ1', 'Dados - '+cTitulo ) //Força o fechamento da janela na confirmação oView:SetCloseOnOk({||.T.}) //O formulário da interface será colocado dentro do container oView:SetOwnerView("VIEW_ZZ1","TELA") Return oView /*/{Protheus.doc} zM1bPre Função chamada na criação do Modelo de Dados (pré-validação) @type function @author Atilio @since 03/09/2016 @version 1.0 /*/ User Function zM1bPre() Local oModelPad := FWModelActive() Local nOpc := oModelPad:GetOperation() Local lRet := .T. //Se for inclusão ou exclusão If nOpc == MODEL_OPERATION_INSERT If RetCodUsr() == '000000' oModelPad:GetModel('FORMZZ1'):GetStruct():SetProperty('ZZ1_COD', MODEL_FIELD_WHEN, FwBuildFeature(STRUCT_FEATURE_WHEN, '.T.')) EndIf EndIf Return lRet /*/{Protheus.doc} zM1bPos Função chamada no clique do botão Ok do Modelo de Dados (pós-validação) @type function @author Atilio @since 03/09/2016 @version 1.0 /*/ User Function zM1bPos() Local oModelPad := FWModelActive() Local cDescri := oModelPad:GetValue('FORMZZ1', 'ZZ1_DESC') Local lRet := .T. //Se a descrição estiver em branco If Empty(cDescri) .Or. Alltrim(Upper(cDescri)) == cDefault lRet := .F. Aviso('Atenção', 'Campo Descrição esta em branco!', {'OK'}, 03) EndIf Return lRet /*/{Protheus.doc} zM1bCom Função chamada após validar o ok da rotina para os dados serem salvos @type function @author Atilio @since 03/09/2016 @version 1.0 /*/ User Function zM1bCom() Local oModelPad := FWModelActive() Local cCodigo := oModelPad:GetValue('FORMZZ1', 'ZZ1_COD') Local cDescri := oModelPad:GetValue('FORMZZ1', 'ZZ1_DESC') Local nOpc := oModelPad:GetOperation() Local lRet := .T. //Se for Inclusão If nOpc == MODEL_OPERATION_INSERT RecLock('ZZ1', .T.) ZZ1_FILIAL := FWxFilial('ZZ1') ZZ1_COD := cCodigo ZZ1_DESC := cDescri ZZ1->(MsUnlock()) ConfirmSX8() Aviso('Atenção', 'Inclusão realizada!', {'OK'}, 03) //Se for Alteração ElseIf nOpc == MODEL_OPERATION_UPDATE RecLock('ZZ1', .F.) ZZ1_DESC := cDescri ZZ1->(MsUnlock()) Aviso('Atenção', 'Alteração realizada!', {'OK'}, 03) //Se for Exclusão ElseIf nOpc == MODEL_OPERATION_DELETE RecLock('ZZ1', .F.) DbDelete() ZZ1->(MsUnlock()) Aviso('Atenção', 'Exclusão realizada!', {'OK'}, 03) EndIf Return lRet /*/{Protheus.doc} zM1bCan Função chamada ao cancelar as informações do Modelo de Dados (botão Cancelar) @type function @author Atilio @since 03/09/2016 @version 1.0 /*/ User Function zM1bCan() Local oModelPad := FWModelActive() Local lRet := .T. //Somente permite cancelar se o usuário confirmar lRet := MsgYesNo("Deseja cancelar a operação?", "Atenção") Return lRet /*---------------------------------------------------------------------* | Func: fAlterar | | Autor: Daniel Atilio | | Data: 03/09/2016 | | Desc: Define se pode abrir o Modelo de Dados | *---------------------------------------------------------------------*/ Static Function fAlterar( oModel ) Local lRet := .T. Local nOperation := oModel:GetOperation() //Se for exclusão If nOperation == MODEL_OPERATION_DELETE //Se não for o Administrador If RetCodUsr() != '000000' lRet := .F. Aviso('Atenção', 'Somente o Administrador pode excluir registros!', {'OK'}, 03) EndIf EndIf Return lRet
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Parabéns pelo exemplo Daniel estou utilizando sempre aqui na empresa, abraços.
Grande Robs.
Obrigado jovem.
Aquele abraço.
Parabéns pelo excelente exemplo MVC.Com certeza ajudará muitos analistas
Boa noite Artur.
Eu que agradeço jovem.
Um grande abraço.
Grato pelo excelente conteúdo em MVC! Gostaria de deixar a sugestão de um artigo informando como inserir um botão com chamada para uma outra tela utilizando o ponto de entrada BUTTON..
Boa noite Allan, tudo bem?
Na verdade já preparei o fonte para essa aula de pontos de entrada em MVC, mas está muito corrido esse fim de ano.
Pode ficar tranquilo, que será postado sim.
Um grande abraço.
Boa tarde, Prof Daniel!! Ótima aula! Porém minha situação se difere um pouco, gostaria de saber se tens alguma sugestão:
Tenho um cadastro “ALUNOS”, um segundo cadastro “MATÉRIAS” e um terceiro “ALUNOxMATÉRIAS”. Considerando relacionamento de 1 aluno para N matérias, gostaria de saber como posso fazer a relação entre essas três tabelas( “ALUNOS”,”MATÉRIAS” e “ALUNOxMATÉRIAS”).
Como faço para, no cadastro “ALUNOS”, mostrar as matérias em que este está cadastrado, por exemplo?
ou como posso, no cadastro “ALUNOxMATÉRIAS”, ligar 1 registro da tabela “ALUNOS” a um registro da tabela “MATÉRIAS”?
Obs.
A tabela “ALUNOxMATÉRIAS” possui os campos “FILIAL”, “COD_ALUNO” e “COD_MATERIA”.
A tabela “ALUNOS” possui os campos “FILIAL”, “COD_ALUNO” e “NOME”
A tabela “MATÉRIAS” possui os campos “FILIAL”, “COD_MATERIA” e “NOME_MATERIA”
Bom dia Gabriela, tudo bem?
Nesse exemplo, você poderia criar uma tabela de vínculo, que conteria o COD_ALUNO, COD_MATERIA e algum outro campo, como observação.
Ai você poderia cadastrar isso em uma Modelo 2 mesmo.
Um grande abraço.
Boa tarde professor Daniel, estou com a seguinte dúvida:
Static Function fAlterar(oModel)
Local lRet := .T.
Local nOperation := oModel:GetOperation()
//Se for exclusão
If nOperation == MODEL_OPERATION_DELETE
//Se não for o Administrador
If RetCodUsr() != ‘000000’
lRet := .F.
Aviso(‘Atenção’, ‘Somente o Administrador pode excluir registros!’, {‘OK’}, 03)
EndIf
EndIf
Return lRet
como faria para bloquear a exclusão caso minha rotina estivesse com a legenda vermelha de encerrado?
Desde já agradeço
Bom dia jovem, tudo bem?
Se eu entendi bem, você gostaria de bloquear uma operação se sua legenda estivesse vermelha.
Acho que a forma mais fácil, é pegar a condição da sua legenda (por exemplo, TAB->CAMPO == ‘1’), copiar e colocar em um If, e se cair dentro desse If, o seu lRet vai ser falso (.F.).
Qualquer dúvida, fico à disposição.
Um grande abraço.
Boa tarde professor Daniel!
na Static Function fAlterar(), como faria para bloquear a exclusão se a minta rotina estivesse com a legenda vermelha de encerrada?
Desde já agradeço.
Boa tarde Atilio,
Eu estou usando esse seu exemplo para aplicar uma “validação” no bcommit de uma alteração em um grid tipo do seu exemplo zmodel3
Se eu aplico sua validação como no exemplo apresentando uma mensagem ela funciona perfeitamente, mas nesse momento eu tambem executo um msexecauto que faz uma baixa no SD3 e usando o execauto, a gravação em si do grid para de funcionar. O execauto funciona perfeitamente mas o grid que eu estava fazendo a alteração não se altera. Imagino que seja algo como um desposicionamento e imagino que eu tenha que forçar a gravação agora por conta disso. Tem algum exemplo de como eu posso gravar os dados do grid que estou posicionado…pois a função do “Bcommit” com o execauto não faz mais a atualização dos dados do cadastro….obrigado
Bom dia Mauricio, tudo joia?
Então, esse é um exemplo bem antigo (2016), acontece que o bCommit foi descontinuado em MVC, e foi substituído pelo FWModelEvent.
Ai dentro dele você vai ter o BeforeTTS (antes da gravação), o InTTS (durante a gravação) e o AfterTTS (após a gravação).
Nesse link tem um exemplo completo de como migrar do antigo bCommit para essa forma nova: https://terminaldeinformacao.com/2023/03/24/como-utilizar-a-fwmodelevent-no-lugar-do-commit-em-uma-rotina-mvc/
Tenha um ótimo e abençoado fim de semana.
Um grande abraço.