Pragiva — Tecnologia na prática

SF2460I o ponto de entrada da nota fiscal de saída

Na MATA461, o SF2460I roda dentro da transação, com SF2 e SD2 já gravados, não recebe PARAMIXB e não bloqueia a nota. Veja o que dá para alterar e o que evitar.

Desenvolvimento Referência técnica 3 min de leitura

Assista o vídeo

SF2460I em resumo

Onde fica
na gravação da nota fiscal de saída, logo depois de SF2, SD2, financeiro e livro fiscal.
Quando dispara
uma vez por nota gerada, com a nota já gravada.
PARAMIXB
nenhum. Nada é passado na chamada.
Retorno
descartado.
Roda dentro da transação?
Sim, no faturamento de pedido e na geração de nota a partir de outra nota.
Serve para bloquear?
Não. Serve para complementar a nota recém-gravada.
Consulta rápida5 seções

Se a dúvida é “onde eu ajusto um campo do SF2 ou do SD2 depois que o padrão gravou a nota”, é aqui. O ponto de entrada do outro lado do processo, que decide se o pedido pode existir, é o MT410TOK; o caminho completo até a nota está em O caminho do pedido de venda no Protheus: do cadastro à nota fiscal. Para o mecanismo geral de chamada, veja Ponto de entrada no Protheus.

Quem chama e em que ponto

A chamada é um ExecBlock("SF2460I", .F., .F.) sem o quarto parâmetro: não há array de parâmetros. Vale também a versão template, que roda antes. Quem chama:

RotinaSituação
Faturamento de pedido (Documento de Saída, MATA461, e o que usa a mesma função de faturamento)Dispara depois da gravação do SF2 e dos itens, do financeiro, do livro fiscal e da atualização do pedido
Geração de nota a partir de outra notaDispara depois da gravação fiscal e antes da contabilização do cabeçalho
MATA468N (localização)Também chama o ponto de entrada

A FINA440 apenas confere se ele existe, sem executá-lo.

No faturamento de pedido, na hora em que ele roda, o padrão já fez:

  • gravou o cabeçalho (SF2) e os itens (SD2);
  • gravou os lançamentos fiscais;
  • gerou os títulos a receber;
  • atualizou o pedido de venda e, quando existem, cargas e integrações ligadas ao pedido;
  • acumulou o lançamento contábil do cabeçalho (padrão 620); o fechamento do lote só acontece depois da transação.

Já na geração de nota a partir de outra nota, a ordem é outra: o ponto de entrada roda antes do lançamento contábil do cabeçalho. Se a sua regra depende disso, teste os dois caminhos.

Dentro da transação

O faturamento envolve a gravação da nota em um Begin Transaction. O ponto de entrada roda dentro dele. Duas consequências práticas:

  • O que você grava aqui entra ou sai junto com a nota. Depois do ponto de entrada, o padrão ainda valida a integração com o GFE e, em caso de erro, chama DisarmTransaction(). Nesse caso, a nota é desfeita e a sua gravação também.
  • Interface e integração externa são armadilhas. Tela, MsgYesNo, chamada HTTP ou espera por outro sistema seguram a transação aberta enquanto ela espera, e o fechamento da contabilização só acontece depois que a transação termina. Faça o mínimo e rápido; o que for lento vai para fora (um job ou uma fila que você alimenta aqui).

Como o retorno é descartado, não existe forma de dizer ao padrão “não gere esta nota” devolvendo .F.. Regra de bloqueio vai para antes: no pedido (MT410TOK) ou na validação da liberação.

O que dá para fazer

Com posicionado na nota gerada e os itens já gravados no , os usos normais são:

  • gravar campo customizado no cabeçalho ou nos itens da nota;
  • sincronizar um dado da nota com uma tabela própria;
  • registrar log da emissão.

O que ainda não vale tentar: mudar valor que já virou título, livro fiscal ou lançamento. Isso foi gravado antes; alterar o SF2 aqui não refaz o financeiro nem o fiscal.

Exemplo

O exemplo grava, no cabeçalho da nota, a quantidade de itens e registra no log. O campo F2_XITENS é fictício: é um campo customizado que você teria de criar. O exemplo confere se ele existe antes de gravar.

ADVPL / TLPP
#Include "Protheus.ch"

/*/{Protheus.doc} SF2460I
Executado depois da gravação da nota fiscal de saída, dentro da transação.
Não recebe PARAMIXB e o retorno é descartado.
@type user function
/*/
User Function SF2460I()

    Local aAreaSF2 := SF2->(GetArea())
    Local aAreaSD2 := SD2->(GetArea())
    Local nItens   := 0
    Local cChave   := ""

    // Campo customizado (fictício): sem ele, a regra não se aplica.
    If SF2->(FieldPos("F2_XITENS")) == 0
        Return Nil
    EndIf

    cChave := SF2->(F2_FILIAL + F2_DOC + F2_SERIE + F2_CLIENTE + F2_LOJA)

    // Itens da nota: ordem 3 do SD2 (filial + doc + série + cliente + loja)
    SD2->(DbSetOrder(3))
    If SD2->(DbSeek(cChave))
        While !SD2->(Eof()) .And. ;
              SD2->(D2_FILIAL + D2_DOC + D2_SERIE + D2_CLIENTE + D2_LOJA) == cChave
            nItens++
            SD2->(DbSkip())
        EndDo
    EndIf

    // Já estamos dentro da transação da nota: só gravação curta, sem tela.
    If RecLock("SF2", .F.)
        SF2->F2_XITENS := nItens
        SF2->(MsUnlock())
    EndIf

    ConOut("[SF2460I] Nota " + SF2->F2_DOC + "/" + SF2->F2_SERIE + " | itens: " + cValToChar(nItens))

    RestArea(aAreaSD2)
    RestArea(aAreaSF2)

Return Nil

Repare que a função sai cedo quando a regra não se aplica e restaura as duas áreas: depois do ponto de entrada o padrão continua usando SF2 e SD2 posicionados.

Armadilhas

Esperar PARAMIXB. Não há. Quem identifica a nota é o SF2 posicionado. Não use Type("PARAMIXB") como guarda de execução; aqui ele não existe.

Devolver .F. para impedir a nota. O retorno é ignorado; a nota já foi gravada.

Tela ou integração lenta. Na MATA461, estão dentro da transação, que fica aberta enquanto isso. Evite.

Esquecer de restaurar a área. Mudar o índice do SD2 e não restaurar afeta o que o padrão faz em seguida.

Supor um único caminho. Pedido faturado e nota gerada de outra nota chamam o mesmo ponto de entrada, mas em momentos diferentes em relação à contabilização. Teste os dois, e a MATA468N se você usa localização.

Continue por aqui