feat: complete unified order model integration for Letzshop API

Update API endpoints and schemas to use the unified Order model:
- Update Letzshop order schemas with OrderItem support
- Update API responses to use new field names (external_*, status, etc.)
- Update confirm/reject endpoints to use OrderItem.external_item_id
- Update Letzshop order service for unified Order model queries
- Update documentation to reflect completed implementation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-19 21:27:24 +01:00
parent 6a10fbba10
commit c49b80ce41
4 changed files with 530 additions and 533 deletions

View File

@@ -71,76 +71,119 @@ class LetzshopCredentialsStatus(BaseModel):
# ============================================================================
# Letzshop Order Schemas
# Letzshop Order Schemas (using unified Order model)
# ============================================================================
class LetzshopInventoryUnit(BaseModel):
"""Schema for Letzshop inventory unit."""
class LetzshopOrderItemResponse(BaseModel):
"""Schema for order item in Letzshop order response."""
id: str
state: str
model_config = ConfigDict(from_attributes=True)
id: int
product_id: int
product_name: str
product_sku: str | None = None
gtin: str | None = None
gtin_type: str | None = None
quantity: int
unit_price: float
total_price: float
external_item_id: str | None = None # Letzshop inventory unit ID
external_variant_id: str | None = None
item_state: str | None = None # confirmed_available, confirmed_unavailable
class LetzshopOrderBase(BaseModel):
"""Base schema for Letzshop order."""
letzshop_order_id: str
letzshop_shipment_id: str | None = None
letzshop_order_number: str | None = None
letzshop_state: str | None = None
customer_email: str | None = None
customer_name: str | None = None
customer_locale: str | None = None
shipping_country_iso: str | None = None
billing_country_iso: str | None = None
total_amount: str | None = None
currency: str = "EUR"
class LetzshopOrderCreate(LetzshopOrderBase):
"""Schema for creating a Letzshop order record."""
vendor_id: int
raw_order_data: dict[str, Any] | None = None
inventory_units: list[dict[str, Any]] | None = None
class LetzshopOrderResponse(LetzshopOrderBase):
"""Schema for Letzshop order response."""
class LetzshopOrderResponse(BaseModel):
"""Schema for Letzshop order response (from unified Order model)."""
model_config = ConfigDict(from_attributes=True)
id: int
vendor_id: int
local_order_id: int | None
sync_status: str
last_synced_at: datetime | None
sync_error: str | None
confirmed_at: datetime | None
rejected_at: datetime | None
tracking_set_at: datetime | None
tracking_number: str | None
tracking_carrier: str | None
inventory_units: list[dict[str, Any]] | None
order_date: datetime | None
order_number: str
# External references
external_order_id: str | None = None
external_shipment_id: str | None = None
external_order_number: str | None = None
# Status
status: str # pending, processing, shipped, delivered, cancelled
# Customer info
customer_email: str
customer_name: str # computed: customer_first_name + customer_last_name
customer_locale: str | None = None
# Address info
ship_country_iso: str
bill_country_iso: str
# Financial
total_amount: float
currency: str = "EUR"
# Tracking
tracking_number: str | None = None
tracking_provider: str | None = None
# Timestamps
order_date: datetime
confirmed_at: datetime | None = None
shipped_at: datetime | None = None
cancelled_at: datetime | None = None
created_at: datetime
updated_at: datetime
# Items (for list view, may be empty)
items: list[LetzshopOrderItemResponse] = Field(default_factory=list)
class LetzshopOrderDetailResponse(LetzshopOrderResponse):
"""Schema for detailed Letzshop order response with raw data."""
"""Schema for detailed Letzshop order response with all data."""
raw_order_data: dict[str, Any] | None = None
# Full customer snapshot
customer_first_name: str
customer_last_name: str
customer_phone: str | None = None
# Full shipping address
ship_first_name: str
ship_last_name: str
ship_company: str | None = None
ship_address_line_1: str
ship_address_line_2: str | None = None
ship_city: str
ship_postal_code: str
# Full billing address
bill_first_name: str
bill_last_name: str
bill_company: str | None = None
bill_address_line_1: str
bill_address_line_2: str | None = None
bill_city: str
bill_postal_code: str
# Raw marketplace data
external_data: dict[str, Any] | None = None
# Notes
customer_notes: str | None = None
internal_notes: str | None = None
class LetzshopOrderStats(BaseModel):
"""Schema for order statistics by status."""
pending: int = 0
confirmed: int = 0
rejected: int = 0
processing: int = 0
shipped: int = 0
delivered: int = 0
cancelled: int = 0
total: int = 0
has_declined_items: int = 0 # Orders with at least one declined item
class LetzshopOrderListResponse(BaseModel):
@@ -150,7 +193,7 @@ class LetzshopOrderListResponse(BaseModel):
total: int
skip: int
limit: int
stats: LetzshopOrderStats | None = None # Order counts by sync_status
stats: LetzshopOrderStats | None = None
# ============================================================================
@@ -191,7 +234,7 @@ class FulfillmentQueueItemResponse(BaseModel):
id: int
vendor_id: int
letzshop_order_id: int
order_id: int # FK to unified orders table
operation: str
payload: dict[str, Any]
status: str