2017-03-14 12:56:57 +00:00
|
|
|
from datetime import datetime
|
|
|
|
from enum import IntEnum
|
|
|
|
import uuid
|
|
|
|
from decimal import Decimal
|
|
|
|
|
|
|
|
from sqlalchemy.ext.hybrid import hybrid_property
|
|
|
|
from sqlalchemy import Column, Integer, Boolean, Unicode, DateTime, Numeric, ForeignKey, UniqueConstraint, func, case
|
|
|
|
from sqlalchemy.orm import relationship, synonym, backref
|
|
|
|
from barker.models.guidtype import GUID
|
|
|
|
from .meta import Base
|
|
|
|
|
|
|
|
|
|
|
|
class VoucherType(IntEnum):
|
|
|
|
REGULAR_BILL = 1
|
|
|
|
NO_CHARGE = 2
|
|
|
|
TAKE_AWAY = 3
|
|
|
|
STAFF = 4
|
|
|
|
|
|
|
|
|
2019-06-13 19:02:34 +00:00
|
|
|
class GuestBook(Base):
|
|
|
|
__tablename__ = 'guest_book'
|
2017-03-14 12:56:57 +00:00
|
|
|
id = Column('id', GUID(), primary_key=True, default=uuid.uuid4)
|
2019-06-13 19:02:34 +00:00
|
|
|
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)
|
|
|
|
|
|
|
|
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):
|
|
|
|
__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)
|
2017-03-14 12:56:57 +00:00
|
|
|
status = Column('status', Unicode(255), nullable=False)
|
|
|
|
|
|
|
|
voucher = relationship('Voucher', backref=backref('status', uselist=False))
|
2019-06-13 19:02:34 +00:00
|
|
|
food_table = relationship('FoodTable', backref=backref('status', uselist=False))
|
|
|
|
guest = relationship('GuestBook', backref=backref('status', uselist=False))
|
2017-03-14 12:56:57 +00:00
|
|
|
|
2019-06-13 19:02:34 +00:00
|
|
|
def __init__(self, voucher_id, food_table_id, guest_book_id, status):
|
2017-03-14 12:56:57 +00:00
|
|
|
self.voucher_id = voucher_id
|
|
|
|
self.food_table_id = food_table_id
|
2019-06-13 19:02:34 +00:00
|
|
|
self.guest_book_id = guest_book_id
|
2017-03-14 12:56:57 +00:00
|
|
|
self.status = status
|
|
|
|
|
|
|
|
|
|
|
|
class InventoryModifier(Base):
|
|
|
|
__tablename__ = 'inventory_modifiers'
|
|
|
|
__table_args__ = (UniqueConstraint('inventory_id', 'modifier_id'),)
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
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):
|
|
|
|
__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'), nullable=False)
|
|
|
|
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
|
|
|
|
|
|
|
|
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]
|
|
|
|
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
|
|
|
|
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:
|
|
|
|
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)
|
|
|
|
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):
|
|
|
|
__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):
|
|
|
|
__tablename__ = 'settlements'
|
|
|
|
__table_args__ = (UniqueConstraint('voucher_id', 'settled'),)
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
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):
|
|
|
|
__tablename__ = 'reprints'
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
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):
|
|
|
|
__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)
|
2019-06-20 07:45:23 +00:00
|
|
|
tax_rate = Column('tax_rate', Numeric)
|
|
|
|
tax_id = Column('tax_id', GUID(), ForeignKey('taxes.id'), nullable=False)
|
2017-03-14 12:56:57 +00:00
|
|
|
discount = Column('discount', Numeric)
|
|
|
|
sort_order = Column('sort_order', Numeric, nullable=False)
|
|
|
|
|
|
|
|
kot = relationship('Kot', backref='inventories')
|
2019-06-20 07:45:23 +00:00
|
|
|
tax = relationship('Tax', foreign_keys=tax_id)
|
2017-03-14 12:56:57 +00:00
|
|
|
product = relationship('Product', backref='inventories')
|
|
|
|
|
2019-06-20 07:45:23 +00:00
|
|
|
def __init__(self, kot_id, product_id, quantity, price, discount, is_hh, tax_id, tax_rate,
|
2019-06-13 19:02:34 +00:00
|
|
|
sort_order):
|
2017-03-14 12:56:57 +00:00
|
|
|
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
|
2019-06-20 07:45:23 +00:00
|
|
|
self.tax_id = tax_id
|
|
|
|
self.tax_rate = tax_rate
|
2017-03-14 12:56:57 +00:00
|
|
|
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):
|
|
|
|
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
|
|
|
|
def st_amount(self):
|
|
|
|
return self.net_taxable * self.service_tax_rate
|
|
|
|
|
|
|
|
@hybrid_property
|
|
|
|
def vat_amount(self):
|
|
|
|
return self.net_taxable * self.vat_rate
|
|
|
|
|
|
|
|
@hybrid_property
|
|
|
|
def amount(self):
|
2019-06-13 19:02:34 +00:00
|
|
|
return Decimal(self.net * (1 + self.service_tax_rate + self.vat_rate))
|
2017-03-14 12:56:57 +00:00
|
|
|
|
|
|
|
@amount.expression
|
|
|
|
def amount(cls):
|
2019-06-13 19:02:34 +00:00
|
|
|
return cls.net * (1 + cls.service_tax_rate + cls.vat_rate)
|