diff --git a/portal_api/dashboard_contabil/CHANGELOG.md b/portal_api/dashboard_contabil/CHANGELOG.md index babf275..9a75b6f 100644 --- a/portal_api/dashboard_contabil/CHANGELOG.md +++ b/portal_api/dashboard_contabil/CHANGELOG.md @@ -115,3 +115,19 @@ Novo botão "Calcular com esta apuração" no modal de indicador, entre "Fórmul Usuário reportou o modal de aviso "Chave(s) de indicador não padrão inexistente(s): diferença." ao tentar alternar um indicador no hub "Gerenciar Indicadores". Causa: um indicador não padrão de chave `diferença` tinha sido excluído em algum momento, mas `IndicadorContabilDefinicaoViewSet.perform_destroy()` só bloqueava/limpava referência pela **fórmula** (`indicador_referenciado`), nunca pelas referências em `ContabilApuracao.indicadores_selecionados`/`indicadores_ocultos` — a chave ficou órfã na apuração que a tinha selecionada. Como o frontend sempre reenvia a lista **inteira** a cada alternância de checkbox (`pidDcRenderHubIndicadores`/evento `change` em `dashboard-contabil.js`), e `ContabilIndicadoresSelecionadosSerializer`/`ContabilIndicadoresOcultosSerializer` rejeitavam a lista inteira se qualquer chave nela não existisse mais, o usuário ficava travado sem conseguir alternar **nenhum** indicador na apuração afetada, não só o excluído. Dois ajustes, um pro sintoma já existente e outro pra causa raiz: (a) as duas validações passaram a **descartar silenciosamente** chave inexistente/órfã em vez de rejeitar a lista inteira — é só estado de exibição (quais cards aparecem/estão ocultos), não dado auditado, então autocorrigir é seguro e resolve o travamento já em produção sem precisar de um script de correção manual; (b) `perform_destroy()` agora também limpa a chave excluída de toda `ContabilApuracao` que a referenciava em `indicadores_selecionados`/`indicadores_ocultos`, pra não deixar mais nenhuma referência órfã nova daqui pra frente. + +### 107. Balancete/D.R.E. nascem recolhidos a partir do "grupo 4" + +Pedido: a árvore do Balancete (e, por extensão confirmada com o usuário, da D.R.E.) nascia sempre totalmente expandida, poluindo visualmente uma apuração com muitas contas analíticas. Passou a nascer recolhida a partir do nível equivalente ao "grupo 4" do código de classificação (ex. `1.01.01.001`, 4 segmentos) — essa conta aparece aberta, mas seus filhos (`1.01.01.001.001` em diante) ficam ocultos até o contador clicar pra expandir; o mesmo limiar de nível é aplicado à D.R.E., sobre `ContabilLinhaDre.nivel`. + +Aplicado nos dois lugares que já compartilhavam o mesmo algoritmo de árvore recolhível: a tela de revisão (`dashboard-contabil.js`, `dcColapsoPadrao()` pré-popula `dcContasColapsadas`/`dcDreColapsadas` em `renderRevisao()`, em vez de nascerem como `Set()` vazio) e o relatório "Gerar Dashboard" (`_contabil_arvore_contexto()` em `views.py` ganhou o campo `colapsado_padrao` por item, calculado a partir da nova constante `_CONTABIL_NIVEL_ABERTO_PADRAO = 3`; `dashboard-contabil-relatorio.html` usa esse campo pra não marcar `is-expanded` no botão e `pidDcrArvore()` semeia o estado `colapsadas` a partir do atributo `data-dcr-colapsado-padrao` antes da primeira renderização). A impressão continua forçando toda linha a aparecer (`tr[hidden] { display: table-row !important }` em `@media print`), então o comportamento de "documento impresso nunca esconde conta atrás de um grupo recolhido" não muda. Nenhuma mudança de modelo/migração — é só o estado inicial da mesma árvore que já existia. + +### 108. Fundo uniforme na tabela do Balancete (revisão) + +Pedido: a linha sintética do Balancete (grupo do plano de contas, ex. "1.02.05 IMOBILIZADO") tinha um fundo elevado (`--bg-surface-raised`) além do negrito, criando um efeito de cores alternadas entre linha de grupo e linha analítica — o usuário pediu pra unificar, no mesmo padrão já usado na D.R.E. (que só usa negrito na linha totalizadora, sem fundo diferente). Removida a regra `.dc-conta-row--sintetica td { background: var(--bg-surface-raised); }` em `dashboard-contabil.css`, mantendo só o negrito (`.dc-conta-row--sintetica { font-weight: 600; }`) — a tabela do Balancete passa a ter uma única cor de fundo, igual à D.R.E. + +### 109. Limiar de recolhimento ajustado pra nível 3 + destaque acompanha o grupo expandido + +Pedido: (a) o limiar de recolhimento padrão da rodada 107 ("grupo 4", ex. `1.01.01.001` aberto) ficou permissivo demais — passou a recolher a partir do 3º segmento do código (ex. `1.01.01` aberto, `1.01.01.001` em diante só sob demanda). `PID_DC_NIVEL_ABERTO_PADRAO` (`dashboard-contabil.js`) e `_CONTABIL_NIVEL_ABERTO_PADRAO` (`views.py`, usada pelo relatório "Gerar Dashboard") foram de `3` pra `2` — mesma dupla de constantes já documentada na rodada 107, ajustadas juntas. + +(b) Novo mecanismo de destaque: ao expandir uma conta/linha, só as linhas que acabaram de ficar visíveis (filhos diretos, não os netos — que continuam recolhidos pelo limiar acima) ganham um realce dourado; expandir uma delas em seguida move o realce pra seus filhos e o grupo destacado antes volta à cor padrão, nunca acumulando mais de uma "leva" ao mesmo tempo — ajuda o contador a acompanhar visualmente onde ele acabou de descer na árvore. `dcContasDestaque`/`dcDreDestaque` (`dashboard-contabil.js`, dois `Set()` resetados em `renderRevisao()`) guardam só a leva mais recente; `dcFilhosDiretos()` (função genérica, reaproveitada pelas duas árvores) calcula os filhos diretos de um item a partir da lista plana. Classe nova `.dc-conta-row--destaque` (`dashboard-contabil.css`, fundo `rgba(var(--gold-rgb), .16)`). Só na tela de revisão — o relatório "Gerar Dashboard" não ganhou esse destaque (é uma navegação estática, sem o mesmo conceito de "acabei de expandir isto agora"). Puramente visual/em memória, sem persistência nem mudança de modelo. diff --git a/portal_api/dashboard_contabil/CLAUDE.md b/portal_api/dashboard_contabil/CLAUDE.md index a4a05b3..be3c5d2 100644 --- a/portal_api/dashboard_contabil/CLAUDE.md +++ b/portal_api/dashboard_contabil/CLAUDE.md @@ -65,7 +65,11 @@ Diferente de `IndicadorApuracaoViewSet`/`ImportacaoPlanoSaudeViewSet` (onde a ch `templates/dashboard-contabil.html` (`page-content--wide`) segue o padrão de 3 sub-views de `indicador-desempenho.html`: `#dc-list-view` (histórico + botão "Nova Análise") / `#dc-form-view` (upload de um único PDF — sem campo de competência, é extraído do arquivo) / `#dc-review-view` (abas Achados/Balancete/DRE, via `.pa-tabs`/`.pa-tab-panel` de `perfis-acesso.css`). Achados têm filtro por severidade e por status (pendentes/todos); tratar/ignorar um achado abre um modal próprio (`#dc-achado-modal`) que exige observação não-vazia; observação de conta abre outro modal (`#dc-observacao-modal`), sem essa exigência (pode ficar em branco). Botão "Gerar Dashboard" (`#dc-gerar-dashboard-btn`) chama `pidGerarDashboardContabil()` — ver "Relatório 'Gerar Dashboard'" abaixo. -**Balancete e DRE usam a mesma árvore recolhível** (`dashboard-contabil.js`): o Balancete já construía uma árvore expansível a partir do nível de indentação derivado do código de classificação (`dcContaNivel()`, contando segmentos separados por `.`) — a DRE não tem código de classificação (ver "Extração do PDF" acima), mas já carregava `nivel` pronto do backend (`ContabilLinhaDre.nivel`, derivado do `x0` de cada linha no PDF), então `renderDre()` reaproveita exatamente o mesmo algoritmo de `renderContas()` (pilha de níveis recolhidos, "tem filhos" = a próxima linha tem nível maior) só que sobre `linha.nivel` direto, sem precisar de um `dcContaNivel` equivalente. Reaproveita as mesmas classes CSS do toggle (`.dc-conta-toggle`/`.dc-conta-toggle-spacer`/`.dc-conta-desc-cell`, `dashboard-contabil.css`) — o nome genérico ("conta") já cobre as duas árvores, não precisou de classe nova. Estado de colapso é independente por aba (`dcContasColapsadas`/`dcDreColapsadas`, dois `Set()` reiniciados juntos em `renderRevisao()`). +**Balancete e DRE usam a mesma árvore recolhível** (`dashboard-contabil.js`): o Balancete já construía uma árvore expansível a partir do nível de indentação derivado do código de classificação (`dcContaNivel()`, contando segmentos separados por `.`) — a DRE não tem código de classificação (ver "Extração do PDF" acima), mas já carregava `nivel` pronto do backend (`ContabilLinhaDre.nivel`, derivado do `x0` de cada linha no PDF), então `renderDre()` reaproveita exatamente o mesmo algoritmo de `renderContas()` (pilha de níveis recolhidos, "tem filhos" = a próxima linha tem nível maior) só que sobre `linha.nivel` direto, sem precisar de um `dcContaNivel` equivalente. Reaproveita as mesmas classes CSS do toggle (`.dc-conta-toggle`/`.dc-conta-toggle-spacer`/`.dc-conta-desc-cell`, `dashboard-contabil.css`) — o nome genérico ("conta") já cobre as duas árvores, não precisou de classe nova. Estado de colapso é independente por aba (`dcContasColapsadas`/`dcDreColapsadas`, dois `Set()`). + +**Nasce recolhida a partir do 3º segmento do código** (pedido explícito do usuário, pra reduzir a poluição visual de uma apuração com muitas contas analíticas — limiar ajustado numa rodada seguinte, ver abaixo): em vez de `renderRevisao()` reiniciar os dois `Set()` vazios (tudo expandido), `dcColapsoPadrao(itens, nivelFn)` os pré-popula com os ids de todo item que tem filhos **e** está no nível `PID_DC_NIVEL_ABERTO_PADRAO` (`2`) ou além — ex. a conta `1.01.01` (3 segmentos, nível 2) aparece aberta, mas seus filhos (`1.01.01.001`, nível 3) ficam ocultos até o contador clicar pra expandir; se expandido, um filho de nível 3 que também tenha netos nasce recolhido de novo pelo mesmo critério, então "nível 3 em diante" precisa sempre de um clique a mais, não só a primeira camada. Mesmo limiar aplicado à DRE, sobre `Math.max(0, linha.nivel)` — decisão confirmada com o usuário (a princípio o pedido citava só o Balancete, mas como a DRE reaproveita o mesmo algoritmo, o mesmo comportamento faz sentido nela também). O relatório "Gerar Dashboard" replica esse mesmo estado inicial (ver abaixo) — não é só a tela de revisão. `PID_DC_NIVEL_ABERTO_PADRAO` (JS) e `_CONTABIL_NIVEL_ABERTO_PADRAO` (`views.py`) são a mesma constante conceitual duplicada nos dois lados (um é SPA, o outro HTML renderizado uma vez) — mudar o limiar exige ajustar os dois. + +**Destaque acompanha o último grupo expandido** (pedido explícito do usuário, mesma rodada do ajuste de limiar acima): ao expandir uma conta/linha, as linhas que acabaram de ficar visíveis (só os filhos **diretos**, não os netos — que continuam recolhidos pelo limiar acima) ganham um realce dourado (`.dc-conta-row--destaque`); se o contador expandir uma dessas linhas em seguida, o realce se move pros filhos dela, e o grupo destacado antes volta pra cor padrão — nunca acumula mais de uma "leva" destacada ao mesmo tempo. `dcContasDestaque`/`dcDreDestaque` (dois `Set()`, um por árvore, resetados em `renderRevisao()`) guardam só a leva mais recente; `dcFilhosDiretos(itens, nivelFn, id)` (função genérica, reaproveitada pelas duas árvores) varre a lista plana a partir do índice do item expandido e para no primeiro item de nível igual ou menor (fim do grupo), coletando só os de nível exatamente `pai+1`. O handler de clique do toggle decide o destino do destaque **antes** de checar se a ação foi expandir ou recolher (`estavaColapsada = colapsadas.has(id)` guardado antes de mutar o `Set`): expandir substitui `dcContasDestaque`/`dcDreDestaque` pelos filhos diretos recém-revelados; recolher só limpa (`new Set()`), já que nada novo foi exposto. Puramente visual, sem persistência — reseta a cada apuração aberta, sem afetar nenhum dado gravado. **Card de achado expande a conta usada no apontamento** (`renderAchados()`, pedido explícito do usuário): `achado.conta` (id, já vem no payload de `/api/contabil-apuracoes/{id}/`, junto de `conta_codigo`/`conta_descricao`) é resolvido pra objeto completo procurando em `apuracaoAtual.contas` (`.find((c) => c.id === achado.conta)`) — sem chamada de API extra, já que a apuração inteira (contas + linhas de DRE + achados) já vem de uma vez só nesse endpoint. Só achados vinculados a uma conta específica ganham o botão "Ver conta usada no apontamento" (`.dc-achado-card__toggle-conta`) — as duas regras gerais (`balanceamento_ativo_passivo`/`debito_credito_divergente`, `conta` nulo no model) não têm uma conta única por trás, então não mostram o toggle. Expandido, mostra código/descrição/saldo anterior/débito/crédito/saldo atual da conta (`.dc-achado-card__conta`, um `