fix: update letzshop API to use unified Order model properties

- Change message exceptions (MessageAttachmentException,
  InvalidConversationTypeException, InvalidRecipientTypeException)
  to extend BusinessLogicException instead of ValidationException
  which doesn't accept error_code parameter

- Update vendor letzshop API endpoints:
  - Change sync_status query param to status in list_orders()
  - Fix response mapping to use unified Order model properties
    (external_order_id, external_shipment_id, status, etc.)
  - Fix confirm_order() to get inventory unit IDs from order items
  - Fix set_tracking() to use external_shipment_id

- Add order_date to test fixtures (required NOT NULL field)

🤖 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-22 23:13:00 +01:00
parent 6f8434f200
commit feca2e19fe
4 changed files with 86 additions and 45 deletions

View File

@@ -267,8 +267,7 @@ def test_api_key(
def list_orders(
skip: int = Query(0, ge=0),
limit: int = Query(50, ge=1, le=200),
sync_status: str | None = Query(None, description="Filter by sync status"),
letzshop_state: str | None = Query(None, description="Filter by Letzshop state"),
status: str | None = Query(None, description="Filter by order status"),
current_user: User = Depends(get_current_vendor_api),
db: Session = Depends(get_db),
):
@@ -280,8 +279,7 @@ def list_orders(
vendor_id=vendor_id,
skip=skip,
limit=limit,
sync_status=sync_status,
letzshop_state=letzshop_state,
status=status,
)
return LetzshopOrderListResponse(
@@ -289,24 +287,24 @@ def list_orders(
LetzshopOrderResponse(
id=order.id,
vendor_id=order.vendor_id,
letzshop_order_id=order.letzshop_order_id,
letzshop_shipment_id=order.letzshop_shipment_id,
letzshop_order_number=order.letzshop_order_number,
letzshop_state=order.letzshop_state,
order_number=order.order_number,
external_order_id=order.external_order_id,
external_shipment_id=order.external_shipment_id,
external_order_number=order.external_order_number,
status=order.status,
customer_email=order.customer_email,
customer_name=order.customer_name,
customer_name=f"{order.customer_first_name} {order.customer_last_name}",
customer_locale=order.customer_locale,
ship_country_iso=order.ship_country_iso,
bill_country_iso=order.bill_country_iso,
total_amount=order.total_amount,
currency=order.currency,
local_order_id=order.local_order_id,
sync_status=order.sync_status,
last_synced_at=order.last_synced_at,
sync_error=order.sync_error,
confirmed_at=order.confirmed_at,
rejected_at=order.rejected_at,
tracking_set_at=order.tracking_set_at,
tracking_number=order.tracking_number,
tracking_carrier=order.tracking_carrier,
inventory_units=order.inventory_units,
tracking_provider=order.tracking_provider,
order_date=order.order_date,
confirmed_at=order.confirmed_at,
shipped_at=order.shipped_at,
cancelled_at=order.cancelled_at,
created_at=order.created_at,
updated_at=order.updated_at,
)
@@ -333,29 +331,50 @@ def get_order(
raise ResourceNotFoundException("LetzshopOrder", str(order_id))
return LetzshopOrderDetailResponse(
# Base fields from LetzshopOrderResponse
id=order.id,
vendor_id=order.vendor_id,
letzshop_order_id=order.letzshop_order_id,
letzshop_shipment_id=order.letzshop_shipment_id,
letzshop_order_number=order.letzshop_order_number,
letzshop_state=order.letzshop_state,
order_number=order.order_number,
external_order_id=order.external_order_id,
external_shipment_id=order.external_shipment_id,
external_order_number=order.external_order_number,
status=order.status,
customer_email=order.customer_email,
customer_name=order.customer_name,
customer_name=f"{order.customer_first_name} {order.customer_last_name}",
customer_locale=order.customer_locale,
ship_country_iso=order.ship_country_iso,
bill_country_iso=order.bill_country_iso,
total_amount=order.total_amount,
currency=order.currency,
local_order_id=order.local_order_id,
sync_status=order.sync_status,
last_synced_at=order.last_synced_at,
sync_error=order.sync_error,
confirmed_at=order.confirmed_at,
rejected_at=order.rejected_at,
tracking_set_at=order.tracking_set_at,
tracking_number=order.tracking_number,
tracking_carrier=order.tracking_carrier,
inventory_units=order.inventory_units,
raw_order_data=order.raw_order_data,
tracking_provider=order.tracking_provider,
order_date=order.order_date,
confirmed_at=order.confirmed_at,
shipped_at=order.shipped_at,
cancelled_at=order.cancelled_at,
created_at=order.created_at,
updated_at=order.updated_at,
# Detail fields from LetzshopOrderDetailResponse
customer_first_name=order.customer_first_name,
customer_last_name=order.customer_last_name,
customer_phone=order.customer_phone,
ship_first_name=order.ship_first_name,
ship_last_name=order.ship_last_name,
ship_company=order.ship_company,
ship_address_line_1=order.ship_address_line_1,
ship_address_line_2=order.ship_address_line_2,
ship_city=order.ship_city,
ship_postal_code=order.ship_postal_code,
bill_first_name=order.bill_first_name,
bill_last_name=order.bill_last_name,
bill_company=order.bill_company,
bill_address_line_1=order.bill_address_line_1,
bill_address_line_2=order.bill_address_line_2,
bill_city=order.bill_city,
bill_postal_code=order.bill_postal_code,
external_data=order.external_data,
customer_notes=order.customer_notes,
internal_notes=order.internal_notes,
)
@@ -461,12 +480,15 @@ def confirm_order(
if unresolved_count > 0:
raise OrderHasUnresolvedExceptionsException(order_id, unresolved_count)
# Get inventory unit IDs from request or order
# Get inventory unit IDs from request or order items
if confirm_request and confirm_request.inventory_unit_ids:
inventory_unit_ids = confirm_request.inventory_unit_ids
elif order.inventory_units:
inventory_unit_ids = [u["id"] for u in order.inventory_units]
else:
# Get inventory unit IDs from order items' external_item_id
inventory_unit_ids = [
item.external_item_id for item in order.items if item.external_item_id
]
if not inventory_unit_ids:
raise ValidationException("No inventory units to confirm")
try:
@@ -516,12 +538,15 @@ def reject_order(
except OrderNotFoundError:
raise ResourceNotFoundException("LetzshopOrder", str(order_id))
# Get inventory unit IDs from request or order
# Get inventory unit IDs from request or order items
if reject_request and reject_request.inventory_unit_ids:
inventory_unit_ids = reject_request.inventory_unit_ids
elif order.inventory_units:
inventory_unit_ids = [u["id"] for u in order.inventory_units]
else:
# Get inventory unit IDs from order items' external_item_id
inventory_unit_ids = [
item.external_item_id for item in order.items if item.external_item_id
]
if not inventory_unit_ids:
raise ValidationException("No inventory units to reject")
try:
@@ -568,13 +593,13 @@ def set_order_tracking(
except OrderNotFoundError:
raise ResourceNotFoundException("LetzshopOrder", str(order_id))
if not order.letzshop_shipment_id:
if not order.external_shipment_id:
raise ValidationException("Order does not have a shipment ID")
try:
with creds_service.create_client(vendor_id) as client:
result = client.set_shipment_tracking(
shipment_id=order.letzshop_shipment_id,
shipment_id=order.external_shipment_id,
tracking_code=tracking_request.tracking_number,
tracking_provider=tracking_request.tracking_carrier,
)