portal_publico/portal_api/dashboard_contabil/modelos.py

99 lines
2.6 KiB
Python

"""Dataclasses puras (sem ORM) do Dashboard Contábil: o formato intermediário
entre o PDF extraído (`parser.py`) e as regras de auditoria (`regras.py`).
Mesmo padrão de `portal_api.planos_saude.modelos`/`portal_api.indicadores.pipeline`
— quem persiste em model é a view, este módulo só representa dados em memória."""
from __future__ import annotations
from dataclasses import dataclass, field
from datetime import date
from decimal import Decimal
@dataclass
class CabecalhoExtraido:
codigo_empresa: str
nome_empresa: str
cnpj: str
periodo_inicio: date
periodo_fim: date
@dataclass
class LinhaBalanceteExtraida:
conta_numero: int
codigo: str
descricao: str
tipo: str # "S" (sintética) ou "A" (analítica)
saldo_anterior: Decimal
debito: Decimal
credito: Decimal
saldo_atual: Decimal
@dataclass
class LinhaDreExtraida:
ordem: int
descricao: str
nivel: int
valor: Decimal
totalizador: bool
@dataclass
class ValorMensalAnaliseVertical:
valor: Decimal
percentual: Decimal
@dataclass
class LinhaAnaliseVerticalExtraida:
"""Uma linha da seção "Demonstração Mensal (Análise Vertical)" — mesma
descrição/nível/negrito de `LinhaDreExtraida` (é a mesma árvore da DRE),
só que com um valor+percentual por mês em vez de um valor único (ver
`parser.py`)."""
ordem: int
descricao: str
nivel: int
totalizador: bool
valores: list[ValorMensalAnaliseVertical]
@dataclass
class ResultadoExtracao:
cabecalho: CabecalhoExtraido
contas: list[LinhaBalanceteExtraida]
linhas_dre: list[LinhaDreExtraida]
meses_analise_vertical: list[str] = field(default_factory=list)
linhas_analise_vertical: list[LinhaAnaliseVerticalExtraida] = field(default_factory=list)
@dataclass
class AchadoDetectado:
regra: str
severidade: str # "alta" | "media" | "baixa"
titulo: str
mensagem: str
codigo_conta: str | None = None
valor_referencia: Decimal | None = None
@dataclass
class SnapshotHistorico:
"""Retrato mínimo de uma apuração anterior já concluída/em revisão da
mesma empresa — usado pelas regras de variação mês a mês (ver
`regras.py`). `contas`/`linhas_dre` são dicionários já resolvidos
(codigo/descrição → valor) pra não precisar reconsultar o ORM dentro das
regras, que são funções puras."""
competencia: date
contas: dict[str, Decimal] = field(default_factory=dict)
linhas_dre: dict[str, Decimal] = field(default_factory=dict)
@dataclass
class ResultadoProcessamento:
extracao: ResultadoExtracao
achados: list[AchadoDetectado]