2026-07-14 17:06:37 +00:00
|
|
|
"""
|
|
|
|
|
Routes pour la gestion de l'arborescence de catégories : profondeur
|
|
|
|
|
illimitée, une catégorie peut avoir des sous-catégories qui peuvent
|
|
|
|
|
elles-mêmes en avoir, etc. (Categorie.parent_id auto-référencé).
|
|
|
|
|
"""
|
2026-07-14 16:38:59 +00:00
|
|
|
|
|
|
|
|
from fastapi import APIRouter, Depends, Form
|
|
|
|
|
from fastapi.requests import Request
|
|
|
|
|
from fastapi.responses import RedirectResponse
|
|
|
|
|
from sqlmodel import Session, select
|
|
|
|
|
|
2026-07-14 17:06:37 +00:00
|
|
|
from app.categories_arbre import categories_racines
|
2026-07-14 16:38:59 +00:00
|
|
|
from app.database import get_session
|
2026-07-14 17:06:37 +00:00
|
|
|
from app.models import Categorie
|
2026-07-14 16:38:59 +00:00
|
|
|
from app.templates_engine import templates
|
|
|
|
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/categories")
|
2026-07-14 17:06:37 +00:00
|
|
|
def lister_categories(request: Request, q: str = "", session: Session = Depends(get_session)):
|
|
|
|
|
"""Sans recherche : affiche l'arborescence complète, repliable.
|
|
|
|
|
|
|
|
|
|
Avec ?q=..., bascule sur une liste plate des catégories dont le nom
|
|
|
|
|
correspond, chacune affichée avec son chemin complet (ex: "Réseau /
|
|
|
|
|
Câbles") — plus rapide pour retrouver une catégorie précise que de
|
|
|
|
|
déplier un arbre profond ou une longue liste de racines.
|
|
|
|
|
"""
|
|
|
|
|
if q:
|
|
|
|
|
toutes = session.exec(select(Categorie)).all()
|
|
|
|
|
q_normalise = q.lower()
|
|
|
|
|
resultats = [c for c in toutes if q_normalise in c.nom.lower()]
|
|
|
|
|
return templates.TemplateResponse(
|
|
|
|
|
request, "categories.html", {"q": q, "resultats": resultats, "racines": []}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
racines = categories_racines(session)
|
2026-07-14 16:38:59 +00:00
|
|
|
return templates.TemplateResponse(
|
2026-07-14 17:06:37 +00:00
|
|
|
request, "categories.html", {"q": "", "resultats": [], "racines": racines}
|
2026-07-14 16:38:59 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/categories")
|
2026-07-14 17:06:37 +00:00
|
|
|
def creer_categorie(
|
|
|
|
|
nom: str = Form(...), parent_id: str = Form(""), session: Session = Depends(get_session)
|
|
|
|
|
):
|
|
|
|
|
"""Crée une catégorie : racine si parent_id est vide, sous-catégorie
|
|
|
|
|
(à n'importe quelle profondeur) sinon. Un seul endpoint pour les deux
|
|
|
|
|
cas, le formulaire d'ajout de chaque nœud de l'arbre poste juste son
|
|
|
|
|
propre id comme parent_id."""
|
|
|
|
|
session.add(Categorie(nom=nom, parent_id=int(parent_id) if parent_id else None))
|
2026-07-14 16:38:59 +00:00
|
|
|
session.commit()
|
|
|
|
|
return RedirectResponse(url="/categories", status_code=303)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/categories/{categorie_id}/supprimer")
|
|
|
|
|
def supprimer_categorie(categorie_id: int, session: Session = Depends(get_session)):
|
2026-07-14 17:06:37 +00:00
|
|
|
"""Supprime une catégorie. Refuse silencieusement si elle a encore des
|
|
|
|
|
sous-catégories ou des matériels rattachés, pour éviter de perdre des
|
|
|
|
|
données par erreur en un clic."""
|
2026-07-14 16:38:59 +00:00
|
|
|
categorie = session.get(Categorie, categorie_id)
|
2026-07-14 17:06:37 +00:00
|
|
|
if categorie and not categorie.enfants and not categorie.materiels:
|
2026-07-14 16:38:59 +00:00
|
|
|
session.delete(categorie)
|
|
|
|
|
session.commit()
|
|
|
|
|
return RedirectResponse(url="/categories", status_code=303)
|