Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename catalogue_item_properties to properties #293 #294

Merged
merged 6 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified data/mock_data.dump
Binary file not shown.
12 changes: 6 additions & 6 deletions inventory_management_system_api/core/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ class NonLeafCategoryError(Exception):
"""


class DuplicateCatalogueItemPropertyNameError(Exception):
class DuplicateCategoryPropertyNameError(Exception):
joelvdavies marked this conversation as resolved.
Show resolved Hide resolved
"""
Catalogue category is attempted to be created with duplicate catalogue item property names.
Catalogue category is attempted to be created with duplicate property names.
"""


class InvalidCatalogueItemPropertyTypeError(Exception):
class InvalidPropertyTypeError(Exception):
"""
The type of the provided value does not match the expected type of the catalogue item property.
The type of the provided value does not match the expected type of the property.
"""


class MissingMandatoryCatalogueItemProperty(Exception):
class MissingMandatoryProperty(Exception):
"""
A mandatory catalogue item property is missing when a catalogue item is attempted to be created.
A mandatory property is missing when a catalogue item is attempted to be created.
joelvdavies marked this conversation as resolved.
Show resolved Hide resolved
"""


Expand Down
44 changes: 21 additions & 23 deletions inventory_management_system_api/models/catalogue_category.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

class AllowedValuesList(BaseModel):
"""
Model representing a list of allowed values for a catalogue item property
Model representing a list of allowed values for a property defined within a catalogue category
"""

type: Literal["list"]
Expand All @@ -24,9 +24,9 @@ class AllowedValuesList(BaseModel):
AllowedValues = Annotated[AllowedValuesList, Field(discriminator="type")]


class CatalogueItemPropertyBase(BaseModel):
class CategoryPropertyBase(BaseModel):
joelvdavies marked this conversation as resolved.
Show resolved Hide resolved
"""
Base database model for a catalogue item property.
Base database model for a property defined within a catalogue category
"""

name: str
Expand All @@ -37,19 +37,19 @@ class CatalogueItemPropertyBase(BaseModel):
allowed_values: Optional[AllowedValues] = None


class CatalogueItemPropertyIn(CatalogueItemPropertyBase):
class CategoryPropertyIn(CategoryPropertyBase):
"""
Input database model for a catalogue item property.
Input database model for a property defined within a catalogue category
"""

# Because the catalogue item properties are stored in a list inside the catalogue categories and not in a separate
# Because the are stored in a list inside the catalogue categories and not in a separate
joelvdavies marked this conversation as resolved.
Show resolved Hide resolved
# collection, it means that the IDs have to be manually generated here.
id: CustomObjectIdField = Field(default_factory=ObjectId, serialization_alias="_id")


class CatalogueItemPropertyOut(CatalogueItemPropertyBase):
class CategoryPropertyOut(CategoryPropertyBase):
"""
Output database model for a catalogue item property.
Output database model for a property defined within a catalogue category
"""

id: StringObjectIdField = Field(alias="_id")
Expand All @@ -59,13 +59,13 @@ class CatalogueItemPropertyOut(CatalogueItemPropertyBase):

def is_equal_without_id(self, other: Any) -> bool:
"""
Compare this instance with another instance of `CatalogueItemPropertyOut` while ignoring the ID.
Compare this instance with another instance of `CategoryPropertyOut` while ignoring the ID.

:param other: An instance of a model to compare with.
:return: `True` if the instances are of the same type and are equal when ignoring the ID field, `False`
otherwise.
"""
if not isinstance(other, CatalogueItemPropertyOut):
if not isinstance(other, CategoryPropertyOut):
return False

return (
Expand All @@ -86,28 +86,26 @@ class CatalogueCategoryBase(BaseModel):
code: str
is_leaf: bool
parent_id: Optional[CustomObjectIdField] = None
catalogue_item_properties: List[CatalogueItemPropertyIn] = []
properties: List[CategoryPropertyIn] = []

@field_validator("catalogue_item_properties", mode="before")
@field_validator("properties", mode="before")
@classmethod
def validate_catalogue_item_properties(cls, catalogue_item_properties: Any, info: ValidationInfo) -> Any:
def validate_properties(cls, properties: Any, info: ValidationInfo) -> Any:
"""
Validator for the `catalogue_item_properties` field that runs after field assignment but before type validation.
Validator for the `properties` field that runs after field assignment but before type validation.

If the value is `None`, it replaces it with an empty list allowing for catalogue categories without catalogue
item properties to be created. If the category is a non-leaf category and if catalogue item properties are
item properties to be created. If the category is a non-leaf category and if are
supplied, it replaces it with an empty list because they cannot have properties.
joelvdavies marked this conversation as resolved.
Show resolved Hide resolved

