# Relatório Contábil (Relatórios > Contabilidade)
> Este arquivo é carregado automaticamente ao trabalhar dentro de `portal_api/dashboard_contabil/`. Ver `CLAUDE.md` na raiz para arquitetura geral/transversal do Portal (modelo de permissões, API, CSS, etc.).
>
> **Este arquivo descreve o estado atual, não o histórico.** Nenhuma seção aqui é datada por rodada e nenhuma narra "antes era X, agora é Y" — quando o motivo de uma decisão importa para não a reverter por engano, ele aparece como motivo, não como cronologia. O histórico rodada a rodada (92 a 148) está em `CHANGELOG.md` nesta mesma pasta. Ao implementar algo novo aqui, atualizar **os dois**: o estado atual neste arquivo, a mudança no changelog.
**Nome**: "Relatório Contábil" é o rótulo visível ao usuário; internamente tudo continua `dashboard_contabil`/`dashboard-contabil.*`/`Contabil*`/`/api/contabil-*`/`apps["dashboard-contabil"]`. O rename foi só de texto visível (menu em `catalogo.py`, `
`/``/cabeçalhos dos dois templates, o botão "Gerar Relatório" e os `verbose_name` do admin) — pedido explícito do usuário, para a ferramenta soar como um aliado do trabalho do contador em vez de mais um sistema. **Não propagar esse rename para dentro do código.**
Ferramenta que otimiza a conferência de balancetes hoje feita manualmente pelo Fisco/Contábil (processo descrito em `ITD-FISCO-7513`, "Roteiro de Conferência de Balancete"): o contador anexa o PDF de Balancete + DRE de uma empresa (mesmo relatório já enviado ao cliente, gerado pelo **Questor** ou pelo **Contabit**, ver "Leiaute Contabit" abaixo), a ferramenta extrai as contas/linhas, roda um motor de regras de auditoria e apresenta os apontamentos numa tela de revisão, onde o contador analisa, registra observações e conclui a análise. No fim, gera um relatório HTML autocontido para o cliente.
**Permissão**: toggle único `apps["dashboard-contabil"]` em `permissoes["relatorios"]` (subgrupo "Contabilidade"), checado via `PermissaoApp("relatorios", "dashboard-contabil")` em todos os ViewSets. **Nasce restrita ao perfil "Inovação"** (override em `seed_portal.py`), já que expõe balancete/DRE completos dos clientes.
## Relatório Contábil - De Paula (segunda instância, seção Diretoria)
Existe uma **segunda aplicação**, `dashboard-contabil-de-paula` ("Relatório Contábil - De Paula"), na seção nova **Diretoria** do menu (entre Relatórios e Relatórios Gerenciais). É a mesma ferramenta, para as **empresas do próprio escritório**. Mesmo modelo de "Importação de Plano de Saúde - De Paula" (`portal_api/planos_saude/CLAUDE.md`): regras compartilhadas, dados e permissão separados.
**Requisito do usuário, que orienta tudo abaixo: quem tem acesso só ao Relatório Contábil não pode, em hipótese alguma, acessar o da De Paula.** São três camadas independentes, cada uma suficiente sozinha:
1. **Tabelas próprias.** Cada model tem uma versão `DePaula` (`ContabilApuracaoDePaula`, `ContabilContaDePaula`, `ContabilLinhaDreDePaula`, `ContabilLinhaAnaliseVerticalDePaula`, `ContabilAchadoDePaula`, `ContabilObservacaoDePaula`, `ContabilObservacaoEdicaoDePaula`, `ContabilApuracaoReprocessamentoDePaula`, migração `0090`), sem nenhuma FK cruzando com as originais. O histórico mês a mês e as observações por empresa + conta também ficam separados: a mesma empresa analisada nas duas aplicações tem dois históricos independentes.
2. **Endpoints próprios**, os mesmos da tabela "API" abaixo com sufixo `-de-paula` (`/api/contabil-apuracoes-de-paula/`, `/api/contabil-contas-de-paula/`, `/api/contabil-linhas-dre-de-paula/`, `/api/contabil-linhas-analise-vertical-de-paula/`, `/api/contabil-observacoes-de-paula/`, `/api/contabil-achados-de-paula/`). Cada queryset só enxerga as tabelas da De Paula, então um id da original devolve 404 ali. Os `PrimaryKeyRelatedField` de apuração dos serializers de observação (`ContabilObservacaoCreateDePaulaSerializer`/`ContabilObservacaoApuracaoDePaulaSerializer`) também usam o queryset da De Paula: apontar uma observação para uma apuração da original devolve 400.
3. **Permissão própria**: `PermissaoApp("diretoria", "dashboard-contabil-de-paula")` (`_CONTABIL_DE_PAULA_PERMISSAO` em `views.py`). Ter `relatorios > dashboard-contabil` não dá acesso, e o inverso também vale.
**Nasce fechada para todos.** O módulo `diretoria` está fora de `BASE_KEYS`/`SECTORAL_KEYS`, e nenhum perfil já gravado em produção tem a chave, que `permissoes_efetivas()` trata como desabilitada. A liberação é sempre manual pela tela de Perfis de Acesso. `seed_portal.py` força `False` em todo perfil que não seja o 8 (só vale para ambiente novo, o seed não roda em produção).
**O que é compartilhado** (nada disso foi copiado):
- todo este pacote (parsers, regras, fórmula, chaves, exportação, PDF do Resumo);
- o **cadastro de indicadores** (`IndicadorContabilDefinicao`, `/api/contabil-indicadores-definicoes/`), decisão explícita do usuário: quem tem qualquer uma das duas permissões gerencia os mesmos indicadores (`OR` das duas `PermissaoApp` em `IndicadorContabilDefinicaoViewSet`), e editar um indicador numa aplicação reflete na outra. Ao excluir um indicador, a limpeza de `indicadores_selecionados`/`indicadores_ocultos` varre as apurações das duas;
- as views, os serializers e o frontend, **parametrizados** (abaixo);
- o template do relatório do cliente (`dashboard-contabil-relatorio.html`), com os links de XLSX/PDF montados a partir de `prefixo_api` no contexto.
**Como a parametrização funciona** (diferente do Plano de Saúde, que duplicou as views: aqui são cerca de 1.000 linhas e duas cópias divergiriam):
- **Models**: cada um é uma base abstrata (`ContabilApuracaoBase`, `ContabilContaBase`, ...) com campos, constantes e métodos, mais duas concretas. As FKs ficam só nas concretas, porque cada variante aponta para os próprios models. Os `related_name` das FKs para a apuração são os mesmos nas duas (`contas`, `linhas_dre`, `linhas_analise_vertical`, `achados`, `observacoes`, `reprocessamentos`); os de `Usuario` têm sufixo `_de_paula`.
- **Views**: os ViewSets originais têm atributos de classe (`permissao_app`, `queryset`, serializers, `prefixo_api`), e os `*DePaulaViewSet` são subclasses que só trocam esses atributos. Os helpers descobrem o model pela própria apuração: `apuracao.contas.create(...)`, `apuracao.achados.model`, `_contabil_modelo_observacao(apuracao)` (= `apuracao.observacoes.model`), `type(apuracao)` para o histórico. `_contabil_monta_historico(modelo_apuracao, cabecalho)` recebe o model fixado por `functools.partial`, porque o pipeline o chama só com o cabeçalho.
- **Frontend**: `dashboard-contabil.js` lê `PID_DC_CONFIG` (`moduleKey`, `appKey` e os 6 prefixos de endpoint); `dashboard-contabil-de-paula.html` define `window.PID_DC_CONFIG` num `