This commit is contained in:
ocroguennec committed 2026-09-19 14:37:02 +02:00
1 parent 6bba34396c
commit 1d5737703b
9 files changed
+347 -45

No files matched your search

+27 -7
View File
@@ -144,13 +144,28 @@ router.get('/', (req, res) => {
// (Fundora, 31/08/26) où la plateforme débite le montant BRUT, pas seulement le net investi.
// 'portefeuille' est un versement complémentaire distinct de montant_investi, jamais câblé
// jusqu'ici. 'compte_courant' reste exclu (aucun impact sur le porte-monnaie).
// Inclut désormais aussi les frais PE (investissement_pe_id) — jusqu'ici absents (LEFT JOIN
// ajouté le 19/09/26, bug trouvé par Claude en creusant le signalement Olivier du même jour
// sur le solde indicatif : une plateforme partagée crowdlending/PE voyait son solde_portefeuille
// légèrement surestimé dès qu'un frais PE "source"/"portefeuille" existait, ce frais n'étant
// jamais déduit nulle part). COALESCE sur investisseur_id : un frais n'a jamais les deux à la
// fois (CHECK en base), donc au plus un des deux LEFT JOIN matche réellement.
// Correctif du même jour (Olivier, après coup) : pour un deal PE, 'source' n'est PAS un débit
// supplémentaire — montant_investi (déjà déduit via capitalInvestiPePerPlat plus bas) est le
// montant BRUT transféré, frais compris. Ne compter un frais PE que s'il est 'portefeuille'
// (versement complémentaire, réellement distinct) ; côté crowdlending, 'source' reste compté
// (montant_investi y est net — cf. cas Fundora du 31/08/26, modèle différent de PE).
const fraisPerPlat = db.prepare(`
SELECT f.plateforme_id,
COALESCE(SUM(f.montant), 0) AS total_frais
FROM frais_operations f
JOIN investissements i ON i.id = f.investissement_id
WHERE ${invWhere.replace('investisseur_id', 'i.investisseur_id')}
AND f.mode_reglement IN ('source', 'portefeuille')
LEFT JOIN investissements i ON i.id = f.investissement_id
LEFT JOIN investissements_pe ipe ON ipe.id = f.investissement_pe_id
WHERE ${invWhere.replace('investisseur_id', 'COALESCE(i.investisseur_id, ipe.investisseur_id)')}
AND (
(i.id IS NOT NULL AND f.mode_reglement IN ('source', 'portefeuille'))
OR (ipe.id IS NOT NULL AND f.mode_reglement = 'portefeuille')
)
${asOf ? 'AND f.date_operation <= ?' : ''}
GROUP BY f.plateforme_id
`).all(...invParams, ...(asOf ? [asOf] : []));
@@ -381,13 +396,18 @@ router.get('/solde-historique', (req, res) => {
`).get(platId, ...invParams, date);
/* ── 5. Frais d'opération 'source'/'portefeuille' (jusqu'à :date) ─── */
// Cf. GET / ci-dessus (fraisPerPlat) — même logique, même exclusion de compte_courant.
// Cf. GET / ci-dessus (fraisPerPlat) — même logique, même exclusion de compte_courant, même
// exclusion des frais PE 'source' (déjà inclus dans montant_investi, cf. commentaire ci-dessus).
const frais = db.prepare(`
SELECT COALESCE(SUM(f.montant), 0) AS total_frais
FROM frais_operations f
JOIN investissements i ON i.id = f.investissement_id
WHERE i.plateforme_id = ? AND ${invWhere.replace('investisseur_id', 'i.investisseur_id')}
AND f.mode_reglement IN ('source', 'portefeuille')
LEFT JOIN investissements i ON i.id = f.investissement_id
LEFT JOIN investissements_pe ipe ON ipe.id = f.investissement_pe_id
WHERE f.plateforme_id = ? AND ${invWhere.replace('investisseur_id', 'COALESCE(i.investisseur_id, ipe.investisseur_id)')}
AND (
(i.id IS NOT NULL AND f.mode_reglement IN ('source', 'portefeuille'))
OR (ipe.id IS NOT NULL AND f.mode_reglement = 'portefeuille')
)
AND f.date_operation <= ?
`).get(platId, ...invParams, date);