import uuid from sqlalchemy import ( UniqueConstraint, Column, Unicode, Numeric, Boolean, ForeignKey, Integer, case, JSON, Table, ) from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.orm import relationship from .meta import Base from sqlalchemy.dialects.postgresql import UUID class Customer(Base): __tablename__ = "customers" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) company = Column("company", Unicode(255), nullable=False) name = Column("name", Unicode(255), nullable=False) phone = Column("phone", Unicode(255), nullable=True, unique=True) address = Column("address", Unicode(255), nullable=False) @property def __name__(self): return self.name def __init__(self, company=None, name=None, phone=None, address=None, id_=None): self.company = company self.name = name self.phone = phone self.address = address self.id = id_ @classmethod def cash(cls): return uuid.UUID("2c716f4b-0736-429a-ad51-610d7c47cb5e") class FoodTable(Base): __tablename__ = "food_tables" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column("name", Unicode(255), nullable=False, unique=True) seats = Column("seats", Integer, nullable=False) section_id = Column("section_id", UUID(as_uuid=True), ForeignKey("sections.id"), nullable=False) is_active = Column("is_active", Boolean, nullable=False) sort_order = Column("sort_order", Integer, nullable=False) section = relationship("Section", foreign_keys=section_id) @property def __name__(self): return self.name def __init__( self, name=None, seats=None, section_id=None, is_active=None, sort_order=0, id_=None, ): self.name = name self.seats = seats self.section_id = section_id self.is_active = is_active self.sort_order = sort_order self.id = id_ class Tax(Base): __tablename__ = "taxes" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column("name", Unicode(255), nullable=False, unique=True) rate = Column("rate", Numeric, nullable=False) is_fixture = Column("is_fixture", Boolean, nullable=False) def __init__(self, name=None, rate=None, is_fixture=False, id_=None): self.name = name self.rate = rate self.is_fixture = is_fixture self.id = id_ class MenuCategory(Base): __tablename__ = "menu_categories" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column("name", Unicode(255), nullable=False, unique=True) discount_limit = Column("discount_limit", Numeric, nullable=False) is_active = Column("is_active", Boolean, nullable=False) is_fixture = Column("is_fixture", Boolean, nullable=False) sort_order = Column("sort_order", Integer, nullable=False) def __init__(self, name, discount_limit, is_active, sort_order, is_fixture=False, id_=None): self.name = name self.discount_limit = discount_limit self.is_active = is_active self.sort_order = sort_order self.is_fixture = is_fixture self.id = id_ class SaleCategory(Base): __tablename__ = "sale_categories" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column("name", Unicode(255), nullable=False, unique=True) tax_id = Column("tax_id", UUID(as_uuid=True), ForeignKey("taxes.id"), nullable=False) tax = relationship("Tax", foreign_keys=tax_id) def __init__(self, name, tax_id=False, id_=None): self.name = name self.tax_id = tax_id self.id = id_ class Product(Base): __tablename__ = "products" __table_args__ = (UniqueConstraint("name", "units"),) id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) 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, 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, nullable=False) is_active = Column("is_active", Boolean, nullable=False) sort_order = Column("sort_order", Integer, nullable=False) menu_category = relationship("MenuCategory", backref="products") sale_category = relationship("SaleCategory", backref="products") modifier_categories = relationship( "ModifierCategory", secondary="modifier_categories_products", order_by="ModifierCategory.sort_order", backref="products", ) def __init__( self, name=None, units=None, menu_category_id=None, sale_category_id=None, price=None, has_happy_hour=None, is_not_available=None, quantity=None, is_active=None, sort_order=0, id_=None, ): 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.is_active = is_active 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, "" modifier_categories_products = Table( "modifier_categories_products", Base.metadata, Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4), Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False), Column("modifier_categories_id", UUID(as_uuid=True), ForeignKey("modifier_categories.id"), nullable=False,), UniqueConstraint("product_id", "modifier_categories_id"), ) class ModifierCategory(Base): __tablename__ = "modifier_categories" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column("name", Unicode(255), nullable=False, unique=True) minimum = Column("minimum", Integer, nullable=False) maximum = Column("maximum", Integer, nullable=True) is_active = Column("is_active", Boolean, nullable=False) sort_order = Column("sort_order", Integer, nullable=False) def __init__( self, name=None, minimum=None, maximum=None, is_active=True, sort_order=0, id_=None, ): self.id = id_ self.name = name self.minimum = minimum self.maximum = maximum self.is_active = is_active self.sort_order = sort_order class Modifier(Base): __tablename__ = "modifiers" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column("name", Unicode(255), nullable=False, unique=True) show_in_bill = Column("show_in_bill", Boolean, nullable=False) price = Column("price", Numeric, nullable=False) is_active = Column("is_active", Boolean, nullable=False) modifier_category_id = Column("modifier_category_id", UUID(as_uuid=True), ForeignKey("modifier_categories.id"), nullable=False,) modifier_category = relationship("ModifierCategory", backref="modifiers") def __init__( self, name=None, show_in_bill=None, price=None, modifier_category_id=None, is_active=True, id_=None, ): self.id = id_ self.name = name self.show_in_bill = show_in_bill self.price = price self.modifier_category_id = modifier_category_id self.is_active = is_active class DbSetting(Base): __tablename__ = "settings" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column("name", Unicode(255), unique=True, nullable=False) data = Column("data", JSON) def __init__(self, id_=None, name=None, data=None): self.id = id_ self.name = name self.data = data class Section(Base): __tablename__ = "sections" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column("name", Unicode(255), unique=True, nullable=False) def __init__(self, name=None, id_=None): self.id = id_ self.name = name class Device(Base): __tablename__ = "devices" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column("name", Unicode(255), unique=True, nullable=False) section_id = Column("section_id", UUID(as_uuid=True), ForeignKey("sections.id"), nullable=False) section = relationship("Section", foreign_keys=section_id) def __init__(self, name=None, section_id=None, id_=None): self.name = name self.section_id = section_id self.id = id_ class Printer(Base): __tablename__ = "printers" id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column("name", Unicode(255), unique=True, nullable=False) address = Column("address", Unicode(255), unique=True, nullable=False) cut_code = Column("cut_code", Unicode(255), nullable=False) def __init__(self, name=None, address=None, cut_code=None, id_=None): self.id = id_ self.name = name self.address = address self.cut_code = cut_code class SectionPrinter(Base): __tablename__ = "section_printers" __table_args__ = (UniqueConstraint("menu_category_id", "section_id"),) id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) menu_category_id = Column("menu_category_id", UUID(as_uuid=True), ForeignKey("menu_categories.id")) section_id = Column("section_id", UUID(as_uuid=True), ForeignKey("sections.id"), nullable=False) printer_id = Column("printer_id", UUID(as_uuid=True), ForeignKey("printers.id"), nullable=False) copies = Column("copies", Integer, nullable=False) menu_category = relationship("MenuCategory", backref="section_printers") section = relationship("Section", backref="section_printers") printer = relationship("Printer", backref="section_printers") def __init__(self, menu_category_id=None, section_id=None, printer_id=None, copies=None, id_=None): self.id = id_ self.menu_category_id = menu_category_id self.section_id = section_id self.printer_id = printer_id self.copies = copies class SettleOption(Base): __tablename__ = "settle_options" id = Column("id", Integer, primary_key=True) name = Column("name", Unicode(255), unique=True, nullable=False) show_in_choices = Column("show_in_choices", Boolean, nullable=False) display_group = Column("display_group", Integer, nullable=False) is_print = Column("is_print", Boolean, nullable=False) def __init__(self, name=None, show_in_choices=None, display_group=None, is_print=None, id_=None): self.id = id_ self.name = name self.show_in_choices = show_in_choices self.display_group = display_group self.is_print = is_print @classmethod def UNSETTLED(cls): return 1 @classmethod def CASH(cls): return 2 @classmethod def CREDIT_CARD(cls): return 3 @classmethod def NO_CHARGE(cls): return 4 @classmethod def BILL_TO_COMPANY(cls): return 5 @classmethod def TIP(cls): return 6 @classmethod def ROUND_OFF(cls): return 7 @classmethod def AMOUNT(cls): return 8 @classmethod def VOID(cls): return 9 @classmethod def STAFF(cls): return 10