From 02d3f138fe7e883b1e10f8a1c53d5ce5e5f571f6 Mon Sep 17 00:00:00 2001 From: Robert Segal Date: Mon, 22 Sep 2025 08:32:19 -0600 Subject: [PATCH] Add price list and price list items endpoints --- mpt_api_client/resources/catalog/catalog.py | 30 ++++++++++ .../resources/catalog/price_list_items.py | 40 +++++++++++++ .../resources/catalog/price_lists.py | 58 +++++++++++++++++++ setup.cfg | 2 + tests/resources/catalog/test_catalog.py | 6 ++ .../catalog/test_price_list_items.py | 42 ++++++++++++++ tests/resources/catalog/test_price_lists.py | 56 ++++++++++++++++++ 7 files changed, 234 insertions(+) create mode 100644 mpt_api_client/resources/catalog/price_list_items.py create mode 100644 mpt_api_client/resources/catalog/price_lists.py create mode 100644 tests/resources/catalog/test_price_list_items.py create mode 100644 tests/resources/catalog/test_price_lists.py diff --git a/mpt_api_client/resources/catalog/catalog.py b/mpt_api_client/resources/catalog/catalog.py index 999d169c..f7d597d7 100644 --- a/mpt_api_client/resources/catalog/catalog.py +++ b/mpt_api_client/resources/catalog/catalog.py @@ -4,6 +4,14 @@ AuthorizationsService, ) from mpt_api_client.resources.catalog.items import AsyncItemsService, ItemsService +from mpt_api_client.resources.catalog.price_list_items import ( + AsyncPriceListItemsService, + PriceListItemsService, +) +from mpt_api_client.resources.catalog.price_lists import ( + AsyncPriceListsService, + PriceListsService, +) from mpt_api_client.resources.catalog.products import AsyncProductsService, ProductsService @@ -18,6 +26,17 @@ def authorizations(self) -> AuthorizationsService: """Authorizations service.""" return AuthorizationsService(http_client=self.http_client) + def price_list_items(self, price_list_id: str) -> PriceListItemsService: + """Price List Items service.""" + return PriceListItemsService( + http_client=self.http_client, endpoint_params={"price_list_id": price_list_id} + ) + + @property + def price_lists(self) -> PriceListsService: + """Price Lists service.""" + return PriceListsService(http_client=self.http_client) + @property def products(self) -> ProductsService: """Products service.""" @@ -40,6 +59,17 @@ def authorizations(self) -> AsyncAuthorizationsService: """Authorizations service.""" return AsyncAuthorizationsService(http_client=self.http_client) + def price_list_items(self, price_list_id: str) -> AsyncPriceListItemsService: + """Price List Items service.""" + return AsyncPriceListItemsService( + http_client=self.http_client, endpoint_params={"price_list_id": price_list_id} + ) + + @property + def price_lists(self) -> AsyncPriceListsService: + """Price Lists service.""" + return AsyncPriceListsService(http_client=self.http_client) + @property def products(self) -> AsyncProductsService: """Products service.""" diff --git a/mpt_api_client/resources/catalog/price_list_items.py b/mpt_api_client/resources/catalog/price_list_items.py new file mode 100644 index 00000000..cb4dcda6 --- /dev/null +++ b/mpt_api_client/resources/catalog/price_list_items.py @@ -0,0 +1,40 @@ +from mpt_api_client.http import AsyncService, CreateMixin, DeleteMixin, Service +from mpt_api_client.http.mixins import ( + AsyncCreateMixin, + AsyncDeleteMixin, + AsyncUpdateMixin, + UpdateMixin, +) +from mpt_api_client.models import Model + + +class PriceListItem(Model): + """Price List Item resource.""" + + +class PriceListItemsServiceConfig: + """Price List Items service configuration.""" + + _endpoint = "/public/v1/catalog/price-lists/{price_list_id}/items" + _model_class = PriceListItem + _collection_key = "data" + + +class PriceListItemsService( + CreateMixin[PriceListItem], + DeleteMixin, + UpdateMixin[PriceListItem], + Service[PriceListItem], + PriceListItemsServiceConfig, +): + """Price List Items service.""" + + +class AsyncPriceListItemsService( + AsyncCreateMixin[PriceListItem], + AsyncDeleteMixin, + AsyncUpdateMixin[PriceListItem], + AsyncService[PriceListItem], + PriceListItemsServiceConfig, +): + """Price List Items service.""" diff --git a/mpt_api_client/resources/catalog/price_lists.py b/mpt_api_client/resources/catalog/price_lists.py new file mode 100644 index 00000000..022a027f --- /dev/null +++ b/mpt_api_client/resources/catalog/price_lists.py @@ -0,0 +1,58 @@ +from mpt_api_client.http import AsyncService, Service +from mpt_api_client.http.mixins import ( + AsyncCreateMixin, + AsyncDeleteMixin, + AsyncUpdateMixin, + CreateMixin, + DeleteMixin, + UpdateMixin, +) +from mpt_api_client.models import Model +from mpt_api_client.resources.catalog.price_list_items import ( + AsyncPriceListItemsService, + PriceListItemsService, +) + + +class PriceList(Model): + """Price List resource.""" + + +class PriceListsServiceConfig: + """Price Lists service configuration.""" + + _endpoint = "/public/v1/catalog/price-lists" + _model_class = PriceList + _collection_key = "data" + + +class PriceListsService( + CreateMixin[PriceList], + DeleteMixin, + UpdateMixin[PriceList], + Service[PriceList], + PriceListsServiceConfig, +): + """Price Lists service.""" + + def items(self, price_list_id: str) -> PriceListItemsService: + """Price List Items service.""" + return PriceListItemsService( + http_client=self.http_client, endpoint_params={"price_list_id": price_list_id} + ) + + +class AsyncPriceListsService( + AsyncCreateMixin[PriceList], + AsyncDeleteMixin, + AsyncUpdateMixin[PriceList], + AsyncService[PriceList], + PriceListsServiceConfig, +): + """Price Lists service.""" + + def items(self, price_list_id: str) -> AsyncPriceListItemsService: + """Price List Items service.""" + return AsyncPriceListItemsService( + http_client=self.http_client, endpoint_params={"price_list_id": price_list_id} + ) diff --git a/setup.cfg b/setup.cfg index 24f1b99a..b4d1ad07 100644 --- a/setup.cfg +++ b/setup.cfg @@ -36,6 +36,8 @@ per-file-ignores = mpt_api_client/resources/catalog/authorizations.py: WPS215 mpt_api_client/resources/catalog/products.py: WPS204 WPS214 WPS215 mpt_api_client/resources/catalog/items.py: WPS215 + mpt_api_client/resources/catalog/price_lists.py: WPS215 WPS110 + mpt_api_client/resources/catalog/price_list_items.py: WPS215 mpt_api_client/resources/catalog/products_item_groups.py: WPS215 mpt_api_client/resources/catalog/products_parameter_groups.py: WPS215 mpt_api_client/resources/catalog/products_parameters.py: WPS215 diff --git a/tests/resources/catalog/test_catalog.py b/tests/resources/catalog/test_catalog.py index 4afcfa5e..cc7526b4 100644 --- a/tests/resources/catalog/test_catalog.py +++ b/tests/resources/catalog/test_catalog.py @@ -6,6 +6,10 @@ ) from mpt_api_client.resources.catalog.catalog import AsyncCatalog, Catalog from mpt_api_client.resources.catalog.items import AsyncItemsService, ItemsService +from mpt_api_client.resources.catalog.price_lists import ( + AsyncPriceListsService, + PriceListsService, +) from mpt_api_client.resources.catalog.products import AsyncProductsService, ProductsService @@ -23,6 +27,7 @@ def async_catalog(async_http_client): ("property_name", "expected_service_class"), [ ("authorizations", AuthorizationsService), + ("price_lists", PriceListsService), ("products", ProductsService), ("items", ItemsService), ], @@ -39,6 +44,7 @@ def test_catalog_properties(catalog, property_name, expected_service_class): ("property_name", "expected_service_class"), [ ("authorizations", AsyncAuthorizationsService), + ("price_lists", AsyncPriceListsService), ("products", AsyncProductsService), ("items", AsyncItemsService), ], diff --git a/tests/resources/catalog/test_price_list_items.py b/tests/resources/catalog/test_price_list_items.py new file mode 100644 index 00000000..3a5013e9 --- /dev/null +++ b/tests/resources/catalog/test_price_list_items.py @@ -0,0 +1,42 @@ +import pytest + +from mpt_api_client.resources.catalog.price_list_items import ( + AsyncPriceListItemsService, + PriceListItemsService, +) + + +@pytest.fixture +def price_list_items_service(http_client): + return PriceListItemsService( + http_client=http_client, endpoint_params={"price_list_id": "ITM-0000-0001"} + ) + + +@pytest.fixture +def async_price_list_items_service(async_http_client): + return AsyncPriceListItemsService( + http_client=async_http_client, endpoint_params={"price_list_id": "ITM-0000-0001"} + ) + + +@pytest.fixture +def test_endpoint(price_list_items_service): + assert price_list_items_service.endpoint == "/public/v1/catalog/price-lists/ITM-0000-0001/items" + + +@pytest.fixture +def async_test_endpoint(async_price_list_items_service): + assert async_price_list_items_service.endpoint == ( + "/public/v1/catalog/price-lists/ITM-0000-0001/items" + ) + + +@pytest.mark.parametrize("method", ["get", "create", "delete", "update"]) +def test_methods_present(price_list_items_service, method): + assert hasattr(price_list_items_service, method) + + +@pytest.mark.parametrize("method", ["get", "create", "delete", "update"]) +def test_async_methods_present(async_price_list_items_service, method): + assert hasattr(async_price_list_items_service, method) diff --git a/tests/resources/catalog/test_price_lists.py b/tests/resources/catalog/test_price_lists.py new file mode 100644 index 00000000..081f8948 --- /dev/null +++ b/tests/resources/catalog/test_price_lists.py @@ -0,0 +1,56 @@ +import pytest + +from mpt_api_client.resources.catalog.price_list_items import ( + AsyncPriceListItemsService, + PriceListItemsService, +) +from mpt_api_client.resources.catalog.price_lists import ( + AsyncPriceListsService, + PriceListsService, +) + + +@pytest.fixture +def price_lists_service(http_client): + return PriceListsService(http_client=http_client) + + +@pytest.fixture +def async_price_lists_service(http_client): + return AsyncPriceListsService(http_client=http_client) + + +@pytest.mark.parametrize("method", ["get", "create", "update", "delete"]) +def test_mixins_present(price_lists_service, method): + assert hasattr(price_lists_service, method) + + +@pytest.mark.parametrize("method", ["get", "create", "update", "delete"]) +def test_async_mixins_present(async_price_lists_service, method): + assert hasattr(async_price_lists_service, method) + + +@pytest.mark.parametrize( + ("service_method", "expected_model_class"), + [ + ("items", PriceListItemsService), + ], +) +def test_property_services(price_lists_service, service_method, expected_model_class): + property_service = getattr(price_lists_service, service_method)("ITM-0000-0001") + + assert isinstance(property_service, expected_model_class) + assert property_service.endpoint_params == {"price_list_id": "ITM-0000-0001"} + + +@pytest.mark.parametrize( + ("service_method", "expected_model_class"), + [ + ("items", AsyncPriceListItemsService), + ], +) +def test_async_property_services(async_price_lists_service, service_method, expected_model_class): + property_service = getattr(async_price_lists_service, service_method)("ITM-0000-0001") + + assert isinstance(property_service, expected_model_class) + assert property_service.endpoint_params == {"price_list_id": "ITM-0000-0001"}