Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 47 additions & 3 deletions docs/reforma_tributaria.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,43 @@ A implementacao cobre:
- `vNF` **NAO inclui** IBS/CBS (proibido em 2025-2026)
- `finNFe=5` (Nota de Debito) e `finNFe=6` (Nota de Credito)
- Campos de entidade para IS (Imposto Seletivo) — **armazenados mas nao serializados** ate o schema suportar (2027)
- Tributacao monofasica (`gIBSCBSMono`) para CST 620 — combustiveis e demais produtos sujeitos ao regime monofasico de IBS/CBS

**Nao inclui** (ainda): Split Payment, cashback, eventos de apuracao assistida, Grupo VB (total do item), Grupo VC (referenciamento de DF-e), Grupo BB (antecipacao de pagamento), tributacao monofasica (`gIBSCBSMono`), diferimento per-item (`gDif`), devolucao de tributos per-item (`gDevTrib`), reducao de aliquota per-item (`gRed`), estorno de credito (`gEstornoCred`), credito presumido per-item (`gCredPresOper`, `gCredPresIBSZFM`).
**Nao inclui** (ainda): Split Payment, cashback, eventos de apuracao assistida, Grupo VB (total do item), Grupo VC (referenciamento de DF-e), Grupo BB (antecipacao de pagamento), diferimento per-item (`gDif`), devolucao de tributos per-item (`gDevTrib`), reducao de aliquota per-item (`gRed`), estorno de credito (`gEstornoCred`), credito presumido per-item (`gCredPresOper`, `gCredPresIBSZFM`).

### Tributacao monofasica — `gIBSCBSMono`

Para produtos com CST 620 (combustiveis, etc.) o grupo emitido dentro de `<IBSCBS>` e `<gIBSCBSMono>` ao inves de `<gIBSCBS>`. Conforme o schema oficial (`DFeTiposBasicos_v1.00.xsd`, type `TMonofasia`), os cinco campos monofasicos vivem sob o wrapper obrigatorio `<gMonoPadrao>` e na ordem definida pelo schema. Alem disso, `<vTotIBSMonoItem>` e `<vTotCBSMonoItem>` sao SIBLINGS de `<gMonoPadrao>` (NAO filhos) e ambos sao OBRIGATORIOS por schema (sem `minOccurs=0`):

```xml
<gIBSCBSMono>
<gMonoPadrao>
<qBCMono>18.0000</qBCMono>
<adRemIBS>0.1000</adRemIBS>
<adRemCBS>0.0000</adRemCBS>
<vIBSMono>1.80</vIBSMono>
<vCBSMono>0.00</vCBSMono>
</gMonoPadrao>
<vTotIBSMonoItem>1.80</vTotIBSMonoItem>
<vTotCBSMonoItem>0.00</vTotCBSMonoItem>
</gIBSCBSMono>
```

| Campo | Tipo | Descricao |
|-------|------|-----------|
| `qBCMono` | TDec1104RTC | Quantidade tributada na base monofasica |
| `adRemIBS` | TDec_0302_04RTC | Aliquota ad rem IBS (valor em BRL por unidade) |
| `adRemCBS` | TDec_0302_04RTC | Aliquota ad rem CBS (valor em BRL por unidade) |
| `vIBSMono` | TDec1302RTC | Valor IBS monofasico |
| `vCBSMono` | TDec1302RTC | Valor CBS monofasico |
| `vTotIBSMonoItem` | TDec1302RTC | Total IBS monofasico do item (sibling de `gMonoPadrao`) |
| `vTotCBSMonoItem` | TDec1302RTC | Total CBS monofasico do item (sibling de `gMonoPadrao`) |

Atributos na entidade `NotaFiscalProduto`: `ibscbs_q_bc_mono`, `ibscbs_ad_rem_ibs`, `ibscbs_v_ibs_mono`, `ibscbs_ad_rem_cbs`, `ibscbs_v_cbs_mono`, `ibscbs_v_tot_ibs_mono_item`, `ibscbs_v_tot_cbs_mono_item`.

Para itens single-line (sem retencao / retencao anterior / diferimento), `vTotIBSMonoItem == vIBSMono` e `vTotCBSMonoItem == vCBSMono`. Quando os atributos nao sao informados pelo caller, o serializador emite `0.00` (default seguro durante o Teste de Carga 2026 com ad rem zerados).

Durante o Teste de Carga 2026 os ad rem ainda nao foram publicados pela SEFAZ, entao os valores podem ser zerados — o grupo `gIBSCBSMono` ainda sera emitido corretamente.

## CSTs disponiveis

