feat: ShiftDetailModal rework, Today cancellation events, shift details icon button
- Backend: add cancellation_events (row count) to _enrich_shift and shift summary - Backend: add cancellation_events field to current business day endpoint - Today tab: hero number now shows cancellation_events (distinct cancel actions), sub-label shows 'X παραγγελίες / Y είδη' - ShiftsOverview: Λεπτομέρειες button is now icon-only (Eye, light blue) matching the delete button style - ShiftDetailModal: modal widened to 1080px; ΠΑΡΑΔΟΘΗΚΑΝ KPI replaced with Ακυρώσεις showing 'X events / Y items'; all filter labels renamed (Πλήρης Παραγγελία, Μόνο Πληρώθηκε, Μόνο Παρήγγειλε, Ανοιχτό ακόμη); new Ακυρώθηκε filter added; cancelled items shown in red, Πληρώθηκε line hidden for cancelled; legend updated; classify() handles cancelled status before other checks Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -84,6 +84,7 @@ def _enrich_shift(shift: WaiterShift, db: Session) -> dict:
|
||||
if shift.ended_at:
|
||||
cancelled_q = cancelled_q.filter(OrderItem.added_at <= shift.ended_at)
|
||||
cancelled_rows = cancelled_q.all()
|
||||
cancellation_events = len(cancelled_rows)
|
||||
cancellations = sum(r.quantity for r in cancelled_rows)
|
||||
cancellation_value = round(sum(r.unit_price * r.quantity for r in cancelled_rows), 2)
|
||||
return {
|
||||
@@ -101,6 +102,7 @@ def _enrich_shift(shift: WaiterShift, db: Session) -> dict:
|
||||
"hourly_rate_snapshot": shift.hourly_rate_snapshot,
|
||||
"duration_hours": pay_data["duration_hours"],
|
||||
"shift_pay": pay_data["shift_pay"],
|
||||
"cancellation_events": cancellation_events,
|
||||
"cancellations": cancellations,
|
||||
"cancellation_value": cancellation_value,
|
||||
# Phase 2E
|
||||
@@ -417,7 +419,7 @@ def get_shift_summary(
|
||||
|
||||
waiter_id = shift.waiter_id
|
||||
|
||||
# Collect all relevant items: paid in this shift OR added by this waiter
|
||||
# Collect all relevant items: paid in this shift OR added by this waiter (any status)
|
||||
paid_items = db.query(OrderItem).options(
|
||||
joinedload(OrderItem.product),
|
||||
joinedload(OrderItem.order),
|
||||
@@ -446,6 +448,22 @@ def get_shift_summary(
|
||||
items_by_id[item.id] = item
|
||||
all_items = list(items_by_id.values())
|
||||
|
||||
# Also include items cancelled within this shift window (may not be in ordered_items
|
||||
# if they were cancelled after the shift ended or deduped out)
|
||||
cancelled_items_for_summary = db.query(OrderItem).options(
|
||||
joinedload(OrderItem.product),
|
||||
joinedload(OrderItem.order),
|
||||
).filter(
|
||||
OrderItem.added_by == waiter_id,
|
||||
OrderItem.status == "cancelled",
|
||||
OrderItem.added_at >= shift.started_at,
|
||||
OrderItem.added_at <= upper_bound,
|
||||
).all()
|
||||
for item in cancelled_items_for_summary:
|
||||
if item.id not in items_by_id:
|
||||
items_by_id[item.id] = item
|
||||
all_items = list(items_by_id.values())
|
||||
|
||||
# Build lookup maps
|
||||
all_waiter_ids = set()
|
||||
for item in all_items:
|
||||
|
||||
Reference in New Issue
Block a user