Pragiva — Tecnologia na prática

MT100TOK o ponto de entrada do OK do Documento de Entrada

MT100TOK dispara ao confirmar o Documento de Entrada, recebe só {lRet} e bloqueia com .F. No MATA103 um .T. não desfaz a reprovação; em outra rotina, sim.

Desenvolvimento Referência técnica 4 min de leitura

Assista o vídeo

MT100TOK em resumo

Onde fica
função A103TudOk(), do MATA103 (Documento de Entrada). É a validação “tudo OK” do grid, executada ao confirmar a tela.
Quando dispara
ao confirmar uma inclusão ou uma classificação, dentro do bloco de validações do padrão e antes da gravação.
PARAMIXB
{lRet}, um elemento lógico com o resultado das validações até ali.
Retorno
usado. .F. interrompe a confirmação.
Serve para bloquear?
Sim. É o lugar certo para uma regra que precisa olhar o documento inteiro antes de gravar.
Consulta rápida7 seções

Para o mecanismo geral, veja Ponto de entrada no Protheus.

Quando ele roda de fato

Na tela do MATA103, a confirmação só executa a validação do grid quando a operação é inclusão ou classificação. Em alteração e exclusão o padrão nem chama TudoOk(), então o MT100TOK não roda. Uma regra escrita aqui não alcança essas operações.

Dentro de A103TudOk() a chamada fica no bloco que só é executado enquanto a validação continua aprovada. Se o padrão já reprovou antes de chegar nele, o ponto de entrada nem é chamado. Isso significa que, no MATA103, PARAMIXB[1] costuma chegar .T.. Ele só chega .F. se uma validação dentro do próprio bloco (por exemplo a do PCO ou a da integração de exportação) reprovou logo antes.

Depois do ponto de entrada o padrão ainda valida: bloqueio de pedidos amarrados ao processo, natureza bloqueada e outras conferências. Passar pelo MT100TOK não significa que o documento está aprovado.

O MT100TOK vem antes da gravação. Para o que acontece na gravação, veja o MT100GRV; para o que acontece depois de tudo, o MT103FIM.

Como o retorno é tratado

No MATA103 a leitura do retorno é defensiva: o padrão só aproveita o retorno quando ele é lógico e falso. Dois efeitos:

  • .F. bloqueia. A confirmação não avança.
  • .T. ou qualquer valor não lógico não muda nada. O .T. do seu PE não desfaz uma reprovação anterior: o padrão nunca transforma um .F. em .T..

Nada disso vale para as outras rotinas que chamam o mesmo ponto de entrada.

Ele não é só do Documento de Entrada

O nome MT100TOK é chamado por mais de uma rotina do pacote:

RotinaFunçãoComo trata o retorno
MATA103, Documento de EntradaA103TudOk()Só um .F. lógico é aproveitado
MATA920, nota fiscal de saídaA920Tudok()Atribuição direta do retorno a lRet
MATA100, entrada de notas fiscais de compraA100TudOk()Atribuição direta do retorno a lRet

Na A920Tudok(), a chamada vem logo depois de o padrão reprovar uma nota sem itens ativos, e a atribuição é incondicional. Um Return .T. ali desfaz essa reprovação. O mesmo ponto de entrada, com a mesma assinatura, se comporta de forma diferente conforme a rotina que o chamou.

Se o seu MT100TOK é feito para o Documento de Entrada, diga isso no código: confira a pilha de chamadas e deixe as outras rotinas passarem sem alteração (o exemplo abaixo faz isso).

Duas consequências práticas:

  1. Comece sempre com lRet := PARAMIXB[1] e devolva lRet, alterado só quando a sua regra reprovar. Assim você nunca aprova o que o padrão barrou, em qualquer rotina.
  2. Sempre devolva um lógico explícito. Nas rotinas com atribuição direta, um Return sem valor entrega Nil, e é esse Nil que passa a ser o lRet.

O que ele recebe

PosiçãoTipoConteúdo
PARAMIXB[1]LógicoResultado das validações do padrão até a chamada

