groupe-meditation/backend/app/routers/ventes_litterature.py
2026-03-04 14:01:00 -05:00

112 lines
3.7 KiB
Python

"""Routes S3 — Vente de littérature."""
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
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.schemas.phase6 import VenteCreate, VenteOut
router = APIRouter(prefix="/ventes-litterature", tags=["S3 — Vente 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."""
result = await db.execute(
select(Affectation).join(Poste).where(
Affectation.membre_id == membre.id,
Affectation.statut == "actif",
Poste.nom.ilike("%littérature%"),
)
)
if not result.scalar_one_or_none():
raise HTTPException(status_code=403, detail="Réservé au responsable de la littérature")
return membre
@router.post("/", response_model=VenteOut)
async def enregistrer_vente(
req: VenteCreate,
membre=Depends(require_resp_litterature),
db: AsyncSession = Depends(get_db),
):
"""S3 — Enregistrer une vente de littérature. Le stock est décrémenté automatiquement."""
# Vérifier le titre
result = await db.execute(
select(Litterature).where(
Litterature.id == req.litterature_id,
Litterature.groupe_id == membre.groupe_id,
)
)
item = result.scalar_one_or_none()
if not item:
raise HTTPException(status_code=404, detail="Titre introuvable")
if req.quantite <= 0:
raise HTTPException(status_code=400, detail="La quantité doit être positive")
if item.quantite_stock < req.quantite:
raise HTTPException(
status_code=400,
detail=f"Stock insuffisant ({item.quantite_stock} disponible, {req.quantite} demandé)"
)
# Décrémenter le stock
item.quantite_stock -= req.quantite
# Créer la vente
vente = VenteLitterature(
litterature_id=req.litterature_id,
groupe_id=membre.groupe_id,
quantite=req.quantite,
montant=req.montant,
date_vente=req.date_vente,
vendu_par=membre.id,
)
db.add(vente)
await db.flush()
return VenteOut(
id=vente.id,
litterature_titre=item.titre,
quantite=vente.quantite,
montant=float(vente.montant),
date_vente=vente.date_vente,
vendu_par_prenom=membre.prenom,
cree_le=vente.cree_le,
)
@router.get("/", response_model=list[VenteOut])
async def liste_ventes(
limite: int = 20,
membre=Depends(get_current_membre),
db: AsyncSession = Depends(get_db),
):
"""Lister les ventes récentes."""
result = await db.execute(
select(VenteLitterature)
.where(VenteLitterature.groupe_id == membre.groupe_id)
.order_by(desc(VenteLitterature.date_vente))
.limit(limite)
)
ventes = result.scalars().all()
out = []
for v in ventes:
item = await db.get(Litterature, v.litterature_id)
vendeur = await db.get(Membre, v.vendu_par) if v.vendu_par else None
out.append(VenteOut(
id=v.id,
litterature_titre=item.titre if item else "?",
quantite=v.quantite,
montant=float(v.montant),
date_vente=v.date_vente,
vendu_par_prenom=vendeur.prenom if vendeur else None,
cree_le=v.cree_le,
))
return out