Expand Down Expand Up @@ -300,13 +335,22 @@ Os totais ficam em um grupo **separado** de `<ICMSTot>`, como irmao dentro de `<
<vCredPres>0.00</vCredPres>
<vCredPresCondSus>0.00</vCredPresCondSus>
</gCBS>
<!-- gMono: totais monofasia (nao implementado) -->
<gMono> <!-- Totais monofasia (DEV-1955) -->
<vIBSMono>0.00</vIBSMono> <!-- Total IBS monofasico padrao -->
<vCBSMono>0.00</vCBSMono> <!-- Total CBS monofasica padrao -->
<vIBSMonoReten>0.00</vIBSMonoReten> <!-- Total IBS monofasico sujeito a retencao -->
<vCBSMonoReten>0.00</vCBSMonoReten> <!-- Total CBS monofasica sujeita a retencao -->
<vIBSMonoRet>0.00</vIBSMonoRet> <!-- Total IBS monofasico retido anteriormente -->
<vCBSMonoRet>0.00</vCBSMonoRet> <!-- Total CBS monofasica retida anteriormente -->
</gMono>
<!-- gEstornoCred: totais estorno de credito (nao implementado) -->
</IBSCBSTot>
</total>
```

> Os subgrupos `gIBS` e `gCBS` sao opcionais (`minOccurs="0"`) — emitidos apenas quando ha valores. Os campos `vDif`, `vDevTrib`, `vCredPres` e `vCredPresCondSus` sao obrigatorios dentro de cada subgrupo (emitidos como "0.00" quando nao utilizados).
>
> O subgrupo `gMono` e opcional, mas obrigatorio sempre que algum item da NF-e carregar `<gIBSCBSMono>` (CST 620, etc.). Quando emitido, **todos os seis filhos** sao obrigatorios (`vIBSMono`, `vCBSMono`, `vIBSMonoReten`, `vCBSMonoReten`, `vIBSMonoRet`, `vCBSMonoRet`). Omitir `<gMono>` em uma NF-e com items monofasicos faz a SEFAZ rejeitar com `cStat 1119 - "Total de IBS e CBS nao informado"`. Os totais `Reten`/`Ret` ainda nao sao acumulados a nivel de item (PyNFe ainda so emite `<gMonoPadrao>`), entao serao "0.00" ate que `<gMonoReten>` / `<gMonoRet>` / `<gMonoDif>` sejam suportados a nivel de item.

### Cabecalho — `cMunFGIBS` no `<ide>`

Expand Down Expand Up @@ -338,7 +382,7 @@ Esses CSTs geram apenas `<CST>` e `<cClassTrib>`, sem `<gIBSCBS>`.

- **`cClassTrib`**: Emitido quando informado (campo obrigatorio na pratica)
- **`cMunFGIBS`**: Emitido no `<ide>` apenas quando informado
- **`<IBSCBSTot>`**: Tipo `TIBSCBSMonoTot`. Omitido se todos os totais forem zero. Quando emitido, `vBCIBSCBS` e obrigatorio como primeiro filho; `gIBS` e `gCBS` sao opcionais
- **`<IBSCBSTot>`**: Tipo `TIBSCBSMonoTot`. Omitido se todos os totais forem zero E nenhum item carregar `<gIBSCBSMono>`. Quando emitido, `vBCIBSCBS` e obrigatorio como primeiro filho; `gIBS`, `gCBS` e `gMono` sao opcionais (mas `gMono` e obrigatorio sempre que houver items monofasicos)
- **`<IBSCBS>`**: Tipo `TTribNFe`. Omitido completamente se `ibscbs_cst` nao for informado
- **IS (`<IS>`)**: Tipo `TIS`. **Nao emitido no XML** — serializacao desabilitada ate 2027
- **`<ISTot>`**: Tipo `TISTot`. **Nao emitido** — sera irmao de `<IBSCBSTot>` (antes dele no schema)
Expand Down
56 changes: 56 additions & 0 deletions pynfe/entidades/notafiscal.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@

from .base import CampoDeprecated, Entidade

# CSTs IBS/CBS that route to <gIBSCBSMono> instead of <gIBSCBS>. Mirrors
# the constant in pynfe.processamento.serializacao but defined here so the
# NotaFiscal accumulator can detect monofasic items without importing the
# serializer. Keep in sync with SerializacaoXML._IBSCBS_CST_MONOFASICO.
_IBSCBS_CST_MONOFASICO = ("620",)


class NotaFiscal(Entidade):
# campos deprecados
Expand Down Expand Up @@ -310,6 +316,24 @@ class NotaFiscal(Entidade):
totais_cbs = Decimal()
totais_is = Decimal()

