112 lines
3.7 KiB
Python
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
|