Files
xenia-pos-local/local_backend/schemas/order.py
bonamin 80842d9be3 fix(connect): store cloud order id locally to enable reliable status mirroring
The Phase 4 _mirror_status_to_cloud function had no way to look up the
cloud order's numeric id once it was marked synced (not in the pending
list anymore), so status updates from local staff could silently fail.

Fix:
  - models/order.py: online_order_cloud_id INTEGER column added to Order
  - main.py: migration for the new column
  - schemas/order.py: online_order_cloud_id exposed in OrderOut
  - cloud_sync.py: stores cloud_order["id"] as online_order_cloud_id
    when creating the local order during the pull
  - connect_orders.py: _mirror_status_to_cloud now takes the integer
    cloud id directly — no more pending-list lookup; function body
    reduced from ~50 lines to ~15

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 00:14:43 +03:00

137 lines
3.6 KiB
Python

from pydantic import BaseModel
from datetime import datetime
from typing import Optional, List
from schemas.base import UTCDatetime
class SelectedOptionInput(BaseModel):
id: Optional[int] = None
name: Optional[str] = None
price_delta: Optional[float] = None
extra_cost: Optional[float] = None
# type tags: "quick" | "pref" | "pref_sub" | "extra" | "extra_sub"
# Omitted by old clients — print code falls back gracefully.
type: Optional[str] = None
class OrderItemInput(BaseModel):
product_id: int
quantity: int
selected_options: Optional[List[SelectedOptionInput]] = None
removed_ingredients: Optional[List[str]] = None
notes: Optional[str] = None
class AddItemsRequest(BaseModel):
items: List[OrderItemInput]
class ProductNameOut(BaseModel):
id: int
name: str
model_config = {"from_attributes": True}
class OrderItemOut(BaseModel):
id: int
order_id: int
product_id: int
product: Optional[ProductNameOut] = None
added_by: int
quantity: int
unit_price: float
selected_options: Optional[str] = None
removed_ingredients: Optional[str] = None
notes: Optional[str] = None
status: str
added_at: UTCDatetime
printed: bool
paid_by: Optional[int] = None
paid_at: Optional[UTCDatetime] = None
payment_method: Optional[str] = None
paid_in_shift_id: Optional[int] = None
model_config = {"from_attributes": True}
class PrintResultOut(BaseModel):
printer_name: str
success: bool
error: Optional[str] = None
class AddItemsResponse(BaseModel):
order: "OrderOut"
print_results: List[PrintResultOut]
model_config = {"from_attributes": True}
class OrderCreate(BaseModel):
table_id: int
class PayItemsRequest(BaseModel):
item_ids: List[int]
payment_method: Optional[str] = None # 'cash' | 'card' | 'other' — optional for now
class OfflinePaymentRequest(BaseModel):
uuid: str # client-generated UUID, used for duplicate detection
item_ids: List[int]
payment_method: Optional[str] = None
offline_at: Optional[str] = None # ISO timestamp of when payment was taken offline
class AssignWaiterRequest(BaseModel):
waiter_id: int
class OrderWaiterOut(BaseModel):
waiter_id: int
model_config = {"from_attributes": True}
class AuditLogOut(BaseModel):
id: int
order_id: int
event_type: str
waiter_id: Optional[int] = None
waiter_name: Optional[str] = None # resolved server-side
item_ids: Optional[str] = None
amount: Optional[float] = None
payment_method: Optional[str] = None
note: Optional[str] = None
created_at: UTCDatetime
offline_at: Optional[str] = None
is_duplicate: int = 0
model_config = {"from_attributes": True}
class OrderOut(BaseModel):
id: int
table_id: Optional[int] = None
opened_by: int
opened_at: UTCDatetime
status: str
closed_at: Optional[UTCDatetime] = None
closed_by: Optional[int] = None
notes: Optional[str] = None
business_day_id: Optional[int] = None
# Xenia Connect — online order fields
source: str = "pos"
online_order_ref: Optional[str] = None
online_order_cloud_id: Optional[int] = None
online_status: Optional[str] = None
online_customer_name: Optional[str] = None
online_customer_phone: Optional[str] = None
online_customer_address: Optional[str] = None
online_customer_notes: Optional[str] = None
online_order_type: Optional[str] = None
items: List[OrderItemOut] = []
waiters: List[OrderWaiterOut] = []
audit_logs: List[AuditLogOut] = []
model_config = {"from_attributes": True}