Phase 1: scaffold local backend — models, schemas, routers, printer service, Docker
This commit is contained in:
86
local_backend/routers/reports.py
Normal file
86
local_backend/routers/reports.py
Normal file
@@ -0,0 +1,86 @@
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import func
|
||||
from datetime import date, datetime, timedelta
|
||||
from typing import Optional, List
|
||||
|
||||
from database import get_db
|
||||
from models.order import Order, OrderItem, OrderWaiter
|
||||
from models.user import User
|
||||
from models.table import Table
|
||||
from schemas.order import OrderOut
|
||||
from schemas.table import TableOut
|
||||
from routers.deps import require_manager
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/shift")
|
||||
def shift_summary(
|
||||
report_date: Optional[date] = Query(default=None, alias="date"),
|
||||
waiter_id: Optional[int] = None,
|
||||
db: Session = Depends(get_db),
|
||||
user: User = Depends(require_manager),
|
||||
):
|
||||
target = report_date or date.today()
|
||||
start = datetime.combine(target, datetime.min.time())
|
||||
end = start + timedelta(days=1)
|
||||
|
||||
q = db.query(Order).filter(Order.opened_at >= start, Order.opened_at < end)
|
||||
if waiter_id:
|
||||
q = q.join(OrderWaiter).filter(OrderWaiter.waiter_id == waiter_id)
|
||||
orders = q.all()
|
||||
|
||||
summary = {}
|
||||
for order in orders:
|
||||
waiter = db.query(User).filter(User.id == order.opened_by).first()
|
||||
key = waiter.username if waiter else "unknown"
|
||||
if key not in summary:
|
||||
summary[key] = {"orders": 0, "items": 0, "total": 0.0}
|
||||
summary[key]["orders"] += 1
|
||||
for item in order.items:
|
||||
if item.status in ("active", "paid"):
|
||||
summary[key]["items"] += item.quantity
|
||||
summary[key]["total"] += item.unit_price * item.quantity
|
||||
|
||||
return {"date": str(target), "waiters": summary}
|
||||
|
||||
|
||||
@router.get("/orders/history", response_model=List[OrderOut])
|
||||
def order_history(
|
||||
from_date: Optional[str] = Query(default=None, alias="from"),
|
||||
to_date: Optional[str] = Query(default=None, alias="to"),
|
||||
waiter_id: Optional[int] = None,
|
||||
order_status: Optional[str] = Query(default=None, alias="status"),
|
||||
page: int = 1,
|
||||
page_size: int = 50,
|
||||
db: Session = Depends(get_db),
|
||||
user: User = Depends(require_manager),
|
||||
):
|
||||
q = db.query(Order)
|
||||
if from_date:
|
||||
q = q.filter(Order.opened_at >= datetime.fromisoformat(from_date))
|
||||
if to_date:
|
||||
q = q.filter(Order.opened_at <= datetime.fromisoformat(to_date))
|
||||
if waiter_id:
|
||||
q = q.join(OrderWaiter).filter(OrderWaiter.waiter_id == waiter_id)
|
||||
if order_status:
|
||||
q = q.filter(Order.status == order_status)
|
||||
return q.order_by(Order.opened_at.desc()).offset((page - 1) * page_size).limit(page_size).all()
|
||||
|
||||
|
||||
@router.get("/tables/summary")
|
||||
def tables_summary(db: Session = Depends(get_db), user: User = Depends(require_manager)):
|
||||
tables = db.query(Table).filter(Table.is_active == True).all()
|
||||
result = []
|
||||
for table in tables:
|
||||
active_order = db.query(Order).filter(
|
||||
Order.table_id == table.id,
|
||||
Order.status.in_(["open", "partially_paid"]),
|
||||
).first()
|
||||
result.append({
|
||||
"table": TableOut.model_validate(table),
|
||||
"status": active_order.status if active_order else "free",
|
||||
"order_id": active_order.id if active_order else None,
|
||||
})
|
||||
return result
|
||||
Reference in New Issue
Block a user