from typing import Optional from sqlalchemy.orm import Session, joinedload from app.crud.base import CRUDBase from app.models.cart import Cart, CartItem from app.schemas.cart import CartCreate, CartItemCreate, CartItemUpdate class CRUDCart(CRUDBase[Cart, CartCreate, CartCreate]): def get_by_user_id(self, db: Session, *, user_id: int) -> Optional[Cart]: return db.query(Cart).filter(Cart.user_id == user_id).first() def get_or_create_cart(self, db: Session, *, user_id: int) -> Cart: cart = self.get_by_user_id(db, user_id=user_id) if not cart: cart = self.create(db, obj_in=CartCreate(user_id=user_id)) return cart def get_cart_with_items(self, db: Session, *, user_id: int) -> Optional[Cart]: return ( db.query(Cart) .filter(Cart.user_id == user_id) .options(joinedload(Cart.items).joinedload(CartItem.product)) .first() ) class CRUDCartItem(CRUDBase[CartItem, CartItemCreate, CartItemUpdate]): def create_or_update_cart_item( self, db: Session, *, cart_id: int, product_id: int, quantity: int ) -> CartItem: cart_item = ( db.query(CartItem) .filter(CartItem.cart_id == cart_id, CartItem.product_id == product_id) .first() ) if cart_item: cart_item.quantity = quantity db.add(cart_item) db.commit() db.refresh(cart_item) return cart_item else: return self.create( db, obj_in=CartItemCreate(cart_id=cart_id, product_id=product_id, quantity=quantity) ) def remove_cart_item( self, db: Session, *, cart_id: int, product_id: int ) -> None: db.query(CartItem).filter( CartItem.cart_id == cart_id, CartItem.product_id == product_id ).delete() db.commit() def clear_cart(self, db: Session, *, cart_id: int) -> None: db.query(CartItem).filter(CartItem.cart_id == cart_id).delete() db.commit() cart = CRUDCart(Cart) cart_item = CRUDCartItem(CartItem)