Skip to content

feat: suporte a gIBSCBSMono para CST 620 (Tributacao Monofasica) — NT 2025.002-RTC#456

Open
felps-dev wants to merge 4 commits intoTadaSoftware:mainfrom
nuvelbr:master
Open

feat: suporte a gIBSCBSMono para CST 620 (Tributacao Monofasica) — NT 2025.002-RTC#456
felps-dev wants to merge 4 commits intoTadaSoftware:mainfrom
nuvelbr:master

Conversation

@felps-dev
Copy link
Copy Markdown
Collaborator

Resumo

Adiciona suporte ao grupo <gIBSCBSMono> para itens com CST IBS/CBS 620 (Tributacao Monofasica) conforme NT 2025.002-RTC / LC 214/2025.

Complementa o trabalho da #448 (reforma tributaria IBS/CBS/IS base), removendo gIBSCBSMono da lista de "Nao inclui (ainda)" documentada em docs/reforma_tributaria.md.

Contexto

Produtos com CST IBS/CBS 620 (combustiveis monofasicos, ex: GLP) emitiam <gIBSCBS> padrao com pIBSUF/pIBSMun/pCBS, o que a SEFAZ rejeita com cStat 1026 — "Aliquota do IBS da UF invalida [nItem:1]". Para esses casos o schema NF-e v4.00 exige o grupo especifico <gIBSCBSMono> com:

  • qBCMono (TDec_1104v) — quantidade tributada na base monofasica
  • adRemIBS (TDec_0302a10) — aliquota ad rem IBS em R$ por unidade
  • vIBSMono (TDec_1302) — valor IBS monofasico
  • adRemCBS — aliquota ad rem CBS em R$ por unidade
  • vCBSMono — valor CBS monofasico

Mudancas

pynfe/entidades/notafiscal.py

Cinco novos atributos em NotaFiscalProduto, adjacentes aos existentes ibscbs_*:

  • ibscbs_q_bc_mono
  • ibscbs_ad_rem_ibs
  • ibscbs_v_ibs_mono
  • ibscbs_ad_rem_cbs
  • ibscbs_v_cbs_mono

pynfe/processamento/serializacao.py

  • Nova constante _IBSCBS_CST_MONOFASICO = ("620",).
  • "620" removido de _IBSCBS_CST_TRIBUTADOS (agora roteado pelo caminho monofasico).
  • _serializar_ibscbs despacha para novo helper _serializar_gibscbs_mono quando o CST esta em _IBSCBS_CST_MONOFASICO, emitindo <gIBSCBSMono> com os 5 filhos na ordem do schema.
  • Demais CSTs continuam gerando <gIBSCBS> tradicional — zero regressao.

docs/reforma_tributaria.md

  • gIBSCBSMono removido da lista "Nao inclui (ainda)".
  • Nova secao dedicada documentando quando o grupo e emitido, os campos esperados e referencia ao schema.

tests/test_nfe_serializacao_reforma_tributaria.py

Tres novos casos de teste:

  1. CST 620 com valores zero (cenario Teste de Carga 2026 para GLP) → emite <gIBSCBSMono> com campos zerados.
  2. CST 620 com ad rem nao-zero → emite <gIBSCBSMono> com valores calculados.
  3. Regressao CST 000 → continua emitindo <gIBSCBS> padrao com gIBSUF/gIBSMun/gCBS.

Validacao local

  • pytest tests/146 passed (excluidos testes opcionais NFSe que requerem pyxb).
  • ruff check . — limpo.
  • ruff format --check . — limpo.

Out of scope / deferred

  • Totalizer <gMono> dentro de <IBSCBSTot> — ainda nao implementado. SEFAZ aceita a omissao em 2026; revisitar quando a NT publicar a regra de totais de monofasicos para 2027+.
  • CSTs 630/640 (outras variantes monofasicas) podem ser adicionadas ao set futuramente conforme a SEFAZ publicar os cClassTrib correspondentes. Comeca com apenas 620 por enquanto.
  • Grupos irmaos (gDif, gDevTrib, gRed, gEstornoCred, gCredPresOper, gCredPresIBSZFM) permanecem na lista "Nao inclui" — cada um tem seu proprio estrutura e sera tratado em PRs dedicados conforme demanda.

Referencias

  • NT 2025.002-RTC — Nota Tecnica SEFAZ da Reforma Tributaria IVA Dual
  • LC 214/2025 — Lei Complementar da Reforma Tributaria
  • Schema XSD: pynfe/data/XSDs/NF-e/leiauteNFe_v4.00.xsd (types TIBSCBSMono, gIBSCBSMono)

