IT-Stock/app/categories_arbre.py
maxsoch 5088182f20 Création rapide depuis le scan, ajustement de stock flexible, filtres matériels
Un code-barre inconnu scanné propose désormais le même formulaire de
création que /materiels au lieu d'un simple message d'erreur. La
quantité peut être ajustée d'un delta choisi librement (pas figé à ±1)
ou définie directement à une valeur absolue après un inventaire. La
racine "/" sert directement la liste des matériels sans redirection.
La page Matériels gagne un filtre par catégorie, un filtre stock bas,
et un tri incluant un regroupement par catégorie.
2026-07-14 19:17:27 +02:00

37 lines
1.4 KiB
Python

"""
Utilitaires de parcours de l'arborescence de catégories (profondeur
illimitée). Partagés entre le routeur categories (affichage de l'arbre) et
le routeur materiels (construction du <select> indenté).
"""
from sqlmodel import Session, select
from app.models import Categorie
def categories_racines(session: Session) -> list[Categorie]:
"""Catégories de premier niveau (sans parent)."""
return list(session.exec(select(Categorie).where(Categorie.parent_id.is_(None))).all())
def aplatir(categories: list[Categorie], profondeur: int = 0) -> list[tuple[int, Categorie]]:
"""Aplatit l'arborescence en une liste (profondeur, categorie), dans
l'ordre d'affichage (chaque nœud juste avant ses enfants). Sert à
construire un <select> indenté sans avoir besoin de JavaScript."""
resultat: list[tuple[int, Categorie]] = []
for categorie in categories:
resultat.append((profondeur, categorie))
resultat.extend(aplatir(categorie.enfants, profondeur + 1))
return resultat
def ids_sous_arbre(categorie: Categorie) -> set[int]:
"""L'id de cette catégorie et de tous ses descendants, à n'importe
quelle profondeur. Sert au filtre "cette catégorie" sur /materiels :
on veut aussi les matériels rattachés à ses sous-catégories, pas
seulement à elle-même."""
ids = {categorie.id}
for enfant in categorie.enfants:
ids |= ids_sous_arbre(enfant)
return ids