# app/api/v1/product.py """ Product endpoints - simplified with service-level exception handling. This module provides classes and functions for: - Product CRUD operations with marketplace support - Advanced product filtering and search - Product export functionality """ import logging from typing import Optional from fastapi import APIRouter, Depends, Query from fastapi.responses import StreamingResponse from sqlalchemy.orm import Session from app.api.deps import get_current_user from app.core.database import get_db from app.services.product_service import product_service from models.schemas.product import (ProductCreate, ProductDetailResponse, ProductListResponse, ProductResponse, ProductUpdate) from models.database.user import User router = APIRouter() logger = logging.getLogger(__name__) @router.get("/product/export-csv") async def export_csv( marketplace: Optional[str] = Query(None, description="Filter by marketplace"), shop_name: Optional[str] = Query(None, description="Filter by shop name"), db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Export products as CSV with streaming and marketplace filtering (Protected).""" def generate_csv(): return product_service.generate_csv_export( db=db, marketplace=marketplace, shop_name=shop_name ) filename = "products_export" if marketplace: filename += f"_{marketplace}" if shop_name: filename += f"_{shop_name}" filename += ".csv" return StreamingResponse( generate_csv(), media_type="text/csv", headers={"Content-Disposition": f"attachment; filename={filename}"}, ) @router.get("/product", response_model=ProductListResponse) def get_products( skip: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=1000), brand: Optional[str] = Query(None), category: Optional[str] = Query(None), availability: Optional[str] = Query(None), marketplace: Optional[str] = Query(None, description="Filter by marketplace"), shop_name: Optional[str] = Query(None, description="Filter by shop name"), search: Optional[str] = Query(None), db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get products with advanced filtering including marketplace and shop (Protected).""" products, total = product_service.get_products_with_filters( db=db, skip=skip, limit=limit, brand=brand, category=category, availability=availability, marketplace=marketplace, shop_name=shop_name, search=search, ) return ProductListResponse( products=products, total=total, skip=skip, limit=limit ) @router.post("/product", response_model=ProductResponse) def create_product( product: ProductCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Create a new product with validation and marketplace support (Protected).""" logger.info(f"Starting product creation for ID: {product.product_id}") db_product = product_service.create_product(db, product) logger.info("Product created successfully") return db_product @router.get("/product/{product_id}", response_model=ProductDetailResponse) def get_product( product_id: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get product with stock information (Protected).""" product = product_service.get_product_by_id_or_raise(db, product_id) # Get stock information if GTIN exists stock_info = None if product.gtin: stock_info = product_service.get_stock_info(db, product.gtin) return ProductDetailResponse(product=product, stock_info=stock_info) @router.put("/product/{product_id}", response_model=ProductResponse) def update_product( product_id: str, product_update: ProductUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Update product with validation and marketplace support (Protected).""" updated_product = product_service.update_product(db, product_id, product_update) return updated_product @router.delete("/product/{product_id}") def delete_product( product_id: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Delete product and associated stock (Protected).""" product_service.delete_product(db, product_id) return {"message": "Product and associated stock deleted successfully"}