Files
simple-pos-system/local_backend/routers/reports.py

87 lines
3.1 KiB
Python

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