""" 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)" ) capital_social_strict: Decimal = Field( default=Decimal('0'), description="Capital Social strict (doar contul 101 - subscris și vărsat)" ) cifra_afaceri: Decimal = Field( default=Decimal('0'), description="Cifra de afaceri (doar 70x FĂRĂ TVA, fără 71x-75x)" ) achizitii_stocuri: Decimal = Field( default=Decimal('0'), description="Achiziții stocuri YTD (Clasa 3 TOTDEB, FĂRĂ TVA)" ) # 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 Sub-indicatori pentru verificare: - active_curente: Active Curente = Stocuri + Creanțe + Disponibilități - disponibilitati: Disponibilități (bancă + casă) - creante: Creanțe comerciale - datorii_curente: Datorii pe termen scurt """ 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" ) # Sub-indicatori pentru verificare manuală în balanță active_curente: Optional[IndicatorResult] = Field( default=None, description="Active Curente = Stocuri + Creanțe + Disponibilități (RON)" ) disponibilitati: Optional[IndicatorResult] = Field( default=None, description="Disponibilități = Bancă (512x) + Casă (531x) (RON)" ) creante: Optional[IndicatorResult] = Field( default=None, description="Creanțe comerciale = Clienți (411x) + Debitori (461x) (RON)" ) datorii_curente: Optional[IndicatorResult] = Field( default=None, description="Datorii pe termen scurt = Furnizori + TVA + Salarii etc. (RON)" ) 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" ) # Sub-indicatori pentru verificare manuală sold_clienti: Optional[IndicatorResult] = Field( default=None, description="Sold Clienți la final de lună (RON)" ) facturari_lunare: Optional[IndicatorResult] = Field( default=None, description="Total facturări în luna curentă (RON)" ) sold_furnizori: Optional[IndicatorResult] = Field( default=None, description="Sold Furnizori la final de lună (RON)" ) achizitii_lunare: Optional[IndicatorResult] = Field( default=None, description="Total achiziții în luna curentă (RON)" ) incasari_luna: Optional[IndicatorResult] = Field( default=None, description="Încasări efectuate în luna curentă (RON)" ) plati_luna: Optional[IndicatorResult] = Field( default=None, description="Plăți efectuate în luna curentă (RON)" ) 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" ) # Sub-indicatori pentru verificare manuală total_clienti: Optional[IndicatorResult] = Field( default=None, description="Sold total clienți (411x) (RON)" ) clienti_restanti: Optional[IndicatorResult] = Field( default=None, description="Sold clienți cu facturi restante (RON)" ) clienti_90plus: Optional[IndicatorResult] = Field( default=None, description="Sold clienți cu facturi >90 zile restant (RON)" ) total_furnizori: Optional[IndicatorResult] = Field( default=None, description="Sold total furnizori (401x) (RON)" ) furnizori_restanti: Optional[IndicatorResult] = Field( default=None, description="Sold furnizori cu facturi restante (RON)" ) trezorerie: Optional[IndicatorResult] = Field( default=None, description="Disponibilități (512x + 531x) (RON)" ) 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" ) # Sub-indicatori pentru verificare manuală incasari_luna: Optional[IndicatorResult] = Field( default=None, description="Încasări luna curentă (RON)" ) plati_luna: Optional[IndicatorResult] = Field( default=None, description="Plăți luna curentă (RON)" ) cf_an_precedent: Optional[IndicatorResult] = Field( default=None, description="Cash Flow aceeași perioadă an precedent (RON)" ) datorii_restante: Optional[IndicatorResult] = Field( default=None, description="Total datorii cu scadență depășită (RON)" ) 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). SURSE DE DATE (toate FĂRĂ TVA): - Vânzări: Cifra de Afaceri din VBAL (Clasa 7 - conturile 70x) - Achiziții: Registru Jurnal ACT (stocuri 3x=4x + cheltuieli directe 6x=4x) Attributes: crestere_vanzari_yoy: Creșterea procentuală a Cifrei de Afaceri față de anul anterior - Formula: (CA_curent - CA_anterior) / CA_anterior * 100 - Sursa: VBAL TOTCRED(70x) - TOTDEB(709) - Good: > 5%, Warning: 0-5%, Danger: < 0% crestere_achizitii_yoy: Creșterea procentuală a achizițiilor totale față de anul anterior - Formula: (achizitii_curent - achizitii_anterior) / achizitii_anterior * 100 - Sursa: ACT (stocuri 3x=4x + cheltuieli directe 6x=4x, fără TVA) - Creșterea achizițiilor poate indica expansiune sau costuri mai mari marja_implicita: Marja implicită din diferența CA - achiziții totale - Formula: (CA - achizitii_totale) / CA * 100 - Arată ce procent din Cifra de Afaceri 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" ) # Sub-indicatori pentru verificare manuală vanzari_an_curent: Optional[IndicatorResult] = Field( default=None, description="Total vânzări YTD an curent (RON)" ) vanzari_an_precedent: Optional[IndicatorResult] = Field( default=None, description="Total vânzări YTD an precedent (RON)" ) achizitii_an_curent: Optional[IndicatorResult] = Field( default=None, description="Total achiziții YTD an curent (stocuri + cheltuieli directe, fără TVA)" ) achizitii_an_precedent: Optional[IndicatorResult] = Field( default=None, description="Total achiziții YTD an precedent (stocuri + cheltuieli directe, fără TVA)" ) 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" ) # Sub-indicator pentru verificare EBIT venituri: Optional[IndicatorResult] = Field( default=None, description="Total venituri (Clasa 7) - pentru verificare calcul EBIT (RON)" ) 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 SolvabilityIndicators(BaseModel): """ Indicatori de solvabilitate pentru evaluarea capacității firmei de a-și acoperi datoriile pe termen lung. Conform articolului UniversulFiscal despre Activul Net Contabil (ANC): - ANC = Total Active - Total Datorii - Implicații legale (din 1 ianuarie 2026): Sub 50% din capital social → restricții dividende, restituire împrumuturi, acordare împrumuturi noi Attributes: activ_net_contabil: Activul Net Contabil (ANC) în RON - Formula: Total Active - Total Datorii - Good: > 0 (firma are avere netă pozitivă) - Danger: <= 0 (firma este insolvabilă tehnic) rata_anc_capital: Rata ANC / Capital Social în % - Formula: (ANC / Capital Social) × 100 - Good: >= 100% (ANC acoperă integral capitalul social) - Warning: 50-100% (ANC sub capital, dar peste pragul legal) - Danger: < 50% (sub pragul legal - restricții aplicabile) total_active: Total Active - valoare de verificare total_datorii: Total Datorii - valoare de verificare capital_social: Capital Social - valoare de verificare """ activ_net_contabil: IndicatorResult = Field( description="Activ Net Contabil = Total Active - Total Datorii (RON)" ) rata_anc_capital: IndicatorResult = Field( description="Rata ANC/Capital = (ANC / Capital Social) × 100 (%)" ) # Valori de bază pentru verificare manuală în balanță total_active: IndicatorResult = Field( description="Total Active - bază calcul ANC" ) total_datorii: IndicatorResult = Field( description="Total Datorii - bază calcul ANC" ) capital_social: IndicatorResult = Field( description="Capital Social - bază calcul Rata ANC" ) class Config: json_schema_extra = { "example": { "activ_net_contabil": { "value": 850000.00, "status": "good", "threshold_min": 0, "threshold_max": None, "message": "Activ net pozitiv - firma solvabilă" }, "rata_anc_capital": { "value": 125.5, "status": "good", "threshold_min": 100.0, "threshold_max": None, "message": "ANC peste capitalul social - situație sănătoasă" }, "total_active": { "value": 1800000.00, "status": "good", "threshold_min": None, "threshold_max": None, "message": "Active Imobilizate + Active Curente" }, "total_datorii": { "value": 950000.00, "status": "good", "threshold_min": None, "threshold_max": None, "message": "Datorii Curente + Datorii Termen Lung" }, "capital_social": { "value": 680000.00, "status": "good", "threshold_min": None, "threshold_max": None, "message": "Capital subscris și vărsat" } } } 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) solvabilitate: Indicatori de solvabilitate (ANC, rata ANC/Capital Social) Usage: GET /api/reports/dashboard/financial-indicators?company=123&luna=12&an=2024 Response example: { "lichiditate": { ... }, "eficienta": { ... }, "risc": { ... }, "cash_flow": { ... }, "dinamica": { ... }, "altman_zscore": { ... }, "profitabilitate": { ... }, "solvabilitate": { ... } } """ 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" ) solvabilitate: SolvabilityIndicators = Field( description="Indicatori de solvabilitate: ANC, rata ANC/Capital Social" ) 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 }, "solvabilitate": { "activ_net_contabil": {"value": 850000.00, "status": "good", "threshold_min": 0}, "rata_anc_capital": {"value": 125.5, "status": "good", "threshold_min": 100.0}, "total_active": {"value": 1800000.00, "status": "good"}, "total_datorii": {"value": 950000.00, "status": "good"}, "capital_social": {"value": 680000.00, "status": "good"} } } }