barker/barker/barker/routers/voucher/show.py

215 lines
7.0 KiB
Python

import re
import uuid
from datetime import datetime, timedelta
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy import and_, or_
from sqlalchemy.orm import Session
from ...core.config import settings
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from ...models.food_table import FoodTable
from ...models.guest_book import GuestBook
from ...models.overview import Overview
from ...models.product_version import ProductVersion
from ...models.voucher import Voucher
from ...models.voucher_type import VoucherType
from ...schemas.user_token import UserToken
router = APIRouter()
# Dependency
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.get("/from-id/{id_}")
def from_id(
id_: str,
db: Session = Depends(get_db),
user: UserToken = Security(get_user),
):
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
return voucher_info(item, db)
@router.get("/from-bill/{id_}")
def from_bill(
id_: str,
db: Session = Depends(get_db),
user: UserToken = Security(get_user),
):
item: Voucher = db.query(Voucher)
if re.compile(r"^\d{2,}-\d{4}$").match(id_):
item = item.filter(
Voucher.bill_id == int(id_.replace("-", "")), Voucher.voucher_type == VoucherType.REGULAR_BILL
)
elif re.compile(r"^K-\d+$").match(id_):
item = item.filter(
Voucher.kot_id == int(id_.replace("K-", "")),
Voucher.voucher_type == VoucherType.KOT,
)
elif re.compile(r"^NC-\d+$").match(id_):
item = item.filter(
Voucher.bill_id == int(id_.replace("NC-", "")),
Voucher.voucher_type == VoucherType.NO_CHARGE,
)
elif re.compile(r"^ST-\d+$").match(id_):
item = item.filter(
Voucher.bill_id == int(id_.replace("ST-", "")),
Voucher.voucher_type == VoucherType.STAFF,
)
else:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Bill Number is invalid",
)
item = item.first()
if item is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Bill not found",
)
return voucher_info(item, db)
@router.get("/from-table/{id_}")
def from_table(
id_: str, # table id
v: Optional[uuid.UUID] = None, # voucher id
g: Optional[uuid.UUID] = None, # guest id
db: Session = Depends(get_db),
user: UserToken = Security(get_user),
):
if v is not None:
item = (
db.query(Overview)
.filter(
Overview.voucher_id == v,
Overview.food_table_id == id_,
)
.first()
)
if item is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Voucher not found",
)
else:
return voucher_info(item.voucher, db)
table = db.query(FoodTable).filter(FoodTable.id == id_).first()
if g is not None:
guest = db.query(GuestBook).filter(GuestBook.id == g).first()
else:
guest = None
return voucher_blank(table, guest)
def voucher_product(product_id: uuid.UUID, date_: datetime, is_happy_hour: bool, db: Session):
product_date = (
date_ + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES - settings.NEW_DAY_OFFSET_MINUTES)
).date()
product: ProductVersion = (
db.query(ProductVersion)
.filter(
and_(
ProductVersion.product_id == product_id,
or_(
ProductVersion.valid_from == None, # noqa: E711
ProductVersion.valid_from <= product_date,
),
or_(
ProductVersion.valid_till == None, # noqa: E711
ProductVersion.valid_till >= product_date,
),
)
)
.first()
)
return {
"id": product_id,
"name": ("H H " if is_happy_hour else "") + product.full_name,
"menuCategory": {
"id": product.menu_category_id,
"name": product.menu_category.name,
},
"saleCategory": {
"id": product.sale_category_id,
"name": product.sale_category.name,
"discountLimit": product.sale_category.discount_limit,
},
}
def voucher_info(item: Voucher, db: Session):
return {
"id": item.id,
"date": item.date.strftime("%H:%M"),
"dateTip": item.date.strftime("%d-%b-%Y %H:%M:%S"),
"pax": item.pax,
"user": {"id": item.user_id, "name": item.user.name},
"creationDate": item.creation_date.strftime("%H:%M"),
"creationDateTip": item.creation_date.strftime("%d-%b-%Y %H:%M:%S"),
"lastEditDate": item.last_edit_date.strftime("%H:%M"),
"lastEditDateTip": item.last_edit_date.strftime("%d-%b-%Y %H:%M:%S"),
"kotId": item.kot_id,
"billId": item.full_bill_id,
"table": {"id": item.food_table_id, "name": item.food_table.name},
"customer": {"id": item.customer_id, "name": item.customer.name} if item.customer is not None else None,
"guest": None, # TODO: Wire this functionality
"narration": item.narration, # TODO: Wire this functionality
"reason": item.reason,
"voucherType": item.voucher_type,
"kots": [
{
"id": k.id,
"code": k.code,
"date": k.date.strftime("%d-%b-%Y %H:%M:%S"),
"user": {"id": k.user_id, "name": k.user.name},
"inventories": [
{
"id": i.id,
"sortOrder": i.sort_order,
"product": voucher_product(i.product_id, item.date, i.is_happy_hour, db),
"quantity": i.quantity,
"price": i.price,
"isHappyHour": i.is_happy_hour,
"taxRate": i.tax_rate,
"tax": {"id": i.tax_id, "name": i.tax.name},
"discount": i.discount,
"modifiers": [
{
"id": m.modifier.id,
"name": m.modifier.name,
"price": m.price,
}
for m in i.modifiers
],
}
for i in k.inventories
],
}
for k in item.kots
],
}
def voucher_blank(table: FoodTable, guest: Optional[GuestBook]):
return {
"pax": table.seats if guest is None else guest.pax,
"table": {"id": table.id, "name": table.name},
"voucherType": VoucherType.KOT,
"customer": {"id": guest.customer_id, "name": guest.customer.name} if guest is not None else None,
"kots": [],
}