Files
xenia-pos-local/local_backend/schemas/table.py
bonamin 79bd3b0f41 feat(local_backend): reservations, print analytics, workday summary, zone-PIN management
- New reservations module: model, schema, router (CRUD + status updates + upcoming alerts)
  and background task for auto-expiring stale reservations
- Reports: print_products, print_categories, print_tables analytics endpoints
  plus meta_products and business_day_summary for workday close/view flow
- printer_service: configurable font sizes/weights, donut/bar chart print layout helpers,
  analytics print blocks per printer
- tables/schemas: surfaced color, zone, and other new fields on Table, Product, User, Printer
- demo_seed.py for quick dev DB population; wipe_database.py utility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 20:25:22 +03:00

100 lines
2.4 KiB
Python

from pydantic import BaseModel, field_validator
from typing import Optional, List
from datetime import datetime
MAX_TABLE_NAME_LENGTH = 6
class TableGroupCreate(BaseModel):
name: str
prefix: Optional[str] = None
color: Optional[str] = None
class TableGroupUpdate(BaseModel):
name: Optional[str] = None
prefix: Optional[str] = None
color: Optional[str] = None
class TableGroupOut(BaseModel):
id: int
name: str
prefix: Optional[str] = None
sort_order: int = 0
color: Optional[str] = None
model_config = {"from_attributes": True}
class TableBase(BaseModel):
label: Optional[str] = None
group_id: Optional[int] = None
is_active: bool = True
class TableCreate(BaseModel):
label: Optional[str] = None
group_id: Optional[int] = None
@field_validator("label")
@classmethod
def label_max_length(cls, v):
if v is not None:
v = v.strip()
if len(v) > MAX_TABLE_NAME_LENGTH:
raise ValueError(f"Table name cannot exceed {MAX_TABLE_NAME_LENGTH} characters")
return v
class TableBatchCreate(BaseModel):
group_id: Optional[int] = None
count: int
name_prefix: str # e.g. "TBL-" → TBL-1, TBL-2 ...
# start_number is computed on the backend from existing tables in the group
class TableUpdate(BaseModel):
label: Optional[str] = None
group_id: Optional[int] = None
is_active: Optional[bool] = None
@field_validator("label")
@classmethod
def label_max_length(cls, v):
if v is not None:
v = v.strip()
if len(v) > MAX_TABLE_NAME_LENGTH:
raise ValueError(f"Table name cannot exceed {MAX_TABLE_NAME_LENGTH} characters")
return v
class TableFloorplanUpdate(BaseModel):
floor_x: float
floor_y: float
class UpcomingReservation(BaseModel):
id: int
guest_name: str
party_size: int
reserved_for: datetime
status: str
model_config = {"from_attributes": True}
class TableOut(BaseModel):
id: int
number: int
label: Optional[str] = None
group_id: Optional[int] = None
is_active: bool = True
floor_x: Optional[float] = None
floor_y: Optional[float] = None
group: Optional[TableGroupOut] = None
has_active_order: bool = False
upcoming_reservation: Optional[UpcomingReservation] = None
model_config = {"from_attributes": True}