def _create_line_item_from_draft( self, draft: types.CartDraft, line_item_draft: types.LineItemDraft) -> types.LineItem: line_id = str(uuid.uuid4()) price = 1000 return types.LineItem( id=line_id, name=types.LocalizedString({"en": line_id}), price=types.Price(value=types.Money(currency_code=draft.currency, cent_amount=price)), taxed_price=types.TaxedItemPrice( total_net=types.TypedMoney( type=types.MoneyType.CENT_PRECISION, currency_code=draft.currency, cent_amount=price * (line_item_draft.quantity or 0), fraction_digits=2, ), total_gross=types.TypedMoney( type=types.MoneyType.CENT_PRECISION, currency_code=draft.currency, cent_amount=price * (line_item_draft.quantity or 0), fraction_digits=2, ), ), total_price=types.Money( currency_code=draft.currency, cent_amount=price * (line_item_draft.quantity or 0), ), quantity=line_item_draft.quantity, price_mode=types.LineItemPriceMode.PLATFORM, line_item_mode=types.LineItemMode.STANDARD, custom=utils.create_from_draft(line_item_draft.custom), )
def test_payments_get_by_id(client): custom_type = client.types.create( types.TypeDraft( name=types.LocalizedString(en="myType"), key="payment-info", resource_type_ids=[types.ResourceTypeId.PAYMENT_INTERFACE_INTERACTION], field_definitions=[ types.FieldDefinition( type=types.CustomFieldStringType(), name="operations", label=types.LocalizedString(en="Operation"), required=False, ) ], ) ) payment = client.payments.create( types.PaymentDraft( key="test-payment", amount_planned=types.Money(cent_amount=2000, currency_code="GBP"), payment_method_info=types.PaymentMethodInfo( payment_interface="ADYEN", method="mc" ), transactions=[ types.TransactionDraft( type=types.TransactionType.CHARGE, amount=types.Money(cent_amount=2000, currency_code="GBP"), interaction_id="8525483242578266", state=types.TransactionState.SUCCESS, ) ], interface_interactions=[ types.CustomFieldsDraft( type=types.TypeResourceIdentifier(id=custom_type.id), fields=types.FieldContainer( { "operations": "CANCEL,CAPTURE,REFUND", "success": True, "psp_reference": "8525483242578266", "merchant_reference": "some reference", "reason": "82132:0005:10/2020", "amount": 2000, "payment_method": "mc", "event_date": "2019-01-24T11:04:17.000000Z", "currency_code": "GBP", "event_code": "AUTHORISATION", "merchant_account_code": "TestMerchant", } ), ) ], ) ) assert payment.id assert payment.key == "test-payment"
def test_multiple_expand(client, commercetools_api): shipping_method = client.shipping_methods.create( types.ShippingMethodDraft( key="test-shipping-method", name="test shipping method", tax_category=types.TaxCategoryResourceIdentifier(id="dummy"), zone_rates=[], is_default=False, )) payment = client.payments.create( types.PaymentDraft( key="test-payment", amount_planned=types.Money(cent_amount=2000, currency_code="GBP"), payment_method_info=types.PaymentMethodInfo( payment_interface="ADYEN", method="mc"), transactions=[ types.TransactionDraft( type=types.TransactionType.CHARGE, amount=types.Money(cent_amount=2000, currency_code="GBP"), state=types.TransactionState.PENDING, ) ], )) order = get_test_order() order.shipping_info.shipping_method.id = shipping_method.id order.payment_info.payments[0].id = payment.id commercetools_api.orders.add_existing(order) expanded_order = client.orders.get_by_id( order.id, expand=["shippingInfo.shippingMethod", "paymentInfo.payments[*]"]) assert expanded_order.id assert expanded_order.shipping_info.shipping_method.obj.id == shipping_method.id assert expanded_order.payment_info.payments[0].obj.id == payment.id expanded_order = client.orders.get_by_id( order.id, expand=["shippingInfo.shippingMethod"]) assert expanded_order.id assert expanded_order.shipping_info.shipping_method.obj.id == shipping_method.id assert expanded_order.payment_info.payments[0].obj is None query_results = client.orders.query( expand=["shippingInfo.shippingMethod", "paymentInfo.payments[*]"]) expanded_order = query_results.results[0] assert expanded_order.id assert expanded_order.shipping_info.shipping_method.obj.id == shipping_method.id assert expanded_order.payment_info.payments[0].obj.id == payment.id
def test_update_actions(client): payment = client.payments.create( types.PaymentDraft( key="test-payment", amount_planned=types.Money(cent_amount=2000, currency_code="GBP"), payment_method_info=types.PaymentMethodInfo( payment_interface="ADYEN", method="mc" ), transactions=[ types.TransactionDraft( type=types.TransactionType.CHARGE, amount=types.Money(cent_amount=2000, currency_code="GBP"), state=types.TransactionState.PENDING, ) ], ) ) existing_transaction = payment.transactions[0] payment = client.payments.update_by_id( payment.id, payment.version, actions=[ types.PaymentAddInterfaceInteractionAction( fields=types.FieldContainer({"pspRef": "1337"}) ), types.PaymentChangeTransactionInteractionIdAction( transaction_id=existing_transaction.id, interaction_id="1337" ), types.PaymentAddTransactionAction( transaction=types.TransactionDraft( type=types.TransactionType.CHARGE, amount=types.Money(currency_code="GBP", cent_amount=1000), interaction_id="123", state=types.TransactionState.INITIAL, ) ), types.PaymentChangeTransactionStateAction( transaction_id=existing_transaction.id, state=types.TransactionState.SUCCESS, ), ], ) assert payment.interface_interactions[0].fields == {"pspRef": "1337"} assert payment.transactions[0].interaction_id == "1337" assert len(payment.transactions) == 2 assert payment.transactions[0].state == types.TransactionState.SUCCESS
def test_product_update_add_change_price_staged(client): product = client.products.create( types.ProductDraft( key="test-product", name=types.LocalizedString(en=f"my-product-1"), slug=types.LocalizedString(en=f"my-product-1"), product_type=types.ProductTypeResourceIdentifier(key="dummy"), master_variant=types.ProductVariantDraft(sku="1", key="1"), ) ) product = client.products.update_by_id( id=product.id, version=product.version, actions=[ types.ProductAddPriceAction( sku="1", price=types.PriceDraft( value=types.Money(cent_amount=1000, currency_code="GBP") ), ) ], ) assert product.master_data.current is None assert len(product.master_data.staged.master_variant.prices) == 1 price = product.master_data.staged.master_variant.prices[0] assert price.value.cent_amount == 1000 assert price.value.currency_code == "GBP" product = client.products.update_by_id( id=product.id, version=product.version, actions=[ types.ProductChangePriceAction( price_id=price.id, price=types.PriceDraft( value=types.Money(cent_amount=3000, currency_code="EUR") ), ) ], ) assert product.master_data.current is None assert len(product.master_data.staged.master_variant.prices) == 1 price = product.master_data.staged.master_variant.prices[0] assert price.value.cent_amount == 3000 assert price.value.currency_code == "EUR"
def test_product_update_add_price_current(client): product = client.products.create( types.ProductDraft( key="test-product", name=types.LocalizedString(en=f"my-product-1"), slug=types.LocalizedString(en=f"my-product-1"), product_type=types.ProductTypeResourceIdentifier(key="dummy"), master_variant=types.ProductVariantDraft(sku="1", key="1"), publish=True, ) ) product = client.products.update_by_id( id=product.id, version=product.version, actions=[ types.ProductAddPriceAction( sku="1", staged=False, price=types.PriceDraft( value=types.Money(cent_amount=1000, currency_code="GBP") ), ) ], ) assert product.master_data.staged is None assert len(product.master_data.current.master_variant.prices) == 1
def test_products_create(client): custom_type = client.types.create( types.TypeDraft(name=types.LocalizedString(en="myType"), resource_type_ids=[types.ResourceTypeId.ASSET], field_definitions=[types.FieldDefinition(name="foo")])) assert custom_type.id draft = types.ProductDraft( key="test-product", publish=True, master_variant=types.ProductVariantDraft( assets=[ types.AssetDraft(custom=types.CustomFieldsDraft( type=types.TypeResourceIdentifier(id=custom_type.id), fields=types.FieldContainer(foo="bar"), )) ], prices=[ types.PriceDraft( value=types.Money(cent_amount=1000, currency_code="EUR"), country="NL", ) ], ), ) product = client.products.create(draft) assert product.id assert product.master_data.current.master_variant.assets assert product.master_data.current.master_variant.prices
def create_from_draft(draft): """Utility method to create normal objects out of draft objects. This is used for non-resource objects. For the resources themselves (which contain) an id, we have the specific implementations of the `BaseModel`. """ if not draft: return None if isinstance(draft, types.CustomFieldsDraft): return types.CustomFields( type=types.TypeReference(type_id=draft.type.type_id, id=draft.type.id), fields=draft.fields, ) if isinstance(draft, types.PriceTierDraft): return types.PriceTier( minimum_quantity=draft.minimum_quantity, value=_money_to_typed( types.Money( cent_amount=draft.value.cent_amount, currency_code=draft.value.currency_code, )), ) raise ValueError(f"Unsupported type {draft.__class__}")
def test_product_update(client): """Test the return value of the update methods. It doesn't test the actual update itself. TODO: See if this is worth testing since we're using a mocking backend """ product = client.products.create( types.ProductDraft( key="test-product", master_variant=types.ProductVariantDraft(sku="1", key="1"), )) assert uuid.UUID(product.id) assert product.key == "test-product" product = client.products.update_by_id( id=product.id, version=product.version, actions=[ types.ProductChangeSlugAction(slug=types.LocalizedString( nl="nl-slug2")) ], ) assert product.key == "test-product" assert product.master_data.published is False product = client.products.update_by_id( id=product.id, version=product.version, actions=[types.ProductPublishAction()]) assert product.master_data.published is True assert not product.master_data.current.master_variant.prices product = client.products.update_by_id( id=product.id, version=product.version, actions=[ types.ProductSetPricesAction( sku="1", prices=[ types.PriceDraft(value=types.Money(cent_amount=1000, currency_code="GBP")) ], staged=False, ) ], ) assert len(product.master_data.current.master_variant.prices) == 1 product = client.products.update_by_key( key="test-product", version=product.version, actions=[ types.ProductChangeSlugAction(slug=types.LocalizedString( nl="nl-slug2")) ], ) assert product.key == "test-product"
def test_product_query_where(client): client.products.create( types.ProductDraft( key="test-product1", master_variant=types.ProductVariantDraft( prices=[ types.PriceDraft( country="NL", value=types.Money(cent_amount=8750, currency_code="EUR"), ) ] ), ) ) client.products.create( types.ProductDraft( key="test-product-2", master_variant=types.ProductVariantDraft( prices=[ types.PriceDraft( country="UK", value=types.Money(cent_amount=8750, currency_code="EUR"), ) ] ), ) ) client.products.create(types.ProductDraft(key="test-product2")) result = client.products.query( where="masterData(staged(masterVariant(prices(country='NL'))))" ) assert len(result.results) == 1 assert result.total == 1 result = client.products.query( where="masterData(staged(masterVariant(prices(country='UK'))))" ) assert len(result.results) == 1 assert result.total == 1 result = client.products.query( where="masterData(staged(masterVariant(prices(country='UK' or country='NL'))))" ) assert len(result.results) == 2 assert result.total == 2
def test_payments_get_by_id(client): payment = client.payments.create( types.PaymentDraft( key="test-payment", amount_planned=types.Money(cent_amount=2000, currency_code="GBP"), payment_method_info=types.PaymentMethodInfo( payment_interface="ADYEN", method="mc" ), transactions=[ types.TransactionDraft( type=types.TransactionType.CHARGE, amount=types.Money(cent_amount=2000, currency_code="GBP"), interaction_id="8525483242578266", state=types.TransactionState.SUCCESS, ) ], interface_interactions=[ types.CustomFieldsDraft( fields=types.FieldContainer( { "operations": "CANCEL,CAPTURE,REFUND", "success": True, "psp_reference": "8525483242578266", "merchant_reference": "some reference", "reason": "82132:0005:10/2020", "amount": 2000, "payment_method": "mc", "event_date": "2019-01-24T11:04:17.000000Z", "currency_code": "GBP", "event_code": "AUTHORISATION", "merchant_account_code": "TestMerchant", } ) ) ], ) ) assert payment.id assert payment.key == "test-payment"
def test_product_update_add_price_current(client): product = client.products.create( types.ProductDraft( key="test-product", master_variant=types.ProductVariantDraft(sku="1", key="1"), publish=True, )) product = client.products.update_by_id( id=product.id, version=product.version, actions=[ types.ProductAddPriceAction( sku="1", staged=False, price=types.PriceDraft( value=types.Money(cent_amount=1000, currency_code="GBP")), ) ], ) assert product.master_data.staged is None assert len(product.master_data.current.master_variant.prices) == 1
def post_load(self, data, **kwargs): return types.Money(**data)
def get_test_order(): order = types.Order( id="20ad6c92-fe04-4983-877e-5f5f80b5e37b", version=10, created_at=datetime.datetime.now(datetime.timezone.utc), last_message_sequence_number=8, order_number="test-number", customer_email="*****@*****.**", anonymous_id="a706a9bf-4cd5-4bd0-b35d-b2373fb0c15e", locale="en", total_price=types.Money(cent_amount=2000, currency_code="GBP"), taxed_price=types.TaxedPrice( total_net=types.Money(cent_amount=1666, currency_code="GBP"), total_gross=types.Money(cent_amount=2000, currency_code="GBP"), tax_portions=[ types.TaxPortion( rate=0.2, amount=types.Money(cent_amount=334, currency_code="GBP"), name="GB", ) ], ), country="GB", order_state=types.OrderState.OPEN, shipment_state=None, payment_state=types.PaymentState.PAID, shipping_info=types.ShippingInfo( shipping_method_name="Shipwire", price=types.TypedMoney( currency_code="GBP", cent_amount=1000, type=types.MoneyType.CENT_PRECISION, fraction_digits=2, ), shipping_rate=types.ShippingRate( price=types.TypedMoney( currency_code="GBP", cent_amount=1000, type=types.MoneyType.CENT_PRECISION, fraction_digits=2, ), free_above=types.TypedMoney( currency_code="GBP", cent_amount=5000, type=types.MoneyType.CENT_PRECISION, fraction_digits=2, ), tiers=[], ), tax_rate=types.TaxRate( name="GB", amount=0.2, included_in_price=False, country="GB", id="8olFiIwX", ), tax_category=types.TaxCategoryReference( type_id=types.ReferenceTypeId.TAX_CATEGORY, id="5e564356-d367-4718-a0bb-6a17c3b1fdeb", ), shipping_method=types.ShippingMethodReference( id="b0e88c41-8553-4904-a2d5-a096c5f6f09f"), taxed_price=types.TaxedItemPrice( total_net=types.TypedMoney( cent_amount=833, currency_code="GBP", type=types.MoneyType.CENT_PRECISION, fraction_digits=2, ), total_gross=types.TypedMoney( cent_amount=1000, currency_code="GBP", type=types.MoneyType.CENT_PRECISION, fraction_digits=2, ), ), shipping_method_state=types.ShippingMethodState.MATCHES_CART, ), tax_mode=types.TaxMode.PLATFORM, tax_rounding_mode=types.RoundingMode.HALF_EVEN, tax_calculation_mode=types.TaxCalculationMode.LINE_ITEM_LEVEL, origin=types.CartOrigin.CUSTOMER, line_items=[ types.LineItem( id="4e7e38f2-45c1-4672-9c41-9c74dbd911bd", product_id="b32d3cfd-6920-4788-a5ee-c0bcfd460c0d", name=types.LocalizedString({"en": "FRUIT MIX STAGE 1"}), product_type=types.ProductTypeReference( id="9faf6335-7618-4f8b-a11d-c0f832b733c1"), product_slug=types.LocalizedString({"en": "fruit-mix-stage-1"}), variant=types.ProductVariant( id=1, sku="982218931672529", prices=[ types.Price( id="fb424988-79b3-4418-8730-9f324025a13c", value=types.Money(cent_amount=1000, currency_code="GBP"), ) ], ), price=types.Price( id="fb424988-79b3-4418-8730-9f324025a13c", value=types.Money(cent_amount=1000, currency_code="GBP"), ), quantity=1, tax_rate=types.TaxRate( name="GB", amount=0.19, included_in_price=False, country="GB", id="7JkeuGwo", ), state=[ types.ItemState( quantity=1, state=types.StateReference( id="0e59473e-1203-4135-8bcb-f1c5141ed5ad"), ) ], price_mode=types.LineItemPriceMode.PLATFORM, total_price=types.Money(cent_amount=1000, currency_code="GBP"), taxed_price=types.TaxedItemPrice( total_net=types.TypedMoney( cent_amount=1190, currency_code="GBP", type=types.MoneyType.CENT_PRECISION, fraction_digits=2, ), total_gross=types.TypedMoney( cent_amount=1190, currency_code="GBP", type=types.MoneyType.CENT_PRECISION, fraction_digits=2, ), ), line_item_mode=types.LineItemMode.STANDARD, ) ], cart=types.CartReference(id="some cart id"), payment_info=types.PaymentInfo(payments=[ types.PaymentReference(id="a433f3f8-5e27-406e-b2b0-d4a1f64592c4") ]), custom=types.CustomFields( fields=types.FieldContainer({ "sentEmails": ["order_email_confirmed"], "shipwireServiceLevelCode": "GD", })), shipping_address=types.Address( first_name="David", last_name="Weterings", street_name="Kanaalweg", street_number="14", postal_code="3526KL", city="Utrecht", country="GB", ), billing_address=types.Address( first_name="David", last_name="Weterings", street_name="Kanaalweg", street_number="14", postal_code="3526KL", city="Utrecht", country="GB", ), ) return order
def test_update_actions(client): custom_type = client.types.create( types.TypeDraft( name=types.LocalizedString(en="myType"), key="payment-info", resource_type_ids=[types.ResourceTypeId.PAYMENT_INTERFACE_INTERACTION], field_definitions=[ types.FieldDefinition( type=types.CustomFieldStringType(), name="operations", label=types.LocalizedString(en="Operation"), required=False, ) ], ) ) payment = client.payments.create( types.PaymentDraft( key="test-payment", amount_planned=types.Money(cent_amount=2000, currency_code="GBP"), payment_method_info=types.PaymentMethodInfo( payment_interface="ADYEN", method="mc" ), transactions=[ types.TransactionDraft( type=types.TransactionType.CHARGE, amount=types.Money(cent_amount=2000, currency_code="GBP"), state=types.TransactionState.PENDING, ) ], ) ) existing_transaction = payment.transactions[0] payment = client.payments.update_by_id( payment.id, payment.version, actions=[ types.PaymentAddInterfaceInteractionAction( type=types.TypeResourceIdentifier(id=custom_type.id), fields=types.FieldContainer({"pspRef": "1337"}), ), types.PaymentChangeTransactionInteractionIdAction( transaction_id=existing_transaction.id, interaction_id="1337" ), types.PaymentAddTransactionAction( transaction=types.TransactionDraft( type=types.TransactionType.CHARGE, amount=types.Money(currency_code="GBP", cent_amount=1000), interaction_id="123", state=types.TransactionState.INITIAL, ) ), types.PaymentChangeTransactionStateAction( transaction_id=existing_transaction.id, state=types.TransactionState.SUCCESS, ), ], ) assert payment.interface_interactions[0].fields == {"pspRef": "1337"} assert payment.transactions[0].interaction_id == "1337" assert len(payment.transactions) == 2 assert payment.transactions[0].state == types.TransactionState.SUCCESS
def _create_from_draft(self, draft: types.CartDraft, id: typing.Optional[str] = None) -> types.Cart: object_id = str(uuid.UUID(id) if id is not None else uuid.uuid4()) line_items = [ self._create_line_item_from_draft(draft, line_item) for line_item in draft.line_items ] total_price = None taxed_price = None if line_items: total_price = types.TypedMoney( type=types.MoneyType.CENT_PRECISION, currency_code=draft.currency, cent_amount=sum(line_item.taxed_price.total_gross.cent_amount for line_item in line_items if line_item.taxed_price and line_item.taxed_price.total_gross), fraction_digits=2, ) taxed_price = types.TaxedPrice( total_net=types.Money( currency_code=draft.currency, cent_amount=sum(line_item.taxed_price.total_net.cent_amount for line_item in line_items if line_item.taxed_price and line_item.taxed_price.total_net), ), total_gross=types.Money( currency_code=draft.currency, cent_amount=sum( line_item.taxed_price.total_gross.cent_amount for line_item in line_items if line_item.taxed_price and line_item.taxed_price.total_gross), ), tax_portions=[ types.TaxPortion( name="0% VAT", amount=types.Money(currency_code=draft.currency, cent_amount=0), ) ], ) # Some fields such as itemShippingAddresses are currently missing. See # https://docs.commercetools.com/http-api-projects-carts for a complete overview return types.Cart( id=str(object_id), version=1, cart_state=types.CartState.ACTIVE, customer_id=draft.customer_id, customer_email=draft.customer_email, customer_group=draft.customer_group, anonymous_id=draft.anonymous_id, country=draft.country, inventory_mode=draft.inventory_mode, tax_mode=draft.tax_mode, tax_rounding_mode=draft.tax_rounding_mode, tax_calculation_mode=draft.tax_calculation_mode, line_items=line_items, shipping_address=draft.shipping_address, billing_address=draft.billing_address, locale=draft.locale, origin=draft.origin, created_at=datetime.datetime.now(datetime.timezone.utc), last_modified_at=datetime.datetime.now(datetime.timezone.utc), custom=utils.create_from_draft(draft.custom), total_price=total_price, taxed_price=taxed_price, )
def post_load(self, data): return types.Money(**data)