Amélioration de la logique des investissements vs dépôts

This commit is contained in:
ocroguennec committed 2026-08-29 16:03:55 +02:00
1 parent c7bbe5dee6
commit f6829dec9d
4 files changed
+349 -52

No files matched your search

@@ -1,7 +1,10 @@
import { useRef, useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import Modal from './Modal.jsx';
import InvSelect from './InvSelect.jsx';
import CountrySelect from './CountrySelect.jsx';
import { api } from '../api.js';
import { fmtEUR, today } from '../utils/format.js';
import { addMonthsFE, addMonthsFinDeMoisFE, lastDayOfMonthFE, dayOfMonth } from '../utils/dateEcheances.js';
/**
@@ -23,6 +26,14 @@ import { addMonthsFE, addMonthsFinDeMoisFE, lastDayOfMonthFE, dayOfMonth } from
* `required`) de l'étape affichée via `reportValidity()` avant d'avancer ; "Précédent" ne
* valide rien. Le bouton Supprimer (édition) reste visible sur les 3 étapes.
*
* Exception au principe "composant bête" ci-dessus : le solde du porte-monnaie de la
* plateforme sélectionnée est chargé directement par CE composant (GET /dashboard/
* solde-historique) et affiché sous le champ Plateforme (étape 1), avec un bouton
* "Déposer" qui navigue vers /depots-retraits?new=1&plateforme_id=… (ouverture auto de la
* modale Nouveau dépôt, cf. DepotsRetraits.jsx). Comportement strictement identique pour
* les deux pages consommatrices, donc porté ici plutôt que dupliqué dans chacune.
*
* Props (suite) :
* Props :
* open, onClose — état d'ouverture
* editingId — id en édition, falsy si création (contrôle le titre,
@@ -92,6 +103,46 @@ export default function InvestissementFormModal({
const showFinDeMois = (form.type_remb === 'in_fine' || form.type_remb === 'differe')
&& dayOfMonth(form.date_premiere_echeance) > 27;
const navigate = useNavigate();
const [soldePlateforme, setSoldePlateforme] = useState(null);
const [soldeLoading, setSoldeLoading] = useState(false);
// Solde indicatif du porte-monnaie de la plateforme sélectionnée (jour même) — uniquement
// en création : à la création on choisit la plateforme en fonction du solde disponible,
// en édition l'investissement existe déjà donc l'indicateur n'a plus lieu d'être (demande
// Olivier 29/08/26).
useEffect(() => {
if (!open || editingId || !form.plateforme_id) {
setSoldePlateforme(null);
return;
}
let cancelled = false;
setSoldeLoading(true);
api.get('/dashboard/solde-historique', { plateforme_id: form.plateforme_id, date: today() })
.then(r => { if (!cancelled) setSoldePlateforme(r?.solde ?? null); })
.catch(() => { if (!cancelled) setSoldePlateforme(null); })
.finally(() => { if (!cancelled) setSoldeLoading(false); });
return () => { cancelled = true; };
}, [open, editingId, form.plateforme_id]);
const handleGoDeposit = () => {
// Sauvegarde la saisie en cours pour la restaurer au retour depuis Dépôts/Retraits
// (cf. DepotsRetraits.jsx maybeReturnToInvestissement + les effets "resumeInvestissement"
// dans Investissements.jsx / InvestissementDetail.jsx).
try {
sessionStorage.setItem('cl_investissement_draft', JSON.stringify({
returnTo: window.location.pathname + window.location.search,
editingId: editingId || null,
form,
}));
} catch {
// sessionStorage indisponible (mode privé, quota…) — tant pis, pas de retour auto,
// le dépôt reste faisable normalement.
}
onClose();
navigate(`/depots-retraits?new=1&plateforme_id=${form.plateforme_id}&resumeInvestissement=1`);
};
const handleMethodeChange = (methode) => {
const defaultCompte = methode === 'compte_courant'
? (comptesInvestisseur.find(c => c.type === 'compte_courant') ?? comptesInvestisseur[0])
@@ -261,6 +312,20 @@ export default function InvestissementFormModal({
<option value="">—</option>
{plats.map(p => <option key={p.id} value={p.id}>{p.nom}{multiDetenteur && p.investisseur_nom ? ` — ${p.investisseur_nom}` : ''}</option>)}
</select>
{!editingId && form.plateforme_id && (
<div style={{
display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8,
marginTop: 6, padding: '5px 10px', borderRadius: 6,
background: 'var(--surface-2)', fontSize: 'var(--fs-sm)',
}}>
<span style={{ color: 'var(--text-muted)' }}>
Porte-monnaie : {soldeLoading ? '…' : (soldePlateforme !== null ? fmtEUR(soldePlateforme) : '—')}
</span>
<button type="button" className="ghost" style={{ fontSize: 11, padding: '2px 8px' }} onClick={handleGoDeposit}>
Déposer
</button>
</div>
)}
</div>
<div>
<label>Détenteur *</label>