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})