Mise en place de la notion de perte définitive, ainsi que la révision avec statut Polongation

This commit is contained in:
ocroguennec committed 2026-08-22 16:27:41 +02:00
1 parent 4ad6ea79e8
commit 8e1b82d161
21 files changed
+1069 -184

No files matched your search

@@ -89,18 +89,27 @@ export default function CapitalMensuelTable({ allRows, allRembs, allReinvests, p
const { grid, multiDetenteur } = useMemo(() => {
if (!allRows.length) return { grid: null, multiDetenteur: false };
const ACTIVE = ['en_cours', 'en_retard', 'procedure'];
// prolongation compte comme actif au même titre que en_retard/procedure dont il
// découle (renégociation) — aucune déduction de capital associée, contrairement à
// perte_definitive ci-dessous.
const ACTIVE = ['en_cours', 'en_retard', 'procedure', 'prolongation'];
// Index plateformes par id (pour nom + detenteur)
const platMap = {};
for (const p of plats) platMap[p.id] = p;
// Pour chaque investissement, capital encours au end of month M
// Pour chaque investissement, capital encours au end of month M.
// Un investissement en perte_definitive reste compté normalement pour les
// mois antérieurs à la date d'effet de la perte (fidélité historique), puis
// voit son capital réduit du montant perdu (capital_perdu) à partir de ce
// mois — sinon il disparaîtrait du total de la plateforme dès la
// déclaration, faisant perdre le capital restant dû (perte partielle).
const getCapitalAtEndOfMonth = (inv, Y, M) => {
const endM = endOfMonth(Y, M);
if (inv.date_souscription > endM) return 0;
const startM = startOfMonth(Y, M);
const isActive = ACTIVE.includes(inv.statut) ||
const isPerteDef = inv.statut === 'perte_definitive';
const isActive = ACTIVE.includes(inv.statut) || isPerteDef ||
((inv.date_cible || lastRembDateMap[inv.id] || null) >= startM);
if (!isActive) return 0;
@@ -112,7 +121,11 @@ export default function CapitalMensuelTable({ allRows, allRembs, allReinvests, p
.filter(rb => rb.date && rb.date <= endM)
.reduce((s, rb) => s + rb.capital, 0);
return Math.max(0, inv.montant_investi + reinvM - capRembM);
let capital = Math.max(0, inv.montant_investi + reinvM - capRembM);
if (isPerteDef && inv.perte_date_effet && endM >= inv.perte_date_effet) {
capital = Math.max(0, capital - (inv.capital_perdu || 0));
}
return capital;
};
// Agréger par plateforme (id)
+17 -4
View File
@@ -53,13 +53,22 @@ export default function InvMensuelTable({ rows, allRembs, allReinvests, year, or
return map;
}, [allRembs]);
/* ── Capital encours d'un investissement à fin de mois M ── */
/* ── Capital encours d'un investissement à fin de mois M ──
* Un investissement en perte_definitive reste compté normalement pour les
* mois antérieurs à la date d'effet de la perte (fidélité historique), puis
* voit son capital réduit du montant perdu (capital_perdu) à partir de ce
* mois — au lieu de disparaître de la table, ce qui ferait perdre tout le
* capital restant dû (potentiellement une perte partielle) des mois suivants. */
const getCapital = (inv, Y, M) => {
const endM = endOfMonth(Y, M);
if (inv.date_souscription > endM) return 0;
const startM = startOfMonth(Y, M);
const ACTIVE = ['en_cours', 'en_retard', 'procedure'];
const isActive = ACTIVE.includes(inv.statut) ||
// prolongation compte comme actif au même titre que en_retard/procedure dont il
// découle (renégociation) — aucune déduction de capital associée, contrairement à
// perte_definitive ci-dessous.
const ACTIVE = ['en_cours', 'en_retard', 'procedure', 'prolongation'];
const isPerteDef = inv.statut === 'perte_definitive';
const isActive = ACTIVE.includes(inv.statut) || isPerteDef ||
((inv.date_cible || lastRembDateMap[inv.id] || null) >= startM);
if (!isActive) return 0;
@@ -69,7 +78,11 @@ export default function InvMensuelTable({ rows, allRembs, allReinvests, year, or
const capRembM = (capRembByInv[inv.id] || [])
.filter(rb => rb.date && rb.date <= endM)
.reduce((s, rb) => s + rb.capital, 0);
return Math.max(0, inv.montant_investi + reinvM - capRembM);
let capital = Math.max(0, inv.montant_investi + reinvM - capRembM);
if (isPerteDef && inv.perte_date_effet && endM >= inv.perte_date_effet) {
capital = Math.max(0, capital - (inv.capital_perdu || 0));
}
return capital;
};
/* ── Grille : une ligne par investissement ── */