Como só vem o lRet, o restante você lê do ambiente da rotina. No MATA103 estão disponíveis aHeader e aCols (o grid, com a última posição de cada linha indicando linha deletada) e, entre outras, cTipo, cA100For e cLoja, que o próprio A103TudOk() usa. Não use variável do padrão sem conferir que ela existe na rotina que chamou: em MATA920 e MATA100 o conjunto é diferente.

Exemplo

Regra de exemplo: exigir centro de custo em todo item ativo do documento. A regra vale só para o Documento de Entrada.

ADVPL / TLPP
#Include "Protheus.ch"

/*/{Protheus.doc} MT100TOK
Chamado ao confirmar o Documento de Entrada (A103TudOk).
Exige centro de custo (D1_CC) em todos os itens não deletados.
@type user function
@return logical, .F. interrompe a confirmação
/*/
User Function MT100TOK()

    Local lRet   := .T.
    Local nPosCC := 0
    Local nX     := 0

    // O retorno do padrão entra como ponto de partida: nunca aprovamos
    // o que ele já reprovou, seja qual for a rotina que chamou.
    If Type("PARAMIXB") <> "A" .Or. Len(PARAMIXB) < 1 .Or. ValType(PARAMIXB[1]) <> "L"
        Return .T.
    EndIf
    lRet := PARAMIXB[1]

    If !lRet
        Return lRet
    EndIf

    // O mesmo PE também é chamado por outras rotinas. A regra é só do MATA103.
    If !FwIsInCallStack("MATA103")
        Return lRet
    EndIf

    nPosCC := aScan(aHeader, {|x| AllTrim(x[2]) == "D1_CC"})
    If nPosCC == 0
        Return lRet
    EndIf

    For nX := 1 To Len(aCols)
        // Última posição de cada linha do grid: .T. quando deletada
        If !aCols[nX][Len(aHeader) + 1] .And. Empty(aCols[nX][nPosCC])
            Help(" ", 1, "MT100TOK",, ;
                "Informe o centro de custo no item " + cValToChar(nX) + ".", 1, 0)
            lRet := .F.
            Exit
        EndIf
    Next nX

Return lRet

Três detalhes do exemplo:

  • O Return antecipado com lRet mantém o que o padrão decidiu e não depende de qual rotina chamou.
  • A mensagem vem antes do .F.. Sem ela, o botão OK só não responde, e o usuário abre chamado dizendo que a tela travou.
  • O laço pára na primeira falha: uma mensagem por confirmação basta.

Armadilhas

Devolver .T. por reflexo. No MATA103 é inofensivo, mas em outras rotinas que chamam o PE desfaz a reprovação do padrão. Devolva lRet.

Abrir diálogo sob ExecAuto. O A103TudOk() também é chamado quando o documento entra por ExecAuto, através da validação automática do grid. Um MsgYesNo ali trava a thread. Prefira Help() ou registro em log, ou proteja o diálogo com IsBlind().

Esperar o PE em alteração ou exclusão. Como visto, a confirmação nessas operações não passa pela validação do grid.

Achar que o PE roda em todo ExecAuto. No fonte, a chamada é condicionada a uma variável interna que o padrão liga por padrão. Quando a rotina é chamada com o parâmetro que mantém a tela aberta para o usuário, o padrão desliga essa variável e a pula na primeira passagem, religando-a logo em seguida. Se a sua integração depende do MT100TOK nesse cenário, teste no seu ambiente.

Confundir com o MT100GRV. O MT100TOK valida a tela; o MT100GRV roda na gravação, com o documento ainda em memória.

Os vizinhos

PEMomentoRetorno é usado?
MT100TOKAo confirmar a tela, na validação do gridSim, só o .F. no MATA103
MT100GRVAntes da gravação física do cabeçalhoSim, .F. interrompe
MT103FIMNo fim da rotina, depois da gravaçãoNão

Se a regra depende do documento já gravado, o lugar é o MT103FIM, não este.

Continue por aqui