diff --git a/app/api/v1/vendor/letzshop.py b/app/api/v1/vendor/letzshop.py index 63d7fa19..ab1e9d3a 100644 --- a/app/api/v1/vendor/letzshop.py +++ b/app/api/v1/vendor/letzshop.py @@ -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, ) diff --git a/app/exceptions/message.py b/app/exceptions/message.py index a13e5099..b1353bf6 100644 --- a/app/exceptions/message.py +++ b/app/exceptions/message.py @@ -3,7 +3,7 @@ Messaging specific exceptions. """ -from .base import BusinessLogicException, ResourceNotFoundException, ValidationException +from .base import BusinessLogicException, ResourceNotFoundException class ConversationNotFoundException(ResourceNotFoundException): @@ -41,7 +41,7 @@ class ConversationClosedException(BusinessLogicException): ) -class MessageAttachmentException(ValidationException): +class MessageAttachmentException(BusinessLogicException): """Raised when attachment validation fails.""" def __init__(self, message: str, details: dict | None = None): @@ -63,7 +63,7 @@ class UnauthorizedConversationAccessException(BusinessLogicException): ) -class InvalidConversationTypeException(ValidationException): +class InvalidConversationTypeException(BusinessLogicException): """Raised when conversation type is not valid for the operation.""" def __init__(self, message: str, allowed_types: list[str] | None = None): @@ -74,7 +74,7 @@ class InvalidConversationTypeException(ValidationException): ) -class InvalidRecipientTypeException(ValidationException): +class InvalidRecipientTypeException(BusinessLogicException): """Raised when recipient type doesn't match conversation type.""" def __init__(self, conversation_type: str, expected_recipient_type: str): diff --git a/tests/integration/api/v1/admin/test_letzshop.py b/tests/integration/api/v1/admin/test_letzshop.py index 051ea560..a80d1e73 100644 --- a/tests/integration/api/v1/admin/test_letzshop.py +++ b/tests/integration/api/v1/admin/test_letzshop.py @@ -246,6 +246,8 @@ class TestAdminLetzshopOrdersAPI: def test_list_vendor_orders_with_data(self, client, db, admin_headers, test_vendor): """Test listing vendor orders with data.""" + from datetime import datetime, timezone + from models.database.order import Order # Create test order using unified Order model with all required fields @@ -256,6 +258,7 @@ class TestAdminLetzshopOrdersAPI: channel="letzshop", external_order_id="admin_order_1", status="pending", + order_date=datetime.now(timezone.utc), customer_first_name="Admin", customer_last_name="Test", customer_email="admin-test@example.com", diff --git a/tests/integration/api/v1/vendor/test_letzshop.py b/tests/integration/api/v1/vendor/test_letzshop.py index 08436e66..3eb6cf25 100644 --- a/tests/integration/api/v1/vendor/test_letzshop.py +++ b/tests/integration/api/v1/vendor/test_letzshop.py @@ -238,6 +238,8 @@ class TestVendorLetzshopOrdersAPI: self, client, db, vendor_user_headers, test_vendor_with_vendor_user ): """Test listing orders with status filter.""" + from datetime import datetime, timezone + from models.database.order import Order # Create test orders using unified Order model with all required fields @@ -248,6 +250,7 @@ class TestVendorLetzshopOrdersAPI: channel="letzshop", external_order_id="order_1", status="pending", + order_date=datetime.now(timezone.utc), customer_first_name="Test", customer_last_name="User", customer_email="test1@example.com", @@ -273,6 +276,7 @@ class TestVendorLetzshopOrdersAPI: channel="letzshop", external_order_id="order_2", status="processing", + order_date=datetime.now(timezone.utc), customer_first_name="Test", customer_last_name="User", customer_email="test2@example.com", @@ -309,6 +313,8 @@ class TestVendorLetzshopOrdersAPI: self, client, db, vendor_user_headers, test_vendor_with_vendor_user ): """Test getting order detail.""" + from datetime import datetime, timezone + from models.database.order import Order order = Order( @@ -319,6 +325,7 @@ class TestVendorLetzshopOrdersAPI: external_order_id="order_detail_test", external_shipment_id="shipment_1", status="pending", + order_date=datetime.now(timezone.utc), customer_first_name="Test", customer_last_name="User", customer_email="test@example.com", @@ -448,6 +455,8 @@ class TestVendorLetzshopFulfillmentAPI: test_vendor_with_vendor_user, ): """Test confirming an order.""" + from datetime import datetime, timezone + from models.database.order import Order, OrderItem # Create test order using unified Order model with all required fields @@ -459,6 +468,7 @@ class TestVendorLetzshopFulfillmentAPI: external_order_id="order_confirm", external_shipment_id="shipment_1", status="pending", + order_date=datetime.now(timezone.utc), customer_first_name="Test", customer_last_name="User", customer_email="test@example.com", @@ -534,6 +544,8 @@ class TestVendorLetzshopFulfillmentAPI: test_vendor_with_vendor_user, ): """Test setting tracking information.""" + from datetime import datetime, timezone + from models.database.order import Order order = Order( @@ -544,6 +556,7 @@ class TestVendorLetzshopFulfillmentAPI: external_order_id="order_tracking", external_shipment_id="shipment_track", status="processing", # confirmed state + order_date=datetime.now(timezone.utc), customer_first_name="Test", customer_last_name="User", customer_email="test@example.com",