Contribuicao patrocinada pela Nuvel ERP. Origem do trabalho: gateway DEV-1929 (cliente real rejeitado por cStat 1026 ao emitir NF-e de GLP em botijao).

…9] (#2)

* feat(reforma): suporte a gIBSCBSMono para CST 620 monofasica [DEV-1929]

Adiciona suporte a tributacao monofasica IBS/CBS conforme NT 2025.002-RTC.
Produtos com CST 620 (combustiveis e demais itens monofasicos) agora emitem
<gIBSCBSMono> com qBCMono, adRemIBS, vIBSMono, adRemCBS e vCBSMono no lugar
do grupo padrao <gIBSCBS> (pIBSUF/pIBSMun/pCBS).

Contexto: SEFAZ rejeita (cStat 1026 - "Aliquota do IBS da UF invalida") qualquer
NF-e com CST 620 emitida com gIBSCBS padrao, pois a spec exige o grupo
gIBSCBSMono para regime monofasico.

Mudancas:
- NotaFiscalProduto ganha 5 novos atributos (ibscbs_q_bc_mono, ibscbs_ad_rem_ibs,
  ibscbs_v_ibs_mono, ibscbs_ad_rem_cbs, ibscbs_v_cbs_mono).
- _serializar_ibscbs roteia para _serializar_gibscbs_mono quando CST in
  _IBSCBS_CST_MONOFASICO (por ora so "620"; 630/640 virao no futuro).
- CST 620 removido de _IBSCBS_CST_TRIBUTADOS (agora pertence ao conjunto
  monofasico) para evitar emissao duplicada.
- Docs atualizadas: gIBSCBSMono removido da lista "Nao inclui".
- 3 novos testes (CST 620 com valores zero, CST 620 com ad rem, regressao CST 000).

* style(serializacao): aplica ruff format em gIBSCBSMono [DEV-1929]

---------

Co-authored-by: felps-dev <felps-dev@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 23, 2026 17:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adiciona suporte ao regime monofásico IBS/CBS para itens com CST 620, passando a serializar o grupo <gIBSCBSMono> (NT 2025.002-RTC) em vez do <gIBSCBS> tradicional, além de atualizar documentação e testes.

Changes:

  • Inclui novos atributos ibscbs_*_mono em NotaFiscalProduto para suportar os 5 campos do gIBSCBSMono.
  • Atualiza a serialização para despachar CST 620 para gIBSCBSMono e remove 620 do fluxo tributado padrão (gIBSCBS).
  • Atualiza docs e adiciona novos testes cobrindo a emissão de gIBSCBSMono e regressão para CST 000.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
pynfe/entidades/notafiscal.py Adiciona campos de entidade para os valores/quantidades do gIBSCBSMono (CST 620).
pynfe/processamento/serializacao.py Implementa a emissão de <gIBSCBSMono> para CST 620 e refatora helper do <gIBSCBS> padrão.
docs/reforma_tributaria.md Documenta a emissão do gIBSCBSMono e remove da lista de “não inclui”.
tests/test_nfe_serializacao_reforma_tributaria.py Adiciona 3 testes para CST 620 (mono) e regressão para CST 000.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

)
self.assertEqual(
xml.xpath("//ns:gIBSCBSMono/ns:vCBSMono", namespaces=self.ns)[0].text, "85.00"
)
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Os novos testes para CST 620 validam o XML por item, mas nao fixam a expectativa para os totais () quando vIBSMono/vCBSMono sao nao-zero. Como a implementacao atual pode omitir IBSCBSTot nesses casos (por nao acumular totais monofasicos), vale adicionar uma assercao explicita (seja para garantir que IBSCBSTot nao e emitido por enquanto, seja para validar gMono/totais quando forem implementados) para evitar regressao silenciosa.

Suggested change
)
)
self.assertEqual(
xml.xpath("//ns:IBSCBSTot", namespaces=self.ns),
[],
"Enquanto os totais monofasicos nao forem acumulados, <IBSCBSTot> nao deve ser emitido.",
)

Copilot uses AI. Check for mistakes.
Comment on lines +670 to +672
# ------------------------------------------------------------------
# Test gIBSCBSMono: CST 620 emits monophasic group
# ------------------------------------------------------------------
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Os blocos de comentario de secao agora ficam com numeracao inconsistente (apos inserir os testes de gIBSCBSMono, o bloco seguinte ainda diz "Test 10"). Isso dificulta manutencao/leitura do arquivo. Sugestao: renumerar as secoes ou trocar para titulos descritivos sem numeros.

