diff --git a/app/filamentdb.py b/app/filamentdb.py index ca83fd7..e4ea1ea 100644 --- a/app/filamentdb.py +++ b/app/filamentdb.py @@ -50,6 +50,20 @@ def available_materials() -> list[str]: return sorted(out) +def spool_counts() -> dict[tuple[str, str], int]: + """Returns {(material, color_name): available_rolls} from cached stock. + + 'Available' = rolls_in_stock + rolls_in_use (anything not in the graveyard). + Multiple filament types with the same material+color are summed. + """ + result: dict[tuple[str, str], int] = {} + for r in get_stock(): + key = (r.get("material") or "", r.get("color_name") or "") + count = (r.get("rolls_in_stock") or 0) + (r.get("rolls_in_use") or 0) + result[key] = result.get(key, 0) + count + return result + + def available_colors(material: str | None = None) -> list[str]: """Unique color names in stock, optionally filtered by material.""" rows = get_stock() diff --git a/app/routers/ui.py b/app/routers/ui.py index 81aa342..95e0d40 100644 --- a/app/routers/ui.py +++ b/app/routers/ui.py @@ -20,7 +20,7 @@ from app.models.printer_type import PrinterType from app.models.pricing import PricingConfig from app.models.todo import Todo from app.constants import COLORS, MATERIALS -from app.filamentdb import available_colors, available_materials, get_stock +from app.filamentdb import available_colors, available_materials, get_stock, spool_counts from app.stl import get_stl_dir, list_stl_files from app.stl_analysis import analyse, get_cache_map # noqa: F401 used in job_detail route @@ -145,6 +145,7 @@ def jobs_page(request: Request, q: str = "", db: Session = Depends(get_db)): "stl_cache": get_cache_map(stl_files, db), "materials": available_materials() or MATERIALS, "colors": available_colors() or COLORS, + "spool_map": spool_counts(), }) diff --git a/app/templates/jobs.html b/app/templates/jobs.html index b0ab80e..ab5cf9a 100644 --- a/app/templates/jobs.html +++ b/app/templates/jobs.html @@ -53,7 +53,17 @@