class Product(db.Model): """Product database class.""" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), unique=True, nullable=False) category_id = db.Column(db.Integer, db.ForeignKey("category.id")) price = db.Column(db.Numeric(scale=2), nullable=False) image = db.Column(db.String(40), nullable=False) quantity = db.Column(db.Integer, nullable=False) quantity_in_cart = db.Column(db.Integer, default=0, nullable=False) date_created = db.Column(db.DateTime, default=datetime.utcnow) created_by_id = db.Column(db.Integer, db.ForeignKey("user.id")) carts = db.relationship("Cart", secondary="product_cart_link") def __repr__(self): """Return name and price for Product.""" return f"Product('{self.name}', '{self.category}','{self.price}')" def __str__(self): """Return name and price for Product.""" return f"Product('{self.name}', '{self.category}', '{self.price}')" def remove_quantity(self, quantity): """Decrement product quantity.""" if self.quantity >= quantity: self.quantity -= quantity self.quantity_in_cart += quantity return quantity return 0 def add_quantity(self, quantity): self.quantity += quantity self.quantity_in_cart -= quantity return quantity
class ProductCartLink(db.Model): """ProductCartLink many-to-many database class.""" id = db.Column(db.Integer, primary_key=True) product_id = db.Column(db.Integer, db.ForeignKey("product.id")) cart_id = db.Column(db.Integer, db.ForeignKey("cart.id")) product = db.relationship("Product", backref=backref("link", cascade="all, delete-orphan")) cart = db.relationship("Cart", backref=backref("link", cascade="all, delete-orphan"))
class Order(db.Model): """Order database class.""" id = db.Column(db.Integer, primary_key=True) number = db.Column(db.String, unique=True, nullable=True) user_id = db.Column(db.Integer, db.ForeignKey("user.id")) def generate_number(self): """Generate order number.""" self.number = secrets.token_hex(4) return self.number
class Cart(db.Model): """Cart database class.""" id = db.Column(db.Integer, primary_key=True) products = db.relationship("Product", secondary="product_cart_link") quantity = db.Column(db.Integer, default=0, nullable=False) subtotal = db.Column(db.Numeric(scale=2), default=0, nullable=False) user_id = db.Column(db.Integer, db.ForeignKey("user.id")) def __repr__(self): """Return quantity and subtotal for Cart.""" return f"Cart('Quantity: {self.quantity}', '${self.subtotal}', '{self.products})" def __str__(self): """Return quantity and subtotal for Cart.""" return f"Cart('Quantity: {self.quantity}', '${self.subtotal}', '{self.products}')" def add(self, product, quantity=1): """Add given product to cart.""" added_quantity = product.remove_quantity(quantity) if added_quantity: self.products.append(product) self.quantity += added_quantity self.subtotal += product.price * added_quantity return self def remove(self, product): """Remove given product from cart.""" self.products.pop(self.products.index(product)) quantity = product.add_quantity(product.quantity_in_cart) self.quantity -= quantity self.subtotal -= product.price * quantity return self def remove_all(self): """Remove all products from cart.""" for product in self.products: product.add_quantity(product.quantity_in_cart) self.products = [] self.quantity = 0 self.subtotal = 0 return self def checkout(self): """Checkout cart.""" for product in self.products: product.quantity_in_cart = 0 self.products = [] self.quantity = 0 self.subtotal = 0 return self
class Category(db.Model): """Product Category database class.""" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(20), unique=True, nullable=False) link = db.Column(db.String(20), nullable=True) products = db.relationship("Product", backref="category", lazy=True) date_created = db.Column(db.DateTime, default=datetime.utcnow) created_by_id = db.Column(db.Integer, db.ForeignKey("user.id")) def __repr__(self): """Return name for Category.""" return f"Category('{self.name}', '{self.link}')" def __str__(self): """Return name for Category.""" return self.name def add_link(self): """Add link based on category name.""" self.link = self.name.lower().replace(" ", "-") return self.link