Copilot uses AI. Check for mistakes.
Comment on lines +1054 to +1058
ibscbs_q_bc_mono = Decimal() # qBCMono
ibscbs_ad_rem_ibs = Decimal() # adRemIBS
ibscbs_v_ibs_mono = Decimal() # vIBSMono
ibscbs_ad_rem_cbs = Decimal() # adRemCBS
ibscbs_v_cbs_mono = Decimal() # vCBSMono
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Os novos campos ibscbs__mono foram adicionados na entidade, mas nao ha integracao com a acumulacao de totais da nota (ex: NotaFiscal.adicionar_produto_servico soma apenas ibscbs_vbc/ibscbs_v_ibs/ibscbs_v_cbs). Com CST 620 isso faz com que valores vIBSMono/vCBSMono nao sejam refletidos nos totais/IBSCBSTot, podendo gerar XML inconsistente (itens com valores monofasicos, mas totais zerados/ausentes). Sugestao: definir e acumular totais especificos (ex: totais_ibs_mono/totais_cbs_mono e/ou gMono) e/ou deixar explicitamente documentado/validado que totais monofasicos serao omitidos ate implementar gMono.

Copilot uses AI. Check for mistakes.
Comment on lines +1360 to +1363
if produto_servico.ibscbs_cst in self._IBSCBS_CST_MONOFASICO:
self._serializar_gibscbs_mono(produto_servico, ibscbs)
elif produto_servico.ibscbs_cst in self._IBSCBS_CST_TRIBUTADOS:
self._serializar_gibscbs(produto_servico, ibscbs)
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Para CST 620, o item passa a serializar vIBSMono/vCBSMono, mas o codigo de totais (IBSCBSTot) e habilitado somente quando existem totais_vbc_ibscbs/totais_ibs/totais_cbs. Como os itens monofasicos nao alimentam esses totais hoje, uma NF composta apenas por CST 620 pode sair sem IBSCBSTot mesmo com valores monofasicos nao-zero. Sugestao: propagar/contabilizar os valores monofasicos em campos de totais apropriados e ajustar o gate (has_reforma) e/ou emitir gMono quando houver CST monofasico.

Copilot uses AI. Check for mistakes.
Comment thread docs/reforma_tributaria.md Outdated

### Tributacao monofasica — `gIBSCBSMono`

Para produtos com CST 620 (combustiveis, etc.) o grupo emitido dentro de `<IBSCBS>` e `<gIBSCBSMono>` ao inves de `<gIBSCBS>`. Campos obrigatorios:
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A frase "o grupo emitido dentro de e " fica ambigua/gramaticalmente incorreta (parece listar dois grupos). Sugestao: reescrever para deixar explicito que o grupo emitido dentro de e (em vez de ).

Suggested change
Para produtos com CST 620 (combustiveis, etc.) o grupo emitido dentro de `<IBSCBS>` e `<gIBSCBSMono>` ao inves de `<gIBSCBS>`. Campos obrigatorios:
Para produtos com CST 620 (combustiveis, etc.), o grupo emitido dentro de `<IBSCBS>` e `<gIBSCBSMono>`, em vez de `<gIBSCBS>`. Campos obrigatorios:

