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>
137 lines
3.6 KiB
Python
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}
|