Hoje vou mostrar para vocês, o que fazer quando uma rotina não tem um ExecAuto.
Todos sabem das vantagens de se utilizar uma operação com ExecAuto, sendo que ele passa por todas as validações do sistema, gatilhos e pontos de entrada.
Apenas para simplificar, imagine criar um pedido de venda, e ter que validar saldos em estoque, risco do cliente, se os produtos existem e estão bloqueados, a transportadora, tabela de preço, vendedor, etc… Por isso existe o recurso que é genial de execução automática, onde apenas é informado os campos e todo o processo é feito sozinho pelo Protheus.
Porém, algumas rotinas não vêm com esse recurso nativo, então hoje iremos ver 2 cenários para essa questão.
Rotinas que são em MVC
As rotinas que são em MVC, você consegue fazer a execução automática, instanciando o modelo de dados, e atribuindo os valores aos campos.
Para esse caso, eu já tive que fazer em duas rotinas que não tinham ExecAuto no padrão, a Convocações de Funcionários (GPEA018) e a Produtos x Clientes (MATA370).
Para demonstrarmos um exemplo de como utilizar, abaixo segue o código para Execauto da MATA370:
//Define as variáveis lDeuCerto := .F. cCliente := "000001" cLojaCli := "01" cProduto := "PROD0001" nPreco := 10.99 dDataRef := Date() DbSelectArea('SA7') SA7->(DbSetOrder(1)) //A7_FILIAL + A7_CLIENTE + A7_LOJA + A7_PRODUTO //Somente se não encontrar Produto x Cliente irá cair dentro da condição If ! SA7->(DbSeek(FWxFilial('SA7') + cCliente + cLojaCli + cProduto)) //Instanciando a rotina MATA370, buscando o model dos campos da SA7MASTER e definindo a operação como inclusão oModel := FWLoadModel("MATA370") oSA7Mod:= oModel:GetModel("SA7MASTER") oModel:SetOperation(3) oModel:Activate() //Define as informações básicas da rotina oSA7Mod:setValue("A7_FILIAL", FWxFilial("SA7") ) oSA7Mod:setValue("A7_CLIENTE", cCliente ) oSA7Mod:setValue("A7_LOJA", cLojaCli ) oSA7Mod:setValue("A7_PRODUTO", cProduto ) oSA7Mod:setValue("A7_PRECO01", nPreco ) oSA7Mod:setValue("A7_DTREF01", dDataRef ) //Tenta validar as informações e realizar o commit If oModel:VldData() If oModel:CommitData() lDeuCerto := .T. EndIf EndIf //Se não deu certo a operação de inclusão If ! lDeuCerto //Busca o Erro do Modelo de Dados aErro := oModel:GetErrorMessage() //Monta o Texto que será mostrado na tela AutoGrLog("Id do formulário de origem:" + ' [' + AllToChar(aErro[01]) + ']') AutoGrLog("Id do campo de origem: " + ' [' + AllToChar(aErro[02]) + ']') AutoGrLog("Id do formulário de erro: " + ' [' + AllToChar(aErro[03]) + ']') AutoGrLog("Id do campo de erro: " + ' [' + AllToChar(aErro[04]) + ']') AutoGrLog("Id do erro: " + ' [' + AllToChar(aErro[05]) + ']') AutoGrLog("Mensagem do erro: " + ' [' + AllToChar(aErro[06]) + ']') AutoGrLog("Mensagem da solução: " + ' [' + AllToChar(aErro[07]) + ']') AutoGrLog("Valor atribuído: " + ' [' + AllToChar(aErro[08]) + ']') AutoGrLog("Valor anterior: " + ' [' + AllToChar(aErro[09]) + ']') //Mostra a mensagem de Erro MostraErro() EndIf //Por fim, desativa o modelo de dados oModel:DeActivate() EndIf
Ah Daniel, mas como vou saber se uma rotina está em MVC? Dê uma olhada nesse link Saiba como identificar se uma função é em MVC e como fazer seu Ponto de Entrada.
Rotinas que não são em MVC
Essa aqui é mais punk para fazer. No caso, você deve simular uma operação manualmente no Protheus, rastreando via DbMonitor (veja como, clicando aqui).
Após você rastrear, você vai procurar as instruções de INSERT e UPDATE nas tabelas.
Com essas linhas, você vai ter que codificar no seu fonte, através de RecLock, então por exemplo, se tiver um insert into com 30 campos, você vai ter que fazer um RecLock true nessa tabela com esses 30 campos.
E se na mesma operação, tiver algum UPDATE em tabela estrangeira, atualizando alguma informação, você vai ter que fazer um RecLock false atualizando também na sua customização.
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Bicho, vc é o cara.
Sempre que vou trabalhar em customizações venho sempre por aqui dar uma pescada. Quase sempre vc já fez algo parecido e compartilhou.
Me senti na obrigação de vir aqui e deixar pelo menos um obrigado.
Saúde e sucesso pra vc.
Grande Edson.
Bondade sua jovem.
Obrigado pelo comentário e feedback.
Grande abraço.
Se a intenção for apenas descobrir se a rotina está ou não em MVC faça um teste ai..
Abra a rotina e peça para incluir um registro, se o botão que aparecer for o de nome Salvar (a rotina ainda não está em MVC), se aparecer Confirmar (a rotina está em MVC).
Boa tarde Carlos, tudo joia?
Opa, obrigado pelo comentário. Sim, se for para só identificar, é só seguir o que você falou que tem no link da TOTVS – https://centraldeatendimento.totvs.com/hc/pt-br/articles/360016345572-Cross-Segmento-Backoffice-Linha-Protheus-ADVPL-Como-validar-se-uma-rotina-est%C3%A1-em-MVC
Mas se você quiser, no link que citamos acima, além de mostrar se uma rotina é em MVC, já é montado o exemplo do ponto de entrada dela (com os ifs dos ids) – https://terminaldeinformacao.com/2018/04/24/saiba-como-identificar-se-uma-funcao-e-em-mvc-como-fazer-seu-ponto-de-entrada/
É um pouco antigo o fonte (de 2018), mas é uma mão na roda para montar o ponto de entrada e já trazer informações do Model.
Um grande abraço.