Pragiva — Tecnologia na prática

Configurador de Tributos (FISA170) para quem programa

O que o desenvolvedor precisa saber do Configurador de Tributos: tabelas, como o motor fiscal o aciona, a flag lCalcTG e como ler os tributos calculados.

Protheus Guia de processo 5 min de leitura

Assista o vídeo

Nesta página8 seções

Resposta curta: o Configurador de Tributos (rotina FISA170) é o cadastro das regras do motor de tributos genéricos. Quem desenvolve não chama a FISA170 para calcular nada: o cálculo acontece dentro do motor fiscal (funções MaFis*), e o seu código só precisa (1) avisar na MaFisIni que sabe gravar/exibir/excluir esses tributos e (2) ler o resultado com a MaFisRet.

O que a FISA170 é

A FISA170 não é um cadastro único. Ao abrir, ela garante que as tabelas do motor existam no dicionário, roda uma carga inicial dos perfis e exibe uma árvore que concentra os cadastros do motor. Sem as tabelas, avisa que o dicionário está desatualizado. Dentro dela há uma tela “Relação de Rotinas” que lista cada fonte do configurador com a data e a hora do RPO, útil para conferir se o ambiente tem a versão esperada.

Entre as rotinas dessa relação aparecem regra de cálculo de documentos fiscais, regra de base de cálculo, regra de alíquota, regra de escrituração, regra de apuração, perfis (origem/destino, participante, operação, produto), fórmulas, mensagens e as tabelas cClassTrib e de crédito presumido de IBS/CBS.

Tabelas que o desenvolvedor encontra

TabelaNome no dicionárioPara que serve
F2ECadastro de TributoO tributo em si (tipo e descrição). A sigla que o motor devolve é o código da regra (), gravado em .
Regra TributáriaA regra de cada tributo: vigência, regra de base, regra de alíquota, perfis, regra financeira e de apuração.
F20 a F26Perfis tributáriosPerfis de origem/destino, participante, operação, produto e tipo de operação.
F27, F28Regra de Base de Cálculo, Regra de AlíquotaComo a base e a alíquota são obtidas.
Tributos Genéricos CalculadosO resultado calculado por item, gravado quando o documento é salvo.
F2FTítulos de Tributos x NFLiga os títulos de tributos ao documento.

O vínculo entre o item do documento e o resultado é um ID gravado no próprio item: na saída e na entrada. Esse ID bate com .

Confira no seu ambienteSQL
SELECT D2.D2_DOC, D2.D2_ITEM, F2D.F2D_TRIB, F2D.F2D_BASE,
       F2D.F2D_ALIQ, F2D.F2D_VALOR
  FROM SD2010 D2
  JOIN F2D010 F2D
    ON F2D.F2D_IDREL = D2.D2_IDTRIB
   AND F2D.F2D_DTEXCL = ' '
   AND F2D.D_E_L_E_T_ = ' '
 WHERE D2.D2_DOC = 'NUMERO_DA_NOTA'
   AND D2.D_E_L_E_T_ = ' '

Ajuste o sufixo das tabelas ao do seu ambiente. O filtro em descarta resultados já marcados como excluídos (a regravação e a exclusão não apagam a linha, só preenchem essa data). Se o item não tem tributo genérico, o ID vem vazio e a consulta não devolve linhas.

Como o motor decide quais regras aplicar

O enquadramento é feito pela função de tributos genéricos do motor fiscal. Ela pesquisa as regras com os dados do item e do documento: produto, NCM, unidades de medida, origem, participante (cliente ou fornecedor), UF de origem e de destino, CFOP, tipo de operação, código de ISS, CEST e data. Esses são exatamente os dados que a função de consulta recebe no JSON da operação.

Dois pontos práticos:

  • Reenquadramento. O motor refaz a pesquisa quando muda produto, participante, loja, UF de origem ou destino, CFOP, TES, data de emissão, natureza, classificação fiscal, tipo de operação, código de ISS, NCM, CEST ou município. Mudar um desses campos por MaFisAlt dispara a recalculagem.
  • Regra em teste. A regra tem status “Em Teste” ou “Aprovada” (). Por padrão a pesquisa ignora as em teste. O último parâmetro da MaFisIni (37º, lF2BTeste) e da MaFisIniNF liga a inclusão delas.

A flag que muda o seu fonte: lCalcTG

O 33º parâmetro da MaFisIni é lCalcTG. A documentação da própria função define que ele só deve ser .T. depois que a rotina estiver preparada para gravar, visualizar e excluir os tributos genéricos. Com .F. o motor não calcula tributo genérico, de propósito: calcular e não gravar deixaria o valor sem rastro.

