The order
module
-
class magento.models.order.Order(data, client)View on GitHub
View Source Code
class Order(Model): """Wrapper for the ``orders`` endpoint""" DOCUMENTATION = 'https://adobe-commerce.redoc.ly/2.3.7-admin/tag/orders' IDENTIFIER = 'entity_id' def __init__(self, data: dict, client: Client): """Initialize an Order object using an API response from the ``orders`` endpoint :param data: API response from the ``orders`` endpoint :param client: an initialized :class:`~.Client` object """ super().__init__( data=data, client=client, endpoint='orders', private_keys=True ) def __repr__(self): return f'<Magento Order: #{self.number} placed on {self.created_at}>' @property def excluded_keys(self) -> List[str]: return ['items', 'payment'] @property def id(self) -> int: """Alias for ``entity_id``""" return getattr(self, 'entity_id', None) @property def number(self) -> str: """Alias for ``increment_id``""" return getattr(self, 'increment_id', None) @cached_property def items(self) -> List[OrderItem]: """The ordered items, returned as a list of :class:`OrderItem` objects .. note:: When a configurable :class:`~.Product` is ordered, the API returns data for both the configurable and simple product * The :class:`OrderItem` is initialized using the configurable product data, since the simple product data is incomplete * The :attr:`~.OrderItem.product` and :attr:`~.OrderItem.product_id` will still match the simple product though If both entries are needed, the unparsed response is in the :attr:`~.data` dict """ return [OrderItem(item, order=self) for item in self.__items if item.get('parent_item') is None] @cached_property def item_ids(self) -> List[int]: """The ``item_id`` s of the ordered :attr:`~.items`""" return [item.item_id for item in self.items] @cached_property def products(self) -> List[Product]: """The ordered :attr:`~items`, returned as their corresponding :class:`~.Product` objects""" return [item.product for item in self.items] def get_invoice(self) -> Invoice: """Retrieve the :class:`~.Invoice` of the Order""" return self.client.invoices.by_order(self) @property def customer(self) -> Customer: return self.client.customers.by_order(self) @property def shipping_address(self) -> dict: """Shipping details, from ``extension_attributes.shipping_assignments``""" return self.extension_attributes.get( 'shipping_assignments', [{}])[0].get( 'shipping', {}).get( 'address', {}) @property def bill_to(self) -> dict: """Condensed version of the ``billing_address`` dict""" if hasattr(self, 'billing_address'): return { 'firstname': self.billing_address.get('firstname', ''), 'lastname': self.billing_address.get('lastname', ''), 'email': self.billing_address.get('email', ''), 'address': self.bill_to_address } @property def bill_to_address(self) -> str: """The billing address, parsed into a single string""" return self._build_address('billing') @property def ship_to(self) -> dict: """Condensed version of the :attr:`~.shipping_address` dict""" return { 'firstname': self.shipping_address.get('firstname', ''), 'lastname': self.shipping_address.get('lastname', ''), 'email': self.shipping_address.get('email', ''), 'address': self.ship_to_address } @property def ship_to_address(self) -> str: """The shipping address, parsed into a single string""" return self._build_address('shipping') def _build_address(self, address_type: str) -> str: """Parses an address dict into a single string :param address_type: the address to parse; either ``shipping`` or ``billing`` """ address_dict = getattr(self, f'{address_type}_address') address = ' '.join(address_dict.get('street', [])) + ', ' for field in ('city', 'region_code', 'postcode', 'country_id'): if value := address_dict.get(field): address += value.replace('None', '') + ', ' return address.strip(', ') @cached_property def payment(self) -> dict: """Payment data""" data = copy.deepcopy(self.__payment) if additional_info := self.extension_attributes.get('payment_additional_info'): data.pop('additional_information', None) data.update(self.unpack_attributes(additional_info, key='key')) return data @property def net_tax(self) -> float: """Final tax amount, with refunds and cancellations taken into account""" return self.base_tax_amount - getattr(self, 'base_tax_refunded', 0) - getattr(self, 'base_tax_canceled', 0) @property def net_total(self) -> float: """Final Order value, with refunds and cancellations taken into account""" return self.base_grand_total - getattr(self, 'base_total_refunded', 0) - getattr(self, 'base_total_canceled', 0) @property def item_refunds(self) -> float: """Total amount refunded for items; excludes shipping and adjustment refunds/fees""" return sum(item.net_refund for item in self.items) @cached_property def total_qty_invoiced(self) -> int: """Total number of units invoiced""" return sum(item.qty_invoiced for item in self.items) @cached_property def total_qty_shipped(self) -> int: """Total number of units shipped""" return sum(item.qty_shipped for item in self.items) @cached_property def total_qty_refunded(self) -> int: """Total number of units refunded""" return sum(item.qty_refunded for item in self.items) @cached_property def total_qty_canceled(self) -> int: """Total number of units canceled""" return sum(item.qty_canceled for item in self.items) @cached_property def total_qty_outstanding(self) -> int: """Total number of units that haven't been shipped/fulfilled yet""" return sum(item.qty_outstanding for item in self.items) @cached_property def net_qty_ordered(self) -> int: """Total number of units ordered, after accounting for refunds and cancellations""" return sum(item.net_qty_ordered for item in self.items) Bases:
Model
Wrapper for the
orders
endpoint- DOCUMENTATION: str = 'https://adobe-commerce.redoc.ly/2.3.7-admin/tag/orders'
Link to the Official Magento 2 API documentation for the endpoint wrapped by the Model
-
__init__(data, client)View on GitHub
View Source Code
def __init__(self, data: dict, client: Client): """Initialize an Order object using an API response from the ``orders`` endpoint :param data: API response from the ``orders`` endpoint :param client: an initialized :class:`~.Client` object """ super().__init__( data=data, client=client, endpoint='orders', private_keys=True ) Initialize an Order object using an API response from the
orders
endpoint
-
property excluded_keys: List[str]View on GitHub
View Source Code
@property def excluded_keys(self) -> List[str]: return ['items', 'payment'] API response keys that shouldn’t be set as object attributes by
set_attrs()
- Returns
list of API response keys that shouldn’t be set as attributes
-
property id: intView on GitHub
View Source Code
@property def id(self) -> int: """Alias for ``entity_id``""" return getattr(self, 'entity_id', None) Alias for
entity_id
-
property number: strView on GitHub
View Source Code
@property def number(self) -> str: """Alias for ``increment_id``""" return getattr(self, 'increment_id', None) Alias for
increment_id
-
property items: List[OrderItem]View on GitHub
View Source Code
@cached_property def items(self) -> List[OrderItem]: """The ordered items, returned as a list of :class:`OrderItem` objects .. note:: When a configurable :class:`~.Product` is ordered, the API returns data for both the configurable and simple product * The :class:`OrderItem` is initialized using the configurable product data, since the simple product data is incomplete * The :attr:`~.OrderItem.product` and :attr:`~.OrderItem.product_id` will still match the simple product though If both entries are needed, the unparsed response is in the :attr:`~.data` dict """ return [OrderItem(item, order=self) for item in self.__items if item.get('parent_item') is None] The ordered items, returned as a list of
OrderItem
objectsNote
When a configurable
Product
is ordered, the API returns data for both the configurable and simple productThe
OrderItem
is initialized using the configurable product data, since the simple product data is incompleteThe
product
andproduct_id
will still match the simple product though
If both entries are needed, the unparsed response is in the
data
dict
-
property item_ids: List[int]View on GitHub
View Source Code
@cached_property def item_ids(self) -> List[int]: """The ``item_id`` s of the ordered :attr:`~.items`""" return [item.item_id for item in self.items] The
item_id
s of the ordereditems
-
property products: List[Product]View on GitHub
View Source Code
@cached_property def products(self) -> List[Product]: """The ordered :attr:`~items`, returned as their corresponding :class:`~.Product` objects""" return [item.product for item in self.items] The ordered
items
, returned as their correspondingProduct
objects
-
get_invoice()View on GitHub
View Source Code
def get_invoice(self) -> Invoice: """Retrieve the :class:`~.Invoice` of the Order""" return self.client.invoices.by_order(self) Retrieve the
Invoice
of the Order- Return type
-
property customer: CustomerView on GitHub
View Source Code
@property def customer(self) -> Customer: return self.client.customers.by_order(self)
-
property shipping_address: dictView on GitHub
View Source Code
@property def shipping_address(self) -> dict: """Shipping details, from ``extension_attributes.shipping_assignments``""" return self.extension_attributes.get( 'shipping_assignments', [{}])[0].get( 'shipping', {}).get( 'address', {}) Shipping details, from
extension_attributes.shipping_assignments
-
property bill_to: dictView on GitHub
View Source Code
@property def bill_to(self) -> dict: """Condensed version of the ``billing_address`` dict""" if hasattr(self, 'billing_address'): return { 'firstname': self.billing_address.get('firstname', ''), 'lastname': self.billing_address.get('lastname', ''), 'email': self.billing_address.get('email', ''), 'address': self.bill_to_address } Condensed version of the
billing_address
dict
-
property bill_to_address: strView on GitHub
View Source Code
@property def bill_to_address(self) -> str: """The billing address, parsed into a single string""" return self._build_address('billing') The billing address, parsed into a single string
-
property ship_to: dictView on GitHub
View Source Code
@property def ship_to(self) -> dict: """Condensed version of the :attr:`~.shipping_address` dict""" return { 'firstname': self.shipping_address.get('firstname', ''), 'lastname': self.shipping_address.get('lastname', ''), 'email': self.shipping_address.get('email', ''), 'address': self.ship_to_address } Condensed version of the
shipping_address
dict
-
property ship_to_address: strView on GitHub
View Source Code
@property def ship_to_address(self) -> str: """The shipping address, parsed into a single string""" return self._build_address('shipping') The shipping address, parsed into a single string
-
property payment: dictView on GitHub
View Source Code
@cached_property def payment(self) -> dict: """Payment data""" data = copy.deepcopy(self.__payment) if additional_info := self.extension_attributes.get('payment_additional_info'): data.pop('additional_information', None) data.update(self.unpack_attributes(additional_info, key='key')) return data Payment data
-
property net_tax: floatView on GitHub
View Source Code
@property def net_tax(self) -> float: """Final tax amount, with refunds and cancellations taken into account""" return self.base_tax_amount - getattr(self, 'base_tax_refunded', 0) - getattr(self, 'base_tax_canceled', 0) Final tax amount, with refunds and cancellations taken into account
-
property net_total: floatView on GitHub
View Source Code
@property def net_total(self) -> float: """Final Order value, with refunds and cancellations taken into account""" return self.base_grand_total - getattr(self, 'base_total_refunded', 0) - getattr(self, 'base_total_canceled', 0) Final Order value, with refunds and cancellations taken into account
-
property item_refunds: floatView on GitHub
View Source Code
@property def item_refunds(self) -> float: """Total amount refunded for items; excludes shipping and adjustment refunds/fees""" return sum(item.net_refund for item in self.items) Total amount refunded for items; excludes shipping and adjustment refunds/fees
-
property total_qty_invoiced: intView on GitHub
View Source Code
@cached_property def total_qty_invoiced(self) -> int: """Total number of units invoiced""" return sum(item.qty_invoiced for item in self.items) Total number of units invoiced
-
property total_qty_shipped: intView on GitHub
View Source Code
@cached_property def total_qty_shipped(self) -> int: """Total number of units shipped""" return sum(item.qty_shipped for item in self.items) Total number of units shipped
-
property total_qty_refunded: intView on GitHub
View Source Code
@cached_property def total_qty_refunded(self) -> int: """Total number of units refunded""" return sum(item.qty_refunded for item in self.items) Total number of units refunded
-
property total_qty_canceled: intView on GitHub
View Source Code
@cached_property def total_qty_canceled(self) -> int: """Total number of units canceled""" return sum(item.qty_canceled for item in self.items) Total number of units canceled
-
property total_qty_outstanding: intView on GitHub
View Source Code
@cached_property def total_qty_outstanding(self) -> int: """Total number of units that haven't been shipped/fulfilled yet""" return sum(item.qty_outstanding for item in self.items) Total number of units that haven’t been shipped/fulfilled yet
-
property net_qty_ordered: intView on GitHub
View Source Code
@cached_property def net_qty_ordered(self) -> int: """Total number of units ordered, after accounting for refunds and cancellations""" return sum(item.net_qty_ordered for item in self.items) Total number of units ordered, after accounting for refunds and cancellations
-
class magento.models.order.OrderItem(item, client=None, order=None)View on GitHub
View Source Code
class OrderItem(Model): """Wrapper for the ``order/items`` endpoint""" DOCUMENTATION = "https://adobe-commerce.redoc.ly/2.3.7-admin/tag/ordersitems" IDENTIFIER = 'item_id' def __init__(self, item: dict, client: Optional[Client] = None, order: Optional[Order] = None): """Initialize an OrderItem using an API response from the ``orders/items`` endpoint .. note:: Initialization requires either a :class:`~.Client` or :class:`Order` object :param item: API response from the ``orders/items`` endpoint :param order: the :class:`Order` that this is an item of :param client: the :class:`~.Client` to use (if not initializing with an Order) :raise ValueError: if both the ``order`` and ``client`` aren't provided """ if client is None: if order is None: raise ValueError('An Order or Client object must be provided') if not isinstance(order, Order): raise TypeError(f'`order` must be of type {Order}') super().__init__( data=item, client=client if client else order.client, endpoint='orders/items' ) self.tax = item.get('base_tax_amount', item.get('tax_amount', 0)) self.refund = item.get('base_amount_refunded', item.get('amount_refunded', 0)) self.tax_refunded = item.get('base_tax_refunded', item.get('tax_refunded', 0)) self.line_total = item.get('base_row_total_incl_tax', item.get('row_total_incl_tax', 0)) self._order = order def __repr__(self): return f"<OrderItem ({self.sku})> from Order ID: {self.order_id}>" @property def excluded_keys(self) -> List[str]: return ['product_id'] @cached_property def order(self) -> Order: """The corresponding :class:`Order`""" if self._order is None: return self.client.orders.by_id(self.order_id) return self._order @cached_property def product(self) -> Product: """The item's corresponding :class:`~.Product` .. note:: **If the ordered item:** * Is a configurable product - the child simple product is returned * Has custom options - the base product is returned """ if self.product_type != 'configurable': return self.client.products.by_id(self.product_id) if not self.extension_attributes.get('custom_options'): return self.client.products.by_sku(self.sku) # Configurable + Custom Options -> configurable product id & unsearchable option sku for item in self.order.data['items']: # Get simple product id from response data if item.get('parent_item_id') == self.item_id: return self.client.products.by_id(item['product_id']) @cached_property def product_id(self) -> int: """Id of the corresponding simple :class:`~.Product`""" return self.__product_id if self.product_type != 'configurable' else self.product.id @cached_property def extension_attributes(self) -> dict: return getattr(self, 'product_option', {}).get('extension_attributes', {}) @cached_property def qty_outstanding(self) -> int: """Number of units that haven't been shipped/fulfilled yet""" return self.net_qty_ordered - self.qty_shipped @cached_property def net_qty_ordered(self) -> int: """Number of units ordered, after accounting for refunds and cancellations""" return self.qty_ordered - self.qty_refunded - self.qty_canceled @cached_property def net_tax(self) -> float: """Tax amount after accounting for refunds and cancellations""" return self.tax - self.tax_refunded - getattr(self, 'tax_canceled', 0) @cached_property def net_total(self) -> float: """Row total (incl. tax) after accounting for refunds and cancellations""" return self.line_total - self.net_refund - self.total_canceled @cached_property def net_refund(self) -> float: """Refund amount after accounting for tax and discount refunds""" return self.refund + self.tax_refunded - getattr(self, 'discount_refunded', 0) @cached_property def total_canceled(self) -> float: """Cancelled amount; note that partial cancellation is not possible""" if self.qty_canceled != 0: return self.line_total return 0 Bases:
Model
Wrapper for the
order/items
endpoint- DOCUMENTATION: str = 'https://adobe-commerce.redoc.ly/2.3.7-admin/tag/ordersitems'
Link to the Official Magento 2 API documentation for the endpoint wrapped by the Model
-
__init__(item, client=None, order=None)View on GitHub
View Source Code
def __init__(self, item: dict, client: Optional[Client] = None, order: Optional[Order] = None): """Initialize an OrderItem using an API response from the ``orders/items`` endpoint .. note:: Initialization requires either a :class:`~.Client` or :class:`Order` object :param item: API response from the ``orders/items`` endpoint :param order: the :class:`Order` that this is an item of :param client: the :class:`~.Client` to use (if not initializing with an Order) :raise ValueError: if both the ``order`` and ``client`` aren't provided """ if client is None: if order is None: raise ValueError('An Order or Client object must be provided') if not isinstance(order, Order): raise TypeError(f'`order` must be of type {Order}') super().__init__( data=item, client=client if client else order.client, endpoint='orders/items' ) self.tax = item.get('base_tax_amount', item.get('tax_amount', 0)) self.refund = item.get('base_amount_refunded', item.get('amount_refunded', 0)) self.tax_refunded = item.get('base_tax_refunded', item.get('tax_refunded', 0)) self.line_total = item.get('base_row_total_incl_tax', item.get('row_total_incl_tax', 0)) self._order = order Initialize an OrderItem using an API response from the
orders/items
endpoint
-
property excluded_keys: List[str]View on GitHub
View Source Code
@property def excluded_keys(self) -> List[str]: return ['product_id'] API response keys that shouldn’t be set as object attributes by
set_attrs()
- Returns
list of API response keys that shouldn’t be set as attributes
-
property order: OrderView on GitHub
View Source Code
@cached_property def order(self) -> Order: """The corresponding :class:`Order`""" if self._order is None: return self.client.orders.by_id(self.order_id) return self._order The corresponding
Order
-
property product: ProductView on GitHub
View Source Code
@cached_property def product(self) -> Product: """The item's corresponding :class:`~.Product` .. note:: **If the ordered item:** * Is a configurable product - the child simple product is returned * Has custom options - the base product is returned """ if self.product_type != 'configurable': return self.client.products.by_id(self.product_id) if not self.extension_attributes.get('custom_options'): return self.client.products.by_sku(self.sku) # Configurable + Custom Options -> configurable product id & unsearchable option sku for item in self.order.data['items']: # Get simple product id from response data if item.get('parent_item_id') == self.item_id: return self.client.products.by_id(item['product_id']) The item’s corresponding
Product
Note
If the ordered item:
Is a configurable product - the child simple product is returned
Has custom options - the base product is returned
-
property product_id: intView on GitHub
View Source Code
@cached_property def product_id(self) -> int: """Id of the corresponding simple :class:`~.Product`""" return self.__product_id if self.product_type != 'configurable' else self.product.id Id of the corresponding simple
Product
-
property extension_attributes: dictView on GitHub
View Source Code
@cached_property def extension_attributes(self) -> dict: return getattr(self, 'product_option', {}).get('extension_attributes', {})
-
property qty_outstanding: intView on GitHub
View Source Code
@cached_property def qty_outstanding(self) -> int: """Number of units that haven't been shipped/fulfilled yet""" return self.net_qty_ordered - self.qty_shipped Number of units that haven’t been shipped/fulfilled yet
-
property net_qty_ordered: intView on GitHub
View Source Code
@cached_property def net_qty_ordered(self) -> int: """Number of units ordered, after accounting for refunds and cancellations""" return self.qty_ordered - self.qty_refunded - self.qty_canceled Number of units ordered, after accounting for refunds and cancellations
-
property net_tax: floatView on GitHub
View Source Code
@cached_property def net_tax(self) -> float: """Tax amount after accounting for refunds and cancellations""" return self.tax - self.tax_refunded - getattr(self, 'tax_canceled', 0) Tax amount after accounting for refunds and cancellations
-
property net_total: floatView on GitHub
View Source Code
@cached_property def net_total(self) -> float: """Row total (incl. tax) after accounting for refunds and cancellations""" return self.line_total - self.net_refund - self.total_canceled Row total (incl. tax) after accounting for refunds and cancellations
-
property net_refund: floatView on GitHub
View Source Code
@cached_property def net_refund(self) -> float: """Refund amount after accounting for tax and discount refunds""" return self.refund + self.tax_refunded - getattr(self, 'discount_refunded', 0) Refund amount after accounting for tax and discount refunds
-
property total_canceled: floatView on GitHub
View Source Code
@cached_property def total_canceled(self) -> float: """Cancelled amount; note that partial cancellation is not possible""" if self.qty_canceled != 0: return self.line_total return 0 Cancelled amount; note that partial cancellation is not possible