barker/barker/barker/models/product_version.py

112 lines
3.5 KiB
Python

import uuid
from barker.models.meta import Base
from barker.models.product import Product
from sqlalchemy import (
Boolean,
Column,
Date,
ForeignKey,
Integer,
Numeric,
Unicode,
case,
func,
text,
)
from sqlalchemy.dialects import postgresql
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship
class ProductVersion(Base):
__tablename__ = "product_versions"
id = Column(
"id", UUID(as_uuid=True), primary_key=True, server_default=text("gen_random_uuid()"), default=uuid.uuid4
)
product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False)
name = Column("name", Unicode(255), nullable=False)
units = Column("units", Unicode(255), nullable=False)
menu_category_id = Column(
"menu_category_id",
UUID(as_uuid=True),
ForeignKey("menu_categories.id"),
nullable=False,
)
sale_category_id = Column(
"sale_category_id",
UUID(as_uuid=True),
ForeignKey("sale_categories.id"),
nullable=False,
)
price = Column("price", Numeric(precision=15, scale=2), nullable=False)
has_happy_hour = Column("has_happy_hour", Boolean, nullable=False)
is_not_available = Column("is_not_available", Boolean, nullable=False)
quantity = Column("quantity", Numeric(precision=15, scale=2), nullable=False)
sort_order = Column("sort_order", Integer, nullable=False)
valid_from = Column("valid_from", Date(), nullable=True)
valid_till = Column("valid_till", Date(), nullable=True)
menu_category = relationship("MenuCategory", backref="products")
sale_category = relationship("SaleCategory", backref="products")
product = relationship("Product", back_populates="versions")
inventories = relationship("Inventory", secondary=Product.__table__, back_populates="product", viewonly=True)
__table_args__ = (
postgresql.ExcludeConstraint(
(name, "="),
(units, "="),
(func.daterange(valid_from, valid_till, text("'[]'")), "&&"),
),
)
def __init__(
self,
product_id=None,
name=None,
units=None,
menu_category_id=None,
sale_category_id=None,
price=None,
has_happy_hour=None,
is_not_available=None,
quantity=None,
valid_from=None,
valid_till=None,
sort_order=0,
id_=None,
):
self.product_id = product_id
self.name = name
self.units = units
self.menu_category_id = menu_category_id
self.sale_category_id = sale_category_id
self.price = price
self.has_happy_hour = has_happy_hour
self.is_not_available = is_not_available
self.quantity = quantity
self.valid_from = valid_from
self.valid_till = valid_till
self.sort_order = sort_order
self.id = id_
@hybrid_property
def full_name(self):
return f"{self.name} ({self.units})" if self.units else self.name
@full_name.expression
def full_name(cls):
return cls.name + case([(cls.units != "", " (" + cls.units + ")")], else_="")
def can_delete(self, advanced_delete):
if self.is_fixture:
return False, f"{self.name} is a fixture and cannot be edited or deleted."
if self.is_active:
return False, "Product is active"
if len(self.inventories) > 0 and not advanced_delete:
return False, "Product has entries"
return True, ""