Por isso, uma customização que monta o cálculo fiscal por conta própria (simulação, pré-nota, rotina de importação) não passa a “ganhar” o Configurador sozinha. Ela precisa:

  1. Chamar a MaFisIni com lCalcTG verdadeiro.
  2. Gravar com MaFisTG(1, cAlias, nItem), que marca como excluído (data em F2D_DTEXCL) o que já havia com aquele ID, grava a F2D e o livro dos tributos genéricos e devolve o ID que o seu fonte deve gravar no campo _IDTRIB do item.
  3. Excluir com MaFisTG(2, , , cIdTrbGen) quando o documento for estornado ou excluído. Ele preenche a data de exclusão e só remove fisicamente a linha da F2D quando não há livro fiscal vinculado ao ID.
  4. Se exibir o documento, usar MaFisBrwTG para montar a grade dos tributos por item.

No reprocessamento de documento já gravado, a MaFisIniNF repassa lCalcTG e lF2BTeste à MaFisIni e lê o ID de tributos do item (D1_IDTRIB/D2_IDTRIB) para recompor os valores.

Lendo o resultado: MaFisRet com NF_TRIBGEN

Depois do cálculo, MaFisRet(, "NF_TRIBGEN") devolve a lista dos tributos genéricos do documento. Cada linha é um array; as posições abaixo vêm das definições padrão do motor fiscal.

PosiçãoConteúdo
1Sigla do tributo
2Base de cálculo
3Valor do tributo
4Código da regra financeira
5ID da regra (F2B)
6 e 7Código da URF e percentual aplicável
9Regra de guia

Passando só a sigla no terceiro parâmetro, MaFisRet(, "NF_TRIBGEN", {cSigla}), volta apenas a linha daquele tributo, ou um array vazio se ele não foi calculado.

ADVPL / TLPP
/*/{Protheus.doc} ListaTribGen
Lista os tributos genericos do documento fiscal em memoria. So faz sentido
com o motor fiscal ja iniciado (MaFisIni com lCalcTG = .T.) e os itens
adicionados.
@type function
@return character, uma linha por tributo (sigla, base e valor)
/*/
Static Function ListaTribGen()
    Local aTrib  := MaFisRet(, "NF_TRIBGEN")
    Local cTexto := ""
    Local nX     := 0

    For nX := 1 To Len(aTrib)
        cTexto += AllTrim(aTrib[nX][1]) + ;
                  " base " + AllTrim(Transform(aTrib[nX][2], "@E 999,999,999.99")) + ;
                  " valor " + AllTrim(Transform(aTrib[nX][3], "@E 999,999,999.99")) + CRLF
    Next nX

    If Empty(cTexto)
        cTexto := "Nenhum tributo generico calculado."
    EndIf
Return cTexto

/*/{Protheus.doc} ValorDoTributo
Valor calculado de um tributo generico do documento em memoria.
@type function
@param cSigla, character, sigla do tributo (codigo da regra, o mesmo de F2D_TRIB)
@return numeric, valor do tributo ou zero se nao foi calculado
/*/
Static Function ValorDoTributo(cSigla)
    Local aLinha := MaFisRet(, "NF_TRIBGEN", {cSigla})
Return IIf(Len(aLinha) >= 3, aLinha[3], 0)

O que muda em relação à TES

A TES continua sendo um dado do item e continua disparando recálculo: ela está na lista de campos que obrigam o motor a pesquisar as regras de novo. Mas o Configurador não é uma “TES mais nova”. Ele é outro mecanismo, com cadastro próprio, e o resultado vai para outras tabelas (F2D, livro de tributos genéricos) em vez dos campos fixos do item. Nos dados que a pesquisa de regras recebe (lista acima), a TES não aparece como chave: quem enquadra a regra é o conjunto produto, participante, operação e localidade. Para entender o que a TES faz no estoque e no financeiro, veja TES: como conferir os efeitos no estoque e no financeiro.

Consequências para o código:

  • Não leia só campos fixos do item. Valor de tributo cadastrado como genérico pode não estar em campo próprio da /; busque por F2D_IDREL ou pela MaFisRet.
  • Chame sempre o motor fiscal. Cálculo reimplementado à mão por cima da TES ignora a regra do Configurador.
  • Pontos de entrada. No configurador e no enquadramento das regras não há chamada de ponto de entrada de usuário (ExistBlock/ExecBlock). O comportamento do cálculo se ajusta por cadastro: regra, perfil e fórmula.

Erro comum

Passar lCalcTG verdadeiro sem gravar com MaFisTG: o documento é gravado, mas o _IDTRIB do item fica vazio e a F2D não recebe nada. O motor foi avisado de que a rotina sabia gravar; ela não sabia.

Solução de problemas

SintomaCausa provávelComo conferir
MaFisRet(, "NF_TRIBGEN") vem vaziolCalcTG falso na MaFisIni, ou regra sem vigência na dataParâmetro 33 da MaFisIni; /
Regra existe e não é aplicadaStatus “Em Teste”F2B_STATUS e parâmetro 37 da MaFisIni
Dicionário desatualizado ao abrir a rotinaTabelas do motor ausentesAlias F20 existe no ambiente
Valor some após reprocessarItem sem _IDTRIB gravadoCampo D1_IDTRIB/D2_IDTRIB e a F2D

Continue por aqui