156 lines
5.8 KiB
Python
156 lines
5.8 KiB
Python
import uuid
|
|
|
|
from decimal import Decimal
|
|
from typing import List, Optional
|
|
|
|
import barker.schemas.voucher as schemas
|
|
|
|
from fastapi import HTTPException, status
|
|
from sqlalchemy import func
|
|
from sqlalchemy.orm import Session
|
|
|
|
from ...models.master import SettleOption, VoucherType
|
|
from ...models.voucher import GuestBook, Overview, Settlement, Voucher
|
|
from ...schemas.receive_payment import ReceivePaymentItem as SettleSchema
|
|
|
|
|
|
def get_tax(tax, voucher_type):
|
|
if voucher_type in [VoucherType.STAFF, VoucherType.NO_CHARGE]:
|
|
return 0
|
|
elif voucher_type in [VoucherType.KOT, VoucherType.REGULAR_BILL]:
|
|
return tax
|
|
else:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
detail="Unexpected Voucher Type",
|
|
)
|
|
|
|
|
|
def get_bill_id(voucher_type: VoucherType, db: Session) -> Optional[int]:
|
|
if voucher_type == VoucherType.KOT:
|
|
return None
|
|
bill_id = (
|
|
db.query(func.coalesce(func.max(Voucher.bill_id), 0) + 1).filter(Voucher.voucher_type == voucher_type).scalar()
|
|
)
|
|
if voucher_type == VoucherType.REGULAR_BILL and bill_id % 10000 == 0:
|
|
bill_id += 1
|
|
return bill_id
|
|
|
|
|
|
def do_update_table(item: Voucher, guest_book: Optional[GuestBook], db: Session):
|
|
status_ = "running" if item.voucher_type == VoucherType.KOT else "printed"
|
|
if item.status is None:
|
|
item.status = Overview(
|
|
voucher_id=item.id,
|
|
food_table_id=item.food_table_id,
|
|
guest_book_id=guest_book.id if guest_book is not None else None,
|
|
status=status_,
|
|
)
|
|
db.add(item.status)
|
|
else:
|
|
item.status.status = status_
|
|
|
|
|
|
def check_permissions(item: Optional[Voucher], voucher_type: VoucherType, permissions: List[str]):
|
|
if voucher_type == VoucherType.KOT and "print-kot" not in permissions:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="You are not allowed to print a kot",
|
|
)
|
|
if voucher_type != VoucherType.KOT and "print-bill" not in permissions:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="You are not allowed to print bill",
|
|
)
|
|
|
|
if item is None:
|
|
return
|
|
if item.voucher_type != VoucherType.KOT and "edit-printed-bill" not in permissions:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="You are not allowed to edit a printed bill",
|
|
)
|
|
|
|
if item.voucher_type != VoucherType.KOT and voucher_type == VoucherType.KOT:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="This Bill is already printed\nCannot add a Kot to it.",
|
|
)
|
|
|
|
if item.voucher_type == VoucherType.VOID:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail=f"This Bill is already void.\nReason: {item.reason}",
|
|
)
|
|
|
|
|
|
def get_guest_book(id_: uuid.UUID, db: Session):
|
|
if id_ is None:
|
|
return id_
|
|
return db.query(GuestBook).filter(GuestBook.id == id_).first()
|
|
|
|
|
|
def do_update_settlements(voucher: Voucher, others: List[SettleSchema], db: Session) -> bool:
|
|
fully_settled = True
|
|
settlements: List[SettleSchema] = []
|
|
settlements += others
|
|
total_amount = voucher.amount
|
|
settlements.append(SettleSchema(id=SettleOption.AMOUNT(), amount=-total_amount))
|
|
round_off = round(total_amount) - total_amount
|
|
if round_off != 0:
|
|
settlements.append(SettleSchema(id=SettleOption.ROUND_OFF(), amount=-round_off))
|
|
unsettled = sum(x.amount for x in settlements)
|
|
if len(others) and unsettled != 0: # This should not be allowed
|
|
raise HTTPException(
|
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
detail="Payment received is not equal to bill amount",
|
|
)
|
|
if unsettled != 0:
|
|
settlements.append(SettleSchema(id=SettleOption.UNSETTLED(), amount=unsettled))
|
|
fully_settled = False
|
|
|
|
for i in settlements:
|
|
old = [s for s in voucher.settlements if s.settled == i.id_]
|
|
if len(old) == 1:
|
|
old[0].amount = i.amount
|
|
else:
|
|
s = Settlement(voucher.id, i.id_, i.amount)
|
|
voucher.settlements.append(s)
|
|
db.add(s)
|
|
|
|
for i in (i for i in voucher.settlements if i.settled not in [x.id_ for x in settlements]):
|
|
voucher.settlements.remove(i)
|
|
db.delete(i)
|
|
return fully_settled
|
|
|
|
|
|
def happy_hour_items_balanced(inventories: List[schemas.Inventory]) -> bool:
|
|
happy = set((i.product.id_, i.quantity) for i in inventories if i.is_happy_hour)
|
|
products = set(i.product.id_ for i in inventories if i.is_happy_hour)
|
|
other = set((i.product.id_, i.quantity) for i in inventories if not i.is_happy_hour and i.product.id_ in products)
|
|
return happy == other
|
|
|
|
|
|
def happy_hour_has_discount(inventories: List[schemas.Inventory]) -> bool:
|
|
happy = set(i.product.id_ for i in inventories if i.is_happy_hour)
|
|
offenders = [i for i in inventories if i.product.id_ in happy and i.discount != 0]
|
|
return len(offenders) > 0
|
|
|
|
|
|
# This is for the whole bill. eg. Kot 1 => Reg 2 + HH 2; Kot 2 => Reg 4; Kot 3 => Reg - 4
|
|
# This is pass okay in happy hours items balanced, but overall this is wrong. Hence this check
|
|
def happy_hour_items_more_than_regular(kots: List[schemas.Kot]) -> bool:
|
|
inventories = {}
|
|
for kot in kots:
|
|
for inventory in kot.inventories:
|
|
if inventory.product.id_ not in inventories:
|
|
inventories[inventory.product.id_] = {"normal": Decimal(0), "happy": Decimal(0)}
|
|
if inventory.is_happy_hour:
|
|
inventories[inventory.product.id_]["happy"] += inventory.quantity
|
|
else:
|
|
inventories[inventory.product.id_]["normal"] += inventory.quantity
|
|
for value in inventories.values():
|
|
if value["happy"] > value["normal"]:
|
|
return True
|
|
return False
|