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, }