Exclude cancelled orders from revenue/count stats

Dashboard and Statistics both summed every order in the period
regardless of status, so a cancelled order's total still counted
toward revenue, average check, card/cash split, and top products.
Cancelled orders are now excluded from all of that on both pages —
the dashboard's status donut is the one exception, since showing
cancellations there is its actual purpose.
This commit is contained in:
byrsapty 2026-08-25 16:10:34 +03:00
parent 8aa88264ff
commit 551b0d3afc
2 changed files with 18 additions and 6 deletions

View file

@ -189,6 +189,12 @@ def dashboard():
Order.created_at >= yesterday_start, Order.created_at < today_start
).all()
# Cancelled orders never earned anything — kept out of every
# revenue/count KPI below, but still counted in the status donut
# further down (that chart's whole point is showing cancellations too).
today_active = [o for o in today_orders if o.status != "cancelled"]
yesterday_active = [o for o in yesterday_orders if o.status != "cancelled"]
def summarize(orders):
delivery = [o for o in orders if o.order_type == "delivery"]
pickup = [o for o in orders if o.order_type == "pickup"]
@ -203,8 +209,8 @@ def dashboard():
"avg_check": round(revenue / len(orders)) if orders else 0,
}
today_stats = summarize(today_orders)
yesterday_stats = summarize(yesterday_orders)
today_stats = summarize(today_active)
yesterday_stats = summarize(yesterday_active)
status_counts = {s: 0 for s in ORDER_STATUSES}
for o in today_orders:
@ -214,7 +220,7 @@ def dashboard():
donut = _status_donut(status_counts)
top_products: dict[str, int] = {}
for order in today_orders:
for order in today_active:
for item in order.items:
top_products[item.product_name] = top_products.get(item.product_name, 0) + item.quantity
top_products_today = sorted(top_products.items(), key=lambda kv: kv[1], reverse=True)[:5]
@ -222,8 +228,8 @@ def dashboard():
finance_today = {
"revenue": today_stats["revenue"],
"card": sum(o.total for o in today_orders if o.payment_method == "card"),
"cash": sum(o.total for o in today_orders if o.payment_method == "cash"),
"card": sum(o.total for o in today_active if o.payment_method == "card"),
"cash": sum(o.total for o in today_active if o.payment_method == "cash"),
"avg_check": today_stats["avg_check"],
"count": today_stats["count"],
}

View file

@ -88,7 +88,13 @@ def statistics():
date_to = request.args.get("date_to", "")
period, start, end = _period_bounds(period, date_from, date_to)
orders = Order.query.filter(Order.created_at >= start, Order.created_at < end).all()
# Cancelled orders never earned anything and shouldn't drag down revenue,
# average check, or counts — this whole page is a business-performance
# view, unlike the dashboard's status donut which still needs to show
# cancellations as their own slice.
orders = Order.query.filter(
Order.created_at >= start, Order.created_at < end, Order.status != "cancelled"
).all()
revenue = sum(o.total for o in orders)
card_revenue = sum(o.total for o in orders if o.payment_method == "card")