Files
roa2web-service-auto/tasks/prd-financial-indicators-dashboard.md
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

326 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PRD: Card Indicatori Financiari în Dashboard Solduri
## 1. Introducere
Adăugarea unui card nou în dashboard-ul solduri cu indicatori financiari esențiali pentru evaluare bancară/creditare și analiză sănătate financiară a firmei. Indicatorii vor include rate de lichiditate, eficiență, risc, și scorul Altman Z-Score pentru predicția falimentului - aceiași indicatori pe care îi folosesc băncile și evaluatorii pentru acordarea de credite.
## 2. Obiective
### Obiectiv Principal
- Oferirea unei viziuni complete asupra sănătății financiare a firmei într-un singur card, cu indicatori calculați automat din datele contabile
### Obiective Secundare
- Vizualizarea evoluției indicatorilor pe 12 luni (sparklines)
- Comparație Year-over-Year pentru fiecare indicator
- Alertare vizuală (cod culoare) pentru valori în afara pragurilor recomandate
- Calculul scorului Altman Z-Score pentru evaluarea riscului de faliment
### Metrici de Succes
- Toți cei 22+ indicatori sunt calculați corect și afișați
- Sparklines afișează evoluția corectă pe 12 luni
- Cod culoare (verde/galben/roșu) corespunde pragurilor standard
- Timpul de încărcare < 2 secunde (cu cache)
## 3. User Stories
### US-001: Backend - Serviciu Agregare Conturi Balanță
**Ca** dezvoltator backend
**Vreau** un serviciu care agregă soldurile din balanța de verificare (VBAL) pe clase de conturi
**Pentru că** am nevoie de date agregate pentru calculul indicatorilor de bilanț și Altman Z-Score
**Acceptance Criteria:**
- [ ] Creat `backend/modules/reports/services/financial_indicators_service.py`
- [ ] Metoda `get_balance_sheet_aggregates()` returnează solduri agregate pentru: active_imobilizate, stocuri, creante, disponibilitati, capital_propriu, rezultat, datorii_termen_lung, datorii_curente, venituri, cheltuieli_operationale
- [ ] Query-ul folosește VBAL view cu LIKE pentru prefixe conturi (ex: `cont LIKE '20%'`)
- [ ] Cache implementat cu TTL 30 minute
- [ ] Unit test verifică structura răspunsului
### US-002: Backend - Calcul Indicatori Lichiditate
**Ca** utilizator al dashboard-ului
**Vreau** văd indicatorii de lichiditate calculați automat
**Pentru că** vreau știu dacă firma poate plăti datoriile pe termen scurt
**Acceptance Criteria:**
- [ ] Calculat `lichiditate_curenta` = Active Curente / Datorii Curente
- [ ] Calculat `lichiditate_imediata` (Quick Ratio) = (Trezorerie + Creanțe) / Datorii Curente
- [ ] Calculat `lichiditate_vedere` (Cash Ratio) = Trezorerie / Datorii Curente
- [ ] Fiecare indicator include: valoare, status (good/warning/danger), prag_min, prag_max
- [ ] npm run typecheck passes
### US-003: Backend - Calcul Indicatori Eficiență
**Ca** utilizator al dashboard-ului
**Vreau** văd indicatorii de eficiență (DSO, DPO, rate)
**Pentru că** vreau știu cât de repede convertesc resursele în bani
**Acceptance Criteria:**
- [ ] Calculat `dso` (Durata Încasare) = (Sold Clienți / Facturări Lunare) × 30 zile
- [ ] Calculat `dpo` (Durata Plată) = (Sold Furnizori / Achiziții Lunare) × 30 zile
- [ ] Calculat `cash_conversion_cycle` = DSO - DPO
- [ ] Calculat `rata_incasare` = Încasări / Facturări × 100
- [ ] Calculat `rata_plata` = Plăți / Achiziții × 100
- [ ] npm run typecheck passes
### US-004: Backend - Calcul Indicatori Risc și Aging
**Ca** utilizator al dashboard-ului
**Vreau** văd indicatorii de risc și aging creanțe/datorii
**Pentru că** vreau știu cât de sănătos este portofoliul de creanțe
**Acceptance Criteria:**
- [ ] Calculat `creante_restante_pct` = Creanțe Restante / Creanțe Total × 100
- [ ] Calculat `creante_90plus_pct` = Creanțe 90+ zile / Creanțe Total × 100
- [ ] Calculat `datorii_restante_pct` = Datorii Restante / Datorii Total × 100
- [ ] Calculat `raport_datorii_trezorerie` = Datorii Furnizori / Trezorerie
- [ ] npm run typecheck passes
### US-005: Backend - Calcul Indicatori Cash Flow
**Ca** utilizator al dashboard-ului
**Vreau** văd indicatorii de cash flow
**Pentru că** vreau știu dacă firma generează sau consumă numerar
**Acceptance Criteria:**
- [ ] Calculat `flux_net_lunar` = Încasări - Plăți (luna curentă)
- [ ] Calculat `cash_flow_ytd` = Suma fluxurilor de la ianuarie
- [ ] Calculat `flux_net_yoy_pct` = (CF_curent - CF_anterior) / CF_anterior × 100
- [ ] Calculat `acoperire_cash_flow` = Cash Flow / Datorii Restante
- [ ] npm run typecheck passes
### US-006: Backend - Calcul Indicatori Dinamică
**Ca** utilizator al dashboard-ului
**Vreau** văd evoluția vânzărilor și achizițiilor
**Pentru că** vreau știu dacă afacerea crește sau scade
**Acceptance Criteria:**
- [ ] Calculat `crestere_vanzari_yoy` = (Vânzări_curent - Vânzări_anterior) / Vânzări_anterior × 100
- [ ] Calculat `crestere_achizitii_yoy` = similar
- [ ] Calculat `marja_implicita` = (Vânzări - Achiziții) / Vânzări × 100
- [ ] npm run typecheck passes
### US-007: Backend - Calcul Altman Z-Score
**Ca** utilizator al dashboard-ului
**Vreau** văd scorul Altman Z-Score calculat automat
**Pentru că** vreau știu riscul de faliment al firmei conform standardelor internaționale
**Acceptance Criteria:**
- [ ] Calculat X1 = Working Capital / Total Assets
- [ ] Calculat X2 = Retained Earnings (cont 117) / Total Assets
- [ ] Calculat X3 = EBIT (Cl.7 - Cl.6 fără 66x) / Total Assets
- [ ] Calculat X4 = Equity (Cl.1 capital) / Total Liabilities
- [ ] Calculat Z'' = 6.56×X1 + 3.26×X2 + 6.72×X3 + 1.05×X4
- [ ] Status: "Zonă Sigură" (>2.60), "Zonă Gri" (1.10-2.60), "Zonă Risc" (<1.10)
- [ ] Răspunsul include și componentele individuale (X1-X4) pentru transparență
- [ ] npm run typecheck passes
### US-008: Backend - Endpoint API Financial Indicators
**Ca** frontend developer
**Vreau** un endpoint API care returnează toți indicatorii calculați
**Pentru că** am nevoie afișez datele în UI
**Acceptance Criteria:**
- [ ] Endpoint `GET /api/reports/dashboard/financial-indicators`
- [ ] Parametri: company (required), luna (optional), an (optional)
- [ ] Răspuns JSON cu structura: { lichiditate: {...}, eficienta: {...}, risc: {...}, cash_flow: {...}, dinamica: {...}, altman_zscore: {...} }
- [ ] Fiecare indicator include: value, status, threshold_min, threshold_max, sparkline_data (array 12 valori)
- [ ] Cache 30 minute implementat
- [ ] Response time < 500ms (cu cache)
- [ ] npm run typecheck passes
### US-009: Backend - Date Istorice pentru Sparklines
**Ca** utilizator
**Vreau** văd evoluția fiecărui indicator pe 12 luni
**Pentru că** vreau înțeleg trendul, nu doar valoarea curentă
**Acceptance Criteria:**
- [ ] Fiecare indicator include câmp `sparkline_data` cu array de 12 valori (ultimele 12 luni)
- [ ] Include și `sparkline_labels` cu etichetele lunilor (ex: ["Feb 24", "Mar 24", ...])
- [ ] Datele sunt calculate pentru fiecare lună din ultimele 12
- [ ] npm run typecheck passes
### US-010: Frontend - Component FinancialIndicatorsCard
**Ca** utilizator al dashboard-ului
**Vreau** un card vizual care afișează indicatorii financiari
**Pentru că** vreau văd rapid starea financiară a firmei
**Acceptance Criteria:**
- [ ] Creat `src/modules/reports/components/dashboard/cards/FinancialIndicatorsCard.vue`
- [ ] Header cu titlu "Indicatori Financiari" și selector perioadă
- [ ] Tabs pentru categorii: Lichiditate, Eficiență, Risc, Z-Score
- [ ] Grid 2x2 sau 2x3 pentru indicatori în fiecare tab
- [ ] Folosește design tokens din `docs/DESIGN_TOKENS.md`
- [ ] npm run typecheck passes
- [ ] Verify in browser that card-ul se afișează corect
### US-011: Frontend - Component IndicatorItem cu Sparkline
**Ca** utilizator
**Vreau** fiecare indicator aibă o mini-diagramă de evoluție
**Pentru că** vreau văd trendul vizual
**Acceptance Criteria:**
- [ ] Creat sub-component pentru afișarea unui indicator individual
- [ ] Afișează: nume, valoare curentă, status (icon + culoare), sparkline
- [ ] Cod culoare: verde (good), galben (warning), roșu (danger)
- [ ] Sparkline folosește array-ul de 12 valori
- [ ] Hover pe sparkline arată valoarea lunii
- [ ] npm run typecheck passes
- [ ] Verify in browser that sparkline-urile se afișează corect
### US-012: Frontend - Expand pentru Detalii Complete
**Ca** utilizator
**Vreau** pot expanda cardul pentru a vedea toți indicatorii
**Pentru că** unii indicatori sunt mai puțin importanți dar vreau acces la ei
**Acceptance Criteria:**
- [ ] Buton/chevron pentru expand/collapse
- [ ] Starea collapsed arată 4-6 indicatori principali
- [ ] Starea expanded arată toți 22+ indicatori în format tabel
- [ ] Animație smooth la expand/collapse
- [ ] npm run typecheck passes
- [ ] Verify in browser that expand/collapse funcționează
### US-013: Frontend - Store Integration
**Ca** frontend developer
**Vreau** integrez datele în Pinia store
**Pentru că** am nevoie de state management pentru indicatori
**Acceptance Criteria:**
- [ ] Adăugat metodă `loadFinancialIndicators(companyId, luna, an)` în `dashboard.js` store
- [ ] State pentru `financialIndicators` cu loading, error, data
- [ ] Computed properties pentru fiecare categorie de indicatori
- [ ] Reîncărcare automată când se schimbă compania sau perioada
- [ ] npm run typecheck passes
### US-014: Frontend - Integrare în DashboardView Desktop
**Ca** utilizator pe desktop
**Vreau** văd cardul de indicatori în dashboard
**Pentru că** vreau acces rapid la informații
**Acceptance Criteria:**
- [ ] Import `FinancialIndicatorsCard` în `DashboardView.vue`
- [ ] Adăugat în grid-ul desktop (rând nou sub metric cards)
- [ ] Card ocupă full width sau 2 coloane
- [ ] Se încarcă împreună cu restul dashboard-ului
- [ ] npm run typecheck passes
- [ ] Verify in browser (desktop) that cardul apare corect în layout
### US-015: Frontend - Integrare în DashboardView Mobile
**Ca** utilizator pe mobil
**Vreau** văd cardul de indicatori în carusel
**Pentru că** vreau acces la informații și pe telefon
**Acceptance Criteria:**
- [ ] Adăugat pagină nouă (Page 6) în `SwipeableCards` carousel
- [ ] Layout adaptat pentru ecran mic (1 coloană sau 2x2 mai mic)
- [ ] Touch-friendly (tap pentru expand, swipe pentru navigare)
- [ ] Respectă padding pentru MobileTopBar și MobileBottomNav
- [ ] npm run typecheck passes
- [ ] Verify in browser (mobile viewport) that cardul funcționează corect
### US-016: Frontend - Dark Mode Support
**Ca** utilizator
**Vreau** cardul arate bine în dark mode
**Pentru că** folosesc aplicația și seara
**Acceptance Criteria:**
- [ ] Culorile de status funcționează în ambele teme
- [ ] Sparklines au contrast suficient
- [ ] Textul e lizibil în dark mode
- [ ] Folosește variabile CSS pentru culori (nu hardcodate)
- [ ] npm run typecheck passes
- [ ] Verify in browser (dark mode) that totul e vizibil și lizibil
## 4. Cerințe Funcționale
1. [REQ-001] Sistemul trebuie calculeze toți cei 22 indicatori financiari definiți
2. [REQ-002] Utilizatorul poate vedea valoarea curentă și evoluția pe 12 luni pentru fiecare indicator
3. [REQ-003] Sistemul trebuie afișeze cod culoare pentru status (verde/galben/roșu) bazat pe praguri standard
4. [REQ-004] Când se schimbă compania sau perioada, indicatorii se recalculează automat
5. [REQ-005] Altman Z-Score trebuie calculat conform formulei Z'' pentru firme private non-manufacturiere
6. [REQ-006] Sistemul trebuie cacheze rezultatele pentru 30 minute
7. [REQ-007] Datele se încarcă în paralel cu restul dashboard-ului (nu secvențial)
## 5. Non-Goals (Ce NU facem)
- **NU** implementăm export PDF/Excel al indicatorilor (poate fi adăugat ulterior)
- **NU** implementăm alerte email când indicatorii depășesc praguri
- **NU** implementăm comparație între multiple firme
- **NU** implementăm indicatori care necesită date care nu sunt în sistemul contabil (ex: prețul acțiunilor pentru Z-Score original)
- **NU** modificăm indicatorii existenți din cardurile solduri (Trezorerie, Clienți, Furnizori, TVA)
## 6. Considerații Tehnice
### Stack/Tehnologii
- **Backend**: Python, FastAPI, python-oracledb, Pydantic
- **Frontend**: Vue.js 3, Pinia, PrimeVue, CSS Variables
- **Database**: Oracle (view VBAL pentru balanță)
### Patterns de Urmat
- Backend service pattern cu `@cached` decorator (vezi `dashboard_service.py`)
- Frontend component pattern cu props pentru configurare (vezi `SolduriCompactCard.vue`)
- CSS design tokens (vezi `docs/DESIGN_TOKENS.md`)
### Conturi VBAL Necesare
```python
ACCOUNT_GROUPS = {
'active_imobilizate': ['20%', '21%', '22%', '23%', '24%', '25%', '26%', '27%', '28%'],
'stocuri': ['30%', '31%', '32%', '33%', '34%', '35%', '36%', '37%', '38%', '39%'],
'creante': ['41%', '44%', '45%', '46%', '47%'],
'disponibilitati': ['51%', '53%'],
'capital_propriu': ['101', '102', '103', '104', '105', '106', '107', '108', '109'],
'rezultat': ['117', '121', '129'],
'datorii_termen_lung': ['161', '162', '163', '164', '165', '166', '167', '168', '169'],
'datorii_curente': ['401', '403', '404', '405', '408', '419', '421', '423', '424', ...],
'venituri': ['70%', '71%', '72%', '74%', '75%', '78%'],
'cheltuieli_operationale': ['60%', '61%', '62%', '63%', '64%', '65%', '68%'],
}
```
### Dependențe
- Depinde de endpoint-urile existente `/dashboard/summary` și `/dashboard/trends`
- Depinde de view-ul Oracle VBAL din schema companiei
### Riscuri Tehnice
- **R1**: Unele firme pot nu aibă toate conturile populate (soluție: returnăm null/N/A pentru indicatorii care nu pot fi calculați)
- **R2**: Query-ul VBAL cu multe LIKE poate fi lent (soluție: cache agresiv 30min)
- **R3**: Valorile Z-Score pot fi distorsionate pentru firme foarte mici (soluție: afișăm disclaimer)
## 7. Considerații UI/UX
### Layout Card (Desktop)
```
┌─────────────────────────────────────────────────────────────────┐
│ 📊 INDICATORI FINANCIARI Ianuarie 2025 ▼ │
├──────────────┬──────────────┬──────────────┬───────────────────┤
│ LICHIDITATE │ EFICIENȚĂ │ RISC │ ALTMAN Z │
├──────────────┴──────────────┴──────────────┴───────────────────┤
│ Quick Ratio DSO Creanțe Rest. Z-Score │
│ 1.85x 32 zile 15.2% 2.45 │
│ ✅ >1.0 ⚠️ <45 ✅ <20% ⚠️ Zonă Gri │
│ ▁▂▃▄▅▆▇█▇▆▅ ▇▆▅▄▃▂▁▂▃▄▅▆ ▁▁▂▂▃▃▄▄▅▅▆▆ ▃▄▄▅▅▆▆▇▇███ │
├─────────────────────────────────────────────────────────────────┤
│ ▼ Mai multe indicatori Refresh ↻ │
└─────────────────────────────────────────────────────────────────┘
```
### Stări UI
- **Loading**: Skeleton/shimmer pentru card
- **Error**: Mesaj de eroare cu buton retry
- **Empty**: "Datele nu sunt disponibile pentru această perioadă"
- **Success**: Afișare indicatori cu cod culoare
### Cod Culoare Status
- 🟢 **Verde** (--green-600): Valoare în zona optimă
- 🟡 **Galben** (--yellow-600): Valoare acceptabilă, de urmărit
- 🔴 **Roșu** (--red-600): Valoare critică, necesită atenție
## 8. Success Metrics
- **Completitudine**: 22/22 indicatori calculați și afișați
- **Performanță**: Response time API < 500ms (cached)
- **UX**: Card încărcat complet în < 2 secunde
- **Acuratețe**: Z-Score calculat corect conform formula standard
## 9. Open Questions
- [x] Care indicatori fie vizibili implicit vs la expand? 4-6 principali vizibili, restul la expand
- [x] Vrem tab-uri sau scroll vertical pentru categorii? Tabs pentru categorii
- [ ] Pragurile pentru cod culoare fie configurabile per firmă sau fixe? Fixe pentru MVP