from sqlalchemy.orm import Session from sqlalchemy.exc import IntegrityError from . import dto, models class CustomsBrokerService: @staticmethod def get_by_id(db: Session, broker_key: str, tenant_id: int, company_id: int): """Get a customs broker by broker_key with tenant/company validation""" return ( db.query(models.CustomsBroker) .filter( models.CustomsBroker.broker_key == broker_key, models.CustomsBroker.tenant_id == tenant_id, models.CustomsBroker.company_id == company_id, ) .first() ) @staticmethod def get_all( db: Session, tenant_id: int, company_id: int, skip: int = 0, limit: int = 100, filters: dict = None, sort_by: str = None, sort_order: str = "asc", ): """Get all customs brokers for a tenant/company with pagination""" query = db.query(models.CustomsBroker).filter( models.CustomsBroker.tenant_id == tenant_id, models.CustomsBroker.company_id == company_id, ) if filters: # Implement filters if needed in the future pass # Apply sorting if sort_by: column = getattr(models.CustomsBroker, sort_by, None) if column: if sort_order == "desc": query = query.order_by(column.desc()) else: query = query.order_by(column.asc()) else: query = query.order_by(models.CustomsBroker.id.desc()) else: query = query.order_by(models.CustomsBroker.id.desc()) total = query.count() items = query.offset(skip).limit(limit).all() return items, total @staticmethod def create(db: Session, broker_data: dto.CustomsBrokerCreateDTO, tenant_id: int, company_id: int): """Create a new customs broker""" broker_dict = broker_data.model_dump() broker_dict["tenant_id"] = tenant_id broker_dict["company_id"] = company_id new_broker = models.CustomsBroker(**broker_dict) db.add(new_broker) try: db.commit() db.refresh(new_broker) return new_broker except IntegrityError: db.rollback() raise ValueError("La clave del agente ya existe o hay datos duplicados.") @staticmethod def update(db: Session, broker_key: str, tenant_id: int, broker_data: dto.CustomsBrokerUpdateDTO, company_id: int): """Update an existing customs broker""" broker = CustomsBrokerService.get_by_id(db, broker_key, tenant_id, company_id) if broker: for key, value in broker_data.model_dump(exclude_unset=True).items(): setattr(broker, key, value) try: db.commit() db.refresh(broker) except IntegrityError: db.rollback() raise ValueError("Los datos duplicados no pueden ser guardados o hay un conflicto de integridad.") return broker @staticmethod def delete(db: Session, broker_key: str, tenant_id: int, company_id: int): """Delete a customs broker""" broker = CustomsBrokerService.get_by_id(db, broker_key, tenant_id, company_id) if broker: db.delete(broker) db.commit() return True return False class CustomsBrokerVUService: @staticmethod def get_by_broker_key(db: Session, broker_key: str): return ( db.query(models.CustomsBrokerVU) .join(models.CustomsBroker) .filter(models.CustomsBroker.broker_key == broker_key) .first() ) @staticmethod def create_vu(db: Session, vu_data: dto.CustomsBrokerVUCreateDTO): new_vu = models.CustomsBrokerVU(**vu_data.dict()) db.add(new_vu) db.commit() db.refresh(new_vu) return new_vu @staticmethod def update_vu(db: Session, broker_key: str, vu_data: dto.CustomsBrokerVUCreateDTO, tenant_id: int, company_id: int): # We need the custom broker ID to insert a new VU broker = ( db.query(models.CustomsBroker) .filter( models.CustomsBroker.broker_key == broker_key, models.CustomsBroker.tenant_id == tenant_id, models.CustomsBroker.company_id == company_id, ) .first() ) if not broker: return None vu = db.query(models.CustomsBrokerVU).filter(models.CustomsBrokerVU.customs_broker_id == broker.id).first() if vu: # Update existing for key, value in vu_data.model_dump(exclude_unset=True).items(): setattr(vu, key, value) db.commit() db.refresh(vu) return vu else: # Create new new_vu_data = vu_data.model_dump() new_vu_data["tenant_id"] = tenant_id new_vu_data["company_id"] = company_id new_vu = models.CustomsBrokerVU(customs_broker_id=broker.id, **new_vu_data) db.add(new_vu) db.commit() db.refresh(new_vu) return new_vu @staticmethod def delete_vu(db: Session, broker_key: str): vu = CustomsBrokerVUService.get_by_broker_key(db, broker_key) if vu: db.delete(vu) db.commit() return vu @staticmethod def ensure_vu_for_broker(db: Session, broker: models.CustomsBroker) -> models.CustomsBrokerVU: """Crea fila VU vacĂ­a si no existe (p. ej. antes de subir CER/KEY/COVE al bucket).""" vu = ( db.query(models.CustomsBrokerVU) .filter(models.CustomsBrokerVU.customs_broker_id == broker.id) .first() ) if vu: return vu vu = models.CustomsBrokerVU( customs_broker_id=broker.id, tenant_id=broker.tenant_id, company_id=broker.company_id, ) db.add(vu) db.commit() db.refresh(vu) return vu class CustomsBrokerPersonnelService: @staticmethod def get_by_broker_key_and_line(db: Session, broker_key: str, line: int, tenant_id: int, company_id: int): return ( db.query(models.CustomsBrokerPersonnel) .join(models.CustomsBroker) .filter( models.CustomsBroker.broker_key == broker_key, models.CustomsBrokerPersonnel.line == line, models.CustomsBroker.tenant_id == tenant_id, models.CustomsBroker.company_id == company_id, ) .first() ) @staticmethod def create_personnel(db: Session, broker_key: str, personnel_data: dto.CustomsBrokerPersonnelDTO, tenant_id: int, company_id: int): broker = ( db.query(models.CustomsBroker) .filter( models.CustomsBroker.broker_key == broker_key, models.CustomsBroker.tenant_id == tenant_id, models.CustomsBroker.company_id == company_id, ) .first() ) if not broker: return None new_personnel_data = personnel_data.model_dump() new_personnel_data["tenant_id"] = tenant_id new_personnel_data["company_id"] = company_id new_personnel = models.CustomsBrokerPersonnel(customs_broker_id=broker.id, **new_personnel_data) db.add(new_personnel) db.commit() db.refresh(new_personnel) return new_personnel @staticmethod def update_personnel( db: Session, broker_key: str, line: int, personnel_data: dto.CustomsBrokerPersonnelDTO, tenant_id: int, company_id: int, ): personnel = CustomsBrokerPersonnelService.get_by_broker_key_and_line( db, broker_key, line, tenant_id, company_id ) if personnel: for key, value in personnel_data.model_dump(exclude_unset=True).items(): setattr(personnel, key, value) db.commit() db.refresh(personnel) return personnel else: return CustomsBrokerPersonnelService.create_personnel( db, broker_key, personnel_data, tenant_id, company_id ) @staticmethod def delete_personnel(db: Session, broker_key: str, line: int): personnel = CustomsBrokerPersonnelService.get_by_broker_key_and_line( db, broker_key, line ) if personnel: db.delete(personnel) db.commit() return personnel