diff --git a/frontend/src/pages/Plateformes.jsx b/frontend/src/pages/Plateformes.jsx index 6ad3167..88f9d6e 100644 --- a/frontend/src/pages/Plateformes.jsx +++ b/frontend/src/pages/Plateformes.jsx @@ -818,6 +818,53 @@ export default function Plateformes() { const netMode = displayMode === 'net'; const prevYearLabel = selectedYear ? Number(selectedYear) - 1 : new Date().getFullYear() - 1; + /* ── Solde porte-monnaie (cf. formule dashboard.js) ────────────── + dépôts − retraits manuels + remboursements crédités au portefeuille + + bonus − capital investi + corrections de solde, cumulés sur la + sélection plateforme(s)/détenteur, jusqu'à une date de coupure. */ + const computeSoldePortefeuille = (cutoff) => { + let balance = 0; + for (const d of allDepots) { + if (!filteredPlatIds.has(d.plateforme_id)) continue; + if (cutoff && d.date_operation > cutoff) continue; + if (d.type === 'depot') balance += d.montant || 0; + else if (d.source !== 'auto_remboursement') balance -= d.montant || 0; + } + for (const r of allRembs) { + if (!filteredPlatIds.has(r.plateforme_id)) continue; + if (r.methode_remboursement !== 'portefeuille') continue; + if (!r.date_remb || (cutoff && r.date_remb > cutoff)) continue; + if (r.type === 'normal') { + const plat = plats.find(p => p.id === r.plateforme_id); + balance += plat?.fiscalite === 'flat_tax' + ? (r.net_recu || 0) + : (r.capital || 0) + (r.cashback || 0) + (r.interets_bruts || 0); + } else if (r.type === 'bonus_parrainage' || r.type === 'bonus_plateforme') { + balance += r.cashback || 0; + } + } + for (const inv of allRows) { + if (!filteredPlatIds.has(inv.plateforme_id)) continue; + if (!inv.date_souscription || (cutoff && inv.date_souscription > cutoff)) continue; + balance -= inv.capital_total ?? inv.montant_investi ?? 0; + } + for (const c of allCorrections) { + if (!filteredPlatIds.has(c.plateforme_id)) continue; + if (cutoff && c.date > cutoff) continue; + balance += c.montant || 0; + } + return Math.round(balance * 100) / 100; + }; + + const soldePortefeuille = useMemo( + () => computeSoldePortefeuille(selectedYear ? `${selectedYear}-12-31` : null), + [allDepots, allRembs, allRows, allCorrections, plats, filteredPlatIds, selectedYear] + ); + const prevSoldePortefeuille = useMemo( + () => computeSoldePortefeuille(`${prevYearLabel}-12-31`), + [allDepots, allRembs, allRows, allCorrections, plats, filteredPlatIds, prevYearLabel] + ); + if (!loading && plats.length === 0) { return ( <> @@ -886,7 +933,7 @@ export default function Plateformes() { } {/* ── KPIs ── */} - {!listFocused &&
+ {!listFocused &&
{/* 1 — Capital investi */}
@@ -914,7 +961,19 @@ export default function Plateformes() {
- {/* 3 — Investissements depuis le début */} + {/* 3 — Porte-monnaie */} +
+
Porte-monnaie
+
+ {fmtEUR(soldePortefeuille)} + +
+
+ {fmtEUR(prevSoldePortefeuille)} en {prevYearLabel} +
+
+ + {/* 4 — Investissements depuis le début */}
Investissements depuis le début
@@ -926,7 +985,7 @@ export default function Plateformes() {
- {/* 4 — Capital remboursé */} + {/* 5 — Capital remboursé */}
Capital remboursé
@@ -938,7 +997,7 @@ export default function Plateformes() {
- {/* 5 — Intérêts perçus */} + {/* 6 — Intérêts perçus */}
Intérêts perçus — {netMode ? 'Net' : 'Brut'}
@@ -955,7 +1014,7 @@ export default function Plateformes() {
- {/* 6 — XIRR */} + {/* 7 — XIRR */} {(() => { const rendement = netMode ? plateformeXirr.net : plateformeXirr.brut; const cutoffLabel = selectedYear ? `31/12/${selectedYear}` : "aujourd'hui";