Programação Por Equipe DevBras

Capa do artigo: ACBr emite a nota, mas quem decide CFOP, CST e regime é o contador

ACBr emite a nota, mas quem decide CFOP, CST e regime é o contador

Separe o que a biblioteca fiscal faz do que é decisão profissional: monte com o contador uma matriz fiscal no banco e deixe o código só aplicar a regra aprovada.

A loja de roupas Ateliê Bruna ligou todos os módulos do componente fiscal "para o sistema ficar completo". Na primeira semana, as vendas do site para clientes de outros estados saíram como NFC-e, autorizadas sem nenhum erro técnico, e o contador só descobriu no fechamento do mês. A biblioteca obedeceu. A regra fiscal, ninguém tinha definido.

A resposta curta: a biblioteca entrega o encanamento técnico, não a decisão fiscal. Ela monta o XML, assina, transmite e interpreta o retorno. Qual documento cada operação exige, qual CFOP, qual situação tributária, qual regime: isso vem de quem responde pela contabilidade. O caminho seguro é escrever essas decisões numa matriz fiscal guardada no banco, aprovada pelo contador, e deixar o código apenas aplicar o que está lá.

O que a biblioteca faz e o que ela não sabe

Projetos como o ACBr, um conjunto de componentes de código aberto muito usado no Brasil, resolvem a parte difícil da tecnologia: leiaute dos documentos, assinatura com certificado digital, comunicação com os webservices das Secretarias da Fazenda, impressão do DANFE, leitura de retornos. É trabalho enorme e valioso, e reescrever isso do zero raramente faz sentido.

O que nenhum componente sabe é a sua operação. Ele não sabe se a Ateliê Bruna é do Simples Nacional ou do regime normal, se a venda é para consumidor final ou para outra empresa, se o produto tem substituição tributária no estado, se a saída é venda, devolução, remessa ou brinde. A biblioteca preenche os campos com o que você mandar. Se você mandar errado, ela emite errado, com toda a competência técnica.

É por isso que "o sistema faz a parte fiscal porque tem a DLL" é uma promessa perigosa. O sistema pode aplicar a regra com perfeição. Criar a regra é outra profissão.

Por que a decisão fiscal acaba escondida no código

O caminho natural de um projeto é este: o desenvolvedor copia um exemplo que funcionou em homologação, com um CFOP e uma situação tributária fixos, e a primeira venda real usa os mesmos valores. Depois aparece uma venda interestadual e alguém adiciona um if. Depois uma devolução, outro if. Em seis meses, a política fiscal da empresa está espalhada em condicionais que só o programador entende, e o contador não tem como revisar.

O resultado é que a pergunta "qual documento esta venda exige?" não tem dono. O programador acha que o contador definiu. O contador acha que o sistema está configurado. A loja acha que está tudo certo porque as notas saem autorizadas.

Como montar a matriz fiscal com o contador

  1. Liste as operações reais da empresa, em linguagem de negócio: venda no balcão, venda no site para pessoa física no mesmo estado, venda no site para outro estado, venda para empresa, devolução de cliente, troca.
  2. Leve a lista ao contador e peça, para cada operação, o modelo do documento, o CFOP, a situação tributária e qualquer observação obrigatória. Registre quem aprovou e quando.
  3. Guarde a matriz numa tabela, não em constantes no código. Cada linha é uma regra aprovada.
  4. Faça o código escolher a regra pela operação e falhar alto quando não encontrar nenhuma. Venda sem regra não emite.
  5. Emita uma nota de cada linha em homologação e mande os XMLs para o contador conferir antes de ligar produção.
  6. Revise a matriz quando a empresa mudar: novo regime, novo estado de venda, novo tipo de produto, nova Nota Técnica publicada.

A tabela de regras da Ateliê Bruna

Os valores abaixo são ilustrativos, de uma empresa fictícia do Simples Nacional. Os códigos reais da sua operação dependem do regime, do estado, do produto e do destinatário, e quem define é o contador.

CREATE TABLE regra_fiscal (
  id INT PRIMARY KEY AUTO_INCREMENT,
  operacao VARCHAR(40) NOT NULL,
  destino VARCHAR(13) NOT NULL,
  modelo CHAR(2) NOT NULL,
  cfop CHAR(4) NOT NULL,
  csosn CHAR(3) NOT NULL,
  observacao VARCHAR(255) NULL,
  aprovado_por VARCHAR(80) NOT NULL,
  aprovado_em DATE NOT NULL,
  ativo TINYINT(1) NOT NULL DEFAULT 1,
  UNIQUE KEY uk_regra (operacao, destino)
);

