fix: printer history report double-counts order totals on reprints

Backend (reports.py):
  - Cache order DB objects to avoid N+1 queries per log entry
  - Track seen_order_totals keyed by order_id so reprinting the same
    order doesn't inflate the total; returns total_amount pre-computed

Frontend (PrinterHistory.jsx):
  - Remove client-side accumulation that caused the same issue; use
    total_amount directly from the API response

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 23:54:07 +03:00
parent 18a75edf2a
commit 38bef6b1f4
2 changed files with 28 additions and 4 deletions

View File

@@ -1063,9 +1063,18 @@ def printer_history(
printers_db = {p.id: p for p in db.query(Printer).all()}
tables_db = {t.id: (t.label or f"T{t.number}") for t in db.query(Table).all()}
# Cache orders to avoid repeated queries
order_cache = {}
def _get_order(oid):
if oid not in order_cache:
order_cache[oid] = db.query(Order).filter(Order.id == oid).first()
return order_cache[oid]
result = []
seen_order_totals = {} # order_id → total, so we don't double-count reprints
for log in logs:
order = db.query(Order).filter(Order.id == log.order_id).first()
order = _get_order(log.order_id)
printer = printers_db.get(log.printer_id)
try:
item_ids = json.loads(log.item_ids)
@@ -1077,6 +1086,18 @@ def printer_history(
if oi:
pname = oi.product.name if oi.product else f"#{oi.product_id}"
items.append({"name": pname, "quantity": oi.quantity})
# Compute full order total (all active+paid items, not just printed slice)
order_total = None
if order:
order_total = sum(
i.unit_price * i.quantity
for i in order.items
if i.status in ("active", "paid")
)
if log.success and log.order_id not in seen_order_totals:
seen_order_totals[log.order_id] = order_total
result.append({
"id": log.id,
"printed_at": _dt(log.printed_at),
@@ -1086,11 +1107,14 @@ def printer_history(
"items": items,
"success": log.success,
"error_message": log.error_message,
"order_total": round(order_total, 2) if order_total is not None else None,
})
total = len(result)
failed = sum(1 for r in result if not r["success"])
return {"logs": result, "total": total, "failed": failed}
# Sum unique order totals (avoid inflating on reprints of the same order)
total_amount = round(sum(seen_order_totals.values()), 2) if seen_order_totals else None
return {"logs": result, "total": total, "failed": failed, "total_amount": total_amount}
# ---------------------------------------------------------------------------