187 lines
6.3 KiB
Python
187 lines
6.3 KiB
Python
"""
|
|
Capa de servicio para lógica de negocio de relación entre partes y países
|
|
"""
|
|
|
|
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 PartCountryCreateDTO, PartCountryResponseDTO, PartCountryUpdateDTO
|
|
from .models import PartCountry
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class PartCountryService:
|
|
"""Servicio para gestión de relaciones entre partes y países"""
|
|
|
|
@staticmethod
|
|
def get_all(
|
|
db: Session,
|
|
skip: int = 0,
|
|
limit: int = 50,
|
|
filters: Optional[Dict[str, Any]] = None,
|
|
) -> Tuple[List[PartCountry], int]:
|
|
"""Get all part-country relationships with pagination"""
|
|
query = db.query(PartCountry)
|
|
|
|
if filters:
|
|
if filters.get("part_id"):
|
|
query = query.filter(PartCountry.part_id == filters["part_id"])
|
|
if filters.get("country_code"):
|
|
query = query.filter(
|
|
PartCountry.country_code.ilike(f"%{filters['country_code']}%")
|
|
)
|
|
if filters.get("preference"):
|
|
query = query.filter(PartCountry.preference == filters["preference"])
|
|
|
|
total = query.count()
|
|
part_countries = query.offset(skip).limit(limit).all()
|
|
|
|
return part_countries, total
|
|
|
|
@staticmethod
|
|
def get_by_id(db: Session, part_country_id: int) -> Optional[PartCountry]:
|
|
"""Get part-country relationship by ID"""
|
|
return db.query(PartCountry).filter(PartCountry.id == part_country_id).first()
|
|
|
|
@staticmethod
|
|
def get_by_part_id(db: Session, part_id: int) -> List[PartCountry]:
|
|
"""Get all countries for a specific part"""
|
|
return db.query(PartCountry).filter(PartCountry.part_id == part_id).all()
|
|
|
|
@staticmethod
|
|
def get_by_part_and_country(db: Session, part_id: int, country_code: str) -> Optional[PartCountry]:
|
|
"""Get specific part-country relationship"""
|
|
return db.query(PartCountry).filter(
|
|
PartCountry.part_id == part_id,
|
|
PartCountry.country_code == country_code
|
|
).first()
|
|
|
|
@staticmethod
|
|
def create(db: Session, part_country_data: PartCountryCreateDTO) -> PartCountry:
|
|
"""Create a new part-country relationship"""
|
|
try:
|
|
db_part_country = PartCountry(
|
|
**part_country_data.model_dump(exclude_unset=True)
|
|
)
|
|
|
|
db.add(db_part_country)
|
|
db.commit()
|
|
db.refresh(db_part_country)
|
|
|
|
return db_part_country
|
|
|
|
except IntegrityError as e:
|
|
db.rollback()
|
|
logger.error(f"IntegrityError creating part-country relationship: {str(e)}")
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail="Relationship already exists or invalid foreign key",
|
|
)
|
|
except Exception as e:
|
|
db.rollback()
|
|
logger.error(f"Error creating part-country relationship: {str(e)}")
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Error creating relationship: {str(e)}",
|
|
)
|
|
|
|
@staticmethod
|
|
def update(
|
|
db: Session, part_country_id: int, part_country_data: PartCountryUpdateDTO
|
|
) -> Optional[PartCountry]:
|
|
"""Update part-country relationship"""
|
|
try:
|
|
db_part_country = db.query(PartCountry).filter(
|
|
PartCountry.id == part_country_id
|
|
).first()
|
|
|
|
if not db_part_country:
|
|
return None
|
|
|
|
update_data = part_country_data.model_dump(exclude_unset=True)
|
|
for field, value in update_data.items():
|
|
setattr(db_part_country, field, value)
|
|
|
|
db.add(db_part_country)
|
|
db.commit()
|
|
db.refresh(db_part_country)
|
|
|
|
return db_part_country
|
|
|
|
except IntegrityError as e:
|
|
db.rollback()
|
|
logger.error(f"IntegrityError updating part-country relationship: {str(e)}")
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail="Cannot update: constraint violation",
|
|
)
|
|
except Exception as e:
|
|
db.rollback()
|
|
logger.error(f"Error updating part-country relationship: {str(e)}")
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Error updating relationship: {str(e)}",
|
|
)
|
|
|
|
@staticmethod
|
|
def delete(db: Session, part_country_id: int) -> bool:
|
|
"""Delete part-country relationship"""
|
|
try:
|
|
db_part_country = db.query(PartCountry).filter(
|
|
PartCountry.id == part_country_id
|
|
).first()
|
|
|
|
if not db_part_country:
|
|
return False
|
|
|
|
db.delete(db_part_country)
|
|
db.commit()
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
db.rollback()
|
|
logger.error(f"Error deleting part-country relationship: {str(e)}")
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Error deleting relationship: {str(e)}",
|
|
)
|
|
|
|
@staticmethod
|
|
def bulk_create(db: Session, part_id: int, countries_data: List[PartCountryCreateDTO]) -> List[PartCountry]:
|
|
"""Create multiple part-country relationships for a part"""
|
|
try:
|
|
# Delete existing relationships for this part
|
|
db.query(PartCountry).filter(PartCountry.part_id == part_id).delete()
|
|
db.commit()
|
|
|
|
# Create new relationships
|
|
db_part_countries = []
|
|
for country_data in countries_data:
|
|
country_data.part_id = part_id
|
|
db_part_country = PartCountry(
|
|
**country_data.model_dump(exclude_unset=True)
|
|
)
|
|
db_part_countries.append(db_part_country)
|
|
|
|
db.add_all(db_part_countries)
|
|
db.commit()
|
|
|
|
for pc in db_part_countries:
|
|
db.refresh(pc)
|
|
|
|
return db_part_countries
|
|
|
|
except Exception as e:
|
|
db.rollback()
|
|
logger.error(f"Error bulk creating part-country relationships: {str(e)}")
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=f"Error creating relationships: {str(e)}",
|
|
)
|