:param catalogue_item_properties: The list of catalogue item properties.
:param properties: The list of properties.
:param info: Validation info from pydantic.
:return: The list of catalogue item properties or an empty list.
:return: The list of or an empty list.
joelvdavies marked this conversation as resolved.
Show resolved Hide resolved
"""
if catalogue_item_properties is None or (
"is_leaf" in info.data and info.data["is_leaf"] is False and catalogue_item_properties
):
catalogue_item_properties = []
if properties is None or ("is_leaf" in info.data and info.data["is_leaf"] is False and properties):
properties = []

return catalogue_item_properties
return properties


class CatalogueCategoryIn(CreatedModifiedTimeInMixin, CatalogueCategoryBase):
Expand All @@ -123,6 +121,6 @@ class CatalogueCategoryOut(CreatedModifiedTimeOutMixin, CatalogueCategoryBase):

id: StringObjectIdField = Field(alias="_id")
parent_id: Optional[StringObjectIdField] = None
catalogue_item_properties: List[CatalogueItemPropertyOut] = []
properties: List[CategoryPropertyOut] = []

model_config = ConfigDict(populate_by_name=True, arbitrary_types_allowed=True)
4 changes: 2 additions & 2 deletions inventory_management_system_api/models/catalogue_item.py
VKTB marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class PropertyIn(BaseModel):
"""
Input database model for a catalogue item property
Input database model for a property defined within a catalogue item or item
"""

id: CustomObjectIdField = Field(serialization_alias="_id")
Expand All @@ -24,7 +24,7 @@ class PropertyIn(BaseModel):

class PropertyOut(BaseModel):
"""
Output database model for a catalogue item property
Output database model for a property defined within a catalogue item or item
"""

id: StringObjectIdField = Field(alias="_id")
Expand Down
50 changes: 25 additions & 25 deletions inventory_management_system_api/repositories/catalogue_category.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
from inventory_management_system_api.models.catalogue_category import (
CatalogueCategoryIn,
CatalogueCategoryOut,
CatalogueItemPropertyIn,
CatalogueItemPropertyOut,
CategoryPropertyIn,
CategoryPropertyOut,
)
from inventory_management_system_api.repositories import utils
from inventory_management_system_api.schemas.breadcrumbs import BreadcrumbsGetSchema
Expand Down Expand Up @@ -257,75 +257,75 @@ def has_child_elements(self, catalogue_category_id: CustomObjectId, session: Cli
is not None
)

def create_catalogue_item_property(
def create_property(
self,
catalogue_category_id: str,
catalogue_item_property: CatalogueItemPropertyIn,
property_in: CategoryPropertyIn,
session: ClientSession = None,
) -> CatalogueItemPropertyOut:
) -> CategoryPropertyOut:
"""
Create a new a catalogue item property within a catalogue category given its ID in a MongoDB database
Create a new a property within a catalogue category given its ID in a MongoDB database

This method only affects catalogue categories so this should only be used in conjunction with the respective
insert methods within the catalogue items and items repos if the catalogue category may have children.

:param catalogue_category_id: The ID of the catalogue category to add the property to
:param catalogue_item_property: The catalogue item property containing the property data
:param property_in: The category property containing the property data
joelvdavies marked this conversation as resolved.
Show resolved Hide resolved
:param session: PyMongo ClientSession to use for database operations
:return: The added catalogue category
joelvdavies marked this conversation as resolved.
Show resolved Hide resolved
"""

logger.info(
"Inserting new catalogue item property into catalogue category with ID: %s in the database",
"Inserting new property into catalogue category with ID: %s in the database",
catalogue_category_id,
)
catalogue_item_property_data = catalogue_item_property.model_dump(by_alias=True)
property_data = property_in.model_dump(by_alias=True)
self._catalogue_categories_collection.update_one(
{"_id": CustomObjectId(catalogue_category_id)},
{
"$push": {"catalogue_item_properties": catalogue_item_property_data},
"$push": {"properties": property_data},
"$set": {"modified_time": datetime.now(timezone.utc)},
},
session=session,
)
return CatalogueItemPropertyOut(**catalogue_item_property_data)
return CategoryPropertyOut(**property_data)

def update_catalogue_item_property(
def update_property(
self,
catalogue_category_id: str,
catalogue_item_property_id: str,
catalogue_item_property: CatalogueItemPropertyIn,
property_id: str,
property_in: CategoryPropertyIn,
session: ClientSession = None,
) -> CatalogueItemPropertyOut:
) -> CategoryPropertyOut:
"""
Updates a catalogue item property given its ID and the ID of the catalogue category it's in
Updates a property given its ID and the ID of the catalogue category it's in

:param catalogue_category_id: The ID of the catalogue category to update
:param catalogue_item_property_id: The ID of the catalogue item property to update
:param catalogue_item_property: The catalogue item property containing the update data
:param property_id: The ID of the property to update
:param property_in: The property containing the update data
:param session: PyMongo ClientSession to use for database operations
:return: The updated catalogue item property
:return: The updated property
"""

logger.info(
"Updating property with ID: %s inside catalogue category with ID: %s in the database",
catalogue_item_property_id,
property_id,
catalogue_category_id,
)

catalogue_item_property_data = catalogue_item_property.model_dump(by_alias=True)
property_data = property_in.model_dump(by_alias=True)
self._catalogue_categories_collection.update_one(
{
"_id": CustomObjectId(catalogue_category_id),
"catalogue_item_properties._id": CustomObjectId(catalogue_item_property_id),
"properties._id": CustomObjectId(property_id),
},
{
"$set": {
"catalogue_item_properties.$[elem]": catalogue_item_property_data,
"properties.$[elem]": property_data,
"modified_time": datetime.now(timezone.utc),
}
},
array_filters=[{"elem._id": CustomObjectId(catalogue_item_property_id)}],
array_filters=[{"elem._id": CustomObjectId(property_id)}],
session=session,
)
return CatalogueItemPropertyOut(**catalogue_item_property_data)
return CategoryPropertyOut(**property_data)
4 changes: 2 additions & 2 deletions inventory_management_system_api/repositories/unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def _is_unit_in_catalogue_category(self, unit_id: str, session: ClientSession =
"""
unit_id = CustomObjectId(unit_id)

# Query for documents where 'unit_id' exists in the nested 'catalogue_item_properties' list
query = {"catalogue_item_properties.unit_id": unit_id}
# Query for documents where 'unit_id' exists in the nested 'properties' list
query = {"properties.unit_id": unit_id}

return self._catalogue_categories_collection.find_one(query, session=session) is not None
Loading