Files
roa2web-service-auto/backend/modules/reports/models/financial_indicators.py
Claude Agent dd4b90f922 feat(financial-indicators): Complete Financial Indicators Dashboard Card
Implementare completă a card-ului Indicatori Financiari în Dashboard Solduri:

Backend:
- Model FinancialIndicators cu 22+ indicatori organizați pe categorii
- Service cu calcule din VBAL (Lichiditate, Eficiență, Risc, Cash Flow, Dinamică)
- Altman Z-Score cu toate componentele (X1-X4) și valori absolute
- Profitabilitate cu ROA, ROE, Cifra Afaceri, Cheltuieli separate (operaționale/financiare)
- Caching inteligent pe company_id, luna, an

Frontend:
- FinancialIndicatorsCard.vue cu 4 indicatori principali collapsed
- Expanded view grupat pe categorii (desktop + mobile BottomSheet)
- Subindicatori pentru verificare manuală în balanță
- Traduceri complete în română
- Dark mode support complet
- Sparklines cu tooltips
- Responsive design (desktop grid + mobile carousel)

Documentație:
- PRD complet cu specificații și formule
- Descrieri cu conturi din planul contabil român (OMFP 1802/2014)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 17:32:48 +00:00

874 lines
34 KiB
Python

"""
Pydantic models pentru indicatori financiari.
Definește structurile de date pentru:
- BalanceSheetAggregates: Solduri agregate din balanța de verificare
- IndicatorResult: Rezultatul standardizat cu sparkline data pentru vizualizare trend
- Modele pentru indicatori de lichiditate, eficiență, risc și Altman Z-Score
"""
from decimal import Decimal
from typing import Optional, List
from pydantic import BaseModel, Field
class BalanceSheetAggregates(BaseModel):
"""
Solduri agregate din balanța de verificare (VBAL) pe categorii de conturi.
Agregă datele din VBAL folosind prefixe de conturi conform Planului de
Conturi General (PCG) românesc pentru calculul indicatorilor financiari.
Attributes:
company_id: ID-ul firmei
luna: Luna contabilă (1-12)
an: Anul contabil
active_imobilizate: Active imobilizate nete (brut - amortizări - ajustări)
stocuri: Valoarea stocurilor (brut - ajustări depreciere)
creante: Creanțe nete (brut - ajustări depreciere)
disponibilitati: Disponibilități bănești (bancă + casă)
capital_propriu: Capital social + prime + rezerve
rezultat: Rezultat reportat + rezultatul exercițiului curent
datorii_termen_lung: Datorii cu scadență > 1 an
datorii_curente: Datorii cu scadență <= 1 an
venituri: Venituri din exploatare (pentru calcul EBIT)
cheltuieli_operationale: Cheltuieli de exploatare (pentru calcul EBIT)
"""
company_id: int = Field(description="ID-ul firmei")
luna: int = Field(ge=1, le=12, description="Luna contabilă (1-12)")
an: int = Field(ge=2000, le=2100, description="Anul contabil")
# Active
active_imobilizate: Decimal = Field(
default=Decimal('0'),
description="Active imobilizate nete (Clasa 2 - amortizări)"
)
stocuri: Decimal = Field(
default=Decimal('0'),
description="Stocuri (Clasa 3 - ajustări depreciere)"
)
creante: Decimal = Field(
default=Decimal('0'),
description="Creanțe comerciale și alte creanțe (4111, 461, etc.)"
)
disponibilitati: Decimal = Field(
default=Decimal('0'),
description="Disponibilități (bancă 512x + casă 531x)"
)
# Pasive - Capitaluri
capital_propriu: Decimal = Field(
default=Decimal('0'),
description="Capital social + prime + rezerve (101, 104, 105, 106)"
)
rezultat: Decimal = Field(
default=Decimal('0'),
description="Rezultat reportat + rezultat curent (107, 117, 121)"
)
# Pasive - Datorii
datorii_termen_lung: Decimal = Field(
default=Decimal('0'),
description="Datorii pe termen lung (Clasa 16)"
)
datorii_curente: Decimal = Field(
default=Decimal('0'),
description="Datorii curente (401, 421, 4423, 462, etc.)"
)
# Venituri și Cheltuieli (pentru calcul EBIT în Altman Z-Score)
venituri: Decimal = Field(
default=Decimal('0'),
description="Venituri din exploatare (Clasa 7)"
)
cheltuieli_operationale: Decimal = Field(
default=Decimal('0'),
description="Cheltuieli operaționale (Clasa 6 fără 66x)"
)
cheltuieli_financiare: Decimal = Field(
default=Decimal('0'),
description="Cheltuieli financiare (Clasa 66 - dobânzi, diferențe curs)"
)
# Computed properties pentru calculele ulterioare
@property
def active_curente(self) -> Decimal:
"""Active curente = stocuri + creanțe + disponibilități"""
return self.stocuri + self.creante + self.disponibilitati
@property
def total_active(self) -> Decimal:
"""Total active = active imobilizate + active curente"""
return self.active_imobilizate + self.active_curente
@property
def total_datorii(self) -> Decimal:
"""Total datorii = datorii termen lung + datorii curente"""
return self.datorii_termen_lung + self.datorii_curente
@property
def capitaluri_proprii(self) -> Decimal:
"""Capitaluri proprii = capital propriu + rezultat"""
return self.capital_propriu + self.rezultat
@property
def ebit(self) -> Decimal:
"""EBIT (Earnings Before Interest and Taxes) = venituri - cheltuieli operaționale"""
return self.venituri - self.cheltuieli_operationale
@property
def working_capital(self) -> Decimal:
"""Working capital (fond de rulment) = active curente - datorii curente"""
return self.active_curente - self.datorii_curente
class Config:
"""Configurare Pydantic"""
from_attributes = True
json_schema_extra = {
"example": {
"company_id": 123,
"luna": 12,
"an": 2024,
"active_imobilizate": 1500000.00,
"stocuri": 350000.00,
"creante": 420000.00,
"disponibilitati": 180000.00,
"capital_propriu": 800000.00,
"rezultat": 250000.00,
"datorii_termen_lung": 500000.00,
"datorii_curente": 400000.00,
"venituri": 2500000.00,
"cheltuieli_operationale": 2100000.00
}
}
class IndicatorResult(BaseModel):
"""
Rezultatul standardizat pentru un indicator financiar.
Fiecare indicator returnează valoarea calculată împreună cu
statusul (good/warning/danger), pragurile de referință și
date pentru sparkline (evoluția pe ultimele 12 luni).
Attributes:
value: Valoarea calculată a indicatorului (None dacă nu se poate calcula)
status: Statusul indicatorului - 'good', 'warning', sau 'danger'
threshold_min: Pragul minim pentru status 'good'
threshold_max: Pragul maxim pentru status 'good' (opțional)
message: Mesaj explicativ (opțional, pentru cazuri speciale)
sparkline_data: Array cu valorile indicatorului pe ultimele 12 luni (pentru vizualizare trend)
sparkline_labels: Array cu etichetele lunilor în format 'MMM YY' (ex: 'Feb 24', 'Mar 24')
"""
value: Optional[float] = Field(
default=None,
description="Valoarea calculată a indicatorului"
)
status: str = Field(
default="warning",
description="Statusul: 'good', 'warning', sau 'danger'"
)
threshold_min: Optional[float] = Field(
default=None,
description="Pragul minim pentru status 'good'"
)
threshold_max: Optional[float] = Field(
default=None,
description="Pragul maxim pentru status 'good'"
)
message: Optional[str] = Field(
default=None,
description="Mesaj explicativ pentru cazuri speciale"
)
sparkline_data: Optional[List[Optional[float]]] = Field(
default=None,
description="Array cu valorile indicatorului pe ultimele 12 luni (pentru sparkline)"
)
sparkline_labels: Optional[List[str]] = Field(
default=None,
description="Array cu etichetele lunilor în format 'MMM YY' (ex: 'Feb 24', 'Mar 24')"
)
class Config:
json_schema_extra = {
"example": {
"value": 1.25,
"status": "good",
"threshold_min": 1.0,
"threshold_max": None,
"message": None,
"sparkline_data": [1.15, 1.18, 1.20, 1.22, 1.19, 1.21, 1.23, 1.25, 1.24, 1.26, 1.25, 1.25],
"sparkline_labels": ["Feb 24", "Mar 24", "Apr 24", "May 24", "Jun 24", "Jul 24", "Aug 24", "Sep 24", "Oct 24", "Nov 24", "Dec 24", "Jan 25"]
}
}
class LiquidityIndicators(BaseModel):
"""
Indicatori de lichiditate pentru evaluarea capacității de plată
a datoriilor pe termen scurt.
Attributes:
lichiditate_curenta: Current Ratio = active_curente / datorii_curente
- Măsoară capacitatea de a plăti datoriile pe termen scurt cu active curente
- Good: >= 2.0, Warning: 1.0-2.0, Danger: < 1.0
lichiditate_imediata: Quick Ratio = (disponibilități + creanțe) / datorii_curente
- Măsoară capacitatea de plată fără a depinde de vânzarea stocurilor
- Good: >= 1.0, Warning: 0.5-1.0, Danger: < 0.5
lichiditate_vedere: Cash Ratio = disponibilități / datorii_curente
- Măsoară capacitatea de plată imediată doar din numerar
- Good: >= 0.2, Warning: 0.1-0.2, Danger: < 0.1
"""
lichiditate_curenta: IndicatorResult = Field(
description="Current Ratio = active_curente / datorii_curente"
)
lichiditate_imediata: IndicatorResult = Field(
description="Quick Ratio = (disponibilități + creanțe) / datorii_curente"
)
lichiditate_vedere: IndicatorResult = Field(
description="Cash Ratio = disponibilități / datorii_curente"
)
class Config:
json_schema_extra = {
"example": {
"lichiditate_curenta": {
"value": 2.37,
"status": "good",
"threshold_min": 2.0,
"threshold_max": None
},
"lichiditate_imediata": {
"value": 1.50,
"status": "good",
"threshold_min": 1.0,
"threshold_max": None
},
"lichiditate_vedere": {
"value": 0.45,
"status": "good",
"threshold_min": 0.2,
"threshold_max": None
}
}
}
class EfficiencyIndicators(BaseModel):
"""
Indicatori de eficiență pentru evaluarea vitezei de conversie
a resurselor în numerar (working capital efficiency).
Attributes:
dso: Days Sales Outstanding (Durata medie de încasare)
- Formula: (clienti_sold / facturari_lunare) * 30
- Măsoară câte zile durează în medie încasarea creanțelor
- Good: < 30 zile, Warning: 30-45 zile, Danger: > 45 zile
dpo: Days Payables Outstanding (Durata medie de plată)
- Formula: (furnizori_sold / achizitii_lunare) * 30
- Măsoară câte zile durează în medie plata furnizorilor
- Valoare mai mare = folosim mai mult creditul furnizorilor
cash_conversion_cycle: Ciclu de conversie a numerarului
- Formula: DSO - DPO
- Pozitiv = numerar blocat în ciclul de afaceri
- Negativ = folosim creditul furnizorilor (favorabil)
rata_incasare: Rata de încasare (Collection Rate)
- Formula: incasari / facturari * 100
- Măsoară ce procent din facturări s-a încasat
- Good: >= 95%, Warning: 80-95%, Danger: < 80%
rata_plata: Rata de plată (Payment Rate)
- Formula: plati / achizitii * 100
- Măsoară ce procent din achiziții s-a achitat
"""
dso: IndicatorResult = Field(
description="Days Sales Outstanding = (clienti_sold / facturari_lunare) * 30"
)
dpo: IndicatorResult = Field(
description="Days Payables Outstanding = (furnizori_sold / achizitii_lunare) * 30"
)
cash_conversion_cycle: IndicatorResult = Field(
description="Cash Conversion Cycle = DSO - DPO"
)
rata_incasare: IndicatorResult = Field(
description="Rata de încasare = incasari / facturari * 100"
)
rata_plata: IndicatorResult = Field(
description="Rata de plată = plati / achizitii * 100"
)
class Config:
json_schema_extra = {
"example": {
"dso": {
"value": 28.5,
"status": "good",
"threshold_min": None,
"threshold_max": 30
},
"dpo": {
"value": 35.2,
"status": "good",
"threshold_min": None,
"threshold_max": None,
"message": "Folosim bine creditul furnizorilor"
},
"cash_conversion_cycle": {
"value": -6.7,
"status": "good",
"threshold_min": None,
"threshold_max": 0,
"message": "Ciclu negativ = finanțare gratuită de la furnizori"
},
"rata_incasare": {
"value": 92.5,
"status": "warning",
"threshold_min": 95,
"threshold_max": None
},
"rata_plata": {
"value": 88.3,
"status": "good",
"threshold_min": None,
"threshold_max": None
}
}
}
class RiskIndicators(BaseModel):
"""
Indicatori de risc și aging pentru evaluarea sănătății
portofoliului de creanțe și datorii.
Attributes:
creante_restante_pct: Procentul creanțelor restante din total clienți
- Formula: clienti_sold_restant / clienti_sold_total * 100
- Măsoară ce procent din creanțe sunt depășite ca termen
- Good: < 20%, Warning: 20-30%, Danger: > 30%
creante_90plus_pct: Procentul creanțelor restante > 90 zile din total
- Formula: clienti_restant_90plus / clienti_sold_total * 100
- Indică creanțele cu risc mare de nerecuperare
- Good: < 5%, Warning: 5-10%, Danger: > 10%
datorii_restante_pct: Procentul datoriilor restante din total furnizori
- Formula: furnizori_sold_restant / furnizori_sold_total * 100
- Măsoară nivelul de întârzieri la plată
- Good: < 10%, Warning: 10-20%, Danger: > 20%
raport_datorii_trezorerie: Raportul între datorii furnizori și trezorerie
- Formula: furnizori_sold_total / trezorerie
- Indică câte luni de cash sunt necesare pentru a plăti furnizorii
- Good: < 2, Warning: 2-4, Danger: > 4
"""
creante_restante_pct: IndicatorResult = Field(
description="Procentul creanțelor restante = clienti_sold_restant / clienti_sold_total * 100"
)
creante_90plus_pct: IndicatorResult = Field(
description="Procentul creanțelor > 90 zile = clienti_restant_90plus / clienti_sold_total * 100"
)
datorii_restante_pct: IndicatorResult = Field(
description="Procentul datoriilor restante = furnizori_sold_restant / furnizori_sold_total * 100"
)
raport_datorii_trezorerie: IndicatorResult = Field(
description="Raport datorii/trezorerie = furnizori_sold_total / trezorerie"
)
class Config:
json_schema_extra = {
"example": {
"creante_restante_pct": {
"value": 15.5,
"status": "good",
"threshold_min": None,
"threshold_max": 20
},
"creante_90plus_pct": {
"value": 3.2,
"status": "good",
"threshold_min": None,
"threshold_max": 5
},
"datorii_restante_pct": {
"value": 8.5,
"status": "good",
"threshold_min": None,
"threshold_max": 10
},
"raport_datorii_trezorerie": {
"value": 1.8,
"status": "good",
"threshold_min": None,
"threshold_max": 2,
"message": "Trezorerie suficientă pentru acoperirea datoriilor"
}
}
}
class CashFlowIndicators(BaseModel):
"""
Indicatori de cash flow pentru evaluarea generării și consumului de numerar.
Attributes:
flux_net_lunar: Fluxul net de numerar lunar (încasări - plăți)
- Formula: incasari_luna - plati_luna
- Pozitiv = firma generează numerar, Negativ = firma consumă numerar
- Good: > 0, Danger: < 0
cash_flow_ytd: Fluxul de numerar cumulat de la începutul anului (Year-To-Date)
- Formula: suma fluxurilor nete de la ianuarie până la luna curentă
- Arată tendința generală a anului în curs
flux_net_yoy_pct: Variația procentuală YoY (Year-over-Year)
- Formula: (cf_curent - cf_anterior) / abs(cf_anterior) * 100
- Compară cash flow-ul curent cu aceeași perioadă din anul anterior
acoperire_cash_flow: Rata de acoperire a datoriilor restante
- Formula: cash_flow_ytd / datorii_restante
- Arată de câte ori cash flow-ul YTD poate acoperi datoriile restante
- Good: > 1 (cash flow suficient), Danger: < 0.5
"""
flux_net_lunar: IndicatorResult = Field(
description="Flux net lunar = incasari_luna - plati_luna"
)
cash_flow_ytd: IndicatorResult = Field(
description="Cash flow cumulat YTD = suma fluxurilor de la ianuarie"
)
flux_net_yoy_pct: IndicatorResult = Field(
description="Variația YoY = (cf_curent - cf_anterior) / abs(cf_anterior) * 100"
)
acoperire_cash_flow: IndicatorResult = Field(
description="Acoperire datorii = cash_flow_ytd / datorii_restante"
)
class Config:
json_schema_extra = {
"example": {
"flux_net_lunar": {
"value": 125000.50,
"status": "good",
"threshold_min": 0,
"threshold_max": None,
"message": "Firma generează numerar"
},
"cash_flow_ytd": {
"value": 850000.00,
"status": "good",
"threshold_min": 0,
"threshold_max": None
},
"flux_net_yoy_pct": {
"value": 15.5,
"status": "good",
"threshold_min": 0,
"threshold_max": None,
"message": "Creștere cash flow față de anul anterior"
},
"acoperire_cash_flow": {
"value": 2.5,
"status": "good",
"threshold_min": 1.0,
"threshold_max": None,
"message": "Cash flow suficient pentru acoperirea datoriilor"
}
}
}
class DynamicsIndicators(BaseModel):
"""
Indicatori de dinamică pentru evaluarea evoluției vânzărilor și achizițiilor.
Arată dacă afacerea crește sau scade prin comparație YoY (Year-over-Year).
Attributes:
crestere_vanzari_yoy: Creșterea procentuală a vânzărilor față de anul anterior
- Formula: (facturari_curent - facturari_anterior) / facturari_anterior * 100
- Măsoară dinamica vânzărilor - creștere sau scădere
- Good: > 5%, Warning: 0-5%, Danger: < 0%
crestere_achizitii_yoy: Creșterea procentuală a achizițiilor față de anul anterior
- Formula: (achizitii_curent - achizitii_anterior) / achizitii_anterior * 100
- Creșterea achizițiilor poate indica expansiune sau costuri mai mari
marja_implicita: Marja implicită din diferența facturări - achiziții
- Formula: (facturari - achizitii) / facturari * 100
- Arată ce procent din vânzări rămâne după achiziții
- Good: > 20%, Warning: 10-20%, Danger: < 10%
"""
crestere_vanzari_yoy: IndicatorResult = Field(
description="Creștere vânzări YoY = (facturari_curent - facturari_anterior) / facturari_anterior * 100"
)
crestere_achizitii_yoy: IndicatorResult = Field(
description="Creștere achiziții YoY = (achizitii_curent - achizitii_anterior) / achizitii_anterior * 100"
)
marja_implicita: IndicatorResult = Field(
description="Marja implicită = (facturari - achizitii) / facturari * 100"
)
class Config:
json_schema_extra = {
"example": {
"crestere_vanzari_yoy": {
"value": 12.5,
"status": "good",
"threshold_min": 5.0,
"threshold_max": None,
"message": "Creștere semnificativă a vânzărilor"
},
"crestere_achizitii_yoy": {
"value": 8.3,
"status": "good",
"threshold_min": None,
"threshold_max": None,
"message": "Achiziții în creștere"
},
"marja_implicita": {
"value": 25.5,
"status": "good",
"threshold_min": 20.0,
"threshold_max": None,
"message": "Marjă implicită sănătoasă"
}
}
}
class AltmanZScore(BaseModel):
"""
Altman Z-Score pentru evaluarea riscului de faliment.
Folosim formula modificată pentru companii private (Z'-Score):
Z' = 6.56*X1 + 3.26*X2 + 6.72*X3 + 1.05*X4
Coeficienții sunt specifici pentru companii care nu sunt listate la bursă,
unde se folosește valoarea contabilă a capitalurilor proprii în loc de
valoarea de piață a acțiunilor.
Componente:
X1: Working Capital / Total Assets
- Măsoară lichiditatea pe termen scurt
- Working capital = active curente - datorii curente
X2: Retained Earnings / Total Assets
- Măsoară profitabilitatea cumulată (rezultat reportat)
- Include conturile 117 și 121 (rezultat reportat + rezultat curent)
X3: EBIT / Total Assets
- Măsoară eficiența operațională
- EBIT = venituri din exploatare - cheltuieli operaționale
X4: Book Value of Equity / Total Liabilities
- Măsoară solvabilitatea (acoperirea datoriilor cu capital propriu)
- Capital propriu / (datorii curente + datorii termen lung)
Zone de risc:
- Safe Zone (zscore > 2.60): Risc minim de faliment
- Grey Zone (1.10 <= zscore <= 2.60): Risc moderat, necesită atenție
- Distress Zone (zscore < 1.10): Risc ridicat de faliment
Attributes:
zscore: Scorul Altman Z calculat
status: Zona de risc ('safe', 'grey', sau 'distress')
x1: Componenta X1 (Working Capital / Total Assets)
x2: Componenta X2 (Retained Earnings / Total Assets)
x3: Componenta X3 (EBIT / Total Assets)
x4: Componenta X4 (Equity / Total Liabilities)
working_capital: Fondul de rulment (active curente - datorii curente)
total_assets: Total active
"""
zscore: IndicatorResult = Field(
description="Scorul Altman Z = 6.56*X1 + 3.26*X2 + 6.72*X3 + 1.05*X4"
)
x1: IndicatorResult = Field(
description="X1 = Working Capital / Total Assets (lichiditate)"
)
x2: IndicatorResult = Field(
description="X2 = Retained Earnings / Total Assets (profitabilitate)"
)
x3: IndicatorResult = Field(
description="X3 = EBIT / Total Assets (eficiență operațională)"
)
x4: IndicatorResult = Field(
description="X4 = Capitaluri Proprii / Datorii Totale (solvabilitate)"
)
# Valori absolute pentru verificare manuală în balanță
capital_de_lucru: IndicatorResult = Field(
description="Capital de lucru = Active Curente - Datorii Curente"
)
active_totale: IndicatorResult = Field(
description="Active Totale = Active Imobilizate + Active Curente"
)
datorii_totale: IndicatorResult = Field(
description="Datorii Totale = Datorii Curente + Datorii Termen Lung"
)
class Config:
json_schema_extra = {
"example": {
"zscore": {
"value": 3.25,
"status": "safe",
"threshold_min": 2.60,
"threshold_max": None,
"message": "Zona sigură - risc minim de faliment"
},
"x1": {
"value": 0.25,
"status": "good",
"threshold_min": 0,
"threshold_max": None
},
"x2": {
"value": 0.15,
"status": "good",
"threshold_min": 0,
"threshold_max": None
},
"x3": {
"value": 0.12,
"status": "good",
"threshold_min": 0,
"threshold_max": None
},
"x4": {
"value": 1.80,
"status": "good",
"threshold_min": 1.0,
"threshold_max": None
},
"capital_de_lucru": {
"value": 450000.00,
"status": "good",
"message": "Active Curente - Datorii Curente"
},
"active_totale": {
"value": 1800000.00,
"status": "good",
"message": "Active Imobilizate + Active Curente"
},
"datorii_totale": {
"value": 1200000.00,
"status": "good",
"message": "Datorii Curente + Datorii Termen Lung"
}
}
}
class ProfitabilityIndicators(BaseModel):
"""
Indicatori de profitabilitate pentru evaluarea randamentului afacerii.
Calculează indicatori cheie pentru evaluarea profitabilității pe baza
datelor din balanța de verificare (VBAL): venituri, cheltuieli, active, capital.
Attributes:
cifra_afaceri: Total venituri din activitatea operațională (Clasa 7)
- Reprezintă volumul total al vânzărilor
- Sursa: suma conturilor 70x-75x din VBAL
cheltuieli_totale: Total cheltuieli operaționale (Clasa 6)
- Reprezintă costurile activității
- Sursa: suma conturilor 60x-65x din VBAL
profit_brut: Diferența dintre venituri și cheltuieli (EBIT)
- Formula: cifra_afaceri - cheltuieli_totale
- Good: > 0, Danger: < 0
marja_profit_brut: Procentul de profit din vânzări
- Formula: profit_brut / cifra_afaceri * 100
- Good: > 10%, Warning: 5-10%, Danger: < 5%
roa: Return on Assets - randamentul activelor
- Formula: profit_brut / total_active * 100
- Măsoară eficiența utilizării activelor
- Good: > 5%, Warning: 2-5%, Danger: < 2%
roe: Return on Equity - randamentul capitalului propriu
- Formula: profit_brut / capitaluri_proprii * 100
- Măsoară randamentul pentru acționari
- Good: > 10%, Warning: 5-10%, Danger: < 5%
"""
cifra_afaceri: IndicatorResult = Field(
description="Cifra de afaceri = Total venituri operaționale (Clasa 7)"
)
# Cheltuieli separate pentru verificare
cheltuieli_operationale: IndicatorResult = Field(
description="Cheltuieli operaționale = Clasa 60x-65x + 68x (fără dobânzi 66x)"
)
cheltuieli_financiare: IndicatorResult = Field(
description="Cheltuieli financiare = Clasa 66x (dobânzi, diferențe curs valutar)"
)
cheltuieli_totale: IndicatorResult = Field(
description="Cheltuieli totale = Operaționale + Financiare"
)
profit_brut: IndicatorResult = Field(
description="Profit brut (EBIT) = Venituri - Cheltuieli operaționale"
)
marja_profit_brut: IndicatorResult = Field(
description="Marja de profit = Profit brut / Cifra afaceri * 100"
)
# Indicatori de bază pentru verificare ROA/ROE
active_totale: IndicatorResult = Field(
description="Active Totale - bază calcul ROA"
)
capitaluri_proprii: IndicatorResult = Field(
description="Capitaluri Proprii - bază calcul ROE"
)
roa: IndicatorResult = Field(
description="Randament Active (ROA) = Profit / Active Totale * 100"
)
roe: IndicatorResult = Field(
description="Randament Capitaluri (ROE) = Profit / Capital Propriu * 100"
)
class Config:
json_schema_extra = {
"example": {
"cifra_afaceri": {
"value": 2500000.00,
"status": "good",
"threshold_min": None,
"threshold_max": None
},
"cheltuieli_totale": {
"value": 2100000.00,
"status": "good",
"threshold_min": None,
"threshold_max": None
},
"profit_brut": {
"value": 400000.00,
"status": "good",
"threshold_min": 0,
"threshold_max": None,
"message": "Profit operațional pozitiv"
},
"marja_profit_brut": {
"value": 16.0,
"status": "good",
"threshold_min": 10.0,
"threshold_max": None
},
"roa": {
"value": 8.5,
"status": "good",
"threshold_min": 5.0,
"threshold_max": None,
"message": "Randament bun al activelor"
},
"roe": {
"value": 15.2,
"status": "good",
"threshold_min": 10.0,
"threshold_max": None,
"message": "Randament atractiv pentru acționari"
}
}
}
class FinancialIndicatorsResponse(BaseModel):
"""
Răspunsul complet al endpoint-ului /api/reports/dashboard/financial-indicators.
Agregă toți indicatorii financiari calculați pentru o firmă și perioadă dată.
Acest model este folosit pentru serializarea JSON a răspunsului API.
Attributes:
lichiditate: Indicatori de lichiditate (Current Ratio, Quick Ratio, Cash Ratio)
eficienta: Indicatori de eficiență (DSO, DPO, CCC, rate încasare/plată)
risc: Indicatori de risc (creanțe/datorii restante, raport datorii/trezorerie)
cash_flow: Indicatori de cash flow (flux net lunar, YTD, YoY, acoperire)
dinamica: Indicatori de dinamică (creștere vânzări/achiziții YoY, marjă)
altman_zscore: Scorul Altman Z-Score și componentele X1-X4
profitabilitate: Indicatori de profitabilitate (ROA, ROE, marjă profit)
Usage:
GET /api/reports/dashboard/financial-indicators?company=123&luna=12&an=2024
Response example:
{
"lichiditate": { ... },
"eficienta": { ... },
"risc": { ... },
"cash_flow": { ... },
"dinamica": { ... },
"altman_zscore": { ... },
"profitabilitate": { ... }
}
"""
lichiditate: LiquidityIndicators = Field(
description="Indicatori de lichiditate: Current Ratio, Quick Ratio, Cash Ratio"
)
eficienta: EfficiencyIndicators = Field(
description="Indicatori de eficiență: DSO, DPO, CCC, rate încasare/plată"
)
risc: RiskIndicators = Field(
description="Indicatori de risc: creanțe/datorii restante, raport datorii/trezorerie"
)
cash_flow: CashFlowIndicators = Field(
description="Indicatori de cash flow: flux net lunar, YTD, YoY, acoperire"
)
dinamica: DynamicsIndicators = Field(
description="Indicatori de dinamică: creștere vânzări/achiziții YoY, marjă implicită"
)
altman_zscore: AltmanZScore = Field(
description="Altman Z-Score și componentele X1-X4"
)
profitabilitate: ProfitabilityIndicators = Field(
description="Indicatori de profitabilitate: ROA, ROE, marja de profit"
)
class Config:
json_schema_extra = {
"example": {
"lichiditate": {
"lichiditate_curenta": {"value": 2.37, "status": "good", "threshold_min": 2.0},
"lichiditate_imediata": {"value": 1.50, "status": "good", "threshold_min": 1.0},
"lichiditate_vedere": {"value": 0.45, "status": "good", "threshold_min": 0.2}
},
"eficienta": {
"dso": {"value": 28.5, "status": "good", "threshold_max": 30},
"dpo": {"value": 35.2, "status": "good"},
"cash_conversion_cycle": {"value": -6.7, "status": "good", "threshold_max": 0},
"rata_incasare": {"value": 92.5, "status": "warning", "threshold_min": 95},
"rata_plata": {"value": 88.3, "status": "good"}
},
"risc": {
"creante_restante_pct": {"value": 15.5, "status": "good", "threshold_max": 20},
"creante_90plus_pct": {"value": 3.2, "status": "good", "threshold_max": 5},
"datorii_restante_pct": {"value": 8.5, "status": "good", "threshold_max": 10},
"raport_datorii_trezorerie": {"value": 1.8, "status": "good", "threshold_max": 2}
},
"cash_flow": {
"flux_net_lunar": {"value": 125000.50, "status": "good", "threshold_min": 0},
"cash_flow_ytd": {"value": 850000.00, "status": "good", "threshold_min": 0},
"flux_net_yoy_pct": {"value": 15.5, "status": "good", "threshold_min": 0},
"acoperire_cash_flow": {"value": 2.5, "status": "good", "threshold_min": 1.0}
},
"dinamica": {
"crestere_vanzari_yoy": {"value": 12.5, "status": "good", "threshold_min": 5.0},
"crestere_achizitii_yoy": {"value": 8.3, "status": "good"},
"marja_implicita": {"value": 25.5, "status": "good", "threshold_min": 20.0}
},
"altman_zscore": {
"zscore": {"value": 3.25, "status": "safe", "threshold_min": 2.60},
"x1": {"value": 0.25, "status": "good"},
"x2": {"value": 0.15, "status": "good"},
"x3": {"value": 0.12, "status": "good"},
"x4": {"value": 1.80, "status": "good"},
"working_capital": 450000.00,
"total_assets": 1800000.00
}
}
}