From a936e7ed81ea6fc08e0850fe8f88131382dc1ef1 Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Mon, 25 May 2026 17:39:38 -0400 Subject: [PATCH] =?UTF-8?q?derni=C3=A8re=20mouture?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + README.md | 48 +- ansible/group_vars/all.yml | 4 +- ansible/roles/app/templates/env.j2 | 4 +- .../nginx/templates/groupe-meditation.conf.j2 | 22 +- backend/app/core/audit.py | 78 ++ backend/app/core/config.py | 3 + backend/app/core/decisions.py | 24 + backend/app/core/reunions.py | 38 + backend/app/core/roles.py | 51 ++ backend/app/core/security.py | 12 +- backend/app/main.py | 24 +- backend/app/models/decision.py | 27 - backend/app/models/groupe.py | 1 + backend/app/models/journal_action.py | 22 + backend/app/models/membre.py | 4 + backend/app/models/mouvement_reserve.py | 20 + backend/app/models/option_sondage.py | 16 - backend/app/models/proposition.py | 7 +- backend/app/models/push_subscription.py | 22 + backend/app/models/sondage.py | 29 - backend/app/models/transaction_comptable.py | 23 + backend/app/models/vote.py | 16 - backend/app/routers/accueil.py | 57 +- backend/app/routers/auth.py | 22 +- backend/app/routers/collectes.py | 229 +++-- backend/app/routers/commandes_jetons.py | 4 +- backend/app/routers/contributions.py | 53 +- backend/app/routers/decisions.py | 110 --- backend/app/routers/depenses.py | 111 ++- backend/app/routers/evenements.py | 25 +- backend/app/routers/jetons.py | 6 +- backend/app/routers/journal.py | 41 + backend/app/routers/litterature.py | 4 +- backend/app/routers/notifications.py | 91 ++ backend/app/routers/operations_bancaires.py | 311 ++++--- backend/app/routers/parametres.py | 6 + backend/app/routers/postes.py | 21 +- backend/app/routers/presences.py | 43 +- backend/app/routers/propositions.py | 61 +- backend/app/routers/pv.py | 68 +- backend/app/routers/rapports.py | 400 +++++++-- backend/app/routers/rapports_rsg.py | 4 +- backend/app/routers/reunions.py | 28 +- backend/app/routers/sondages.py | 214 ----- backend/app/routers/ventes_litterature.py | 36 +- backend/app/schemas/phase1.py | 39 +- backend/app/schemas/phase3.py | 2 + backend/app/schemas/phase4.py | 5 + backend/app/schemas/phase8.py | 54 -- backend/app/schemas/propositions.py | 8 +- backend/app/schemas/schemas.py | 3 + backend/app/services/finance.py | 111 +++ backend/app/services/notifications.py | 76 ++ data/import/Rapport de trésorerie.xlsx | Bin 0 -> 116249 bytes deploy/seed.py | 42 +- docs/ANSIBLE.md | 6 + docs/ARCHITECTURE.md | 52 ++ docs/DEPLOIEMENT.md | 390 +-------- docs/Liste-de-prix-rev.-Fevrier-2026.pdf | Bin 0 -> 307104 bytes docs/RUNBOOK.md | 50 +- docs/UTILISATEURS.md | 89 +- frontend/public/push-sw.js | 24 + frontend/src/App.jsx | 74 +- frontend/src/components/BottomNav.jsx | 41 + frontend/src/components/MeetingDateSelect.jsx | 19 + frontend/src/components/PageHeader.jsx | 16 +- frontend/src/index.css | 16 + frontend/src/pages/Accueil.jsx | 179 +++- frontend/src/pages/AffecterPostes.jsx | 17 +- frontend/src/pages/AssembleeAffaires.jsx | 255 ++++++ frontend/src/pages/Collecte.jsx | 65 +- frontend/src/pages/Decisions.jsx | 355 ++++++-- frontend/src/pages/Depense.jsx | 268 ++---- frontend/src/pages/EnvoiContributions.jsx | 23 +- frontend/src/pages/EtatFinancier.jsx | 235 ++++-- frontend/src/pages/Evenements.jsx | 9 +- frontend/src/pages/GererMembres.jsx | 15 + frontend/src/pages/GererPostes.jsx | 81 +- frontend/src/pages/JournalActions.jsx | 63 ++ frontend/src/pages/LancerSondage.jsx | 163 ---- frontend/src/pages/Login.jsx | 19 +- frontend/src/pages/Parametres.jsx | 10 + frontend/src/pages/PlanifierRotations.jsx | 9 +- frontend/src/pages/Profil.jsx | 104 +++ frontend/src/pages/Propositions.jsx | 277 ------ frontend/src/pages/RapportReunion.jsx | 25 +- frontend/src/pages/Rapports.jsx | 21 +- frontend/src/pages/RemiseJeton.jsx | 20 +- frontend/src/pages/ReunionHebdomadaire.jsx | 207 +++++ frontend/src/pages/Tresorerie.jsx | 791 ++++++++++++++---- frontend/src/pages/VenteLitterature.jsx | 20 +- frontend/src/pages/VotesOuverts.jsx | 176 ---- frontend/src/stores/store.js | 31 + frontend/src/utils/datesReunion.js | 105 +++ frontend/src/utils/pushNotifications.js | 56 ++ frontend/vite.config.js | 3 + 97 files changed, 4245 insertions(+), 2916 deletions(-) create mode 100644 backend/app/core/audit.py create mode 100644 backend/app/core/decisions.py create mode 100644 backend/app/core/reunions.py create mode 100644 backend/app/core/roles.py delete mode 100644 backend/app/models/decision.py create mode 100644 backend/app/models/journal_action.py create mode 100644 backend/app/models/mouvement_reserve.py delete mode 100644 backend/app/models/option_sondage.py create mode 100644 backend/app/models/push_subscription.py delete mode 100644 backend/app/models/sondage.py create mode 100644 backend/app/models/transaction_comptable.py delete mode 100644 backend/app/models/vote.py delete mode 100644 backend/app/routers/decisions.py create mode 100644 backend/app/routers/journal.py create mode 100644 backend/app/routers/notifications.py delete mode 100644 backend/app/routers/sondages.py delete mode 100644 backend/app/schemas/phase8.py create mode 100644 backend/app/services/finance.py create mode 100644 backend/app/services/notifications.py create mode 100644 data/import/Rapport de trésorerie.xlsx create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/Liste-de-prix-rev.-Fevrier-2026.pdf create mode 100644 frontend/public/push-sw.js create mode 100644 frontend/src/components/BottomNav.jsx create mode 100644 frontend/src/components/MeetingDateSelect.jsx create mode 100644 frontend/src/pages/AssembleeAffaires.jsx create mode 100644 frontend/src/pages/JournalActions.jsx delete mode 100644 frontend/src/pages/LancerSondage.jsx delete mode 100644 frontend/src/pages/Propositions.jsx create mode 100644 frontend/src/pages/ReunionHebdomadaire.jsx delete mode 100644 frontend/src/pages/VotesOuverts.jsx create mode 100644 frontend/src/utils/datesReunion.js create mode 100644 frontend/src/utils/pushNotifications.js diff --git a/.gitignore b/.gitignore index 557d6ac..fb5bcbe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ node_modules/ dist/ +__pycache__/ +*.py[cod] *.retry ansible/group_vars/vault.yml diff --git a/README.md b/README.md index e082767..3fe26f7 100644 --- a/README.md +++ b/README.md @@ -11,29 +11,28 @@ Application mobile-first pour la gestion des groupes AA. 1 module = 1 tâche. | Frontend | React 18 + Vite (PWA installable) | | UI | Tailwind CSS (mobile-first) | | État | Zustand | -| Backend | FastAPI (Python) async, 82 routes | -| DB | PostgreSQL + SQLAlchemy async (23+ tables) | +| Backend | FastAPI (Python) async | +| DB | PostgreSQL + SQLAlchemy async | | Auth | JWT 30 jours + bcrypt 12 rounds (prénom + PIN) | | PDF | WeasyPrint | | Serveur | NGINX (statiques + reverse proxy HTTPS) | ## Modules -### Consultation (C1-C7) — Tous les membres +### Consultation — Tous les membres - **C1** Rapports PDF — finances, PV, résolutions, rapport complet -- **C2** Événements à venir — anniversaires de sobriété et événements ad hoc du district +- **C2** Événements — anniversaires de sobriété, événements et résolutions - **C4** Littérature — inventaire avec prix, alerte stock bas -- **C5** Décisions en cours — suivi des résolutions -- **C6** Votes ouverts — sondages de conscience de groupe, vote anonyme +- **C5** Gouvernance — décisions du groupe, propositions, résolutions, nominations et contributions - **C7** Mon profil — modifier, changer PIN, notifications -- **C8** Propositions — soumettre, seconder, voter (créables en tout temps) -- **C9** S'impliquer — postes vacants, candidatures +- **C9** Postes à pourvoir — postes vacants, candidatures ### Saisie hebdomadaire (S1-S5) -- **S1** Collecte 7e Tradition — saisie le jour de réunion, confirmation par un second membre, historique mensuel avec totaux -- **S1T** Trésorerie — soldes (banque + encaisse + disponible après réserves), réception des collectes et ventes de littérature, registre détaillé des transactions, opérations bancaires (dépôt/retrait/relevé) +- **S0** Réunion hebdomadaire — formulaire regroupé pour rapport, collecte, jeton et littérature +- **S1** Collecte 7e Tradition — réservé aux postes exécutifs +- **S1T** Trésorerie — soldes (banque + encaisse + réserves affectées), réception des collectes et ventes de littérature, registre détaillé des transactions, opérations bancaires (dépôt/retrait/relevé) - **S2** Remise de jeton — 9 types, historique - **S3** Vente littérature — stock auto-décrémenté, montant à remettre au trésorier - **S4** Rapport de réunion — thème + annonces @@ -41,6 +40,7 @@ Application mobile-first pour la gestion des groupes AA. 1 module = 1 tâche. ### Saisie mensuelle (M1-M6) +- **M0** Assemblée d'affaires — formulaire regroupé pour réunion, présences et PV - **M1** Rédiger PV — auto-renseigné depuis les propositions secondées, décisions structurées - **M2** Présences réunion d'affaires - **M3** Rapport RSG — template 3 sections @@ -50,27 +50,23 @@ Application mobile-first pour la gestion des groupes AA. 1 module = 1 tâche. ### Gestion — Exécutif -- **G1** Inviter un membre — code 48h -- **G2** Gérer les membres — fiche complète, droit à l'oubli -- **G6** Lancer un sondage — oui/non, choix multiple, unanimité +- **G2** Gestion des membres — membres, invitations, droit à l'oubli - **G9** Paramètres du groupe — nom, horaire, adresse, format - **G11** Gestion des mandats — affecter, terminer, planifier les rotations - **G12** Gestion des postes — créer, abolir, candidatures, accès aux modules ## Trésorerie -Le calcul des soldes repose sur le relevé bancaire mensuel : +La source de vérité financière est le registre `transactions_comptables`. -- **Solde banque** = dernier relevé + dépôts − retraits depuis le relevé -- **Disponible** = solde banque − engagements non débités − réserves -- **Réserves** = réserve prudente (500 $) + réserve anniversaire (20 $/mois) -- **Encaisse** = collectes reçues + ventes remises − dépôts − dépenses cash +- **Banque** et **encaisse** sont calculées depuis les écritures comptables. +- **Réserves** est calculé depuis l'historique `mouvements_reserves`. +- Toute dépense ou contribution par chèque/virement reste un engagement jusqu'à confirmation du débit. +- Les rapports mensuels doivent s'appuyer sur ce registre. -Toute dépense par chèque ou virement est un engagement. Le trésorier confirme le débit lorsque l'argent quitte effectivement le compte. +## Gouvernance -## Propositions et résolutions - -Les propositions peuvent être créées en tout temps par n'importe quel membre, sans nécessiter une réunion d'affaires. Le cycle est : proposée → secondée → votée (adoptée/rejetée). Lorsqu'adoptée, la proposition devient une résolution numérotée (RES-2026-001) et peut être associée à l'assemblée d'affaires lors du vote. +Les propositions peuvent être créées en tout temps par n'importe quel membre, sans type initial. Le cycle est : proposée → secondée → transformée en résolution par l'exécutif. Lorsqu'adoptée, la proposition devient une décision numérotée avec les préfixes `RES` (résolution), `NOM` (nomination) ou `DON` (contribution), et les sections « ÉTANT DONNÉ QUE » et « LE GROUPE A DÉCIDÉ DE ». Le PV de la réunion d'affaires s'auto-renseigne depuis les propositions secondées en attente de vote. @@ -87,9 +83,10 @@ Le PV de la réunion d'affaires s'auto-renseigne depuis les propositions second ``` backend/ API FastAPI (Python) app/ - core/ Config, DB, sécurité - models/ Modèles SQLAlchemy (23+ tables) - routers/ Routes API (26 groupes) + core/ Config, DB, sécurité, rôles, règles communes + services/ Logique métier réutilisable + models/ Modèles SQLAlchemy + routers/ Routes API schemas/ Schémas Pydantic frontend/ React + Vite + Tailwind src/ @@ -103,6 +100,7 @@ docs/ DEPLOIEMENT.md, RUNBOOK.md ## Documentation - [Guide utilisateur](docs/UTILISATEURS.md) +- [Architecture technique](docs/ARCHITECTURE.md) - [Déploiement Ansible](docs/ANSIBLE.md) - [Runbook d'exploitation](docs/RUNBOOK.md) diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index e1345ac..1df9dd3 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -33,6 +33,9 @@ groupe_meditation_database_url: >- groupe_meditation_cors_origins: - "https://{{ groupe_meditation_domain }}" groupe_meditation_invitation_expire_hours: 48 +groupe_meditation_vapid_public_key: "" +groupe_meditation_vapid_private_key_b64: "" +groupe_meditation_vapid_subject: "mailto:admin@{{ groupe_meditation_domain }}" # Initialisation applicative. Le seed existant est interactif; Ansible lui # fournit ces valeurs seulement si la base ne contient encore aucun groupe. @@ -52,4 +55,3 @@ groupe_meditation_certbot_email: admin@example.com # Sauvegardes. groupe_meditation_backup_dir: /var/backups/groupe-meditation groupe_meditation_backup_retention_days: 30 - diff --git a/ansible/roles/app/templates/env.j2 b/ansible/roles/app/templates/env.j2 index 959a268..5bf8f63 100644 --- a/ansible/roles/app/templates/env.j2 +++ b/ansible/roles/app/templates/env.j2 @@ -3,4 +3,6 @@ DATABASE_URL={{ groupe_meditation_database_url }} JWT_SECRET={{ groupe_meditation_jwt_secret }} CORS_ORIGINS={{ groupe_meditation_cors_origins | to_json }} INVITATION_EXPIRE_HOURS={{ groupe_meditation_invitation_expire_hours }} - +VAPID_PUBLIC_KEY={{ groupe_meditation_vapid_public_key }} +VAPID_PRIVATE_KEY_B64={{ groupe_meditation_vapid_private_key_b64 }} +VAPID_SUBJECT={{ groupe_meditation_vapid_subject }} diff --git a/ansible/roles/nginx/templates/groupe-meditation.conf.j2 b/ansible/roles/nginx/templates/groupe-meditation.conf.j2 index 5e6a345..d45f833 100644 --- a/ansible/roles/nginx/templates/groupe-meditation.conf.j2 +++ b/ansible/roles/nginx/templates/groupe-meditation.conf.j2 @@ -18,9 +18,24 @@ server { root {{ groupe_meditation_web_root }}; index index.html; + location = /index.html { + expires off; + add_header Cache-Control "no-cache, no-store, must-revalidate" always; + add_header Pragma "no-cache" always; + add_header Expires "0" always; + } + + location ~ ^/(sw\.js|push-sw\.js|registerSW\.js|manifest\.webmanifest)$ { + expires off; + add_header Cache-Control "no-cache, no-store, must-revalidate" always; + add_header Pragma "no-cache" always; + add_header Expires "0" always; + try_files $uri =404; + } + location ~* \.(js|css|png|jpg|svg|woff2|ico)$ { expires 1y; - add_header Cache-Control "public, immutable"; + add_header Cache-Control "public, immutable" always; try_files $uri =404; } @@ -28,10 +43,5 @@ server { try_files $uri $uri/ /index.html; } - location = /index.html { - add_header Cache-Control "no-cache, no-store, must-revalidate"; - } - client_max_body_size 5M; } - diff --git a/backend/app/core/audit.py b/backend/app/core/audit.py new file mode 100644 index 0000000..ea6b88f --- /dev/null +++ b/backend/app/core/audit.py @@ -0,0 +1,78 @@ +"""Journalisation automatique des changements API.""" +from jose import JWTError, jwt +from sqlalchemy import select +from starlette.middleware.base import BaseHTTPMiddleware + +from app.core.config import settings +from app.core.database import async_session +from app.models.journal_action import JournalAction +from app.models.membre import Membre +from app.services.notifications import notify_group_change + + +MUTATING_METHODS = {"POST", "PUT", "PATCH", "DELETE"} +SKIPPED_PREFIXES = ( + "/api/auth/connexion", + "/api/health", +) + + +def _token_payload(request): + header = request.headers.get("authorization") or "" + if not header.lower().startswith("bearer "): + return None + token = header.split(" ", 1)[1].strip() + try: + return jwt.decode(token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM]) + except JWTError: + return None + + +class AuditMiddleware(BaseHTTPMiddleware): + async def dispatch(self, request, call_next): + response = await call_next(request) + path = request.url.path + if ( + request.method not in MUTATING_METHODS + or not path.startswith("/api/") + or any(path.startswith(prefix) for prefix in SKIPPED_PREFIXES) + or response.status_code >= 400 + ): + return response + + payload = _token_payload(request) + if not payload or not payload.get("sub"): + return response + + async with async_session() as db: + membre = None + result = await db.execute(select(Membre).where(Membre.id == payload["sub"])) + membre = result.scalar_one_or_none() + if not membre: + return response + + details = { + "query": dict(request.query_params), + "impersonification": bool(payload.get("adm")), + } + db.add(JournalAction( + groupe_id=membre.groupe_id, + membre_id=membre.id, + admin_id=payload.get("adm"), + methode=request.method, + chemin=path, + statut_http=response.status_code, + adresse_ip=request.client.host if request.client else None, + user_agent=(request.headers.get("user-agent") or "")[:255] or None, + details=details, + )) + await notify_group_change( + db, + groupe_id=membre.groupe_id, + actor_id=membre.id, + title="Changement dans l'application", + body=f"{membre.prenom} a enregistré une modification.", + url="/", + ) + await db.commit() + return response diff --git a/backend/app/core/config.py b/backend/app/core/config.py index fd17bbd..906776f 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -17,6 +17,9 @@ class Settings(BaseSettings): "https://groupe-meditation.87-16.org", ] INVITATION_EXPIRE_HOURS: int = 48 + VAPID_PUBLIC_KEY: str | None = None + VAPID_PRIVATE_KEY_B64: str | None = None + VAPID_SUBJECT: str = "mailto:admin@groupe-meditation.local" class Config: env_file = str(_ENV_FILE) diff --git a/backend/app/core/decisions.py b/backend/app/core/decisions.py new file mode 100644 index 0000000..6ba70b9 --- /dev/null +++ b/backend/app/core/decisions.py @@ -0,0 +1,24 @@ +"""Utilitaires pour la numérotation des décisions du groupe.""" +from sqlalchemy import func, select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.models.proposition import Proposition + +PREFIXES_DECISION = { + "resolution": "RES", + "nomination": "NOM", + "contribution": "DON", +} + + +async def prochain_numero_decision(groupe_id, type_decision: str, annee: int, db: AsyncSession) -> str: + prefixe = PREFIXES_DECISION.get(type_decision, "RES") + result = await db.execute( + select(func.count(Proposition.id)).where( + Proposition.groupe_id == groupe_id, + Proposition.numero_resolution.isnot(None), + Proposition.numero_resolution.like(f"{prefixe}-{annee}-%"), + ) + ) + count = result.scalar() or 0 + return f"{prefixe}-{annee}-{count + 1:03d}" diff --git a/backend/app/core/reunions.py b/backend/app/core/reunions.py new file mode 100644 index 0000000..3bf94bb --- /dev/null +++ b/backend/app/core/reunions.py @@ -0,0 +1,38 @@ +"""Règles communes liées aux dates de réunion.""" +from datetime import date as dt_date +from calendar import monthrange + +JOURS_SEMAINE = { + "lundi": 0, + "mardi": 1, + "mercredi": 2, + "jeudi": 3, + "vendredi": 4, + "samedi": 5, + "dimanche": 6, +} + + +def jour_reunion_attendu(groupe) -> int | None: + if not getattr(groupe, "jour_reunion", None): + return None + return JOURS_SEMAINE.get(groupe.jour_reunion.lower()) + + +def date_correspond_au_jour_reunion(groupe, date_reunion: dt_date) -> bool: + jour = jour_reunion_attendu(groupe) + return True if jour is None else date_reunion.weekday() == jour + + +def date_assemblee_affaires_du_mois(annee: int, mois: int, jour_cible: int, ordre: str) -> dt_date: + dates = [] + for jour in range(1, monthrange(annee, mois)[1] + 1): + date = dt_date(annee, mois, jour) + if date.weekday() == jour_cible: + dates.append(date) + if not dates: + return dt_date(annee, mois, 1) + if ordre == "derniere": + return dates[-1] + index = {"premiere": 0, "deuxieme": 1, "troisieme": 2, "quatrieme": 3}.get(ordre, 0) + return dates[index] if index < len(dates) else dates[-1] diff --git a/backend/app/core/roles.py b/backend/app/core/roles.py new file mode 100644 index 0000000..5878cd0 --- /dev/null +++ b/backend/app/core/roles.py @@ -0,0 +1,51 @@ +"""Vérifications de rôles applicatifs.""" +from fastapi import Depends, HTTPException +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.core.database import get_db +from app.core.security import get_current_membre, is_sysadmin +from app.models.affectation import Affectation +from app.models.poste import Poste + + +async def membre_a_poste_ou_executif(membre_id, libelle_poste: str, db: AsyncSession) -> bool: + from app.models.membre import Membre + membre = await db.get(Membre, membre_id) + if membre and is_sysadmin(membre): + return True + result = await db.execute( + select(Affectation).join(Poste).where( + Affectation.membre_id == membre_id, + Affectation.statut == "actif", + (Poste.nom.ilike(f"%{libelle_poste}%") | (Poste.categorie == "executif")), + ) + ) + return result.scalars().first() is not None + + +async def require_tresorier( + membre=Depends(get_current_membre), + db: AsyncSession = Depends(get_db), +): + if not await membre_a_poste_ou_executif(membre.id, "trésorier", db): + raise HTTPException(status_code=403, detail="Réservé au trésorier ou à l'exécutif") + return membre + + +async def require_secretaire( + membre=Depends(get_current_membre), + db: AsyncSession = Depends(get_db), +): + if not await membre_a_poste_ou_executif(membre.id, "secrétaire", db): + raise HTTPException(status_code=403, detail="Réservé au secrétaire ou à l'exécutif") + return membre + + +async def require_rsg( + membre=Depends(get_current_membre), + db: AsyncSession = Depends(get_db), +): + if not await membre_a_poste_ou_executif(membre.id, "RSG", db): + raise HTTPException(status_code=403, detail="Réservé au RSG ou à l'exécutif") + return membre diff --git a/backend/app/core/security.py b/backend/app/core/security.py index b0c4fb6..4af9b2e 100644 --- a/backend/app/core/security.py +++ b/backend/app/core/security.py @@ -21,10 +21,12 @@ def verify_pin(pin: str, hashed: str) -> bool: return bcrypt.checkpw(pin.encode("utf-8"), hashed.encode("utf-8")) -def create_token(membre_id: str, groupe_id: str, expire_jours: int = None) -> str: +def create_token(membre_id: str, groupe_id: str, expire_jours: int = None, admin_id: str | None = None) -> str: jours = expire_jours or settings.JWT_EXPIRE_DAYS expire = datetime.now(timezone.utc) + timedelta(days=jours) payload = {"sub": str(membre_id), "grp": str(groupe_id), "exp": expire} + if admin_id: + payload["adm"] = str(admin_id) return jwt.encode(payload, settings.JWT_SECRET, algorithm=settings.JWT_ALGORITHM) @@ -35,6 +37,10 @@ def decode_token(token: str) -> dict: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token invalide ou expiré") +def is_sysadmin(membre) -> bool: + return bool(getattr(membre, "is_sysadmin", False)) + + async def get_current_membre( credentials: HTTPAuthorizationCredentials = Depends(security), db: AsyncSession = Depends(get_db), @@ -51,6 +57,8 @@ async def get_current_membre( raise HTTPException(status_code=401, detail="Membre introuvable ou inactif") if groupe_id and str(membre.groupe_id) != str(groupe_id): raise HTTPException(status_code=401, detail="Session invalide pour ce groupe") + if payload.get("adm"): + setattr(membre, "_sysadmin_session", True) return membre @@ -58,6 +66,8 @@ async def require_executif( membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db), ): + if is_sysadmin(membre): + return membre from app.models.affectation import Affectation from app.models.poste import Poste result = await db.execute( diff --git a/backend/app/main.py b/backend/app/main.py index b1aedf6..8da8579 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -6,10 +6,12 @@ District 87-16, Région 87 from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware +from sqlalchemy import text from app.core.config import settings +from app.core.audit import AuditMiddleware from app.core.database import engine, Base -from app.routers import auth, membres, postes, accueil, invitations, collectes, reunions, depenses, decisions, calendrier, rapports, rotations, parametres, presences, pv, rapports_rsg, jetons, anniversaires, commandes_jetons, litterature, ventes_litterature, contributions, config_repartition, sondages, propositions, operations_bancaires, evenements +from app.routers import auth, membres, postes, accueil, invitations, collectes, reunions, depenses, calendrier, rapports, rotations, parametres, presences, pv, rapports_rsg, jetons, anniversaires, commandes_jetons, litterature, ventes_litterature, contributions, config_repartition, propositions, operations_bancaires, evenements, notifications, journal # Import models pour que create_all crée toutes les tables from app.models.sync_log import SyncLog # noqa: F401 @@ -19,12 +21,27 @@ from app.models.evenement import Evenement # noqa: F401 from app.models.candidature import Candidature # noqa: F401 from app.models.poste_module import PosteModule # noqa: F401 from app.models.reserve import Reserve # noqa: F401 +from app.models.transaction_comptable import TransactionComptable # noqa: F401 +from app.models.mouvement_reserve import MouvementReserve # noqa: F401 +from app.models.journal_action import JournalAction # noqa: F401 +from app.models.push_subscription import PushSubscription # noqa: F401 @asynccontextmanager async def lifespan(app: FastAPI): async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) + await conn.execute(text( + "ALTER TABLE groupes " + "ADD COLUMN IF NOT EXISTS assemblee_affaires_ordre VARCHAR(20) DEFAULT 'premiere'" + )) + await conn.execute(text("ALTER TABLE propositions ADD COLUMN IF NOT EXISTS date_adoption DATE")) + await conn.execute(text("ALTER TABLE propositions ADD COLUMN IF NOT EXISTS etant_donne_que TEXT")) + await conn.execute(text("ALTER TABLE propositions ADD COLUMN IF NOT EXISTS groupe_a_decide_de TEXT")) + await conn.execute(text("DROP TABLE IF EXISTS votes")) + await conn.execute(text("DROP TABLE IF EXISTS options_sondage")) + await conn.execute(text("DROP TABLE IF EXISTS sondages")) + await conn.execute(text("DROP TABLE IF EXISTS decisions")) yield await engine.dispose() @@ -43,6 +60,7 @@ app.add_middleware( allow_methods=["*"], allow_headers=["*"], ) +app.add_middleware(AuditMiddleware) # Montage des routes app.include_router(auth.router, prefix="/api") @@ -53,7 +71,6 @@ app.include_router(invitations.router, prefix="/api") app.include_router(collectes.router, prefix="/api") app.include_router(reunions.router, prefix="/api") app.include_router(depenses.router, prefix="/api") -app.include_router(decisions.router, prefix="/api") app.include_router(calendrier.router, prefix="/api") app.include_router(rapports.router, prefix="/api") app.include_router(rotations.router, prefix="/api") @@ -68,10 +85,11 @@ app.include_router(litterature.router, prefix="/api") app.include_router(ventes_litterature.router, prefix="/api") app.include_router(contributions.router, prefix="/api") app.include_router(config_repartition.router, prefix="/api") -app.include_router(sondages.router, prefix="/api") app.include_router(propositions.router, prefix="/api") app.include_router(operations_bancaires.router, prefix="/api") app.include_router(evenements.router, prefix="/api") +app.include_router(notifications.router, prefix="/api") +app.include_router(journal.router, prefix="/api") @app.get("/api/health") diff --git a/backend/app/models/decision.py b/backend/app/models/decision.py deleted file mode 100644 index 0f1ee4a..0000000 --- a/backend/app/models/decision.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Table decisions — suivi des décisions de réunion d'affaires.""" -import uuid -from datetime import date, datetime, timezone -from sqlalchemy import String, Date, DateTime, Text, ForeignKey, Enum as SAEnum -from sqlalchemy.orm import Mapped, mapped_column -from app.core.database import Base - - -class Decision(Base): - __tablename__ = "decisions" - - id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4) - groupe_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("groupes.id"), nullable=False) - reunion_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("reunions.id")) - sujet: Mapped[str] = mapped_column(String(255), nullable=False) - description: Mapped[str | None] = mapped_column(Text) - statut: Mapped[str] = mapped_column( - SAEnum("en_attente", "en_cours", "complete", name="statut_decision"), - default="en_attente", - ) - responsable_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("membres.id")) - proposeur: Mapped[str | None] = mapped_column(String(100)) - secondeur: Mapped[str | None] = mapped_column(String(100)) - date_decision: Mapped[date] = mapped_column(Date, nullable=False) - date_completion: Mapped[date | None] = mapped_column(Date) - cree_par: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("membres.id")) - cree_le: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) diff --git a/backend/app/models/groupe.py b/backend/app/models/groupe.py index ef36382..f5b67e6 100644 --- a/backend/app/models/groupe.py +++ b/backend/app/models/groupe.py @@ -16,6 +16,7 @@ class Groupe(Base): adresse_local: Mapped[str | None] = mapped_column(Text) jour_reunion: Mapped[str | None] = mapped_column(String(10)) heure_reunion: Mapped[time | None] = mapped_column(Time) + assemblee_affaires_ordre: Mapped[str] = mapped_column(String(20), default="premiere") format_reunion: Mapped[str | None] = mapped_column(Text) lien_aa87: Mapped[str] = mapped_column(String(255), default="https://aa87.org") cree_le: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) diff --git a/backend/app/models/journal_action.py b/backend/app/models/journal_action.py new file mode 100644 index 0000000..5cf92af --- /dev/null +++ b/backend/app/models/journal_action.py @@ -0,0 +1,22 @@ +"""Journal d'audit des actions membres.""" +import uuid +from datetime import datetime, timezone +from sqlalchemy import String, DateTime, ForeignKey, JSON, Integer +from sqlalchemy.orm import Mapped, mapped_column +from app.core.database import Base + + +class JournalAction(Base): + __tablename__ = "journal_actions" + + id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4) + groupe_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("groupes.id"), index=True) + membre_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("membres.id"), index=True) + admin_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("membres.id"), index=True) + methode: Mapped[str] = mapped_column(String(10), nullable=False) + chemin: Mapped[str] = mapped_column(String(255), nullable=False) + statut_http: Mapped[int] = mapped_column(Integer, nullable=False) + adresse_ip: Mapped[str | None] = mapped_column(String(64)) + user_agent: Mapped[str | None] = mapped_column(String(255)) + details: Mapped[dict | None] = mapped_column(JSON) + cree_le: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), index=True) diff --git a/backend/app/models/membre.py b/backend/app/models/membre.py index 73c608e..4fe3943 100644 --- a/backend/app/models/membre.py +++ b/backend/app/models/membre.py @@ -27,3 +27,7 @@ class Membre(Base): groupe = relationship("Groupe", back_populates="membres") affectations = relationship("Affectation", back_populates="membre", foreign_keys="Affectation.membre_id") + + @property + def is_sysadmin(self) -> bool: + return (self.courriel or "").strip().lower() == "sysadmin" or bool(getattr(self, "_sysadmin_session", False)) diff --git a/backend/app/models/mouvement_reserve.py b/backend/app/models/mouvement_reserve.py new file mode 100644 index 0000000..8de9e49 --- /dev/null +++ b/backend/app/models/mouvement_reserve.py @@ -0,0 +1,20 @@ +"""Historique des mouvements entre réserves.""" +import uuid +from datetime import datetime, timezone +from sqlalchemy import DateTime, ForeignKey, Numeric, String, Text +from sqlalchemy.orm import Mapped, mapped_column +from app.core.database import Base + + +class MouvementReserve(Base): + __tablename__ = "mouvements_reserves" + + id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4) + groupe_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("groupes.id"), nullable=False) + source_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("reserves.id"), nullable=True) + destination_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("reserves.id"), nullable=True) + montant: Mapped[float] = mapped_column(Numeric(10, 2), nullable=False) + type: Mapped[str] = mapped_column(String(40), nullable=False) + note: Mapped[str | None] = mapped_column(Text) + cree_par: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("membres.id")) + cree_le: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) diff --git a/backend/app/models/option_sondage.py b/backend/app/models/option_sondage.py deleted file mode 100644 index 77b9fc1..0000000 --- a/backend/app/models/option_sondage.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Table options_sondage — Options de vote.""" -import uuid -from sqlalchemy import String, Integer, ForeignKey -from sqlalchemy.orm import Mapped, mapped_column, relationship -from app.core.database import Base - - -class OptionSondage(Base): - __tablename__ = "options_sondage" - - id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4) - sondage_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("sondages.id", ondelete="CASCADE"), nullable=False) - texte: Mapped[str] = mapped_column(String(200), nullable=False) - ordre: Mapped[int] = mapped_column(Integer, default=0) - - sondage = relationship("Sondage", back_populates="options") diff --git a/backend/app/models/proposition.py b/backend/app/models/proposition.py index 41f03ce..0014347 100644 --- a/backend/app/models/proposition.py +++ b/backend/app/models/proposition.py @@ -13,7 +13,7 @@ class Proposition(Base): groupe_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("groupes.id"), nullable=False) reunion_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("reunions.id"), nullable=True) type_proposition: Mapped[str] = mapped_column( - String(20), default="generale", # generale, nomination, contribution + String(20), default="proposition", # proposition, resolution, nomination, contribution ) sujet: Mapped[str] = mapped_column(String(255), nullable=False) description: Mapped[str | None] = mapped_column(Text) @@ -23,8 +23,11 @@ class Proposition(Base): SAEnum("proposee", "secondee", "adoptee", "rejetee", name="statut_proposition"), default="proposee", ) - numero_resolution: Mapped[str | None] = mapped_column(String(20)) # RES-2026-001 + numero_resolution: Mapped[str | None] = mapped_column(String(20)) # RES/NOM/DON-2026-001 date_vote: Mapped[date | None] = mapped_column(Date) + date_adoption: Mapped[date | None] = mapped_column(Date) + etant_donne_que: Mapped[str | None] = mapped_column(Text) + groupe_a_decide_de: Mapped[str | None] = mapped_column(Text) note: Mapped[str | None] = mapped_column(Text) # Lien vers la candidature (si type=nomination) candidature_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("candidatures.id")) diff --git a/backend/app/models/push_subscription.py b/backend/app/models/push_subscription.py new file mode 100644 index 0000000..598836a --- /dev/null +++ b/backend/app/models/push_subscription.py @@ -0,0 +1,22 @@ +"""Abonnements Web Push des appareils membres.""" +import uuid +from datetime import datetime, timezone +from sqlalchemy import String, DateTime, ForeignKey, JSON, UniqueConstraint +from sqlalchemy.orm import Mapped, mapped_column +from app.core.database import Base + + +class PushSubscription(Base): + __tablename__ = "push_subscriptions" + __table_args__ = ( + UniqueConstraint("endpoint", name="uq_push_subscription_endpoint"), + ) + + id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4) + groupe_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("groupes.id"), nullable=False, index=True) + membre_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("membres.id"), nullable=False, index=True) + endpoint: Mapped[str] = mapped_column(String(500), nullable=False) + abonnement: Mapped[dict] = mapped_column(JSON, nullable=False) + user_agent: Mapped[str | None] = mapped_column(String(255)) + cree_le: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) + modifie_le: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) diff --git a/backend/app/models/sondage.py b/backend/app/models/sondage.py deleted file mode 100644 index b89834e..0000000 --- a/backend/app/models/sondage.py +++ /dev/null @@ -1,29 +0,0 @@ -"""Table sondages — Votes de conscience de groupe.""" -import uuid -from datetime import datetime, timezone -from sqlalchemy import String, Text, DateTime, ForeignKey, Enum as SAEnum -from sqlalchemy.orm import Mapped, mapped_column, relationship -from app.core.database import Base - - -class Sondage(Base): - __tablename__ = "sondages" - - id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4) - groupe_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("groupes.id"), nullable=False) - titre: Mapped[str] = mapped_column(String(200), nullable=False) - description: Mapped[str | None] = mapped_column(Text) - type: Mapped[str] = mapped_column( - SAEnum("oui_non", "choix_multiple", "unanimite", name="type_sondage"), - nullable=False, - ) - cree_par: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("membres.id")) - date_ouverture: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) - date_fermeture: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) - statut: Mapped[str] = mapped_column( - SAEnum("brouillon", "ouvert", "ferme", name="statut_sondage"), - default="brouillon", - ) - cree_le: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) - - options = relationship("OptionSondage", back_populates="sondage", cascade="all, delete-orphan") diff --git a/backend/app/models/transaction_comptable.py b/backend/app/models/transaction_comptable.py new file mode 100644 index 0000000..60e269b --- /dev/null +++ b/backend/app/models/transaction_comptable.py @@ -0,0 +1,23 @@ +"""Registre comptable central.""" +import uuid +from datetime import date, datetime, timezone +from sqlalchemy import Date, DateTime, ForeignKey, Numeric, String, Text +from sqlalchemy.orm import Mapped, mapped_column +from app.core.database import Base + + +class TransactionComptable(Base): + __tablename__ = "transactions_comptables" + + id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4) + groupe_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("groupes.id"), nullable=False) + date_transaction: Mapped[date] = mapped_column(Date, nullable=False) + type: Mapped[str] = mapped_column(String(40), nullable=False) + compte: Mapped[str] = mapped_column(String(40), nullable=False) + montant: Mapped[float] = mapped_column(Numeric(10, 2), nullable=False) + sens: Mapped[str] = mapped_column(String(10), nullable=False) # debit ou credit + source_table: Mapped[str | None] = mapped_column(String(80)) + source_id: Mapped[uuid.UUID | None] = mapped_column(nullable=True) + note: Mapped[str | None] = mapped_column(Text) + cree_par: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("membres.id")) + cree_le: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) diff --git a/backend/app/models/vote.py b/backend/app/models/vote.py deleted file mode 100644 index e04d850..0000000 --- a/backend/app/models/vote.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Table votes — Votes anonymes.""" -import uuid -from datetime import datetime, timezone -from sqlalchemy import DateTime, ForeignKey -from sqlalchemy.orm import Mapped, mapped_column -from app.core.database import Base - - -class Vote(Base): - __tablename__ = "votes" - - id: Mapped[uuid.UUID] = mapped_column(primary_key=True, default=uuid.uuid4) - sondage_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("sondages.id", ondelete="CASCADE"), nullable=False) - option_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("options_sondage.id", ondelete="CASCADE"), nullable=False) - membre_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("membres.id"), nullable=False) - vote_le: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) diff --git a/backend/app/routers/accueil.py b/backend/app/routers/accueil.py index 784f141..7bc78f5 100644 --- a/backend/app/routers/accueil.py +++ b/backend/app/routers/accueil.py @@ -4,7 +4,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.core.database import get_db -from app.core.security import get_current_membre +from app.core.security import get_current_membre, is_sysadmin from app.models.affectation import Affectation from app.models.poste import Poste from app.models.groupe import Groupe @@ -18,26 +18,24 @@ MODULES_CONSULTATION = [ ModuleTuile(code="C1", nom="Rapports PDF", description="Finances, PV, résolutions", icone="📄", couleur="blue"), ModuleTuile(code="C2", nom="Événements", description="Anniversaires et événements", icone="📅", couleur="green"), ModuleTuile(code="C4", nom="Littérature", description="Inventaire et prix", icone="📚", couleur="purple"), - ModuleTuile(code="C5", nom="Décisions en cours", description="Suivi réunion d'affaires", icone="📌", couleur="red"), - ModuleTuile(code="C6", nom="Votes ouverts", description="Conscience de groupe", icone="🗳️", couleur="indigo"), + ModuleTuile(code="C5", nom="Gouvernance", description="Décisions du groupe", icone="📌", couleur="red"), ModuleTuile(code="C7", nom="Mon profil", description="Modifier, PIN, notifications", icone="👤", couleur="gray"), - ModuleTuile(code="C8", nom="Propositions", description="Soumettre, seconder, résolutions", icone="📋", couleur="orange"), ModuleTuile(code="C9", nom="Postes à pourvoir", description="Postes disponibles, candidature", icone="🙋", couleur="yellow"), - ModuleTuile(code="C10", nom="État financier", description="Résultats et transactions", icone="📊", couleur="blue"), + ModuleTuile(code="S1T", nom="Trésorerie", description="État des résultats, soldes, registre", icone="🏦", couleur="green"), ] MODULES_PAR_CODE = {m.code: m for m in MODULES_CONSULTATION} +MODULES_PAR_CODE["S0"] = ModuleTuile(code="S0", nom="Rencontre hebdomadaire", description="Saisies du contexte régulier", icone="🗓️", couleur="green") +MODULES_PAR_CODE["M0"] = ModuleTuile(code="M0", nom="Assemblée d'affaires", description="Présences et procès-verbal", icone="🏛️", couleur="indigo") +MODULES_PAR_CODE["S1"] = ModuleTuile(code="S1", nom="Collecte 7e", description="Saisir le panier", icone="💰", couleur="green") -# Modules de saisie visibles par TOUS les membres MODULES_SAISIE_TOUS = [ - ModuleTuile(code="S1", nom="Collecte 7e", description="Saisir le panier", icone="💰", couleur="green"), ModuleTuile(code="S5", nom="Dépense", description="Soumettre une dépense", icone="💸", couleur="red"), ] # Modules de saisie par poste MODULES_SAISIE = { "Trésorier(ière)": [ - ModuleTuile(code="S1T", nom="Trésorerie", description="Réceptions, dépôts, soldes", icone="🏦", couleur="green"), ModuleTuile(code="M4", nom="Envoi contributions", description="District, région, BSG", icone="📮", couleur="blue"), ], "Secrétaire": [ @@ -65,10 +63,10 @@ MODULES_SAISIE = { MODULES_GESTION = [ ModuleTuile(code="G2", nom="Gestion des membres", description="Membres, invitations, désactivation", icone="👥", couleur="blue"), - ModuleTuile(code="G6", nom="Lancer un sondage", description="Conscience de groupe", icone="📊", couleur="indigo"), ModuleTuile(code="G9", nom="Paramètres groupe", description="Nom, horaire, adresse", icone="🔧", couleur="gray"), ModuleTuile(code="G11", nom="Gestion des mandats", description="Affecter, terminer, rotations", icone="🎯", couleur="purple"), ModuleTuile(code="G12", nom="Gestion des postes", description="Postes, candidatures, accès", icone="📋", couleur="purple"), + ModuleTuile(code="G13", nom="Journal", description="Changements enregistrés", icone="🧾", couleur="gray"), ] for _modules in [MODULES_SAISIE_TOUS, MODULES_GESTION, *MODULES_SAISIE.values()]: @@ -82,6 +80,34 @@ async def accueil( db: AsyncSession = Depends(get_db), ): """Écran d'accueil dynamique — retourne les modules selon les postes du membre.""" + if is_sysadmin(membre): + modules_saisie_sysadmin = [] + codes_vus = set() + for module in [MODULES_PAR_CODE["S1"], MODULES_PAR_CODE["S0"], MODULES_PAR_CODE["M0"], *MODULES_SAISIE_TOUS, *[m for mods in MODULES_SAISIE.values() for m in mods]]: + if module.code not in codes_vus: + modules_saisie_sysadmin.append(module) + codes_vus.add(module.code) + groupe = await db.get(Groupe, membre.groupe_id) + groupe_info = None + if groupe: + groupe_info = { + "id": str(groupe.id), + "nom": groupe.nom, + "jour_reunion": groupe.jour_reunion, + "heure_reunion": groupe.heure_reunion.strftime("%H:%M") if groupe.heure_reunion else None, + "assemblee_affaires_ordre": groupe.assemblee_affaires_ordre, + "adresse_local": groupe.adresse_local, + } + return AccueilResponse( + membre=MembrePublic.model_validate(membre), + postes=["Sysadmin"], + est_executif=True, + modules_consultation=MODULES_CONSULTATION, + modules_saisie=modules_saisie_sysadmin, + modules_gestion=MODULES_GESTION, + groupe=groupe_info, + ) + # Récupérer les affectations actives result = await db.execute( select(Affectation).join(Poste).where( @@ -106,13 +132,15 @@ async def accueil( # Modules de saisie : collecte pour tous + modules par poste modules_saisie = list(MODULES_SAISIE_TOUS) - codes_vus = {"S1", "S5"} + codes_vus = {"S5"} result = await db.execute(select(PosteModule).where(PosteModule.poste_id.in_(poste_ids))) if poste_ids else None modules_configures = result.scalars().all() if result else [] if modules_configures: codes = sorted({pm.module_code for pm in modules_configures}) for code in codes: + if code == "S1" and "executif" not in postes_categories: + continue m = MODULES_PAR_CODE.get(code) if m and not code.startswith("G") and m.code not in codes_vus: modules_saisie.append(m) @@ -123,6 +151,13 @@ async def accueil( if m.code not in codes_vus: modules_saisie.append(m) codes_vus.add(m.code) + if "executif" in postes_categories and "S1" not in codes_vus: + modules_saisie.insert(0, MODULES_PAR_CODE["M0"]) + modules_saisie.insert(0, MODULES_PAR_CODE["S0"]) + modules_saisie.insert(0, ModuleTuile(code="S1", nom="Collecte 7e", description="Saisir le panier", icone="💰", couleur="green")) + codes_vus.add("S1") + codes_vus.add("S0") + codes_vus.add("M0") # Modules de gestion : seulement si exécutif if modules_configures: @@ -143,12 +178,14 @@ async def accueil( "nom": groupe.nom, "jour_reunion": groupe.jour_reunion, "heure_reunion": groupe.heure_reunion.strftime("%H:%M") if groupe.heure_reunion else None, + "assemblee_affaires_ordre": groupe.assemblee_affaires_ordre, "adresse_local": groupe.adresse_local, } return AccueilResponse( membre=MembrePublic.model_validate(membre), postes=postes_noms, + est_executif="executif" in postes_categories, modules_consultation=modules_consultation, modules_saisie=modules_saisie, modules_gestion=modules_gestion, diff --git a/backend/app/routers/auth.py b/backend/app/routers/auth.py index fce6d16..67f22c9 100644 --- a/backend/app/routers/auth.py +++ b/backend/app/routers/auth.py @@ -5,7 +5,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func from app.core.database import get_db -from app.core.security import hash_pin, verify_pin, create_token +from app.core.security import get_current_membre, hash_pin, verify_pin, create_token, is_sysadmin from app.models.membre import Membre from app.models.groupe import Groupe from app.models.invitation import Invitation @@ -36,6 +36,7 @@ async def liste_groupes(db: AsyncSession = Depends(get_db)): "adresse_local": g.adresse_local, "jour_reunion": g.jour_reunion, "heure_reunion": g.heure_reunion.strftime("%H:%M") if g.heure_reunion else None, + "assemblee_affaires_ordre": g.assemblee_affaires_ordre, "format_reunion": g.format_reunion, } for g in groupes] @@ -63,6 +64,25 @@ async def connexion(req: ConnexionRequest, db: AsyncSession = Depends(get_db)): ) +@router.post("/impersoner/{membre_id}", response_model=TokenResponse) +async def impersoner_membre( + membre_id: str, + admin=Depends(get_current_membre), + db: AsyncSession = Depends(get_db), +): + if not is_sysadmin(admin): + raise HTTPException(status_code=403, detail="Réservé au sysadmin") + cible = await db.get(Membre, membre_id) + if not cible or cible.groupe_id != admin.groupe_id or not cible.actif: + raise HTTPException(status_code=404, detail="Membre introuvable ou inactif") + setattr(cible, "_sysadmin_session", True) + token = create_token(str(cible.id), str(cible.groupe_id), admin_id=str(admin.id)) + return TokenResponse( + access_token=token, + membre=MembrePublic.model_validate(cible), + ) + + @router.post("/inscription", response_model=TokenResponse) async def inscription(req: InscriptionRequest, db: AsyncSession = Depends(get_db)): # Valider le code d'invitation diff --git a/backend/app/routers/collectes.py b/backend/app/routers/collectes.py index 7a7be62..4c8afbc 100644 --- a/backend/app/routers/collectes.py +++ b/backend/app/routers/collectes.py @@ -1,11 +1,13 @@ """Routes S1 — Collecte 7e Tradition.""" -from datetime import date, datetime, time as dt_time, timezone +from datetime import date, datetime, time as dt_time, timedelta, timezone from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, desc, extract, func from app.core.database import get_db -from app.core.security import get_current_membre, require_executif +from app.core.roles import membre_a_poste_ou_executif, require_tresorier +from app.core.reunions import JOURS_SEMAINE +from app.core.security import get_current_membre, require_executif, is_sysadmin from app.models.collecte import Collecte from app.models.groupe import Groupe from app.models.membre import Membre @@ -13,34 +15,16 @@ from app.models.depense import Depense from app.models.envoi_contribution import EnvoiContribution from app.models.operation_bancaire import OperationBancaire from app.models.reserve import Reserve -from app.models.affectation import Affectation -from app.models.poste import Poste +from app.models.mouvement_reserve import MouvementReserve from app.schemas.phase1 import CollecteCreate, CollecteOut, CollecteUpdate, SoldesOut +from app.services.finance import encaisse, solde_banque, solde_reserve, transaction router = APIRouter(prefix="/collectes", tags=["S1 — Collecte 7e Tradition"]) -JOURS_SEMAINE = { - "lundi": 0, "mardi": 1, "mercredi": 2, "jeudi": 3, - "vendredi": 4, "samedi": 5, "dimanche": 6, -} - async def _est_tresorier(membre_id, groupe_id, db: AsyncSession) -> bool: """Vérifie si un membre est trésorier ou exécutif.""" - result = await db.execute( - select(Affectation).join(Poste).where( - Affectation.membre_id == membre_id, - Affectation.statut == "actif", - (Poste.nom.ilike("%trésorier%") | (Poste.categorie == "executif")), - ) - ) - return result.scalars().first() is not None - - -async def _require_tresorier(membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db)): - if not await _est_tresorier(membre.id, membre.groupe_id, db): - raise HTTPException(status_code=403, detail="Réservé au trésorier ou à l'exécutif") - return membre + return await membre_a_poste_ou_executif(membre_id, "trésorier", db) async def _to_out(c: Collecte, db: AsyncSession) -> CollecteOut: @@ -66,28 +50,41 @@ async def _to_out(c: Collecte, db: AsyncSession) -> CollecteOut: @router.post("/", response_model=CollecteOut) async def saisir_collecte( req: CollecteCreate, - membre=Depends(get_current_membre), + membre=Depends(require_executif), db: AsyncSession = Depends(get_db), ): - """S1 — N'importe quel membre saisit la collecte. Rétroactif possible sur les dates de réunion.""" + """S1 — Un membre exécutif saisit la collecte.""" groupe = await db.get(Groupe, membre.groupe_id) aujourdhui = date.today() + retro_sysadmin = is_sysadmin(membre) # Validation : pas dans le futur - if req.date_collecte > aujourdhui: + if req.date_collecte > aujourdhui and not retro_sysadmin: raise HTTPException(status_code=400, detail="La date ne peut pas être dans le futur") # Validation : la date doit tomber un jour de réunion if groupe.jour_reunion: jour_attendu = JOURS_SEMAINE.get(groupe.jour_reunion.lower()) - if jour_attendu is not None and req.date_collecte.weekday() != jour_attendu: + if jour_attendu is not None and req.date_collecte.weekday() != jour_attendu and not retro_sysadmin: raise HTTPException( status_code=400, detail=f"La collecte doit avoir lieu un {groupe.jour_reunion}", ) + if jour_attendu is not None and not retro_sysadmin: + dernieres_reunions = [] + d = aujourdhui + while len(dernieres_reunions) < 52: + if d.weekday() == jour_attendu: + dernieres_reunions.append(d) + d -= timedelta(days=1) + if req.date_collecte not in dernieres_reunions: + raise HTTPException( + status_code=400, + detail="La date doit faire partie des 52 dernières rencontres du groupe", + ) # Validation : si c'est aujourd'hui, pas avant l'heure de la réunion - if req.date_collecte == aujourdhui and groupe.heure_reunion: + if req.date_collecte == aujourdhui and groupe.heure_reunion and not retro_sysadmin: now = datetime.now(timezone.utc) if isinstance(groupe.heure_reunion, dt_time) and now.time() < groupe.heure_reunion: raise HTTPException( @@ -126,10 +123,10 @@ async def saisir_collecte( async def ajuster_collecte( collecte_id: str, req: CollecteUpdate, - membre=Depends(get_current_membre), + membre=Depends(require_executif), db: AsyncSession = Depends(get_db), ): - """Ajuster le montant (exécutif ou celui qui a saisi, avant confirmation).""" + """Ajuster le montant avant confirmation.""" result = await db.execute( select(Collecte).where( Collecte.id == collecte_id, @@ -142,11 +139,6 @@ async def ajuster_collecte( if collecte.statut != "en_attente": raise HTTPException(status_code=400, detail="Le montant ne peut plus être modifié après confirmation") - # Vérifier : exécutif ou saisi_par - est_exec = await _est_tresorier(membre.id, membre.groupe_id, db) - if collecte.saisi_par != membre.id and not est_exec: - raise HTTPException(status_code=403, detail="Seul un exécutif ou la personne qui a saisi peut modifier") - if req.montant is not None: collecte.montant = req.montant await db.flush() @@ -156,7 +148,7 @@ async def ajuster_collecte( @router.post("/{collecte_id}/confirmer", response_model=CollecteOut) async def confirmer_collecte( collecte_id: str, - membre=Depends(get_current_membre), + membre=Depends(require_executif), db: AsyncSession = Depends(get_db), ): """Un second membre confirme le montant. Si le trésorier est impliqué → réception auto.""" @@ -186,6 +178,7 @@ async def confirmer_collecte( collecte.statut = "recu" collecte.recu_par = tresorier_id collecte.date_reception = date.today() + db.add(transaction(collecte.groupe_id, tresorier_id, collecte.date_collecte, "collecte", "encaisse", collecte.montant, "debit", "collectes", collecte.id, "Collecte reçue")) else: collecte.statut = "confirmee" @@ -196,7 +189,7 @@ async def confirmer_collecte( @router.post("/{collecte_id}/reception", response_model=CollecteOut) async def accuser_reception( collecte_id: str, - membre=Depends(_require_tresorier), + membre=Depends(require_tresorier), db: AsyncSession = Depends(get_db), ): """Le trésorier accuse réception (pour les cas sans trésorier impliqué).""" @@ -220,6 +213,7 @@ async def accuser_reception( collecte.statut = "recu" collecte.recu_par = membre.id collecte.date_reception = date.today() + db.add(transaction(collecte.groupe_id, membre.id, collecte.date_collecte, "collecte", "encaisse", collecte.montant, "debit", "collectes", collecte.id, "Collecte reçue")) await db.flush() return await _to_out(collecte, db) @@ -230,7 +224,7 @@ async def liste_collectes( mois: int | None = None, annee: int | None = None, limite: int = 20, - membre=Depends(get_current_membre), + membre=Depends(require_executif), db: AsyncSession = Depends(get_db), ): query = select(Collecte).where(Collecte.groupe_id == membre.groupe_id) @@ -257,8 +251,6 @@ async def soldes_tresorerie( from app.models.vente_litterature import VenteLitterature gid = membre.groupe_id - - # ── Dernier relevé bancaire ── result = await db.execute( select(OperationBancaire).where( OperationBancaire.groupe_id == gid, @@ -266,54 +258,10 @@ async def soldes_tresorerie( ).order_by(desc(OperationBancaire.date_operation)).limit(1) ) dernier_releve = result.scalar_one_or_none() - solde_releve = float(dernier_releve.montant) if dernier_releve else 0.0 date_releve = str(dernier_releve.date_operation) if dernier_releve else None - # ── Dépôts et retraits depuis le dernier relevé ── - filtre_depuis = dernier_releve.date_operation if dernier_releve else None - - # Dépôts après relevé - q = select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == gid, - OperationBancaire.type == "depot", - ) - if filtre_depuis: - q = q.where(OperationBancaire.date_operation > filtre_depuis) - result = await db.execute(q) - depots_depuis = float(result.scalar()) - - # Retraits après relevé - q = select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == gid, - OperationBancaire.type == "retrait", - ) - if filtre_depuis: - q = q.where(OperationBancaire.date_operation > filtre_depuis) - result = await db.execute(q) - retraits_depuis = float(result.scalar()) - - # Contributions débitées après relevé - q = select(func.coalesce(func.sum(EnvoiContribution.montant), 0)).where( - EnvoiContribution.groupe_id == gid, - EnvoiContribution.debitee == True, - ) - if filtre_depuis: - q = q.where(EnvoiContribution.date_envoi > filtre_depuis) - result = await db.execute(q) - contributions_debitees_depuis = float(result.scalar()) - - # Dépenses bancaires débitées après relevé - q = select(func.coalesce(func.sum(Depense.montant), 0)).where( - Depense.groupe_id == gid, - Depense.paye == True, - Depense.methode.in_(["VIREMENT", "CHEQUE"]), - ) - if filtre_depuis: - q = q.where(Depense.date_confirmation > filtre_depuis) - result = await db.execute(q) - depenses_bancaires_depuis = float(result.scalar()) - - solde_banque = solde_releve + depots_depuis - retraits_depuis - contributions_debitees_depuis - depenses_bancaires_depuis + solde_banque_actuel = await solde_banque(gid, db) + encaisse_actuelle = await encaisse(gid, db) # ── Dépenses engagées non payées (chèque/virement votés mais pas encore débités) ── result = await db.execute( @@ -336,7 +284,6 @@ async def soldes_tresorerie( contributions_non_debitees = float(result.scalar()) engagements_non_debites += contributions_non_debitees - # ── Réserves ── result = await db.execute( select(Reserve).where( Reserve.groupe_id == gid, @@ -344,49 +291,20 @@ async def soldes_tresorerie( ).order_by(Reserve.nom) ) reserves = result.scalars().all() - reserves_details = [ - { + reserves_details = [] + for r in reserves: + montant = await solde_reserve(r.id, db) + r.montant = montant + reserves_details.append({ "id": str(r.id), "nom": r.nom, - "montant": float(r.montant), + "montant": round(montant, 2), "note": r.note, - } - for r in reserves - ] - total_reserves = sum(r["montant"] for r in reserves_details) + }) + total_reserves_reelles = sum(r["montant"] for r in reserves_details) # ── Somme disponible ── - disponible = solde_banque - engagements_non_debites - total_reserves - - # ── Encaisse (cash reçu par le trésorier, pas déposé) ── - result = await db.execute( - select(func.coalesce(func.sum(Collecte.montant), 0)).where( - Collecte.groupe_id == gid, Collecte.statut == "recu")) - total_collectes_recues = float(result.scalar()) - - result = await db.execute( - select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == gid, OperationBancaire.type == "depot")) - total_depots = float(result.scalar()) - - result = await db.execute( - select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == gid, OperationBancaire.type == "retrait")) - total_retraits = float(result.scalar()) - - result = await db.execute( - select(func.coalesce(func.sum(Depense.montant), 0)).where( - Depense.groupe_id == gid, Depense.paye == True, Depense.methode == "COLLECTE")) - depenses_cash = float(result.scalar()) - - # Ventes de littérature remises au trésorier - result = await db.execute( - select(func.coalesce(func.sum(VenteLitterature.montant), 0)).where( - VenteLitterature.groupe_id == gid, VenteLitterature.remis_tresorier == True)) - ventes_recues = float(result.scalar()) - - encaisse = total_collectes_recues + ventes_recues + total_retraits - total_depots - depenses_cash - + disponible = solde_banque_actuel + encaisse_actuelle - engagements_non_debites - total_reserves_reelles # ── Argent en circulation (collectes non remises au trésorier) ── result = await db.execute( select(Collecte).where( @@ -398,6 +316,7 @@ async def soldes_tresorerie( det = await db.get(Membre, c.detenteur_id) if c.detenteur_id else None total_en_circulation += float(c.montant) details_circulation.append({ + "id": str(c.id), "date": str(c.date_collecte), "montant": float(c.montant), "detenteur": det.prenom if det else "?", @@ -428,14 +347,15 @@ async def soldes_tresorerie( }) return { - "solde_banque": round(solde_banque, 2), + "solde_banque": round(solde_banque_actuel, 2), "date_releve": date_releve, - "encaisse": round(encaisse, 2), + "encaisse": round(encaisse_actuelle, 2), "disponible": round(disponible, 2), "engagements_non_debites": round(engagements_non_debites, 2), "reserve_prudente": 0, "reserve_anniversaire": 0, - "total_reserves": round(total_reserves, 2), + "total_reserves": round(total_reserves_reelles, 2), + "total_reserves_reelles": round(total_reserves_reelles, 2), "reserves_details": reserves_details, "en_possession": round(total_en_circulation, 2), "en_possession_details": details_circulation, @@ -455,9 +375,11 @@ async def registre_transactions( """Registre détaillé de toutes les transactions financières du groupe.""" from app.models.vente_litterature import VenteLitterature from app.models.litterature import Litterature + from app.models.transaction_comptable import TransactionComptable gid = membre.groupe_id transactions = [] + dons_operation_ids = set() # Filtres date def filtre_mois(d): @@ -544,7 +466,30 @@ async def registre_transactions( "par": "Trésorier", }) - # 5. Opérations bancaires (dépôts/retraits) + # 5. Dons déposés directement à la banque + result = await db.execute( + select(TransactionComptable).where( + TransactionComptable.groupe_id == gid, + TransactionComptable.type == "don", + TransactionComptable.compte == "banque", + TransactionComptable.sens == "debit", + ).order_by(TransactionComptable.date_transaction) + ) + for don in result.scalars().all(): + if filtre_mois(don.date_transaction): + m = await db.get(Membre, don.cree_par) if don.cree_par else None + if don.source_id: + dons_operation_ids.add(don.source_id) + ajouter_transaction({ + "date": str(don.date_transaction), + "type": "don", + "description": f"Don déposé directement{(' — ' + don.note) if don.note else ''}", + "entree": float(don.montant), + "sortie": 0, + "par": m.prenom if m else "?", + }) + + # 6. Opérations bancaires (dépôts/retraits) result = await db.execute( select(OperationBancaire).where( OperationBancaire.groupe_id == gid, @@ -552,6 +497,8 @@ async def registre_transactions( ).order_by(OperationBancaire.date_operation) ) for op in result.scalars().all(): + if op.id in dons_operation_ids: + continue if filtre_mois(op.date_operation): m = await db.get(Membre, op.effectue_par) is_depot = op.type == "depot" @@ -564,5 +511,27 @@ async def registre_transactions( "par": m.prenom if m else "?", }) - transactions.sort(key=lambda t: t["date"]) + # 7. Mouvements virtuels entre le disponible et les réserves + result = await db.execute( + select(MouvementReserve).where(MouvementReserve.groupe_id == gid) + .order_by(MouvementReserve.cree_le) + ) + for mv in result.scalars().all(): + date_mouvement = mv.cree_le.date() + if filtre_mois(date_mouvement): + source = await db.get(Reserve, mv.source_id) if mv.source_id else None + destination = await db.get(Reserve, mv.destination_id) if mv.destination_id else None + createur = await db.get(Membre, mv.cree_par) if mv.cree_par else None + source_nom = source.nom if source else "Disponible" + destination_nom = destination.nom if destination else "Disponible" + ajouter_transaction({ + "date": str(date_mouvement), + "type": "reserve_virement", + "description": f"Virement de réserve : {source_nom} → {destination_nom} ({float(mv.montant):.2f} $)", + "entree": 0, + "sortie": 0, + "par": createur.prenom if createur else "?", + }) + + transactions.sort(key=lambda t: t["date"], reverse=True) return transactions diff --git a/backend/app/routers/commandes_jetons.py b/backend/app/routers/commandes_jetons.py index 2f0aff2..c8cadb5 100644 --- a/backend/app/routers/commandes_jetons.py +++ b/backend/app/routers/commandes_jetons.py @@ -5,7 +5,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func from app.core.database import get_db -from app.core.security import get_current_membre +from app.core.security import get_current_membre, is_sysadmin from app.models.jeton import Jeton from app.models.affectation import Affectation from app.models.poste import Poste @@ -17,6 +17,8 @@ router = APIRouter(prefix="/commandes-jetons", tags=["M6 — Commander jetons"]) async def require_resp_jetons(membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db)): """Vérifie que le membre est responsable des jetons.""" + if is_sysadmin(membre): + return membre result = await db.execute( select(Affectation).join(Poste).where( Affectation.membre_id == membre.id, diff --git a/backend/app/routers/contributions.py b/backend/app/routers/contributions.py index 18507ff..365f14f 100644 --- a/backend/app/routers/contributions.py +++ b/backend/app/routers/contributions.py @@ -2,15 +2,17 @@ from datetime import date from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import select, desc, func +from sqlalchemy import select, desc from app.core.database import get_db +from app.core.decisions import prochain_numero_decision +from app.core.roles import require_tresorier +from app.core.security import is_sysadmin from app.core.security import get_current_membre from app.models.envoi_contribution import EnvoiContribution from app.models.config_repartition import ConfigRepartition from app.models.membre import Membre -from app.models.affectation import Affectation -from app.models.poste import Poste +from app.services.finance import solde_banque, total_reserves, transaction from app.schemas.phase7 import ( EnvoiContributionCreate, EnvoiContributionOut, CalculRepartitionIn, CalculRepartitionOut, @@ -28,33 +30,6 @@ DEFAUT_REPARTITION = { } -async def _prochain_numero_resolution(groupe_id, annee: int, db: AsyncSession) -> str: - from app.models.proposition import Proposition - - result = await db.execute( - select(func.count(Proposition.id)).where( - Proposition.groupe_id == groupe_id, - Proposition.numero_resolution.isnot(None), - Proposition.numero_resolution.like(f"RES-{annee}-%"), - ) - ) - count = result.scalar() or 0 - return f"RES-{annee}-{count + 1:03d}" - - -async def require_tresorier(membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db)): - result = await db.execute( - select(Affectation).join(Poste).where( - Affectation.membre_id == membre.id, - Affectation.statut == "actif", - Poste.nom.ilike("%trésorier%"), - ) - ) - if not result.scalars().first(): - raise HTTPException(status_code=403, detail="Réservé au trésorier") - return membre - - async def _get_repartition(groupe_id, db: AsyncSession) -> dict[str, float]: """Récupère la répartition active ou utilise les défauts.""" result = await db.execute( @@ -123,7 +98,8 @@ async def enregistrer_envoi( if not secondeur or secondeur.groupe_id != membre.groupe_id or not secondeur.actif: raise HTTPException(status_code=404, detail="Secondeur introuvable ou inactif") - numero_resolution = await _prochain_numero_resolution(membre.groupe_id, date.today().year, db) + date_decision = req.date_envoi if is_sysadmin(membre) else date.today() + numero_resolution = await prochain_numero_decision(membre.groupe_id, "contribution", date_decision.year, db) resolution = Proposition( groupe_id=membre.groupe_id, type_proposition="contribution", @@ -136,7 +112,9 @@ async def enregistrer_envoi( secondeur_id=req.secondeur_id, statut="adoptee", numero_resolution=numero_resolution, - date_vote=date.today(), + date_vote=date_decision, + date_adoption=date_decision, + groupe_a_decide_de=f"Envoyer {req.montant:.2f} $ à {DESTINATIONS_LABELS[req.destination]}.", ) db.add(resolution) await db.flush() @@ -189,17 +167,16 @@ async def confirmer_debit_contribution( if envoi.debitee: raise HTTPException(status_code=400, detail="Contribution déjà débitée") - from app.routers.operations_bancaires import _solde_banque_brut, _total_reserves - - solde_banque = await _solde_banque_brut(membre.groupe_id, db) - if float(envoi.montant) > solde_banque: + solde_banque_actuel = await solde_banque(membre.groupe_id, db) + if float(envoi.montant) > solde_banque_actuel: raise HTTPException(status_code=400, detail="Le solde en banque est insuffisant pour confirmer ce débit") - total_reserves = await _total_reserves(membre.groupe_id, db) - if solde_banque - float(envoi.montant) < total_reserves: + total_reserves_actuel = await total_reserves(membre.groupe_id, db) + if solde_banque_actuel - float(envoi.montant) < total_reserves_actuel: raise HTTPException(status_code=400, detail="Ce débit ferait dépasser les réserves par rapport au solde en banque") envoi.debitee = True envoi.engagee = True + db.add(transaction(membre.groupe_id, membre.id, date.today(), "contribution", "banque", envoi.montant, "credit", "envois_contributions", envoi.id, DESTINATIONS_LABELS.get(envoi.destination, envoi.destination))) await db.flush() saisi = await db.get(Membre, envoi.saisi_par) if envoi.saisi_par else None diff --git a/backend/app/routers/decisions.py b/backend/app/routers/decisions.py deleted file mode 100644 index 52ade4a..0000000 --- a/backend/app/routers/decisions.py +++ /dev/null @@ -1,110 +0,0 @@ -"""Routes C5 — Décisions en cours.""" -from fastapi import APIRouter, Depends, HTTPException -from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import select, desc - -from app.core.database import get_db -from app.core.security import get_current_membre, require_executif -from app.models.decision import Decision -from app.models.membre import Membre -from app.schemas.phase2 import DecisionCreate, DecisionOut, DecisionUpdate - -router = APIRouter(prefix="/decisions", tags=["C5 — Décisions en cours"]) - - -async def _to_out(d: Decision, db: AsyncSession) -> DecisionOut: - resp = await db.get(Membre, d.responsable_id) if d.responsable_id else None - return DecisionOut( - id=d.id, - sujet=d.sujet, - description=d.description, - statut=d.statut, - responsable_prenom=resp.prenom if resp else None, - proposeur=d.proposeur, - secondeur=d.secondeur, - date_decision=d.date_decision, - date_completion=d.date_completion, - cree_le=d.cree_le, - ) - - -@router.get("/", response_model=list[DecisionOut]) -async def liste_decisions( - statut: str | None = None, - limite: int = 50, - membre=Depends(get_current_membre), - db: AsyncSession = Depends(get_db), -): - """C5 — Lister les décisions du groupe avec filtre optionnel par statut.""" - query = select(Decision).where(Decision.groupe_id == membre.groupe_id) - if statut: - query = query.where(Decision.statut == statut) - query = query.order_by(desc(Decision.date_decision)).limit(limite) - result = await db.execute(query) - return [await _to_out(d, db) for d in result.scalars().all()] - - -@router.get("/compteur") -async def compteur_decisions( - membre=Depends(get_current_membre), - db: AsyncSession = Depends(get_db), -): - """Nombre de décisions ouvertes (pour le badge sur la tuile).""" - result = await db.execute( - select(Decision).where( - Decision.groupe_id == membre.groupe_id, - Decision.statut.in_(["en_attente", "en_cours"]), - ) - ) - return {"ouvertes": len(result.scalars().all())} - - -@router.post("/", response_model=DecisionOut) -async def creer_decision( - req: DecisionCreate, - executif=Depends(require_executif), - db: AsyncSession = Depends(get_db), -): - """Créer une décision (exécutif — typiquement via le PV).""" - decision = Decision( - groupe_id=executif.groupe_id, - reunion_id=req.reunion_id, - sujet=req.sujet.strip(), - description=req.description, - statut=req.statut, - responsable_id=req.responsable_id, - proposeur=req.proposeur, - secondeur=req.secondeur, - date_decision=req.date_decision, - cree_par=executif.id, - ) - db.add(decision) - await db.flush() - return await _to_out(decision, db) - - -@router.patch("/{decision_id}", response_model=DecisionOut) -async def modifier_decision( - decision_id: str, - req: DecisionUpdate, - executif=Depends(require_executif), - db: AsyncSession = Depends(get_db), -): - """Modifier le statut d'une décision (exécutif).""" - result = await db.execute( - select(Decision).where(Decision.id == decision_id, Decision.groupe_id == executif.groupe_id) - ) - decision = result.scalar_one_or_none() - if not decision: - raise HTTPException(status_code=404, detail="Décision introuvable") - - if req.statut is not None: - decision.statut = req.statut - if req.description is not None: - decision.description = req.description - if req.responsable_id is not None: - decision.responsable_id = req.responsable_id - if req.date_completion is not None: - decision.date_completion = req.date_completion - await db.flush() - return await _to_out(decision, db) diff --git a/backend/app/routers/depenses.py b/backend/app/routers/depenses.py index 9fd863e..9d3a682 100644 --- a/backend/app/routers/depenses.py +++ b/backend/app/routers/depenses.py @@ -1,42 +1,24 @@ """Routes S5 — Dépenses (ouvert à tous, confirmé par le trésorier).""" import os -import uuid as uuid_mod -from datetime import datetime, timezone -from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form +from datetime import date, datetime, timezone +from fastapi import APIRouter, Depends, HTTPException, UploadFile, File from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, desc from app.core.database import get_db -from app.core.security import get_current_membre +from app.core.roles import membre_a_poste_ou_executif, require_tresorier +from app.core.security import get_current_membre, is_sysadmin from app.models.depense import Depense from app.models.membre import Membre -from app.models.affectation import Affectation -from app.models.poste import Poste from app.schemas.phase1 import DepenseCreate, DepenseOut, DepenseUpdate +from app.services.finance import encaisse, engagements_non_debites, solde_banque, total_reserves, transaction router = APIRouter(prefix="/depenses", tags=["S5 — Dépenses"]) -METHODES_VALIDES = {"DU", "VIREMENT", "CHEQUE", "COLLECTE"} +METHODES_VALIDES = {"VIREMENT", "CHEQUE", "COLLECTE"} UPLOAD_DIR = "/opt/groupe-meditation/uploads/preuves" -async def _est_tresorier_ou_executif(membre_id, db: AsyncSession) -> bool: - result = await db.execute( - select(Affectation).join(Poste).where( - Affectation.membre_id == membre_id, - Affectation.statut == "actif", - (Poste.nom.ilike("%trésorier%") | (Poste.categorie == "executif")), - ) - ) - return result.scalars().first() is not None - - -async def _require_tresorier(membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db)): - if not await _est_tresorier_ou_executif(membre.id, db): - raise HTTPException(status_code=403, detail="Réservé au trésorier ou à l'exécutif") - return membre - - async def _to_out(d: Depense, db: AsyncSession) -> DepenseOut: qui = await db.get(Membre, d.qui) saisi = await db.get(Membre, d.saisi_par) if d.saisi_par else None @@ -61,12 +43,21 @@ async def soumettre_depense( membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db), ): - """S5 — N'importe quel membre soumet une dépense courante.""" + """S5 — Un membre soumet une dépense pour lui-même; un exécutif peut le faire pour un autre.""" + qui_id = membre.id + if req.membre_id and req.membre_id != membre.id: + if not await membre_a_poste_ou_executif(membre.id, "trésorier", db): + raise HTTPException(status_code=403, detail="Seul un exécutif peut soumettre une dépense pour un autre membre") + beneficiaire = await db.get(Membre, req.membre_id) + if not beneficiaire or beneficiaire.groupe_id != membre.groupe_id or not beneficiaire.actif: + raise HTTPException(status_code=404, detail="Membre introuvable ou inactif") + qui_id = beneficiaire.id + depense = Depense( groupe_id=membre.groupe_id, - date_depense=req.date_depense, + date_depense=req.date_depense if req.date_depense and is_sysadmin(membre) else date.today(), montant=req.montant, - qui=membre.id, # le membre qui soumet est celui qui a payé + qui=qui_id, quoi=req.quoi.strip(), paye=False, methode=None, # sera renseigné par le trésorier @@ -110,7 +101,7 @@ async def telecharger_preuve( async def confirmer_depense( depense_id: str, methode: str, - membre=Depends(_require_tresorier), + membre=Depends(require_tresorier), db: AsyncSession = Depends(get_db), ): """Le trésorier confirme la dépense et renseigne le mode de paiement.""" @@ -124,13 +115,23 @@ async def confirmer_depense( depense = result.scalar_one_or_none() if not depense: raise HTTPException(status_code=404, detail="Dépense introuvable") + if depense.confirme_par is not None: + raise HTTPException(status_code=400, detail="Cette dépense a déjà été traitée") if methode_norm == "COLLECTE": - from app.routers.operations_bancaires import _encaisse - - encaisse = await _encaisse(membre.groupe_id, db) - if float(depense.montant) > encaisse: + solde_encaisse = await encaisse(membre.groupe_id, db) + if float(depense.montant) > solde_encaisse: raise HTTPException(status_code=400, detail="L'encaisse disponible est insuffisante pour payer cette dépense") + elif methode_norm in ("CHEQUE", "VIREMENT"): + solde_banque_actuel = await solde_banque(membre.groupe_id, db) + total_reserves_actuel = await total_reserves(membre.groupe_id, db) + engagements = await engagements_non_debites(membre.groupe_id, db) + disponible = solde_banque_actuel - total_reserves_actuel - engagements + if float(depense.montant) > disponible: + raise HTTPException( + status_code=400, + detail="Le solde bancaire disponible est insuffisant pour engager cette dépense", + ) depense.methode = methode_norm depense.confirme_par = membre.id @@ -139,8 +140,8 @@ async def confirmer_depense( # Si cash (COLLECTE) → payé immédiatement if methode_norm == "COLLECTE": depense.paye = True + db.add(transaction(membre.groupe_id, membre.id, date.today(), "depense", "encaisse", depense.montant, "credit", "depenses", depense.id, depense.quoi)) - # Si DU → le groupe doit rembourser, pas encore payé # Si CHEQUE/VIREMENT → engagement, en attente de débit await db.flush() @@ -150,7 +151,7 @@ async def confirmer_depense( @router.post("/{depense_id}/confirmer-debit", response_model=DepenseOut) async def confirmer_debit( depense_id: str, - membre=Depends(_require_tresorier), + membre=Depends(require_tresorier), db: AsyncSession = Depends(get_db), ): """Le trésorier confirme que le chèque/virement a été débité du compte.""" @@ -165,20 +166,46 @@ async def confirmer_debit( if depense.methode not in ("CHEQUE", "VIREMENT"): raise HTTPException(status_code=400, detail="Seuls les chèques/virements nécessitent confirmation de débit") - from app.routers.operations_bancaires import _solde_banque_brut, _total_reserves - - solde_banque = await _solde_banque_brut(membre.groupe_id, db) - if float(depense.montant) > solde_banque: + solde_banque_actuel = await solde_banque(membre.groupe_id, db) + if float(depense.montant) > solde_banque_actuel: raise HTTPException(status_code=400, detail="Le solde en banque est insuffisant pour confirmer ce débit") - total_reserves = await _total_reserves(membre.groupe_id, db) - if solde_banque - float(depense.montant) < total_reserves: + total_reserves_actuel = await total_reserves(membre.groupe_id, db) + if solde_banque_actuel - float(depense.montant) < total_reserves_actuel: raise HTTPException(status_code=400, detail="Ce débit ferait dépasser les réserves par rapport au solde en banque") depense.paye = True + depense.date_confirmation = datetime.now(timezone.utc) + db.add(transaction(membre.groupe_id, membre.id, date.today(), "depense", "banque", depense.montant, "credit", "depenses", depense.id, depense.quoi)) await db.flush() return await _to_out(depense, db) +@router.delete("/{depense_id}") +async def rejeter_depense( + depense_id: str, + membre=Depends(require_tresorier), + db: AsyncSession = Depends(get_db), +): + """Rejeter une dépense soumise : elle est supprimée du registre.""" + result = await db.execute( + select(Depense).where(Depense.id == depense_id, Depense.groupe_id == membre.groupe_id) + ) + depense = result.scalar_one_or_none() + if not depense: + raise HTTPException(status_code=404, detail="Dépense introuvable") + if depense.confirme_par is not None: + raise HTTPException(status_code=400, detail="Seules les dépenses soumises non traitées peuvent être rejetées") + + if depense.preuve_nom: + chemin = os.path.join(UPLOAD_DIR, depense.preuve_nom) + if os.path.exists(chemin): + os.remove(chemin) + + await db.delete(depense) + await db.flush() + return {"message": "Dépense rejetée"} + + @router.get("/", response_model=list[DepenseOut]) async def liste_depenses( limite: int = 30, @@ -204,7 +231,7 @@ async def liste_depenses( @router.get("/a-confirmer") async def depenses_a_confirmer( - membre=Depends(_require_tresorier), + membre=Depends(require_tresorier), db: AsyncSession = Depends(get_db), ): """Dépenses soumises en attente de confirmation par le trésorier.""" @@ -221,7 +248,7 @@ async def depenses_a_confirmer( async def modifier_depense( depense_id: str, req: DepenseUpdate, - membre=Depends(_require_tresorier), + membre=Depends(require_tresorier), db: AsyncSession = Depends(get_db), ): """Modifier une dépense (trésorier).""" diff --git a/backend/app/routers/evenements.py b/backend/app/routers/evenements.py index 35f55c7..2373dc3 100644 --- a/backend/app/routers/evenements.py +++ b/backend/app/routers/evenements.py @@ -1,8 +1,8 @@ -"""Routes — Événements (anniversaires + ad hoc + résolutions).""" +"""Routes — Événements (anniversaires + ad hoc).""" from datetime import date, timedelta from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import select, desc +from sqlalchemy import select from app.core.database import get_db from app.core.security import get_current_membre, require_executif @@ -11,7 +11,6 @@ from app.models.membre import Membre from app.models.affectation import Affectation from app.models.poste import Poste from app.models.evenement import Evenement -from app.models.proposition import Proposition router = APIRouter(prefix="/evenements", tags=["Événements"]) @@ -31,7 +30,7 @@ async def evenements_a_venir( membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db), ): - """Tous les événements : anniversaires, ad hoc et résolutions.""" + """Tous les événements : anniversaires et ad hoc.""" aujourdhui = date.today() debut = aujourdhui - timedelta(days=jours_avant) limite = aujourdhui + timedelta(days=jours) @@ -84,24 +83,6 @@ async def evenements_a_venir( "groupe_nom": groupe_nom, }) - # ── 3. Résolutions adoptées du groupe ── - result = await db.execute( - select(Proposition).where( - Proposition.groupe_id == membre.groupe_id, - Proposition.statut == "adoptee", - ).order_by(desc(Proposition.date_vote)) - ) - for p in result.scalars().all(): - date_res = str(p.date_vote) if p.date_vote else str(p.cree_le.date()) - evenements.append({ - "type": "resolution", - "date": date_res, - "titre": f"📜 {p.numero_resolution or 'RES'} — {p.sujet}", - "detail": p.description or p.note, - "lieu": None, - "groupe_nom": groupe.nom if groupe else "?", - }) - # Trier par date evenements.sort(key=lambda e: e["date"]) return evenements diff --git a/backend/app/routers/jetons.py b/backend/app/routers/jetons.py index bb24a88..337c765 100644 --- a/backend/app/routers/jetons.py +++ b/backend/app/routers/jetons.py @@ -4,7 +4,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, desc from app.core.database import get_db -from app.core.security import get_current_membre +from app.core.security import get_current_membre, is_sysadmin from app.models.jeton import Jeton from app.models.membre import Membre from app.models.affectation import Affectation @@ -16,11 +16,13 @@ router = APIRouter(prefix="/jetons", tags=["S2 — Remise de jeton"]) async def require_resp_jetons(membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db)): """Vérifie que le membre est responsable des jetons.""" + if is_sysadmin(membre): + return membre result = await db.execute( select(Affectation).join(Poste).where( Affectation.membre_id == membre.id, Affectation.statut == "actif", - Poste.nom.ilike("%jeton%"), + (Poste.nom.ilike("%jeton%") | (Poste.categorie == "executif")), ) ) if not result.scalars().first(): diff --git a/backend/app/routers/journal.py b/backend/app/routers/journal.py new file mode 100644 index 0000000..ad2e04b --- /dev/null +++ b/backend/app/routers/journal.py @@ -0,0 +1,41 @@ +"""Consultation du journal d'audit.""" +from fastapi import APIRouter, Depends +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.core.database import get_db +from app.core.security import require_executif +from app.models.journal_action import JournalAction + +router = APIRouter(prefix="/journal", tags=["Journal"]) + + +@router.get("/actions") +async def journal_actions( + limite: int = 100, + executif=Depends(require_executif), + db: AsyncSession = Depends(get_db), +): + limite = max(1, min(limite, 500)) + result = await db.execute( + select(JournalAction) + .where(JournalAction.groupe_id == executif.groupe_id) + .order_by(JournalAction.cree_le.desc()) + .limit(limite) + ) + return [ + { + "id": str(item.id), + "groupe_id": str(item.groupe_id) if item.groupe_id else None, + "membre_id": str(item.membre_id) if item.membre_id else None, + "admin_id": str(item.admin_id) if item.admin_id else None, + "methode": item.methode, + "chemin": item.chemin, + "statut_http": item.statut_http, + "adresse_ip": item.adresse_ip, + "user_agent": item.user_agent, + "details": item.details, + "cree_le": item.cree_le.isoformat(), + } + for item in result.scalars().all() + ] diff --git a/backend/app/routers/litterature.py b/backend/app/routers/litterature.py index 9038752..de4f67c 100644 --- a/backend/app/routers/litterature.py +++ b/backend/app/routers/litterature.py @@ -4,7 +4,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.core.database import get_db -from app.core.security import get_current_membre +from app.core.security import get_current_membre, is_sysadmin from app.models.litterature import Litterature from app.models.affectation import Affectation from app.models.poste import Poste @@ -15,6 +15,8 @@ router = APIRouter(prefix="/litterature", tags=["C4/M5 — Littérature"]) async def require_resp_litterature(membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db)): """Vérifie que le membre est responsable de la littérature.""" + if is_sysadmin(membre): + return membre result = await db.execute( select(Affectation).join(Poste).where( Affectation.membre_id == membre.id, diff --git a/backend/app/routers/notifications.py b/backend/app/routers/notifications.py new file mode 100644 index 0000000..6828928 --- /dev/null +++ b/backend/app/routers/notifications.py @@ -0,0 +1,91 @@ +"""Routes de notifications Web Push.""" +from fastapi import APIRouter, Depends, HTTPException, Request +from pydantic import BaseModel +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.core.config import settings +from app.core.database import get_db +from app.core.security import get_current_membre +from app.models.push_subscription import PushSubscription +from app.services.notifications import notifications_configured, send_to_subscriptions + +router = APIRouter(prefix="/notifications", tags=["Notifications"]) + + +class PushSubscriptionIn(BaseModel): + endpoint: str + expirationTime: int | None = None + keys: dict + + +@router.get("/configuration") +async def configuration_notifications(): + return { + "enabled": notifications_configured(), + "public_key": settings.VAPID_PUBLIC_KEY, + } + + +@router.post("/abonnement") +async def enregistrer_abonnement( + abonnement: PushSubscriptionIn, + request: Request, + membre=Depends(get_current_membre), + db: AsyncSession = Depends(get_db), +): + if not notifications_configured(): + raise HTTPException(status_code=400, detail="Les notifications ne sont pas configurées sur ce serveur") + result = await db.execute(select(PushSubscription).where(PushSubscription.endpoint == abonnement.endpoint)) + sub = result.scalar_one_or_none() + if sub: + sub.groupe_id = membre.groupe_id + sub.membre_id = membre.id + sub.abonnement = abonnement.model_dump() + sub.user_agent = (request.headers.get("user-agent") or "")[:255] or None + else: + db.add(PushSubscription( + groupe_id=membre.groupe_id, + membre_id=membre.id, + endpoint=abonnement.endpoint, + abonnement=abonnement.model_dump(), + user_agent=(request.headers.get("user-agent") or "")[:255] or None, + )) + membre.push_sub = abonnement.model_dump() + await db.flush() + return {"message": "Notifications activées"} + + +@router.delete("/abonnement") +async def retirer_abonnement( + endpoint: str, + membre=Depends(get_current_membre), + db: AsyncSession = Depends(get_db), +): + result = await db.execute( + select(PushSubscription).where( + PushSubscription.endpoint == endpoint, + PushSubscription.membre_id == membre.id, + ) + ) + sub = result.scalar_one_or_none() + if sub: + await db.delete(sub) + membre.push_sub = None + await db.flush() + return {"message": "Notifications désactivées"} + + +@router.post("/test") +async def envoyer_test( + membre=Depends(get_current_membre), + db: AsyncSession = Depends(get_db), +): + result = await db.execute(select(PushSubscription).where(PushSubscription.membre_id == membre.id)) + sent = await send_to_subscriptions(db, result.scalars().all(), { + "title": "Notifications activées", + "body": "Cet appareil recevra les avis du groupe.", + "url": "/", + }) + await db.flush() + return {"message": "Notification de test envoyée", "sent": sent} diff --git a/backend/app/routers/operations_bancaires.py b/backend/app/routers/operations_bancaires.py index c662fc8..79b0e25 100644 --- a/backend/app/routers/operations_bancaires.py +++ b/backend/app/routers/operations_bancaires.py @@ -1,128 +1,87 @@ """Routes — Opérations bancaires (dépôts, retraits).""" from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import select, desc, func +from sqlalchemy import select, desc from app.core.database import get_db +from app.core.roles import require_tresorier from app.core.security import get_current_membre from app.models.operation_bancaire import OperationBancaire -from app.models.collecte import Collecte -from app.models.depense import Depense +from app.models.transaction_comptable import TransactionComptable +from app.models.mouvement_reserve import MouvementReserve from app.models.reserve import Reserve -from app.models.vente_litterature import VenteLitterature from app.models.membre import Membre -from app.models.affectation import Affectation -from app.models.poste import Poste -from app.schemas.phase1 import OperationBancaireCreate, OperationBancaireOut, ReserveCreate, ReserveOut, ReserveUpdate +from app.schemas.phase1 import OperationBancaireCreate, OperationBancaireOut, ReserveCreate, ReserveOut, ReserveMouvementOut, ReserveTransfer, ReserveUpdate, TransactionComptableOut +from app.services.finance import encaisse, reserve_disponible, solde_banque, solde_reserve, total_reserves router = APIRouter(prefix="/banque", tags=["Opérations bancaires"]) -async def _require_tresorier(membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db)): - """Vérifie que le membre est trésorier ou exécutif.""" - result = await db.execute( - select(Affectation).join(Poste).where( - Affectation.membre_id == membre.id, - Affectation.statut == "actif", - (Poste.nom.ilike("%trésorier%") | (Poste.categorie == "executif")), - ) +def _mouvement_reserve(groupe_id, membre_id, montant, type_mouvement, source_id=None, destination_id=None, note=None): + return MouvementReserve( + groupe_id=groupe_id, + source_id=source_id, + destination_id=destination_id, + montant=montant, + type=type_mouvement, + note=note, + cree_par=membre_id, ) - if not result.scalars().first(): - raise HTTPException(status_code=403, detail="Réservé au trésorier ou à l'exécutif") - return membre -async def _encaisse(groupe_id, db: AsyncSession) -> float: - total_collectes = float((await db.execute( - select(func.coalesce(func.sum(Collecte.montant), 0)).where( - Collecte.groupe_id == groupe_id, Collecte.statut == "recu") - )).scalar()) - ventes_recues = float((await db.execute( - select(func.coalesce(func.sum(VenteLitterature.montant), 0)).where( - VenteLitterature.groupe_id == groupe_id, VenteLitterature.remis_tresorier == True) - )).scalar()) - retraits = float((await db.execute( - select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == groupe_id, OperationBancaire.type == "retrait") - )).scalar()) - depots = float((await db.execute( - select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == groupe_id, OperationBancaire.type == "depot") - )).scalar()) - depenses_cash = float((await db.execute( - select(func.coalesce(func.sum(Depense.montant), 0)).where( - Depense.groupe_id == groupe_id, Depense.paye == True, Depense.methode == "COLLECTE") - )).scalar()) - return total_collectes + ventes_recues + retraits - depots - depenses_cash - - -async def _solde_banque_brut(groupe_id, db: AsyncSession) -> float: - from app.models.envoi_contribution import EnvoiContribution - - result = await db.execute( - select(OperationBancaire).where( - OperationBancaire.groupe_id == groupe_id, - OperationBancaire.type == "releve", - ).order_by(desc(OperationBancaire.date_operation)).limit(1) +def _ligne_comptable(groupe_id, membre_id, op: OperationBancaire, compte: str, sens: str): + return TransactionComptable( + groupe_id=groupe_id, + date_transaction=op.date_operation, + type=op.type, + compte=compte, + montant=op.montant, + sens=sens, + source_table="operations_bancaires", + source_id=op.id, + note=op.note, + cree_par=membre_id, ) - dernier_releve = result.scalar_one_or_none() - solde_releve = float(dernier_releve.montant) if dernier_releve else 0.0 - filtre_depuis = dernier_releve.date_operation if dernier_releve else None - q_depots = select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == groupe_id, OperationBancaire.type == "depot") - q_retraits = select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == groupe_id, OperationBancaire.type == "retrait") - q_contribs = select(func.coalesce(func.sum(EnvoiContribution.montant), 0)).where( - EnvoiContribution.groupe_id == groupe_id, EnvoiContribution.debitee == True) - q_depenses = select(func.coalesce(func.sum(Depense.montant), 0)).where( - Depense.groupe_id == groupe_id, - Depense.paye == True, - Depense.methode.in_(["VIREMENT", "CHEQUE"]), + +def _ligne_comptable_montant(groupe_id, membre_id, op: OperationBancaire, compte: str, sens: str, montant: float): + return TransactionComptable( + groupe_id=groupe_id, + date_transaction=op.date_operation, + type=op.type, + compte=compte, + montant=montant, + sens=sens, + source_table="operations_bancaires", + source_id=op.id, + note=op.note, + cree_par=membre_id, ) - if filtre_depuis: - q_depots = q_depots.where(OperationBancaire.date_operation > filtre_depuis) - q_retraits = q_retraits.where(OperationBancaire.date_operation > filtre_depuis) - q_contribs = q_contribs.where(EnvoiContribution.date_envoi > filtre_depuis) - q_depenses = q_depenses.where(Depense.date_confirmation > filtre_depuis) - - depots = float((await db.execute(q_depots)).scalar()) - retraits = float((await db.execute(q_retraits)).scalar()) - contribs = float((await db.execute(q_contribs)).scalar()) - depenses = float((await db.execute(q_depenses)).scalar()) - return solde_releve + depots - retraits - contribs - depenses - - -async def _total_reserves(groupe_id, db: AsyncSession, exclure_id: str | None = None) -> float: - query = select(func.coalesce(func.sum(Reserve.montant), 0)).where( - Reserve.groupe_id == groupe_id, - Reserve.active == True, - ) - if exclure_id: - query = query.where(Reserve.id != exclure_id) - return float((await db.execute(query)).scalar()) @router.post("/", response_model=OperationBancaireOut) async def enregistrer_operation( req: OperationBancaireCreate, - membre=Depends(_require_tresorier), + membre=Depends(require_tresorier), db: AsyncSession = Depends(get_db), ): """Enregistrer un dépôt ou retrait bancaire (trésorier).""" if req.type not in ("depot", "retrait", "releve"): raise HTTPException(status_code=400, detail="Type doit être 'depot', 'retrait' ou 'releve'") + provenance_depot = (req.provenance_depot or "encaisse").lower() + if req.type == "depot" and provenance_depot not in ("encaisse", "don"): + raise HTTPException(status_code=400, detail="Provenance du dépôt invalide") if req.montant <= 0: raise HTTPException(status_code=400, detail="Le montant doit être positif") - solde_banque = await _solde_banque_brut(membre.groupe_id, db) - total_reserves = await _total_reserves(membre.groupe_id, db) - if req.type == "depot" and req.montant > await _encaisse(membre.groupe_id, db): + solde_banque_actuel = await solde_banque(membre.groupe_id, db) + total_reserves_actuel = await total_reserves(membre.groupe_id, db) + if req.type == "depot" and provenance_depot == "encaisse" and req.montant > await encaisse(membre.groupe_id, db): raise HTTPException(status_code=400, detail="Le dépôt ne peut pas dépasser l'encaisse disponible") - if req.type == "retrait" and req.montant > solde_banque: + if req.type == "retrait" and req.montant > solde_banque_actuel: raise HTTPException(status_code=400, detail="Le retrait ne peut pas dépasser le solde en banque") - if req.type == "retrait" and solde_banque - req.montant < total_reserves: + if req.type == "retrait" and solde_banque_actuel - req.montant < total_reserves_actuel: raise HTTPException(status_code=400, detail="Le retrait ferait dépasser les réserves par rapport au solde en banque") - if req.type == "releve" and req.montant < total_reserves: + if req.type == "releve" and req.montant < total_reserves_actuel: raise HTTPException(status_code=400, detail="Le relevé ne peut pas être inférieur au total des réserves") op = OperationBancaire( @@ -131,10 +90,39 @@ async def enregistrer_operation( montant=req.montant, date_operation=req.date_operation, effectue_par=membre.id, - note=req.note, + note=req.note or ("Don déposé directement au compte bancaire" if provenance_depot == "don" else None), ) db.add(op) await db.flush() + if op.type == "depot": + if provenance_depot == "don": + db.add(TransactionComptable( + groupe_id=membre.groupe_id, + date_transaction=op.date_operation, + type="don", + compte="banque", + montant=op.montant, + sens="debit", + source_table="operations_bancaires", + source_id=op.id, + note=op.note, + cree_par=membre.id, + )) + else: + db.add(_ligne_comptable(membre.groupe_id, membre.id, op, "banque", "debit")) + db.add(_ligne_comptable(membre.groupe_id, membre.id, op, "encaisse", "credit")) + elif op.type == "retrait": + db.add(_ligne_comptable(membre.groupe_id, membre.id, op, "banque", "credit")) + db.add(_ligne_comptable(membre.groupe_id, membre.id, op, "encaisse", "debit")) + else: + delta = req.montant - solde_banque_actuel + if delta != 0: + db.add(_ligne_comptable_montant( + membre.groupe_id, membre.id, op, "banque", + "debit" if delta > 0 else "credit", + abs(delta), + )) + await db.flush() return OperationBancaireOut( id=op.id, type=op.type, @@ -153,55 +141,154 @@ async def liste_reserves(membre=Depends(get_current_membre), db: AsyncSession = .order_by(Reserve.nom) ) return [ - ReserveOut(id=r.id, nom=r.nom, montant=float(r.montant), note=r.note, active=r.active, cree_le=r.cree_le) + ReserveOut(id=r.id, nom=r.nom, montant=round(await solde_reserve(r.id, db), 2), note=r.note, active=r.active, cree_le=r.cree_le) for r in result.scalars().all() ] +@router.get("/registre-comptable", response_model=list[TransactionComptableOut]) +async def registre_comptable( + limite: int = 200, + membre=Depends(get_current_membre), + db: AsyncSession = Depends(get_db), +): + result = await db.execute( + select(TransactionComptable) + .where(TransactionComptable.groupe_id == membre.groupe_id) + .order_by(desc(TransactionComptable.date_transaction), desc(TransactionComptable.cree_le)) + .limit(limite) + ) + transactions = result.scalars().all() + out = [] + for tx in transactions: + createur = await db.get(Membre, tx.cree_par) if tx.cree_par else None + out.append(TransactionComptableOut( + id=tx.id, + date_transaction=tx.date_transaction, + type=tx.type, + compte=tx.compte, + montant=float(tx.montant), + sens=tx.sens, + source_table=tx.source_table, + source_id=tx.source_id, + note=tx.note, + cree_par_prenom=createur.prenom if createur else None, + cree_le=tx.cree_le, + )) + return out + + @router.post("/reserves", response_model=ReserveOut) -async def creer_reserve(req: ReserveCreate, membre=Depends(_require_tresorier), db: AsyncSession = Depends(get_db)): +async def creer_reserve(req: ReserveCreate, membre=Depends(require_tresorier), db: AsyncSession = Depends(get_db)): if not req.nom.strip(): raise HTTPException(status_code=400, detail="Nom requis") - if req.montant < 0: - raise HTTPException(status_code=400, detail="Le montant doit être positif ou nul") - total = await _total_reserves(membre.groupe_id, db) + req.montant - solde_banque = await _solde_banque_brut(membre.groupe_id, db) - if total > solde_banque: - raise HTTPException(status_code=400, detail="Le total des réserves ne peut pas dépasser le solde en banque") - reserve = Reserve(groupe_id=membre.groupe_id, nom=req.nom.strip(), montant=req.montant, note=req.note) + if req.montant != 0: + raise HTTPException(status_code=400, detail="Créer la réserve à zéro, puis utiliser un virement pour l'approvisionner") + reserve = Reserve(groupe_id=membre.groupe_id, nom=req.nom.strip(), montant=0, note=req.note) db.add(reserve) await db.flush() - return ReserveOut(id=reserve.id, nom=reserve.nom, montant=float(reserve.montant), note=reserve.note, active=reserve.active, cree_le=reserve.cree_le) + return ReserveOut(id=reserve.id, nom=reserve.nom, montant=0, note=reserve.note, active=reserve.active, cree_le=reserve.cree_le) @router.patch("/reserves/{reserve_id}", response_model=ReserveOut) -async def modifier_reserve(reserve_id: str, req: ReserveUpdate, membre=Depends(_require_tresorier), db: AsyncSession = Depends(get_db)): +async def modifier_reserve(reserve_id: str, req: ReserveUpdate, membre=Depends(require_tresorier), db: AsyncSession = Depends(get_db)): reserve = await db.get(Reserve, reserve_id) if not reserve or reserve.groupe_id != membre.groupe_id or not reserve.active: raise HTTPException(status_code=404, detail="Réserve introuvable") - montant = float(reserve.montant) if req.montant is None else req.montant - if montant < 0: - raise HTTPException(status_code=400, detail="Le montant doit être positif ou nul") - total = await _total_reserves(membre.groupe_id, db, reserve_id) + montant - solde_banque = await _solde_banque_brut(membre.groupe_id, db) - if total > solde_banque: - raise HTTPException(status_code=400, detail="Le total des réserves ne peut pas dépasser le solde en banque") + ancien_montant = await solde_reserve(reserve.id, db) + if req.montant is not None and round(req.montant, 2) != round(ancien_montant, 2): + raise HTTPException(status_code=400, detail="Modifier le montant d'une réserve via l'action Virement") if req.nom is not None: if not req.nom.strip(): raise HTTPException(status_code=400, detail="Nom requis") reserve.nom = req.nom.strip() - reserve.montant = montant if req.note is not None: reserve.note = req.note.strip() or None + reserve.montant = await solde_reserve(reserve.id, db) await db.flush() return ReserveOut(id=reserve.id, nom=reserve.nom, montant=float(reserve.montant), note=reserve.note, active=reserve.active, cree_le=reserve.cree_le) +@router.get("/reserves/mouvements", response_model=list[ReserveMouvementOut]) +async def liste_mouvements_reserves( + limite: int = 100, + membre=Depends(get_current_membre), + db: AsyncSession = Depends(get_db), +): + result = await db.execute( + select(MouvementReserve) + .where(MouvementReserve.groupe_id == membre.groupe_id) + .order_by(desc(MouvementReserve.cree_le)) + .limit(limite) + ) + mouvements = result.scalars().all() + out = [] + for mv in mouvements: + source = await db.get(Reserve, mv.source_id) if mv.source_id else None + destination = await db.get(Reserve, mv.destination_id) if mv.destination_id else None + createur = await db.get(Membre, mv.cree_par) if mv.cree_par else None + out.append(ReserveMouvementOut( + id=mv.id, + source_id=mv.source_id, + source_nom=source.nom if source else "Disponible", + destination_id=mv.destination_id, + destination_nom=destination.nom if destination else "Disponible", + montant=float(mv.montant), + type=mv.type, + note=mv.note, + cree_par_prenom=createur.prenom if createur else None, + cree_le=mv.cree_le, + )) + return out + + +@router.post("/reserves/transfert") +async def transferer_reserve(req: ReserveTransfer, membre=Depends(require_tresorier), db: AsyncSession = Depends(get_db)): + if req.montant <= 0: + raise HTTPException(status_code=400, detail="Le montant doit être positif") + if req.source_id == req.destination_id: + raise HTTPException(status_code=400, detail="La source et la destination doivent être différentes") + + source = None if req.source_id == "disponible" else await db.get(Reserve, req.source_id) + destination = None if req.destination_id == "disponible" else await db.get(Reserve, req.destination_id) + + if req.source_id != "disponible" and (not source or source.groupe_id != membre.groupe_id or not source.active): + raise HTTPException(status_code=404, detail="Réserve source introuvable") + if req.destination_id != "disponible" and (not destination or destination.groupe_id != membre.groupe_id or not destination.active): + raise HTTPException(status_code=404, detail="Réserve destination introuvable") + + if req.source_id == "disponible": + disponible = await reserve_disponible(membre.groupe_id, db) + if req.montant > disponible: + raise HTTPException(status_code=400, detail="La réserve disponible est insuffisante") + elif req.montant > await solde_reserve(source.id, db): + raise HTTPException(status_code=400, detail="La réserve source est insuffisante") + + if source: + source.montant = await solde_reserve(source.id, db) - req.montant + if destination: + destination.montant = await solde_reserve(destination.id, db) + req.montant + + db.add(_mouvement_reserve( + membre.groupe_id, + membre.id, + req.montant, + "transfert", + source_id=source.id if source else None, + destination_id=destination.id if destination else None, + )) + await db.flush() + return {"message": "Transfert effectué"} + + @router.delete("/reserves/{reserve_id}") -async def supprimer_reserve(reserve_id: str, membre=Depends(_require_tresorier), db: AsyncSession = Depends(get_db)): +async def supprimer_reserve(reserve_id: str, membre=Depends(require_tresorier), db: AsyncSession = Depends(get_db)): reserve = await db.get(Reserve, reserve_id) if not reserve or reserve.groupe_id != membre.groupe_id or not reserve.active: raise HTTPException(status_code=404, detail="Réserve introuvable") + montant = await solde_reserve(reserve.id, db) + if round(montant, 2) != 0: + raise HTTPException(status_code=400, detail="Une réserve doit être vide avant d'être supprimée") reserve.active = False await db.flush() return {"message": "Réserve supprimée"} diff --git a/backend/app/routers/parametres.py b/backend/app/routers/parametres.py index cef229f..1d682cb 100644 --- a/backend/app/routers/parametres.py +++ b/backend/app/routers/parametres.py @@ -10,6 +10,8 @@ from app.schemas.phase3 import GroupeUpdate, GroupeDetail router = APIRouter(prefix="/groupe", tags=["G9 — Paramètres"]) +ORDRES_ASSEMBLEE = {"premiere", "deuxieme", "troisieme", "quatrieme", "derniere"} + @router.get("/", response_model=GroupeDetail) async def detail_groupe( @@ -45,6 +47,10 @@ async def modifier_groupe( groupe.heure_reunion = None else: groupe.heure_reunion = None + if req.assemblee_affaires_ordre is not None: + ordre = req.assemblee_affaires_ordre.strip() + if ordre in ORDRES_ASSEMBLEE: + groupe.assemblee_affaires_ordre = ordre if req.format_reunion is not None: groupe.format_reunion = req.format_reunion.strip() if req.lien_aa87 is not None: diff --git a/backend/app/routers/postes.py b/backend/app/routers/postes.py index 7e4f714..9b6fd51 100644 --- a/backend/app/routers/postes.py +++ b/backend/app/routers/postes.py @@ -2,9 +2,10 @@ from datetime import date from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import select, func +from sqlalchemy import select from app.core.database import get_db +from app.core.decisions import prochain_numero_decision from app.core.security import get_current_membre, require_executif from app.models.poste import Poste from app.models.affectation import Affectation @@ -16,20 +17,6 @@ from app.schemas.schemas import PosteOut, PosteCreate, AffectationCreate, Termin router = APIRouter(prefix="/postes", tags=["Postes et affectations"]) -async def _prochain_numero_resolution(groupe_id, annee: int, db: AsyncSession) -> str: - from app.models.proposition import Proposition - - result = await db.execute( - select(func.count(Proposition.id)).where( - Proposition.groupe_id == groupe_id, - Proposition.numero_resolution.isnot(None), - Proposition.numero_resolution.like(f"RES-{annee}-%"), - ) - ) - count = result.scalar() or 0 - return f"RES-{annee}-{count + 1:03d}" - - # ── Postes ── @router.get("/", response_model=list[PosteOut]) @@ -501,7 +488,7 @@ async def creer_affectation(req: AffectationCreate, executif=Depends(require_exe if result.scalar_one_or_none(): raise HTTPException(status_code=400, detail="Ce poste est déjà affecté") - numero_resolution = await _prochain_numero_resolution(executif.groupe_id, req.date_debut.year, db) + numero_resolution = await prochain_numero_decision(executif.groupe_id, "nomination", req.date_debut.year, db) resolution = Proposition( groupe_id=executif.groupe_id, type_proposition="nomination", @@ -512,6 +499,8 @@ async def creer_affectation(req: AffectationCreate, executif=Depends(require_exe statut="adoptee", numero_resolution=numero_resolution, date_vote=req.date_debut, + date_adoption=req.date_debut, + groupe_a_decide_de=f"Nommer {cible.prenom} au poste de {poste.nom}.", ) db.add(resolution) await db.flush() diff --git a/backend/app/routers/presences.py b/backend/app/routers/presences.py index 5656751..3696e5c 100644 --- a/backend/app/routers/presences.py +++ b/backend/app/routers/presences.py @@ -1,50 +1,22 @@ """Routes M2 — Présences en réunion d'affaires.""" -from datetime import date as dt_date -from calendar import monthrange from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, desc, extract from app.core.database import get_db +from app.core.roles import require_secretaire +from app.core.reunions import date_assemblee_affaires_du_mois, jour_reunion_attendu from app.core.security import get_current_membre from app.models.reunion import Reunion from app.models.groupe import Groupe from app.models.presence import Presence from app.models.membre import Membre -from app.models.affectation import Affectation -from app.models.poste import Poste from app.schemas.phase4 import ( PresencesBatch, PresenceOut, ReunionAffairesCreate, ReunionAffairesOut, ) router = APIRouter(prefix="/presences", tags=["M2 — Présences affaires"]) -JOURS_SEMAINE = { - "lundi": 0, "mardi": 1, "mercredi": 2, "jeudi": 3, - "vendredi": 4, "samedi": 5, "dimanche": 6, -} - - -def _premier_jour_du_mois(annee: int, mois: int, jour_cible: int) -> dt_date: - """Retourne la date du premier 'jour_cible' (0=lundi) du mois.""" - premier = dt_date(annee, mois, 1) - diff = (jour_cible - premier.weekday()) % 7 - return dt_date(annee, mois, 1 + diff) - - -async def require_secretaire(membre=Depends(get_current_membre), db=Depends(get_db)): - """Vérifie que le membre est secrétaire ou exécutif.""" - result = await db.execute( - select(Affectation).join(Poste).where( - Affectation.membre_id == membre.id, - Affectation.statut == "actif", - (Poste.nom.ilike("%secrétaire%") | (Poste.categorie == "executif")), - ) - ) - if not result.scalars().first(): - raise HTTPException(status_code=403, detail="Réservé au secrétaire ou à l'exécutif") - return membre - @router.post("/reunion", response_model=ReunionAffairesOut) async def creer_reunion_affaires( @@ -55,16 +27,17 @@ async def creer_reunion_affaires( """Créer une réunion d'affaires (point de départ pour présences et PV).""" groupe = await db.get(Groupe, membre.groupe_id) - # ── Validation : premier jour de réunion du mois, une seule par mois ── + # ── Validation : réunion d'affaires prévue dans les paramètres du groupe ── dt = req.date_reunion if groupe.jour_reunion: - jour_attendu = JOURS_SEMAINE.get(groupe.jour_reunion.lower()) + jour_attendu = jour_reunion_attendu(groupe) if jour_attendu is not None: - premier = _premier_jour_du_mois(dt.year, dt.month, jour_attendu) - if dt.date() != premier: + ordre = groupe.assemblee_affaires_ordre or "premiere" + date_attendue = date_assemblee_affaires_du_mois(dt.year, dt.month, jour_attendu, ordre) + if dt.date() != date_attendue: raise HTTPException( status_code=400, - detail=f"La réunion d'affaires doit avoir lieu le premier {groupe.jour_reunion} du mois ({premier.isoformat()})", + detail=f"La réunion d'affaires doit avoir lieu à la date prévue ({date_attendue.isoformat()})", ) # Une seule réunion d'affaires par mois diff --git a/backend/app/routers/propositions.py b/backend/app/routers/propositions.py index 6e55934..823e707 100644 --- a/backend/app/routers/propositions.py +++ b/backend/app/routers/propositions.py @@ -2,9 +2,10 @@ from datetime import date, timezone, datetime from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import select, desc, extract, func +from sqlalchemy import select, desc, extract from app.core.database import get_db +from app.core.decisions import prochain_numero_decision from app.core.security import get_current_membre, require_executif from app.models.proposition import Proposition from app.models.reunion import Reunion @@ -24,7 +25,7 @@ async def _to_out(p: Proposition, db: AsyncSession) -> PropositionOut: return PropositionOut( id=p.id, reunion_id=p.reunion_id, - type_proposition=p.type_proposition or "generale", + type_proposition=p.type_proposition or "proposition", sujet=p.sujet, description=p.description, proposeur_prenom=proposeur.prenom if proposeur else "?", @@ -32,6 +33,9 @@ async def _to_out(p: Proposition, db: AsyncSession) -> PropositionOut: statut=p.statut, numero_resolution=p.numero_resolution, date_vote=p.date_vote, + date_adoption=p.date_adoption, + etant_donne_que=p.etant_donne_que, + groupe_a_decide_de=p.groupe_a_decide_de, note=p.note, candidature_id=p.candidature_id, cree_le=p.cree_le, @@ -39,19 +43,6 @@ async def _to_out(p: Proposition, db: AsyncSession) -> PropositionOut: ) -async def _prochain_numero(groupe_id, annee: int, db: AsyncSession) -> str: - """Génère le prochain numéro de résolution : RES-2026-001.""" - result = await db.execute( - select(func.count(Proposition.id)).where( - Proposition.groupe_id == groupe_id, - Proposition.numero_resolution.isnot(None), - Proposition.numero_resolution.like(f"RES-{annee}-%"), - ) - ) - count = result.scalar() or 0 - return f"RES-{annee}-{count + 1:03d}" - - @router.post("/", response_model=PropositionOut) async def creer_proposition( req: PropositionCreate, @@ -72,7 +63,7 @@ async def creer_proposition( prop = Proposition( groupe_id=membre.groupe_id, reunion_id=req.reunion_id, - type_proposition=req.type_proposition or "generale", + type_proposition="proposition", sujet=req.sujet.strip(), description=req.description, proposeur_id=membre.id, @@ -130,18 +121,28 @@ async def voter_proposition( prop = result.scalar_one_or_none() if not prop: raise HTTPException(status_code=404, detail="Proposition introuvable") - if prop.statut != "secondee": - raise HTTPException(status_code=400, detail="Seule une proposition secondée peut être mise au vote") - - prop.statut = req.statut - prop.date_vote = date.today() - if req.note: - prop.note = req.note.strip() + if req.statut == "adoptee" and prop.statut != "secondee": + raise HTTPException(status_code=400, detail="Seule une proposition secondée peut être transformée en résolution") + if req.statut == "rejetee" and prop.statut not in ("proposee", "secondee"): + raise HTTPException(status_code=400, detail="Seule une proposition en cours peut être rejetée") # Attribuer un numéro de résolution si adoptée if req.statut == "adoptee": - prop.numero_resolution = await _prochain_numero( - executif.groupe_id, date.today().year, db + etant_donne_que = (req.etant_donne_que or "").strip() + groupe_a_decide_de = (req.groupe_a_decide_de or "").strip() + if not etant_donne_que or not groupe_a_decide_de: + raise HTTPException( + status_code=400, + detail='Les sections "ÉTANT DONNÉ QUE" et "LE GROUPE A DÉCIDÉ DE" sont obligatoires', + ) + + prop.etant_donne_que = etant_donne_que + prop.groupe_a_decide_de = groupe_a_decide_de + prop.note = None + if prop.type_proposition not in ("nomination", "contribution"): + prop.type_proposition = "resolution" + prop.numero_resolution = await prochain_numero_decision( + executif.groupe_id, prop.type_proposition, date.today().year, db ) if req.reunion_id and not prop.reunion_id: prop.reunion_id = req.reunion_id @@ -162,12 +163,20 @@ async def voter_proposition( db.add(affectation) elif req.statut == "rejetee": + if req.note: + prop.note = req.note.strip() + # Si nomination rejetée, mettre la candidature en refusée if prop.type_proposition == "nomination" and prop.candidature_id: cand = await db.get(Candidature, prop.candidature_id) if cand: cand.statut = "refusee" + prop.statut = req.statut + prop.date_vote = date.today() + if req.statut == "adoptee": + prop.date_adoption = prop.date_vote + await db.flush() return await _to_out(prop, db) @@ -211,7 +220,7 @@ async def registre_resolutions( query = query.where(extract("year", Proposition.cree_le) == annee) if type_proposition: query = query.where(Proposition.type_proposition == type_proposition) - query = query.order_by(Proposition.numero_resolution) + query = query.order_by(Proposition.date_vote, Proposition.cree_le, Proposition.numero_resolution) result = await db.execute(query) return [await _to_out(p, db) for p in result.scalars().all()] diff --git a/backend/app/routers/pv.py b/backend/app/routers/pv.py index 03713ab..5eef6bb 100644 --- a/backend/app/routers/pv.py +++ b/backend/app/routers/pv.py @@ -4,31 +4,16 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, desc from app.core.database import get_db +from app.core.roles import require_secretaire from app.core.security import get_current_membre from app.models.pv_reunion import PvReunion from app.models.reunion import Reunion from app.models.membre import Membre -from app.models.decision import Decision -from app.models.affectation import Affectation -from app.models.poste import Poste -from app.schemas.phase4 import PvCreate, PvOut, PvUpdate +from app.schemas.phase4 import PvAdoption, PvCreate, PvOut, PvUpdate router = APIRouter(prefix="/pv", tags=["M1 — Procès-verbal"]) -async def require_secretaire(membre=Depends(get_current_membre), db=Depends(get_db)): - result = await db.execute( - select(Affectation).join(Poste).where( - Affectation.membre_id == membre.id, - Affectation.statut == "actif", - (Poste.nom.ilike("%secrétaire%") | (Poste.categorie == "executif")), - ) - ) - if not result.scalars().first(): - raise HTTPException(status_code=403, detail="Réservé au secrétaire ou à l'exécutif") - return membre - - async def _to_out(pv: PvReunion, db: AsyncSession) -> PvOut: redacteur = await db.get(Membre, pv.redacteur_id) reunion = await db.get(Reunion, pv.reunion_id) if pv.reunion_id else None @@ -110,23 +95,6 @@ async def creer_pv( db.add(pv) await db.flush() - # Créer les décisions dans la table decisions (pour C5) - if req.decisions: - for d in req.decisions: - decision = Decision( - groupe_id=membre.groupe_id, - reunion_id=req.reunion_id, - sujet=d.sujet, - description=d.decision, - statut=d.statut, - proposeur=d.proposeur, - secondeur=d.secondeur, - date_decision=reunion.date_reunion.date() if reunion.date_reunion else None, - cree_par=membre.id, - ) - db.add(decision) - await db.flush() - return await _to_out(pv, db) @@ -155,3 +123,35 @@ async def modifier_pv( pv.approuve = req.approuve await db.flush() return await _to_out(pv, db) + + +@router.patch("/{pv_id}/adopter", response_model=PvOut) +async def adopter_pv( + pv_id: str, + req: PvAdoption, + membre=Depends(require_secretaire), + db: AsyncSession = Depends(get_db), +): + result = await db.execute( + select(PvReunion) + .join(Reunion, PvReunion.reunion_id == Reunion.id) + .where(PvReunion.id == pv_id, Reunion.groupe_id == membre.groupe_id) + ) + pv = result.scalar_one_or_none() + if not pv: + raise HTTPException(status_code=404, detail="PV introuvable") + if not req.proposeur.strip() or not req.secondeur.strip(): + raise HTTPException(status_code=400, detail="Proposeur et secondeur requis") + + decisions = list(pv.decisions or []) + decisions.append({ + "sujet": "Adoption du procès-verbal précédent", + "decision": "Le procès-verbal précédent est adopté.", + "proposeur": req.proposeur.strip(), + "secondeur": req.secondeur.strip(), + "statut": "complete", + }) + pv.decisions = decisions + pv.approuve = True + await db.flush() + return await _to_out(pv, db) diff --git a/backend/app/routers/rapports.py b/backend/app/routers/rapports.py index 46c53b5..72be14a 100644 --- a/backend/app/routers/rapports.py +++ b/backend/app/routers/rapports.py @@ -1,6 +1,7 @@ """Routes C1 — Rapports PDF (finances, PV, rapport RSG).""" import io -from datetime import date, datetime +from html import escape +from datetime import date, datetime, time, timedelta, timezone from fastapi import APIRouter, Depends, HTTPException from fastapi.responses import StreamingResponse from sqlalchemy.ext.asyncio import AsyncSession @@ -24,6 +25,19 @@ MOIS_FR = [ ] +def _texte_decision_resolution(p: Proposition) -> str: + """Retourne le texte décisionnel si la résolution utilise le format structuré.""" + if p.groupe_a_decide_de: + return p.groupe_a_decide_de + if not p.note: + return p.sujet + marqueur = "LE GROUPE A DÉCIDÉ DE" + if marqueur not in p.note: + return p.sujet + decision = p.note.split(marqueur, 1)[1].strip() + return decision or p.sujet + + def _css(): return """ body { font-family: 'DejaVu Sans', sans-serif; font-size: 11pt; color: #333; margin: 2cm; } @@ -355,33 +369,34 @@ async def rapport_resolutions( for p in propositions: proposeur = await db.get(Membre, p.proposeur_id) if p.proposeur_id else None secondeur = await db.get(Membre, p.secondeur_id) if p.secondeur_id else None - badge = '✓ Adoptée' if p.statut == "adoptee" else '✗ Rejetée' + numero_date = f"{escape(p.numero_resolution or '—')}
{escape(str(p.date_adoption or p.date_vote or '—'))}" + resolution = escape(_texte_decision_resolution(p)).replace("\n", "
") + proposeurs = f"{escape(proposeur.prenom if proposeur else '—')} / {escape(secondeur.prenom if secondeur else '—')}" rows += f""" - {p.numero_resolution or '—'} - {p.date_vote or '—'} - {p.sujet} - {proposeur.prenom if proposeur else '—'} - {secondeur.prenom if secondeur else '—'} - {badge} + {numero_date} + {resolution} + {proposeurs} """ - nb_adoptees = sum(1 for p in propositions if p.statut == "adoptee") - nb_rejetees = sum(1 for p in propositions if p.statut == "rejetee") - html_content = f""" +
{groupe.nom if groupe else 'Groupe'}
District {groupe.district if groupe else '87-16'} · Région {groupe.region if groupe else '87'}

Registre des résolutions — {annee}

+

Décisions prises en Groupe

- - {rows if rows else ''} + + + + + + + {rows if rows else ''}
N°DateSujetProposeurSecondeurRésultat
Aucune résolution pour cette année
N° / dateRésolutionProposeur / secondeur
Aucune résolution pour cette année
-

{nb_adoptees} résolution(s) adoptée(s), {nb_rejetees} rejetée(s)

- @@ -399,18 +414,27 @@ async def rapport_resolutions( @router.get("/etat-financier") async def etat_financier_temps_reel( + annee: int | None = None, + mois: int | None = None, membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db), ): - """État des résultats et transactions en temps réel (JSON).""" + """État des résultats par période et soldes courants (JSON).""" from sqlalchemy import func, desc from app.models.operation_bancaire import OperationBancaire from app.models.reserve import Reserve + from app.models.transaction_comptable import TransactionComptable from app.models.vente_litterature import VenteLitterature - from app.models.litterature import Litterature + from app.services.finance import encaisse as solde_encaisse + from app.services.finance import engagements_non_debites + from app.services.finance import solde_banque as solde_banque_actuel + from app.services.finance import solde_reserve gid = membre.groupe_id groupe = await db.get(Groupe, gid) + aujourd_hui = date.today() + annee = annee or aujourd_hui.year + mois = mois or aujourd_hui.month # ── Dernier relevé bancaire ── result = await db.execute( @@ -422,81 +446,71 @@ async def etat_financier_temps_reel( dernier_releve = result.scalar_one_or_none() solde_releve = float(dernier_releve.montant) if dernier_releve else 0.0 - # ── Revenus ── + # ── État des résultats : période demandée ── result = await db.execute( select(func.coalesce(func.sum(Collecte.montant), 0)).where( - Collecte.groupe_id == gid, Collecte.statut == "recu")) + Collecte.groupe_id == gid, + Collecte.statut == "recu", + extract("year", Collecte.date_reception) == annee, + extract("month", Collecte.date_reception) == mois, + ) + ) total_collectes = float(result.scalar()) result = await db.execute( select(func.coalesce(func.sum(VenteLitterature.montant), 0)).where( - VenteLitterature.groupe_id == gid, VenteLitterature.remis_tresorier == True)) + VenteLitterature.groupe_id == gid, + VenteLitterature.remis_tresorier == True, + extract("year", VenteLitterature.date_remise) == annee, + extract("month", VenteLitterature.date_remise) == mois, + ) + ) total_ventes = float(result.scalar()) - revenus = total_collectes + total_ventes + result = await db.execute( + select(func.coalesce(func.sum(TransactionComptable.montant), 0)).where( + TransactionComptable.groupe_id == gid, + TransactionComptable.type == "don", + TransactionComptable.compte == "banque", + TransactionComptable.sens == "debit", + extract("year", TransactionComptable.date_transaction) == annee, + extract("month", TransactionComptable.date_transaction) == mois, + ) + ) + total_dons = float(result.scalar()) + + revenus = total_collectes + total_ventes + total_dons - # ── Dépenses ── result = await db.execute( select(func.coalesce(func.sum(Depense.montant), 0)).where( - Depense.groupe_id == gid, Depense.paye == True)) + Depense.groupe_id == gid, + Depense.paye == True, + extract("year", Depense.date_confirmation) == annee, + extract("month", Depense.date_confirmation) == mois, + ) + ) total_depenses_payees = float(result.scalar()) result = await db.execute( select(func.coalesce(func.sum(Depense.montant), 0)).where( - Depense.groupe_id == gid, Depense.paye == False, Depense.confirme_par.isnot(None))) + Depense.groupe_id == gid, + Depense.paye == False, + Depense.confirme_par.isnot(None), + ) + ) total_engagements = float(result.scalar()) - # ── Contributions ── result = await db.execute( select(func.coalesce(func.sum(EnvoiContribution.montant), 0)).where( EnvoiContribution.groupe_id == gid, EnvoiContribution.debitee == True, + extract("year", EnvoiContribution.date_envoi) == annee, + extract("month", EnvoiContribution.date_envoi) == mois, )) total_contributions = float(result.scalar()) - # ── Encaisse ── - result = await db.execute( - select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == gid, OperationBancaire.type == "depot")) - total_depots = float(result.scalar()) - - result = await db.execute( - select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == gid, OperationBancaire.type == "retrait")) - total_retraits = float(result.scalar()) - - result = await db.execute( - select(func.coalesce(func.sum(Depense.montant), 0)).where( - Depense.groupe_id == gid, Depense.paye == True, Depense.methode == "COLLECTE")) - depenses_cash = float(result.scalar()) - - encaisse = total_collectes + total_ventes + total_retraits - total_depots - depenses_cash - - # ── Solde banque ── - filtre_depuis = dernier_releve.date_operation if dernier_releve else None - q_depots = select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == gid, OperationBancaire.type == "depot") - q_retraits = select(func.coalesce(func.sum(OperationBancaire.montant), 0)).where( - OperationBancaire.groupe_id == gid, OperationBancaire.type == "retrait") - q_depenses_bancaires = select(func.coalesce(func.sum(Depense.montant), 0)).where( - Depense.groupe_id == gid, - Depense.paye == True, - Depense.methode.in_(["VIREMENT", "CHEQUE"]), - ) - q_contributions = select(func.coalesce(func.sum(EnvoiContribution.montant), 0)).where( - EnvoiContribution.groupe_id == gid, - EnvoiContribution.debitee == True, - ) - if filtre_depuis: - q_depots = q_depots.where(OperationBancaire.date_operation > filtre_depuis) - q_retraits = q_retraits.where(OperationBancaire.date_operation > filtre_depuis) - q_depenses_bancaires = q_depenses_bancaires.where(Depense.date_confirmation > filtre_depuis) - q_contributions = q_contributions.where(EnvoiContribution.date_envoi > filtre_depuis) - depots_depuis = float((await db.execute(q_depots)).scalar()) - retraits_depuis = float((await db.execute(q_retraits)).scalar()) - depenses_bancaires_depuis = float((await db.execute(q_depenses_bancaires)).scalar()) - contributions_depuis = float((await db.execute(q_contributions)).scalar()) - solde_banque = solde_releve + depots_depuis - retraits_depuis - depenses_bancaires_depuis - contributions_depuis + encaisse = await solde_encaisse(gid, db) + solde_banque = await solde_banque_actuel(gid, db) # ── Réserves ── result = await db.execute( @@ -505,14 +519,18 @@ async def etat_financier_temps_reel( Reserve.active == True, ).order_by(Reserve.nom) ) - reserves_details = [ - {"id": str(r.id), "nom": r.nom, "montant": float(r.montant), "note": r.note} - for r in result.scalars().all() - ] + reserves_details = [] + for reserve in result.scalars().all(): + reserves_details.append({ + "id": str(reserve.id), + "nom": reserve.nom, + "montant": round(await solde_reserve(reserve.id, db), 2), + "note": reserve.note, + }) total_reserves = sum(r["montant"] for r in reserves_details) - disponible = solde_banque - total_engagements - total_reserves - + engagements_courants = await engagements_non_debites(gid, db) + disponible = solde_banque + encaisse - engagements_courants - total_reserves # ── Dernières transactions ── result = await db.execute( select(Collecte).where(Collecte.groupe_id == gid, Collecte.statut == "recu") @@ -531,6 +549,11 @@ async def etat_financier_temps_reel( return { "groupe": groupe.nom if groupe else "?", + "periode": { + "annee": annee, + "mois": mois, + "libelle": f"{MOIS_FR[mois]} {annee}", + }, "date_releve": str(dernier_releve.date_operation) if dernier_releve else None, "solde_releve": round(solde_releve, 2), "solde_banque": round(solde_banque, 2), @@ -539,19 +562,246 @@ async def etat_financier_temps_reel( "revenus": { "collectes": round(total_collectes, 2), "ventes_litterature": round(total_ventes, 2), + "dons": round(total_dons, 2), "total": round(revenus, 2), }, "sorties": { "depenses_payees": round(total_depenses_payees, 2), - "engagements": round(total_engagements, 2), + "engagements": round(engagements_courants, 2), "contributions": round(total_contributions, 2), "total": round(total_depenses_payees + total_contributions, 2), }, "reserves": { "details": reserves_details, "total": round(total_reserves, 2), + "total_reelles": round(total_reserves, 2), }, "resultat_net": round(revenus - total_depenses_payees - total_contributions, 2), "dernieres_collectes": dernieres_collectes, "dernieres_depenses": dernieres_depenses, } + + +@router.get("/etat-resultats/{annee}/{mois}") +async def rapport_etat_resultats( + annee: int, + mois: int, + membre=Depends(get_current_membre), + db: AsyncSession = Depends(get_db), +): + """PDF mensuel: état des résultats et position de trésorerie.""" + try: + from weasyprint import HTML + except ImportError: + raise HTTPException(status_code=500, detail="WeasyPrint non installé") + + if mois < 1 or mois > 12: + raise HTTPException(status_code=400, detail="Mois invalide") + + from sqlalchemy import func, desc + from app.models.operation_bancaire import OperationBancaire + from app.models.mouvement_reserve import MouvementReserve + from app.models.reserve import Reserve + from app.models.transaction_comptable import TransactionComptable + from app.models.vente_litterature import VenteLitterature + + gid = membre.groupe_id + groupe = await db.get(Groupe, gid) + fin_mois = (date(annee + 1, 1, 1) if mois == 12 else date(annee, mois + 1, 1)) - timedelta(days=1) + fin_mois_dt = datetime.combine(fin_mois, time.max).replace(tzinfo=timezone.utc) + + async def solde_compte_a_date(compte: str) -> float: + debits = float((await db.execute( + select(func.coalesce(func.sum(TransactionComptable.montant), 0)).where( + TransactionComptable.groupe_id == gid, + TransactionComptable.compte == compte, + TransactionComptable.sens == "debit", + TransactionComptable.date_transaction <= fin_mois, + ) + )).scalar()) + credits = float((await db.execute( + select(func.coalesce(func.sum(TransactionComptable.montant), 0)).where( + TransactionComptable.groupe_id == gid, + TransactionComptable.compte == compte, + TransactionComptable.sens == "credit", + TransactionComptable.date_transaction <= fin_mois, + ) + )).scalar()) + return debits - credits + + async def solde_reserve_a_date(reserve_id) -> float: + entrees = float((await db.execute( + select(func.coalesce(func.sum(MouvementReserve.montant), 0)).where( + MouvementReserve.destination_id == reserve_id, + MouvementReserve.cree_le <= fin_mois_dt, + ) + )).scalar()) + sorties = float((await db.execute( + select(func.coalesce(func.sum(MouvementReserve.montant), 0)).where( + MouvementReserve.source_id == reserve_id, + MouvementReserve.cree_le <= fin_mois_dt, + ) + )).scalar()) + return entrees - sorties + + async def engagements_a_date() -> float: + depenses = float((await db.execute( + select(func.coalesce(func.sum(Depense.montant), 0)).where( + Depense.groupe_id == gid, + Depense.paye == False, + Depense.methode.in_(["VIREMENT", "CHEQUE"]), + Depense.date_confirmation <= fin_mois_dt, + ) + )).scalar()) + contributions = float((await db.execute( + select(func.coalesce(func.sum(EnvoiContribution.montant), 0)).where( + EnvoiContribution.groupe_id == gid, + EnvoiContribution.engagee == True, + EnvoiContribution.debitee == False, + EnvoiContribution.date_envoi <= fin_mois, + ) + )).scalar()) + return depenses + contributions + + total_collectes = float((await db.execute( + select(func.coalesce(func.sum(Collecte.montant), 0)).where( + Collecte.groupe_id == gid, + Collecte.statut == "recu", + extract("year", Collecte.date_reception) == annee, + extract("month", Collecte.date_reception) == mois, + ) + )).scalar()) + total_ventes = float((await db.execute( + select(func.coalesce(func.sum(VenteLitterature.montant), 0)).where( + VenteLitterature.groupe_id == gid, + VenteLitterature.remis_tresorier == True, + extract("year", VenteLitterature.date_remise) == annee, + extract("month", VenteLitterature.date_remise) == mois, + ) + )).scalar()) + total_dons = float((await db.execute( + select(func.coalesce(func.sum(TransactionComptable.montant), 0)).where( + TransactionComptable.groupe_id == gid, + TransactionComptable.type == "don", + TransactionComptable.compte == "banque", + TransactionComptable.sens == "debit", + extract("year", TransactionComptable.date_transaction) == annee, + extract("month", TransactionComptable.date_transaction) == mois, + ) + )).scalar()) + total_depenses = float((await db.execute( + select(func.coalesce(func.sum(Depense.montant), 0)).where( + Depense.groupe_id == gid, + Depense.paye == True, + extract("year", Depense.date_confirmation) == annee, + extract("month", Depense.date_confirmation) == mois, + ) + )).scalar()) + total_contributions = float((await db.execute( + select(func.coalesce(func.sum(EnvoiContribution.montant), 0)).where( + EnvoiContribution.groupe_id == gid, + EnvoiContribution.debitee == True, + extract("year", EnvoiContribution.date_envoi) == annee, + extract("month", EnvoiContribution.date_envoi) == mois, + ) + )).scalar()) + + revenus = total_collectes + total_ventes + total_dons + charges = total_depenses + total_contributions + resultat = revenus - charges + banque = await solde_compte_a_date("banque") + caisse = await solde_compte_a_date("encaisse") + engagements = await engagements_a_date() + + result = await db.execute( + select(Reserve).where(Reserve.groupe_id == gid).order_by(Reserve.nom) + ) + reserves = [] + total_reserves = 0.0 + for reserve in result.scalars().all(): + montant = await solde_reserve_a_date(reserve.id) + if not reserve.active and round(montant, 2) == 0: + continue + total_reserves += montant + reserves.append((reserve.nom, montant)) + disponible = banque + caisse - engagements - total_reserves + + result = await db.execute( + select(OperationBancaire).where( + OperationBancaire.groupe_id == gid, + OperationBancaire.type == "releve", + OperationBancaire.date_operation <= fin_mois, + ).order_by(desc(OperationBancaire.date_operation)).limit(1) + ) + dernier_releve = result.scalar_one_or_none() + + rows_reserves = "".join( + f"{escape(nom)}{montant:.2f} $" + for nom, montant in reserves + ) or "Aucune réserve enregistrée" + + css = _css() + """ + .montant { text-align: right; white-space: nowrap; } + .positif { color: #1e8449; } + .negatif { color: #c0392b; } + .note { color: #777; font-size: 9pt; } + """ + signe = "+" if resultat >= 0 else "" + classe_resultat = "positif" if resultat >= 0 else "negatif" + + groupe_nom = groupe.nom if groupe and groupe.nom else "Groupe" + district = str(groupe.district if groupe and groupe.district else "87-16") + region = str(groupe.region if groupe and groupe.region else "87") + + html_content = f""" +
+
{escape(groupe_nom)}
+
District {escape(district)} · Région {escape(region)}
+
+

État des résultats — {MOIS_FR[mois]} {annee}

+ +

Revenus

+ + + + + +
Collectes 7e Tradition{total_collectes:.2f} $
Ventes de littérature{total_ventes:.2f} $
Dons déposés directement{total_dons:.2f} $
Total des revenus{revenus:.2f} $
+ +

Charges

+ + + + +
Dépenses payées{total_depenses:.2f} $
Contributions envoyées{total_contributions:.2f} $
Total des charges{charges:.2f} $
+ +

{'Excédent' if resultat >= 0 else 'Déficit'} : {signe}{resultat:.2f} $

+ +

Position de trésorerie

+ + + + + + +
Solde bancaire au {fin_mois.isoformat()}{banque:.2f} $
Encaisse au {fin_mois.isoformat()}{caisse:.2f} $
Engagements non débités{engagements:.2f} $
Réserves{total_reserves:.2f} $
Disponible au {fin_mois.isoformat()}{disponible:.2f} $
+ {f'

Dernier relevé bancaire : {dernier_releve.date_operation}

' if dernier_releve else ''} + +

Réserves

+ + {rows_reserves} + +
Total des réserves{total_reserves:.2f} $
+ + + """ + + pdf_bytes = HTML(string=html_content).write_pdf() + filename = f"etat_resultats_{groupe_nom.replace(' ', '_')}_{annee}_{mois:02d}.pdf" + return StreamingResponse( + io.BytesIO(pdf_bytes), + media_type="application/pdf", + headers={"Content-Disposition": f'inline; filename="{filename}"'}, + ) diff --git a/backend/app/routers/rapports_rsg.py b/backend/app/routers/rapports_rsg.py index 36f7c65..f90454d 100644 --- a/backend/app/routers/rapports_rsg.py +++ b/backend/app/routers/rapports_rsg.py @@ -4,7 +4,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, desc from app.core.database import get_db -from app.core.security import get_current_membre +from app.core.security import get_current_membre, is_sysadmin from app.models.rapport_rsg import RapportRsg from app.models.membre import Membre from app.models.affectation import Affectation @@ -16,6 +16,8 @@ router = APIRouter(prefix="/rapports-rsg", tags=["M3 — Rapport RSG"]) async def require_rsg(membre=Depends(get_current_membre), db=Depends(get_db)): """Vérifie que le membre est RSG, RSG substitut ou exécutif.""" + if is_sysadmin(membre): + return membre result = await db.execute( select(Affectation).join(Poste).where( Affectation.membre_id == membre.id, diff --git a/backend/app/routers/reunions.py b/backend/app/routers/reunions.py index 562a72e..3b710ec 100644 --- a/backend/app/routers/reunions.py +++ b/backend/app/routers/reunions.py @@ -5,40 +5,20 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, desc, extract from app.core.database import get_db -from app.core.security import get_current_membre +from app.core.reunions import jour_reunion_attendu +from app.core.security import get_current_membre, require_executif from app.models.reunion import Reunion from app.models.groupe import Groupe from app.models.membre import Membre -from app.models.affectation import Affectation -from app.models.poste import Poste from app.schemas.phase1 import ReunionCreate, ReunionOut router = APIRouter(prefix="/reunions", tags=["S4 — Rapport de réunion"]) -JOURS_SEMAINE = { - "lundi": 0, "mardi": 1, "mercredi": 2, "jeudi": 3, - "vendredi": 4, "samedi": 5, "dimanche": 6, -} - - -async def require_animateur(membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db)): - """Vérifie que le membre est animateur ou exécutif.""" - result = await db.execute( - select(Affectation).join(Poste).where( - Affectation.membre_id == membre.id, - Affectation.statut == "actif", - (Poste.nom.ilike("%animateur%") | (Poste.categorie == "executif")), - ) - ) - if not result.scalars().first(): - raise HTTPException(status_code=403, detail="Réservé à l'animateur ou à l'exécutif") - return membre - @router.post("/", response_model=ReunionOut) async def creer_rapport_reunion( req: ReunionCreate, - membre=Depends(require_animateur), + membre=Depends(require_executif), db: AsyncSession = Depends(get_db), ): """S4 — L'animateur note le thème et les annonces.""" @@ -46,7 +26,7 @@ async def creer_rapport_reunion( # ── Validation : réunion régulière ── if req.type == "reguliere" and groupe.jour_reunion: - jour_attendu = JOURS_SEMAINE.get(groupe.jour_reunion.lower()) + jour_attendu = jour_reunion_attendu(groupe) jour_soumis = req.date_reunion.weekday() if jour_attendu is not None and jour_soumis != jour_attendu: raise HTTPException( diff --git a/backend/app/routers/sondages.py b/backend/app/routers/sondages.py deleted file mode 100644 index 654c341..0000000 --- a/backend/app/routers/sondages.py +++ /dev/null @@ -1,214 +0,0 @@ -"""Routes G6/C6 — Sondages et votes de conscience de groupe.""" -from datetime import datetime, timezone -from fastapi import APIRouter, Depends, HTTPException -from sqlalchemy.ext.asyncio import AsyncSession -from sqlalchemy import select, desc, func - -from app.core.database import get_db -from app.core.security import get_current_membre, require_executif -from app.models.sondage import Sondage -from app.models.option_sondage import OptionSondage -from app.models.vote import Vote -from app.models.membre import Membre -from app.schemas.phase8 import SondageCreate, SondageOut, SondageUpdate, OptionOut, VoteCreate - -router = APIRouter(prefix="/sondages", tags=["G6/C6 — Sondages et votes"]) - -TYPES_VALIDES = {"oui_non", "choix_multiple", "unanimite"} - - -async def _build_sondage_out(sondage: Sondage, membre_id, db: AsyncSession) -> SondageOut: - """Construit la sortie complète d'un sondage avec comptage des votes.""" - cree = await db.get(Membre, sondage.cree_par) if sondage.cree_par else None - - # Options avec comptage - result = await db.execute( - select(OptionSondage) - .where(OptionSondage.sondage_id == sondage.id) - .order_by(OptionSondage.ordre) - ) - options = result.scalars().all() - - options_out = [] - total = 0 - for opt in options: - count_result = await db.execute( - select(func.count(Vote.id)).where(Vote.option_id == opt.id) - ) - nb = count_result.scalar() or 0 - total += nb - options_out.append(OptionOut( - id=opt.id, texte=opt.texte, ordre=opt.ordre, nb_votes=nb - )) - - # Le membre a-t-il voté? - vote_result = await db.execute( - select(Vote).where(Vote.sondage_id == sondage.id, Vote.membre_id == membre_id) - ) - a_vote = vote_result.scalar_one_or_none() is not None - - return SondageOut( - id=sondage.id, - titre=sondage.titre, - description=sondage.description, - type=sondage.type, - cree_par_prenom=cree.prenom if cree else None, - date_ouverture=sondage.date_ouverture, - date_fermeture=sondage.date_fermeture, - statut=sondage.statut, - options=options_out, - total_votes=total, - a_vote=a_vote, - ) - - -@router.post("/", response_model=SondageOut) -async def creer_sondage( - req: SondageCreate, - membre=Depends(require_executif), - db: AsyncSession = Depends(get_db), -): - """G6 — Créer un sondage de conscience de groupe.""" - if req.type not in TYPES_VALIDES: - raise HTTPException(status_code=400, detail=f"Type invalide. Choix: {list(TYPES_VALIDES)}") - - if req.date_fermeture <= req.date_ouverture: - raise HTTPException(status_code=400, detail="La date de fermeture doit être après l'ouverture") - - # Pour oui_non, créer automatiquement les options - options_data = req.options - if req.type == "oui_non" and len(options_data) == 0: - from app.schemas.phase8 import OptionCreate - options_data = [OptionCreate(texte="Oui"), OptionCreate(texte="Non")] - - if len(options_data) < 2: - raise HTTPException(status_code=400, detail="Au moins 2 options sont requises") - - sondage = Sondage( - groupe_id=membre.groupe_id, - titre=req.titre.strip(), - description=req.description, - type=req.type, - cree_par=membre.id, - date_ouverture=req.date_ouverture, - date_fermeture=req.date_fermeture, - statut="brouillon", - ) - db.add(sondage) - await db.flush() - - for i, opt in enumerate(options_data): - option = OptionSondage( - sondage_id=sondage.id, - texte=opt.texte.strip(), - ordre=i, - ) - db.add(option) - await db.flush() - - return await _build_sondage_out(sondage, membre.id, db) - - -@router.get("/", response_model=list[SondageOut]) -async def liste_sondages( - statut: str | None = None, - membre=Depends(get_current_membre), - db: AsyncSession = Depends(get_db), -): - """Lister les sondages du groupe.""" - query = select(Sondage).where(Sondage.groupe_id == membre.groupe_id) - if statut: - query = query.where(Sondage.statut == statut) - query = query.order_by(desc(Sondage.date_ouverture)) - - result = await db.execute(query) - sondages = result.scalars().all() - - return [await _build_sondage_out(s, membre.id, db) for s in sondages] - - -@router.get("/{sondage_id}", response_model=SondageOut) -async def detail_sondage( - sondage_id: str, - membre=Depends(get_current_membre), - db: AsyncSession = Depends(get_db), -): - result = await db.execute( - select(Sondage).where(Sondage.id == sondage_id, Sondage.groupe_id == membre.groupe_id) - ) - sondage = result.scalar_one_or_none() - if not sondage: - raise HTTPException(status_code=404, detail="Sondage introuvable") - return await _build_sondage_out(sondage, membre.id, db) - - -@router.patch("/{sondage_id}", response_model=SondageOut) -async def modifier_statut_sondage( - sondage_id: str, - req: SondageUpdate, - membre=Depends(require_executif), - db: AsyncSession = Depends(get_db), -): - """Ouvrir ou fermer un sondage.""" - result = await db.execute( - select(Sondage).where(Sondage.id == sondage_id, Sondage.groupe_id == membre.groupe_id) - ) - sondage = result.scalar_one_or_none() - if not sondage: - raise HTTPException(status_code=404, detail="Sondage introuvable") - - if req.statut and req.statut in ("brouillon", "ouvert", "ferme"): - sondage.statut = req.statut - await db.flush() - - return await _build_sondage_out(sondage, membre.id, db) - - -@router.post("/{sondage_id}/voter") -async def voter( - sondage_id: str, - req: VoteCreate, - membre=Depends(get_current_membre), - db: AsyncSession = Depends(get_db), -): - """C6 — Voter dans un sondage ouvert. Un membre = un vote.""" - result = await db.execute( - select(Sondage).where(Sondage.id == sondage_id, Sondage.groupe_id == membre.groupe_id) - ) - sondage = result.scalar_one_or_none() - if not sondage: - raise HTTPException(status_code=404, detail="Sondage introuvable") - - if sondage.statut != "ouvert": - raise HTTPException(status_code=400, detail="Ce sondage n'est pas ouvert au vote") - - now = datetime.now(timezone.utc) - if now < sondage.date_ouverture or now > sondage.date_fermeture: - raise HTTPException(status_code=400, detail="La période de vote est terminée ou pas encore ouverte") - - # Vérifier qu'il n'a pas déjà voté - existing = await db.execute( - select(Vote).where(Vote.sondage_id == sondage.id, Vote.membre_id == membre.id) - ) - if existing.scalar_one_or_none(): - raise HTTPException(status_code=400, detail="Vous avez déjà voté dans ce sondage") - - # Vérifier que l'option appartient au sondage - opt_result = await db.execute( - select(OptionSondage).where( - OptionSondage.id == req.option_id, - OptionSondage.sondage_id == sondage.id, - ) - ) - if not opt_result.scalar_one_or_none(): - raise HTTPException(status_code=400, detail="Option invalide") - - vote = Vote( - sondage_id=sondage.id, - option_id=req.option_id, - membre_id=membre.id, - ) - db.add(vote) - await db.flush() - - return {"message": "Vote enregistré", "option_id": str(req.option_id)} diff --git a/backend/app/routers/ventes_litterature.py b/backend/app/routers/ventes_litterature.py index bd55dae..d60e7b2 100644 --- a/backend/app/routers/ventes_litterature.py +++ b/backend/app/routers/ventes_litterature.py @@ -4,12 +4,13 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, desc from app.core.database import get_db -from app.core.security import get_current_membre +from app.core.security import get_current_membre, is_sysadmin from app.models.litterature import Litterature from app.models.vente_litterature import VenteLitterature from app.models.membre import Membre from app.models.affectation import Affectation from app.models.poste import Poste +from app.models.transaction_comptable import TransactionComptable from app.schemas.phase6 import VenteCreate, VenteOut router = APIRouter(prefix="/ventes-litterature", tags=["S3 — Vente littérature"]) @@ -17,11 +18,13 @@ router = APIRouter(prefix="/ventes-litterature", tags=["S3 — Vente littératur async def require_resp_litterature(membre=Depends(get_current_membre), db: AsyncSession = Depends(get_db)): """Vérifie que le membre est responsable de la littérature.""" + if is_sysadmin(membre): + return membre result = await db.execute( select(Affectation).join(Poste).where( Affectation.membre_id == membre.id, Affectation.statut == "actif", - Poste.nom.ilike("%littérature%"), + (Poste.nom.ilike("%littérature%") | (Poste.categorie == "executif")), ) ) if not result.scalars().first(): @@ -151,15 +154,16 @@ async def confirmer_reception_vente( ): """Le trésorier confirme la réception du montant de la vente.""" # Vérifier que c'est le trésorier ou exécutif - result = await db.execute( - select(Affectation).join(Poste).where( - Affectation.membre_id == membre.id, - Affectation.statut == "actif", - (Poste.nom.ilike("%trésorier%") | (Poste.categorie == "executif")), + if not is_sysadmin(membre): + result = await db.execute( + select(Affectation).join(Poste).where( + Affectation.membre_id == membre.id, + Affectation.statut == "actif", + (Poste.nom.ilike("%trésorier%") | (Poste.categorie == "executif")), + ) ) - ) - if not result.scalars().first(): - raise HTTPException(status_code=403, detail="Réservé au trésorier ou à l'exécutif") + if not result.scalars().first(): + raise HTTPException(status_code=403, detail="Réservé au trésorier ou à l'exécutif") result = await db.execute( select(VenteLitterature).where( @@ -177,5 +181,17 @@ async def confirmer_reception_vente( vente.remis_tresorier = True vente.recu_par = membre.id vente.date_remise = date_type.today() + db.add(TransactionComptable( + groupe_id=vente.groupe_id, + date_transaction=vente.date_remise, + type="vente_litterature", + compte="encaisse", + montant=vente.montant, + sens="debit", + source_table="ventes_litterature", + source_id=vente.id, + note="Vente de littérature reçue", + cree_par=membre.id, + )) await db.flush() return {"message": "Réception confirmée"} diff --git a/backend/app/schemas/phase1.py b/backend/app/schemas/phase1.py index 5abebbf..2faa439 100644 --- a/backend/app/schemas/phase1.py +++ b/backend/app/schemas/phase1.py @@ -36,6 +36,7 @@ class CollecteUpdate(BaseModel): # ── Opérations bancaires ── class OperationBancaireCreate(BaseModel): type: str = "depot" + provenance_depot: Optional[str] = "encaisse" montant: float date_operation: date note: Optional[str] = None @@ -53,6 +54,20 @@ class OperationBancaireOut(BaseModel): model_config = {"from_attributes": True} +class TransactionComptableOut(BaseModel): + id: UUID + date_transaction: date + type: str + compte: str + montant: float + sens: str + source_table: Optional[str] = None + source_id: Optional[UUID] = None + note: Optional[str] = None + cree_par_prenom: Optional[str] = None + cree_le: datetime + + class ReserveCreate(BaseModel): nom: str montant: float @@ -65,6 +80,12 @@ class ReserveUpdate(BaseModel): note: Optional[str] = None +class ReserveTransfer(BaseModel): + source_id: str + destination_id: str + montant: float + + class ReserveOut(BaseModel): id: UUID nom: str @@ -76,6 +97,19 @@ class ReserveOut(BaseModel): model_config = {"from_attributes": True} +class ReserveMouvementOut(BaseModel): + id: UUID + source_id: Optional[UUID] = None + source_nom: Optional[str] = None + destination_id: Optional[UUID] = None + destination_nom: Optional[str] = None + montant: float + type: str + note: Optional[str] = None + cree_par_prenom: Optional[str] = None + cree_le: datetime + + class SoldesOut(BaseModel): encaisse: float # cash reçu par trésorier, pas encore déposé compte_bancaire: float # dépôts - dépenses payées - contributions @@ -107,10 +141,11 @@ class ReunionOut(BaseModel): # ── S5 Dépense (ouvert à tous) ── class DepenseCreate(BaseModel): - date_depense: date montant: float quoi: str - # qui = auto (membre courant) + membre_id: Optional[UUID] = None + date_depense: Optional[date] = None + # qui = auto, sauf si un exécutif soumet pour un autre membre # methode renseignée par le trésorier à la confirmation diff --git a/backend/app/schemas/phase3.py b/backend/app/schemas/phase3.py index bab1b86..961899b 100644 --- a/backend/app/schemas/phase3.py +++ b/backend/app/schemas/phase3.py @@ -30,6 +30,7 @@ class GroupeUpdate(BaseModel): adresse_local: Optional[str] = None jour_reunion: Optional[str] = None heure_reunion: Optional[str] = None # frontend envoie "HH:MM", parsé dans parametres.py + assemblee_affaires_ordre: Optional[str] = None format_reunion: Optional[str] = None lien_aa87: Optional[str] = None @@ -42,6 +43,7 @@ class GroupeDetail(BaseModel): adresse_local: Optional[str] = None jour_reunion: Optional[str] = None heure_reunion: Optional[time] = None # sérialisé "HH:MM:SS" par pydantic + assemblee_affaires_ordre: Optional[str] = "premiere" format_reunion: Optional[str] = None lien_aa87: str cree_le: datetime diff --git a/backend/app/schemas/phase4.py b/backend/app/schemas/phase4.py index c4e2be3..6cfcfb8 100644 --- a/backend/app/schemas/phase4.py +++ b/backend/app/schemas/phase4.py @@ -71,6 +71,11 @@ class PvUpdate(BaseModel): approuve: Optional[bool] = None +class PvAdoption(BaseModel): + proposeur: str + secondeur: str + + # ── M3 Rapport RSG ── class RapportRsgCreate(BaseModel): reunion_dist: date diff --git a/backend/app/schemas/phase8.py b/backend/app/schemas/phase8.py deleted file mode 100644 index be820f3..0000000 --- a/backend/app/schemas/phase8.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Schémas Phase 8 — Votes et sondages.""" -from pydantic import BaseModel -from datetime import datetime -from uuid import UUID -from typing import Optional - - -# ── G6 Lancer un sondage ── -class OptionCreate(BaseModel): - texte: str - - -class SondageCreate(BaseModel): - titre: str - description: Optional[str] = None - type: str = "oui_non" # oui_non, choix_multiple, unanimite - date_ouverture: datetime - date_fermeture: datetime - options: list[OptionCreate] = [] - - -class OptionOut(BaseModel): - id: UUID - texte: str - ordre: int - nb_votes: int = 0 - - model_config = {"from_attributes": True} - - -class SondageOut(BaseModel): - id: UUID - titre: str - description: Optional[str] = None - type: str - cree_par_prenom: Optional[str] = None - date_ouverture: datetime - date_fermeture: datetime - statut: str - options: list[OptionOut] = [] - total_votes: int = 0 - a_vote: bool = False # le membre courant a-t-il voté? - - model_config = {"from_attributes": True} - - -class SondageUpdate(BaseModel): - statut: Optional[str] = None # ouvert, ferme - - -# ── C6 Voter ── -class VoteCreate(BaseModel): - option_id: UUID - diff --git a/backend/app/schemas/propositions.py b/backend/app/schemas/propositions.py index c176206..cf22116 100644 --- a/backend/app/schemas/propositions.py +++ b/backend/app/schemas/propositions.py @@ -9,13 +9,12 @@ class PropositionCreate(BaseModel): reunion_id: Optional[UUID] = None sujet: str description: Optional[str] = None - type_proposition: str = "generale" # generale, nomination, contribution class PropositionOut(BaseModel): id: UUID reunion_id: Optional[UUID] = None - type_proposition: str = "generale" + type_proposition: str = "proposition" sujet: str description: Optional[str] = None proposeur_prenom: str @@ -23,6 +22,9 @@ class PropositionOut(BaseModel): statut: str numero_resolution: Optional[str] = None date_vote: Optional[date] = None + date_adoption: Optional[date] = None + etant_donne_que: Optional[str] = None + groupe_a_decide_de: Optional[str] = None note: Optional[str] = None candidature_id: Optional[UUID] = None cree_le: datetime @@ -34,4 +36,6 @@ class PropositionOut(BaseModel): class PropositionVote(BaseModel): statut: str # adoptee ou rejetee note: Optional[str] = None + etant_donne_que: Optional[str] = None + groupe_a_decide_de: Optional[str] = None reunion_id: Optional[UUID] = None diff --git a/backend/app/schemas/schemas.py b/backend/app/schemas/schemas.py index e268ad6..a6996a8 100644 --- a/backend/app/schemas/schemas.py +++ b/backend/app/schemas/schemas.py @@ -36,6 +36,7 @@ class MembrePublic(BaseModel): courriel: str groupe_id: UUID date_abstinence: Optional[date] = None + is_sysadmin: bool = False model_config = {"from_attributes": True} @@ -123,6 +124,7 @@ class ModuleTuile(BaseModel): class AccueilResponse(BaseModel): membre: MembrePublic postes: list[str] + est_executif: bool = False modules_consultation: list[ModuleTuile] modules_saisie: list[ModuleTuile] modules_gestion: list[ModuleTuile] @@ -148,5 +150,6 @@ class GroupeOut(BaseModel): district: str region: str jour_reunion: Optional[str] = None + assemblee_affaires_ordre: Optional[str] = "premiere" model_config = {"from_attributes": True} diff --git a/backend/app/services/finance.py b/backend/app/services/finance.py new file mode 100644 index 0000000..e3a5c27 --- /dev/null +++ b/backend/app/services/finance.py @@ -0,0 +1,111 @@ +"""Services financiers: registre comptable, soldes et réserves.""" +from sqlalchemy import desc, func, select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.models.depense import Depense +from app.models.envoi_contribution import EnvoiContribution +from app.models.mouvement_reserve import MouvementReserve +from app.models.reserve import Reserve +from app.models.transaction_comptable import TransactionComptable + + +async def solde_compte(groupe_id, compte: str, db: AsyncSession) -> float: + debits = float((await db.execute( + select(func.coalesce(func.sum(TransactionComptable.montant), 0)).where( + TransactionComptable.groupe_id == groupe_id, + TransactionComptable.compte == compte, + TransactionComptable.sens == "debit", + ) + )).scalar()) + credits = float((await db.execute( + select(func.coalesce(func.sum(TransactionComptable.montant), 0)).where( + TransactionComptable.groupe_id == groupe_id, + TransactionComptable.compte == compte, + TransactionComptable.sens == "credit", + ) + )).scalar()) + return debits - credits + + +async def encaisse(groupe_id, db: AsyncSession) -> float: + return await solde_compte(groupe_id, "encaisse", db) + + +async def solde_banque(groupe_id, db: AsyncSession) -> float: + return await solde_compte(groupe_id, "banque", db) + + +async def engagements_non_debites(groupe_id, db: AsyncSession) -> float: + depenses = float((await db.execute( + select(func.coalesce(func.sum(Depense.montant), 0)).where( + Depense.groupe_id == groupe_id, + Depense.paye == False, + Depense.methode.in_(["VIREMENT", "CHEQUE"]), + ) + )).scalar()) + contributions = float((await db.execute( + select(func.coalesce(func.sum(EnvoiContribution.montant), 0)).where( + EnvoiContribution.groupe_id == groupe_id, + EnvoiContribution.engagee == True, + EnvoiContribution.debitee == False, + ) + )).scalar()) + return depenses + contributions + + +async def solde_reserve(reserve_id, db: AsyncSession) -> float: + entrees = float((await db.execute( + select(func.coalesce(func.sum(MouvementReserve.montant), 0)).where( + MouvementReserve.destination_id == reserve_id, + ) + )).scalar()) + sorties = float((await db.execute( + select(func.coalesce(func.sum(MouvementReserve.montant), 0)).where( + MouvementReserve.source_id == reserve_id, + ) + )).scalar()) + return entrees - sorties + + +async def total_reserves(groupe_id, db: AsyncSession, exclure_id: str | None = None) -> float: + result = await db.execute(select(Reserve).where(Reserve.groupe_id == groupe_id, Reserve.active == True)) + total = 0.0 + for reserve in result.scalars().all(): + if exclure_id and str(reserve.id) == str(exclure_id): + continue + total += await solde_reserve(reserve.id, db) + return total + + +async def reserve_disponible(groupe_id, db: AsyncSession) -> float: + return ( + await solde_banque(groupe_id, db) + - await total_reserves(groupe_id, db) + - await engagements_non_debites(groupe_id, db) + ) + + +async def dernier_releve(groupe_id, db: AsyncSession): + from app.models.operation_bancaire import OperationBancaire + result = await db.execute( + select(OperationBancaire).where( + OperationBancaire.groupe_id == groupe_id, + OperationBancaire.type == "releve", + ).order_by(desc(OperationBancaire.date_operation)).limit(1) + ) + return result.scalar_one_or_none() + + +def transaction(groupe_id, membre_id, date_transaction, type_, compte, montant, sens, source_table=None, source_id=None, note=None): + return TransactionComptable( + groupe_id=groupe_id, + date_transaction=date_transaction, + type=type_, + compte=compte, + montant=montant, + sens=sens, + source_table=source_table, + source_id=source_id, + note=note, + cree_par=membre_id, + ) diff --git a/backend/app/services/notifications.py b/backend/app/services/notifications.py new file mode 100644 index 0000000..1fe8917 --- /dev/null +++ b/backend/app/services/notifications.py @@ -0,0 +1,76 @@ +"""Envoi des notifications Web Push.""" +import asyncio +import base64 +import json +from tempfile import NamedTemporaryFile +from typing import Iterable + +from pywebpush import WebPushException, webpush +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.core.config import settings +from app.models.push_subscription import PushSubscription + + +def notifications_configured() -> bool: + return bool(settings.VAPID_PUBLIC_KEY and settings.VAPID_PRIVATE_KEY_B64) + + +def _private_key_pem() -> str: + if not settings.VAPID_PRIVATE_KEY_B64: + return "" + return base64.b64decode(settings.VAPID_PRIVATE_KEY_B64).decode() + + +def _send_sync(abonnement: dict, payload: dict) -> None: + private_key = _private_key_pem() + with NamedTemporaryFile("w", suffix=".pem") as key_file: + key_file.write(private_key) + key_file.flush() + webpush( + subscription_info=abonnement, + data=json.dumps(payload, ensure_ascii=False), + vapid_private_key=key_file.name, + vapid_claims={"sub": settings.VAPID_SUBJECT}, + ) + + +async def send_to_subscriptions(db: AsyncSession, subscriptions: Iterable[PushSubscription], payload: dict) -> int: + if not notifications_configured(): + return 0 + sent = 0 + for sub in subscriptions: + try: + await asyncio.to_thread(_send_sync, sub.abonnement, payload) + sent += 1 + except WebPushException as exc: + if getattr(exc.response, "status_code", None) in {404, 410}: + await db.delete(sub) + except Exception: + continue + return sent + + +async def notify_group_change( + db: AsyncSession, + *, + groupe_id, + actor_id, + title: str, + body: str, + url: str = "/", +) -> int: + if not notifications_configured() or not groupe_id: + return 0 + result = await db.execute( + select(PushSubscription).where( + PushSubscription.groupe_id == groupe_id, + PushSubscription.membre_id != actor_id, + ) + ) + return await send_to_subscriptions(db, result.scalars().all(), { + "title": title, + "body": body, + "url": url, + }) diff --git a/data/import/Rapport de trésorerie.xlsx b/data/import/Rapport de trésorerie.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..b52f543805d570c61beccde840d077c3b6d48e55 GIT binary patch literal 116249 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

wQNsVq`EYEtJTi zR{xHWE(mQ62Fc!pWrRCxq5ko#v4deEf{K?bgfysAAV^l2lF%SXGDyM1W6V)VwcFuQ zLM$<<>K`ZzA1Ku$5pXD>Wn(2Uw+-g9!*62>uh99M68Q9~Ix=acDD0sXr1hzYboS2t zcZ~{J+)~4BmMO$Wz0xJKJbQ)k-L`MtbzF=J_C5X-s#we>v!G zKBz0ah5qDPlW(U78a-+u4FjE!$VfN5>;Ax(zI>Za=e$*N%t|!DZxrT>al?_$lt%h$it1Uk1-ZAtkCzfkk zDoAFiI3m_phQZSq^PdBTyrReeqU>;Slj8Hf=8vtu)%aU$!7?I3`zB`$&qUc_lUigd zGFF-4;)vFv;#GhsE3lZQHaZ5_Ny z56UG=F+PHdvqnO+MvC+AlY;Woix@gKt!;Wl1!W&AtNgN-Ze;(HDRCsQlI4q^6xnG< zLwARj78Ez$Gi0^d0!jaB%;P+IA_1EGWxc%8Gb9Y6S<|QHT+KpV>8UWC$jCmKY!wDA zUDZpjCUb0HQx`eAGHGM4JKc023-o5SizpAAvn2eM9%xmaR}4;8XW;B@Q!hlY2X?fw z&Au_F|BZzmxRSm#*$QLoowuc|@{^Y4X($d+OsZ%I#?&Gl9ge<{w_jJBqF*3=p;d^Lth>6T<$sVggJBtaWua9` z%qh>SNdTgylYp>B_Bpf4jrKeholw2gr;bc0qym`2EyWi|)}an5P>^6oogx(VBUu$< zGRh?~oU*?+=b4aj4)uaNv8#TZyjrXbYS~UVuPn zykE8-4|>o?gk_&TG{-Nr0$wo$2`vh6IdE{7`C z91R#3bA9?N&OPaKLJAPHPfkJ#KGhNb2z@#_Br=1T%*;g0%(b|sKw-caWoc+F>r)f? z?-`!+LY24q0K|g%wrC%$GLpD4%H8b zwd9rSKee0!tNGaQ=Igl}Bh{beISN3YLs8?={+F4KfG@~&{NRB6q3)#>=LF_nT1q4 z#ks+Dz8xhGQ)BYScg$yW_X#R1oQeATz4&KVGKiku8Ucs25n){u$nDzEj)7SfE;YQC_3Ph^xg z3j7;uM*~9tYo#k7`fUqdO$&H@P#^Y2>Nb3s4TfW_N2|B0#>?zYjf7m zR=Ocn;YDS&S;(;vXSD5ZuJjXBmW#Ve?FlNImCFt)JHF06Uo80xm7RHp%KGRSmD+D~ z+1uX7FRqrhC8F%^jh~KSM-A1OP#9FRv2S)Anhekfln;Ts;4 zv8HY3C`O>x5btmq(>2`XR4EWBI_!bG z8q#99$=b=dT@NZrIdw<)IOKoOpQJh3xB@wCK$_d}{omHR{twcez+Y)@(j8#RuFvWg zeyFG)1rFSEQ1OwhCbJ>#*d*=0H?LNP|I!vF_AqdK1o;K|T zR~QYN#CsbWUrumJgow({w8%A;AG&k6!0(IY;k6IwXQU&l0%l>Ome{&>&@5j_K~?F+MpxsVVpQN~L%G zO}kyIU~OoeN?~zz$J?b_X}~O#ygBhenQZ7yv;KCd=687Q`VnBF>sE#d)hjwf#UO!Z5_2(lL)f;j+S$QIy9MRTX92L;$-ul{m;LhaO$s;E#5rk^{4w38Yxlii zHPN@c6RXdOc7}ENSH^#=OQPFz;6d}2Xh5P}XKdzIzNbVxtl3#yawaYG0Q<(dr%bz8 zZV9aQjrSTRk^J_4oGc@^c>0Q5!Lfc9qw|MKia{Ys`mDpX~KV ze}TT`X^`}(9bCeQhc{jR_^4F+C&p{P3TMNkT3|B06Co~Z`<$q{=C4o zV^>Im$;BVH1v2}tKetvN+2{+0X5FlN$Pe5jlhjBUdsiSx%QTP1v;|Y@(lq-8%9DGA|;v>56SSnF;t#jWn zOUQ-(4$XVX1!o1pgfeO%HS)WU$-XV790H_HSRYQUB|fd5$(rg}fHu)Z5LYc%g<0nc zdRtM(&oqh5gDwAf<`vv@T+kH|;2wCtU2e+nc6)K%YfNq`TyCp76LT8UdFxxWVJ!Ig zXEsD&c(g7*`E;`&$k#3C*YXiynp?JIXPc2*W*1Amzc|9Dx5dZr$esJWeSC7ZtAF-m z7j$#Z8*tNM2dHv8yP)gcBj|Rm$2`lcS0R8Z*T12P2dHwQ!Pob_b);MrU3i1El-4LO zxuA#OcSuq=DX^2agc!VQB96aa+$YO5RLGynG!Iv=aq?{7zY^ujNtV`A_6*ZwZg#e) z`AGC$XA_g6=SSJ$ZzJj@Bx8Qwx%DmR6I}AXFU7qB+->9ZHgdVunM0aMvGE8=3ITJO zt5D)htLY1NC3@JIi}8ggk2uxaSFrL zE55UH!7ipuAdJvkAc*|}a3-i0c^daWrIcJf2ib|40GtW7&F*fo;DDg3a?@W=oQXQT zauJJWaV}HZ^k1?kYl8gLjd?HU^9j_LdQG#fSvkgT~`e>syZ?$i}WkK$;z8 z7pj%;RMZRp8b_=nIC>i`zPMUS%z@x?urIitevA-m2EqL~#|}LpoaN0PYCy;)zqxot z43J~DST4jF_<4h>X5&k#Gk}?36iNthVh~EO021v`fiOD-{q?P(#EG)R*4M4dJ0i-V z#WQm$^#Yb-gdhah*XXX%ERBFNcX5BQ^kTWVp}7piEO0`+beL;g`9p9Zrx+yA9$gIb z&A-Bw>WOY0$f1@bLENr^@v3n)O5vv`Y9z!OOR+;RF+ev7%ZuAX-I%}E#O`9Fyf+sO zg}s$843Vh{5z6$fmAO`MO$IunWLhCaiK>r+xd1Ma6n$YyT_Jy$|{f3UA^Urf{|wtGMmhag1Ru)0vM*H*xnlZz(B^i$=p-P2mb&8VNerQ zu}aB;!d$+-LcZSF%D95NyUqChMK^zsuzHBheS8qP`N9RfaH}8kM@*%dM+6aa zB{X#giE9F9o_)%}(QXf zTqxnVcESmJvjIX?QGvj~6doU6_*^pmExF(=tUlG^;>ya(N@{3mX*DZqELOSU;Nm)I zYIWji+cS+a$yW_C$mYms&=FQ8$7y_Npnx#MG9XaJhsQ#mOQff=Lm_9CsMt7bhCwnK zfg`e%`-{3zafE-O#X(|g#*Fs}0|@hcBvh4OvSXY)_9J*0*6H)1d{{_zG~pOny*gT> zIyy&(&$?MHXCm}i!;yQTrK?cy4@CVB1n8}eCz0m-y|OIM5?XP46RYXBrx!;j@tFd? z=%Vxn?q>Nhehtc6u*5+&0NTjD<>eo*F2&3u0O|aCY35a%();2v@jIdWht6{u2jpA( z6oI+5oMDZ_K#%Y{0j0d8!&A*Jtw(yvW^fk6(Q2a2rw0vDDX{A54#kNc+UxWPoSi~B z$1oQPjs$#jQE=`mnjr%`iP-EMav;tYNQ?gb}9PfEnt!eY5!LLTlGKJh}%* zot-N9nT6%;E~%MV<7h*zjo2r8G#WUHI5JqWsWOt7Nf_sh@ig&NabKwH1L}g8<72-* z$iUrU6EaaP6~@{HF~5+O9g@H_N3%z3YK8C5rnA}dJ!}Niq7L4Nq5Oj9O6NhLMU_?@ zRR5H%!zW%Z{xPvKte_SbRa$mXVva+Lhv+<87UK~AC1(N!4kd~#0tkaLoi_nvsR6-U z@2i>mS2G4Ff_RK*s>mV)&YI)wa3pw8jca`^ErO*2#>;T^@cQU`pJo$cTLwv#A@3T) z3TA>sBvhxEd^^NW@P%`pydQtlg>#xZ0fuzLkx?EZ zjp_^g_FORUaar+|66)Z(CtM?-)xFQ*ml<15VZ}kULX_nYFt2G0_cBf}S5L^{sBi$%>?UXRM{fiNh2sd;l&pyK z|2Y7-d!H+q2<&-W|8(>Y{P>YF+UIkiIw24H3r>^RBFerz!HHj6zy9F3I%C~Y9|?(e zEV3(PEwV$Cg$S!13FBCtAXZ~-b?|fF1lIFp1mVL zyB=~?ITob*MS>jwj_bC!){MR$%6{3_3-yI7V8hF1_DqZr?RwmG>ex@(X7(`4PSEC8 z*NIq8;|#Ce-N3M+k-)-Bwst#6Cu`Oo>E1aBzmD5yy;4jcyM`J~cjhelvAyg`&=@wJ zeS1TEn{)NHG5rNen%_qH)J3b+JDmhNJkbG(bysOX3#Egr5!fJzvB7zwn!rF~bT7C^Z9{_dG zEhl0xC?&mAw@I->T(Ny@WaiJ#(T!ho(7i9zjqi)z8yfH%w(J^0*=>8JTn!we;Ve@r z5aAdMc^SmND!hbU%lP7xNJlGm5#zh&}ge3C>TZDl;b| zpK3CgOjww7SQzI~&XkNC${pl2uq6dBksvQyV`b=zzeO(Kr<1JyNT1z16M*bnCZ74B!((r`CpoS@&fG_MAVX@t;sqA!wg{gta1SBJchB+bG>I zVb7tL!k&#zV6iKcn?Usq?{C{q{LnrJ2y3O(M9x-b(nb+qN+S35ln~b1sLeLPeL=#| z*C!Of%W0!_-2@XXz1l+dpr{pSJgO1Fa&b;^^@td%5rJ#$#W?aIOH`pw;C|VV=^C`= z#9xM=V8e}>V1tSZ|BC=59K)_keGTYyZM3$Tw4d^XCcwN2GSgI&O$scE|Irp$uy_+3 z7g-uX(^L&Kltna@8ckzx(*sB61`wN6^fi&M^Zm@&-lLP&>7w`4u~^taGUvAkp;yRp zSIDSN1!&d5LMfy9XsX|~S)n!?bl&J8r>Y~TR%FmP(8d`kLY@bJv6>c)l@_Fb?G3kz zK-%_7Wz&EiZxnjHxE0-AVc9QZ(J#X{MzI0;WIg&u9@vn28XA)D-Z6hJnj0Ah!{eG^ z!Q*qsVNPjFE&Hi@9I5IYPra&P(IG#aB1`sI3=-WyK=C=wmHYyEfc8DpY0Bl%>cb2z zo(2t`M&k6N{59-2UlLR2!`V@^Y41ou@5qS>)-P}1Lz*@-7RAaq_C*A?JxGg`rtv@| z!-?ky6OHKot4n2c{mal{Xu>bHjDYwSh^oKqu^$MS3=-`@$>omN1@2kD1K|eh6KRVQ zOH)|~UJy|N-#v8I8#ll&B@#YNK1a%_`A-Pv{6`k!+=1i-O-t8dVeR*&rk#KM9fZo8Mp_w_>UUqx8cdE@3&rC2|C}A zvb$t;1>9OM&Rc*aSlm%{YCz?*BP?u~#Jpy~ar&?3?d|xT`{-zGI9qH*nH@0c+HQ&; zmmI*k)^9~K$D|TQx!--fcN5DJnz7a1tj%WRf2IYH{$0s{K z&^x|;&F@y@^$y+_=G^G{m#a)7$Er=EShWE&OmW*ZO1-wMF$hhkrl~jMv;f{!@BrL1criQ6g2FY!+@2cELS2?)$xp^tmbiL*!s++&7g~2uUBdI;^Tk}nE_qk+6ZblOl z&aUp9%LI1L04v!=&I$T#L9zo`#{138*%2-9Ytb%c_is(VC(m!$jCwTZwKY;?99nN) zI-&k{+%n_+fWFsXNz6VNb-Tl-_Fb}agU$!O${Gu9{!ih}apcsNDsS}&$*g!4oWJP_GcOGP{|ZM1Mw^$x57uXLC)XlCK4ajgJ;xL$WkDx60^P-&Z8?G3uV?Bp<(((fs1etkpz&)5kMb+|$l$+H$IrCsQWCwfFwxbZ$( zXG-w$ZZbg`qc;(&bi%v(Bg_4}&8EJOV)(N06ZIqVMyH9B1bHTIDBjY@r!LRPo) z0#ncre%>O?nLS1+Ma_YH@uLUO$lNtPVrH-i5}(tsV6Y5=iVC7WJ^@Vt@b zeKQJSblwHmp4IyPcsJffK0s84JWN#Tg$YVuny`T(3*SC+;KMbw1IDUUle~BZ6at3f zIUe@w&ZeBsbDqHy348y5CtkMw2YA8_08ill1D;R@z!N|GhI7SlBKNDno%hZKE^Tf_ zpyrWbsZ`<%Q-|S}yF;htw6DG1x$tcJZN%9@2vfnl94+;T9br2AbQ~>>XE~+}pWce? zb1kXAc5+yAL7H;>wR))j=2cr8YBB93mt2F2C5^*fuW6jN<``F2CQXeT=#13+{>*`A zt<(Sd*Z0el>8pYbk{-XSbanzju=5q*F=a^f5;cf(oTr`?bnURTOiS8iS8dDj>L}6G zc@pe2FYytamSyofwxsZl_oaM^$Gx+Wp`4XgNoHUzX~5&h|BgKI?f;KFQS?Nf`1IeAC$@h=IQzU@ShhW#!1F!kNj)pW z-t3q&B*ugNyg*l_Lk`&i*)!(}62%sW`4)$L`A&@gVoyc6H44T+VF8A{2ChybH!cfx z<6_VQyGv%e&6@YGWEZ(h&fU9Y(Q8Au!gccjD~PV&7Ut~oe=?l$SC>X#9fPcJ*|#~Xm{g6&;yz%Mx7ffNk{ai|f6jbwR^yeL74vkM!|(R%@PL2cy^vA34uRfq|f zsqjTx_qFnsVHL!Une~Y7?-&dfo~53niu5UETZash48~ zBYmGVy&OFqnADwz-{J#6V=Z3?{;5|CE{s(kc zzacWAs&RCWJW@%7pBm#b~44nr6K>^Wgh6%&cDD2U85}tV$ zPho=D#~kh}i&2NLjVswj6{`z#HbD~0sk92m7*8P!Rl*RCQ}gn@Ll2lrVU8~43t@4I z`TI;NA`Kbp`R~-!Rqv~#UF;{@WiYcCwy8bh>)5K3caXXPe+(p5f# zRYd`%j}9=^(TV~FX_3X<4lI^fU_RQf-XmO~cxwPbu@8NIIhWa*NZo96L;-teX)>+g zyvx&KG63Dj~(0BuAMf2lSIDIk=ET5zb*AA}6KdoTwL6CZ-`> zUob?MGj>%+8NLlz7W5sz570~$BM;&{_S1BB_@Q%ihm^$5e^7k;e(wkC7hX8FQptFiV{ z(Hy&k5tvLcZh-ZCH7EnzicEl8(eS=<1mMMTm)Or6JfEbnw1yVSU_HSM+>{BExX?_K zf?n7hvd?Xgch>F9Tjgr*(4Ygw;2cpxtGd$gIlUIbdVwSR4$`NI;};Jt0z`Q;ofDSbRm96;OuQxzmiHR(m>=3Sqy?j`5Ff$@|EWkiOmUbxLA_v=-Ht)YZ}_%bTkSd zF&7PKbje_fC&3#qqxC90AMsn0#n0tV73K)MD236K3wGm8KG{gIoRLJ-4aS_&6$2RB zdZ?A^aGLa*`l#MbnNZQ@Vo{P}QIvfgFa*&r1~JT37=;Na3kHq@mF!#SO3a<8Q7!Fw z;N+xB%z1@h+VkShV%R4(b4#RZ61c}_w!YL_XyO6+k_$qc<%kZZM6@xwdCZBa8#G2`bcEE!1AB1nnXas0*eX80Y$jX~qeyaHZ;RD|V{0#o%#Bt}H!$81R{ z+6%k+z=9T$O;ufxCW&O&awzms|22sV9P9=c zgX@&1>zJo23@o^?5A*4uQ5EsLl$;Yo0Rs|Eq31=bOCcF6|LfIy;P2nR99?F!EFNdc9t22eDaZPdrRAi(LSlT#YV5;F$)kW+81ObAlA@W?Wc-; zJ@jFB?_hoeJP|2Q6}Nim0V2gh*7v>>_I0W18$|S#Uk?m%{8($d!qyd$=l)*B^@XgR59IV#g}qMq$V zTIjeyTJo>V1;2uS@UA6Mae7d5dK8zQOonN*!=E=#e)VjKZHyU#(XgnEKh%kzDp2L$ zoXnh4u|QLhLQ|l6t0==AXGe!QP4hhzXjY`L<8&BlP7&EdBq@<3DKZ#oyc8ocw$q~B|ft$B2yi6 zn`nRynna+tTL0d7SYwEVE!TJ;zoW8)blURvtU?^O|IK~Z4XRCYtn(ERO;-NTXNx1Q{mAQ4}gIru6|ByGXs1f1xrL&A{qrUTCYcaiJWlP4L-Rk zn4l1ChQRBvr1u2ng!9OZFJm<&>eU3oOnkny2RTXd_1CPywy~RWO#M(C`(bZAY4*f~ zXt5%$Hn>4ZZ#Z5itll)^sIx8mJ)OYG{xiz#ZA%YEqSdL^`wf`@XC(auK87cTM6-U& zhrZX;=_7JqSjbKN7X!i@$(LQe9PfP)AL(Nw(o^Jt8xZizDusxGazP#UE7A$nMmC@9)F%80LhwzIWJ8vLHHt6 zv4D#{7q!ZwjeM!;qhc@X;I|o?0Ic20Z!BpHYLH9A2ZRP+LORK}qLvqIh!H$0&Oah# zM-jz_0g70}Ela>cg}dSJBcbe-fpP)unHkecCOUKPfkQ7W7O_3{Pd}?(3(Z^})%baS zcRH(>OZ$JrDMp{*6l9`*;S}~G{{g2Mc!pCHhy8_9fc`6-q6~mjEHzy&09qi7xBvs0 zcmOVqPpX4&ruah3a)wDXpam8^X@P59jI5=bn|rU4rZ+s6uZ+AhG$j?-JC}F(!1K4s zXcIA;wOKP<>U6!}V9j@97|Z_6pa*rM3s0^4)Ei3Z=@RlVzP|R56(YsDW+raKE%+gDzrh1`-y_Ijtx+~Q7_=ev_ zP32bDHLv)**BR1$38TIT)YeaM@P~3IIlE+>;2!`%HMwO+1pcFtSYv;7Ulgl~8LN`a-}&~JwTDKO-JB~$zlPCdT=Wf84oLZ%tLy{s<~DNFVhOD_AWD6-BrsBPf+CNhCSdvJ42<|ygl#Q9gngN@=(RnkhrWZt2) z?X*VmEXj~bySGERzVCjOpS?y$O?GeRUlW|^jQn%z@BTq(VfC+1uRK|B!a5~zy>_#r zXF2{o`y7>0?;iY`u+Z4uW46GBU262Wtca%CJNN`uz^4bl{M9-;*krGuT=z`=Up~F8 zWHg)9b9p{4dc?h$Zl50yoAUHz(?q*Y4}b>f1ZaTY=^prAORuqoCmnFY0~%nye3dKy zJx+))7~eJ?9k(*3n`h+^{ee|$h>#+#)@6ZVcF@ltSQxd(C_2IQZFEyUnYiP86qm4E47U#Tppm1g5w~_dl3yDgqPA~aNSR-TU*&Cn z^Ys%%#fxY3;i%u}o$Y<{>CHx*p7H(l>6vc-2L0pHi%E6sLTl92NQUgeAa$cw&1sz` z)CuKoy4O|ADwSK4uGS@a$oYL{2m#UIAcrK_93&CpA0UsH?qQjnm#n$t*_7;&R{<+% zchMs38o!0_U;N}Vs`zyi>Zqd60CsV)eIXAYzo7aMB6muq=fZ-n)|Sg-a+r$C))8mZ zBsk~2i!SjGe;^{+W6ujEji$Xuz|6yp9>ncOW-EP|6 zYXuWqhxwYy_M;8Tm<%aG4)qaM`1jCuj>=eOvbSGLlzP#S>v zXHik@RPjfwtx+t%z3tqBrje*d?pgeMJENV6Z$}4yxOe6>y-F7E5)Tfz+RoZ+b-O)E z4l(NPc2`ql&wnNU;C6Fk)ZOX%a6|rhfpM?3P4e(gO?oofO@VB?1R#b|#iYmEw1+Je`D)g$>fvD4v`6G~ zt}W#kp(XTDUGj|}A+NE}p9VNt>FF9MfNhaHgopId1+#=qpHoBoIy>A z-O7u2<#H7MY8!i2WGbT<-LN_-ApWs$!B{yuP{iG~$;B_I{y_KX3DeT;K+` zr%eIstl%D225mqm-;8JSQnemMBjnMDx>j__Ks@L2|7+FL`cGE9_kdMT^+1EtdpJC2KmE1Y9Xyqspc!llSoOr|A`Db==k&l~()k2p zOa%qGl-x(^iiB3n;6N@z?jl?~FVPkc*rsR`uCn+U%{<^!NohiyIX^QR6Vq zuPbBs5d6aPFt-vZY+O%=67+ZsFw1 z_Ui*3XCGrnG~m=Lsdjd?kh9j5Gi2<1wf$t$oA_@`dQJCD&nCU}GSCtKvq|rc2Y^s; z%P+gSqRKD-6gql(6ng>;gbQE|86qAUth7@&fqAXCX;LWXFuIz_x}XKI0SE>C9X*|| z@%Jmm|7_Cp`L{_g@Be1fTNiiA4-&mhis?Bs2%2v|08DvrDcj+^3KOJ0%F^ybZ~#+Y zc(lUD`Xq`^EhIEA%@m~Zq+xa`>{BAHGCD9N1r^@uqk*qSo%%s?mNz3L-MhqG^?{a4 zJdR4<_lpgGsM$IuVSS4JP%}ItOo)e{&o(zIda!=-Ug3CM+{w!a{pE*@^d}|{0)@|W zOowxo#QH~$W!J4ye47E^I$u6N?k;slzACSGY%wz-ApB(=R5MM`xRisa#5L~_tNdt_ z!!8c>a8vNOYXsvn=iccV?nFdC_kEOnrpM&ukyfuZWRW}s1)$3&N7ywXdUV-sJ3_R( z+{=cg%-a?7^|7i4&5mf!ehD4p*IWXtW~l>#RkQW4?Vgzv(~9aISReC<&fs+P?8n%6 zp?5&BpKUXunS7G_w<15k^~fryg{6ZE6QnHc;7V@fOZH~zM37H*|5@Q|wG6yrxOC4> z3i|;G@B4P((&%vbS)n6hoJpUkS|w&qQ6*7CnfzJPwp+@)$M#kJ_QU(8206;EMmbK5 z`&*PCo7?6}9HPca960|%HAxx6YVYcL1SS?}q=do&DvEO8VL1#go@A7)x_J(Jhl2X@ z^LXLYlusq~UH-?A0V*dXWpw77vr#$~=fQ9LlT-_slkh1n5Irh}%&~jz7UON<%vUhG z*ibhz>SCDbPo?BP<@W@FoMzCCjE0y-$}5~*Y^OJ`t{jMDZ%QcZ;-{)jjFLs-m0}>D z<~|lvC3{zUFdUK~3B^EWiYlJU_~(-C_4igelVw>}r4&kN6myLPKAe{QLNY(S1qixA z(a5I9_~r4KnKuue;{YO-+Jj7@cQujSAe{&jS)Woy*fGJd67H~424EOk>X-(5*I+W> z6*1rx0ll5RX(M!_iFK)7B*aOUp?EsZ*W>19J8B~I7j7=Q=?&cn8lzvLI?3`ZEE+5< zgvH62ySit5`cdGyUL`W&UL)oYNdtc_oo~OP@5U|Y?9NlTL87=5iWhEvz_hug3m7hL zX8D#ryh@Kx)~%QZta!J7G(=nT3`vjp<8PC~gXd#w#!#&o-GQ5QC4NmJlL|fp`%C4f z-Lf`!JTWw5dTRPakrPvlceOji5A2e9jgLHyI3L1TWWgye9e*n{IQp_Gxa5aO)QFL? z(&v+*o-nu@)P2c4)dx=L)Vp**D&BfU6|YEzC1Qw}YvzdO|9vUR+V zCGW#qme}={zeIA<#6n3{sOk;E2^!S7b1%@rS>Rb$uoE02qn^m+*u^!1J=~)O1tap- zDEQ(?ic#7cIoBp^3|2JY1O-9UvbtY%$J3YN?H z!&rb|J5K4g!`bSh#7{)=qzQ=87U5ypA7fe3QLVHOH67`VnAN~xZMiN6)#oT~j;9Qd(YgolsS&yGTw z%)w5VY$?IydqAcL&&Tfbl+HV`EGOY=z%a?RkWzz!+FXn>t(&?JzVHQSz@ufrgZ)HC zMc!GG&2lF1>G^E|ttJD0!;5N`Gj%Uz%tK|zPjk1(>^r*j0)Yu7c3~^GWJz} zGRnB?8_7FM-Y{w2FiW&q&X~RIL651gf;!j&vJ-ZoHLv_34;Btr1`b!1ZQdPye!;Em zMh}%0!Lnl#P4A7AM(#G+3L&)>L6e|?uZP%RM&Z%)e9MU$PHVuUKJoJq`(ik{@KDHh z&-V&3rs|cz_v0=~TiYvHJ+Pp#OXqD#wE^mvV574EOf=?)J)`E=t8U;KH$&_gCsiW1 z7`!H-#a4IE$Uv}QN3@7JX5{Ky-=kK#4X-ydoQiv@ib5{RpZrD@g+^)erJskgOQ?4| zR6YsP9RQ&NhH0K>*l#?;6g&E8jCp7ds(W17I27@d6+gkQT*Cr~!qOc;r+I479W1>7 z@p|CCg|IpS9=sFid2cBD&VM|3-If^Vs9J8`bR16j*{umn&BmVjt;k(SCVkpJfr)b| ztxdN?6@AUd>AL;8d6Jo8(UdAv0yU)!bLnkuEV6On3-2({DfH3??DrFBp!VzR>oS(u z5CaU?lBq*WDr9@3duXyoVElR#c8)ZB)XB5z9(5*;HhdImjkZP|S#tzzZnfOuGRIz4 z9O0Q?uxuayAI{z~DvoE}+fD+(0zrbi1t+)$ceezW;0zAIJp>8v1b27$!QF$q1b2cv zyglT<_dd^g-g7=YYt_`M>aLj&OgFHqulsksQA@|FH|-Hn>G6wTu$c()E>>1#eEuK9 zV)#jP`)bOpzCvY!4|l9KT+BXM<&D-YX8E}#t~yuzH(3_oKAwn;^}*>IXm0~5ygzsZ zr$_Hf*kSd@iZgz<5gJ%_cKexbJbr;WZ`l~C6iM_7 zFzVG8$;6H%79*cV`A-W%4b&H@4MLr(!H!fDj!+Pepb|6m!T#;AM5h?iSF8Cofh*~) zPC~g`lZNP=0n>LXrm^jg4f={z;)>PujHLN|N5aUiKg=JNsISV@$)BfSebCIdM-1GyC89I=bDwuf{KPbHnnXHgcVry9;^wcimy zLrVNn2O^xS*op)u3XnsL5d<#J=NN$-p}d1c6C>yIGMd@Rn>Zyt&XyM*4@W@@TKJ}7 z;BPZpFgHx)Pi)|8oZtHdD`K7?zO1_Ca*Ov%8X4#8TLr+}4RVeWn$S-OsJKQnjR^3p*w5azBEy6l;`+oMps04nv1 z&%tPCH^LaP3mq%9?Hw>JT?JnqAC(-KkgA{{$lV1SfZRDD>~d8#HMmHuf}L~M6nR~g z)$<=kQkZT6s<33muYY+Lbse<(B&-9-T@KOoO_fMW5`f%&Z=@atn>#Za z1#0ST>-8@%kjbL82%TzV@g}7sd|gP88>zeAa{=Rg!&1G10!jV zri9P{awqQzLGIioAjsXq-X4XPhr*9%1?<>XxC!q;37~)#qEIIL0zFY?tyz zJsj2MYGZ<_+(@O|)*OCy$Mhfh+ zft>!girD`Nx%*oZn*z8cq@E417W5zf8enhctvG8%HOr%k9dq%ja2PQy-$jaQ2RTMH z?M=OCPH_pk!*_}HjG_)wo4w2l9BPc@I~=>B5iaIz`9N;GQ3 z(aqEA*V)>f5x1oAOjENwRu+fgsOH9)1)A)HI(XrZkipe!>8>uN%=FU8_FZp-2~9k` zqZ@|{-^%j5hSqXd-B@PY$a=!f2F+^AR$EP7>N4J~!DsX5egVPxxfNiLl+%`FiP-}Un_faILhI;9vlvf#Xg-K8gr;KQ zT<}pWsl#tpEU(q&dJ>EGFrtB*EGNu2J{je9Jwa{=p~G3))Ut2%kNGN zSk&&Vc-GL(kE^RMOx=m(Wp9ka^NlsAMs3VXpxi$86bElU`FZD!xeF#cyVUhfXf9NZ zOLO!aqK)DvY1g{oc`O_zNN=-K`#0)q-RW>j;@HJaLHrU>yq3X>wS7gH-G!1%CTqJ% z=(Un#Hc_5m_=JPUYpL)w&>No+>1h@+&G^J0&*{w;GIh9=$`Us`hErRH+iG!Gli%;( zjq3hK0lTYt?%^c+mb;1S!3laWTyVLCQxsPe!u;)GuzQSpQ)*l5tR zuYH_oFjc*~EJj!%OaM?SX!t1)FvW1aG_t^W>-Zb*pu^we3!iR$?W}1HB7+;L%Fl`* z)Bedi#@EMJ?ln~oUqoW700nF%1{GjcPzV!ze&g#}G&~C+yRLFF4T42;ihR4Z0oT_qBOYI>m_P*HKu%CiSn`J_U*4_n*X%%Z5Bgqw>0+gPt>AePmHyamp} zhM59Sb&v)Q;DLR+;L7{#fn`;p7WbPolPN!ZLK~jwF6+)YGiIb)xqojsq+=)b_U@&o z_4@3zgjl!I80}e_Mt7bE()2#{&PpTw3oM{gc8COetDG=iMeX%cr1CWlV@c(yx*AQQ z450-MbIfECF7m>ws`xuc?if1Cg?;}Dv06lc5eY7APJpUIn0 zW?`8euV^2%HgP@;E*#dC5uIJEDT{~HiXZL!UL_R2uH8pDK}tTHO)%WN{4`@OIPw#z za9~Ee-qiCEG4k+kN05kTCkxgiz=~4Q>jq_|6rD}KxxHc^gDvwo1WvIP^?fSY9?pD- z_b~Q+h~6Y%g1ta2=}YC<>pc7=`jAd|irB2oKUGl$dx2?wF-_6t5(XsK(Y+m6+o1#E z>&Dpdp^~%u_mIN0%kul3i~8AZN2;JXGs9xhD-r-o?ym_JBzgjV=?V5 giBfadT( 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ë}>ddlRSm_79_k}`6d}7wN#Fg-*VS_rfEWfFRoCXV5cs1PxZTZkUPnT z`K&Qv?F8mkCxcs1*cSIFmuM)fC}Xa2n#IvtatG|1iXN&)ZKULz`bg*_FMY{8XfvwQckWam)UW^$3EC6-#P4pL%*9f4WL`NZ*r*Zebb@fRb0&VzFIO50(` zLK)fj>Ll$o#tJLi$xia#o32bQ$N?rr8yY+1mB&c^<0p?MIl??T#`dPMaaLv<6%{Ux z3=PU;Wni_-YL6Ya4I=aVug^QX?)YFAYv2f&WXM`sYz54RzFoKA*qoP~f!#Z7F+Xn6 zNDs7t#ug;gK5>bwn7fg^QNUq&v3H*9n=_Fmp1Hf|NZXPVMp63 zdpv8EGNp2<8Z#qjtcYf62~$wJS0m$7i!EK}Nw=NVcD z9Fp*9T}33QH5D;1v>`G0N6tAmWLjP)hL5#epJAsaQxrwJ5PaqAA1|1TR4+K4e0!&s zVMD{{lC*7o_v!k$_OsZpY9k{}17EzTP^f8f$JnTIaxh&ldn$Kfzg7st^GTF#bOPV9V-)4 zKE{OPLpKx?ExRvH4V9t?H@ACDEme0H-SCZdcbg_0pXEB+W3Nt65HcX~eu4&8KV~t8(p(#}rQnzDp zbK(sH?+RPM3chr5hmP!>q)lRY%}8)7?90T7wchKFaj%RuxBvQG%}PKU)AsH8A;hCC zU+B$e`Box99A-UxM%@%f6*bKFDFZKMDR>D9`wnTlqzNEjb??i*e2l`MdTFrH-HTN@ zqRZ!+a7Kmwk|^nek7!2gB9lghP)kuLp5U-qkIa!Oq&N#NO>S!Y;DzJIAFsGD)kbsP z*MaE+ihg@f9&tzA|4Ok9(gP>y^^Od>87b_9gC!lJv6=%_L>lmzh;) z;ukFLHLDFRzwCDsKN6T|RccHZx>v!5dpAaWWEIXW^>(>VG4VZ_U@ck6rHR#IoXU~e z?ToN798EjbqT3AgiRQv=X46M_ppn*S_UHv7Tq@EXbS8C^jBl8i`1MtzwavNAia0hf#?YRwB_Ue;2>JvFVoxFKwNM4QxJH=DS&9s!I-CRWF-rd&z2Vs_KtF&Oa7~*Ji8^B{{LEAdm#n zf7NEdNsz6pjh2V2nW=!!!$i#37pWo}{C*bd%NWFdVCAS< z5k3}-U0a<`E2DR6efaJ-pgo2JfMt8{j>Zq5kK9Rl&>V8}M9wXJ*mR9xajy#!2-J!EUzr88O;<9@+tbU{ z8J=C)Lp9j&>{^7CVouNM0wXu|F=E$sj}zt^kvv`dHDUt&8AG?@AJa-}j!B&>ydaz= za%|@1WCwBM;j?nPo)?R$b`C69(uC!$pmVkQOqnvGMGhdvaM9fpF9kame;iuCOB1)@ zVN`O}$#K^aiXZCA*jz$Nme8Hho(?BDWe5;I-TNwhu7+!}&4KljQ`e*M4?hk7`r$Q0w{H zM`zIk8+MW*%+hYKZ=Lq`!&s8WwXEO2#G;XdPnd}7U59y4TVH>Sp^p7jsy(Tl*c&I= zJ?>nSsDtGzXe|?pFUDHb?S`A@zs`Duu4u5dM0kO-6({y#ZE9;knWm6C)@K3fTF-H{ za0o#KB!u)dfF{*M)8Ykn$^t!2czdSR0_C#rv3pIIUt*F`W}=Y4IeWW|&%F0^>X>b@ z2!5rM*{4+u#n%N-+lZN#+g8y&+tJ@>$iNa$)f+<7RlIZFMkn0!YaZD7g8qFfe{WqnHX6@8R{tZKJRch0IB@Y<- zn%?Q*n1$9QG*fqF+!R^=%2|tQ+_rA}uxCX-jN5}{uv?zOB~xjYa`;%Ab`S!IiQRzpXe zhU^>0`$3zhXl8lG{Y}??|C2jxW1IY5L5U&dEuRFw@EV(8Q*quptGAB6^$0~Sv+w>Z z2;m$P@~9Ib(xNR5UTVB4@uEG+;({(@l%cEhxnzbX1Jzk5WQjlBLeUS(5?-)N$4YoR%LxL;7$Ko3P*Ffg)0fk3P4G9?x`nPO_ zX9{I*16e-=)FwFpl(N4MEIjO-Jb8KG``-hyq=d+t0nmOt5D4=3^*?`E0bgLE+yBDC zr@L9Zy55895<*U(KI^&*3J8P-+@0VT&U-+lzb4H6P551iqw2j-8sM@KOb`gJ!2i1Y z=syE{+1okW@&4TZoM`tu;GAc6AOZ*+Qw;(E5xL?f0bk(mo?d=Vc0W7qzXx6NJE8Xi zZh8}#^+$0fAPAHOw3LWu`U%1l;dhL*kBS6*$^863FgnZ#F#-r967=dOx)p#?_yfZ# zju6BDbGiNBrO7VgO3w!{EWiT(zeehVIzo&9AEHRbb$h#802t;!q-nB5h~Y;VDVqg{ zOM3t#{RhU(3o!bb_0~)KN48E3L%9bp)jv9l7txmjQ#!Jqon-?Aw~p|F!e6W6L|nd@DE{{ClONk z5ylD2`1}=In8H7V$@_{B^YiVkzpEaJQjHxHp)i;i2r2wOty_M_#Kf{ReghWMdk-w8 z_iJXK5+NZfmOt0e`<-G!gkxI>2&4N)$_Owcr0^q5;HxjW{Z$w$afBFzRm9b|YW!L# zZ>uAu@FPs%tIG`jDh!(?LJYzh;_77QUxhLEL`dOBn7~)fntm0A<}qRnA_cxW4D&0+ zKNledp~_r+{DBYI{OgG7ep3Dz!1-NWuJ*~{k4gW!`6i@)`>TIHH2og@YS$M~x+^ZW z`D*Zgy79jQu6FU@J>-9#ZOawFU;X9ZLtpJ5{CfNLRwP87LM=5kpm_y>Xn~Is&`!Q; J2bz4){{g~xtW*F1 literal 0 HcmV?d00001 diff --git a/deploy/seed.py b/deploy/seed.py index e0941b4..b51d63c 100644 --- a/deploy/seed.py +++ b/deploy/seed.py @@ -26,7 +26,6 @@ from app.models.depense import Depense from app.models.reunion import Reunion from app.models.presence import Presence from app.models.pv_reunion import PvReunion -from app.models.decision import Decision from app.models.rotation import Rotation from app.models.rapport_rsg import RapportRsg from app.models.jeton import Jeton @@ -34,9 +33,6 @@ from app.models.litterature import Litterature from app.models.vente_litterature import VenteLitterature from app.models.envoi_contribution import EnvoiContribution from app.models.config_repartition import ConfigRepartition -from app.models.sondage import Sondage -from app.models.option_sondage import OptionSondage -from app.models.vote import Vote from app.models.sync_log import SyncLog from app.models.proposition import Proposition from app.models.operation_bancaire import OperationBancaire @@ -44,6 +40,8 @@ from app.models.evenement import Evenement from app.models.candidature import Candidature from app.models.poste_module import PosteModule from app.models.reserve import Reserve +from app.models.transaction_comptable import TransactionComptable +from app.models.mouvement_reserve import MouvementReserve POSTES = [ @@ -103,7 +101,7 @@ async def seed(): nom_membre = input(" Nom (optionnel, Entrée pour passer): ").strip() nom_membre = nom_membre.title() if nom_membre else None courriel = input(" Courriel: ").strip().lower() - while not courriel or "@" not in courriel: + while not courriel or ("@" not in courriel and courriel != "sysadmin"): courriel = input(" Courriel invalide. Réessayer: ").strip().lower() telephone = input(" Téléphone: ").strip() while not telephone: @@ -112,12 +110,14 @@ async def seed(): while not pin.isdigit() or len(pin) != 4: pin = input(" PIN invalide. 4 chiffres: ").strip() - print("\n Postes disponibles:") - for i, (nom_poste, _, _, _, _, _) in enumerate(POSTES[:4], 1): - print(f" {i}. {nom_poste}") - choix = input(" Votre poste (1-4): ").strip() - poste_idx = int(choix) - 1 if choix.isdigit() and 1 <= int(choix) <= 4 else 0 - poste_choisi = POSTES[poste_idx][0] + poste_choisi = None + if courriel != "sysadmin": + print("\n Postes disponibles:") + for i, (nom_poste, _, _, _, _, _) in enumerate(POSTES[:4], 1): + print(f" {i}. {nom_poste}") + choix = input(" Votre poste (1-4): ").strip() + poste_idx = int(choix) - 1 if choix.isdigit() and 1 <= int(choix) <= 4 else 0 + poste_choisi = POSTES[poste_idx][0] membre = Membre( groupe_id=groupe.id, @@ -130,15 +130,15 @@ async def seed(): db.add(membre) await db.flush() - # ── Affectation ── - affectation = Affectation( - groupe_id=groupe.id, - membre_id=membre.id, - poste_id=postes_map[poste_choisi].id, - date_debut=date.today(), - statut="actif", - ) - db.add(affectation) + if poste_choisi: + affectation = Affectation( + groupe_id=groupe.id, + membre_id=membre.id, + poste_id=postes_map[poste_choisi].id, + date_debut=date.today(), + statut="actif", + ) + db.add(affectation) # ── Première invitation ── code = secrets.token_hex(6).upper() @@ -174,7 +174,7 @@ async def seed(): print(f"\n═══ Initialisation terminée ═══") print(f" Membre: {prenom} ({courriel})") print(f" Groupe: Groupe Méditation") - print(f" Poste: {poste_choisi}") + print(f" Poste: {poste_choisi or 'Sysadmin'}") print(f"\n Code d'invitation pour les prochains membres: {code}") print(f" (Expire dans 7 jours)") print(f"\n Connectez-vous sur l'app avec:") diff --git a/docs/ANSIBLE.md b/docs/ANSIBLE.md index 0d732a0..15bcb78 100644 --- a/docs/ANSIBLE.md +++ b/docs/ANSIBLE.md @@ -114,6 +114,12 @@ ssh ansible@groupe-meditation.87-16.org 'sudo journalctl -u groupe-meditation -n - Site NGINX reverse proxy + SPA. - Sauvegarde quotidienne dans `/var/backups/groupe-meditation`. +## Documents liés + +- [Architecture technique](ARCHITECTURE.md) +- [Runbook d'exploitation](RUNBOOK.md) +- [Guide utilisateur](UTILISATEURS.md) + ## Notes importantes - Le playbook ne modifie pas le code applicatif. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..f903e2c --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,52 @@ +# Architecture technique + +## Sources de vérité + +- `propositions` porte les propositions, résolutions, nominations et contributions. +- Une décision de groupe est une proposition adoptée avec `date_adoption`, `numero_resolution`, `etant_donne_que` et `groupe_a_decide_de`. +- `transactions_comptables` est la source des soldes financiers. +- `mouvements_reserves` est la source des soldes de réserves. +- `reserves.montant` est un cache d'affichage; il ne doit pas devenir la source de vérité. + +## Backend + +- `app/core`: configuration, sécurité, rôles, règles communes. +- `app/services`: logique métier réutilisable, notamment `finance.py`. +- `app/models`: tables SQLAlchemy. +- `app/routers`: endpoints FastAPI. Les routers doivent orchestrer, pas contenir les calculs centraux. +- `app/schemas`: contrats Pydantic d'entrée/sortie. + +Règle de maintenance: un router ne doit pas importer un autre router pour obtenir une logique métier. Extraire dans `app/services` ou `app/core`. + +## Frontend + +- `src/pages`: écrans applicatifs. +- `src/components`: composants partagés. +- `src/utils`: calculs purs et helpers. +- `src/stores`: état global et client API. + +Règle de maintenance: si un contrôle ou calcul apparaît dans plusieurs pages, l'extraire dans `components` ou `utils`. + +## Comptabilité + +Les écritures comptables utilisent: + +- `compte`: `banque` ou `encaisse`; +- `sens`: `debit` augmente le compte, `credit` le diminue; +- `source_table` et `source_id`: lien vers l'objet métier. + +Exemples: + +- Collecte reçue: débit `encaisse`. +- Vente de littérature reçue: débit `encaisse`. +- Dépôt bancaire: débit `banque`, crédit `encaisse`. +- Retrait bancaire: crédit `banque`, débit `encaisse`. +- Dépense cash: crédit `encaisse`. +- Dépense par chèque/virement débitée: crédit `banque`. +- Contribution débitée: crédit `banque`. + +## Déploiement + +La voie normale est Ansible. Voir [ANSIBLE.md](ANSIBLE.md). + +Le déploiement installe PostgreSQL, le backend FastAPI, le frontend compilé, NGINX, systemd et les sauvegardes. diff --git a/docs/DEPLOIEMENT.md b/docs/DEPLOIEMENT.md index 5692308..c456791 100644 --- a/docs/DEPLOIEMENT.md +++ b/docs/DEPLOIEMENT.md @@ -1,389 +1,7 @@ -# Guide de déploiement — Groupe Méditation +# Déploiement -## Debian Bookworm + NGINX + PostgreSQL +La méthode supportée est le déploiement Ansible depuis ce dépôt. -Testé sur Debian 12 (Bookworm) avec un utilisateur `ansible` ayant accès sudo. +Voir [ANSIBLE.md](ANSIBLE.md) pour la procédure complète. -Principe : on utilise ce que Debian fournit. Pas de dépôt externe. - ---- - -## 0. Prérequis système - -```bash -# Définir un mot de passe pour l'utilisateur ansible (indispensable pour récupération console) -sudo passwd ansible - -sudo apt update && sudo apt upgrade -y -sudo apt install -y curl ca-certificates gnupg -``` - ---- - -## 1. Installer PostgreSQL - -On installe le PostgreSQL fourni par Debian Bookworm (version 15) : - -```bash -sudo apt install -y postgresql postgresql-client -sudo systemctl enable postgresql -sudo systemctl start postgresql -``` - -Créer l'utilisateur et la base. **Choisissez votre mot de passe maintenant** — il sera réutilisé à l'étape 6 : - -```bash -sudo -u postgres psql << 'SQL' -CREATE USER grpmed WITH PASSWORD 'votre_mot_de_passe_ici'; -CREATE DATABASE groupe_meditation OWNER grpmed; -GRANT ALL PRIVILEGES ON DATABASE groupe_meditation TO grpmed; -\c groupe_meditation -GRANT ALL ON SCHEMA public TO grpmed; -SQL -``` - -Vérifier la connexion. **Important : utiliser `127.0.0.1`, pas `localhost`** (asyncpg résout `localhost` en IPv6 `::1` sur Debian Bookworm, tandis que PostgreSQL n'écoute que sur `127.0.0.1`) : - -```bash -PGPASSWORD='votre_mot_de_passe_ici' psql -U grpmed -h 127.0.0.1 -d groupe_meditation -c "SELECT 1;" -``` - ---- - -## 2. Installer Node.js - -On installe le Node.js fourni par Debian Bookworm (version 18) : - -```bash -sudo apt install -y nodejs npm -``` - -Vérifier : - -```bash -node --version -npm --version -``` - ---- - -## 3. Installer Python et les dépendances système - -```bash -sudo apt install -y python3 python3-pip python3-venv - -# Dépendances système pour WeasyPrint (rapports PDF) -sudo apt install -y libpango-1.0-0 libpangocairo-1.0-0 \ - libgdk-pixbuf2.0-0 libffi-dev libcairo2 -``` - ---- - -## 4. Installer NGINX - -```bash -sudo apt install -y nginx -sudo systemctl enable nginx -sudo systemctl start nginx -``` - ---- - -## 5. Déployer le code source - -```bash -# Copier l'archive sur le serveur, puis : -cd ~ -unzip groupe-meditation-v12.zip - -# Backend -sudo mkdir -p /opt/groupe-meditation -sudo cp -r ~/groupe-meditation/backend/ /opt/groupe-meditation/backend/ -sudo cp -r ~/groupe-meditation/deploy/ /opt/groupe-meditation/deploy/ - -# Environnement virtuel Python -cd /opt/groupe-meditation/backend -sudo python3 -m venv venv -sudo /opt/groupe-meditation/backend/venv/bin/pip install -r requirements.txt -``` - ---- - -## 6. Configurer le backend - -Générer le secret JWT : - -```bash -openssl rand -base64 48 -``` - -Créer le `.env` : - -```bash -cd /opt/groupe-meditation/backend -sudo cp .env.example .env -sudo nano .env -``` - -Modifier `.env` avec le **même mot de passe** que l'étape 1. - -**⚠️ Utiliser `127.0.0.1`, jamais `localhost`** dans `DATABASE_URL` : - -``` -DATABASE_URL=postgresql+asyncpg://grpmed:votre_mot_de_passe_ici@127.0.0.1:5432/groupe_meditation -JWT_SECRET=valeur_generee_ci-dessus -CORS_ORIGINS=["https://groupe-meditation.87-16.org"] -INVITATION_EXPIRE_HOURS=48 -``` - -**Permissions du `.env` — obligatoire** (le service tourne en `www-data`) : - -```bash -sudo chown www-data:www-data /opt/groupe-meditation/backend/.env -sudo chmod 640 /opt/groupe-meditation/backend/.env -``` - ---- - -## 7. Initialiser la base de données - -**Le seed doit être lancé depuis le dossier `backend/`** pour que le fichier `.env` soit trouvé : - -```bash -cd /opt/groupe-meditation/backend -/opt/groupe-meditation/backend/venv/bin/python ../deploy/seed.py -``` - -Si le `.env` n'est pas trouvé, le script utilisera les valeurs par défaut de `config.py` (qui ont un autre mot de passe) et la connexion échouera. - -Le script crée **interactivement** : -- Les tables (23+) -- Les 10 postes prédéfinis -- La littérature de base (5 titres) -- Le premier groupe et le premier membre -- Un code d'invitation valide 7 jours - ---- - -## 7b. Mise à jour d'une base existante (v11 → v12) - -Si la base existe déjà, exécuter ces commandes SQL **avant** de relancer le service : - -```bash -PGPASSWORD='votre_mot_de_passe_ici' psql -U grpmed -h 127.0.0.1 -d groupe_meditation << 'SQL' --- ══ Membre : courriel obligatoire, nom optionnel, téléphone obligatoire ══ --- Remplir les courriels manquants avant de rendre NOT NULL -UPDATE membres SET courriel = CONCAT(LOWER(prenom), '_', LEFT(id::text, 4), '@temp.local') - WHERE courriel IS NULL OR courriel = ''; -UPDATE membres SET telephone = '000-000-0000' - WHERE telephone IS NULL OR telephone = ''; -ALTER TABLE membres ALTER COLUMN courriel SET NOT NULL; -ALTER TABLE membres ALTER COLUMN telephone SET NOT NULL; -ALTER TABLE membres ALTER COLUMN nom DROP NOT NULL; --- Contrainte d'unicité courriel+groupe -ALTER TABLE membres ADD CONSTRAINT uq_courriel_groupe UNIQUE (courriel, groupe_id); - --- ══ Tâches ══ -CREATE TABLE IF NOT EXISTS taches ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - nom VARCHAR(200) NOT NULL, - informations TEXT, - ordre_affichage INTEGER DEFAULT 99, - cree_le TIMESTAMPTZ DEFAULT NOW() -); -CREATE TABLE IF NOT EXISTS postes_taches ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - poste_id UUID NOT NULL REFERENCES postes(id), - tache_id UUID NOT NULL REFERENCES taches(id), - cree_le TIMESTAMPTZ DEFAULT NOW() -); - --- ══ Poste : champ informations ══ -ALTER TABLE postes ADD COLUMN IF NOT EXISTS informations TEXT; - --- ══ Dépenses : preuve, methode nullable ══ -ALTER TABLE depenses ADD COLUMN IF NOT EXISTS preuve_nom VARCHAR(255); -ALTER TABLE depenses ALTER COLUMN methode DROP NOT NULL; - --- ══ Candidatures : type, nomination, retrait ══ --- Ajouter les nouvelles valeurs au type ENUM -DO $$ BEGIN - ALTER TYPE statut_candidature ADD VALUE IF NOT EXISTS 'retiree'; -EXCEPTION WHEN duplicate_object THEN NULL; -END $$; -DO $$ BEGIN - CREATE TYPE type_candidature AS ENUM ('candidature', 'nomination'); -EXCEPTION WHEN duplicate_object THEN NULL; -END $$; -ALTER TABLE candidatures ADD COLUMN IF NOT EXISTS type VARCHAR(20) DEFAULT 'candidature'; -ALTER TABLE candidatures ADD COLUMN IF NOT EXISTS nomme_par UUID REFERENCES membres(id); -ALTER TABLE candidatures ADD COLUMN IF NOT EXISTS acceptee_par_membre BOOLEAN; -ALTER TABLE candidatures ADD COLUMN IF NOT EXISTS proposition_id UUID REFERENCES propositions(id); - --- ══ Envoi contributions : résolution, engagement ══ -ALTER TABLE envois_contributions ADD COLUMN IF NOT EXISTS resolution_id UUID REFERENCES propositions(id); -ALTER TABLE envois_contributions ADD COLUMN IF NOT EXISTS engagee BOOLEAN DEFAULT false; -ALTER TABLE envois_contributions ADD COLUMN IF NOT EXISTS debitee BOOLEAN DEFAULT false; - --- ══ Propositions : type et lien candidature ══ -ALTER TABLE propositions ADD COLUMN IF NOT EXISTS type_proposition VARCHAR(20) DEFAULT 'generale'; -ALTER TABLE propositions ADD COLUMN IF NOT EXISTS candidature_id UUID REFERENCES candidatures(id); - --- ══ Répertoire des preuves ══ --- Créer le répertoire manuellement : --- sudo mkdir -p /opt/groupe-meditation/uploads/preuves --- sudo chown www-data:www-data /opt/groupe-meditation/uploads/preuves -SQL -``` - -Ensuite créer le répertoire des preuves et relancer : - -```bash -sudo mkdir -p /opt/groupe-meditation/uploads/preuves -sudo chown www-data:www-data /opt/groupe-meditation/uploads/preuves -sudo systemctl restart groupe-meditation -``` - ---- - -## 8. Créer le service systemd - -```bash -sudo cp /opt/groupe-meditation/deploy/groupe-meditation.service /etc/systemd/system/ -sudo chown -R www-data:www-data /opt/groupe-meditation -sudo systemctl daemon-reload -sudo systemctl enable groupe-meditation -sudo systemctl start groupe-meditation -``` - -Vérifier : - -```bash -sudo systemctl status groupe-meditation -curl -s http://127.0.0.1:8000/api/health -``` - -Doit retourner `{"status":"ok","app":"Groupe Méditation","version":"0.1.0"}` - ---- - -## 9. Construire et déployer le frontend - -```bash -cd ~/groupe-meditation/frontend -npm install -npm run build - -sudo mkdir -p /var/www/groupe-meditation -sudo cp -r dist/* /var/www/groupe-meditation/ -sudo chown -R www-data:www-data /var/www/groupe-meditation -``` - ---- - -## 10. Configurer NGINX - -NGINX fait tout : fichiers statiques du frontend + reverse proxy vers FastAPI. - -```bash -sudo cp ~/groupe-meditation/deploy/nginx-groupe-meditation.conf \ - /etc/nginx/sites-available/groupe-meditation -sudo ln -sf /etc/nginx/sites-available/groupe-meditation /etc/nginx/sites-enabled/ -sudo rm -f /etc/nginx/sites-enabled/default - -sudo nginx -t -sudo systemctl reload nginx -``` - -Tester en HTTP : - -```bash -curl -s http://groupe-meditation.87-16.org/api/health -``` - ---- - -## 11. Certificat TLS (Let's Encrypt) - -```bash -sudo apt install -y certbot python3-certbot-nginx -sudo certbot --nginx -d groupe-meditation.87-16.org -``` - -Certbot modifie automatiquement la config NGINX pour ajouter HTTPS et la redirection 80→443. - ---- - -## 12. Sauvegarde automatique - -```bash -sudo cp ~/groupe-meditation/deploy/backup.sh /etc/cron.daily/groupe-meditation-backup -sudo chmod +x /etc/cron.daily/groupe-meditation-backup -``` - ---- - -## 13. Vérification finale - -```bash -# API -curl -s https://groupe-meditation.87-16.org/api/health | python3 -m json.tool - -# Documentation OpenAPI -# https://groupe-meditation.87-16.org/api/docs - -# Frontend -# https://groupe-meditation.87-16.org -``` - ---- - -## Mise à jour de l'application - -```bash -# 1. Copier les nouveaux fichiers -cd ~ -unzip groupe-meditation-vXX.zip - -# 2. Backend -sudo cp -r ~/groupe-meditation/backend/ /opt/groupe-meditation/backend/ -cd /opt/groupe-meditation/backend -sudo venv/bin/pip install -r requirements.txt - -# 3. Migrations SQL si nécessaire (voir section 7b) - -# 4. Permissions -sudo chown -R www-data:www-data /opt/groupe-meditation -sudo chown www-data:www-data /opt/groupe-meditation/backend/.env -sudo chmod 640 /opt/groupe-meditation/backend/.env - -# 5. Relancer le service -sudo systemctl restart groupe-meditation - -# 6. Frontend -cd ~/groupe-meditation/frontend -npm install && npm run build -sudo cp -r dist/* /var/www/groupe-meditation/ -``` - ---- - -## Dépannage - -| Problème | Commande / Solution | -|----------|---------------------| -| API ne démarre pas | `sudo journalctl -u groupe-meditation -f` | -| Workers bloqués au démarrage | `DATABASE_URL` doit utiliser `127.0.0.1` (pas `localhost`) | -| `InvalidPasswordError` au seed | Lancer depuis `backend/`, vérifier `.env` lisible | -| `InvalidPasswordError` à l'API | `sudo chown www-data:www-data .env && sudo chmod 640 .env` | -| NGINX 502 Bad Gateway | `sudo systemctl status groupe-meditation` — Uvicorn démarré ? | -| NGINX 504 Gateway Timeout | Worker bloqué DB — vérifier `127.0.0.1` dans `DATABASE_URL` | -| WeasyPrint échoue | `sudo apt install libpango-1.0-0 libpangocairo-1.0-0` | -| `seed.py ImportError` | Vérifier les noms de classes dans `models/` | -| Console inaccessible | `sudo passwd ansible` — à faire en tout début | -| `type "..." does not exist` après ALTER | Relancer le service pour que `create_all` crée les types manquants | -| Nouvelle colonne absente | Exécuter les ALTER TABLE de la section 7b | - ---- - -**Hébergé au Québec · 100 % logiciel libre · Zéro traçage** +Ce fichier est conservé comme point d'entrée historique afin d'éviter deux procédures concurrentes. diff --git a/docs/Liste-de-prix-rev.-Fevrier-2026.pdf b/docs/Liste-de-prix-rev.-Fevrier-2026.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5674ce11ca593580305b62162562b421b719da5a GIT binary patch literal 307104 zcma&N1yo*3vNnu6f#B}$@Z#?7?!n#N2`+&U++BmaJHg%E-QDdcnKO50)_=Y`_g$;m zUAt+kdaA0scQvWJuqZ7f9VP2L}NIfvtfBJU2JJw7HG3zJs}ku@M0y zy)*$68-SgaonDTB3BbTeFG9e?$i~dTLN80eM6dk25WvPkFHWFEz{0}tL9*!Z^1>V2 z82xUG;9tLwJ^)PY|LQ~7*wEIbTEwEj$;h3PkGVoUHr z{T`$uy|l57sgoH2BjC@FT>i|Hoq=A_*4F7a9~l1plhOx|J}4GOdS!PzV|sN(V-tEc zEk*(W0pkZ39Gx7D^{wGy%+?GHjPwxo^bGX$=D?!iN(4xzi4g}gpiKJxjoJLg`wj_W za-oE)IRXZ^_2O;2tk4;nAWNALOA|3^wh-oK;aJzNBtYKMc;f1SZ!DD>cDj69Vne3eWWDNCifUfv@=p)&HfFXd2Wzk~bVLqht z*O>m2kE4^mgOi(su?aj313U~Vsfe5?Jj_33_FG~f68#@k2oW%{vHz_=2$&cc{)b^7 zOp+sDWM!gPB4A_x4<_j8Z5Zk4H4k(Sbt1l{34{Uz2V$sy&7pzALB_c2V`gAT3zBeB z7L$CjgVpWq{4qB<+0}`IH90v6qzVG24L3p^?^nx=IQ&&)1Op6XzS11<6QBYht6r|W ztd=!e9_#C0>Z2HSOOT0KP4vsQpEGHK>dR>jSERM<`(frH3Yy>+oD8RyjphJgsF(ts zir{~N33bOvQj-EQw}%KO5^eNU!BnqZ6H@U8hGGEPvn1mG8;<=Y`hO~lzKtox+dGgb zkRlK*kPwgnCB2NkgXM1|eSrFR_Ctl79Gs0mkSt^Dq;I6}q)z}~`GXxfXD6!r z2K=Gr^-YbX_1$fqo#>U!ZA`5`bi>q`{`Vip->78!2jD&$GjvjRFgE@JL}u1MZ~uT# z=%Z~bTho6j-*0XGDE@1xLbf(e#x_olS|6|f)cTF$KaKv*{K5S1%x^28_>p1!1MuIO z-);PP!~D<8pYiL^3pv=@3EH}8(K0g9eP|aG!9Sm@3=DJ(0Coa)2EgwE9eObbTW7nE zwwV94{=o?&bN&BY%@6zVG3bBIU(wjn*4e?(_%EAb>!4((Z)p76fGB;~9stvy4nCMI z;^ri# z3F|)t{v!e2kKc!7`8{3&270AGGXBTR9Y1JgeFH~&rGHqM-*EU33IFc?FA4vRsT4JL zaQxsN1K@wOlLY|yZMgq3SRbQNa5@vPwGC1A zoIrrDtR)r5p-4cjb#?A4CRtA^6?TG(p^1p{vt|486mLyo%U??n8r>hMtI{aYJ^)oV zP*weNpn`Q388q^Y1aJUV7>f)$f>5bI$wV_6;XzEfNf-mnt<;2VSqURiU7AY*<2uW!RkbkCF{$onKLxL~h9M=_A|UT#4BL z1=)>_KChe@8M1?!lMbkmxixw*yRMT=7zohV6B|A5gO7GTqUsE|F+{$h0f!p3Pq4z% z>`6SU{awrbTdTF9;p|Cbm9|Y_%-F0o^p4)`N_5~2*I-*#s0~-ht2=Hu}dcA0R+I?Z>JdJPlL_$b{2HAs7IkcX`wWfP}_7ufHRf+3My>G(G=_9 zlr&J4ydQEdi^CYR)Ud2n=nDl-f6zTF_>LuLNe-_IHt$?3xfG^at~m*_Pjp39EBQpE z*~6*%j-fl&uI(|<3Z=XVJj1YpP#7tT5L9F)$m|82Q;nSiB#>Xvny4`cWDdULt$$Qk zBA+0a$2b%xhDCJF(Kip` za2CBN;DGh3yieA$#}jW}9_~-i2P%}F6t#yn6A4Q**{cUP@@6I8Z52mfS#48*I4#ag zhes7#JAj$F&wM1XE?n(YrRcoOg~W_Mfz$_rBn+q^J{v$22RAAtjVN*4 zld|Vn&*Jz=o_UdH@|Q55T5oTCtp7r+;MX~%Dhl=$hFl(7X7N)kYIt<&ePtu{Y-g=+ zs&>Y78+1zrA7P%@$&nG|>AZA`?V0yqL@(2ULIW8XR0S zV=4je0=1GO!4tsnBtUBku_GYbZO^oEJKv}ZmJ1<@;(pJo)4V^lZ0VMw_0UvyE)#NM zX)?f_khJ#o_@Y|ge|=9|)rG`Xrp}}XIw0gbci-M?g)8-C-J9F@-Pn4d&5nf2zV^Jg zr0rgaaOR;FMF0MpHxl1Ji^pb-4r|@5QZudS<*}GV)b)XIolp_m7TM541X2`Z|9eXO zvEIm6T&AFQ+d>E2*1@wJ67bLA_={a+cvJ4tMwDZ57kXQ~ZC`{BWwZx>h&Hi=pV_QX z&@>>SS8F`_R{{r@Ib%WW%KpV5k6s9_h zfQT<=0nk&7A)@d;BAZAyWA^;L9D^q11;mApB_;UF0@a1EDIExmv z@b{~o-;0y~w}bg>mHgpV{^dl(!?fc@!?*ZRg6`eJHC^aa%#P-0g9sKTA<(aT*sp;Y zDNp%R1DWW&o`1$p-*kd8fAKlWhysmo$~h6944YEgJX{PDBhMJa8~fX2gJ(m%Lf?o^^`v&O4seZn z_FR)Aw<;gk3A9dVhuE`3V7tedzDwuByl(IPe)@EAtAZIanWyq#>E)4<>)=HusMKh7A30j=`i%dt8 zl`0HUIzV9$lJ)z)JlM6mtb$DZG|bSFa7RCxh}8rvPM+wwFmwGcr0N}&M|@kju5m?< z+G5Fp%HNTk_h(7218J!SHbYI6dj~XL~HMu|Wykz(wbQG@loFCp_c>a@I>^U*N zWAIGj8KF+2eei9d+iU&BbG+D*_AaW$JC8PAXShbFmL?bUsQmHWAU}HvY0vO=>&)s40mxaLdY0XIknHj0<7ee~( zfZ~!qnFmr#fZFnLm2;X$cXm*?yuFDlE04#Ynue~uF3hnD&1-GjW7)QgG;Y*2SfqYE zTz+haeRnZS3#Vw*Ex-&Ja>*TH3gtbpOL+w;AqVK%mF2M6PTb$YlvL#C3MsFrJ$C`0 z!ZGe}V4NJ}B=)tjf(oK^v&Ls%`{=TwT<>2tu?LczG{i`AVWnwL=h&X0s-R5|5pqor zp=w^Ab1zCPoQoq#xvDG>I(iJr+&*+tig3@)hWGudvciC)k%HS3j<77w67CB$u;p6HR zYouf!0dK||$Skpno7u8|*4XCyez9rdaLb>;x6aGO&Os7!a(0G~_hYi~GjUFi^k zHUo2>gYJDl$+YNYb=zvC@S(#PRrr3fM(VD*rn_d}xV>{cJ&K07|GsKL$b5`7>v7mg zyhtPX5_lP~?pNtvU6;lb`MK4v?YcLU(BEGaogo&(M!zkYqtjPdaVtzhW5TWoTEP97 zD3rQbdJ;C<5&vSC?F9=IrGo1^wu5j3Ot!mfS){G;JeN)50eXA63z4i|h#!h9qOKsH zb1F@#9cyJJMHrW2KY4b`SI5M@!q_%lVC?Hc4f#t7a_-h7TN?sB(|Gb3IX;u=?MQgb zke+D@$1%Fgp<{vh?u^2BK5y2VjNKg<5^G6X0uEU5F%U$wv^WBwscZO)@@|;{0#YLz zcx>avRef+W4m}s}FZ#95=YccIsg++OEtE~4L!wP`uDuu6Yjb2&z#~O=18pj1(D9DG zJ?G7^gISUo>6^mUJiW5+&(${KMqWOfNw@58Fa`k=Sz7C@g6y(t{2EX4m;9k4UTUvi z{i3oFm;iHL5T8>@0^%s{*%`ipdbYvQi8KNlv5f4a=7-EbG*ORo7**yRV-Cj8AVOVJ zO-&`#Byqwy2qKuP9d88+MZM*I6AZJaUc8?zxwRwJQ7Hvh^A!eML63SzKS7Pxoq?w3 zRyOI?&$m&<(^rsf3&uImtSW{)~!eZV}Bi|xsd9(->_p~ikl!_64H zckkQ_@UaX!X(UDR24NZo9E{ zIXkezc6WGlScip4W5ux0P-5?ipMp;qJ%fpF@L)S=v$HNXp3&X)>gALi_6%(@meV?c z$`QmtDJb${;F(|a5)ET*v2Z3M#r6G3^xX-68matXcF}lKfnbqFe6H!ltDAVZW~S5$ zN0qC;{Ip_|UvZfoVM3M#zOHf_$rh-1`3@_YA0sb$mUSXd1Wgm!ulPy-rw5`P?vvLy zV_iYVZYe8Zlvc^o1c2EH70Q>ub|Erw%QcA@IWI{99TOKe$!3(yT!F_|yiqH~O^GjcjMvhYR=`LRr*2BiXW&zYWPS+s% zFl#N(YnTId=37!gtYIr>xU_$fBLmRG!+)<~5Og*W~}mcefPl{_geFaS2!7v+Bm;gctgFe6R$? z3e^SFxdp1RCe)MVtLLDqy_miii>cu}q`Fz9YFTH8Eov9ZKCll{mI5!XuUvJ;5b49c zSC-sz;dkqbR1*##KH8@*vL>S^_%}Esd|RQ+hv}g>(CtNu_^JnKz_M{BvmD`~^H6OG z$now>)OR9! zvJ@iN3W8+eE>TEc*1=mA){A#>KhjdJDC5M@t;<=9mNJlJ^Pha;l0x9v#KF@kHgKsf zZdpLKP6n05pR@8ozQiVsK*V#&XYU6l;!PKIfFeJeV0k-yk3Zz_kRk(^oZgD_)A zM6oO>MbP&usT31r?>2=%v6eUThPqewi9&3b;S<)@mh-bD;7=|Z zPIZ=O)znHL2F1y!Hzj%x3y~kNf-F^1pjr768M)uY_jQq-e(_M;_1Wu7eczT@_Wk0Z>v1w-fzGj8or0?%boD$y_^AI% zHQbcvU%KAqKOIwgJ!FMyL|fC5lBu?DD?4~}$aVGdIL%gAF%DJ1;(occ1Lv9=j4YcX zM=gqpp7$6MXQw&_1%Rc*pf%Eo6@;R~01a!I4Y{R97YwB_Eh=jpagedB4kj;Z{gL7w zgt}`a!$e*6I^XKx`z5ECK)?i- z1_*H*oer!_@+KTs6Xsln|LPaTR}nhy7z=r)HEAdNGiPrNdresOIHiKna^`sOpG9ap z`ZZ6nP9?E>K%GB}B6OTLE7!atvt5rj?ho$U)|>3d>6Z@^t><0ejaN#~FQB0ypl?1| zAS-n<7Qs2$D?^aM##v5I z3=RI=>~Kdo;4|5y7meey*d8}akHxQP?W<`6f^w|DpGQw7EnkF3D(ALG)^$L4NhJBT z9!Lm0V81EY-#q3FC9x;Olp{ZaA_`hlj5v9D_>82TA0Mx9ewWvDb=X<9R%6fYS1u>o zb_Ht=?9-{;FMfpgdPi}xG3f)!30}^+N<(ytt#0)~8B1@QzBTvSK!4uGvxm*HfPQ1U z>`uk~omN&5Vtx=vBh3rGa@YU@1@=S@aOcai5v5GQ+P>m)4Rc01-~-`Qvda}lV#7y@ z(6KgZ4VYqUvEIP`#sh*bZ*^X%n0jH-x5A8cqHoB_eR?|kNy#VooUHgFfw45Cu_Zm| zkp0;82c?VUx18*1D9ogppHn&C@~5_#*hRN~bS=dWAXyycO4crkZOPl6UPI0CpTsvb z-Tzn?atvZ`{6+3g(d!UaLD1twYyLBPu5c>MlgvqQ^7AN?(e(Er ze6rjVn~t`7%sPpD1x)kFK657^?^%NolPL-ry*vywdleQwx_BZu&Z4!(@}HSCj(ZE2 zh_>}--%Q(0p73bA9v4Xm=njbwkINg7xJXj==+4SH*_+h;aR+Do2307jhJ<2Dq$#MP zWXr=o`f57!TrcvK&5z%)vemq_U@Rl}iXcnFpEQjn3V~tM|IV&Vv za?$6Tv2(D+68I(nZ}$WcRVfCNWo?UV(5dBVc3BM#u=oLN0tD2uQ1=8!fu6Wz^p+}} z3tm#3ofUM^d!rXS~ksxBg8`C!XT77aYD;DAXc$?=)9JUc=X=A)#$SI!|a1u0&C8FAr z$ubsQ^4|GE5^?-PMiY8&iGj~enDa>3qL_t!=SeOsRORCaS75nzl6M|&xmM}{tn=I0 z{NpJ@%TwEA+VR$@gwp0>c5cs==Cs)+OFYjD*4~90cY?Np`D|{BsX)2xs zG^v?5u^av1l<4*bUYUkz>}*Ha`4*3u7euBu3<#!{)1BTR2#tkGRn?yNqfslnO50g znzbBa99B3DgC;x`J>CkI)WS6yM5~(PZ&X+E*uq>{06X+<(JEnGh4s~FkZ_{N;UK^E z6Ni(8u6iClmBZdg^KtQNP^fyH$LG4S`^O$LUZ}gWYxgc?-iZ}l<~3Y=-Efbz>8`O) zJPO)bad%i_hgx}GANQ@vY-hvo+M0RebN$NwEtS=&7ET(wSl{XFGpUM|9K#GWZm$j0 zufnu2e{#F>OC9CxbOoWaz$uiXhUcbO*v}Uv`YL93-}4>KkkR`i*$sL+Kc`F)l}nxu z<6U)pY}zJo;>Z5ph5Y^|_TOCyGXv|tyO6vO7qZQY*#4|`F|*W}vZ;kssh%}x@(oR* z%39}U;%1{yQd5tZE0v<lr#tm5bQ6z}>Bg;rUMmY+#Lv@>K`sdpPeBf?l}ze&epTwT z!aWXKSTiEs>5hxF-4%7Q+NgJy&1$83by{kr3zWG!EWOt6-{rRRw8gP|7MqrIF5Q zzadO*4uCKr@E15SEI4*yOM(L+EB~|15%hRqzM5XJ3?u-wohqJeMnKJ0Y;Pt6GvON( za&Z#*o1yettS|YXAN10)-b!l^e*erV8qlmyOSRUz3oK{;I^K2M+v*#FQ2uv%=wzBV z9Icp8$}LkYODQaTbl((e2@^ZxU*|&Y?MNqI%N!Gv^w!AVQ&*T|Hn3Ge&NkyY+!oEU zX;%rir!$y@;-N`RQnK-^K#CjDtkniSC*BLySO1`TGay zVcZWZ4+32ns3IInemctRUq8V=EN?ynv#<1!+Ysd)7x5qQ5nvb{_u!$x!ZwC+C?k)6 zb>}(J$nJ?`6ADJB*$PQN=CJ! zUool&j%^RPEZ?q2nN1fX!49x81;n<1I9mOv=eEABkqAT4?8vjT;p_}IL9 zz+2d6oQv?YZ-o{7sK@+@GWluHWZPt69ejT_SVJC|h-X}Zgl>e(8*n03F*sv{>3^0h z)xJ^vR4+GrhrGrUES^*k=A4DhIJ{#ntIOv#Vn5BvL|B5?I(zj7=jAb!DYr-*&&(dP z&&wG)(|7^I%~|STvzbXtw|Ru5iqAf`vQs(IQit)=)|jKDU1YO03DO)1tI#u(4SW6a zi34{6av*iN~F6XU5pBgMk*QY7gFtI|oD$fh7wB zs`wzDu|cX&xAY3EUJQr^Q^>A7<4GeSLo?}TQ8V4yr_)(50I*k9skHdAZ4_Vi^`*Ow zAnL%{{3ai&T**0H7R|`FA`-UP^lL|CIZ`ca3D&^15x2*%v+BQh-lzu=VKo6ag%lmn zMvcCfXV^$y`|ka?nsue@Eg{6W42Tm>)!M;(O8?4|m8VW6_hZe)l;4D~agM3X>KT|^ za^Hp&Nw{p)zWG5z3IhA0K|V`wxt667j=^?c|IEY}xgp+zD>qW~DGR!~`xy0JI}Arn zQT9ewT4tT=>Sk7Q(4yRxh-~XqnN3IVxvO5Fcg?cLfQ4;R;~l%VYi;f!EYXNSmQgY;b6-8 zh05Q_BOGeExjsV_iicK$d_HRZ`i86rq(hZL^Y>=_-{QvpCIaD~VN`4k|FILORg-c2 z2s3CqR@*SKCo=&0LC_`L2XLWj7-Y9bvYZl{0;L7mFwy;7QjEQucSY|Md;y|8n)n9f z*Lh~J-oDy#OV44ZHmk)Dz9W#h<#G)b?79)RaqzGyLu#()g1 zirA3i&JHu;I7IeRW*dr5N8hc*^>91@^1VM22M= zDdI_3$!Y{sZbpP7aCD@i!Xewhty65cdBf!~;UYL9>pa5WXk@ztS|T-u7hdj2kopp} zn$y!e%aJPmaDA2O4`O2-@o1F~;G~QBh`UDf*6QW53(~o4dRb@B^mmH!NTVVH*$XMq z!ypBtfTFJrpuk|1e&MBgn*v)IA?3@!?vQRkJ*D;jdyEqZUE)VW<}=C zDtfB$U_o-&x`+5gqM2;s^^Zhe;J-puk_{}(HN|w^vHt)%_C=bWb&;~yXBfK+IeW!u zZ%zr<;0#W_Ap&c$+zuW?rjkXG@VqBfbgTI?DT+a#UN(GuJa04T1!CPH?DKVYH~!m- zrR(tS5N+e}`_6az)h5dZAN}_XVYk9ZjW{zL`c-`_^Vd41x2_D$n0oZhZ{)mI?Al)V z41NbFOsdIIvZdpkwkN=BDL4gw)f^FYT01jngkBVyP{IN@~!Ye+}i55-XSKpDwnM$ z(mrS}&gk)SKOvJ}IE2&z? zNl)?B?#+oj^Q=3KcaS{(r7LHuhL&-AcWyz2DDY-#{Z{Dtmb&n`=fupVjYsHl=R}w+ zc%v;t#L1z--(mmbWH7YYfU|rf-6^X^?PT1Gw92sK`Y0>F`jXh@SAwh9?wYEr#UpEE z6sG2-%m(^;tp@f9y@)@t74`hR7T6KNkgRZ=Gx>AKYr!t!F3lJq>KY8jRaab2o}ChC z=7u0B7Svq_AGj{RQXvg-N($2abOkCsWM)ii3OU#gP=U{79V>B$ZGG=NDTp3%-}Y8O zvI2b`gQ01N3f-T&PsI|=ngX%g{If@v3ZxOQUw3p@`3}Ml-cBu&f^$n`w{cm-sZ^m* zf-e!txA~l4y>I%gMRkfKMa}zdUNz4bWo5PuQVl05PzTY?99Ke!wxHF0(iJPC!QzKy zCP5C4f*Y94_fXu~iY3wt+!f>de53BxcbC=qN?lDI_JmV>B-J?6^@3_18|vPzy@q=qj%{n?Gg}G=QWSX|c z-7T22dO@s!%6nvqj=-@i_9{l>-)E2YzZ8AC17@9RVe_JzxUS5Jz{fn0HRP>YeEuTj zU0H#%!>84#NX>HMXXLQ(jj>Vhy0&tB$_??B6Y+LfMa<_+;mMM03j~~$Q7^C7Kaps< z%Kzp`e$>bC_QZ=N5|=>eae%O~=(TN8VWlCQRTWAurI_pspHoR7#Z(*?`(SqB;XG0+ zNi$Y+8p{G0z>v`W8*~wDwPE@m+%}}#x~dEJx4=${o-e9r3(rv9Ypq>2#dWva7NJUK zRS@*FIBS-Be&=oy{-DB;fUb}cc(X}sTDhwRT5kTeTD5$^=Bx5@XcQaj*8@9S7u;a? zxY1_!h^B(1RIx0Hn=aH5Iaswgi%c5^EYYqw+ z7T`9roMvDa>Bz5ZZq2lO*5rt%xth6HcbOl1mi*HKp1*Z=f1)D)`<{gb!1(WbmRhyt zm>E_?@63t`tv;2i$yJwdqF!BbaeECt)}P8`2tDOB@^uTt{)8{ynrc$@b=!UyOmhp0 z4NgxthY2(!LyX@A=TZo^`MGYb=h|R8Y_7&BDR#|sUVn+4xr3j2BduTM+EU6YzsBl0B6}qOMD#F$qL$k3~&ujJ65wRgQVO0AfxOf=6})ISEkw?tdj{ zh}4+%t0|PJ$1P^sYWD}miW`T6?3Gc20g5+2Up0 zNu{?yt`b454)tisSE|!l=RO9wwIj%r02Hv+MuF+na}g6o!&K5kA)%*{K-ajH)=vAc z$%WC4#0?rv+zoa1{Zq*&Xml;^Q@G?`qF1}J-)bYO^p|&8b961P8D@195nw&kpj?Q@ zoDI``*SUf^R_Z=yMwC-T--VwK2a^_>5aCBeKCav-U|!Y{G1Oh#xCF$LlzLUofaz_K z2$2c)Q15@uDw*Z)Ga4yU_Rn4AW)<^J!2A-Gk@`-5`d(;(OqD61wQ<`g>uX~-S<*QE zR3lw@)uiKTlqq+TgTA-Pn`y!{aG42_4jV-l$b}W0dpfI-3Y$mc#`O81XhcSPZfti7 z1!D!b<XGj-Nt?oylH%yd3cJDL>JjOOE_D} z{W#ZTtVRQk0?AHa17Uy2*E>QR1z5l$!SZ7wh|y;Tz@`WGcVu*Mk2;jIzF4ej47LY@ zHY&3)ih%5i^CR&N3rQe8cp`=LqfUiXar>a}rtrxG-3NLhrgEZQg^!1DC!{u+WhM*r zH5f1^1Q|a2M)kFZ?`#>V3a43EV-oK5h-$^pQRBC2I^OAzs@HL`aPBeNJ2nWH%4HI`}WDD__*A6^irpwq1v^dz^Z}{R3z~2Os0)+!%ig~M%+DawcIh;VzU!5GI=d~^w)scm}i3(vUa zaRM|`y9ev*!JK=t;?-l#lsBhTfz0X*)H*tb%zibUTV2O;A|<_w|EMF$Cof!C1FnT~ zUxkCN;$^xtyDFu3o7?kVF_vC1$m99GgqBbl*{*>MX#&{5z_6fXJGPydvjmVAoF(<( zPvbPVoc+&pfJH~=6>+#kl2p(=e^h29KzhE;*43yH7=nS7(r(tTjbTsOmYJsxA|ZSzaKpNG#dv#s5)haAPcBeX@9 zemb@$q5I`OEL+_`dFa=QfJ4`En#8f1rTJKNr~911$lx*^NnJgjQO*YNmBp3t^0bJ% z?Vf4G_RYjK?w0HQH2NLt9crr}5-Uf_)zxXVoeEsiXz4@Qe|6N(c9KXK_&P8aPQ#l< zq7Se!q`@d|fU6NR9z(v8cLK@p#CiO^5BayC{QqUc1mO6OAd*rwosYO|6z}_r4XrYL zlSfiXEPuF1tV)7a807_q5pO#~QpM%lFZ|!_{R8cmgBmN6Xmh~ zkr$Pa(2N~Ig}b))vrwvX=0s&azIw`*^xeUe0Qg?Gf2d!C`!Cc0ulcM zf%Y2A;-S+$JU15ZS$^LrYd-AnGHwqHX>|ZtCp1p6=JDoVVbXWzQ316jO8D8hg^{A* zy;X2AV}4FZ-O;f+lL9ZJiopI~G`iEyHo*_jk{Ym&kX-yzA;8Zyj9Vz%oL-R2Ff5Te zKs9yNZjhj*jIhfdc!kAS*BK+u3uVP}IhXW4q1H(saiU6Zu;D5j3G-uO zvx=ul>UYZ;Iy9r)`ElhPtkYpG=hYUDl6_=2drUCLpMPELUO8E-PM(6kc6I%r&R^va z{Iz(`V!FU-k7M>ZFxS1UwihNQXAk-atwlf&H|RTyd{wK>^b=*6(8_>c3=4&2Z*_6B zhWsK*+^CTFv{Zbb5yU0>!DSt}$~5ze*_{U9C+r;hE5S0|Og)V6JK9og%@D3#LCxlp z#Nm@>kuQl@_%enP$yO-kjnV{)ZZK#2fRNcCj+T>y<0``vYglnDe0HgYm{--$`&NY& z7e|FT9pc8cW-Q}?vu0=qGKKLdUu9An52s~Z45Mb|ECxi1O!(>8smVK{u84w5anH}Y zxV(M3%z<$-^@$DmVJ>_U~@6Lr_W+I%%T5$C+GFZzH+O$Py z$DPI@CRXjYOdN&y?$VscKi$cJ`k|7yc@RD|#|Q%Ac+|7i&aMn4*US&J9$t96#hL7H z@{>D@gMv^qak1ku@|8%>19ZDvVYzu+&uI#Zf4oH+=-r$q6^J#hUhAmMoLx;{`oo*N zS)W%f*QM~jU>_TTJD+g;3di6wzW#xYA!FLuMc!mBOp_$uXVTae0?MZD?@rJ6y{#uf z?-Ews-+0@CPX;_;5SaXeI2U!>tNJtd2n#uMt&o&DSI1mShKJv9)LHYv?0wSb6Yf6F-rdT}#YItyblhe)f&#nmpA3#xog@8Un{E|?_gZilDC&v$q){1=NZLySZnSB9M0U5h z@lA12g$z751Ij&sWpY`y(O&&ehh0X&?awYDNVFEX*Z}5qP+X1p2l#7f=U9`BC06B5 zv|fg~Ju2jokwrHGKb6DlICOlFcM(!XUWE(FY2CcsVOWSRlazWe$bJqM@7iq4u|rXK zb$)jqna>{}%I#N=K9vjcSKk)sChVFt(cK>_Z{l8zg`RlNYiS<8BxAu=wi=N-{ ze?Bm{%R=@kq{fiQ7`Q<=cU{#yUoEMV^{XPcajx!SPp7)T>U{*Ch7%r|e9y|lI@be~ zKt(YkXMxchAcE|A2i09l1+YPfd&mM0krzxv8Mgy{#Y#=5Aj0N&7; zAq>eEywgK?F7$8TAWdsOQyp+luq)=GAAZ@5=&U)JupCNl#1+3*yKHg~;S5*ymgq}Ud|cFStd}EOry}w_Y>yDYu~l!E`k?{9fOHzh~(G zDZHGS`9H(UV@GYe84v^i5m1RLzNPbnhy?8CuWUZ5Q_#R)6XLyL((D&^w?@UP7I_== z3pHFVnuV#WF8eK$c@^2VcQ(xZV+~z8PnKqB9F0o*vF;{I<(R(h1?zj-2ohMm&&$S6 z`{{gl5*jHtv^KhZb^zDodcMYI5^v}-*mS<+mZ;IUwY=wJ2Ct@?>)hnz*`eAq3{alg z9!GB%vUDSa7S=P@?NdUFH`&&82-E6APg#J>dh@V68{N#?PK*OuW;`YSc8z43?fWUZ zIu;G_NoU+XJBdt%lN7P`54MW zt^T?QDS#j7jd&xV{w)hlUk;4t^PTF1mcA``8|oZ&k(zo%macJIxJP^jYR2Ct9~2+7 z2fl4M>u`zF*5@`EA-<%d?o=;W z2B5W@<(5b1^i8CWBJtueORq#diUgJ6qbq0M=XPf z%jbIQJ~8kzhhRLDUbp+kfP+hy4pZOg(Hw0$a4Ldk92yRTeAt#mjy;Sr+k=2zraG=t znvA1#ZR9PbBYZ1jA1AroJi!OwOXM^wMHw2=-`#(j%o-JSvx((A}I zZF69Z4W}~Y&fp*wKbZ1Y`VlRuHhW)uuVnyNRf^Uq{plE*Oj)22A&aS5#hI$YjXh>( zwGmzdTIXk*n1n$@)&%@)7Rf>WN6*t(KkzU#CibGaVhC8^X8?875&I|>(oekvo|Nrbh`}E z{`t02baV1$TMCMPY|eALWIO12P2En~B1aJcPzvaUxm;mfNoA_)UoJP1aIZ=z63OsD zp!H@DG-&uB!5Hby+wz*9;9pB?g_GxSYD8^hvr&{fKm}>U`fZ6fm8E!ZUy_13euU<0 z#Fz>YNs<`gRrV~R;ZbGEu{ZXnbg@jyM#H2z<9=xEOrsLtdUS}5=&&kW;Z@+68mw1MfC`TXLpw3z4V+d<#(90}7!g^Xk z9zqD=y|HxjiS$-ClIUHi+l(Pw&;l@DlK9@4nQ_Uz0+F7iqkuE?tB$N13WU6x0hKz~ z$z;NG<4##BJVn)hwDoO~Pi2W{3r(0!$f z=pt=VRl&?Q@QGQ;urVro&jUjU1eSfD2&whPuSrH!{IqF30ENTRq>0*RCNz{BMS&Jz z>7KwMRKy}g92)aAd=daJ#?zBHcgF9b#Txch-bg+Up_$m9k2~V!Sw^c>Cq~}jdmHMNm$YyN8qjCRv|v)2MouaM)$gLa0(y-kxy;c)Xp+h->I0>e-j%tN zl9>V0Cr#PVkRgL{e$lbqD)g!IbYEs3uzk|{RxnYqO%CaL2ux!BI;maJEg=?;(LH zUc<<6kLL@d<;|S;(Dsg0oKA;|7bSQa6dhHLeEU&sKBI35vRNAz=&@O6DvI^}m*R-& z3Y-ffPyUFI{TC;3O|nA<{8A6t`!Vvb@Y~BgfJc zKfCTN!+$R;`Bn_x(C4+E{`t=4C^gj5v#zaN$<}t;&MXo{yMLRXa7yV_Wc*z=Cu-;S zg|$rVG{e7lC;z7_8jS2L|M5LCP;J>}<>QEUUTs86O(1bk2L%zVh@KXy(+n9_=4$~$ z7%m%~75N<}{6xh$oM|m}xda;oQFMqY`wotxX`$Nc;NfQ{awXRbY;Ip4JCB9`^3n!ZX?xmk{xEG6aZ%VOi=jv7|BmNL!Pyhg`y_ zRp6W*3vtR9bxC*+qFsgtFOe2xHK&YQ;u=0+>tdnejiYL&77vDlBJtEZk-oN4sMcG z_y4$umL`?u2;J8NcC!_Cix^uS276Hu6*uLHF3mT!%xAHdooOFL>Lj=9FsrpRyAsRQ zX`!3AE4EWhxlgp(MLQLlW;4bl-+pz4D=1IMDecTzzPVwl?y3H|R3X9G z5+>fox5}rjYrw`5o5KMT?`(w)<*vk&=I?SVCBW5oqy#3RnLb8c?0E?_Mp2=#G zv?a@e=r0B=Md?WN3mk;1Pw)w>4WF4bRmK_hWVCq(H*jaOKTo$auvZgS0zQQ)v zEKzod7=~q+Io8X-H%6evm#?`aI_HlU1(8L{EG$5Lf@2r#+uel@%L8L8jL68 zciGIlvC@rpZs}lIRngNbqgVU>e~g?%lqkTmWpCNGZQHhO+qP}nwr$(Cty{LM`o3PT z*ZPA$=t<6Um=TfZoY=@&GSWfSd5NX!8LGz{Gs_cA1s3^26fn{`*v$UlcT4;yV6HQ4L`4!2hzULb=%F=;!dt?HSMLGxLWonAQ$lFv;JtOwH`MoEqG6 zILK>{1q_Ice9gZ9@7`o|%=K{jLSIN4?gta&nLq_A{+mcDX zf@TE`!UTqAI(8WGUmwU{wC}nIZf!;!W`81&iyilRoWFt*E_T(6E-FJ9F zwWVJS(3xTWY&s_wW8LfhiSctUzUG&C!bzqT#Ee6f_(R8E4W7N{3`S?ijO}-!d$hOn zgUpsf{L*AiW7IY;rlnx3syo)y4WIO=i-inaIZhT5(JIiae?j4%s#=lYc z34Moym~GhNUjh1}>M#Ab?;=_u*Vp*a`62Sveip8U?Xb1F%_ek>ysA6D<632W_wgdXLWhr4PGrRUp5~#bIMb7#ZU!TI;ry=eZuW1X1_D6m1h&Z57?Kn0hG}q6s{;Y zz5BVm&yvjR*xz!v`j73RaD(Rpy`x{Z?YGf5xt=f-?U!6kJx`&yD&K4UmVnK1KhN!R zk9_>B>3=q}wBPxfsyJ4BK-TDH?I1#!&#(n0n9KKvF_e?yz=qOZ~2P3?A;OJFL)x zUnkF%9BFr1mfiBF`{6x)df_h+2{pnUk@7piVfWj@aGf7x6NIyV6^rn@A2$n*Kx-La zI!Ps3IZ2w!tvZW_KIyS<#_GqYZ)kBw#c^!yhuN)`fNhc$4eSAOAodT?UQ`g>Q2(9Y z-<`3ZB>YD`>d{9)tHDm)TtEn-xD$qsqx6v!d0ixKSXPtP6T%a6dLNBg#~+vOb$kAPxZ=P7?#C#Dhof^B3zhj_6u~`UVx^6r z50@7|q+LMg+vi_Ao?}czUT**V@HfHt6EU({cpEBU?P2rh!Peg#A(@WBwxL`B1WNk< zh#(mjj;iEkWq=IR?cWQM-9h$w&~(^&BeVsP5tGg}md>p?bp?K2B9e-UMZ~F{`+tpX z+a{v3P*sRH@PpoMS>4o0M@mLBXw&&ZblXmh^(8WUXf{^i^a3mhxp^%vrxP34o8yWT z{pqD60B>U%iO)}A70-F6)?BeVAT?z1)s#3oA+X$*s222E!27jd~wc@pn#6WLrd!V z6&&Gk4-t_>N+y%RN#pSmozY}E_kQ)*@u;ZS_vZK$7!rj__fBbJ@zEH4l0o$kMbblR zb=~=lRd4Z_TC=g$db{31HP+}gx2tWi_tOmo26uwT>)4!sw|-xUG(skq!|Q~4Hmld} ze({i!ShZHWM@};|qjl1DyZsIN+S{~wqoyqQ)Hg-O885d21jG=hjVZz;*rW%J2nxj% zf=nPIj@AlMGDx+cg-z`eA1aZsXhSyWC4-5?#KQWX0Vqu)(^ye+p|kWy zDVc&)9BG+&yj*aloURi>@ zvf^{@$2hj_jlqpcEVEda(ainn1Odf05RK@Rp;W|4Y00+Z+~H)*M9gmn_B6sdxJxis zCzmJZ2m36iHp>DFoh4s+O|6fD)+MwfDVI_-=j-fEua_$CdDK&U?_w^Yy$wZ z41z28$zVNUJO;skVMGEE38`X}MaT+i&(VHpT!c+)n}C;A+-#G;pYB}?e}a{GoAT7G zsYq`ASaW?2QP~uz#}57%9Ek#*m5me#S-S+Srl@)KmmJb<@g?zq@SIQtVT998Z9pL>{H^ijPr(# z)D6iFsczIO9XL)#98&CGIG$qYW*b8bTMKgvx=fv=ovhulCst*L(vGwCrJWj`Zy5x< zM~+bOyLEe+vk^Di)JG+*{%1I}-78JVyafL9d#L2uF;}>*rfFA!I!0qguW3RngPqxVAu3FH!z(FJdCnlY&~=hknNZ53Dzmkeje36Q ziYW$qY8_pSRfJWBUL%V6gk#q_80riqhR|)Cs!!$T+6dN{W|vk_Z7wY#o19ymo12@` zt*Wi1tc|=an>Boze)YWeuZ_CRxvja4s1J)Em$a7vR(e)+R&rMLE5r%Ui{b6Zq{`lF^j?d z(z|i*pa408V#St1+O3=kI_o)idUl1_E^T~VjCKmK*7QYw?#25qF-k9AO0hps^Y%Z| zJ1byb9zCyTCfq;2_NKU|%X;Pr`^koE-i=pJsIV|WuKEF~kwuB1;_AUM)FWrsgL2FR znPEM7RS!6P2N|nJ5D9(d_=ZrgM&`;#p{&PvwMRv+#?*z0kdEX7(X|Irw)<7Ihg`nE z8rmZilL_FC?vbhNvD)NgA>Qb&-XI;)!`+Dq0g~clCej0mrAL^h#TZTXNqvW@rw6RP zLp$EEL)Jr)r;q&L^!6EY_t{MrG#BIf2_@|FLsu6(H~Fy?pvV{=@M*N0BUqPEHzhZk zV=xoQJQ8ACmteaG>6(*V6<{^Y*{%zElBGV)`A!x9IK{)r^I(tEwhNdwCB@FkQRE45 zi0mE;j+BLCDj?ny@hb1^9?D9c10yN?GZi>88-XO*Zd zWjq<@K{~_t?l9r*;*Ax@#YsDb(=H%W=2bdH*DgRo6zD6AOBE@LvYewPFIXeXVS0pY zDsXzo;GDxs8cL{hXpAtdIi`%M)+JjbYfP=wQMIO4B?hc{w*0YM6Ko8#Hc(qrOqy)0 zxwZye8+E9|G=|w3a<5Ij)^$^-UK+ls<8buBHV9JZV4H{x1JlQ28v#|vV;hdD!*ldU zu86rtWSf|-s6R7vjLtSdToZH*(>7342WuOxt~k2}BsDVBiB==rLO%vl0fCC6a;Rm_p01`Cw`30)fH9$;qNu>Wl z27vOX3lB9{Dyv#7b3ly234-ZC{v8~^;(0BdUqCNe--m6ydcqNq5E$R(CkP(OxJhFt z5FU!Ti6jrr)G21h8QfG;Cmb3Cb5l?ch26w-Q<5Gcx+!bMDc!VHCoq@6E{mKdDe7f4 ziaX*RlS(nl<(Ac%<@77cAywcj+AZ=4l#(J@){mseq~J>TQL)_e_E*m*`A`GzXlk!lc>3M3V)lo}=a-LOkCE7&Y* zGfIyufGzSgicu?wEy^@Xc9kcU@-^~QE0isoH3}k@HIy$ocPUjay-JonoB6DuX*N#w z2d$MhmR+7wJvF-ux0N`(hzF!csqH-#VU7YWiwk$Gms*YW_=j0=~D2`{w6HY>82<(ujbt>ULgL|Yr zRFFLv?ksX;=b^au$Sd zA;1rgFD}pDzu&g$4~m5i?hk;*Z4O*8zb+X>3U6AXg)xsjNC22A;A9Sv01vVt07DCh zNjf^&+=#zA8Ok0W1}q*-Yz{LKZ}{M>wIiGMm#I^FZ=U6&w6?^K0A-UOvseh!SP<1% zNXr~dPQdGf&IgQ1pR^m+uAe#`#z~)cI_SOr59;D;JvizT+!N8aFy9j06BSNDk#n?f z(UEhY>>>qa!IHA1S$XuVB1cXUB&QtOIiXJBl(K}{Ii|{jOJymRvJhKEsx1eHbJoqg zPN&%G1;EOJkUF5$f=Jxo3k23dc~5D%dIr`3dTU9TE2AiYA%;MZF#1O0k>P3IRcj+A z>sT6k#3K4k9N2mTG%Z7_=mGVYc7!lTBiliP?c^bjz$^zR+kph^k%jFwhpi}u1SJ0oW3HQEH6j8n;D;Wy4Ry0Zhx=`eB5avcXGI+1MWeGY=0x{ zwI@~|X}zVnCpMsLTiM#Boe3tO8GNR7Xa=DfdZz7YdLo&C&rq(Zoa}Dekh1%#FE(EoNCS}SV3m5zRepr(5JUB{+d2a{HJ4YyoyIINEDnPqN>+zIwN- zUQfC`a7{AN5iAa*yTtr0T)KS0SfmJ+!`cjb)W}gIiVEbak%S7=tdTVXryCTmQ9Xuz z?BuW!Lx*^WPWN>8EpM`4#){IN6Rg)VWbG8O;YWqS$q|qa651#$g`&%XG~0n&_Fy-I zJne9B^+3EaIM2R5{CLaH9|^wIdFP;8X1M{J?%>aN;J8Cb=J31*5b%P*?Ysf$!4>Ne zTt;YDnB8*&+S5bcS0Uf_^7Vs|!pyM)X!d}zqiFXi-ZI38(AgnQ_PDhDA_JA`p;HbZ zwSz3}sA~tH+re7GkhVi@_G0rspLalC=zIfm_e@`ieUPi$aBon!2sU@eYO@jxf|9O|$MLMQYb+OhFOCIMK4Vi!Um zMSH(QUxHAdzrP7ZC+ZxsvdKwL23Xb>pV$67^}o`qa%If!I1T3|{bm4LteHv6vow)wPo>*}KD%#-yF(Po+H zIyb^iW7za~nR3%*r%;b}k1_ANU*^89W$j8kY1`7c~#6URK?Nb~ReozAR$X3Qp5srmy~N+Em_bO3CIzwo0y0dEu|zP@W%f#H&b3`5gG5^r*$1?PJFjsd!M^bxsTL) zpI=vhx-xCHVsXr=wydnS%&@vTb%tOUfu8tR6yOG}-2Zv8a>GjZQSPL~g4R%h(ffr8`vJ05Vm zQDl#~vmoSyaSjcSFs;it_n@~!pAWuYZrmZSFR-t;_qflco>1K(y9TX$t~mZ;?n?q; z22^2Ofhge^cO^pC2}cgzu@Ka-)DYY_>Xk{(W-P)mD^osBK6vko-ci%`O{p}_v;&ys z!A9{gQ}sC11H#^TOb!^dV-)uAWgIKYJ}8x#<@6}EgvvrI;w-BFxA&u`6fZr2e|xQH zxG3nTR7WbwC@Xz~@hHYE7Coc$sP}GdK{B??)GTeSFbb5>QJO2x za3LLDW-BNSfM7Zx9b{&{oB?fGux8B5oFSdEX3&ypeV?{w+M0oFTDoHFn!#;a!=?wD zAxJWNkRe)H7tSO{vN4pdj$o4U#;`|*^nUby^nvn*s*zYVwu0ok!FGJe_CAw3t9Kga z`1=nxc7^pq^BJ3??`K4|L7_S=xo)94*=uIDZsHn}(vY{I;u@o4c5(&UC4p@vwJn*@ zV}iHqA9in#EAWI#yL1drs0o)r?S(iOI$pq-g1#o=nz9ovsW(OFkv;DGZv-0=?uc+q z%$DxPq9YrBbw`dnW#CS2e=W!+Ekk-dMS5op_lAlHzTl2!Blt0SDDB3uo7K8=&+XSc zszaK?ofLau_y=>VPX5I&d=Ix+sahp24ACr#ur#V}_=4?|InyCjCuF#?;n8DVfih<5 zk!M|tGKTtYke-ivM#QK~`zzfOovuOZm#P*K#2`FGUTBbgrQcG27!ey25iJuDR#U^O zs)a#h^aR>0FM&UPX9Y?@Qjc3#7o)pl%m2lhp9JI-}ayqn>s z@cjh#A?J;mS1aU_?j#v@>HKZRqcpeJ^o-4;=2y)0#GL^~P&aD>Pe@1r+~4!Fx5PKu zqw7-lH)#j7|KpeU*XfGL#4{jS5&de+OdcyY5ilx@82&Dp`BqOHuQnL}9HvTqfF)3K z9xPE@2-FChdeG(O(-x#T#3cR%w_oE%wzDr-`9`U6zmeY@War}7NBlzd&e45L2MQn_ z0Jb?)R~<^R;)o9}Zanm)9x!&F`IVvuQ#e~4)CL~`aYyhKWO$IUL0Px@g~M2oSM$c+ z4LMj4m|EZA#^V)Ic#x|e#5GCAK^>n{fIT{(qaHKp-QlAZu{E(5#yIG0>w&x`8Q8}F zTRH%w9!XZ;MLHGjgy&W0l~i3GsBofGK|X+{0c#31;703)1pQCgzSgGQ3OPK`Fe^v@ z-t5jkZcwKEADhL-5Jmx7Uyh}ntD6x1MzUP)#hg_P(549Yy#c-hUMaVw0;J;kNs(g9 zA@M5FBagq`X7w0f(9A_Uu!L4*L!{#c;l~2J*ra=3IFsUCpawiw(L>>?uN7%>MkL-i zb0=mXkvPY1QRU52Z!_adl zphTn=bfXcPxTV!j>dYZwvE4j{LKMAReOEYj{Qh3i+Z+M55mzlc37RjcI~vMQ8Ca;2@yUBP+{ zlf>mmdc<|MVf)7Cow5bX2}ha|>OR4Lhe#zz#N$K=Zk^D2NbeSDN;i?Jw}~gsLa@Ix zzMPowy@`D|eSK260g)$_CX%rVqMrEBj_d<_G^bP328AJqbfU*97{6w%19a)LU4;QT z0M8CWdq!1{x}=AAS%5WzDe56m$C5N6r%sB-uTJF0vZaaQ-am48jZ;oMY<3geQ|4B7 z^WpW6E#Q*gV|c@QuqNFelYBwiX-^aDc=s5f#$|D5R$C7;PEFeJ@=p11O3};*q<7;HRN3nuB zvnL0QvhmL59vC!0TQH}1zIk8Ab=1IGO{+QcKWWFAq}b#0M_~sg8>Fos);n^x4!N*T zT{)y+2it7dkk)6B9`xcz?Uzmf4LbP6eIxw>NBM~njIbCk3#yMK?8K_whjkBK?2&Rl z5-w6MoF<%n?T{Dg5l}X}P>vfAj&D$fI4%U)w=n4;DIMf_1EDm=HBt5=ypZ`NZ&1*7 z(&~_@7%ZRE=UUkjKNm+)lGSibudS*DRV>*WP6V#}YkUr8L7!9pO4nOO(;jgN{d;y* zTPv!m=lp6iVu%rsZEbx7HMrYA8_-FL4xPYl9^ViHV?e5n*;eeMFWFx|zsQ_H5AC79 zSRBs^Cl=}otW?hBa{)aAG$XW?F->d(Q%oScI0{UPU-4UOJ$55aXc7Cf#c}p&XExWX ztsk-mH3lgLIX6U;{fPpRP&Y1e6;3@1K9qOoh592aYlO%9eeLVJM8*fLbjRS3q}ho2 zX&{O|R(4Q#x9X?lzBV7e;0r;kFY=32wGoI5Jz(>Oj*EzNItoN!F4}Dq&I9mik=O-* za2Nu#-b8heeVhAuOkew86uo=7KF3zi#yjR@NVXl^hajnaz5st?H|XL?Kif6`k(NGS zbPOpOdcUj-^SWS%Wl^*@^o^{2!NT2A3cvJek5;5J?+|jQ9iE8OzAEI78tM?{QXgVW z57Zap%B@kfoyV|C6%M{*%;AA_R?;A3BM)*t*asdW@9R_$bMr59%2ewA5cT%-FaYWZ zudu!lhs{3DG@rN^iM~sOJvXlBjC^+S4&v$t*v3Ex$!8n=5cYQTWmMwj)wj6P zLD1b>)Kk+^(qUm^G?ZEPS7>0RN_7>)Qf++dTT#YErDX2Xp({H!@}W_2!B$Jvuq9na zG^pPxnV+0=YzYyn7y~b!&9-{Y-2)yZC<@quw1B*KIaI=8M_SXeBL5`!w@EoNbuy3y zp@cs8Qb0Sz0xC=R$v?o}0U! zX`p?exK+#o{xybiEo$kePD8t!Ix$_n`q{y9x<_qMT_q=eU0KhtVYM!1g19!o$-;)a zX4K)534J)%2JuETjtnUpdyIx;25F|M(2vMbI;r?oVw&1*%II$|bLnUmbdC9oWZPN= z9xXINDQ4jZQfhEg7>RIVf+9JaP5MR9zw%g_2V@fVs92-XS0<<8nkZb%9jti}Errw- zaDS-ybKi|CjO}F&%Te(BMJ-(#?+`5%q}?J{mBpT zLg8BVt-+FTtmwad`%?FpG(cR5hGJhxBD;aRe3J63AxJS~tTHP+VvM>Al=4TYDxfA!j zons4mW!DT9ZnWuF(}f|9tnSU`qde0c)RQ~?#T`gX*-*!dM{a*dIW&qa7K*J8oNQ8m zUZ0yelBd2@+AqAjf#VzQia?^OUu5PAUis4@gHV_aS51(Gl4i~TL&lim#34e_+~RQTd>X^| z&Q(%L9265;GMx9J_b4GQ-AqoF&H|Cy*BzqYZ?;~_c{sacyR*FSr(IyGtuapQ((*Cc@^xDi`c-mxh^T`*HfAR5-ixT}wu8vgG zNfwSNY!uPSkya5d%Gd0V?+&RQp4;P3Qaj#{{Sdi{E#n!z$CWr+ztp@LzSVeTN81lP zVMUm>T2Paq4N@+3`{SVbT@5n}o_5rR= z-1|}fzu5(FSGWUGvPFtCm*klD8FKskH$jKCUk2L@dr#+Dg7ZSQGwFC~tI_%$pfI%| zItED-?+9KxoQQlmj&aZy{6vONz*FpU|VBalMILpPKCCL$OymTfp?Z>|QP^=PT^E`Ulxh5}R1<3GEH4kh-H$dw3*z zu7!f6Hdp~#ok-PCQzRV#e3mLvJFd_YI z@IS7#QY0W0MKm{nm82!<&9oROY#B~A;K?6pYzQ`;phc8eHkknJm=kk$SR84*hq#wM znzSa4ZW|dqwx{aqO4HrT7sNUoB`(1`p}W{MCPvfQTCUjc zd4o^=$2i>_ZVyKu+dyys6a5MpM*fT9#BOYVk~U^!n$QspeW7PiO78KrmmP1mui?Ru z&JodTDK^$z+-{~G&dQzKT7B8BU#V$5kE+5Kutzl7o%7F!AiwU8{LlA_p{9p)sTFuC zU3&{`OywvordiYYm|h&-#Ce>3P8^=jBJH@N#!IF)1&4jLWVLK!b3}v@*)Bxr@I-yd z!+6SJ;p#{mLIja&Vg`j80Iy-$D`{P?!6|{+8V*7LwSK&CCFnE@LOpKcry#IE!je|t zO+YUoFrZtI_I?#1O4LCDIdut+EC^1Y?`il}qcRzx>cGhpqeMm( z0p)nOk?W3&b;&9-awXiUHy%V9(YmTYd>`w{)wZ z#?k0{iO`Gzg<`amM)=Sn*+kJ?7ZO-eoTJBlaZ6GJuT2U~I z2&gjofikH{#(9sYT-joX)YtKSh7zPyCS+#Dy#44HIPz^-|XTHfmI%S|t6C{E@0;ubzOZC9suk z44Hh*{urQKi-2h)OmpvrmBp1vfS$4VGxO+QC`y_^wZr>PTXswMlGlI~kHmS%G=0#> zKVIio{j;v4{pHJ13Ov?Hs%vVu>VL#8vFciqu!!{J(tp1gq|=%$@L~zOclYj+T3=RI zO#~eEy1dv5cQCmdACFD+8&Hw);HWtjU^#1fJC?gg*DbH?-5hg9fl_I`@=C;bZEw@& zHb$Upm3<{Q^RWr?#DQRk7@T2k%hvZBC3dOBHKhloXDEa#1 z9yoa;jCQ~nMy0E-{>1pxSZ*dk!wz9eUNw~7Z0>-LHgA!v# znef9nd0fncs90abhX6+6qZy7F?K~}4?l8{ORR0SPZ8)9xx}I(8waneW)p6BDU+r;! zc8pY=&gzPs8PDdl*cm6WdLP_w(rCx&jdtBZjp2GfKU874Hn&&hM=!*jx%Z zKUH!rP^P6%<31ueH&#SeF}P*yvG^I|GG_(WKg?su_hU08g?9{MGhI$!Ma+n4B!&Dg zOM#by7U>7iU&W%+SEpgBKt){C&k_w9N}wwlKvprs#}QpHQo)og48-N~KCc&MaigarKYEt_Gpqges()9ck+jcs)f9suNIfOS%eDT&j_b zs5DN#I^k`c4e{pfs`ir~9$1NhSOQRpC+1X|BT+RPZ4hVeZ7p6!s{k$|!-YBM?iMF5Hatu`@Xk!k znx$Rs@r%F4Fw|-`?0>w+*-_hU*Nb3vJo!%9t-Y`eo3gNSvvn;jY3p@;m_0|K{>={g z#M*0jzvpvSgRn>7Z48MH`4e!BKQ9OYplt-EL@paW<0B19 zk0cEkKn^2jZZ2sSNU>ymCF{?ueHwcmFNhH<7|Kcm?XqclR}6p{307J_3bfk!t2Gfl zF~70EE3sPrd-U1+`{_nw4GYWF@xtUYVU<%wmw#3^SDU4)p_YgK_%OH1LaX@->r!@< z&lQV|#kc0mxv6TarLRk5jlfHY2jNxibv2gZ`qJJq<2vmd+hNRQ(xRk|$JYGQ(Az_>cIb1A~3gZ|mqD-NSc3U#Okw|>zACaAM zTt-sVq$m(MmUnEi`NwzH@5=ZWj_(sHTd^K-o{F0haJd+GW{!$qlqN@1$0~tZ#?SQ> zb8GPwC@$XpopW-fZfD02WlopP<}cy?nWJ)!md?sz7ivbGju`8=kWWglwBM}}>t{`A zi`L!-dKjfH@Z$rD+8=W^1_GKW8WC>2NeM%$Cq+@3uWH$-SDDk0efSohlC(H5rCURfDxil{q)_6+EAP*G8L7~6ka z%T*63gM0g|=@5aFpv46iCDITPB{U|fhagvijq2*eK0~E)2L|m?;VHriOcCG}(GaO9 zNOX?blI~yx-S`%{*$s&drQ93{6LA`;XZdDiEL3)b!AI~!#T`4ica2WWO=!6QM)a^- za#*;<5xNK=Bka_LIPUO619ZYD*}kP7FWo;V)JPwoLX<=d&l?~}wt>_93Wf`jwD zcP%2LiY*>H8#4vap6SQt&W{^S6B~Zg(c!7!O2T2j?*vXR?*-duR{dX%J|74HNt_?f z<;u4Pxl}YV@2ka^&+qE(@pH3{$H_mR?uWxwA0FJ8DIjz?VkjR9iwmDl)uf&JItH2f z4^9OSu6MUW>9RDfoZ+ZidJwzEp6s$u93s5*!)I<3x@ILvVL3IjSI(Rdk6)2G@;JW3 z`_+Re-q~Z`9{Kes%n_P?3)lcu^(d@6@u-!MD`Bd^hXpnTsqy)tgZPTE+$jpz2K7}o zZ`Va5LzSOsxxnfF;61s8#RtKLB!y2V;?V}5IX?G9944}spFB_Dc&$ohd{Dm3{wNcg zB|&ew+FT^lrL*{KFY@ zGH(&$h}R!fhML#Q_jI5YXL(C*QPZSq=x|OlS)CHwhwF!yroJY!YpU8)Hxhopq*SEOxQH?DA_0;_V;0F6mk@N|u5)5M{a0|7Eg7|SEuKo9eYTa1LG z6ac!L@-e5g(O+hG{*E(kmqS(=?`gq`#Vxl?KtPjAX?Q#s5qtQnDT zXhOU9A17QNe9vw3n8*UDdoy^oze7!3_d#<%>x=DZWR)d9+X&AvMl#WDF8bi&qYKiarMLR#|}L$wQ2(6p$-rg?9|V7O61dgX7nZ6wBC) zRD2MH4e5uV@=vt0@9jS^tsjSpAt-jUJ1OmffO@^Ej1{z)J{6u<4vPso_M&~yWk+_c z(^PPt9ZWq$HIva!Uaz_8TViHk;@H{sH%ok!kt#79a*Bgj4SfgNf&C zOo0(}X7|Jq07SVL17y!HgHRDLl zh7jb7^>^U*g1yUDTxgfysBR?6uD};>y1&N(yLW#I_W%~`{Le*9OHhN(Jr3C_1l8F| zw9(oN23Y~10F$Hzg5Qk1NyX1{_BN}Jhdfy>d z7miOpcVI@l#T((q*KCTGiVDar!E*)pnHSA~Ku=)+=_yHyM9Z}!gJd-dZuE(LPSH3B8`P7(vKJv+GfmtD^HWF#{x~BFocvm^-?X)G&nTKy zwAE8lJ3y7n+cadi+M`;_vVJl{7Z7W!@ksQi@QiN#BtWojIsw&H2dJ@ffS%t2b-xH5 z-me4$x&uO<=R_nG6FES}d9fq(CFFCBsrrvGj7ONHVsW!`aw8Hb(?5KVR*YcZfD17z ziX0Y4!P8ZcQH}EqjzEx;nPLDm>EVZR3_CMiSyYZOSIiwCjZq(kKC?NQP^PFS)1tyq z5oluWsUqX!z>x`Jzx%YUPr-)`E}I9Xg5zo4IXe`z4>tQCCDriKVn^s>>K*y zMn=-p)HDtT48k7M?>$S3Pd1Y&l2o79#$#c6e*Bsp{;WyFEA+{?ydQDYIe+obQ6!-jaf03`Q?-tB_`LfGI^F zupcrQxZ>Nq8(affR4sv1B32B?m)>>K7nWKa1g+R)T1V4Jy{x!Rez*}B=? z+TLCdooQ{I?Y@sVfX0gT)Kmba|EVBYm%-Mkz{Y9=j{dVH%t{L3D_kB>4iae2QDUQr zU*myHPfHvxD&DME0CTVqK8cJePbs8a5dKHk&2$df{FRxht!QO;=GX7{)empfHhrkV zkapF80S#fwp2_+kb69m7maAPa!t36^0o{*ecW8HK8`Xi0mnL@r?SSMa&>dsXpRL0$ zLQlU#=c>PMU}oFu(6k$*kkbpv`XqA%wHwye(Hyq=;53}YJ)>T_dT2auDj7L@pkz3s zT~UBKnOzsT0SuHQFT4?PcAO+&uuw*je1b|bQJgj_XJs+`Cjk(3fNoqA=ZnE)S;5HlPrbctr3Z!I3AtIkzoGF2FK6aUY_Flb^3(o47w zp?;QaJNP8b1HMswSh_JSiq|mzLUEXpR(&nm;RHY_59*2IMJi(T}j%o^Vx-eD<%%A310E>350lYt;;MiDPLJ?DvYD zn36U&lG3~b4sQ&xM2mU#+d`Q{Zm3-HC|RcC=Ts$OWC)Xo;f}lE1c=Ju3DlypxF{5s z)It0mc8(q?&&qQMULo^Fb@i~UTb03W!kP}E?Bv>J?{OPVgL@#X zgQ*Y{uBG+j?om55#_IwGe4hpSbC`7$C=}+>4bf}i1ZgBn^nzr?D)Bkjq3LRwfl}kf zJUToSf;Z#D{J~%G&jp6)LQDt9&G4A#9&gl$Ea-xAL$?Jv=6D}W-OzS}Sm##eaRY?R zcrN+APrSzzLbbBo-RWWSl_4gv*nL)+*kgsm z26XBtZQ9~Cz-8(hIG%&UZg)L7UqEp8H6E)BioiIXI+cAqJC!6X(CTF!8ymyh?vXp< ze?Hbx1Yw4~76q{5D#dwhlH1^Kx(ck6S=%JoI47_t4UfaIiUZGhy znAs543=%d#b7&wJZDeq8n;&`=dNja_Fte6g^H8*#p_g(OX>Ryk{A-Fm`fQXD(O$em zv13>gnP%@puQ|S57mvs?uA-YMQ+`Z35Q|?TPg95Tdo%ojs3_pcNjMPm2+xx~wDlvf z0*U=Wo`|)Eo^{45tGm!lB&7g*htd3Jb{pKYpIaWLlPYrhz}fTo?x0F-k8P39yxhmi z-QYrx1*b<5!WU4JpUM57)U@}bKQ$$~0#=v)iWiNL?_qj+EumPfU?QH3G9iuYwC2uo zoqnbss(D?rsC&;tQiP{K8DJ!#poyn<^@z;H_LG?nJZ{P*C zfvBE#o9+e7bEx}#MR=lMnbIm{EhUe#PuW^hIF(r=6+2Pv#RF=)5)`u~8k8j_;#dJ6 zN!$xPfVurhG&(^AWAaR>0lF`bZzAuAqt`A4me8{U_L+O`$URo}=YWV?ONG<3%;2fu z#oL&T+Lv^DJKwni52!2!R7xuW8@`;3rkJR1?QGUas-TuDC+@D+E{N*)+hR_v472NB z0IjdR-g5$qZsy}^X;mZY^z`>9)W&@wPxt$IB>ST0bJ{O((&yR3sB1ms-DNN5H`};~ z)8gmtY}*g~BWi%d=!M}-{!M)0!VtD2VeIV1<12zxOKAbKS4daMS)(&w>e;=bky*2@ zO`NVH^Dz~T1+6X2YiR3%I8C-?xp*5{C#IC2{#p77<6HSDdA3Dl>nUa-=40htB}Z<* zJsWRkZOKuxZh++>+dO5LlIGi60;Z7 zO5J#-y3C?@^_WbO)iPz#+R_ZKUeu?IDlCH1o1t zd~sL*<&2{5^oMeBDKDda_^UZDof$zC(FzZqaA4Qx?lz~Fz~A+n(O#Ig*FP|C@g5U9 zD=iMX8u!lizgL?xN7G@aXs00dBxaX>7qzSF`>JW zV{r8lL6+A2=vX7@bml;|fe|5y)|wHDDE3N#!J(nRQEtZa;Q8_efDixj)CvSK$_fSG zf{G}b05lTS!ZlLagRx#W)k0Z#IvTID+Z~NJ-?MJB@4Yx!Y3ESPCY~x&qf0q>&A&%P zVr!2kNv40_D_+uQe;gn4RtbgQSx`Dh;E(J3tJz4)h7A>`S^f#vZS7jf?!yP(gN6YO z5dr++)&-K_GEBs};RS}KP&0(?Ge$Ww?MQA%JL&o>so&4S%Bjt{1Mn$-LC5Q?S)d

??WZr;zL^Q#LG=Az1~Gx8;S0Ikj@g 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 Y;fSw)^Gp6)V9m+K!^_3@ufY1h003=2z5oCK literal 0 HcmV?d00001 diff --git a/docs/RUNBOOK.md b/docs/RUNBOOK.md index 5712454..753a252 100644 --- a/docs/RUNBOOK.md +++ b/docs/RUNBOOK.md @@ -42,13 +42,13 @@ ## Trésorerie (S1T) -Le trésorier dispose de quatre onglets. +Le module Trésorerie s'ouvre sur l'état des résultats. Les opérations de modification sont réservées aux postes exécutifs. ### Soldes -- **Solde banque** : basé sur le dernier relevé + dépôts/retraits enregistrés depuis -- **Disponible** : solde banque − engagements non débités − réserves +- **Solde banque** : calculé depuis le registre comptable +- **Disponible** : banque − engagements non débités − réserves affectées - **Encaisse** : cash reçu mais pas encore déposé à la banque -- **Réserves** : prudente (500 $) + anniversaire (+20 $/mois depuis la création du groupe) +- **Réserves** : soldes calculés depuis l'historique des mouvements de réserves - **En circulation** : collectes pas encore remises au trésorier ### À recevoir @@ -57,18 +57,18 @@ Deux catégories : 2. **Ventes de littérature** non remises — le responsable de la littérature vend, puis le trésorier confirme qu'il a reçu l'argent via « Confirmer la remise » ### Registre -Journal détaillé de toutes les transactions du mois courant : collectes, ventes, dépenses, contributions, opérations bancaires. Avec totaux entrées/sorties. +Journal détaillé des transactions : collectes, ventes, dépenses, contributions et opérations bancaires. Le registre comptable est la source de vérité des soldes. -### Opération bancaire -Trois types : -- **Dépôt** : enregistrer un dépôt bancaire -- **Retrait** : enregistrer un retrait -- **Relevé** : saisir le solde du relevé mensuel de la banque (sert de base au calcul des soldes) +### Opérations +Trois fonctions : +- **Dépôt** : enregistrer un dépôt bancaire provenant de l'encaisse ou d'un don direct +- **Retrait** : enregistrer un retrait de la banque vers l'encaisse +- **Virement** : transférer des montants entre les réserves ### Flux mensuel recommandé -1. Recevoir le relevé bancaire → enregistrer un **relevé** dans S1T -2. Vérifier que le solde correspond → les écarts signalent des opérations non enregistrées -3. Préparer le rapport financier pour la réunion d'affaires +1. Recevoir le relevé bancaire → vérifier le registre de trésorerie +2. Vérifier que le solde correspond → les écarts signalent des opérations non enregistrées ou une correction à saisir +3. Préparer l'état des résultats pour la réunion d'affaires --- @@ -88,17 +88,20 @@ Lorsque l'argent quitte effectivement le compte : --- -## Propositions et résolutions (C8) +## Gouvernance (C5) ### Soumettre une proposition 1. N'importe quel membre peut soumettre une proposition **en tout temps** (pas besoin d'une réunion d'affaires) 2. Le sujet est obligatoire ; la réunion d'affaires est optionnelle 3. Un autre membre doit **seconder** la proposition pour qu'elle soit recevable -### Voter une résolution -1. L'exécutif vote **Adopter** ou **Rejeter** lors de la réunion d'affaires -2. Si adoptée, un numéro de résolution est attribué (RES-2026-001) -3. La proposition est automatiquement associée à la réunion d'affaires lors du vote +### Transformer en résolution +1. L'exécutif transforme une proposition secondée en résolution +2. Les sections **ÉTANT DONNÉ QUE** et **LE GROUPE A DÉCIDÉ DE** sont obligatoires +3. Si adoptée, un numéro est attribué : `RES` pour une résolution, `NOM` pour une nomination, `DON` pour une contribution + +### Rejeter une proposition +Un membre de l'exécutif peut rejeter une proposition en cours depuis C5. ### Lien avec le PV Lors de la rédaction du PV (M1), le secrétaire peut **importer les propositions secondées** en un clic. Elles pré-remplissent la section décisions avec le sujet, le proposeur et le secondeur. @@ -108,14 +111,14 @@ Lors de la rédaction du PV (M1), le secrétaire peut **importer les proposition ## Réunion d'affaires mensuelle ### Avant la réunion -- Les membres soumettent leurs propositions via C8 (en tout temps) +- Les membres soumettent leurs propositions via C5 (en tout temps) - D'autres membres secondent les propositions recevables ### Pendant la réunion 1. **Secrétaire** : M2 (présences) → M1 (PV avec import des propositions) 2. **RSG** : M3 (rapport du district) -3. **Trésorier** : présente le rapport financier (depuis le registre S1T) -4. **Exécutif** : vote les propositions secondées (C8) +3. **Trésorier** : présente l'état des résultats et la position de trésorerie +4. **Exécutif** : transforme les propositions secondées en résolutions (C5) ### Après la réunion Le secrétaire finalise le PV avec les décisions votées. @@ -135,9 +138,8 @@ Le secrétaire finalise le PV avec les décisions votées. | Rapport | URL API | Contenu | |---------|---------|---------| -| Financier mensuel | `/api/rapports/finances/{annee}/{mois}` | Collectes + dépenses + solde | +| État des résultats | `/api/rapports/etat-resultats/{annee}/{mois}` | Revenus + charges + excédent/déficit + trésorerie | | Réunions du mois | `/api/rapports/reunions/{annee}/{mois}` | Réunions + thèmes | -| Financier complet | `/api/rapports/financier-complet/{annee}/{mois}` | Collectes + dépenses + contributions + impayés | > **Note :** les routes PDF nécessitent WeasyPrint installé sur le serveur. @@ -213,7 +215,7 @@ sudo systemctl start groupe-meditation | Module | RSG | RSG sub | Trés. | Secr. | Anim. | Litt. | Jetons | Tous | |--------|:---:|:-------:|:-----:|:-----:|:-----:|:-----:|:------:|:----:| | C1-C9 Consultation | | | | | | | | ✓ | -| S1 Collecte | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| S1 Collecte | ✓ | ✓ | ✓ | ✓ | | | | | | S1T Trésorerie | | | ✓ | | | | | | | S2 Remise jeton | | | | | | | ✓ | | | S3 Vente litt. | | | | | | ✓ | | | diff --git a/docs/UTILISATEURS.md b/docs/UTILISATEURS.md index c895bbe..7a9d0a2 100644 --- a/docs/UTILISATEURS.md +++ b/docs/UTILISATEURS.md @@ -77,13 +77,11 @@ Permet de consulter l'inventaire de littérature : - quantités; - alertes de stock bas. -### Décisions en cours +### Gouvernance -Affiche le suivi des décisions et propositions non terminées. +Permet de suivre les propositions non terminées, de soumettre une nouvelle proposition, de seconder une proposition non secondée, et de consulter l'historique des résolutions. -### Votes ouverts - -Permet aux membres de voter dans les sondages ouverts. +Une proposition n'a pas de type lors de sa soumission. Les membres de l'exécutif peuvent transformer une proposition secondée en résolution, ou rejeter une proposition en cours. L'application exige alors de remplir les sections « ÉTANT DONNÉ QUE » et « LE GROUPE A DÉCIDÉ DE ». ### Mon profil @@ -98,21 +96,11 @@ Permet de modifier : Un courriel déjà utilisé dans le même groupe ne peut pas être repris. -### Propositions - -Permet de : - -- soumettre une proposition; -- consulter les propositions; -- seconder une proposition; -- suivre le statut des résolutions. - Une proposition suit normalement ce cycle : 1. proposée; 2. secondée; -3. votée; -4. adoptée ou rejetée. +3. transformée en résolution par l'exécutif. Une proposition adoptée devient une résolution numérotée. @@ -122,24 +110,32 @@ Permet de consulter les postes vacants et de proposer sa candidature. Si un membre est nominé à un poste, il peut accepter ou refuser la nomination. -### État financier +### Trésorerie -Affiche une vue rapide : +La page d'accueil du module affiche l'état des résultats : revenus, charges et excédent ou déficit pour un mois donné. +Le bouton **Télécharger le PDF** génère le rapport mensuel à présenter au groupe. + +L'écran affiche aussi la position courante de trésorerie : - solde bancaire; - encaisse; - montant disponible; -- résultat net; -- revenus; -- sorties; +- montants engagés; - réserves; -- dernières collectes; -- dernières dépenses. +- dernières collectes et dépenses. -## 4. Modules de saisie accessibles à tous +Les membres peuvent consulter l'état des résultats et le registre. Les boutons qui modifient les données de trésorerie sont réservés aux postes exécutifs. + +## 4. Modules de saisie + +### Rencontre hebdomadaire + +Formulaire regroupé pour les données de la réunion régulière : thème, annonces, collecte, jeton et vente de littérature. Les sections non remplies sont ignorées. ### Collecte 7e Tradition +Ce module est réservé aux postes exécutifs. + Permet de saisir une collecte. Règles importantes : @@ -153,15 +149,18 @@ Le module offre aussi une liste des collectes existantes. ### Dépense -Permet à un membre de soumettre une dépense. +Permet à un membre de soumettre une dépense en son nom. Un membre de l'exécutif peut aussi soumettre une dépense au nom d'un autre membre. + +La date de la dépense est la date de soumission. La dépense n'est pas considérée comme payée tant que le trésorier ne l'a pas confirmée. Le trésorier choisit la méthode : - `COLLECTE` : payé depuis l'encaisse; -- `CHEQUE` ou `VIREMENT` : engagement à confirmer lorsque le débit apparaît; -- `DU` : montant dû au membre. +- `CHEQUE` ou `VIREMENT` : engagement à confirmer lorsque le débit apparaît. + +Une dépense soumise peut aussi être rejetée. Dans ce cas, elle est supprimée. ## 5. Trésorerie @@ -205,21 +204,20 @@ Types disponibles : - dépôts bancaires; - retraits bancaires. -### Réserves +### Réserves et opérations -Permet de créer, modifier et supprimer les réserves. +Dans l'onglet **Opérations**, il est possible de créer, modifier et supprimer les réserves. Règle importante : le total des réserves ne peut jamais dépasser le solde en banque. -### Opérations bancaires - Permet d'enregistrer : -- un dépôt : transfert de l'encaisse vers la banque; +- un dépôt provenant de l'encaisse; +- un don déposé directement à la banque; - un retrait : transfert de la banque vers l'encaisse; -- un relevé : solde réel du compte bancaire à une date donnée. +- un virement entre réserves. -Le dépôt ne peut pas dépasser l'encaisse disponible. +Un dépôt provenant de l'encaisse ne peut pas dépasser l'encaisse disponible. Un don augmente directement le solde bancaire et apparaît dans les revenus de l'état des résultats. ## 6. Envoi contributions @@ -246,6 +244,10 @@ La contribution ne modifie pas les soldes immédiatement. Elle doit être confir ## 7. Procès-verbal, présences et rapport RSG +### Assemblée d'affaires + +Formulaire regroupé pour créer ou sélectionner une assemblée, noter les présences et rédiger le procès-verbal. + ### Rédiger PV Permet de préparer un procès-verbal de réunion d'affaires. @@ -354,17 +356,7 @@ Permet de modifier les informations générales : - heure; - format. -## 13. Sondages - -### Lancer un sondage - -Permet à l'exécutif de créer un sondage. - -### Votes ouverts - -Permet aux membres de voter. - -## 14. Bonnes pratiques +## 13. Bonnes pratiques - Utiliser son propre compte, jamais celui d'un autre membre. - Ne pas partager son PIN. @@ -375,7 +367,7 @@ Permet aux membres de voter. - Garder les réserves à jour. - Utiliser les propositions et résolutions pour conserver une trace claire des décisions. -## 15. Problèmes fréquents +## 14. Problèmes fréquents ### Je ne peux pas me connecter @@ -397,7 +389,7 @@ Demander à l'exécutif de vérifier : ### Le dépôt est refusé -Le montant du dépôt dépasse probablement l'encaisse disponible. +Si le dépôt provient de l'encaisse, son montant dépasse probablement l'encaisse disponible. ### Une réserve est refusée @@ -415,7 +407,7 @@ Causes possibles : - collecte déjà enregistrée pour cette date; - date future. -## 16. Règles importantes de l'application +## 15. Règles importantes de l'application - Les données sont séparées par groupe. - Un membre se connecte avec son courriel et son PIN. @@ -423,4 +415,3 @@ Causes possibles : - Les résolutions adoptées sont numérotées automatiquement. - Les mandats ne se terminent pas seuls. - Les accès aux modules sont contrôlés par les postes. - diff --git a/frontend/public/push-sw.js b/frontend/public/push-sw.js new file mode 100644 index 0000000..1304691 --- /dev/null +++ b/frontend/public/push-sw.js @@ -0,0 +1,24 @@ +self.addEventListener('push', (event) => { + let data = {}; + if (event.data) { + try { + data = event.data.json(); + } catch { + data = { title: 'Groupe Méditation', body: event.data.text() }; + } + } + const title = data.title || 'Groupe Méditation'; + const options = { + body: data.body || 'Nouvelle notification', + icon: '/icon-192.png', + badge: '/icon-192.png', + data: { url: data.url || '/' }, + }; + event.waitUntil(self.registration.showNotification(title, options)); +}); + +self.addEventListener('notificationclick', (event) => { + event.notification.close(); + const url = event.notification.data?.url || '/'; + event.waitUntil(clients.openWindow(url)); +}); diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index cbddf16..bd30a06 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -23,13 +23,13 @@ import Inventaire from './pages/Inventaire'; import AjusterInventaire from './pages/AjusterInventaire'; import EnvoiContributions from './pages/EnvoiContributions'; import ConfigRepartition from './pages/ConfigRepartition'; -import LancerSondage from './pages/LancerSondage'; -import VotesOuverts from './pages/VotesOuverts'; -import Propositions from './pages/Propositions'; import Tresorerie from './pages/Tresorerie'; import Impliquer from './pages/Impliquer'; import GererPostes from './pages/GererPostes'; -import EtatFinancier from './pages/EtatFinancier'; +import ReunionHebdomadaire from './pages/ReunionHebdomadaire'; +import AssembleeAffaires from './pages/AssembleeAffaires'; +import JournalActions from './pages/JournalActions'; +import BottomNav from './components/BottomNav'; export default function App() { const { token, page, loadAccueil, loadGroupes } = useStore(); @@ -57,37 +57,45 @@ export default function App() { // Pages protégées if (token) { + let pageActive; switch (page) { - case 'accueil': return ; - case 'profil': return ; - case 'S1': return ; - case 'S1T': return ; - case 'S4': return ; - case 'S5': return ; - case 'C1': return ; - case 'C2': return ; - case 'C5': return ; - case 'G2': return ; - case 'G9': return ; - case 'G11': return ; - case 'G12': return ; - case 'M1': return ; - case 'M2': return ; - case 'M3': return ; - case 'S2': return ; - case 'M6': return ; - case 'S3': return ; - case 'C4': return ; - case 'M5': return ; - case 'M4': return ; - case 'G8': return ; - case 'G6': return ; - case 'C6': return ; - case 'C8': return ; - case 'C9': return ; - case 'C10': return ; - default: return ; + case 'accueil': pageActive = ; break; + case 'profil': pageActive = ; break; + case 'S0': pageActive = ; break; + case 'M0': pageActive = ; break; + case 'S1': pageActive = ; break; + case 'S1T': pageActive = ; break; + case 'S4': pageActive = ; break; + case 'S5': pageActive = ; break; + case 'C1': pageActive = ; break; + case 'C2': pageActive = ; break; + case 'C5': pageActive = ; break; + case 'G2': pageActive = ; break; + case 'G9': pageActive = ; break; + case 'G11': pageActive = ; break; + case 'G12': pageActive = ; break; + case 'G13': pageActive = ; break; + case 'M1': pageActive = ; break; + case 'M2': pageActive = ; break; + case 'M3': pageActive = ; break; + case 'S2': pageActive = ; break; + case 'M6': pageActive = ; break; + case 'S3': pageActive = ; break; + case 'C4': pageActive = ; break; + case 'M5': pageActive = ; break; + case 'M4': pageActive = ; break; + case 'G8': pageActive = ; break; + case 'C9': pageActive = ; break; + case 'C10': pageActive = ; break; + default: pageActive = ; } + const afficherNavigationContextes = page === 'accueil'; + return ( + <> +
{pageActive}
+ {afficherNavigationContextes && } + + ); } // Pages publiques diff --git a/frontend/src/components/BottomNav.jsx b/frontend/src/components/BottomNav.jsx new file mode 100644 index 0000000..d6b7a14 --- /dev/null +++ b/frontend/src/components/BottomNav.jsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { useStore } from '../stores/store'; + +const NAV_CONTEXTS = [ + { id: 'accueil', label: 'Accueil', icon: '⌂' }, + { id: 'reunion', label: 'Réunion', icon: '□' }, + { id: 'affaires', label: 'Affaires', icon: '◇' }, + { id: 'gestion', label: 'Gestion', icon: '○' }, +]; + +export default function BottomNav() { + const { navContext, setNavContext, setPage } = useStore(); + + const ouvrirContexte = (id) => { + setNavContext(id); + setPage('accueil'); + }; + + return ( + + ); +} diff --git a/frontend/src/components/MeetingDateSelect.jsx b/frontend/src/components/MeetingDateSelect.jsx new file mode 100644 index 0000000..66a34d1 --- /dev/null +++ b/frontend/src/components/MeetingDateSelect.jsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { labelDateReunion } from '../utils/datesReunion'; + +const SELECT_CLASS = 'w-full p-3 bg-gray-50 rounded-xl border-0 focus:ring-2 focus:ring-aa-blue'; + +export default function MeetingDateSelect({ dates, value, onChange, className = SELECT_CLASS }) { + if (!dates.length) { + return ( +
+ Configurez le jour de réunion dans les paramètres du groupe. +
+ ); + } + return ( + + ); +} diff --git a/frontend/src/components/PageHeader.jsx b/frontend/src/components/PageHeader.jsx index 5edef2a..1214f70 100644 --- a/frontend/src/components/PageHeader.jsx +++ b/frontend/src/components/PageHeader.jsx @@ -4,11 +4,17 @@ import { useStore } from '../stores/store'; export default function PageHeader({ titre, sousTitre }) { const { setPage } = useStore(); return ( -
- -
-

{titre}

- {sousTitre &&

{sousTitre}

} +
+ +
+

{titre}

+ {sousTitre &&

{sousTitre}

}
); diff --git a/frontend/src/index.css b/frontend/src/index.css index 46e5715..0b0eec0 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -10,6 +10,7 @@ body { font-family: 'DM Sans', sans-serif; -webkit-font-smoothing: antialiased; + overscroll-behavior-y: contain; } button:active { @@ -20,3 +21,18 @@ button:active { from { transform: scale(0.5); opacity: 0; } to { transform: scale(1); opacity: 1; } } + +@layer utilities { + .pb-safe { + padding-bottom: max(0.5rem, env(safe-area-inset-bottom)); + } + + .app-bottom-space { + padding-bottom: calc(5.5rem + env(safe-area-inset-bottom)); + } + + .tap-target { + min-height: 48px; + min-width: 48px; + } +} diff --git a/frontend/src/pages/Accueil.jsx b/frontend/src/pages/Accueil.jsx index 5cb0c52..7eebd45 100644 --- a/frontend/src/pages/Accueil.jsx +++ b/frontend/src/pages/Accueil.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo, useState } from 'react'; import { useStore } from '../stores/store'; const COULEURS = { @@ -12,18 +12,65 @@ const COULEURS = { gray: 'bg-gray-50 border-gray-200 text-gray-700', }; +const NAVIGABLE = ['C7', 'S0', 'S1', 'S1T', 'S2', 'S3', 'S4', 'S5', 'C1', 'C2', 'C4', 'C5', 'C9', 'G2', 'G9', 'G11', 'G12', 'G13', 'M0', 'M1', 'M2', 'M3', 'M4', 'M5', 'M6']; + +const CONTEXTES = { + accueil: { + titre: 'Accueil', + description: 'Les objets les plus utiles au quotidien.', + sections: [ + { titre: 'À faire maintenant', codes: ['S5', 'C5', 'S1T', 'S0'] }, + { titre: 'Consulter', codes: ['C2', 'S1T', 'C1', 'C4'] }, + { titre: 'Mon espace', codes: ['C7', 'C9'] }, + ], + }, + reunion: { + titre: 'Réunion', + description: 'Ce qui sert pendant une réunion régulière.', + sections: [ + { titre: 'Rapport de réunion', codes: ['S0', 'S4'] }, + { titre: 'Saisies', codes: ['S1', 'S2', 'S3'] }, + { titre: 'Références', codes: ['C2', 'C4'] }, + ], + }, + affaires: { + titre: 'Affaires', + description: 'Décisions, assemblées et vie de groupe.', + sections: [ + { titre: "Assemblée d'affaires", codes: ['M0', 'M2', 'M1', 'M3'] }, + { titre: 'Gouvernance', codes: ['C5', 'C1'] }, + { titre: 'Postes à pourvoir', codes: ['C9'] }, + ], + }, + gestion: { + titre: 'Gestion', + description: 'Administration, finances et structure du groupe.', + sections: [ + { titre: 'Finances', codes: ['S1T', 'S5', 'M4'] }, + { titre: 'Membres et structure', codes: ['G2', 'G11', 'G12', 'G9', 'G13'] }, + { titre: 'Inventaire', codes: ['C4', 'M5', 'M6'] }, + ], + }, +}; + +function ouvrirModule(module) { + if (module.code === 'C7') useStore.setState({ page: 'profil' }); + else if (NAVIGABLE.includes(module.code)) useStore.setState({ page: module.code }); + else alert(`Module ${module.code} - ${module.nom}\n\n(Sera disponible dans les prochaines phases)`); +} + function Tuile({ module, onClick }) { const cls = COULEURS[module.couleur] || COULEURS.gray; return (
{postes.length > 0 && ( @@ -77,11 +144,49 @@ export default function Accueil() { )}
- {/* Modules */} -
-
-
-
+
+ setRecherche(e.target.value)} + placeholder="Chercher un module" + className="w-full min-h-[48px] px-4 bg-white rounded-2xl border-0 shadow-sm text-base focus:ring-2 focus:ring-aa-blue" + /> + + {q ? ( +
+

+ Résultats +

+ {resultatsRecherche.length === 0 ? ( +
+ Aucun module trouvé +
+ ) : ( +
+ {resultatsRecherche.map((m) => ouvrirModule(m)} />)} +
+ )} +
+ ) : ( + <> + {sections.length === 0 && ( +
+ Aucun module accessible dans ce contexte +
+ )} + {sections.map((section) => ( +
+

+ {section.titre} +

+
+ {section.modules.map((m) => ouvrirModule(m)} />)} +
+
+ ))} + + )}
); diff --git a/frontend/src/pages/AffecterPostes.jsx b/frontend/src/pages/AffecterPostes.jsx index 7f105dc..cf13d5a 100644 --- a/frontend/src/pages/AffecterPostes.jsx +++ b/frontend/src/pages/AffecterPostes.jsx @@ -1,16 +1,21 @@ import React, { useState, useEffect } from 'react'; import { api } from '../stores/api'; +import { useStore } from '../stores/store'; import PageHeader from '../components/PageHeader'; import SuccessCheck from '../components/SuccessCheck'; +import MeetingDateSelect from '../components/MeetingDateSelect'; +import { datesReunion, dateLocale } from '../utils/datesReunion'; export default function AffecterPostes({ compact = false }) { + const { groupe } = useStore(); + const choixDates = datesReunion(groupe, { joursAvant: 365, joursApres: 180 }); const [postes, setPostes] = useState([]); const [membres, setMembres] = useState([]); const [affectations, setAffectations] = useState([]); const [form, setForm] = useState({ membre_id: '', poste_id: '', - date_debut: new Date().toISOString().slice(0, 10), + date_debut: dateLocale(), proposeur_id: '', secondeur_id: '', }); @@ -31,6 +36,12 @@ export default function AffecterPostes({ compact = false }) { }).catch(() => setLoading(false)); }, []); + useEffect(() => { + if (choixDates.length > 0 && !choixDates.includes(form.date_debut)) { + setForm((f) => ({ ...f, date_debut: choixDates.find((d) => d >= dateLocale()) || choixDates[choixDates.length - 1] })); + } + }, [groupe?.jour_reunion]); + const handleSubmit = async () => { if (!form.membre_id || !form.poste_id || !form.proposeur_id || !form.secondeur_id) { setError('Sélectionnez un membre, un poste, un proposeur et un secondeur'); @@ -131,9 +142,7 @@ export default function AffecterPostes({ compact = false }) {
- setForm({ ...form, date_debut: e.target.value })} - className="w-full p-3 bg-gray-50 rounded-xl border-0 focus:ring-2 focus:ring-aa-blue" /> + setForm({ ...form, date_debut: v })} />
diff --git a/frontend/src/pages/AssembleeAffaires.jsx b/frontend/src/pages/AssembleeAffaires.jsx new file mode 100644 index 0000000..e2d89c3 --- /dev/null +++ b/frontend/src/pages/AssembleeAffaires.jsx @@ -0,0 +1,255 @@ +import React, { useEffect, useState } from 'react'; +import { api } from '../stores/api'; +import { useStore } from '../stores/store'; +import PageHeader from '../components/PageHeader'; +import { dateHeureReunionIso, datesAssembleesAffaires, dateLocale, labelDateReunion } from '../utils/datesReunion'; + +const INPUT = 'w-full p-3 bg-gray-50 rounded-xl border-0 focus:ring-2 focus:ring-aa-blue'; + +export default function AssembleeAffaires() { + const { postes, groupe } = useStore(); + const estExecutif = postes.some((p) => ['RSG', 'RSG Substitut(e)', 'Trésorier(ière)', 'Secrétaire'].includes(p)); + const choixDates = datesAssembleesAffaires(groupe); + const [membres, setMembres] = useState([]); + const [reunions, setReunions] = useState([]); + const [pvs, setPvs] = useState([]); + const [propositions, setPropositions] = useState([]); + const [resolutions, setResolutions] = useState([]); + const [postesVacants, setPostesVacants] = useState([]); + const [reunionId, setReunionId] = useState(''); + const [dateSelection, setDateSelection] = useState(dateLocale()); + const [dateReunion, setDateReunion] = useState(dateLocale()); + const [note, setNote] = useState(''); + const [presencesMap, setPresencesMap] = useState({}); + const [contenu, setContenu] = useState(''); + const [pvPrecedent, setPvPrecedent] = useState(null); + const [showPvPrecedent, setShowPvPrecedent] = useState(false); + const [adoption, setAdoption] = useState({ proposeur: '', secondeur: '' }); + const [msg, setMsg] = useState(''); + const [error, setError] = useState(''); + const [loading, setLoading] = useState(false); + + const charger = async () => { + try { + const [m, r, pv, props, res, postesDispo] = await Promise.all([ + api.get('/membres/actifs'), + api.get('/presences/reunions'), + api.get('/pv/'), + api.get('/propositions/?statut=secondee&limite=100'), + api.get('/propositions/resolutions'), + api.get('/postes/disponibles'), + ]); + setMembres(m); + setReunions(r); + setPvs(pv); + setPropositions(props); + setResolutions(res); + setPostesVacants(postesDispo); + const map = {}; + m.forEach((mb) => { map[mb.id] = true; }); + setPresencesMap(map); + const duJour = r.find((x) => x.date_reunion?.slice(0, 10) === dateSelection); + if (duJour) setReunionId(duJour.id); + } catch (e) { setError(e.message); } + }; + + useEffect(() => { charger(); }, []); + useEffect(() => { + if (choixDates.length > 0) { + if (!choixDates.includes(dateSelection)) setDateSelection(choixDates.find((d) => d >= dateLocale()) || choixDates[choixDates.length - 1]); + if (!choixDates.includes(dateReunion)) setDateReunion(choixDates.find((d) => d >= dateLocale()) || choixDates[choixDates.length - 1]); + } + }, [groupe?.jour_reunion, groupe?.assemblee_affaires_ordre]); + useEffect(() => { + const duJour = reunions.find((x) => x.date_reunion?.slice(0, 10) === dateSelection); + setReunionId(duJour?.id || ''); + const precedents = pvs.filter((p) => p.date_reunion && p.date_reunion.slice(0, 10) < dateSelection); + setPvPrecedent(precedents[0] || null); + }, [dateSelection, reunions, pvs]); + + const reunion = reunions.find((r) => r.id === reunionId); + const pvJour = pvs.find((p) => p.date_reunion?.slice(0, 10) === dateSelection); + const resolutionsJour = resolutions.filter((r) => (r.date_vote || r.cree_le?.slice(0, 10)) === dateSelection); + const nbPresents = Object.values(presencesMap).filter(Boolean).length; + + const toggle = (membreId) => setPresencesMap({ ...presencesMap, [membreId]: !presencesMap[membreId] }); + const imprimer = () => window.print(); + + const creerRapport = async () => { + const res = await api.post('/presences/reunion', { + date_reunion: dateHeureReunionIso(dateReunion, groupe), + note: note.trim() || null, + }); + setReunionId(res.id); + setReunions([res, ...reunions]); + setDateSelection(res.date_reunion.slice(0, 10)); + return res.id; + }; + + const enregistrer = async () => { + setError(''); + setMsg(''); + setLoading(true); + try { + const id = reunionId || await creerRapport(); + const presences = Object.entries(presencesMap).map(([membre_id, present]) => ({ membre_id, present })); + await api.post('/presences/', { reunion_id: id, presences }); + if (contenu.trim()) { + await api.post('/pv/', { + reunion_id: id, + contenu: contenu.trim(), + decisions: null, + }); + } + setMsg(contenu.trim() ? 'Présences et PV enregistrés' : 'Présences enregistrées'); + await charger(); + } catch (e) { setError(e.message); } + setLoading(false); + }; + + const adopterPvPrecedent = async () => { + if (!pvPrecedent) return; + setError(''); + try { + await api.patch(`/pv/${pvPrecedent.id}/adopter`, adoption); + setMsg('PV précédent adopté'); + await charger(); + } catch (e) { setError(e.message); } + }; + + const textePvAuto = [ + 'Ouverture de l’assemblée.', + '', + pvPrecedent ? `Lecture du procès-verbal précédent (${new Date(pvPrecedent.date_reunion).toLocaleDateString('fr-CA')}).` : 'Lecture du procès-verbal précédent.', + '', + 'Réflexions en cours:', + ...propositions.map((p) => `- ${p.sujet} (${p.proposeur_prenom} / ${p.secondeur_prenom || 'à confirmer'})`), + '', + 'Décisions prises pendant cette assemblée:', + ...resolutionsJour.map((r) => `- ${r.numero_resolution || ''} ${r.sujet}`.trim()), + '', + 'Postes disponibles:', + ...postesVacants.map((p) => `- ${p.nom}`), + ].join('\n'); + + return ( +
+ +
+ {msg &&
{msg}
} + {error &&
{error}
} + + + + + +
+ + {pvPrecedent && ( + + )} +
+
+ + {showPvPrecedent && pvPrecedent && ( + +

{new Date(pvPrecedent.date_reunion).toLocaleDateString('fr-CA')}

+

{pvPrecedent.contenu}

+ {estExecutif && !pvPrecedent.approuve && ( +
+
+ setAdoption({ ...adoption, proposeur: e.target.value })} placeholder="Proposeur" className={INPUT} /> + setAdoption({ ...adoption, secondeur: e.target.value })} placeholder="Secondeur" className={INPUT} /> +
+ +
+ )} +
+ )} + +
+

Rapport d’assemblée d’affaires

+

{dateSelection}

+
+ {reunion?.presences?.length ? reunion.presences.filter((p) => p.present).map((p) =>
  • {p.membre_prenom}
  • ) :
  • Présences à cocher sur papier
  • } +
    +
    + {propositions.length ? propositions.map((p) =>
  • {p.sujet} ({p.proposeur_prenom} / {p.secondeur_prenom || 'à confirmer'})
  • ) :
  • Aucune proposition secondée non résolue
  • } +
    +
    + {resolutionsJour.length ? resolutionsJour.map((r) =>
  • {r.numero_resolution} — {r.sujet}
  • ) :
  • Aucune décision enregistrée pour cette date
  • } +
    +
    + {postesVacants.length ? postesVacants.map((p) =>
  • {p.nom}
  • ) :
  • Aucun poste vacant
  • } +
    +
    +

    Procès-verbal

    +

    {pvJour?.contenu || textePvAuto}

    +
    +
    + + {estExecutif && ( + <> + + {reunions.length > 0 && ( + + + + )} + {!reunionId && ( + <> + + setNote(e.target.value)} placeholder="Note optionnelle" className={INPUT} /> + + + )} + + + +
    {membres.map((m) => ( + + ))}
    +
    + + +