from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, delete from app.database import get_db from app.models import Commune, TariffParams, Household, Vote, CommuneContent, AdminUser, admin_commune_table from app.schemas import ( CommuneCreate, CommuneUpdate, CommuneOut, TariffParamsUpdate, TariffParamsOut, ) from app.services.auth_service import get_current_admin, require_super_admin router = APIRouter() @router.get("/", response_model=list[CommuneOut]) async def list_communes(db: AsyncSession = Depends(get_db)): result = await db.execute(select(Commune).where(Commune.is_active == True)) return result.scalars().all() @router.post("/", response_model=CommuneOut) async def create_commune( data: CommuneCreate, db: AsyncSession = Depends(get_db), admin: AdminUser = Depends(require_super_admin), ): existing = await db.execute(select(Commune).where(Commune.slug == data.slug)) if existing.scalar_one_or_none(): raise HTTPException(status_code=400, detail="Slug déjà utilisé") commune = Commune(name=data.name, slug=data.slug, description=data.description) db.add(commune) await db.flush() params = TariffParams(commune_id=commune.id) db.add(params) await db.commit() await db.refresh(commune) return commune @router.get("/{slug}", response_model=CommuneOut) async def get_commune(slug: str, db: AsyncSession = Depends(get_db)): result = await db.execute(select(Commune).where(Commune.slug == slug)) commune = result.scalar_one_or_none() if not commune: raise HTTPException(status_code=404, detail="Commune introuvable") return commune @router.put("/{slug}", response_model=CommuneOut) async def update_commune( slug: str, data: CommuneUpdate, db: AsyncSession = Depends(get_db), admin: AdminUser = Depends(get_current_admin), ): result = await db.execute(select(Commune).where(Commune.slug == slug)) commune = result.scalar_one_or_none() if not commune: raise HTTPException(status_code=404, detail="Commune introuvable") if data.name is not None: commune.name = data.name if data.description is not None: commune.description = data.description if data.is_active is not None: commune.is_active = data.is_active if data.vote_deadline is not None: commune.vote_deadline = data.vote_deadline await db.commit() await db.refresh(commune) return commune @router.delete("/{slug}") async def delete_commune( slug: str, db: AsyncSession = Depends(get_db), admin: AdminUser = Depends(require_super_admin), ): result = await db.execute(select(Commune).where(Commune.slug == slug)) commune = result.scalar_one_or_none() if not commune: raise HTTPException(status_code=404, detail="Commune introuvable") # Delete related data in order await db.execute(delete(Vote).where(Vote.commune_id == commune.id)) await db.execute(delete(Household).where(Household.commune_id == commune.id)) await db.execute(delete(TariffParams).where(TariffParams.commune_id == commune.id)) await db.execute(delete(CommuneContent).where(CommuneContent.commune_id == commune.id)) await db.execute(delete(admin_commune_table).where(admin_commune_table.c.commune_id == commune.id)) await db.delete(commune) await db.commit() return {"detail": f"Commune '{slug}' supprimée"} @router.get("/{slug}/params", response_model=TariffParamsOut) async def get_params(slug: str, db: AsyncSession = Depends(get_db)): result = await db.execute( select(TariffParams).join(Commune).where(Commune.slug == slug) ) params = result.scalar_one_or_none() if not params: raise HTTPException(status_code=404, detail="Paramètres introuvables") return params @router.put("/{slug}/params", response_model=TariffParamsOut) async def update_params( slug: str, data: TariffParamsUpdate, db: AsyncSession = Depends(get_db), admin: AdminUser = Depends(get_current_admin), ): result = await db.execute( select(TariffParams).join(Commune).where(Commune.slug == slug) ) params = result.scalar_one_or_none() if not params: raise HTTPException(status_code=404, detail="Paramètres introuvables") for field, value in data.model_dump(exclude_unset=True).items(): setattr(params, field, value) await db.commit() await db.refresh(params) return params