Pragiva — Tecnologia na prática

FA050INC o ponto de entrada que valida a inclusão no Contas a Pagar

FA050INC roda no OK da inclusão do título, sem PARAMIXB, e o .F. barra a gravação. Pelo ExecAuto o log pode trazer só 'Processo invalido'.

Desenvolvimento Referência técnica 4 min de leitura

Assista o vídeo

FA050INC em resumo

Onde fica
FA050Inclu(), dentro do FINA050 (Contas a Pagar).
Quando dispara
na validação final da inclusão do título (o “tudo OK” da tela), depois de várias validações do próprio padrão.
PARAMIXB
não existe. O padrão chama o ponto de entrada sem array.
Retorno
usado — .F. barra a inclusão.
Serve para bloquear?
Sim, na inclusão. Alteração tem outro ponto de entrada, o FA050ALT.
Consulta rápida6 seções

Como não há PARAMIXB, a regra trabalha com o que já está em memória: as variáveis M->E2_* do título que está sendo incluído.

Para o mecanismo geral de como o padrão chama um PE, veja Ponto de entrada no Protheus. Para o ponto de entrada do menu do mesmo programa, veja F050ROT.

Como o padrão monta a chamada

O FA050Inclu() não chama o PE na hora. Ele monta uma string de validação (cTudoOK) somando condições com .AND.. Se o ponto de entrada estiver compilado, a chamada dele, sem array de parâmetros, é acrescentada a essa cadeia.

Duas consequências, ambas lidas nessa montagem:

  • O retorno entra numa expressão lógica. Devolva sempre .T. ou .F., nunca Nil ou outro tipo.
  • Como ele vem no meio da cadeia, roda depois das validações que o padrão já concatenou antes (entidades contábeis, por exemplo) e antes das que vêm depois (FA050VLMV(), F050VlCpos(), F050VldVlr() e outras). Se uma condição anterior já reprovou, é esperado que o PE nem seja chamado — é o comportamento normal do .AND. (inferido, não testado no ambiente).

O mesmo cTudoOK alimenta a tela e a inclusão automática, então o PE precisa funcionar nos dois cenários.

Na tela: .F. mantém o usuário na inclusão

Na inclusão manual o padrão entrega o cTudoOK à AxInclui, como parâmetro de validação do OK. Um .F. do PE deixa a tela aberta. Por isso a regra precisa avisar (Help()): sem mensagem, o botão parece não funcionar.

Por ExecAuto: o que dá para afirmar

Quando o título vem por MsExecAuto com o FINA050, o FA050Inclu() segue outro caminho, e há dois pontos de validação:

  1. Antes de gravar, o padrão chama EnchAuto(cAlias, aAutoCab, cTudoOk, nOpc). Se ela devolver .F., o padrão faz lMsErroAuto := .T. e lRet := .F..
  2. Depois, na gravação, chama AxIncluiAuto(cAlias, cTudoOk, ...). Aqui o fonte é explícito: se o cTudoOk for falso, a função registra no log Processo invalido, devolve 3 e não grava. Ela não atribui lMsErroAuto nesse trecho.

O que isso significa para o FA050INC:

  • O título não é gravado quando o PE retorna .F. (verificado em AxIncluiAuto).
  • O log automático traz só Processo invalido, sem a sua mensagem. Quem chama não sabe qual regra barrou.
  • Neste caminho o FA050Inclu() não marca lMsErroAuto por conta própria. Se o EnchAuto já avaliar o cTudoOk (ela é função compilada, sem fonte para conferir), o erro sobe por ali; se não avaliar, o .F. do PE só chega ao AxIncluiAuto e o chamador pode ver lMsErroAuto ainda .F. com o título não gravado. O fonte compilado não permite confirmar qual dos dois acontece.

Para saber qual é o caso no seu ambiente, chame o ExecAuto com vazio usando o exemplo abaixo e olhe lMsErroAuto e o log ao voltar. Por segurança, o PE deve fazer o que ele mesmo controla: escrever a causa no log da rotina automática com AutoGRLog() e marcar lMsErroAuto := .T. quando a variável existir. Isso não depende de saber o que o EnchAuto faz. Para ler esse log do lado de quem chama, veja MsExecAuto: como descobrir por que a rotina falhou.

Para saber se está sob ExecAuto, o FINA050 declara lF050Auto como Private (verdadeira quando a rotina recebe o array de campos). Ela é a chave certa para decidir entre Help() e log.

Exemplo

Regra de demonstração: não deixar incluir título sem histórico (E2_HIST). O campo não é obrigatório no dicionário padrão, então a regra é da empresa.

ADVPL / TLPP
#Include "Protheus.ch"

/*/{Protheus.doc} FA050INC
Executado na validacao final da inclusao do titulo (FA050Inclu).
Nao recebe PARAMIXB: le as variaveis de memoria M->E2_*.
@type user function
@return logical, .F. barra a inclusao
/*/
User Function FA050INC()

    Local lRet  := .T.
    Local lAuto := (Type("lF050Auto") == "L" .And. lF050Auto)
    Local cMsg  := "Informe o histórico do título (E2_HIST)."

    If Empty(M->E2_HIST)
        lRet := .F.

        If lAuto
            // Sem tela: a causa vai para o log do ExecAuto
            AutoGRLog("FA050INC: " + cMsg)
            If Type("lMsErroAuto") == "L"
                lMsErroAuto := .T.
            EndIf
        Else
            Help(" ", 1, "FA050INC",, cMsg, 1, 0)
        EndIf
    EndIf

Return lRet

Repare que o retorno é sempre lógico e que a mensagem tem dois destinos: tela ou log. Sem tela, quem lê o resultado do ExecAuto só enxerga o log, não um Help().

Armadilhas

Retornar .F. calado. Na tela o botão OK parece travado; no ExecAuto o chamador só vê Processo invalido.

Esperar PARAMIXB. Não existe. Ler PARAMIXB[1] aqui é erro.

Retornar outro tipo. O retorno entra numa cadeia .AND.; Nil ou texto quebra a avaliação.

Aplicar a regra a título que não é seu. O FA050Inclu() também é chamado por outros fluxos (a substituição de títulos e uma rotina do módulo jurídico, por exemplo), então o PE pode rodar fora da tela de inclusão comum. Se a regra vale só para certa origem, filtre por M->E2_ORIGEM ou pelo que identifica o seu caso.

Os vizinhos

PEMomentoBloqueia?
F050ROTMontagem do menuNão
FA050INCValidação final da inclusãoSim
FA050ALTValidação final da alteraçãoSim

Não confunda com F050INC, sem o “A”: o FINA050 também chama esse nome, e a chamada fica depois da gravação do título, não na validação do OK.

Continue por aqui