Skip to content

fix(danfse): aplicar exibição condicional do regime especial e da linha municipal #120

Closed

Description

@vitormattos

Problema

O DANFSe v2 renderizado por nfse-php apresenta a célula Regime Especial de Tributação incondicionalmente na primeira linha do bloco "Tributação Municipal (ISSQN)", ao lado de "Tipo de Tributação do ISSQN" e "Município / UF / País de Incidência".

Isso não respeita integralmente a distribuição e as regras condicionais da NT SE/CGNFS-e nº 008/2026, versão 1.02:

  • No Anexo I / item 2.4.5, Regime Especial de Tributação do ISSQN integra uma linha de campos condicionais junto a imunidade, suspensão de exigibilidade e outros campos municipais.
  • Pela nota 5, essa linha pode ser suprimida quando todos os seus campos estão sem dados no XML. Não é correto tomar a ausência do regime isoladamente como autorização para ocultar outros campos presentes.
  • O código regEspTrib=0 é um valor fiscal válido e significa "Nenhum": não equivale à ausência da tag.
  • O domínio oficial admite 0,1,2,3,4,5,6,9. src/Danfse/Enum/RegimeEspecialTributacao.php reconhece apenas 0–6, logo 9 ("Outros") atualmente é apresentado como desconhecido.

A ausência de testes específicos para essas combinações permite regressões mesmo quando todos os rótulos principais do PDF estão presentes.

Evidências no código

  • src/Danfse/DanfseTemplate.php: buildData() converte DPS/infDPS/prest/regTrib/regEspTrib em tributacao_municipal.regime_especial via RegimeEspecialTributacao::labelFor(), sem fornecer informações de presença/ausência e agrupamento condicional da linha.
  • src/Danfse/HTMLTemplate.php: imprime sempre a célula de regime especial na linha inicial de tributação municipal, independentemente da presença de outros campos condicionais.
  • src/Danfse/Enum/RegimeEspecialTributacao.php e tests/Unit/Danfse/RegimeEspecialTributacaoTest.php: não abrangem 9 ("Outros").

Resultado esperado

  1. Representar corretamente todos os códigos de regime especial admitidos pelo contrato oficial, inclusive 9 = Outros; preservar 0 = Nenhum.
  2. Reorganizar a célula de regime especial para a linha correspondente no modelo do DANFSe, respeitando a disposição do Anexo I.
  3. Derivar a presença da linha condicional inteira da existência de dados nos campos pertinentes do XML autorizado. Quando não houver dados em nenhum campo da linha, permitir sua supressão conforme a nota 5, sem ocultar campos válidos de outros participantes da linha.
  4. Distinguir explicitamente tag ausente, valor 0 válido e valor não reconhecido, sem inventar enquadramentos fiscais.
  5. Para operações não sujeitas à incidência de ISSQN, respeitar a regra própria de substituição/supressão do bloco municipal estabelecida na seção 2.3 e nota 4; não mostrar indevidamente a linha de regime especial.
  6. Não introduzir informações tributárias que não estejam no XML nem inferir o regime pela natureza jurídica da empresa.

Coordenação com a auditoria #119 / épico #118: mapear e utilizar os dados dos campos irmãos necessários à condição de exibição da linha. Demais campos municipais ausentes são avaliados no escopo da conformidade integral; não aproveitar esta issue para alterar apuração de ISS ou construir toda a lógica de benefícios fiscais.

Testes e verificação

  • Traduzir regEspTrib=0 para "Nenhum" e regEspTrib=9 para "Outros".
  • Verificar regEspTrib válido, ausente e desconhecido, sem alterar o XML.
  • Verificar que regEspTrib ausente não esconde campos condicionais presentes na mesma linha.
  • Verificar que a linha pode ser suprimida quando todos os seus campos estão ausentes.
  • Verificar que valor 0 presente não é tratado como ausência.
  • Verificar as condições de operação não sujeita a ISSQN.
  • Testar posição e agrupamento de células com asserts estruturais do HTML, além dos rótulos.
  • Gerar PDF local a partir de XMLs inteiramente sintéticos e inspecionar o bloco ISSQN sem cortes, linhas vazias indevidas ou deslocamentos.
  • Executar composer test, composer cs:check, composer psalm e CI pertinente.

Se o contrato de estado da operação não constar do XML autorizado, documentar a incerteza na discussão da issue/PR em vez de inventar valor no PDF.

Referências

Fora de escopo

  • Modificar regEspTrib na DPS, validar enquadramento tributário do contribuinte ou alterar emissão.
  • Modificar cálculos, retenções e bases do ISSQN.
  • Acoplar o renderizador ao ERP ou a cadastros específicos.
  • Criar arquivos Markdown de diagnósticos, diários de implementação ou estados transitórios. Referências normativas, evidências e progresso ficam nas issues/PRs.
  • Usar dados reais de empresas, clientes ou documentos nas fixtures e evidências.

Activity

  1. vitormattos commented on Oct 12, 2026

    @vitormattos
    MemberAuthor

    Implementação preliminar no draft PR #123 (commit fcb4976, assinatura verificada, DCO válido). Distinção entre tag ausente/zero/9, apresentação da linha municipal condicional e testes sintéticos. Não pronto para merge: conferir caminhos XML/XSD de benefício/imunidade/deduções, semântica de não incidência e PDFs renderizados; CI pendente. Não altera DPS, elegibilidade de regime (#424 Akaunting), cálculo nem PR #116.

  2. vitormattos commented on Oct 12, 2026

    @vitormattos
    MemberAuthor

    Contrato de entrada confirmado na frente Akaunting #424 (12/10/2026)

    O produtor de DPS foi integrado à LibreCodeCoop/akaunting-nfse pelos PRs #437 e #441 (merge final 2f7cc1f). A biblioteca nfse-php incorporou nos PRs #134 e #135 o suporte de DpsData::regimeApuracaoSimplesNacional e a serialização <regApTribSN> para opSimpNac=3, preservando a API posicional.

    Handoff exclusivamente para o renderer #120: usar XML autorizado sintético como fonte, distinguir ausência física de regEspTrib (documento histórico/incompleto), <regEspTrib>0</regEspTrib> (Nenhum) e <regEspTrib>9</regEspTrib> (Outros), além de outros campos municipais presentes na linha condicional. Não reinterpretar regApTribSN como regEspTrib, não inferir regime pelo cadastro e não apagar a linha inteira quando algum campo irmão deve aparecer. Testar XML → HTML estrutural → PDF local com documentos sintéticos; sem transmissão e sem sobrescrever arquivos históricos.

    A issue Akaunting #424 não pode reivindicar sua validação de apresentação enquanto #120/PR #123 não estiverem concluídos. Não se propõe alteração nesta frente de XML ou de autorização municipal; somente contrato verificável para os testes do DANFSe.

  3. vitormattos commented on Oct 12, 2026

    @vitormattos
    MemberAuthor

    Validação final das linhas municipais condicionais: regEspTrib ausente, 0 (Nenhum), 9 (Outros), desconhecido, exibição de outros campos presentes, zero verdadeiro em benefício/imunidade e operação não sujeita a ISS (códigos 2/3/4). O modelo, HTML e PDFs sintéticos estão incorporados no PR #136, merge 11fa63d (CI 10/10, A4 em uma página nos cenários visuais). Não há cálculo de tributos nem alteração do XML. PR #123 foi encerrado como substituído. Escopo encerrado, com a fonte tipográfica estrita ainda rastreada no épico #118.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions