Pragiva — Tecnologia na prática

A010TOK o ponto de entrada da validação do Cadastro de Produto

A010TOK roda ao confirmar inclusão ou alteração do produto, sem PARAMIXB, e bloqueia com .F. No MVC do MATA010 ele continua valendo, só muda quem o chama.

Desenvolvimento Referência técnica 4 min de leitura

Assista o vídeo

A010TOK em resumo

Onde fica
validação final do MATA010 (Cadastro de Produto, tabela SB1). Na tela clássica é A010TudoOk(); no cadastro em MVC é o evento de pós-validação do formulário SB1MASTER.
Quando dispara
ao confirmar a inclusão ou a alteração, antes de gravar.
PARAMIXB
não existe. O padrão chama o ponto de entrada sem enviar parâmetros.
Retorno
usado. .F. interrompe a confirmação; qualquer valor que não seja lógico é tratado como .T..
Serve para bloquear?
Sim, para inclusão e alteração. Exclusão não passa por ele.
Consulta rápida5 seções

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

Sem PARAMIXB: de onde vêm os dados

Como nada chega por parâmetro, o ponto de entrada lê o produto em edição pelas variáveis de memória M->B1_*. É o que o próprio padrão faz ao validar o cadastro (M->B1_LOCALIZ, M->B1_APROPRI e outras). Na tela clássica isso vale para o momento em que o A010TOK roda. No MVC o padrão usa M-> na validação do modelo inteiro (ModelPosVld), mas o A010TOK é chamado em outro ponto, na validação do formulário (FieldPosVld), e não conferi que M-> já esteja preenchido nesse instante: teste no seu ambiente antes de depender disso. Na tela clássica o padrão ainda compara M->B1_CAMPO (o que o usuário digitou) com o campo de posicionado (o que está gravado) para detectar mudança; essa leitura do registro antigo não foi conferida no MVC, então não dependa dela sem testar.

A mesma ausência vale para a operação: o ponto de entrada não recebe nOpc. Na tela clássica o padrão usa as variáveis privadas INCLUI e ALTERA para distinguir; no MVC não conferi que elas existam nesse momento. Se a regra serve às duas operações, nada a fazer.

O que muda entre a tela clássica e o MVC

O padrão escolhe o caminho pela existência da tabela G3Q no dicionário: com ela, o MATA010 sobe em MVC; sem ela, usa a tela clássica. Em qualquer dos dois o A010TOK é chamado, o que muda é por quem.

Tela clássicaCadastro em MVC
Quem chamaA010TudoOk(), passada como validação final da inclusão e da alteraçãoevento de pós-validação do formulário SB1MASTER, só para inclusão e alteração
ChamadaExecBlock("A010TOK", .F., .F.)ExecBlock("A010TOK", .F., .F.)
Retorno não lógicovira .T.vira .T.
Antes delea chave do produto já foi conferida (produto duplicado nem chega ao ponto de entrada)a checagem de chave está no ModelPosVld do evento padrão; a ordem em relação ao A010TOK não foi confirmada, então não assuma que o produto já é inédito

Duas diferenças práticas:

  • Na tela clássica, a sua resposta não é jogada fora. O ponto de entrada só roda se a chave do produto estiver livre, e as validações seguintes do padrão (, integração com chão de fábrica, amarração de conta e centro de custo, custeio de apropriação indireta) são todas condicionadas a lRet. Se você devolve .F., elas nem executam. Se devolve .T., seguem normalmente. Diferente de pontos de entrada que sobrescrevem o retorno do padrão (como o MT410TOK), aqui devolver .T. não desfaz validação anterior: o padrão simplesmente continua depois.
  • Existe também um ponto de entrada de template com o mesmo nome, A010TOK, chamado por ExecTemplate. Na tela clássica o template roda primeiro e o ponto de entrada de usuário só é chamado se o template devolveu .T.. No MVC o template é tratado em outro evento, na validação do modelo (ModelPosVld). Quem não usa template pode ignorar.

Exemplo

A regra é neutra: produto do tipo PA não pode ser confirmado sem grupo e sem NCM (). O exemplo lê tudo de M->, avisa o usuário antes de reprovar e devolve sempre um lógico.

ADVPL / TLPP
#Include "Protheus.ch"

/*/{Protheus.doc} A010TOK
Validação final do Cadastro de Produto (MATA010), sem PARAMIXB.
Chamado na inclusão e na alteração. Validado contra o padrão na tela
clássica; no MVC, confirme no seu ambiente que M-> já está preenchido.
@type user function
@return logical, .F. interrompe a confirmação do produto
/*/
User Function A010TOK()

    Local lRet  := .T.
    Local cMsg  := ""

    // Regra só para produto acabado. Outros tipos seguem o padrão.
    If M->B1_TIPO <> "PA"
        Return .T.
    EndIf

    If Empty(M->B1_GRUPO)
        cMsg := "Produto acabado exige grupo de estoque."
    ElseIf Empty(M->B1_POSIPI)
        cMsg := "Produto acabado exige NCM."
    EndIf

    If !Empty(cMsg)
        // O botão confirmar não pode simplesmente deixar de responder:
        // o padrão também chama Help antes de reprovar.
        Help(" ", 1, "A010TOK",, cMsg, 1, 0)
        lRet := .F.
    EndIf

Return lRet

Repare que não há GetArea/RestArea: o exemplo não muda o ponteiro de nenhuma tabela. Se a sua regra consultar outra tabela com DbSeek, aí sim guarde e restaure a área.

Armadilhas

Procurar o PARAMIXB. Ele não existe aqui. O padrão chama o ponto de entrada sem enviar parâmetros; quem lê PARAMIXB[1] por hábito (de pontos de entrada como o MT410TOK) está lendo algo que esta chamada não preencheu. Veja PARAMIXB: o array que às vezes não é seu.

Esquecer de devolver lógico. Um Return sem valor, ou com outro tipo, é lido como .T.. A validação que você escreveu passa em silêncio.

Bloquear sem mensagem. Sem Help ou aviso equivalente, o usuário clica em confirmar e nada acontece. O padrão avisa antes de reprovar nas validações que ele mesmo faz; faça igual.

Esperar que ele rode na exclusão. Não roda. No cadastro em MVC a exclusão tem outro ponto de entrada, MTA010OK, chamado só nessa operação.

Regra de inclusão aplicada na alteração. Como não há nOpc, uma regra pensada só para produto novo vai barrar também a manutenção de produto antigo que nasceu fora dela. Decida isso de forma explícita.

Os vizinhos

No cadastro em MVC, MT010INC e MT010ALT são chamados no evento de transação do modelo, depois da validação, na inclusão e na alteração. Servem para efeitos colaterais, não para barrar. Regra que precisa impedir o cadastro fica no A010TOK.

Continue por aqui