from typing import Optional, List from sqlalchemy import func from app.models.classroom import Classroom from app.repositories.base_repository import BaseRepository from app import db class ClassroomRepository(BaseRepository[Classroom]): """Repositorio especializado en operaciones de persistencia y filtrado de aulas.""" def __init__(self): super().__init__(Classroom) def get_by_code_and_building(self, building_id: int, code: str, floor: str) -> Optional[Classroom]: """Busca un aula por edificio, código y piso para verificar duplicados.""" return Classroom.query.filter_by( building_id=building_id, code=code.strip(), floor=str(floor).strip() ).first() def get_active_classrooms(self, building_id: Optional[int] = None, floor: Optional[str] = None, only_virtual: bool = False, only_physical: bool = False) -> List[Classroom]: """Retorna aulas activas con filtros opcionales de edificio, piso y modalidad.""" query = Classroom.query.filter_by(is_active=True) if building_id: query = query.filter_by(building_id=building_id) if floor: query = query.filter_by(floor=str(floor).strip()) classrooms = query.order_by(Classroom.floor.asc(), Classroom.code.asc()).all() if only_virtual: return [c for c in classrooms if c.is_virtual] elif only_physical: return [c for c in classrooms if not c.is_virtual] return classrooms def get_virtual_classrooms(self) -> List[Classroom]: """Obtiene todas las salas virtuales activas.""" return [c for c in self.get_active_classrooms() if c.is_virtual] def get_physical_classrooms(self) -> List[Classroom]: """Obtiene todas las aulas físicas activas.""" return [c for c in self.get_active_classrooms() if not c.is_virtual] def search(self, term: str) -> List[Classroom]: """Búsqueda de aulas por código, edificio o descripción.""" if not term: return self.get_all(order_by=Classroom.code.asc()) term_clean = f"%{term.strip()}%" return Classroom.query.filter( Classroom.is_active == True, (Classroom.code.ilike(term_clean)) | (Classroom.building.ilike(term_clean)) | (Classroom.description.ilike(term_clean)) ).order_by(Classroom.code.asc()).all()