feat: suporte a gIBSCBSMono para CST 620 (Tributacao Monofasica) — NT 2025.002-RTC - #456
feat: suporte a gIBSCBSMono para CST 620 (Tributacao Monofasica) — NT 2025.002-RTC#456felps-dev wants to merge 10 commits into
Conversation
…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>
There was a problem hiding this comment.
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_*_monoemNotaFiscalProdutopara suportar os 5 campos dogIBSCBSMono. - Atualiza a serialização para despachar CST 620 para
gIBSCBSMonoe remove 620 do fluxo tributado padrão (gIBSCBS). - Atualiza docs e adiciona novos testes cobrindo a emissão de
gIBSCBSMonoe 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" | ||
| ) |
There was a problem hiding this comment.
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.
| ) | |
| ) | |
| self.assertEqual( | |
| xml.xpath("//ns:IBSCBSTot", namespaces=self.ns), | |
| [], | |
| "Enquanto os totais monofasicos nao forem acumulados, <IBSCBSTot> nao deve ser emitido.", | |
| ) |
| # ------------------------------------------------------------------ | ||
| # Test gIBSCBSMono: CST 620 emits monophasic group | ||
| # ------------------------------------------------------------------ |
There was a problem hiding this comment.
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.
| 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 |
There was a problem hiding this comment.
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.
| 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) |
There was a problem hiding this comment.
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.
|
|
||
| ### Tributacao monofasica — `gIBSCBSMono` | ||
|
|
||
| Para produtos com CST 620 (combustiveis, etc.) o grupo emitido dentro de `<IBSCBS>` e `<gIBSCBSMono>` ao inves de `<gIBSCBS>`. Campos obrigatorios: |
There was a problem hiding this comment.
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 ).
| 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: |
…-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>
…EV-2177] (#6) O Informe Tecnico 2025.003 trocou o host de consulta da NFC-e de Goias de `nfe.sefaz.go.gov.br` / `homolog.sefaz.go.gov.br` para `nfeweb.sefaz.go.gov.br` (producao) e `nfewebhomolog.sefaz.go.gov.br` (homologacao). Emitir com o host antigo gera rejeicao 395 no SEFAZ-GO. Ajusta os prefixos HTTPS/HOMOLOGACAO do dict NFCE["GO"], que alimentam tanto o <qrCode> quanto o <urlChave> via SerializacaoQrcode.gerar_qrcode. Segue a mesma convencao de subdominio-por-UF ja usada por RS/MS no mesmo dict, sem mudanca na logica de serializacao. Adiciona teste de regressao cobrindo producao e homologacao para GO. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…[DEV-2266] (#7) - MDFeRecepcaoSinc agora envia o XML assinado do <MDFe> compactado com gzip e codificado em base64 como texto de mdfeDadosMsg, conforme o MOC do MDF-e (o envelope <enviMDFe>/<idLote> vale apenas para o envio assincrono). SVRS retornava HTTP 400 com corpo vazio para o formato antigo. - Resposta sincrona parseada: retorna (0, mdfeProc) quando autorizado e (1, retMDFe, manifesto) em rejeicao (tanto no nivel do retMDFe, ex. 580, quanto no nivel do protMDFe/infProt); resposta HTTP crua so quando o corpo nao e parseavel. - Content-Type application/soap+xml para o servico sincrono (SOAP 1.2). - Serializacao: omite <valePed/> vazio (rejeitado com cStat 580 pelo schema do modal) e omite <infANTT/> quando nenhum filho e serializado.
…o autorizador [DEV-2468] (#8) * fix(nfce): separa host de QRCode do host de webservice em GO [DEV-2468] As chaves HTTPS/HOMOLOGACAO de NFCE["GO"] eram lidas por dois consumidores: SerializacaoQrcode.gerar_qrcode (host do portal de consulta) e ComunicacaoSefaz._get_url (host do autorizador). Como GO usa servidores diferentes para os dois papeis, atualizar o host do QRCode para nfeweb (IT 2025.003) passou a POSTar toda autorizacao de NFC-e para o portal de consulta, que responde redirect + HTML - a nota nunca recebia veredito da SEFAZ e a falha aparecia como erro de transporte, sem rejeicao. Agora HTTPS/HOMOLOGACAO voltam ao host do autorizador (identicos a NFE["GO"]) e QR_HOST/QR_HOST_HOMOLOGACAO carregam o host do portal de consulta, lidos apenas pelo novo helper qrcode_host. SP e AM tambem passam a ler o host de QR pelo helper, com valores que preservam a saida byte a byte. Nenhuma UF fora de GO muda de comportamento. * docs(webservices): registra distincao entre host de consulta e de autorizador [DEV-2468] Documenta as duas familias de chave de host em webservices.py (autorizador vs portal de consulta) no AGENTS.md e no source map, e atualiza as contagens de linha dos mapas de webservices.py e serializacao.py. * test(nfce): trava hosts de qrCode e urlChave de SP, AM, BA e MG [DEV-2468]
…EV-2468] (#9) Mesma classe de defeito do GO: `NFCE["AM"]["HTTPS"]` carregava o prefixo do portal de consulta (`https://sistemas.`) enquanto os caminhos de endpoint de AM ja embutem o subdominio `nfce.`, produzindo `https://sistemas.nfce.sefaz.am.gov.br/nfce-services/...` — host que NAO existe (NXDOMAIN). Toda emissao de NFC-e em AM falhava sem nem abrir conexao. Dois fatos independentes fixam o prefixo correto: - `HOMOLOGACAO` = `https://hom` concatena para `homnfce.sefaz.am.gov.br`, que resolve e exige certificado de cliente (alert TLS 42, "Acceptable client certificate CA names", cert `CN=*.sefaz.am.gov.br`, `O=SECRETARIA DE ESTADO DA FAZENDA SEFAZ`) — assinatura de endpoint SOAP com mTLS. Logo os caminhos sao prefixados apenas com o esquema, e producao tem de ser `https://` -> `nfce.sefaz.am.gov.br`, que apresenta o mesmo certificado e a mesma exigencia de certificado de cliente. - `sistemas.sefaz.am.gov.br` completa o handshake sem certificado de cliente e apresenta `CN=sistemas.sefaz.am.gov.br` — e o portal publico, correto para `<qrCode>`/`<urlChave>` e errado para SOAP. O `<qrCode>`/`<urlChave>` de AM continua em `https://sistemas.` via `QR_HOST` (byte a byte identico, travado em `tests/test_nfce_qrcode_hosts_por_uf.py`). Essa separacao de chaves, introduzida pelo #8, e o que torna a correcao possivel sem tocar no QR — a razao registrada no #8 para postergar AM ("quebraria a garantia de byte-identidade") deixou de valer. Tambem neste commit: - `test_sp_e_am_mantem_o_host_de_qr_historico` passa a comparar com literais em vez de derivar o esperado de `NFCE[uf]["HTTPS"]` — derivar da chave sob correcao tornava a trava vazia exatamente quando ela importa. - `docs/webservices_map.md` e `docs/serializacao_map.md`: as ancoras de linha estavam desatualizadas (o docstring do #8 deslocou todo o `webservices.py`), o que anula o proposito dos source maps. Recalculadas contra o arquivo real.
…A/PR [DEV-2468] (#10) * fix(nfce): urlChave e campo proprio, nao o endereco do QR Code [DEV-2468] O <urlChave> era montado como qrcode_host(uf) + NFCE[uf]["URL"], reaproveitando a familia de host do QR Code. Sao registros oficiais DIFERENTES: GO rejeita 878 ("Endereco do site da UF da Consulta por chave de acesso diverge do previsto") ao receber o endereco do leitor de QR no urlChave. O IT 2025.003, que originou o DEV-2177, define somente a URL do QR Code, por isso a rodada anterior acertou o <qrCode> e nao percebeu o outro campo. Introduz CONSULTA_CHAVE / CONSULTA_CHAVE_HOMOLOGACAO com a URL COMPLETA e verbatim do registro, lida por url_consulta_chave. Nenhum prefixo de host e concatenado nesse valor - foi essa concatenacao sobre URLs ja completas que gerou lixo do tipo https://nfce.http://www.dfe.ms.gov.br/nfce/consulta. gerar_qrcode passa a ter um unico ponto de montagem do urlChave, sem host, e as ramificacoes por UF ficam restritas ao <qrCode>. Valores de ACBrNFeServicos.ini (URL-ConsultaNFCe_2.00), confirmados para GO pelo registro ENCAT: - GO [NFCe_GO_P]/[NFCe_GO_H]: emitia o portal nfeweb; agora http://www.sefaz.go.gov.br/nfce/consulta e a pagina de homologacao do nfce.go. - BA [NFCe_BA_P]/[NFCe_BA_H]: emitia hinternet (valor de HOMOLOGACAO) tambem em producao; agora http://www.sefaz.ba.gov.br/nfce/consulta em producao. - PR [NFCe_PR_P]/[NFCe_PR_H]: valor ja correto, agora declarado na chave dedicada para nao voltar a depender do caminho legado. Saida byte-identica. O <qrCode> nao muda em nenhuma UF, e o urlChave de RJ, AC, DF, PE e SC continua byte-identico. As demais UFs divergentes (AP, ES, MS, RS, AM, CE, MG, PA, RO, RR, SE) ficam como estao: nao ha loja nelas para validar a correcao. * docs(nfce): docstrings de qrcode_host paravam de citar o urlChave [DEV-2468] Depois da separacao dos dois campos, qrcode_host serve apenas o <qrCode>. As docstrings que ainda diziam "<qrCode>/<urlChave>" descrevem exatamente o acoplamento que gerou a rejeicao 878, e apontam o proximo leitor para o helper errado.
… [DEV-2468] (#11) Revisao da rodada DEV-2468 (PRs #8, #9, #10). Nenhuma mudanca de comportamento: so corrige documentacao que os proprios testes da rodada contradizem. 1. A regra "nenhuma UF usa o mesmo endereco no qrCode e no urlChave" era falsa em tres lugares (AGENTS.md, docstring de webservices.py, webservices_map.md). O teste da mesma rodada trava UFS_URLCHAVE_IGUAL_AO_QRCODE = {"RS", "SC"} e documenta que o ACBr registra o mesmo endereco nos dois campos para SC. Como estava, a regra levaria um agente futuro a "corrigir" SC, que esta pinado byte-identico. 2. A docstring de qrcode_host afirmava nao servir o urlChave, mas url_consulta_chave chama qrcode_host no caminho legado (UF sem CONSULTA_CHAVE). E justamente esse acoplamento que exigiu QR_HOST em AM e SP nesta rodada. 3. Source maps com numeros errados e contraditorios entre si: AGENTS.md dizia 2895 linhas para serializacao.py (real 2881) e 615 para webservices.py; a linha de SerializacaoNfse no serializacao_map.md apontava 2326-2392 (real 2312-2378, sobrepondo SerializacaoQrcodeMDFe); e todas as faixas de secao do webservices_map.md estavam deslocadas (NFE listada em 343-514, real 412-583). AGENTS.md torna a leitura do map obrigatoria antes de abrir arquivo grande, entao numero errado manda o proximo agente para a janela errada. Todas as faixas foram recalculadas do arquivo.
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
gIBSCBSMonoda lista de "Nao inclui (ainda)" documentada emdocs/reforma_tributaria.md.Contexto
Produtos com CST IBS/CBS 620 (combustiveis monofasicos, ex: GLP) emitiam
<gIBSCBS>padrao compIBSUF/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 monofasicaadRemIBS(TDec_0302a10) — aliquota ad rem IBS em R$ por unidadevIBSMono(TDec_1302) — valor IBS monofasicoadRemCBS— aliquota ad rem CBS em R$ por unidadevCBSMono— valor CBS monofasicoMudancas
pynfe/entidades/notafiscal.pyCinco novos atributos em
NotaFiscalProduto, adjacentes aos existentesibscbs_*:ibscbs_q_bc_monoibscbs_ad_rem_ibsibscbs_v_ibs_monoibscbs_ad_rem_cbsibscbs_v_cbs_monopynfe/processamento/serializacao.py_IBSCBS_CST_MONOFASICO = ("620",)._IBSCBS_CST_TRIBUTADOS(agora roteado pelo caminho monofasico)._serializar_ibscbsdespacha para novo helper_serializar_gibscbs_monoquando o CST esta em_IBSCBS_CST_MONOFASICO, emitindo<gIBSCBSMono>com os 5 filhos na ordem do schema.<gIBSCBS>tradicional — zero regressao.docs/reforma_tributaria.mdgIBSCBSMonoremovido da lista "Nao inclui (ainda)".tests/test_nfe_serializacao_reforma_tributaria.pyTres novos casos de teste:
<gIBSCBSMono>com campos zerados.<gIBSCBSMono>com valores calculados.<gIBSCBS>padrao comgIBSUF/gIBSMun/gCBS.Validacao local
pytest tests/— 146 passed (excluidos testes opcionais NFSe que requerempyxb).ruff check .— limpo.ruff format --check .— limpo.Out of scope / deferred
<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+.cClassTribcorrespondentes. Comeca com apenas 620 por enquanto.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
pynfe/data/XSDs/NF-e/leiauteNFe_v4.00.xsd(typesTIBSCBSMono,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).