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:
@@ -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}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user