feat: refactorizar espacios fisicos desacoplando Edificio, Piso y Aula con selectores en cascada y filtros
This commit is contained in:
+52
-13
@@ -9,23 +9,57 @@ class Classroom(db.Model):
|
||||
building_id = db.Column(db.Integer, db.ForeignKey('buildings.id'), nullable=True)
|
||||
building = db.Column(db.String(100), nullable=False)
|
||||
code = db.Column('room_number', db.String(50), nullable=False) # Maps to room_number column in DB
|
||||
floor = db.Column(db.Integer, nullable=False)
|
||||
floor = db.Column(db.String(50), nullable=False, default='1')
|
||||
capacity = db.Column(db.Integer, nullable=False)
|
||||
description = db.Column(db.Text)
|
||||
is_active = db.Column('active', db.Boolean, default=True, nullable=False) # Maps to active column in DB
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
# Relación con Building (mapeada vía backref 'building_entity' en Building.classrooms)
|
||||
@property
|
||||
def building_rel(self):
|
||||
return self.building_entity
|
||||
|
||||
@property
|
||||
def building_name(self):
|
||||
"""Nombre del edificio desacoplado"""
|
||||
if self.building_rel:
|
||||
return self.building_rel.name
|
||||
return self.building or 'Edificio Central'
|
||||
|
||||
@property
|
||||
def floor_display(self):
|
||||
"""Formato amigable para el piso: PB, Planta Baja, Piso X"""
|
||||
f = str(self.floor).strip() if self.floor is not None else ''
|
||||
if f in ['0', 'PB', 'pb', 'Planta Baja', 'planta baja']:
|
||||
return 'Planta Baja'
|
||||
if f.lower().startswith('piso') or '°' in f:
|
||||
return f
|
||||
return f"Piso {f}"
|
||||
|
||||
@property
|
||||
def is_virtual(self):
|
||||
"""Indica si el aula es virtual"""
|
||||
return (self.code and 'VIRTUAL' in self.code.upper()) or (self.building and 'VIRTUAL' in self.building.upper())
|
||||
|
||||
@property
|
||||
def location_display(self):
|
||||
"""Ubicación completa y limpia: Edificio · Piso · Aula"""
|
||||
if self.is_virtual:
|
||||
return '🌐 Campus Virtual'
|
||||
return f"{self.building_name} · {self.floor_display} · {self.code}"
|
||||
|
||||
# Virtual properties for compatibility
|
||||
@property
|
||||
def name(self):
|
||||
"""Generate name from building and code"""
|
||||
return f"{self.building}-{self.code}"
|
||||
return f"{self.building_name}-{self.code}"
|
||||
|
||||
@property
|
||||
def campus_location(self):
|
||||
"""Placeholder for campus location - can be expanded when campus model is implemented"""
|
||||
return None
|
||||
"""Placeholder for campus location"""
|
||||
return self.building_rel.address if self.building_rel else None
|
||||
|
||||
# Virtual field for compatibility - combines building and code
|
||||
@property
|
||||
@@ -39,28 +73,34 @@ class Classroom(db.Model):
|
||||
# Override code property for consistency
|
||||
@property
|
||||
def code_display(self):
|
||||
return f"{self.building}-{self.code}"
|
||||
return f"{self.building_name} - {self.code}"
|
||||
|
||||
@property
|
||||
def capacity_display(self):
|
||||
"""Retorna '∞' para aulas virtuales o capacidad ilimitada, o el número entero."""
|
||||
if self.capacity == 0 or (self.code and 'VIRTUAL' in self.code.upper()):
|
||||
if self.capacity == 0 or self.is_virtual:
|
||||
return '∞'
|
||||
return str(self.capacity)
|
||||
|
||||
@property
|
||||
def is_unlimited(self):
|
||||
return self.capacity == 0 or (self.code and 'VIRTUAL' in self.code.upper())
|
||||
return self.capacity == 0 or self.is_virtual
|
||||
|
||||
def to_dict(self):
|
||||
"""Convert classroom to dictionary"""
|
||||
return {
|
||||
'id': self.id,
|
||||
'code': self.code_display,
|
||||
'building': self.building,
|
||||
'building_id': self.building_id,
|
||||
'building': self.building_name,
|
||||
'code': self.code,
|
||||
'code_display': self.code_display,
|
||||
'name': self.name,
|
||||
'floor': self.floor,
|
||||
'floor_display': self.floor_display,
|
||||
'location_display': self.location_display,
|
||||
'capacity': self.capacity,
|
||||
'capacity_display': self.capacity_display,
|
||||
'is_virtual': self.is_virtual,
|
||||
'description': self.description,
|
||||
'campus_location': self.campus_location,
|
||||
'is_active': self.is_active,
|
||||
@@ -71,10 +111,9 @@ class Classroom(db.Model):
|
||||
|
||||
def get_full_location(self):
|
||||
"""Get full classroom location"""
|
||||
location = f"{self.building} - Floor {self.floor}"
|
||||
if self.campus_location:
|
||||
location += f" ({self.campus_location})"
|
||||
return location
|
||||
if self.is_virtual:
|
||||
return 'Campus Virtual (Remoto)'
|
||||
return f"{self.building_name} - {self.floor_display}"
|
||||
|
||||
@staticmethod
|
||||
def find_best_classroom(max_students, start_time, end_time, exclude_reservation_id=None):
|
||||
|
||||
Reference in New Issue
Block a user