import uuid from datetime import datetime from typing import Optional from fastapi import APIRouter, HTTPException, status, Depends, Security from sqlalchemy import func from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.orm import Session 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, VoucherType, Kot, Product, Inventory, InventoryModifier, GuestBook from ...routers.voucher import ( get_tax, do_update_settlements, get_bill_id, do_update_table, check_permissions, get_guest_book, ) from barker.printing import print_kot, print_bill router = APIRouter() # Dependency def get_db(): try: db = SessionLocal() yield db finally: db.close() @router.post("/save") def save( data: schemas.VoucherIn, u: bool, # Update table? p: str, # Print type g: Optional[uuid.UUID] = None, # Guest book id db: Session = Depends(get_db), user: UserToken = Security(get_user), ): try: update_table = u voucher_type = VoucherType[p] guest_book = get_guest_book(g, db) item: Voucher = do_save(data, voucher_type, guest_book, db, user) if update_table: do_update_table(item, guest_book, db) db.commit() print_kot(item.id, db) if item.voucher_type != VoucherType.KOT: print_bill(item.id, db) 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 do_save( data: schemas.VoucherIn, voucher_type: VoucherType, guest_book: GuestBook, db: Session, user: UserToken, ): now = datetime.now() check_permissions(None, voucher_type, user.permissions) bill_id = get_bill_id(voucher_type, db) kot_id = db.query(func.coalesce(func.max(Voucher.kot_id), 0) + 1).scalar() item = Voucher( now, guest_book.pax if guest_book is not None else data.pax, bill_id, kot_id, data.table.id_, data.customer.id_ if data.customer is not None else None, voucher_type, user.id_, ) db.add(item) for k in data.kots: if not len(k.inventories): continue code = db.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar() kot = Kot(item.id, code, item.food_table_id, item.date, item.user_id) item.kots.append(kot) db.add(kot) for index, i in enumerate(k.inventories): product = db.query(Product).filter(Product.id == i.product.id_).first() tax_rate = get_tax(product.sale_category.tax.rate, voucher_type) inv = Inventory( kot.id, product.id, round(i.quantity, 2), product.price, round(i.discount, 5), i.is_happy_hour, product.sale_category.tax_id, tax_rate, index, ) kot.inventories.append(inv) db.add(inv) for m in i.modifiers: mod = InventoryModifier(None, m.id_, 0) inv.modifiers.append(mod) db.add(mod) db.flush() do_update_settlements(item, [], db) if len(item.kots) == 0 or len(item.kots[0].inventories) == 0: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Please add some products", ) return item