barker/barker/barker/routers/voucher/change.py

92 lines
2.9 KiB
Python

import uuid
from decimal import Decimal
from typing import Optional
from fastapi import APIRouter, HTTPException, status, Depends, Security
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
from .save import do_save
from ...schemas.auth import UserToken
import barker.schemas.voucher as schemas
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from ...models import Voucher, SettleOption, Overview, Reprint
from ...routers.voucher import (
do_update_settlements,
get_guest_book,
)
from barker.schemas.receive_payment import ReceivePaymentItem as SettleSchema
router = APIRouter()
# Dependency
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.put("/change/{id_}")
def change(
id_: uuid.UUID,
data: schemas.VoucherIn,
u: bool, # Update table?
g: Optional[uuid.UUID] = None, # Guest book id
db: Session = Depends(get_db),
user: UserToken = Security(get_user),
):
try:
old: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
amount_changed: bool = old.amount != round(
sum(
Decimal((0 if i.is_happy_hour else i.price) * i.quantity * (1 - i.discount) * (1 + i.tax_rate))
for k in data.kots
for i in k.inventories
),
2,
)
items_changed: bool = len([i for k in old.kots for i in k.inventories]) != len(
[i for k in data.kots for i in k.inventories]
)
if amount_changed or items_changed:
void_and_issue_new_bill(data, u, g, old, db, user)
else:
reprint_bill(id_, user.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 reprint_bill(voucher_id: uuid.UUID, user_id: uuid.UUID, db: Session):
item = Reprint(voucher_id=voucher_id, user_id=user_id)
db.add(item)
def void_and_issue_new_bill(
data: schemas.VoucherIn, u: bool, g: Optional[uuid.UUID], old: Voucher, db: Session, user: UserToken
):
update_table = u
guest_book = get_guest_book(g, db)
item = do_save(data, old.voucher_type, guest_book, db, user)
db.flush()
old.void = True
old.void_reason = f"Bill Discounted / Changed. New Bill ID is {item.full_bill_id}"
do_update_settlements(old, [SettleSchema(id=SettleOption.VOID(), amount=round(old.amount))], db)
if update_table:
if old.status is None:
item.status = Overview(voucher_id=None, food_table_id=item.food_table_id, status="printed")
db.add(item.status)
else:
db.query(Overview).filter(Overview.voucher_id == old.id).update({Overview.voucher_id: item.id})