Files
plantillas-proyectos/backend/api/v1/modules/a76/company/service.py
acazares 962f43fe62 Refactor and enhance CRUD operations for Seal, Trailer, Transporter, Vehicle, and Customs Broker modules
- Updated SealService to support tenant and company filtering with pagination and enhanced CRUD methods.
- Refactored TrailerService to include tenant and company support, added filtering capabilities, and improved CRUD methods.
- Introduced TenantCRUDRoutes for Trailer and Transporter routes to streamline API endpoint creation and management.
- Enhanced TransporterService with tenant and company filtering, pagination, and improved CRUD operations.
- Added Customs Broker module with DTOs, models, services, and routes for managing customs broker data.
- Implemented CRUD operations for Customs Broker, including personnel and VU management.
- Improved data validation and descriptions in DTOs for better API documentation.
2025-11-11 18:20:39 -06:00

162 lines
4.7 KiB
Python

"""
Capa de servicio para lógica de negocio de empresa
"""
import logging
from typing import List, Optional, Tuple, Dict, Any
from fastapi import HTTPException
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session
from .dto import CompanyCreateDTO, CompanyResponseDTO, CompanyUpdateDTO
from .models import Company
logger = logging.getLogger(__name__)
class CompanyService:
"""Servicio para gestión de empresa"""
def __init__(self, db: Session):
self.db = db
# Métodos para TenantCRUDRoutes
@staticmethod
def get_all(
db: Session,
tenant_id: int,
company_id: int,
skip: int = 0,
limit: int = 50,
filters: Optional[Dict[str, Any]] = None,
) -> Tuple[List[Company], int]:
"""Get all companies for a tenant with pagination"""
query = db.query(Company).filter(Company.tenant_id == tenant_id)
# Apply filters if provided
if filters:
if filters.get("name"):
query = query.filter(
Company.name.ilike(f"%{filters['name']}%")
)
if filters.get("rfc"):
query = query.filter(
Company.rfc.ilike(f"%{filters['rfc']}%")
)
total = query.count()
companies = query.offset(skip).limit(limit).all()
return companies, total
@staticmethod
def get_by_id(
db: Session, company_id: int, tenant_id: int, company_id_unused: int
) -> Optional[Company]:
"""Get company by ID"""
return (
db.query(Company)
.filter(
Company.id == company_id,
Company.tenant_id == tenant_id,
)
.first()
)
@staticmethod
def create(
db: Session,
company_data: CompanyCreateDTO,
tenant_id: int,
company_id: int,
) -> Company:
"""Create a new company"""
try:
db_company = Company(
**company_data.model_dump(exclude_unset=True),
tenant_id=tenant_id
)
db.add(db_company)
db.commit()
db.refresh(db_company)
return db_company
except IntegrityError as e:
db.rollback()
logger.error(f"IntegrityError creating company: {str(e)}")
raise HTTPException(
status_code=400,
detail="Company already exists",
)
except Exception as e:
db.rollback()
logger.error(f"Error creating company: {str(e)}")
raise HTTPException(status_code=500, detail="Error creating company")
@staticmethod
def update(
db: Session,
company_id: int,
tenant_id: int,
company_id_unused: int,
company_data: CompanyUpdateDTO,
) -> Optional[Company]:
"""Update a company"""
company = CompanyService.get_by_id(db, company_id, tenant_id, company_id_unused)
if not company:
return None
# Update only provided fields
update_data = company_data.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(company, field, value)
try:
db.commit()
db.refresh(company)
return company
except Exception as e:
db.rollback()
logger.error(f"Error updating company {company_id}: {str(e)}")
raise HTTPException(status_code=500, detail="Error updating company")
@staticmethod
def delete(
db: Session, company_id: int, tenant_id: int, company_id_unused: int
) -> bool:
"""Delete a company"""
company = CompanyService.get_by_id(db, company_id, tenant_id, company_id_unused)
if not company:
return False
try:
db.delete(company)
db.commit()
return True
except Exception as e:
db.rollback()
logger.error(f"Error deleting company {company_id}: {str(e)}")
raise HTTPException(status_code=500, detail="Error deleting company")
# Custom methods
def get_companies_by_tenant(self, tenant_id: int) -> List[Company]:
"""Get all companies for a tenant"""
return (
self.db.query(Company)
.filter(Company.tenant_id == tenant_id)
.order_by(Company.name)
.all()
)
def exists_company(self, tenant_id: int) -> bool:
"""Check if a company exists for a tenant"""
return (
self.db.query(Company)
.filter(Company.tenant_id == tenant_id)
.first()
is not None
)