barker/barker/barker/routers/product.py

242 lines
7.5 KiB
Python

import uuid
from typing import Optional, List
from fastapi import APIRouter, HTTPException, status, Depends, Security
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session, joinedload
from ..schemas.auth import UserToken
import barker.schemas.master as schemas
from ..core.security import get_current_active_user as get_user
from ..db.session import SessionLocal
from ..models.master import Product
router = APIRouter()
# Dependency
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.post("/list", response_model=List[schemas.Product])
def sort_order(
data: List[schemas.Product], db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["products"]),
):
try:
indexes = {}
for item in data:
if item.menu_category.id_ in indexes:
indexes[item.menu_category.id_] += 1
else:
indexes[item.menu_category.id_] = 0
db.query(Product).filter(Product.id == item.id_).update(
{Product.sort_order: indexes[item.menu_category.id_]}
)
db.commit()
return [
product_info(item)
for item in db.query(Product)
.order_by(Product.menu_category_id)
.order_by(Product.sort_order)
.order_by(Product.name)
.options(joinedload(Product.menu_category), joinedload(Product.sale_category))
.all()
]
except SQLAlchemyError as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e),
)
except Exception:
db.rollback()
raise
@router.post("", response_model=schemas.Product)
def save(
data: schemas.ProductIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["products"]),
):
try:
item = Product(
name=data.name,
units=data.units,
menu_category_id=data.menu_category.id_,
sale_category_id=data.sale_category.id_,
price=data.price,
has_happy_hour=data.has_happy_hour,
is_not_available=data.is_not_available,
quantity=data.quantity,
is_active=data.is_active,
)
db.add(item)
db.commit()
return product_info(item)
except SQLAlchemyError as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e),
)
except Exception:
db.rollback()
raise
@router.put("/{id_}", response_model=schemas.Product)
def update(
id_: uuid.UUID,
data: schemas.ProductIn,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["products"]),
):
try:
item: Product = db.query(Product).filter(Product.id == id_).first()
item.name = data.name
item.units = data.units
item.menu_category_id = data.menu_category.id_
item.sale_category_id = data.sale_category.id_
item.price = data.price
item.has_happy_hour = data.has_happy_hour
item.is_not_available = data.is_not_available
item.quantity = data.quantity
item.is_active = data.is_active
db.commit()
return product_info(item)
except SQLAlchemyError as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e),
)
except Exception:
db.rollback()
raise
@router.delete("/{id_}")
def delete(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["products"]),
):
try:
item: Product = db.query(Product).filter(Product.id == id_).first()
if item is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Product not found",
)
else:
raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED, detail="Product deletion not implemented",
)
except Exception:
db.rollback()
raise
@router.get("")
def show_blank(
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["products"]),
):
return product_info(None)
@router.get("/list")
def show_list(db: Session = Depends(get_db), user: UserToken = Depends(get_user)):
return [
product_info(item)
for item in db.query(Product)
.order_by(Product.menu_category_id)
.order_by(Product.sort_order)
.order_by(Product.name)
.options(joinedload(Product.menu_category), joinedload(Product.sale_category))
.all()
]
@router.get("/query")
async def show_term(
mc: uuid.UUID = None,
a: bool = None,
db: Session = Depends(get_db),
current_user: UserToken = Depends(get_user),
):
list_ = []
for item in db.query(Product).filter(Product.is_active == a, Product.menu_category_id == mc).order_by(Product.sort_order, Product.name).all():
list_.append(
{
"id": item.id,
"name": item.full_name,
"saleCategory": {"id": item.sale_category_id, "name": item.sale_category.name, },
"tax": {
"id": item.sale_category.tax_id,
"name": item.sale_category.tax.name,
"rate": item.sale_category.tax.rate,
},
"price": item.price,
"hasHappyHour": False,
"isNotAvailable": item.is_not_available,
"isActive": item.is_active,
"sortOrder": item.sort_order,
}
)
if item.has_happy_hour:
list_.append(
{
"id": item.id,
"name": "H H " + item.full_name,
"saleCategory": {"id": item.sale_category_id, "name": item.sale_category.name, },
"tax": {
"id": item.sale_category.tax_id,
"name": item.sale_category.tax.name,
"rate": item.sale_category.tax.rate,
},
"price": item.price,
"hasHappyHour": True,
"isNotAvailable": item.is_not_available,
"isActive": item.is_active,
"sortOrder": item.sort_order,
}
)
return list_
@router.get("/{id_}")
def show_id(
id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["products"]),
):
item: Product = db.query(Product).filter(Product.id == id_).first()
return product_info(item)
def product_info(item: Optional[Product]):
if item is None:
return {
"name": "",
"units": "",
"menuCategory": {},
"saleCategory": {},
"price": 0,
"hasHappyHour": False,
"isNotAvailable": False,
"isActive": True,
"sortOrder": 0,
}
return {
"id": item.id,
"name": item.name,
"units": item.units,
"menuCategory": {"id": item.menu_category_id, "name": item.menu_category.name},
"saleCategory": {
"id": item.sale_category_id,
"name": item.sale_category.name,
},
"price": item.price,
"hasHappyHour": item.has_happy_hour,
"isNotAvailable": item.is_not_available,
"isActive": item.is_active,
"sortOrder": item.sort_order,
}