Skip to content

Commit 361822e

Browse files
tleguijtmvantellingen
authored andcommitted
Add support for Order imports
1 parent eba35b8 commit 361822e

File tree

7 files changed

+93
-25
lines changed

7 files changed

+93
-25
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
The old pattern is deprecated but will remain backwards compatible for now
2929
- Allow passing custom HTTP adapter to BaseClient (@lime-green)
3030
- Add support for custom address fields and update actions
31+
- Testing: Add support for `Order` imports
3132
- Testing: fixed issues with `get_by_key` lookups in certain testing backends
3233
- Testing: Added missing actions for Cart Discounts, Discount Codes and Extensions
3334
- Testing: Add `datetime` and `list` updater utils

src/commercetools/testing/abstract.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def _generate_key(self, obj):
9090
def _create_from_draft(self, draft, id=None):
9191
raise NotImplementedError()
9292

93-
def query(self, where):
93+
def query(self, where=None):
9494
objects = list(self.objects.values())
9595
if not where:
9696
return objects

src/commercetools/testing/orders.py

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@
99
from commercetools.platform.models._schemas.order import (
1010
DeliverySchema,
1111
OrderFromCartDraftSchema,
12+
OrderImportDraftSchema,
1213
OrderPagedQueryResponseSchema,
1314
OrderSchema,
1415
OrderUpdateSchema,
1516
)
1617
from commercetools.platform.models._schemas.payment import PaymentReferenceSchema
18+
from commercetools.platform.models.common import CentPrecisionMoney
1719
from commercetools.testing.abstract import BaseModel, ServiceBackend
1820
from commercetools.testing.utils import (
21+
create_commercetools_response,
22+
create_from_draft,
23+
money_to_typed,
1924
set_custom_field,
2025
set_line_item_custom_field,
2126
update_attribute,
@@ -28,30 +33,65 @@ class OrdersModel(BaseModel):
2833
_resource_schema = OrderSchema
2934

3035
def _create_from_draft(
31-
self, draft: models.OrderFromCartDraft, id: typing.Optional[str] = None
36+
self,
37+
draft: typing.Union[models.OrderFromCartDraft, models.OrderImportDraft],
38+
id: typing.Optional[str] = None,
3239
) -> models.Order:
3340
"""
3441
Note this implementation needs further refinement. For example:
3542
- Copying fields from an existing cart
3643
- Setting custom type fields?
3744
"""
45+
id = str(id if id is not None else uuid.uuid4())
3846

39-
object_id = str(uuid.UUID(id) if id is not None else uuid.uuid4())
47+
if isinstance(draft, models.OrderFromCartDraft):
48+
return self._create_from_cart_draft(draft, id)
49+
elif isinstance(draft, models.OrderImportDraft):
50+
return self._create_from_import_draft(draft, id)
51+
52+
def _create_from_cart_draft(self, draft: models.OrderFromCartDraft, id: str):
53+
"""
54+
Note this implementation needs further refinement. For example:
55+
- Copying fields from an existing cart
56+
- Setting custom type fields?
57+
"""
4058
cart_identifier = models.CartResourceIdentifier(id=draft.id)
4159

4260
cart_data = self._storage.get_by_resource_identifier(cart_identifier)
4361
cart = None
62+
total_price = None
4463
if cart_data:
4564
cart: models.Cart = CartSchema().load(cart_data)
65+
total_price = copy.deepcopy(cart.total_price)
66+
67+
order = models.Order(
68+
id=id,
69+
version=1,
70+
created_at=datetime.datetime.now(datetime.timezone.utc),
71+
last_modified_at=datetime.datetime.now(datetime.timezone.utc),
72+
line_items=[],
73+
custom_line_items=[],
74+
total_price=total_price,
75+
sync_info=[],
76+
last_message_sequence_number=0,
77+
refused_gifts=[],
78+
order_number=draft.order_number,
79+
payment_state=draft.payment_state,
80+
order_state=OrderState.OPEN,
81+
origin=CartOrigin.CUSTOMER,
82+
)
83+
return order
4684

85+
def _create_from_import_draft(self, draft: models.OrderImportDraft, id: str):
4786
order = models.Order(
48-
id=str(object_id),
87+
id=id,
4988
version=1,
5089
created_at=datetime.datetime.now(datetime.timezone.utc),
5190
last_modified_at=datetime.datetime.now(datetime.timezone.utc),
5291
line_items=[],
5392
custom_line_items=[],
54-
total_price=copy.deepcopy(cart.total_price),
93+
total_price=money_to_typed(draft.total_price),
94+
taxed_price=create_from_draft(draft.taxed_price),
5595
sync_info=[],
5696
last_message_sequence_number=0,
5797
refused_gifts=[],
@@ -138,6 +178,7 @@ def urls(self):
138178
return [
139179
("^$", "GET", self.query),
140180
("^$", "POST", self.create),
181+
("^import$", "POST", self.import_),
141182
("^key=(?P<key>[^/]+)$", "GET", self.get_by_key),
142183
("^key=(?P<key>[^/]+)$", "POST", self.update_by_key),
143184
("^key=(?P<key>[^/]+)$", "DELETE", self.delete_by_key),
@@ -146,6 +187,14 @@ def urls(self):
146187
("^(?P<id>[^/]+)$", "DELETE", self.delete_by_id),
147188
]
148189

190+
def import_(self, request):
191+
obj = OrderImportDraftSchema().loads(request.body)
192+
data = self.model.add(obj)
193+
expanded_data = self._expand(request, data)
194+
return create_commercetools_response(
195+
request, json=expanded_data, status_code=201
196+
)
197+
149198
_actions = {
150199
"changeOrderState": update_enum_attribute("orderState", "order_state"),
151200
"changePaymentState": update_enum_attribute("paymentState", "payment_state"),

src/commercetools/testing/payments.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ def _create_from_draft(
3333
last_modified_at=datetime.datetime.now(datetime.timezone.utc),
3434
customer=draft.customer,
3535
amount_authorized=draft.amount_authorized,
36-
amount_paid=utils._money_to_typed(draft.amount_paid),
37-
amount_planned=utils._money_to_typed(draft.amount_planned),
38-
amount_refunded=utils._money_to_typed(draft.amount_refunded),
36+
amount_paid=utils.money_to_typed(draft.amount_paid),
37+
amount_planned=utils.money_to_typed(draft.amount_planned),
38+
amount_refunded=utils.money_to_typed(draft.amount_refunded),
3939
anonymous_id=draft.anonymous_id,
4040
payment_method_info=draft.payment_method_info,
4141
payment_status=draft.payment_status,
@@ -55,7 +55,7 @@ def _create_transaction_draft(
5555
id=str(uuid.uuid4()),
5656
timestamp=draft.timestamp,
5757
type=draft.type,
58-
amount=utils._money_to_typed(draft.amount),
58+
amount=utils.money_to_typed(draft.amount),
5959
interaction_id=draft.interaction_id,
6060
state=draft.state,
6161
)
@@ -68,7 +68,7 @@ def updater(self, obj, action):
6868
id=str(uuid.uuid4()),
6969
timestamp=draft.timestamp,
7070
type=draft.type,
71-
amount=utils._money_to_typed(draft.amount),
71+
amount=utils.money_to_typed(draft.amount),
7272
interaction_id=draft.interaction_id,
7373
state=draft.state,
7474
)

src/commercetools/testing/products.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ def convert_draft_price(
293293
id=price_id or str(uuid.uuid4()),
294294
country=price_draft.country,
295295
channel=price_draft.channel,
296-
value=utils._money_to_typed(price_draft.value),
296+
value=utils.money_to_typed(price_draft.value),
297297
valid_from=price_draft.valid_from,
298298
valid_until=price_draft.valid_until,
299299
discounted=price_draft.discounted,

src/commercetools/testing/shipping_methods.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ def _create_from_draft(
3636
shipping_rates: typing.List[models.ShippingRate] = []
3737
for shipping_rate_draft in rate_draft.shipping_rates or []:
3838
shipping_rate = models.ShippingRate(
39-
price=utils._money_to_typed(shipping_rate_draft.price),
40-
free_above=utils._money_to_typed(shipping_rate_draft.free_above),
39+
price=utils.money_to_typed(shipping_rate_draft.price),
40+
free_above=utils.money_to_typed(shipping_rate_draft.free_above),
4141
tiers=copy.deepcopy(shipping_rate_draft.tiers),
4242
)
4343
shipping_rates.append(shipping_rate)

src/commercetools/testing/utils.py

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
)
1818
from commercetools.platform.models._abstract import _BaseType
1919
from commercetools.platform.models._schemas.product import ProductSchema
20-
from commercetools.platform.models.cart import Cart, CartSetLineItemCustomFieldAction
20+
from commercetools.platform.models.cart import (
21+
Cart,
22+
CartSetLineItemCustomFieldAction,
23+
TaxPortion,
24+
)
2125
from commercetools.platform.models.order import Order, OrderSetLineItemCustomFieldAction
2226

2327

@@ -49,7 +53,7 @@ def get_product_variants(product_catalog_data: dict) -> typing.List[dict]:
4953
return variants
5054

5155

52-
def create_from_draft(draft):
56+
def create_from_draft(draft: typing.Optional[_BaseType]):
5357
"""Utility method to create normal objects out of draft objects.
5458
5559
This is used for non-resource objects. For the resources themselves (which contain)
@@ -65,13 +69,26 @@ def create_from_draft(draft):
6569
if isinstance(draft, models.PriceTierDraft):
6670
return models.PriceTier(
6771
minimum_quantity=draft.minimum_quantity,
68-
value=_money_to_typed(
72+
value=money_to_typed(
6973
models.Money(
7074
cent_amount=draft.value.cent_amount,
7175
currency_code=draft.value.currency_code,
7276
)
7377
),
7478
)
79+
if isinstance(draft, models.TaxedPriceDraft):
80+
return models.TaxedPrice(
81+
total_net=money_to_typed(draft.total_net),
82+
total_gross=money_to_typed(draft.total_gross),
83+
tax_portions=[
84+
models.TaxPortion(
85+
name=portion.name,
86+
rate=portion.rate,
87+
amount=money_to_typed(portion.amount),
88+
)
89+
for portion in draft.tax_portions
90+
],
91+
)
7592

7693
raise ValueError(f"Unsupported type {draft.__class__}")
7794

@@ -87,17 +104,18 @@ def custom_fields_from_draft(
87104
)
88105

89106

90-
def _money_to_typed(
107+
def money_to_typed(
91108
money: typing.Optional[models.Money],
92109
) -> typing.Optional[models.TypedMoney]:
93-
if money is not None:
94-
return models.TypedMoney(
95-
cent_amount=money.cent_amount,
96-
currency_code=money.currency_code,
97-
type=models.MoneyType.CENT_PRECISION,
98-
fraction_digits=2,
99-
)
100-
return None
110+
if money is None:
111+
return None
112+
113+
return models.TypedMoney(
114+
cent_amount=money.cent_amount,
115+
currency_code=money.currency_code,
116+
type=models.MoneyType.CENT_PRECISION,
117+
fraction_digits=2,
118+
)
101119

102120

103121
def update_attribute(dst: str, src: str):

0 commit comments

Comments
 (0)