Correction bug
This commit is contained in:
1 parent
8e1b82d161
commit
dc05e633c6
2 files changed
+64
-4
No files matched your search
@@ -73,7 +73,8 @@ const PerteSchema = z.object({
|
||||
function regenererEcheancier(investissementId) {
|
||||
const inv = db.prepare(`
|
||||
SELECT id, montant_investi, taux_interet, duree_mois, type_remb, freq_interets,
|
||||
date_premiere_echeance, date_debut_simul, date_souscription, echeance_fin_de_mois
|
||||
date_premiere_echeance, date_debut_simul, date_souscription, echeance_fin_de_mois,
|
||||
date_cible
|
||||
FROM investissements WHERE id = ?
|
||||
`).get(investissementId);
|
||||
if (!inv) return;
|
||||
|
||||
@@ -125,7 +125,8 @@ export function monthsDiff(isoA, isoB) {
|
||||
export function adjustSimulForActuals(db, investissementId) {
|
||||
const inv = db.prepare(`
|
||||
SELECT id, montant_investi, taux_interet, duree_mois, type_remb, freq_interets,
|
||||
date_premiere_echeance, date_debut_simul, date_souscription, echeance_fin_de_mois
|
||||
date_premiere_echeance, date_debut_simul, date_souscription, echeance_fin_de_mois,
|
||||
date_cible
|
||||
FROM investissements WHERE id = ?
|
||||
`).get(investissementId);
|
||||
|
||||
@@ -433,7 +434,8 @@ function adjustFirstPartialPeriod(db, investissementId) {
|
||||
export function generateSimulWithReinvestissements(db, investissementId) {
|
||||
const inv = db.prepare(`
|
||||
SELECT id, montant_investi, taux_interet, duree_mois, type_remb, freq_interets,
|
||||
date_premiere_echeance, date_debut_simul, date_souscription, echeance_fin_de_mois
|
||||
date_premiere_echeance, date_debut_simul, date_souscription, echeance_fin_de_mois,
|
||||
date_cible
|
||||
FROM investissements WHERE id = ?
|
||||
`).get(investissementId);
|
||||
|
||||
@@ -452,6 +454,31 @@ export function generateSimulWithReinvestissements(db, investissementId) {
|
||||
// taux_interet peut légitimement valoir 0 (cf. commentaire dans adjustSimulForActuals)
|
||||
if (inv.taux_interet == null || !inv.duree_mois) return;
|
||||
|
||||
// Cas particulier "differe" (versement unique), avec réinvestissements : une seule échéance
|
||||
// au total, ancrée sur date_cible (la date d'effet de la révision la plus récente, jamais
|
||||
// recalculée à partir d'un décompte de mois écoulés — cf. commentaire équivalent, et le
|
||||
// bug qu'il corrige, dans generateSimul() plus bas).
|
||||
if ((inv.type_remb || 'in_fine') === 'differe') {
|
||||
const finDeMoisDiffere = !!inv.echeance_fin_de_mois;
|
||||
const startDate = inv.date_cible || inv.date_premiere_echeance || inv.date_souscription;
|
||||
if (!startDate) return;
|
||||
const date = finDeMoisDiffere ? lastDayOfMonth(startDate) : startDate;
|
||||
const capital = round2(
|
||||
inv.montant_investi +
|
||||
reinvests.filter(r => r.date_reinvestissement <= date).reduce((s, r) => s + r.montant, 0)
|
||||
);
|
||||
const interets = round2(capital * (inv.taux_interet / 100 / 12) * inv.duree_mois);
|
||||
db.transaction(() => {
|
||||
db.prepare('DELETE FROM simul_remboursements WHERE investissement_id=?').run(investissementId);
|
||||
db.prepare(`
|
||||
INSERT INTO simul_remboursements
|
||||
(investissement_id, numero_echeance, date_prevue, capital_prevu, interets_prevus, total_prevu)
|
||||
VALUES (?,?,?,?,?,?)
|
||||
`).run(investissementId, 1, date, capital, interets, round2(capital + interets));
|
||||
})();
|
||||
return;
|
||||
}
|
||||
|
||||
const finDeMois = !!inv.echeance_fin_de_mois;
|
||||
const type = inv.type_remb || 'in_fine';
|
||||
const freq = inv.freq_interets || 'mensuel';
|
||||
@@ -609,12 +636,44 @@ export function generateSimulWithReinvestissements(db, investissementId) {
|
||||
*/
|
||||
export function generateSimul(db, inv) {
|
||||
const { id, montant_investi, taux_interet, duree_mois, type_remb, freq_interets,
|
||||
date_premiere_echeance, date_debut_simul, date_souscription, echeance_fin_de_mois } = inv;
|
||||
date_premiere_echeance, date_debut_simul, date_souscription, echeance_fin_de_mois,
|
||||
date_cible } = inv;
|
||||
|
||||
// taux_interet peut légitimement valoir 0 (cf. commentaire dans adjustSimulForActuals)
|
||||
if (taux_interet == null || !duree_mois) return;
|
||||
|
||||
const finDeMois = !!echeance_fin_de_mois;
|
||||
|
||||
// Cas particulier "differe" (versement unique) : il n'existe jamais qu'une seule échéance
|
||||
// au total, donc le mécanisme de restructuration ci-dessous (numérotation par mois écoulés
|
||||
// depuis date_premiere_echeance, conservation d'échéances déjà honorées) n'a pas de sens —
|
||||
// il a été conçu pour les prêts à échéances multiples (in_fine/amortissable) où l'on
|
||||
// reprend le calendrier en cours de route. Appliqué tel quel à un prêt différé après une
|
||||
// révision (ex. prolongation), il produisait un numero_echeance et une date aberrants :
|
||||
// numero_echeance = mois écoulés + 1 (ex. n°10) au lieu de 1, et une date recalculée à
|
||||
// partir de l'ancienne cadence (date_premiere_echeance + mois écoulés) au lieu de la
|
||||
// nouvelle date cible — bug signalé par Olivier le 22/08/26 sur le dossier "Le Dolce
|
||||
// Notte". On régénère donc toujours une unique échéance, ancrée sur date_cible (la date
|
||||
// d'effet de la révision la plus récente, ou la date de première échéance d'origine si
|
||||
// aucune révision n'a encore eu lieu).
|
||||
if ((type_remb || 'in_fine') === 'differe') {
|
||||
const startDate = date_cible || date_premiere_echeance || date_souscription;
|
||||
if (!startDate) return;
|
||||
const [echeance] = buildSchedule({
|
||||
montant: montant_investi, taux: taux_interet, duree: duree_mois,
|
||||
type: 'differe', freq: freq_interets || 'in_fine', startDate, finDeMois,
|
||||
});
|
||||
db.transaction(() => {
|
||||
db.prepare('DELETE FROM simul_remboursements WHERE investissement_id=?').run(id);
|
||||
db.prepare(`
|
||||
INSERT INTO simul_remboursements
|
||||
(investissement_id, numero_echeance, date_prevue, capital_prevu, interets_prevus, total_prevu)
|
||||
VALUES (?,?,?,?,?,?)
|
||||
`).run(id, 1, echeance.date, echeance.capital, echeance.interets, echeance.total);
|
||||
})();
|
||||
return;
|
||||
}
|
||||
|
||||
const isRestructuration = !!date_debut_simul;
|
||||
|
||||
// En mode restructuration, on a besoin de connaître les échéances déjà honorées
|
||||
|
||||
Reference in new issue
Block a user