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) {
|
function regenererEcheancier(investissementId) {
|
||||||
const inv = db.prepare(`
|
const inv = db.prepare(`
|
||||||
SELECT id, montant_investi, taux_interet, duree_mois, type_remb, freq_interets,
|
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 = ?
|
FROM investissements WHERE id = ?
|
||||||
`).get(investissementId);
|
`).get(investissementId);
|
||||||
if (!inv) return;
|
if (!inv) return;
|
||||||
|
|||||||
@@ -125,7 +125,8 @@ export function monthsDiff(isoA, isoB) {
|
|||||||
export function adjustSimulForActuals(db, investissementId) {
|
export function adjustSimulForActuals(db, investissementId) {
|
||||||
const inv = db.prepare(`
|
const inv = db.prepare(`
|
||||||
SELECT id, montant_investi, taux_interet, duree_mois, type_remb, freq_interets,
|
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 = ?
|
FROM investissements WHERE id = ?
|
||||||
`).get(investissementId);
|
`).get(investissementId);
|
||||||
|
|
||||||
@@ -433,7 +434,8 @@ function adjustFirstPartialPeriod(db, investissementId) {
|
|||||||
export function generateSimulWithReinvestissements(db, investissementId) {
|
export function generateSimulWithReinvestissements(db, investissementId) {
|
||||||
const inv = db.prepare(`
|
const inv = db.prepare(`
|
||||||
SELECT id, montant_investi, taux_interet, duree_mois, type_remb, freq_interets,
|
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 = ?
|
FROM investissements WHERE id = ?
|
||||||
`).get(investissementId);
|
`).get(investissementId);
|
||||||
|
|
||||||
@@ -452,6 +454,31 @@ export function generateSimulWithReinvestissements(db, investissementId) {
|
|||||||
// taux_interet peut légitimement valoir 0 (cf. commentaire dans adjustSimulForActuals)
|
// taux_interet peut légitimement valoir 0 (cf. commentaire dans adjustSimulForActuals)
|
||||||
if (inv.taux_interet == null || !inv.duree_mois) return;
|
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 finDeMois = !!inv.echeance_fin_de_mois;
|
||||||
const type = inv.type_remb || 'in_fine';
|
const type = inv.type_remb || 'in_fine';
|
||||||
const freq = inv.freq_interets || 'mensuel';
|
const freq = inv.freq_interets || 'mensuel';
|
||||||
@@ -609,12 +636,44 @@ export function generateSimulWithReinvestissements(db, investissementId) {
|
|||||||
*/
|
*/
|
||||||
export function generateSimul(db, inv) {
|
export function generateSimul(db, inv) {
|
||||||
const { id, montant_investi, taux_interet, duree_mois, type_remb, freq_interets,
|
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)
|
// taux_interet peut légitimement valoir 0 (cf. commentaire dans adjustSimulForActuals)
|
||||||
if (taux_interet == null || !duree_mois) return;
|
if (taux_interet == null || !duree_mois) return;
|
||||||
|
|
||||||
const finDeMois = !!echeance_fin_de_mois;
|
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;
|
const isRestructuration = !!date_debut_simul;
|
||||||
|
|
||||||
// En mode restructuration, on a besoin de connaître les échéances déjà honorées
|
// En mode restructuration, on a besoin de connaître les échéances déjà honorées
|
||||||
|
|||||||
Reference in new issue
Block a user