feat: bump client-services (accumulated feature work + deploy fixes)
Snapshot of in-progress work across local_backend, manager_dashboard, and waiter_pwa (pricing, chat, fiscal, prep zones, recovery codes, CRM, inventory, permissions), plus the nginx/docker-compose deploy fixes for the Unraid + NPM reverse-proxy setup. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ from sqlalchemy import func
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import Optional
|
||||
from datetime import datetime, timezone
|
||||
from pydantic import BaseModel
|
||||
|
||||
from database import get_db
|
||||
from models.business_day import BusinessDay
|
||||
@@ -173,6 +174,60 @@ def close_business_day(
|
||||
return day
|
||||
|
||||
|
||||
class PatchBusinessDayRequest(BaseModel):
|
||||
closed_at: str # ISO-8601 datetime string
|
||||
|
||||
|
||||
@router.patch("/{day_id}", status_code=status.HTTP_200_OK)
|
||||
def patch_business_day(
|
||||
day_id: int,
|
||||
body: "PatchBusinessDayRequest",
|
||||
db: Session = Depends(get_db),
|
||||
user: User = Depends(require_manager),
|
||||
):
|
||||
"""Edit the close-time of a past (closed) business day.
|
||||
Constraints:
|
||||
- Day must already be closed.
|
||||
- new closed_at must be ≥ the latest order closed_at in this day.
|
||||
- new closed_at must be ≤ now (UTC).
|
||||
"""
|
||||
day = db.query(BusinessDay).filter(BusinessDay.id == day_id).first()
|
||||
if not day:
|
||||
raise HTTPException(status_code=404, detail="Business day not found")
|
||||
if day.status != "closed":
|
||||
raise HTTPException(status_code=400, detail="Can only edit a closed business day")
|
||||
|
||||
try:
|
||||
new_closed = datetime.fromisoformat(body.closed_at.replace("Z", "+00:00"))
|
||||
if new_closed.tzinfo is None:
|
||||
new_closed = new_closed.replace(tzinfo=timezone.utc)
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=422, detail="Invalid datetime format")
|
||||
|
||||
now = datetime.now(timezone.utc)
|
||||
if new_closed > now:
|
||||
raise HTTPException(status_code=400, detail="Close time cannot be in the future")
|
||||
|
||||
# Must not be earlier than the latest order closed_at in this day
|
||||
last_order_close = (
|
||||
db.query(func.max(Order.closed_at))
|
||||
.filter(Order.business_day_id == day_id, Order.closed_at != None)
|
||||
.scalar()
|
||||
)
|
||||
if last_order_close:
|
||||
if last_order_close.tzinfo is None:
|
||||
last_order_close = last_order_close.replace(tzinfo=timezone.utc)
|
||||
if new_closed < last_order_close:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Close time cannot be earlier than the last order's close time ({_dt(last_order_close)})"
|
||||
)
|
||||
|
||||
day.closed_at = new_closed
|
||||
db.commit()
|
||||
return {"id": day.id, "closed_at": _dt(day.closed_at)}
|
||||
|
||||
|
||||
@router.delete("/{day_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def delete_business_day(
|
||||
day_id: int,
|
||||
|
||||
Reference in New Issue
Block a user