diff --git a/backend/app/routers/pv.py b/backend/app/routers/pv.py index d2e646a..ac67c31 100644 --- a/backend/app/routers/pv.py +++ b/backend/app/routers/pv.py @@ -121,6 +121,13 @@ async def modifier_pv( pv = result.scalar_one_or_none() if not pv: raise HTTPException(status_code=404, detail="PV introuvable") + if pv.approuve: + raise HTTPException( + status_code=400, + detail="Un PV adopté ne peut pas être modifié directement. Inscrivez la correction au PV d'une assemblée suivante.", + ) + if req.approuve is not None: + raise HTTPException(status_code=400, detail="Utilisez le processus d'adoption du PV") reunion = await db.get(Reunion, pv.reunion_id) if reunion: await verifier_reunion_non_cristallisee( diff --git a/docs/10_MANUEL_UTILISATEUR.md b/docs/10_MANUEL_UTILISATEUR.md index 4e6910b..90ab9aa 100644 --- a/docs/10_MANUEL_UTILISATEUR.md +++ b/docs/10_MANUEL_UTILISATEUR.md @@ -165,6 +165,8 @@ Le rapport du trésorier doit être adopté avant de décider du montant des con Les rapports cristallisés sont téléchargés depuis l'icône de rapport sur les tuiles concernées. +Un PV adopté ne se modifie pas directement. Si une correction est demandée après adoption, elle est inscrite au PV d'une assemblée suivante; le PV original demeure inchangé. + ## 13. Gouvernance Le module `Gouvernance` rassemble les propositions, réflexions en cours, rejets et décisions. diff --git a/frontend/src/pages/AssembleeAffaires.jsx b/frontend/src/pages/AssembleeAffaires.jsx index ea2a18c..bbb8f52 100644 --- a/frontend/src/pages/AssembleeAffaires.jsx +++ b/frontend/src/pages/AssembleeAffaires.jsx @@ -32,6 +32,7 @@ export default function AssembleeAffaires({ contexte = false }) { const [contenu, setContenu] = useState(''); const [pvPrecedent, setPvPrecedent] = useState(null); const [pvCorrection, setPvCorrection] = useState(''); + const [correctionPvAdopte, setCorrectionPvAdopte] = useState(''); const [adoption, setAdoption] = useState({ proposeur_id: '', secondeur_id: '' }); const [adoptionAssemblee, setAdoptionAssemblee] = useState({ proposeur_id: '', secondeur_id: '' }); const [don, setDon] = useState({ destination: 'District 87-16', montant: '', methode: 'VIREMENT', proposeur_id: '', secondeur_id: '' }); @@ -118,6 +119,7 @@ export default function AssembleeAffaires({ contexte = false }) { const precedent = precedents[0] || null; setPvPrecedent(precedent); setPvCorrection(precedent?.contenu || ''); + setCorrectionPvAdopte(''); setContenu(pvJour?.contenu || textePvAuto(precedent, propositions, resolutionsJour, postesVacants)); }, [ouverteId, pvs.length, propositions.length, resolutions.length, postesVacants.length]); @@ -324,6 +326,33 @@ export default function AssembleeAffaires({ contexte = false }) { } }; + const inscrireCorrectionPvAdopte = async () => { + const texte = correctionPvAdopte.trim(); + if (!reunionOuverte || !pvPrecedent || !texte) { + setError('Correction requise'); + return; + } + const datePv = pvPrecedent.date_reunion?.slice(0, 10) || 'date inconnue'; + const ajout = `Correction au procès-verbal du ${datePv}:\n${texte}`; + const nouveauContenu = [contenu.trim(), ajout].filter(Boolean).join('\n\n'); + setLoading(true); + setError(''); + try { + await api.post('/pv/', { + reunion_id: reunionOuverte.id, + contenu: nouveauContenu, + decisions: null, + }); + setContenu(nouveauContenu); + setCorrectionPvAdopte(''); + setMsg('Correction inscrite au PV courant'); + await charger(); + } catch (e) { + setError(e.message); + } + setLoading(false); + }; + const adopterAssemblee = async () => { if (!reunionOuverte) return; if (!adoptionAssemblee.proposeur_id || !adoptionAssemblee.secondeur_id) { @@ -438,7 +467,30 @@ export default function AssembleeAffaires({ contexte = false }) { ) : ( -
{pvPrecedent.contenu}
+{pvPrecedent.contenu}
+ {estExecutif && pvPrecedent.approuve && ( ++ Ce PV est adopté et ne peut pas être modifié. Une correction sera inscrite au PV courant. +
+