64 lines
2.1 KiB
Python
64 lines
2.1 KiB
Python
|
|
"""
|
||
|
|
Routes pour l'écran de scan à la douchette code-barres.
|
||
|
|
|
||
|
|
La douchette émule un clavier : elle "tape" le code puis un retour à la
|
||
|
|
ligne (touche Entrée). Il suffit donc d'un unique <input> dans un <form> :
|
||
|
|
le navigateur soumet automatiquement le formulaire quand Entrée est
|
||
|
|
pressée, sans qu'on ait besoin d'écrire de JavaScript spécifique pour
|
||
|
|
capter le scan.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from fastapi import APIRouter, Depends, Form
|
||
|
|
from fastapi.requests import Request
|
||
|
|
from sqlmodel import Session, select
|
||
|
|
|
||
|
|
from app.database import get_session
|
||
|
|
from app.email_alerts import verifier_et_alerter
|
||
|
|
from app.models import Materiel
|
||
|
|
from app.templates_engine import templates
|
||
|
|
|
||
|
|
router = APIRouter()
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/scan")
|
||
|
|
def page_scan(request: Request):
|
||
|
|
"""Affiche le champ de scan, vide."""
|
||
|
|
return templates.TemplateResponse(
|
||
|
|
request, "scan.html", {"materiel": None, "erreur": None}
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/scan")
|
||
|
|
def rechercher_par_code_barre(
|
||
|
|
request: Request, code_barre: str = Form(...), session: Session = Depends(get_session)
|
||
|
|
):
|
||
|
|
"""Cherche le matériel correspondant au code-barre scanné."""
|
||
|
|
materiel = session.exec(
|
||
|
|
select(Materiel).where(Materiel.code_barre == code_barre)
|
||
|
|
).first()
|
||
|
|
erreur = None if materiel else f"Aucun matériel avec le code-barre « {code_barre} »."
|
||
|
|
return templates.TemplateResponse(
|
||
|
|
request, "scan.html", {"materiel": materiel, "erreur": erreur}
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/scan/{materiel_id}/ajuster")
|
||
|
|
def ajuster_quantite(
|
||
|
|
request: Request,
|
||
|
|
materiel_id: int,
|
||
|
|
delta: int = Form(...),
|
||
|
|
session: Session = Depends(get_session),
|
||
|
|
):
|
||
|
|
"""Ajuste la quantité en stock d'un matériel (+1 en réception, -1 en
|
||
|
|
sortie) puis vérifie si une alerte de stock bas doit être envoyée."""
|
||
|
|
materiel = session.get(Materiel, materiel_id)
|
||
|
|
if materiel:
|
||
|
|
materiel.quantite = max(0, materiel.quantite + delta)
|
||
|
|
session.add(materiel)
|
||
|
|
session.commit()
|
||
|
|
session.refresh(materiel)
|
||
|
|
verifier_et_alerter(materiel, session)
|
||
|
|
return templates.TemplateResponse(
|
||
|
|
request, "scan.html", {"materiel": materiel, "erreur": None}
|
||
|
|
)
|