""" Capa de servicio para lógica de negocio de localización """ import logging from typing import Any, Dict, List, Optional, Tuple from fastapi import HTTPException from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import Session from .dto import LocationCreateDTO, LocationResponseDTO, LocationUpdateDTO from .models import Location logger = logging.getLogger(__name__) class LocationService: """Servicio para gestión de localización""" def __init__(self, db: Session): self.db = db @staticmethod def get_all( db: Session, skip: int = 0, limit: int = 50, filters: Optional[Dict[str, Any]] = None, ) -> Tuple[List[Location], int]: """Get all locations with pagination""" query = db.query(Location) if filters: if filters.get("code"): query = query.filter( Location.code.ilike(f"%{filters['code']}%")) if filters.get("description"): query = query.filter( Location.description.ilike(f"%{filters['description']}%") ) total = query.count() locations = query.offset(skip).limit(limit).all() return locations, total @staticmethod def get_by_id(db: Session, location_id: int) -> Optional[Location]: """Get location by ID""" return db.query(Location).filter(Location.id == location_id).first() @staticmethod def get_by_code(db: Session, code: str) -> Optional[Location]: """Get location by code""" return db.query(Location).filter(Location.code == code).first() @staticmethod def create(db: Session, location_data: LocationCreateDTO) -> Location: """Create a new location""" try: db_location = Location( **location_data.model_dump(exclude_unset=True)) db.add(db_location) db.commit() db.refresh(db_location) return db_location except IntegrityError as e: db.rollback() logger.error(f"IntegrityError creating location: {str(e)}") raise HTTPException( status_code=400, detail="Location code already exists", ) except Exception as e: db.rollback() logger.error(f"Error creating location: {str(e)}") raise HTTPException( status_code=500, detail="Error creating location") @staticmethod def update( db: Session, location_id: int, location_data: LocationUpdateDTO ) -> Optional[Location]: """Update a location""" try: db_location = db.query(Location).filter( Location.id == location_id).first() if not db_location: return None for key, value in location_data.model_dump(exclude_unset=True).items(): setattr(db_location, key, value) db.commit() db.refresh(db_location) return db_location except IntegrityError as e: db.rollback() logger.error(f"IntegrityError updating location: {str(e)}") raise HTTPException( status_code=400, detail="Error updating location", ) except Exception as e: db.rollback() logger.error(f"Error updating location: {str(e)}") raise HTTPException( status_code=500, detail="Error updating location") @staticmethod def delete(db: Session, location_id: int) -> bool: """Delete a location""" try: db_location = db.query(Location).filter( Location.id == location_id).first() if not db_location: return False db.delete(db_location) db.commit() return True except Exception as e: db.rollback() logger.error(f"Error deleting location: {str(e)}") raise HTTPException( status_code=500, detail="Error deleting location")