fix(report): count paid+completed sales (migrated=paid), fix hour :00 bind-param, add format breakdown

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
type-two 2026-06-23 18:26:57 +10:00
parent 336d525585
commit 6a95efb9bb

View File

@ -495,7 +495,8 @@ async def reports(ident=Depends(require_token), db=Depends(get_db)):
# ── Reports workbench — parameterized + lazy (each chart fetched on demand) ───────────────────
_DONE = "s.status = 'completed'"
# migrated history is status='paid'; new POS sales are 'completed' — count both, exclude open holds
_DONE = "s.status IN ('completed','paid')"
def _period(days: int, frm, to):
@ -548,7 +549,8 @@ async def report_series(days: int = Query(30), bucket: str = Query("day"),
_BREAKDOWN = {
"payment": "SELECT coalesce(nullif(s.payment_method,''),'?') AS name, count(*) AS count, coalesce(sum(s.total),0)::float AS revenue FROM sales s WHERE {where} AND {done} GROUP BY 1 ORDER BY {order} DESC LIMIT {lim}",
"weekday": "SELECT trim(to_char(s.sale_date,'Dy')) AS name, extract(dow from s.sale_date) AS _o, count(*) AS count, coalesce(sum(s.total),0)::float AS revenue FROM sales s WHERE {where} AND {done} GROUP BY 1,2 ORDER BY _o",
"hour": "SELECT lpad(extract(hour from s.sale_date)::text,2,'0')||':00' AS name, count(*) AS count, coalesce(sum(s.total),0)::float AS revenue FROM sales s WHERE {where} AND {done} GROUP BY 1 ORDER BY 1",
"hour": "SELECT to_char(s.sale_date,'HH24')||'h' AS name, count(*) AS count, coalesce(sum(s.total),0)::float AS revenue FROM sales s WHERE {where} AND {done} AND s.sale_date IS NOT NULL GROUP BY 1 ORDER BY 1",
"format": "SELECT coalesce(nullif(f.name,''),'') AS name, count(*) AS count, coalesce(sum(si.line_total),0)::float AS revenue FROM sales s JOIN sale_items si ON si.sale_id=s.id JOIN inventory i ON i.sku=si.sku JOIN disc_release_format f ON f.release_id=i.release_id WHERE {where} AND {done} GROUP BY 1 ORDER BY {order} DESC LIMIT {lim}",
"condition": "SELECT coalesce(nullif(i.condition,''),'') AS name, count(*) AS count, coalesce(sum(si.line_total),0)::float AS revenue FROM sales s JOIN sale_items si ON si.sale_id=s.id JOIN inventory i ON i.sku=si.sku WHERE {where} AND {done} GROUP BY 1 ORDER BY {order} DESC LIMIT {lim}",
"kind": "SELECT coalesce(nullif(i.kind,''),'') AS name, count(*) AS count, coalesce(sum(si.line_total),0)::float AS revenue FROM sales s JOIN sale_items si ON si.sale_id=s.id JOIN inventory i ON i.sku=si.sku WHERE {where} AND {done} GROUP BY 1 ORDER BY {order} DESC LIMIT {lim}",
"genre": "SELECT g.genre_name AS name, count(*) AS count, coalesce(sum(si.line_total),0)::float AS revenue FROM sales s JOIN sale_items si ON si.sale_id=s.id JOIN inventory i ON i.sku=si.sku JOIN disc_release_genre g ON g.release_id=i.release_id WHERE {where} AND {done} AND g.genre_name<>'' GROUP BY 1 ORDER BY {order} DESC LIMIT {lim}",