barker/barker/barker/routers/voucher/save.py

180 lines
5.9 KiB
Python
Raw Normal View History

import uuid
from datetime import datetime, timedelta
from typing import Optional
import barker.schemas.voucher as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy import and_, func, or_
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
from ...core.config import settings
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from ...models.master import ProductVersion, VoucherType
from ...models.voucher import GuestBook, Inventory, InventoryModifier, Kot, Voucher
from ...printing.bill import print_bill
from ...printing.kot import print_kot
from ...routers.voucher import (
check_permissions,
do_update_settlements,
do_update_table,
get_bill_id,
get_guest_book,
get_tax,
happy_hour_has_discount,
happy_hour_items_balanced,
)
from ...schemas.auth import UserToken
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: int, # 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()
product_date = (now - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).date()
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
if not happy_hour_items_balanced(k.inventories):
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Happy hour products are not balanced.",
)
if happy_hour_has_discount(k.inventories):
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Discount is not allowed on happy hour products.",
)
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):
if i.quantity == 0:
continue
total_quantity = round(
sum(inv.quantity for ko in data.kots for inv in ko.inventories if inv.product.id_ == i.product.id_),
2,
)
product: ProductVersion = (
db.query(ProductVersion)
.filter(
and_(
ProductVersion.product_id == i.product.id_,
or_(
ProductVersion.valid_from == None, # noqa: E711
ProductVersion.valid_from <= product_date,
),
or_(
2020-11-12 07:02:16 +00:00
ProductVersion.valid_till == None, # noqa: E711
ProductVersion.valid_till >= product_date,
),
)
)
.first()
)
if total_quantity < 0:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=f"Quantity of {product.full_name} cannot be less than 0",
)
if round(i.quantity, 2) < 0:
if "edit-printed-product" not in user.permissions:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"You are not allowed to delete printed products."
f"\n In this case {product.full_name}",
)
tax_rate = get_tax(product.sale_category.tax.rate, voucher_type)
inv = Inventory(
kot.id,
product.product_id,
round(i.quantity, 2),
product.price,
round(min(i.discount, product.sale_category.discount_limit), 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