Pragiva — Tecnologia na prática

MT103LOK valida a linha do rateio por centro de custo do documento de entrada

MT103LOK roda na linha OK do rateio de um item da nota, não recebe PARAMIXB e roda antes das validações do padrão. Retornar .T. não desfaz a recusa do padrão.

Desenvolvimento Referência técnica 4 min de leitura

Assista o vídeo

MT103LOK em resumo

Onde fica
função NfeRatLOk(), a validação da linha OK do rateio por centro de custo de um item do documento de entrada.
Quando dispara
ao sair de uma linha da janela “Rateio por Centro de Custo”, aberta a partir de um item da nota. É a validação de uma linha do rateio (tabela SDE), não da linha do item (SD1).
PARAMIXB
nenhum. A chamada é Execblock("MT103LOK",.F.,.F.), sem parâmetros.
Retorno
usado. .F. impede a linha de ser aceita.
Serve para bloquear?
Sim, mas ele roda antes das regras do padrão para a linha, e o padrão continua depois dele.
Consulta rápida5 seções

Quem procura “validar o item da nota” quer outro ponto de entrada: este só enxerga o rateio. Para a confirmação do documento inteiro, veja o MT100TOK. Para o mecanismo geral de chamada de PE, veja Ponto de entrada no Protheus.

Quando ele roda e o que já está carregado

NfeRatCC() monta a janela do rateio com uma grade (MsNewGetDados) e informa NfeRatLOk como validação de linha e NfeRatTOk como validação do conjunto. A janela só é desenhada quando a nota não está em modo automático (l103Auto).

Como PARAMIXB não existe, o PE trabalha com as variáveis da própria grade, exatamente como o padrão faz dentro de NfeRatLOk:

VariávelO que é
aHeadercolunas do rateio; procure a posição pelo nome do campo (, , , , )
aColslinhas do rateio
nlinha que acabou de ser digitada

Não fixe posição de coluna: use aScan no aHeader, como o padrão.

O que o padrão faz depois do seu retorno

Antes de chamar o PE, o padrão só monta dois arrays com a conta, o centro de custo, o item contábil, a classe de valor e as demais entidades da linha. Em seguida chama o PE e atribui o retorno a lRetorno. Daí em diante, as regras do padrão só derrubam o resultado, nunca o levantam:

  • se o PE devolveu .T. e o parâmetro está falso, recusa linha repetida (mesma combinação de centro de custo, conta, item e classe de valor, considerando só linhas não excluídas) com o help CCEXIST;
  • recusa percentual zero em linha não excluída (A103PERC);
  • se está falso, confere a amarração entre conta e centro de custo com CtbAmarra();
  • exige centro de custo preenchido (A103RATEI);
  • recusa centro de custo bloqueado (ajuda CTA_BLOQ);
  • recalcula o percentual rateado e consulta o módulo de planejamento orçamentário (PcoVldLan).

Consequências práticas:

  • Retornar .T. é seguro. Diferente do que acontece em outros pontos de entrada de validação, aqui o seu .T. não apaga uma recusa do padrão, porque o padrão decide depois de você.
  • Retornar .F. pula as demais conferências. Todas as condições seguintes começam com lRetorno .And., então o padrão não mostra os próprios helps. A única exceção é a checagem de percentual zero, que roda mesmo assim e pode somar um segundo help. Por isso a mensagem do seu PE é a que o usuário precisa ver: sem ela, a linha é recusada em silêncio.
  • O PE roda em linha excluída também. A chamada não tem guarda de linha deletada (o padrão só protege a conferência de percentual; a de duplicidade ignora linhas excluídas na busca, mas não olha se a linha atual é a excluída). Sua regra precisa olhar o último elemento da linha, o flag de exclusão.

Exemplo

Regra de exemplo: quando a linha informa conta contábil, o item contábil passa a ser obrigatório. É uma regra que o padrão não faz.

ADVPL / TLPP
#Include "Protheus.ch"

/*/{Protheus.doc} MT103LOK
Executado em NfeRatLOk(), na linha OK do rateio por centro de custo do
documento de entrada. Sem PARAMIXB: lê aHeader, aCols e n.
@type function
@return logical, .F. recusa a linha do rateio
/*/
User Function MT103LOK()

    Local lRet      := .T.
    Local nPConta   := aScan(aHeader, {|x| AllTrim(x[2]) == "DE_CONTA"})
    Local nPItemCta := aScan(aHeader, {|x| AllTrim(x[2]) == "DE_ITEMCTA"})
    Local aLinha    := {}

    // Colunas ausentes no dicionário do ambiente: não há o que validar.
    If nPConta == 0 .Or. nPItemCta == 0
        Return .T.
    EndIf

    aLinha := aCols[n]

    // Linha excluída não precisa passar pela regra. O flag fica na última
    // posição da linha.
    If aLinha[Len(aLinha)]
        Return .T.
    EndIf

    If !Empty(aLinha[nPConta]) .And. Empty(aLinha[nPItemCta])
        // Sem mensagem, a linha é recusada em silêncio.
        Help(" ", 1, "MT103LOK",, ;
            "Informe o item contábil para a conta contábil desta linha do rateio.", 1, 0)
        lRet := .F.
    EndIf

Return lRet

Os dois Return .T. antecipados cobrem os casos em que a regra não se aplica. Não há RecLock nem acesso a tabela: a linha ainda está só em memória.

Armadilhas

Esperar PARAMIXB. Não há nada para ler. Se o seu código lê PARAMIXB[1], ele falha.

Confundir a linha do rateio com a linha do item. No momento da chamada, aHeader e aCols são os do rateio. O item da nota que originou o rateio não está nessas variáveis; confira o DE_ de cada coluna e não use D1_ ali.

Esquecer a linha excluída. Uma linha apagada pelo usuário ainda passa pelo PE, e uma regra de “campo obrigatório” a recusaria.

Bloquear sem mensagem. Com .F., o padrão não explica nada; sem Help() ou equivalente, o usuário só vê a linha não sair.

Tentar revalidar o conjunto aqui. A validação do rateio inteiro é outra, NfeRatTOk(); este PE só enxerga a linha atual.

Parâmetros que mudam as conferências do padrão

MV_RATDUPL e MV_DAMARCT entram nas regras de duplicidade e de amarração conta x centro de custo descritas acima. No dicionário, MV_RATDUPL é lógico e permite duplicidade no rateio por centro de custo (com .T., a recusa CCEXIST não ocorre); MV_DAMARCT é lógico e, com .T., desconsidera a checagem da amarração contábil na inclusão do documento de entrada. Em ambos, o código do padrão assume falso quando o parâmetro não existe.

Confira no seu ambienteSQL
SELECT X6_VAR, X6_TIPO, X6_DESCRIC, X6_CONTEUD
  FROM SX6010
 WHERE X6_VAR IN ('MV_RATDUPL', 'MV_DAMARCT')

A consulta mostra o cadastro no seu ambiente. Quem usa o parâmetro, e com que efeito, é o que está descrito acima, conferido no código do padrão.

Continue por aqui