# Reforma Tributaria - Totais Monofasia (Group W03 - IBSCBSTot/gMono)
# Per NT 2025.002-RTC schema TIBSCBSMonoTot, when ANY item carries
# <gIBSCBSMono>, the IBSCBSTot wrapper MUST emit a <gMono> sibling with
# six TDec1302RTC values (all REQUIRED inside <gMono>): vIBSMono,
# vCBSMono, vIBSMonoReten, vCBSMonoReten, vIBSMonoRet, vCBSMonoRet.
# SEFAZ rejects with cStat 1119 ("Total de IBS e CBS nao informado")
# when items emit <gIBSCBSMono> but the totalizer omits <gMono>.
# ``totais_mono_item_count`` tracks the number of monofasic items so
# the serializer can decide to emit <gMono> even when all six values
# are zero (Teste de Carga 2026 scenario, where every ad rem is 0).
totais_v_ibs_mono = Decimal() # sum of vTotIBSMonoItem (gMonoPadrao)
totais_v_cbs_mono = Decimal() # sum of vTotCBSMonoItem (gMonoPadrao)
totais_v_ibs_mono_reten = Decimal() # sum of vTotIBSMonoItem (gMonoReten)
totais_v_cbs_mono_reten = Decimal() # sum of vTotCBSMonoItem (gMonoReten)
totais_v_ibs_mono_ret = Decimal() # sum of vTotIBSMonoItem (gMonoRet)
totais_v_cbs_mono_ret = Decimal() # sum of vTotCBSMonoItem (gMonoRet)
totais_mono_item_count = int()

# Reforma Tributaria - cMunFGIBS (Group B)
municipio_fato_gerador_ibs = str()

Expand Down Expand Up @@ -483,6 +507,21 @@ def adicionar_produto_servico(self, **kwargs):
self.totais_cbs += obj.ibscbs_v_cbs
self.totais_is += obj.is_valor

# Reforma Tributaria - Totais Monofasia (IBSCBSTot/gMono per NT 2025.002-RTC)
# Aggregate item-level vTotIBSMonoItem / vTotCBSMonoItem so the
# serializer can emit <gMono> with the required totals. PyNFe today
# only supports <gMonoPadrao> at item level (see _serializar_gibscbs_mono),
# so the Reten/Ret accumulators stay at zero, but the schema requires
# all six fields to be emitted whenever <gMono> is present, so they
# are kept here to align with TIBSCBSMonoTot/gMono.
# ``totais_mono_item_count`` is incremented when CST routes to mono,
# giving the serializer a stable signal to emit <gMono> even if every
# value is zero (Teste de Carga 2026 scenario).
self.totais_v_ibs_mono += obj.ibscbs_v_tot_ibs_mono_item
self.totais_v_cbs_mono += obj.ibscbs_v_tot_cbs_mono_item
if obj.ibscbs_cst in _IBSCBS_CST_MONOFASICO:
self.totais_mono_item_count += 1

# TODO calcular impostos aproximados
# self.totais_tributos_aproximado += obj.tributos

Expand Down Expand Up @@ -1046,6 +1085,23 @@ class NotaFiscalProduto(Entidade):
ibscbs_p_cbs = Decimal() # pCBS
ibscbs_v_cbs = Decimal() # vCBS

# gIBSCBSMono - Tributacao monofasica (CST 620)
# Emitted as <gIBSCBSMono> instead of <gIBSCBS> for CST 620 items.
# qBCMono = quantity in monophasic base unit (TDec_1104v)
# adRemIBS / adRemCBS = ad rem rate in BRL per unit (TDec_0302a10)
# vIBSMono / vCBSMono = final value in BRL
# vTotIBSMonoItem / vTotCBSMonoItem = item-level mono totals (TDec1302RTC). Per
# NT 2025.002-RTC schema TMonofasia, these are REQUIRED siblings of
# <gMonoPadrao> inside <gIBSCBSMono> (NOT children of <gMonoPadrao>). For a
# single-line item without retencao/diferimento, they equal vIBSMono/vCBSMono.
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
Comment on lines +1097 to +1101
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.
ibscbs_v_tot_ibs_mono_item = Decimal() # vTotIBSMonoItem
ibscbs_v_tot_cbs_mono_item = Decimal() # vTotCBSMonoItem

# IS (Imposto Seletivo) - Group UB-IS
is_cst_selec = str() # CSTSelec (2-digit)
is_c_class_trib = str() # cClassTribIS 6-digit
Expand Down
Loading
Loading