Source code for magento.models.category

from __future__ import annotations
import copy
from . import Model
from typing import TYPE_CHECKING, List, Optional, Set, Dict, Union
from functools import cached_property

if TYPE_CHECKING:
    from magento import Client
    from . import Product, Order, OrderItem, Invoice


[docs]class Category(Model): """Wrapper for the ``categories`` endpoint""" DOCUMENTATION = 'https://adobe-commerce.redoc.ly/2.3.7-admin/tag/categories' IDENTIFIER = 'id'
[docs] def __init__(self, data: dict, client: Client): """Initialize a Category object using an API response from the ``categories`` endpoint :param data: raw API response """ super().__init__( data=data, client=client, endpoint='categories' )
def __repr__(self): return f'<Magento Category: {self.name}>' @property def excluded_keys(self): return ['custom_attributes'] @cached_property def custom_attributes(self) -> Dict[str, str]: return self.unpack_attributes(self.data.get('custom_attributes')) @cached_property def subcategories(self) -> List[Category]: """The child categories, returned as a list of :class:`~.Category` objects .. note:: Only the direct child categories are returned. For a list of all descendants, use :attr:`~.all_subcategories` """ if hasattr(self, 'children_data'): # A list of API response dicts (when Category is from search) return [self.parse(child) for child in self.children_data] if hasattr(self, 'children') and self.children: # String of subcategory ids (from categories/{id} endpoint) return self.query_endpoint().by_list('entity_id', self.children) else: return [] @cached_property def subcategory_ids(self) -> List[int]: """The ``category_ids`` of the :attr:`~.subcategories`""" if hasattr(self, 'children'): if self.children: return [int(child) for child in self.children.split(',')] return [] return [category.id for category in self.subcategories] @cached_property def subcategory_names(self) -> List[str]: """The names of the category's :attr:`~.subcategories`""" return [category.name for category in self.subcategories] @cached_property def all_subcategories(self) -> Optional[List[Category]]: """Recursively retrieves all descendants of the category""" if not self.subcategories: return [] children = copy.deepcopy(self.subcategories) for child in self.subcategories: children.extend(child.all_subcategories) return children @cached_property def all_subcategory_ids(self) -> List[int]: """The ``category_ids`` of :attr:`~.all_subcategories`""" return [category.id for category in self.all_subcategories] @cached_property def products(self) -> List[Product]: """The :class:`~.Product` s in the category Alias for :meth:`get_products` """ return self.get_products() @cached_property def product_ids(self) -> List[int]: """The ``product_ids`` of the category's :attr:`~.products`""" return [product.id for product in self.products] @cached_property def skus(self) -> List[str]: """The skus of the category's :attr:`~.products`""" return [product.sku for product in self.products] @cached_property def all_products(self) -> List[Product]: """The :class:`~.Product` s in the category and in :attr:`~.all_subcategories` Alias for :meth:`get_products` with ``search_subcategories=True`` """ return self.get_products(search_subcategories=True) @cached_property def all_product_ids(self) -> Set[int]: """The ``product_ids`` of the products in the category and in :attr:`~.all_subcategories`""" return set(product.id for product in self.all_products) @cached_property def all_skus(self) -> Set[str]: """The skus of the products in the category and in :attr:`~.all_subcategories`""" return set(product.sku for product in self.all_products)
[docs] def get_products(self, search_subcategories: bool = False) -> Optional[Product | List[Product]]: """Retrieves the category's products :param search_subcategories: if ``True``, also retrieves products from :attr:`~.all_subcategories` """ return self.client.products.by_category(self, search_subcategories) or []
[docs] def get_orders(self, search_subcategories: bool = False) -> Optional[Order | List[Order]]: """Retrieve any :class:`~.Order` that contains one of the category's :attr:`~products` :param search_subcategories: if ``True``, also searches for orders from :attr:`~.all_subcategories` """ return self.client.orders.by_category(self, search_subcategories)
[docs] def get_order_items(self, search_subcategories: bool = False) -> Optional[OrderItem | List[OrderItem]]: """Retrieve any :class:`~.OrderItem` that contains one of the category's :attr:`~products` :param search_subcategories: if ``True``, also searches for order items from :attr:`~.all_subcategories` """ return self.client.order_items.by_category(self, search_subcategories)
[docs] def get_invoices(self, search_subcategories: bool = False) -> Optional[Invoice | List[Invoice]]: """Retrieve any :class:`~.Invoice` that contains one of the category's :attr:`~products` :param search_subcategories: if ``True``, also searches for invoices from :attr:`~.all_subcategories` """ return self.client.invoices.by_category(self, search_subcategories)