diff --git a/inventree/base.py b/inventree/base.py index e224128..7af8a3d 100644 --- a/inventree/base.py +++ b/inventree/base.py @@ -2,9 +2,10 @@ import json import logging -import requests import os +import requests + from . import api as inventree_api INVENTREE_PYTHON_VERSION = "0.23.1" @@ -60,7 +61,7 @@ def pk(self): # Coerce 'pk' values to integer if self.getPkField() == 'pk': val = int(val) - + return val def __str__(self): @@ -92,7 +93,7 @@ def __init__(self, api, pk=None, data=None): pk = int(str(pk).strip()) except Exception: raise TypeError(f"Invalid primary key value '{pk}' for {self.__class__}") - + if pk <= 0: raise ValueError(f"Supplier value ({pk}) for {self.__class__} must be positive.") @@ -113,7 +114,13 @@ def __init__(self, api, pk=None, data=None): @classmethod def getModelType(cls): """Return the model type for this label printing class.""" - return cls.MODEL_TYPE + model_type = cls.MODEL_TYPE + + if not model_type: + # Default to the class name (lower case) if the model type is not explicitly defined + model_type = cls.__name__.lower() + + return model_type @classmethod def checkApiVersion(cls, api): @@ -532,7 +539,7 @@ def uploadAttachment(self, attachment, comment=""): model_type=self.getModelType(), model_id=self.pk ) - + def addLinkAttachment(self, link, comment=""): """Add an external link attachment against this Object. @@ -570,7 +577,7 @@ class ParameterTemplate(InventreeObject): class ParameterMixin: """Mixin class which allows a model class to interact with parameters. - + Ref: https://github.com/inventree/InvenTree/pull/10699 """ @@ -604,9 +611,13 @@ class MetadataMixin: @property def metadata_url(self): """Return the metadata URL for this model instance.""" + + # Legacy metadata API endpoints if self._api.api_version < self.NEW_METADATA_API_VERSION: return os.path.join(self._url, "metadata/") + model_type = self.getModelType() + return f"metadata/{model_type}/{self.pk}/" def getMetadata(self): diff --git a/inventree/company.py b/inventree/company.py index 29f43c9..485062e 100644 --- a/inventree/company.py +++ b/inventree/company.py @@ -13,6 +13,7 @@ class Contact(inventree.base.InventreeObject): URL = 'company/contact/' MIN_API_VERSION = 104 + MODEL_TYPE = 'contact' class Address(inventree.base.InventreeObject): @@ -20,6 +21,7 @@ class Address(inventree.base.InventreeObject): URL = 'company/address/' MIN_API_VERSION = 126 + MODEL_TYPE = 'address' class Company( @@ -117,6 +119,7 @@ class SupplierPart( """ URL = 'company/part/' + MODEL_TYPE = "supplierpart" def getPriceBreaks(self): """ Get a list of price break objects for this SupplierPart """ diff --git a/inventree/part.py b/inventree/part.py index 8e94240..a2de68f 100644 --- a/inventree/part.py +++ b/inventree/part.py @@ -38,6 +38,7 @@ class PartCategory(inventree.base.MetadataMixin, inventree.base.InventreeObject) """ Class representing the PartCategory database model """ URL = 'part/category/' + MODEL_TYPE = 'partcategory' def getParts(self, **kwargs): return Part.list(self._api, category=self.pk, **kwargs) @@ -120,7 +121,7 @@ def getParameters(self): if self._api.api_version < inventree.base.Parameter.MIN_API_VERSION: # Return legacy PartParameter objects return PartParameter.list(self._api, part=self.pk) - + return super().getParameters() def getRelated(self): @@ -140,7 +141,7 @@ def setInternalPrice(self, quantity: int, price: float): """ return InternalPrice.setInternalPrice(self._api, self.pk, quantity, price) - + def getSalePrice(self): """ Get sales prices for this part @@ -197,6 +198,7 @@ class BomItem( """ Class representing the BomItem database model """ URL = 'bom/' + MODEL_TYPE = 'bomitem' class BomItemSubstitute( @@ -279,7 +281,7 @@ def add_related(cls, api, part1, part2): class PartParameter(inventree.base.InventreeObject): """Legacy class representing the PartParameter database model. - + This has now been replaced with the generic Parameter model. Ref: https://github.com/inventree/InvenTree/pull/10699 @@ -298,7 +300,7 @@ class PartParameterTemplate(inventree.base.InventreeObject): """Legacy class representing the PartParameterTemplate database model. This has now been replaced with the generic ParameterTemplate model. - + Ref: https://github.com/inventree/InvenTree/pull/10699 """ diff --git a/inventree/stock.py b/inventree/stock.py index decf4e7..da87a1e 100644 --- a/inventree/stock.py +++ b/inventree/stock.py @@ -10,7 +10,6 @@ import inventree.part import inventree.report - logger = logging.getLogger('inventree') @@ -58,7 +57,6 @@ class StockItem( """Class representing the StockItem database model.""" URL = 'stock/' - MODEL_TYPE = 'stockitem' @classmethod diff --git a/test/test_part.py b/test/test_part.py index d2e2513..4d42a3d 100644 --- a/test/test_part.py +++ b/test/test_part.py @@ -15,12 +15,12 @@ from test_api import InvenTreeTestCase # noqa: E402 -from inventree.base import Attachment, Parameter, ParameterTemplate # noqa: E402 +from inventree.base import (Attachment, Parameter, # noqa: E402 + ParameterTemplate) from inventree.company import SupplierPart # noqa: E402 from inventree.part import InternalPrice # noqa: E402 -from inventree.part import (BomItem, PartParameter, # noqa: E402 - Part, - PartCategory, PartCategoryParameterTemplate, +from inventree.part import (BomItem, Part, PartCategory, # noqa: E402 + PartCategoryParameterTemplate, PartParameter, PartRelated, PartTestTemplate) from inventree.stock import StockItem # noqa: E402 @@ -28,6 +28,18 @@ class PartCategoryTest(InvenTreeTestCase): """Tests for PartCategory models""" + def test_metadata(self): + """Fetch metadata for a particular category.""" + + cat = PartCategory.list(self.api, limit=1)[0] + + url = cat.metadata_url + + self.assertEqual(url, f"metadata/partcategory/{cat.pk}/") + + metadata = cat.getMetadata() + self.assertIsInstance(metadata, dict) + def test_part_cats(self): """ Tests for category filtering @@ -74,7 +86,7 @@ def test_elec(self): # Create some new categories under this one for idx in range(3): - name = f"Subcategory {n+idx}" + name = f"Subcategory {n + idx}" cat = PartCategory.create(self.api, { "parent": child.pk, @@ -290,7 +302,7 @@ def test_part_list(self): for i in range(5): prt = Part.create(self.api, { "category": 5, - "name": f"Special Part {n+i}", + "name": f"Special Part {n + i}", "description": "A new part in this category!", }) @@ -741,7 +753,7 @@ def test_get_requirements(self): 'required_for_sales_orders', 'allocated_to_sales_orders', ] - + for f in fields: self.assertIn(f, req)