2025-03-28 10:27:24 +00:00

118 lines
3.2 KiB
Python

from typing import List, Dict, Optional, Union, Any
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_
from models.book import Book
from schemas.book import BookCreate, BookUpdate
def validate_isbn(isbn: str) -> bool:
"""
Validate ISBN format.
Args:
isbn: ISBN string to validate
Returns:
bool: True if ISBN format is valid, False otherwise
"""
# Remove any hyphens or spaces
isbn = isbn.replace('-', '').replace(' ', '')
if len(isbn) == 13: # ISBN-13
return isbn.isdigit()
elif len(isbn) == 10: # ISBN-10
return isbn[:-1].isdigit() and (isbn[-1].isdigit() or isbn[-1].lower() == 'x')
return False
def get_available_books(db: Session, skip: int = 0, limit: int = 100) -> List[Book]:
"""
Get list of available books with pagination.
Args:
db: Database session
skip: Number of records to skip
limit: Maximum number of records to return
Returns:
List of available Book objects
"""
return db.query(Book)\
.filter(Book.is_available == True)\
.filter(Book.quantity > 0)\
.offset(skip)\
.limit(limit)\
.all()
def search_books(
db: Session,
search_term: str,
include_unavailable: bool = False
) -> List[Book]:
"""
Search books by title, author or ISBN.
Args:
db: Database session
search_term: Search string
include_unavailable: Whether to include unavailable books
Returns:
List of matching Book objects
"""
query = db.query(Book)
# Create search conditions
search_conditions = or_(
Book.title.ilike(f"%{search_term}%"),
Book.author.ilike(f"%{search_term}%"),
Book.isbn == search_term
)
if not include_unavailable:
query = query.filter(Book.is_available == True)
return query.filter(search_conditions).all()
def update_book_availability(db: Session, book_id: int) -> Optional[Book]:
"""
Update book availability based on quantity.
Args:
db: Database session
book_id: ID of book to update
Returns:
Updated Book object if found, None otherwise
"""
book = db.query(Book).filter(Book.id == book_id).first()
if book:
book.is_available = book.quantity > 0
db.commit()
db.refresh(book)
return book
return None
def validate_book_data(book_data: Union[BookCreate, BookUpdate]) -> Dict[str, str]:
"""
Validate book data before creation/update.
Args:
book_data: Book data to validate
Returns:
Dict containing any validation errors
"""
errors = {}
if hasattr(book_data, 'isbn') and book_data.isbn:
if not validate_isbn(book_data.isbn):
errors['isbn'] = "Invalid ISBN format"
if hasattr(book_data, 'price') and book_data.price:
if book_data.price < 0:
errors['price'] = "Price cannot be negative"
if hasattr(book_data, 'quantity') and book_data.quantity:
if book_data.quantity < 0:
errors['quantity'] = "Quantity cannot be negative"
return errors