112 lines
3.5 KiB
Python
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, ""
|