INSERT INTO regra_fiscal (operacao, destino, modelo, cfop, csosn, aprovado_por, aprovado_em) VALUES
  ('venda_balcao', 'interna', '65', '5102', '102', 'Contabilidade Exemplo', '2026-09-30'),
  ('venda_site', 'interna', '55', '5102', '102', 'Contabilidade Exemplo', '2026-09-30'),
  ('venda_site', 'interestadual', '55', '6108', '102', 'Contabilidade Exemplo', '2026-09-30');

Modelo 65 é a NFC-e, pensada para venda ao consumidor final dentro do estado; modelo 55 é a NF-e. As colunas aprovado_por e aprovado_em parecem burocracia, mas são o que responde à pergunta "quem decidiu isso?" daqui a dois anos.

No código, a escolha vira uma consulta simples:

SELECT modelo, cfop, csosn, observacao
FROM regra_fiscal
WHERE operacao = ? AND destino = ? AND ativo = 1;

Se a consulta não retornar nada, o pedido fica com status "aguardando regra fiscal" e alguém é avisado. É melhor uma venda esperando uma hora do que cem notas emitidas com o código de outra operação. O NCM, que identifica a mercadoria, fica no cadastro de cada produto, também conferido pelo contador.

Rejeição não é bug de código até prova em contrário

Quando a Secretaria da Fazenda rejeita uma nota, o retorno traz um código de status e um motivo por escrito. Muita equipe abre um chamado de bug sem ler a mensagem. Leia primeiro. Rejeições costumam cair em três grupos: dado cadastral (CNPJ, inscrição estadual, endereço), regra fiscal (combinação de CFOP, situação tributária e destino que não faz sentido) e técnico (schema, assinatura, certificado vencido, serviço fora do ar).

Só o terceiro grupo é problema do programador. Os outros dois são do cadastro e da matriz. Registre o código e o motivo de cada rejeição numa tabela; em um mês você sabe quais regras precisam voltar ao contador. O post sobre NF-e rejeitada com XML que parece perfeito cobre o lado técnico de schema e assinatura.

Atualizar a biblioteca de propósito, não no dia da rejeição

O leiaute fiscal muda por meio de Notas Técnicas publicadas no Portal da NF-e, com prazos de homologação e produção. A biblioteca precisa acompanhar, e alguém no projeto precisa acompanhar a biblioteca. Programe a atualização: leia a Nota Técnica, atualize o componente num branch, rode as notas de exemplo em homologação, publique. Esperar o dia em que produção começa a rejeitar é transformar manutenção prevista em incêndio. O post sobre biblioteca fiscal que acompanha o leiaute trata desse ciclo.

Erros comuns

  • Ligar todos os módulos "para ficar completo": o sistema passa a emitir documentos que a empresa não deveria emitir, sem ninguém perceber.
  • CFOP e situação tributária fixos no código: a política fiscal fica invisível para o contador e muda a cada if novo.
  • Emitir com regra padrão quando não há regra para a operação: a nota sai autorizada e errada, e corrigir depois dá muito mais trabalho.
  • Tratar toda rejeição como bug: o programador mexe no código para "passar" uma regra fiscal que estava errada na origem.
  • Prometer ao cliente que o sistema faz a contabilidade: você assume uma responsabilidade profissional que o software não cumpre.
  • Atualizar a biblioteca só quando produção quebra: a correção vira emergência, sem teste em homologação.

Checklist

  • Existe uma lista escrita das operações fiscais da empresa.
  • Cada operação tem uma regra na tabela, com quem aprovou e quando.
  • O código não tem CFOP nem situação tributária fixos.
  • Pedido sem regra fiscal não emite e gera aviso.
  • Cada regra foi testada em homologação e conferida pelo contador.
  • Rejeições são registradas com código, motivo e classificação.
  • Há alguém responsável por acompanhar Notas Técnicas e versões da biblioteca.

Este texto descreve a organização técnica do sistema. Ele não substitui um contador habilitado nem define a tributação de nenhuma operação real.

Escolha uma venda qualquer feita ontem no seu sistema: alguém no projeto consegue apontar, numa tabela ou documento, quem decidiu qual documento e qual CFOP ela exigia?

Avalie este artigo

Referência: https://acbr.sourceforge.io/drupal/