Bug
This commit is contained in:
1 parent
dc05e633c6
commit
c9ca27b7be
1 file changed
+25
-4
@@ -673,12 +673,26 @@ router.post('/:id/revisions', (req, res, next) => {
|
|||||||
|
|
||||||
// Recalcule duree_mois si la date cible change réellement, pour que l'échéancier régénéré
|
// Recalcule duree_mois si la date cible change réellement, pour que l'échéancier régénéré
|
||||||
// atteigne effectivement cette nouvelle date (cf. convention date_cible = date_premiere_echeance
|
// atteigne effectivement cette nouvelle date (cf. convention date_cible = date_premiere_echeance
|
||||||
// + (duree_mois - 1) mois, utilisée côté frontend pour tous les types de prêt).
|
// + (duree_mois - 1) mois, utilisée côté frontend pour les prêts à échéances multiples).
|
||||||
|
//
|
||||||
|
// Cas particulier "differe" (versement unique) : duree_mois y représente le nombre total de
|
||||||
|
// mois entre date_souscription et l'unique échéance (cf. buildSchedule(), qui l'utilise
|
||||||
|
// directement dans interets = montant * taux/100/12 * duree — même convention qu'à la
|
||||||
|
// création du prêt), PAS un décompte d'échéances depuis date_premiere_echeance. Réutiliser
|
||||||
|
// la formule "+1 depuis date_premiere_echeance" ici sous-évalue lourdement la durée réelle
|
||||||
|
// (et donc les intérêts) — bug signalé par Olivier le 22/08/26 sur "Le Troubadour" : une
|
||||||
|
// prolongation de 12%→17% jusqu'au 30/09/2026 donnait duree_mois=8 (mois écoulés entre
|
||||||
|
// date_premiere_echeance et la nouvelle date cible, +1) au lieu de 25 (mois écoulés depuis
|
||||||
|
// la souscription), d'où des intérêts largement sous-estimés (28,33€ au lieu de ~88,54€).
|
||||||
const dateChangee = nouvelle_date_cible !== ancienne_date_cible;
|
const dateChangee = nouvelle_date_cible !== ancienne_date_cible;
|
||||||
let nouveau_duree_mois = ancien_duree_mois;
|
let nouveau_duree_mois = ancien_duree_mois;
|
||||||
if (dateChangee && inv.date_premiere_echeance) {
|
if (dateChangee) {
|
||||||
|
if (inv.type_remb === 'differe' && inv.date_souscription) {
|
||||||
|
nouveau_duree_mois = monthsDiff(inv.date_souscription, nouvelle_date_cible);
|
||||||
|
} else if (inv.date_premiere_echeance) {
|
||||||
nouveau_duree_mois = monthsDiff(inv.date_premiere_echeance, nouvelle_date_cible) + 1;
|
nouveau_duree_mois = monthsDiff(inv.date_premiere_echeance, nouvelle_date_cible) + 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Statut "Prolongation" : uniquement quand la date cible change réellement ET que le
|
// Statut "Prolongation" : uniquement quand la date cible change réellement ET que le
|
||||||
// dossier est actuellement en_retard/procedure (renégociation d'un prêt à risque). Un
|
// dossier est actuellement en_retard/procedure (renégociation d'un prêt à risque). Un
|
||||||
@@ -782,7 +796,7 @@ router.put('/:id/revisions/:rid', (req, res, next) => {
|
|||||||
const body = RevisionSchema.parse(req.body);
|
const body = RevisionSchema.parse(req.body);
|
||||||
const invId = Number(req.params.id);
|
const invId = Number(req.params.id);
|
||||||
const inv = db.prepare(`
|
const inv = db.prepare(`
|
||||||
SELECT i.id, i.statut, i.date_premiere_echeance FROM investissements i
|
SELECT i.id, i.statut, i.date_premiere_echeance, i.type_remb, i.date_souscription FROM investissements i
|
||||||
JOIN investisseurs inv ON inv.id = i.investisseur_id
|
JOIN investisseurs inv ON inv.id = i.investisseur_id
|
||||||
WHERE i.id = ? AND inv.user_id = ?
|
WHERE i.id = ? AND inv.user_id = ?
|
||||||
`).get(invId, req.user.id);
|
`).get(invId, req.user.id);
|
||||||
@@ -802,11 +816,18 @@ router.put('/:id/revisions/:rid', (req, res, next) => {
|
|||||||
const nouveau_taux = body.nouveau_taux ?? ancien_taux;
|
const nouveau_taux = body.nouveau_taux ?? ancien_taux;
|
||||||
const nouvelle_date_cible = body.nouvelle_date_cible ?? ancienne_date_cible;
|
const nouvelle_date_cible = body.nouvelle_date_cible ?? ancienne_date_cible;
|
||||||
|
|
||||||
|
// Cf. commentaire équivalent dans POST /:id/revisions : un prêt "differe" (versement
|
||||||
|
// unique) recalcule duree_mois depuis date_souscription (sans +1), jamais depuis
|
||||||
|
// date_premiere_echeance comme les prêts à échéances multiples.
|
||||||
const dateChangee = nouvelle_date_cible !== ancienne_date_cible;
|
const dateChangee = nouvelle_date_cible !== ancienne_date_cible;
|
||||||
let nouveau_duree_mois = ancien_duree_mois;
|
let nouveau_duree_mois = ancien_duree_mois;
|
||||||
if (dateChangee && inv.date_premiere_echeance) {
|
if (dateChangee) {
|
||||||
|
if (inv.type_remb === 'differe' && inv.date_souscription) {
|
||||||
|
nouveau_duree_mois = monthsDiff(inv.date_souscription, nouvelle_date_cible);
|
||||||
|
} else if (inv.date_premiere_echeance) {
|
||||||
nouveau_duree_mois = monthsDiff(inv.date_premiere_echeance, nouvelle_date_cible) + 1;
|
nouveau_duree_mois = monthsDiff(inv.date_premiere_echeance, nouvelle_date_cible) + 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Statut : on rejoue le même raisonnement que POST/DELETE combinés — d'abord retrouver le
|
// Statut : on rejoue le même raisonnement que POST/DELETE combinés — d'abord retrouver le
|
||||||
// statut d'avant l'effet de cette révision (sauf si autre chose l'a fait évoluer entre
|
// statut d'avant l'effet de cette révision (sauf si autre chose l'a fait évoluer entre
|
||||||
|
|||||||
Reference in new issue
Block a user