import uuid from functools import reduce from typing import Optional from fastapi import APIRouter, HTTPException, status, Depends, Security from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.orm import Session 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 ModifierCategory, MenuCategory, Product router = APIRouter() # Dependency def get_db(): try: db = SessionLocal() yield db finally: db.close() @router.post("", response_model=schemas.ModifierCategory) def save( data: schemas.ModifierCategoryIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["modifiers"]), ): try: item = ModifierCategory(name=data.name, minimum=data.minimum, maximum=data.maximum, is_active=data.is_active) db.add(item) add_products(item, data.menu_categories, db) db.commit() return modifier_category_info(item, db=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 @router.put("/{id_}", response_model=schemas.ModifierCategory) def update( id_: uuid.UUID, data: schemas.ModifierCategoryIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["modifiers"]), ): try: item: ModifierCategory = db.query(ModifierCategory).filter(ModifierCategory.id == id_).first() item.name = data.name item.minimum = data.minimum item.maximum = data.maximum item.is_active = data.is_active add_products(item, data.menu_categories, db) db.commit() return modifier_category_info(item, db=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 @router.delete("/{id_}") def delete( id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["modifiers"]), ): try: item: ModifierCategory = db.query(ModifierCategory).filter(ModifierCategory.id == id_).first() db.delete(item) db.commit() return modifier_category_info(None, db=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 @router.get("") def show_blank( db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["modifiers"]), ): return modifier_category_info(None, db=db) @router.get("/list") def show_list(db: Session = Depends(get_db), user: UserToken = Depends(get_user)): list_ = db.query(ModifierCategory).order_by(ModifierCategory.sort_order).order_by(ModifierCategory.name).all() menu_categories = ( db.query(MenuCategory) .join(MenuCategory.products) .filter(Product.is_active == True) .order_by(MenuCategory.sort_order, Product.sort_order, Product.name) .all() ) modifier_categories = [] for item in list_: modifier_category = { "id": item.id, "name": item.name, "minimum": item.minimum, "maximum": item.maximum, "isActive": item.is_active, "menuCategories": [ { "id": mc.id, "name": mc.name, "enabled": reduce(lambda x, y: x and (y in item.products), mc.products, True), "products": [{"id": p.id, "name": p.name} for p in mc.products if p in item.products], } for mc in menu_categories ], } modifier_category["menuCategories"] = [i for i in modifier_category["menuCategories"] if len(i["products"]) > 0] modifier_categories.append(modifier_category) return modifier_categories @router.get("/for-product/{id_}") def for_product( id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user), ): product: Product = db.query(Product).filter(Product.id == id_).first() return [ { "id": item.id, "name": item.name, "minimum": item.minimum, "maximum": item.maximum, "isActive": item.is_active, "modifiers": [ {"id": m.id, "name": m.name, "price": m.price} for m in item.modifiers if m.is_active == True ], } for item in product.modifier_categories if item.is_active == True ] @router.get("/{id_}") def show_id( id_: uuid.UUID, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["modifiers"]), ): item: ModifierCategory = db.query(ModifierCategory).filter(ModifierCategory.id == id_).first() return modifier_category_info(item, db=db) def modifier_category_info(item: Optional[ModifierCategory], db: Session): menu_categories = ( db.query(MenuCategory) .join(MenuCategory.products) .filter(Product.is_active == True) .order_by(MenuCategory.sort_order, Product.sort_order, Product.name) .all() ) if item is None: return { "name": "", "minimum": 0, "maximum": 0, "isActive": True, "menuCategories": [ { "id": mc.id, "name": mc.name, "enabled": False, "products": [{"id": p.id, "name": p.name, "enabled": False} for p in mc.products], } for mc in menu_categories ], "sortOrder": item.sort_order, } return { "id": item.id, "name": item.name, "minimum": item.minimum, "maximum": item.maximum, "isActive": item.is_active, "menuCategories": [ { "id": mc.id, "name": mc.name, "enabled": False, "products": [ {"id": p.id, "name": p.name, "enabled": True if p in item.products else False} for p in mc.products ], } for mc in menu_categories ], "sortOrder": item.sort_order, } def add_products(modifier_category: ModifierCategory, menu_categories, db: Session): for mc in menu_categories: for p in mc.products: old = [x for x in modifier_category.products if x.id == p.id_] old = None if len(old) == 0 else old[0] if p.enabled and old is None: product_object = db.query(Product).filter(Product.id == p.id_).one() modifier_category.products.append(product_object) elif not p.enabled and old: modifier_category.products.remove(old)