| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 | import sqlmodelfrom .exception import validator_exceptionfrom .validator import name_validatorfrom .validator import description_validatorfrom .validator import barcode_validatorfrom .validator import author_validatorclass 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. """    barcode: 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    @property    def avairable(self) -> bool:        """ This check that item is avairable on stock. """        return self.stock_count > 0    def __str__(self) -> str:        """        This dump product to string, which is helpfull when debug.        Returns:            (str): Product as string dump        """        content = str(self.name) + " "        if self.in_database:            content = content + "#" + str(self.id)        content = content + "\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 self.name is None or self.description is None:             return False        if self.barcode is None or self.author is None:            return False        return True                class product_factory:    """    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    def add_to_stock(self) -> None:        """        This add one item to stock.        """        self.__target.stock_count += 1    def get_from_stock(self) -> bool:        """        This get single item from stock.        Returns:            (bool): True when get success, false when not avairable                """        if not self.__target.avairable:            return False        self.__target.stock_count -= 1        return True    @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.barcode    @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.barcode = target    @property    def author(self) -> str | None:        """ This return author of the product. """        return self.__target.author    @author.setter    def author(self, target: str) -> None:        """ This validate author of the product, and set it. """        if author_validator(target).invalid:            raise validator_exception("product.author")        self.__target.author = target    @property    def image(self) -> str | None:        """ This return image link of the product. """        return self.__target.image    @image.setter    def image(self, target: str | None) -> None:        """ This set image link of the product. """        self.__target.image = target    @property    def stock_count(self) -> int:        """ This return how much product is in stock. """        return self.__target.stock_count    @stock_count.setter    def stock_count(self, target: int) -> None:        """ This set stock count of the product, it mut be positive number. """        if target < 0:            raise validator_exception("product.stock_count")        self.__target.stock_count = target
 |