FixBug: Décalrage de date des prêts différés
This commit is contained in:
@@ -12,6 +12,8 @@ export default function DataCleanupSection() {
|
||||
const [loadingReprocess, setLoadingReprocess] = useState(false);
|
||||
const [showDiffereModal, setShowDiffereModal] = useState(false);
|
||||
const [loadingDiffere, setLoadingDiffere] = useState(false);
|
||||
const [showEcheancierModal, setShowEcheancierModal] = useState(false);
|
||||
const [loadingEcheancier, setLoadingEcheancier] = useState(false);
|
||||
const [showBackfillModal, setShowBackfillModal] = useState(false);
|
||||
const [loadingBackfill, setLoadingBackfill] = useState(false);
|
||||
const [successMsg, setSuccessMsg] = useState(null);
|
||||
@@ -54,13 +56,16 @@ export default function DataCleanupSection() {
|
||||
setErrorMsg(null);
|
||||
setSuccessMsg(null);
|
||||
try {
|
||||
const { updated, detail } = await api.post('/investissements/fix-differe-dates', {});
|
||||
const { updated, detail, statutsMisAJour } = await api.post('/investissements/fix-differe-dates', {});
|
||||
if (updated === 0) {
|
||||
setSuccessMsg('Aucune date incohérente détectée sur les prêts différés.');
|
||||
} else {
|
||||
const suffixeStatuts = statutsMisAJour > 0
|
||||
? ` (statut recalculé pour ${statutsMisAJour} prêt${statutsMisAJour > 1 ? 's' : ''} suite à la correction)`
|
||||
: '';
|
||||
setSuccessMsg(
|
||||
`${updated} prêt${updated > 1 ? 's' : ''} différé${updated > 1 ? 's' : ''} corrigé${updated > 1 ? 's' : ''} : ` +
|
||||
detail.map(d => d.nom_projet).join(', ') + '.'
|
||||
detail.map(d => d.nom_projet).join(', ') + '.' + suffixeStatuts
|
||||
);
|
||||
}
|
||||
setShowDiffereModal(false);
|
||||
@@ -72,6 +77,29 @@ export default function DataCleanupSection() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleCheckEcheancierDiffere = async () => {
|
||||
setLoadingEcheancier(true);
|
||||
setErrorMsg(null);
|
||||
setSuccessMsg(null);
|
||||
try {
|
||||
const { updated, detail } = await api.post('/investissements/check-echeancier-differe', {});
|
||||
if (updated === 0) {
|
||||
setSuccessMsg("Échéancier cohérent pour tous les prêts différés — rien à corriger.");
|
||||
} else {
|
||||
setSuccessMsg(
|
||||
`Échéancier régénéré pour ${updated} prêt${updated > 1 ? 's' : ''} différé${updated > 1 ? 's' : ''} : ` +
|
||||
detail.map(d => d.nom_projet).join(', ') + '.'
|
||||
);
|
||||
}
|
||||
setShowEcheancierModal(false);
|
||||
} catch (err) {
|
||||
setErrorMsg(err.message || 'Une erreur est survenue.');
|
||||
setShowEcheancierModal(false);
|
||||
} finally {
|
||||
setLoadingEcheancier(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBackfillComptes = async () => {
|
||||
setLoadingBackfill(true);
|
||||
setErrorMsg(null);
|
||||
@@ -148,6 +176,30 @@ export default function DataCleanupSection() {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between',
|
||||
padding: '14px 16px', borderRadius: 8,
|
||||
border: '1px solid var(--border)', background: 'var(--bg-secondary, var(--bg))',
|
||||
marginBottom: 10 }}>
|
||||
<div>
|
||||
<div style={{ fontWeight: 500, fontSize: 'var(--fs-sm)', marginBottom: 2 }}>
|
||||
Vérifier la cohérence de l'échéancier des prêts différés
|
||||
</div>
|
||||
<div className="text-muted" style={{ fontSize: 12 }}>
|
||||
Contrôle que l'échéancier de projection de chaque prêt différé comporte bien une unique
|
||||
échéance, à la date de 1ère échéance / date cible enregistrée sur le prêt. Régénère
|
||||
automatiquement l'échéancier en cas d'écart (ex. date corrigée sans mise à jour de la
|
||||
simulation).
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
style={{ marginLeft: 16, whiteSpace: 'nowrap', flexShrink: 0 }}
|
||||
onClick={() => setShowEcheancierModal(true)}
|
||||
disabled={loadingEcheancier}
|
||||
>
|
||||
Vérifier
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between',
|
||||
padding: '14px 16px', borderRadius: 8,
|
||||
border: '1px solid var(--border)', background: 'var(--bg-secondary, var(--bg))',
|
||||
@@ -222,6 +274,31 @@ export default function DataCleanupSection() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showEcheancierModal && (
|
||||
<div className="modal-overlay" onClick={() => setShowEcheancierModal(false)}>
|
||||
<div className="modal" style={{ maxWidth: 480 }} onClick={e => e.stopPropagation()}>
|
||||
<div className="modal-header" style={{ borderBottom: '1px solid var(--border)', paddingBottom: 12, marginBottom: 16 }}>
|
||||
<h3 style={{ margin: 0 }}>Vérifier la cohérence de l'échéancier des prêts différés</h3>
|
||||
</div>
|
||||
<p style={{ margin: '0 0 12px', lineHeight: 1.6 }}>
|
||||
Pour chaque prêt de type <strong>différé</strong>, cette opération vérifie que l'échéancier
|
||||
de projection (simulation de remboursement) contient bien une unique échéance, à la date
|
||||
enregistrée sur le prêt (1ère échéance / date cible).
|
||||
</p>
|
||||
<p style={{ margin: '0 0 20px', lineHeight: 1.6 }} className="text-muted">
|
||||
En cas d'écart (échéance manquante, en double, ou à une date différente de celle du prêt),
|
||||
l'échéancier est régénéré automatiquement à partir des données actuelles du prêt.
|
||||
</p>
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
|
||||
<button onClick={() => setShowEcheancierModal(false)} disabled={loadingEcheancier}>Annuler</button>
|
||||
<button className="primary" onClick={handleCheckEcheancierDiffere} disabled={loadingEcheancier}>
|
||||
{loadingEcheancier ? 'Vérification en cours…' : 'Lancer la vérification'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showBackfillModal && (
|
||||
<div className="modal-overlay" onClick={() => setShowBackfillModal(false)}>
|
||||
<div className="modal" style={{ maxWidth: 480 }} onClick={e => e.stopPropagation()}>
|
||||
|
||||
Reference in New Issue
Block a user