barker/barker/barker/routers/voucher/merge_move.py

178 lines
5.8 KiB
Python

import uuid
from datetime import datetime
from typing import List
import barker.schemas.merge_move as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy import func
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from ...models.master import VoucherType
from ...models.voucher import Kot, Overview, Settlement, Voucher
from ...routers.voucher import do_update_settlements, do_update_table, get_bill_id
from ...schemas.user_token import UserToken
router = APIRouter()
# Dependency
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.post("/move-kot/merge")
def merge_kot(
data: schemas.MergeKot,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["merge-kots"]),
):
try:
check_if_voucher_is_unprinted(data.voucher_id, db)
kots: int = db.query(func.count(Kot.id)).filter(Kot.voucher_id == data.voucher_id).scalar()
if kots <= 1:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Single kot cannot be used, move table instead. This error should not show up in frontend",
)
check_if_voucher_is_unprinted(data.new_voucher_id, db)
db.query(Kot).filter(Kot.id == data.kot_id, Kot.voucher_id == data.voucher_id).update(
{Kot.voucher_id: data.new_voucher_id}
)
update_settlements([data.voucher_id, data.new_voucher_id], db)
db.commit()
except SQLAlchemyError as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
)
except Exception:
db.rollback()
raise
@router.post("/move-kot/move")
def move_kot(
data: schemas.MoveKot,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["move-kot-to-new-table"]),
):
try:
now = datetime.now()
check_if_voucher_is_unprinted(data.voucher_id, db)
kots: int = db.query(func.count(Kot.id)).filter(Kot.voucher_id == data.voucher_id).scalar()
if kots <= 1:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Single kot cannot be used, move table instead. This error should not show up in frontend",
)
kot = db.query(Kot).filter(Kot.id == data.kot_id).first()
bill_id = get_bill_id(kot.voucher.voucher_type, db)
kot_id = db.query(func.coalesce(func.max(Voucher.kot_id), 0) + 1).scalar()
item = Voucher(
now,
kot.voucher.pax,
bill_id,
kot_id,
data.table_id,
kot.voucher.customer_id if kot.voucher.customer is not None else None,
kot.voucher.voucher_type,
user.id_,
)
db.add(item)
item.kots.append(kot)
db.flush()
do_update_table(item, None, db)
update_settlements([data.voucher_id, item.id], db)
db.commit()
except SQLAlchemyError as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
)
except Exception:
db.rollback()
raise
@router.post("/move-table/move")
def move_table(
data: schemas.MoveTable,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["move-table"]),
):
try:
db.query(Overview).filter(Overview.voucher_id == data.voucher_id).update(
{Overview.food_table_id: data.table_id}
)
db.query(Voucher).filter(Voucher.id == data.voucher_id).update({Voucher.food_table_id: data.table_id})
db.commit()
except SQLAlchemyError as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
)
except Exception:
db.rollback()
raise
@router.post("/move-table/merge")
def merge_table(
data: schemas.MergeTable,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["merge-tables"]),
):
try:
check_if_voucher_is_unprinted(data.voucher_id, db)
check_if_voucher_is_unprinted(data.new_voucher_id, db)
db.query(Kot).filter(Kot.voucher_id == data.voucher_id).update({Kot.voucher_id: data.new_voucher_id})
db.query(Overview).filter(Overview.voucher_id == data.voucher_id).delete()
db.query(Settlement).filter(Settlement.voucher_id == data.voucher_id).delete()
db.query(Voucher).filter(Voucher.id == data.voucher_id).delete()
update_settlements([data.new_voucher_id], db)
db.commit()
except SQLAlchemyError as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
)
except Exception:
db.rollback()
raise
def update_settlements(vouchers: List[uuid.UUID], db: Session):
for v in vouchers:
voucher: Voucher = db.query(Voucher).filter(Voucher.id == v).first()
do_update_settlements(voucher, [], db)
def check_if_voucher_is_unprinted(voucher_id: uuid.UUID, db: Session) -> None:
voucher_type: VoucherType = db.query(Voucher.voucher_type).filter(Voucher.id == voucher_id).scalar()
if voucher_type is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Original bill not found",
)
if voucher_type != VoucherType.KOT:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Bill is printed or void.",
)