groupe-meditation/backend/app/models/envoi_contribution.py
Daniel Allaire 6677b0f57b Ajouter historique métier et protection concurrente
Ajoute modifie_le aux objets sensibles et fait transmettre la version affichée par le frontend pour refuser les écritures périmées avec un message HTTP 409.

Ajoute une table historique_modifications et un service d'historique métier afin de journaliser automatiquement les raisons des changements importants sans intervention de l'utilisateur.

Expose l'historique métier dans le module Journal, distinct du journal technique, et documente les processus utilisateurs ainsi qu'une présentation sobre aux membres.
2026-05-31 10:59:41 -04:00

26 lines
1.5 KiB
Python

"""Table envois_contributions — Envois aux organismes AA."""
import uuid
from datetime import date, datetime, timezone
from sqlalchemy import Boolean, Date, DateTime, ForeignKey, Numeric, Enum as SAEnum, String
from sqlalchemy.orm import Mapped, mapped_column
from app.core.database import Base
class EnvoiContribution(Base):
__tablename__ = "envois_contributions"
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_envoi: Mapped[date] = mapped_column(Date, nullable=False)
destination: Mapped[str] = mapped_column(String(120), nullable=False)
montant: Mapped[float] = mapped_column(Numeric(10, 2), nullable=False)
methode: Mapped[str] = mapped_column(
SAEnum("DU", "VIREMENT", "CHEQUE", name="methode_contribution"),
nullable=False,
)
resolution_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("propositions.id"))
engagee: Mapped[bool] = mapped_column(Boolean, default=False) # montant engagé
debitee: Mapped[bool] = mapped_column(Boolean, default=False) # montant débité du compte
saisi_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))
modifie_le: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))