barker/barker/models/voucher.py

334 lines
10 KiB
Python
Raw Normal View History

from datetime import datetime
from enum import IntEnum
import uuid
from decimal import Decimal
from sqlalchemy.ext.hybrid import hybrid_property
2019-07-13 16:02:18 +00:00
from sqlalchemy import (
Column,
Integer,
Boolean,
Unicode,
DateTime,
Numeric,
ForeignKey,
UniqueConstraint,
func,
case,
)
from sqlalchemy.orm import relationship, backref
from barker.models.guidtype import GUID
from .meta import Base
class VoucherType(IntEnum):
2019-07-13 16:02:18 +00:00
KOT = 0
REGULAR_BILL = 1
NO_CHARGE = 2
STAFF = 4
class GuestBook(Base):
2019-07-13 16:02:18 +00:00
__tablename__ = "guest_book"
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
customer_id = Column(
"customer_id", GUID(), ForeignKey("customers.id"), nullable=False
)
pax = Column("pax", Numeric, nullable=False)
date = Column("creation_date", DateTime(timezone=True), nullable=False)
2019-07-13 16:02:18 +00:00
customer = relationship("Customer")
def __init__(self, customer_id=None, pax=None, id_=None):
self.customer_id = customer_id
self.pax = pax
self.id = id_
self.date = datetime.utcnow()
class Overview(Base):
2019-07-13 16:02:18 +00:00
__tablename__ = "overview"
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
voucher_id = Column("voucher_id", GUID(), ForeignKey("vouchers.id"), unique=True)
food_table_id = Column(
"food_table_id", GUID(), ForeignKey("food_tables.id"), unique=True
)
guest_book_id = Column(
"guest_book_id", GUID(), ForeignKey("guest_book.id"), unique=True
)
status = Column("status", Unicode(255), nullable=False)
voucher = relationship("Voucher", backref=backref("status", uselist=False))
food_table = relationship("FoodTable", backref=backref("status", uselist=False))
guest = relationship("GuestBook", backref=backref("status", uselist=False))
def __init__(self, voucher_id, food_table_id, guest_book_id, status):
self.voucher_id = voucher_id
self.food_table_id = food_table_id
self.guest_book_id = guest_book_id
self.status = status
class InventoryModifier(Base):
2019-07-13 16:02:18 +00:00
__tablename__ = "inventory_modifiers"
__table_args__ = (UniqueConstraint("inventory_id", "modifier_id"),)
2019-07-13 16:02:18 +00:00
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
inventory_id = Column(
"inventory_id", GUID(), ForeignKey("inventories.id"), nullable=False
)
modifier_id = Column(
"modifier_id", GUID(), ForeignKey("modifiers.id"), nullable=False
)
price = Column("price", Numeric, nullable=False)
2019-07-13 16:02:18 +00:00
inventory = relationship("Inventory", backref="modifiers")
modifier = relationship("Modifier")
def __init__(self, inventory_id, modifier_id, price):
self.inventory_id = inventory_id
self.modifier_id = modifier_id
self.price = price
class Voucher(Base):
2019-07-13 16:02:18 +00:00
__tablename__ = "vouchers"
__table_args__ = (UniqueConstraint("bill_id", "voucher_type"),)
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
date = Column("date", DateTime, nullable=False, index=True)
pax = Column("pax", Numeric, nullable=False)
bill_id = Column("bill_id", Numeric)
kot_id = Column("kot_id", Numeric, nullable=False, unique=True)
creation_date = Column("creation_date", DateTime(timezone=True), nullable=False)
last_edit_date = Column("last_edit_date", DateTime(timezone=True), nullable=False)
food_table_id = Column(
"food_table_id", GUID(), ForeignKey("food_tables.id"), nullable=False
)
customer_id = Column("customer_id", GUID(), ForeignKey("customers.id"))
narration = Column("narration", Unicode(1000), nullable=False)
is_void = Column("is_void", Boolean, nullable=False)
void_reason = Column("void_reason", Unicode(255))
is_printed = Column("is_printed", Boolean, nullable=False)
voucher_type = Column("voucher_type", Integer, nullable=False)
user_id = Column("user_id", GUID(), ForeignKey("users.id"), nullable=False)
user = relationship("User", backref="vouchers")
food_table = relationship("FoodTable", backref="vouchers")
customer = relationship("Customer", backref="vouchers")
kots = relationship(
"Kot",
backref="voucher",
cascade="delete, delete-orphan",
cascade_backrefs=False,
)
settlements = relationship(
"Settlement",
backref="voucher",
cascade="delete, delete-orphan",
cascade_backrefs=False,
)
reprints = relationship(
"Reprint",
backref="voucher",
cascade="delete, delete-orphan",
cascade_backrefs=False,
)
@property
def __name__(self):
return self.name
2019-07-13 16:02:18 +00:00
def __init__(
self,
pax,
food_table_id,
customer_id,
is_printed,
voucher_type,
user_id,
dbsession,
):
now = datetime.now()
self.date = now
self.pax = pax
if is_printed:
type = [1, 3] if voucher_type in [1, 3] else [voucher_type]
2019-07-13 16:02:18 +00:00
self.bill_id = (
dbsession.query(func.coalesce(func.max(Voucher.bill_id), 0) + 1)
.filter(Voucher.voucher_type.in_(type))
.scalar()
)
self.kot_id = dbsession.query(
func.coalesce(func.max(Voucher.kot_id), 0) + 1
).scalar()
self.creation_date = now
self.last_edit_date = now
self.food_table_id = food_table_id
self.customer_id = customer_id
2019-07-13 16:02:18 +00:00
self.narration = ""
self.is_void = False
self.void_reason = None
self.is_printed = is_printed
self.voucher_type = voucher_type
self.user_id = user_id
@property
def full_bill_id(self):
if self.bill_id is None:
2019-07-13 16:02:18 +00:00
return "K-" + str(self.kot_id)
if self.voucher_type == VoucherType.NO_CHARGE.value:
return "NC-" + str(self.bill_id)
if self.voucher_type == VoucherType.STAFF.value:
return "ST-" + str(self.bill_id)
2019-07-13 16:02:18 +00:00
if self.voucher_type in [
VoucherType.TAKE_AWAY.value,
VoucherType.REGULAR_BILL.value,
]:
return str(self.bill_id // 10000) + "-" + str(self.bill_id % 10000)
else:
raise Exception
class Kot(Base):
2019-07-13 16:02:18 +00:00
__tablename__ = "kots"
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
voucher_id = Column(
"voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False, index=True
)
code = Column("code", Numeric, nullable=False, unique=True)
food_table_id = Column(
"food_table_id", GUID(), ForeignKey("food_tables.id"), nullable=False
)
date = Column("date", DateTime, nullable=False, index=True)
user_id = Column("user_id", GUID(), ForeignKey("users.id"), nullable=False)
user = relationship("User", backref="kots")
food_table = relationship("FoodTable", backref="kots")
def __init__(
self,
voucher_id=None,
food_table_id=None,
date=None,
user_id=None,
id=None,
dbsession=None,
):
self.id = id
self.voucher_id = voucher_id
self.code = dbsession.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar()
self.food_table_id = food_table_id
self.date = date
self.user_id = user_id
class Settlement(Base):
2019-07-13 16:02:18 +00:00
__tablename__ = "settlements"
__table_args__ = (UniqueConstraint("voucher_id", "settled"),)
2019-07-13 16:02:18 +00:00
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
voucher_id = Column(
"voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False, index=True
)
settled = Column("settled", ForeignKey("settle_options.id"), nullable=False)
amount = Column("amount", Numeric, nullable=False)
2019-07-13 16:02:18 +00:00
settle_option = relationship("SettleOption")
def __init__(self, voucher_id=None, settled=None, amount=None, id=None):
self.id = id
self.voucher_id = voucher_id
self.settled = settled
self.amount = amount
class Reprint(Base):
2019-07-13 16:02:18 +00:00
__tablename__ = "reprints"
2019-07-13 16:02:18 +00:00
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
date = Column("date", DateTime, nullable=False, index=True)
voucher_id = Column(
"voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False, index=True
)
user_id = Column("user_id", GUID(), ForeignKey("users.id"), nullable=False)
2019-07-13 16:02:18 +00:00
user = relationship("User", backref="reprints")
def __init__(self, voucher_id=None, user_id=None, id=None):
self.id = id
self.date = datetime.now()
self.voucher_id = voucher_id
self.user_id = user_id
class Inventory(Base):
2019-07-13 16:02:18 +00:00
__tablename__ = "inventories"
__table_args__ = (
UniqueConstraint("kot_id", "product_id", "is_happy_hour", "price"),
)
id = Column("id", GUID(), primary_key=True, default=uuid.uuid4)
kot_id = Column("kot_id", GUID(), ForeignKey("kots.id"), nullable=False, index=True)
product_id = Column("product_id", GUID(), ForeignKey("products.id"), nullable=False)
quantity = Column("quantity", Numeric)
price = Column("price", Numeric)
is_happy_hour = Column("is_happy_hour", Boolean, nullable=False)
tax_rate = Column("tax_rate", Numeric)
tax_id = Column("tax_id", GUID(), ForeignKey("taxes.id"), nullable=False)
discount = Column("discount", Numeric)
sort_order = Column("sort_order", Numeric, nullable=False)
kot = relationship("Kot", backref="inventories")
tax = relationship("Tax", foreign_keys=tax_id)
product = relationship("Product", backref="inventories")
def __init__(
self,
kot_id,
product_id,
quantity,
price,
discount,
is_hh,
tax_id,
tax_rate,
sort_order,
):
self.kot_id = kot_id
self.product_id = product_id
self.quantity = quantity
self.price = price
self.discount = discount
self.is_happy_hour = is_hh
self.tax_id = tax_id
self.tax_rate = tax_rate
self.sort_order = sort_order
@hybrid_property
def effective_price(self):
return 0 if self.is_happy_hour == True else self.price
@effective_price.expression
def effective_price(cls):
2019-07-13 16:02:18 +00:00
return case([(cls.is_happy_hour == True, 0)], else_=cls.price)
@hybrid_property
def net(self):
return self.effective_price * self.quantity * (1 - self.discount)
@hybrid_property
2019-07-13 16:02:18 +00:00
def tax_amount(self):
return self.net_taxable * self.tax_rate
@hybrid_property
def amount(self):
2019-07-13 16:02:18 +00:00
return Decimal(self.net * (1 + self.tax_rate))
@amount.expression
def amount(cls):
2019-07-13 16:02:18 +00:00
return cls.net * (1 + cls.tax_rate)