barker/barker/barker/routers/guest_book.py

199 lines
6.7 KiB
Python

import uuid
from datetime import date, datetime, timedelta
import barker.schemas.guest_book as schemas
from fastapi import APIRouter, Depends, HTTPException, Security, status
from sqlalchemy import desc, select
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import joinedload
from ..core.config import settings
from ..core.security import get_current_active_user as get_user
from ..db.session import SessionFuture
from ..models.customer import Customer
from ..models.guest_book import GuestBook
from ..models.voucher import Voucher
from ..schemas.user_token import UserToken
router = APIRouter()
@router.post("", response_model=schemas.GuestBook)
def save(
data: schemas.GuestBookIn,
user: UserToken = Security(get_user, scopes=["customers"]),
) -> schemas.GuestBook:
try:
with SessionFuture() as db:
customer = db.execute(select(Customer).where(Customer.phone == data.phone)).scalars().one_or_none()
if customer is None:
if len(data.name) == 0:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="New customer name cannot be blank",
)
if len(data.phone) == 0:
data.phone = data.name
customer = Customer(
name=data.name,
phone=data.phone,
address=data.address,
print_in_bill=False,
)
db.add(customer)
else:
customer.name = data.name or customer.name
customer.address = data.address or customer.address
item = GuestBook(
pax=data.pax, customer=customer, date_=data.date_ - timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES)
)
db.add(item)
db.commit()
return guest_book_info(item)
except SQLAlchemyError as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
)
@router.put("/{id_}", response_model=schemas.GuestBook)
def update_route(
id_: uuid.UUID,
data: schemas.GuestBookIn,
user: UserToken = Security(get_user, scopes=["customers"]),
) -> schemas.GuestBook:
try:
with SessionFuture() as db:
item: GuestBook = db.execute(select(GuestBook).where(GuestBook.id == id_)).scalar_one()
item.customer.name = data.name
item.customer.phone = data.phone
item.customer.address = data.address
item.pax = data.pax
item.date = data.date_ - timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES)
db.commit()
return guest_book_info(item)
except SQLAlchemyError as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
)
@router.delete("/{id_}", response_model=schemas.GuestBookIn)
def delete_route(
id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["customers"]),
) -> schemas.GuestBookIn:
try:
with SessionFuture() as db:
item: GuestBook = db.execute(select(GuestBook).where(GuestBook.id == id_)).scalar_one()
db.delete(item)
db.commit()
return blank_guest_book_info()
except SQLAlchemyError as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
)
@router.get("", response_model=schemas.GuestBookIn)
def show_blank(
user: UserToken = Security(get_user, scopes=["customers"]),
) -> schemas.GuestBookIn:
return blank_guest_book_info()
@router.get("/list", response_model=schemas.GuestBookList)
def show_list(
q: str | None = None,
user: UserToken = Depends(get_user),
) -> schemas.GuestBookList:
if q is None or q == "":
d = date.today()
else:
d = datetime.strptime(q, "%d-%b-%Y")
list_ = (
select(GuestBook)
.where(
GuestBook.date >= d + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES - settings.TIMEZONE_OFFSET_MINUTES)
)
.where(
GuestBook.date
< d
+ timedelta(
minutes=settings.NEW_DAY_OFFSET_MINUTES - settings.TIMEZONE_OFFSET_MINUTES,
days=1,
)
)
.order_by(GuestBook.date)
)
guest_book: list[schemas.GuestBookListItem] = []
with SessionFuture() as db:
for i, item in enumerate(db.execute(list_).scalars().all()):
gbli = schemas.GuestBookListItem(
id=item.id,
serial=i + 1,
name=item.customer.name,
phone=item.customer.phone,
pax=item.pax,
date=item.date,
status=None if item.status is None else item.status.status,
tableId=None if item.status is None else item.status.food_table.id,
voucherId=None if item.status is None else item.status.voucher_id,
tableName=None if item.status is None else item.status.food_table.name,
)
if item.status is None:
last = (
db.execute(
select(Voucher)
.where(Voucher.customer_id == item.customer_id)
.order_by(desc(Voucher.date))
.options(joinedload(Voucher.food_table, innerjoin=True))
)
.scalars()
.first()
)
if last is not None:
gbli.status = "old"
gbli.voucher_id = last.id
gbli.table_name = last.food_table.name
guest_book.insert(0, gbli)
return schemas.GuestBookList(date=d, list=guest_book)
@router.get("/{id_}", response_model=schemas.GuestBook)
def show_id(
id_: uuid.UUID,
user: UserToken = Security(get_user, scopes=["customers"]),
) -> schemas.GuestBook:
with SessionFuture() as db:
item: GuestBook = db.execute(select(GuestBook).where(GuestBook.id == id_)).scalar_one()
return guest_book_info(item)
def guest_book_info(item: GuestBook) -> schemas.GuestBook:
return schemas.GuestBook(
id=item.id,
name=item.customer.name,
phone=item.customer.phone,
pax=item.pax,
address=item.customer.address,
date=item.date + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES),
)
def blank_guest_book_info() -> schemas.GuestBookIn:
return schemas.GuestBookIn(
name="",
phone="",
pax=0,
address="",
date=datetime.utcnow() + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES),
)