"""Shops / Bezugsquellen: verwaltbare Liste für „gekauft bei“ (nur Gegenstände).""" from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import func from sqlalchemy.orm import Session from ..database import get_db from ..deps import get_current_user, require_admin from ..models import Product, Shop, User from ..schemas import ShopCreate, ShopOut, ShopUpdate router = APIRouter(prefix="/shops", tags=["shops"]) def _to_out(db: Session, shop: Shop) -> ShopOut: out = ShopOut.model_validate(shop) out.product_count = db.query(Product).filter(Product.shop_id == shop.id).count() return out @router.get("", response_model=list[ShopOut]) def list_shops( db: Session = Depends(get_db), _: User = Depends(get_current_user) ) -> list[ShopOut]: return [_to_out(db, s) for s in db.query(Shop).order_by(Shop.name).all()] @router.post("", response_model=ShopOut, status_code=status.HTTP_201_CREATED) def create_shop( payload: ShopCreate, db: Session = Depends(get_db), _: User = Depends(require_admin), ) -> ShopOut: name = payload.name.strip() if db.query(Shop).filter(func.lower(Shop.name) == name.lower()).first(): raise HTTPException(status.HTTP_409_CONFLICT, "Diesen Shop gibt es bereits") shop = Shop(name=name, website=(payload.website or None)) db.add(shop) db.commit() db.refresh(shop) return _to_out(db, shop) @router.patch("/{shop_id}", response_model=ShopOut) def update_shop( shop_id: int, payload: ShopUpdate, db: Session = Depends(get_db), _: User = Depends(require_admin), ) -> ShopOut: shop = db.get(Shop, shop_id) if shop is None: raise HTTPException(status.HTTP_404_NOT_FOUND, "Shop nicht gefunden") data = payload.model_dump(exclude_unset=True) if "name" in data and data["name"]: name = data["name"].strip() doppelt = ( db.query(Shop) .filter(func.lower(Shop.name) == name.lower(), Shop.id != shop_id) .first() ) if doppelt is not None: raise HTTPException(status.HTTP_409_CONFLICT, "Diesen Shop gibt es bereits") shop.name = name if "website" in data: shop.website = data["website"] or None db.commit() db.refresh(shop) return _to_out(db, shop) @router.delete("/{shop_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_shop( shop_id: int, db: Session = Depends(get_db), _: User = Depends(require_admin), ) -> None: """Artikel bleiben bestehen, sie verlieren nur die Bezugsquelle (SET NULL).""" shop = db.get(Shop, shop_id) if shop is None: raise HTTPException(status.HTTP_404_NOT_FOUND, "Shop nicht gefunden") # SQLite setzt Fremdschlüssel nicht ohne Weiteres um, deshalb ausdrücklich. db.query(Product).filter(Product.shop_id == shop_id).update( {Product.shop_id: None} ) db.delete(shop) db.commit()