from typing import List, Optional, Dict from sqlalchemy.orm import Session from app.models.card import Card from app.services.base_service import BaseService from app.schemas.card import CardCreate, CardUpdate class CardService(BaseService[Card]): def __init__(self): super().__init__(Card) def create(self, db: Session, obj_in: Dict) -> Card: """ Create a new card in the database. Args: db: Database session obj_in: Dictionary containing card data Returns: Card: The created card object """ return super().create(db, obj_in) def update(self, db: Session, db_obj: Card, obj_in: Dict) -> Card: """ Update an existing card in the database. Args: db: Database session db_obj: The card object to update obj_in: Dictionary containing updated card data Returns: Card: The updated card object """ return super().update(db, db_obj, obj_in) def get_by_name(self, db: Session, name: str) -> Optional[Card]: """ Get a card by its name. Args: db: Database session name: The name of the card to find Returns: Optional[Card]: The card if found, None otherwise """ return db.query(self.model).filter(self.model.name == name).first() def get_by_set(self, db: Session, set_name: str, skip: int = 0, limit: int = 100) -> List[Card]: """ Get all cards from a specific set. Args: db: Database session set_name: The name of the set to filter by skip: Number of records to skip (for pagination) limit: Maximum number of records to return Returns: List[Card]: List of cards from the specified set """ return db.query(self.model).filter(self.model.set_name == set_name).offset(skip).limit(limit).all() def get_by_rarity(self, db: Session, rarity: str, skip: int = 0, limit: int = 100) -> List[Card]: """ Get all cards of a specific rarity. Args: db: Database session rarity: The rarity to filter by skip: Number of records to skip (for pagination) limit: Maximum number of records to return Returns: List[Card]: List of cards with the specified rarity """ return db.query(self.model).filter(self.model.rarity == rarity).offset(skip).limit(limit).all() def update_quantity(self, db: Session, card_id: int, quantity_change: int) -> Card: """ Update the quantity of a card. Args: db: Database session card_id: The ID of the card to update quantity_change: The amount to change the quantity by (can be positive or negative) Returns: Card: The updated card object Raises: ValueError: If the card is not found or if the resulting quantity would be negative """ card = self.get(db, card_id) if not card: raise ValueError(f"Card with ID {card_id} not found") new_quantity = card.quantity + quantity_change if new_quantity < 0: raise ValueError(f"Cannot reduce quantity below 0. Current quantity: {card.quantity}, attempted change: {quantity_change}") card.quantity = new_quantity db.add(card) db.commit() db.refresh(card) return card def search(self, db: Session, query: str, skip: int = 0, limit: int = 100) -> List[Card]: """ Search for cards by name or set name. Args: db: Database session query: The search query skip: Number of records to skip (for pagination) limit: Maximum number of records to return Returns: List[Card]: List of cards matching the search query """ return db.query(self.model).filter( (self.model.name.ilike(f"%{query}%")) | (self.model.set_name.ilike(f"%{query}%")) ).offset(skip).limit(limit).all()