import sqlmodel from .exception import validator_exception from .validator import name_validator from .validator import description_validator class product(sqlmodel.SQLModel, table = True): """ This class is product model in database. Product is item, which could be shared. """ """ ID of the product in the database. """ id: int | None = sqlmodel.Field(default = None, primary_key = True) """ Name of the product, or title of the book. """ name: str | None = sqlmodel.Field(default = None, index = True) """ Description of the product, provided by creator. """ description: str | None = sqlmodel.Field(default = None) """ Author of the product. """ author: str | None = sqlmodel.Field(default = None) """ Link to image of the product. """ image: str | None = sqlmodel.Field(default = None) """ Count of instances this products in stock. """ stock_count: int = sqlmodel.Field(default = 0) """ This is barcode (EAN) of the product. """ badcode: str | None = sqlmodel.Field( default = None, index = True, unique = True ) @property def in_database(self) -> bool: """ This return True when product exists in database. """ return self.id is not None def __str__(self) -> str: """ This dump product to string, which is helpfull when debug. Returns: (str): Product as string dump """ content = str(self.name) + " " + str(self.id or "") + "\n" content = content + "Description: " + str(self.description) + "\n" content = content + "Author: " + str(self.author) + "\n" content = content + "Barcode (EAN): " + str(self.barcode) + "\n" content = content + "Image (link): " + str(self.image) + "\n" content = content + "In stock: " + str(self.stock_count) + "\n" return content @property def ready(self) -> bool: """ Check that product is ready to insert into database. """ if name is None or description is None: return False if barcode is None or author is None: return False return True class product_builder: """ This is builder of the product. It helps to handle validation of the product params, and modify exists product with validators. """ def __init__(self, target: product | None = None) -> None: """ This create new builder. When get already created item, it work on given once. When receive None, create new product to work on. Parameters: target (product | None): Item to work on (default: None) """ if target is not None: self.__target = target return self.__target = product() @property def ready(self) -> bool: """ It return True when target is ready to insert into database. """ return self.__target.ready @property def result(self) -> product: """ It return ready product, or raise Exception if not Ready yet. """ if not self.__target.ready: raise Exception("Product in builder is not ready yet.") return self.__target @property def name(self) -> str | None: """ It return name of the product. """ return self.__target.name @name.setter def name(self, target: str) -> None: """ It set name of the product, and validating it. """ if name_validator(target).invalid: raise validator_exception("product.name") self.__target.name = target @property def description(self) -> str | None: """ This return product description. """ return self.__target.description @description.setter def description(self, target: str) -> None: """ This set description of the product, and validate it.""" if description_validator(target).invalid: raise validator_exception("product.description") self.__target.description = target @property def barcode(self) -> str | None: """ It return barcode of building product. """ return self.__target.badcode @barcode.setter def barcode(self, target: str) -> None: """ This set new barcode, and validate it. """ if barcode_validator(target).invalid: raise validator_exception("product.barcode") self.__target.badcode = barcode