110 lines
3.9 KiB
Python
110 lines
3.9 KiB
Python
import uuid
|
|
|
|
import barker.schemas.voucher as schemas
|
|
|
|
from fastapi import APIRouter, HTTPException, Security, status
|
|
from sqlalchemy import select, update
|
|
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 SessionFuture
|
|
from ...models.overview import Overview
|
|
from ...models.reprint import Reprint
|
|
from ...models.settle_option import SettleOption
|
|
from ...models.voucher import Voucher
|
|
from ...models.voucher_type import VoucherType
|
|
from ...printing.bill import print_bill
|
|
from ...printing.kot import print_kot
|
|
from ...routers.voucher import (
|
|
do_update_bill_numbers,
|
|
do_update_settlements,
|
|
get_guest_book,
|
|
)
|
|
from ...schemas.receive_payment import ReceivePaymentItem as SettleSchema
|
|
from ...schemas.user_token import UserToken
|
|
from .save import do_save
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.put("/change/{id_}")
|
|
def change(
|
|
id_: uuid.UUID,
|
|
data: schemas.VoucherIn,
|
|
u: bool, # Update table?
|
|
g: uuid.UUID | None = None, # Guest book id
|
|
user: UserToken = Security(get_user, scopes=["edit-printed-bill"]),
|
|
):
|
|
try:
|
|
with SessionFuture() as db:
|
|
old: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one()
|
|
if old.voucher_type == VoucherType.VOID:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
detail="Voucher cannot be reprinted. It is already void.",
|
|
)
|
|
bill_changed: bool = (
|
|
len(
|
|
set((i.id, i.amount) for k in old.kots for i in k.inventories)
|
|
^ set((i.id_, i.amount) for k in data.kots for i in k.inventories)
|
|
)
|
|
!= 0
|
|
)
|
|
new_kot: bool = len([k for k in data.kots if k.id_ is None and len(k.inventories) > 0]) > 0
|
|
if bill_changed:
|
|
id_ = void_and_issue_new_bill(data, u, g, old, db, user)
|
|
else:
|
|
if data.customer is not None:
|
|
old.customer_id = data.customer.id_
|
|
else:
|
|
old.customer_id = None
|
|
reprint_bill(id_, user.id_, db)
|
|
db.commit()
|
|
with SessionFuture() as db:
|
|
if bill_changed and new_kot:
|
|
print_kot(id_, db)
|
|
print_bill(id_, db)
|
|
except SQLAlchemyError as e:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=str(e),
|
|
)
|
|
|
|
|
|
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: uuid.UUID | None,
|
|
old: Voucher,
|
|
db: Session,
|
|
user: UserToken,
|
|
) -> uuid.UUID:
|
|
update_table = u
|
|
guest_book = get_guest_book(g, db)
|
|
item: Voucher = do_save(data, old.voucher_type, guest_book, db, user)
|
|
db.flush()
|
|
new_bill_id = (", ".join(f"{x.regime.prefix}-{x.bill_number}" for x in item.bills),)
|
|
old_bill_id = (", ".join(f"{x.regime.prefix}-{x.bill_number}" for x in old.bills),)
|
|
old.reason = f"Bill Discounted or Changed / Old Bill: {old_bill_id} / New Bill: {new_bill_id}."
|
|
old.voucher_type = VoucherType.VOID
|
|
do_update_bill_numbers(old, db)
|
|
do_update_settlements(old, [SettleSchema(id=SettleOption.VOID(), amount=round(old.amount))], db)
|
|
|
|
if update_table:
|
|
if old.status is None:
|
|
guest_book_id = None if guest_book is None else guest_book.id
|
|
item.status = Overview(
|
|
voucher_id=None, food_table_id=item.food_table_id, guest_book_id=guest_book_id, status="printed"
|
|
)
|
|
db.add(item.status)
|
|
else:
|
|
db.execute(update(Overview).where(Overview.voucher_id == old.id).values(voucher_id=item.id))
|
|
return item.id
|