diff --git a/modules/connectors/eshipper/karrio/providers/eshipper/rate.py b/modules/connectors/eshipper/karrio/providers/eshipper/rate.py index f1d0b4d4ca..0ca1809336 100644 --- a/modules/connectors/eshipper/karrio/providers/eshipper/rate.py +++ b/modules/connectors/eshipper/karrio/providers/eshipper/rate.py @@ -93,10 +93,15 @@ def rate_request( payload.options, package_options=packages.options, ) - shipping_date = lib.to_date(options.shipment_date.state or datetime.datetime.now()) request = eshipper.RateRequestType( - scheduledShipDate=lib.fdatetime(shipping_date, output_format="%Y-%m-%d %H:%M"), + scheduledShipDate=lib.fdatetime( + lib.to_next_business_datetime( + options.shipping_date.state or datetime.datetime.now(), + current_format="%Y-%m-%dT%H:%M", + ), + output_format="%Y-%m-%dT%H:%M:%S.%fZ", # 2024-09-30T09:10:29.195Z + ), raterequestfrom=eshipper.FromType( attention=shipper.contact, company=shipper.company_name, diff --git a/modules/connectors/eshipper/tests/eshipper/test_rate.py b/modules/connectors/eshipper/tests/eshipper/test_rate.py index 6deedea36c..b0dd92c2d0 100644 --- a/modules/connectors/eshipper/tests/eshipper/test_rate.py +++ b/modules/connectors/eshipper/tests/eshipper/test_rate.py @@ -79,7 +79,7 @@ def test_parse_rate_response(self): }, ], "options": { - "shipment_date": "2024-07-16", + "shipping_date": "2024-07-16T10:00", }, } @@ -326,7 +326,7 @@ def test_parse_rate_response(self): "zip": "L4T3T1", "country": "CA", }, - "scheduledShipDate": "2024-07-16 00:00", + "scheduledShipDate": "2024-07-16T10:00:00.000000Z", "packagingUnit": "Metric", "packages": { "type": "Package", diff --git a/modules/core/karrio/server/core/validators.py b/modules/core/karrio/server/core/validators.py index 923112c292..d05703d653 100644 --- a/modules/core/karrio/server/core/validators.py +++ b/modules/core/karrio/server/core/validators.py @@ -111,29 +111,25 @@ def __init__(self, instance=None, **kwargs): if data: options = (data or {}).get("options") or {} - # TODO: remove this when we have a standard shipping date field - shipment_date = lib.to_date( - options.get("shipment_date") - or (getattr(instance, "options", None) or {}).get("shipment_date") - ) shipping_date = lib.to_date( options.get("shipping_date") or (getattr(instance, "options", None) or {}).get("shipping_date"), current_format="%Y-%m-%dT%H:%M", ) - # TODO: remove this when we have a standard shipping date field - if ( - shipment_date is not None - and shipment_date.date() < datetime.now().date() - ): - options.update(shipment_date=datetime.now().strftime("%Y-%m-%d")) - kwargs["data"].update(dict(options=options)) - if shipping_date is None or shipping_date.date() < datetime.now().date(): options.update(shipping_date=datetime.now().strftime("%Y-%m-%dT%H:%M")) kwargs["data"].update(dict(options=options)) + if shipping_date or options.get("shipping_date"): + options.update( + shipment_date=lib.fdate( + shipping_date or options.get("shipping_date"), + current_format="%Y-%m-%dT%H:%M", + ) + ) + kwargs["data"].update(dict(options=options)) + super().__init__(instance, **kwargs) diff --git a/modules/manager/karrio/server/manager/tests/test_shipments.py b/modules/manager/karrio/server/manager/tests/test_shipments.py index c41fe190de..5de95b1a64 100644 --- a/modules/manager/karrio/server/manager/tests/test_shipments.py +++ b/modules/manager/karrio/server/manager/tests/test_shipments.py @@ -361,7 +361,7 @@ def test_cancel_purchased_shipment(self): "return_address": None, "billing_address": None, "services": [], - "options": {"shipping_date": ANY}, + "options": {"shipping_date": ANY, "shipment_date": ANY}, "customs": None, "reference": None, "carrier_ids": ["canadapost"], @@ -375,6 +375,7 @@ def test_cancel_purchased_shipment(self): "options": { "insurance": 54, "currency": "CAD", + "shipment_date": "2050-01-01", "shipping_date": "2050-01-01T10:30", }, } @@ -513,7 +514,7 @@ def test_cancel_purchased_shipment(self): } ], "services": [], - "options": {"shipping_date": ANY}, + "options": {"shipping_date": ANY, "shipment_date": ANY}, "payment": {"paid_by": "sender", "currency": "CAD", "account_number": None}, "return_address": None, "billing_address": None, diff --git a/modules/orders/karrio/server/orders/tests/test_orders.py b/modules/orders/karrio/server/orders/tests/test_orders.py index 0fa58c5d02..06807d0ddd 100644 --- a/modules/orders/karrio/server/orders/tests/test_orders.py +++ b/modules/orders/karrio/server/orders/tests/test_orders.py @@ -519,7 +519,7 @@ def test_fulfilled_order_when_all_items_are_fulfilled(self): } ], "services": [], - "options": {"currency": "CAD", "shipment_date": ANY}, + "options": {"currency": "CAD", "shipment_date": ANY, "shipping_date": ANY}, "payment": {"paid_by": "sender", "currency": "CAD", "account_number": None}, "billing_address": None, "customs": None, @@ -748,7 +748,7 @@ def test_fulfilled_order_when_all_items_are_fulfilled(self): } ], "services": [], - "options": {"currency": "CAD", "shipment_date": ANY}, + "options": {"currency": "CAD", "shipment_date": ANY, "shipping_date": ANY}, "payment": {"paid_by": "sender", "currency": "CAD", "account_number": None}, "billing_address": None, "customs": None, @@ -962,7 +962,7 @@ def test_fulfilled_order_when_all_items_are_fulfilled(self): } ], "services": [], - "options": {"currency": "CAD", "shipment_date": ANY}, + "options": {"currency": "CAD", "shipment_date": ANY, "shipping_date": ANY}, "payment": {"paid_by": "sender", "currency": "CAD", "account_number": None}, "billing_address": None, "customs": None, diff --git a/modules/sdk/karrio/core/units.py b/modules/sdk/karrio/core/units.py index 35550ae17a..6d3760e90b 100644 --- a/modules/sdk/karrio/core/units.py +++ b/modules/sdk/karrio/core/units.py @@ -1,5 +1,6 @@ """Karrio universal data types and units definitions""" +from ctypes import util import attr import typing import numbers @@ -1057,6 +1058,7 @@ def __init__( _key = key option_values[key] = _val + self._raw_options = options self._options = option_values self._option_list = self._filter( option_values, (items_filter or utils.identity) @@ -1169,6 +1171,16 @@ def email_notification_to(self) -> utils.OptionEnum: @property def shipment_date(self) -> utils.OptionEnum: + # Check if shipment_date is not defined and fallback to shipping_date + if not self[ShippingOption.shipment_date.name].state: + return utils.OptionEnum( + "shipment_date", + str, + utils.DF.fdate( + self._raw_options.get("shipping_date"), "%Y-%m-%dT%H:%M" + ), + ) + return self[ShippingOption.shipment_date.name] @property