Files
cantarire-etichetare/cantarire/routes/history.py
T
ske087 bff6d70b17 Initial commit: aplicatie de cantarire si etichetare
Aplicatie Flask + SQLite pentru productie alimentara: cantarirea
componentelor unui produs finit si tiparirea etichetei prin QZ Tray.

- produse finite (retete) formate din componente cantarite
- designer vizual de etichete (mm/px, zona sigura, campuri variabile,
  cod QR cu continut din mai multe bucati)
- legare produs finit -> sablon de eticheta
- navigare pe doua taburi: Cantarire / Setari
- administrare: componente, produse finite, sabloane, campuri, istoric
- backup, resetare baza de date, checklist de pregatire, /healthz
- CLI de administrare si serviciu systemd pentru productie
- vendor/syncpulse-scale-bridge (GPL-3.0-or-later) pentru citirea cantarului
2026-10-18 23:38:45 +03:00

66 lines
2.0 KiB
Python

"""Istoricul pachetelor si exportul CSV."""
from __future__ import annotations
import csv
import io
from flask import Blueprint, Response, render_template, request
from ..repositories import get_recipe, list_packages, list_recipes, to_csv_rows
from ..units import format_weight
bp = Blueprint("history", __name__, url_prefix="/istoric")
def _filters() -> dict:
recipe_id = request.args.get("recipe_id", "").strip()
status = request.args.get("status", "").strip()
return {
"date_from": request.args.get("date_from", "").strip(),
"date_to": request.args.get("date_to", "").strip(),
"recipe_id": int(recipe_id) if recipe_id.isdigit() else None,
"status": status if status in {"open", "done", "void"} else "",
"query": request.args.get("q", "").strip(),
"limit": 1000,
}
def _totals(packages: list[dict]) -> str:
groups: dict[str, float] = {}
for package in packages:
if package.get("status") != "done":
continue
unit = package.get("unit") or ""
groups[unit] = groups.get(unit, 0.0) + float(package.get("total_weight") or 0)
return ", ".join(
f"{format_weight(value)} {unit}" for unit, value in sorted(groups.items())
) or "0"
@bp.get("")
def index():
filters = _filters()
packages = list_packages(**filters)
recipe = get_recipe(filters["recipe_id"]) if filters["recipe_id"] else None
return render_template(
"history/list.html",
packages=packages,
filters=filters,
recipes=list_recipes(include_inactive=True),
total=_totals(packages),
selected_recipe=recipe,
)
@bp.get("/export.csv")
def export_csv():
packages = list_packages(**_filters())
buffer = io.StringIO()
writer = csv.writer(buffer, delimiter=";", lineterminator="\r\n")
writer.writerows(to_csv_rows(packages))
return Response(
buffer.getvalue(),
mimetype="text/csv; charset=utf-8",
headers={"Content-Disposition": 'attachment; filename="produse-finite.csv"'},
)