barker/barker/barker/routers/voucher/__init__.py

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