Copilot uses AI. Check for mistakes.
felps-dev and others added 3 commits April 24, 2026 21:24
…-RTC [DEV-1953] (#3)

Ao emitir NF-e com CST 620 (Tributacao monofasica), o grupo <gIBSCBSMono>
estava sendo serializado com os cinco campos direto (qBCMono, adRemIBS,
vIBSMono, adRemCBS, vCBSMono), sem o wrapper <gMonoPadrao> exigido pelo
schema oficial (DFeTiposBasicos_v1.00.xsd, type TMonofasia).

SEFAZ rejeitava toda emissao com cStat 225:
  Falha no Schema XML da NFe
  Elemento: enviNFe/NFe[1]/infNFe/det[1]/imposto/IBSCBS/gIBSCBSMono/qBCMono

Alem do wrapper ausente, a ordem dos campos tambem violava o schema
(adRemCBS deve vir antes de vIBSMono, nao depois).

Estrutura corrigida:

  <gIBSCBSMono>
    <gMonoPadrao>
      <qBCMono>TDec1104RTC</qBCMono>
      <adRemIBS>TDec_0302_04RTC</adRemIBS>
      <adRemCBS>TDec_0302_04RTC</adRemCBS>
      <vIBSMono>TDec1302RTC</vIBSMono>
      <vCBSMono>TDec1302RTC</vCBSMono>
    </gMonoPadrao>
  </gIBSCBSMono>

Tests atualizados para validar wrapper + ordem correta conforme o
schema TMonofasia/gMonoPadrao (xsd linhas 687-727).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…no [DEV-1954] (#4)

Schema TMonofasia (DFeTiposBasicos_v1.00.xsd) define que gIBSCBSMono possui
duas tags REQUERIDAS (sem minOccurs=0) como siblings de gMonoPadrao:
vTotIBSMonoItem e vTotCBSMonoItem (ambos TDec1302RTC).

Antes deste fix, mesmo apos a DEV-1953 que adicionou o wrapper gMonoPadrao,
o XML emitido por PyNFe ainda terminava em </gMonoPadrao></gIBSCBSMono> sem
os dois totais, e SEFAZ rejeitava com cStat 225 "Falha no Schema XML da
NFe (Elemento: ...gIBSCBSMono/)" para todas as notas com CST 620 do cliente
E B DA FONSECA (loja 37, CNPJ 24712859000191).

Mudancas:

- NotaFiscalProduto: dois novos atributos ibscbs_v_tot_ibs_mono_item e
  ibscbs_v_tot_cbs_mono_item (default Decimal()) aceitos via kwargs em
  adicionar_produto_servico (Entidade.__setattr__ exige existencia previa).

- _serializar_gibscbs_mono: emite os dois totais como filhos diretos de
  gIBSCBSMono apos o gMonoPadrao, formatados em 2 casas decimais. Para
  itens single-line (sem retencao/diferimento) os totais devem igualar
  vIBSMono / vCBSMono. Quando nao informados pelo caller, emite 0.00 (default
  seguro durante o Teste de Carga 2026 com ad rem zerados).

- Tests: estende test_cst620_monofasica_emite_gibscbsmono e
  test_cst620_monofasica_com_valores_calculados para asserir presenca, ordem
  e tipo decimal dos totais. Adiciona test_cst620_v_tot_mono_item_default_zero_when_unset
  para garantir que o default seguro funciona quando o caller omite os campos.

- Docs (reforma_tributaria.md): atualiza o exemplo XML e a tabela de campos
  com vTotIBSMonoItem / vTotCBSMonoItem.
…-1955] (#5)

* fix(reforma): adiciona gMono em IBSCBSTot para itens monofasicos [DEV-1955]

Quando uma NF-e contem itens com <gIBSCBSMono> (CST 620), o totalizador
<IBSCBSTot> precisa emitir o subgrupo <gMono> com os seis campos obrigatorios
(vIBSMono, vCBSMono, vIBSMonoReten, vCBSMonoReten, vIBSMonoRet, vCBSMonoRet)
conforme schema TIBSCBSMonoTot/gMono em DFeTiposBasicos_v1.00.xsd. Sem o
subgrupo, SEFAZ rejeita com cStat 1119 ("Total de IBS e CBS nao informado").

Mudancas:

- pynfe/entidades/notafiscal.py: adiciona constante _IBSCBS_CST_MONOFASICO
  (espelho do set definido em SerializacaoXML), seis acumuladores
  totais_v_ibs_mono / totais_v_cbs_mono / totais_v_*_mono_reten /
  totais_v_*_mono_ret e contador totais_mono_item_count. Em
  adicionar_produto_servico, soma vTotIBSMonoItem / vTotCBSMonoItem dos
  itens e incrementa o contador quando o CST e monofasico.
- pynfe/processamento/serializacao.py: forca emissao de <IBSCBSTot> quando
  ha pelo menos um item monofasico (mesmo com totais standard zerados) e
  emite <gMono> com os seis filhos quando totais_mono_item_count > 0. Os
  filhos Reten/Ret ainda sao zero pois PyNFe so suporta <gMonoPadrao> a
  nivel de item, mas o schema exige todos os seis quando <gMono> e emitido.
- tests/test_nfe_serializacao_reforma_tributaria.py: 4 testes novos:
  test_ibscbstot_gmono_emitido_para_item_monofasico_unico (cenario E B
  DA FONSECA com qtde 18 e ad rem zero), test_ibscbstot_gmono_soma_
  multiplos_itens_monofasicos, test_ibscbstot_sem_gmono_quando_so_itens_
  padrao (regressao), test_ibscbstot_misto_emite_gibs_gcbs_e_gmono.
- docs/reforma_tributaria.md: atualiza exemplo de IBSCBSTot para incluir
  <gMono> e adiciona notas sobre quando o subgrupo e obrigatorio.

Tests: 153 passed (149 baseline + 4 novos). ruff check + format clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(reforma): substitui em-dashes por ASCII em comentarios [DEV-1955]

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants