fix layout

This commit is contained in:
Alejandro Vazquez
2026-04-17 18:14:59 -03:00
parent ffb383554a
commit ec977bf90b
7 changed files with 45 additions and 29 deletions
+14 -5
View File
@@ -5,18 +5,27 @@ class Classroom(db.Model):
__tablename__ = 'classrooms' __tablename__ = 'classrooms'
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
# campus_id = db.Column(db.Integer, db.ForeignKey('campuses.id'), nullable=False) campus_id = db.Column(db.Integer, nullable=True) # Maps to campus_id in DB
building = db.Column(db.String(100), nullable=False) building = db.Column(db.String(100), nullable=False)
code = db.Column(db.String(50), nullable=False) # Changed from room_number code = db.Column('room_number', db.String(50), nullable=False) # Maps to room_number column in DB
name = db.Column(db.String(100), nullable=False)
floor = db.Column(db.Integer, nullable=False) floor = db.Column(db.Integer, nullable=False)
capacity = db.Column(db.Integer, nullable=False) capacity = db.Column(db.Integer, nullable=False)
description = db.Column(db.Text) description = db.Column(db.Text)
campus_location = db.Column(db.String(100)) is_active = db.Column('active', db.Boolean, default=True, nullable=False) # Maps to active column in DB
is_active = db.Column(db.Boolean, default=True, nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow) created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Virtual properties for compatibility
@property
def name(self):
"""Generate name from building and code"""
return f"{self.building}-{self.code}"
@property
def campus_location(self):
"""Placeholder for campus location - can be expanded when campus model is implemented"""
return None
# Virtual field for compatibility - combines building and code # Virtual field for compatibility - combines building and code
@property @property
def room_number(self): def room_number(self):
+3 -3
View File
@@ -334,11 +334,11 @@ class ReservationOptimizer:
'commission_id': gene.commission_id, 'commission_id': gene.commission_id,
'classroom_id': gene.classroom_id, 'classroom_id': gene.classroom_id,
'user_id': admin_user_id, 'user_id': admin_user_id,
'start_time': gene.start_time, 'start_time': gene.start_time.isoformat() if gene.start_time else None,
'end_time': gene.end_time, 'end_time': gene.end_time.isoformat() if gene.end_time else None,
'purpose': gene.purpose, 'purpose': gene.purpose,
'expected_attendees': gene.expected_attendees, 'expected_attendees': gene.expected_attendees,
'status': ReservationStatus.PENDING 'status': ReservationStatus.PENDING.value # Convert enum to string
} }
optimized_reservations.append(reservation_data) optimized_reservations.append(reservation_data)
+16 -7
View File
@@ -15,18 +15,27 @@ class Reservation(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
classroom_id = db.Column(db.Integer, db.ForeignKey('classrooms.id'), nullable=False) classroom_id = db.Column(db.Integer, db.ForeignKey('classrooms.id'), nullable=False)
commission_id = db.Column(db.Integer, db.ForeignKey('commissions.id'), nullable=False) commission_id = db.Column(db.Integer, db.ForeignKey('commissions.id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) user_id = db.Column('teacher_id', db.Integer, db.ForeignKey('users.id'), nullable=False) # Maps to teacher_id in DB
start_time = db.Column(db.DateTime, nullable=False) start_time = db.Column(db.DateTime, nullable=False)
end_time = db.Column(db.DateTime, nullable=False) end_time = db.Column(db.DateTime, nullable=False)
purpose = db.Column(db.String(500), nullable=False) purpose = db.Column(db.String(500), nullable=False)
status = db.Column(db.Enum(ReservationStatus), default=ReservationStatus.PENDING, nullable=False) status = db.Column(db.String(20), default='PENDING', nullable=False) # DB uses VARCHAR not ENUM
expected_attendees = db.Column(db.Integer, nullable=False) expected_attendees = db.Column(db.Integer, nullable=False)
notes = db.Column(db.Text) notes = db.Column(db.Text)
created_at = db.Column(db.DateTime, default=datetime.utcnow) created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Virtual property to convert status string to enum
@property
def status_enum(self):
"""Get status as enum"""
try:
return ReservationStatus(self.status)
except (ValueError, AttributeError):
return ReservationStatus.PENDING
# Relationships # Relationships
classroom = db.relationship('Classroom', backref=db.backref('reservation_list', lazy=True, cascade='all, delete-orphan')) classroom = db.relationship('Classroom', backref=db.backref('reservation_list', lazy=True, cascade='all, delete-orphan'))
commission = db.relationship('Commission', backref=db.backref('reservation_list', lazy=True, cascade='all, delete-orphan')) commission = db.relationship('Commission', backref=db.backref('reservation_list', lazy=True, cascade='all, delete-orphan'))
@@ -42,7 +51,7 @@ class Reservation(db.Model):
'start_time': self.start_time.isoformat() if self.start_time else None, 'start_time': self.start_time.isoformat() if self.start_time else None,
'end_time': self.end_time.isoformat() if self.end_time else None, 'end_time': self.end_time.isoformat() if self.end_time else None,
'purpose': self.purpose, 'purpose': self.purpose,
'status': self.status.value if self.status else None, 'status': self.status, # Already a string in DB
'expected_attendees': self.expected_attendees, 'expected_attendees': self.expected_attendees,
'notes': self.notes, 'notes': self.notes,
'created_at': self.created_at.isoformat() if self.created_at else None, 'created_at': self.created_at.isoformat() if self.created_at else None,
@@ -54,7 +63,7 @@ class Reservation(db.Model):
def is_confirmed(self): def is_confirmed(self):
"""Check if reservation is confirmed""" """Check if reservation is confirmed"""
return self.status == ReservationStatus.CONFIRMED return self.status == ReservationStatus.CONFIRMED.value
def can_be_cancelled(self): def can_be_cancelled(self):
"""Check if reservation can be cancelled (24 hours before start)""" """Check if reservation can be cancelled (24 hours before start)"""
@@ -65,9 +74,9 @@ class Reservation(db.Model):
"""Check if this reservation conflicts with another""" """Check if this reservation conflicts with another"""
if self.classroom_id != other_reservation.classroom_id: if self.classroom_id != other_reservation.classroom_id:
return False return False
if self.status != ReservationStatus.CONFIRMED: if self.status != ReservationStatus.CONFIRMED.value:
return False return False
if other_reservation.status != ReservationStatus.CONFIRMED: if other_reservation.status != ReservationStatus.CONFIRMED.value:
return False return False
# Check time overlap # Check time overlap
@@ -79,7 +88,7 @@ class Reservation(db.Model):
"""Find conflicting reservations for a specific classroom and time slot""" """Find conflicting reservations for a specific classroom and time slot"""
query = Reservation.query.filter( query = Reservation.query.filter(
Reservation.classroom_id == classroom_id, Reservation.classroom_id == classroom_id,
Reservation.status == ReservationStatus.CONFIRMED, Reservation.status == ReservationStatus.CONFIRMED.value,
Reservation.start_time < end_time, Reservation.start_time < end_time,
Reservation.end_time > start_time Reservation.end_time > start_time
) )
+1 -1
View File
@@ -11,7 +11,7 @@ class Subject(db.Model):
department = db.Column(db.String(100), nullable=False) department = db.Column(db.String(100), nullable=False)
credits = db.Column(db.Integer, nullable=False) credits = db.Column(db.Integer, nullable=False)
# duration_in_minutes = db.Column(db.Integer, nullable=False) # duration_in_minutes = db.Column(db.Integer, nullable=False)
is_active = db.Column(db.Boolean, default=True, nullable=False) 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) created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
+2 -4
View File
@@ -34,7 +34,6 @@ def add_classroom():
# campus_id=form.campus_id.data, # campus_id=form.campus_id.data,
building=form.building.data, building=form.building.data,
code=form.room_number.data, code=form.room_number.data,
name=f"{form.building.data}-{form.room_number.data}",
floor=form.floor.data, floor=form.floor.data,
capacity=form.capacity.data, capacity=form.capacity.data,
description=form.description.data, description=form.description.data,
@@ -106,7 +105,7 @@ def view_classroom(id):
upcoming_reservations = Reservation.query.filter( upcoming_reservations = Reservation.query.filter(
Reservation.classroom_id == id, Reservation.classroom_id == id,
Reservation.start_time > datetime.utcnow(), Reservation.start_time > datetime.utcnow(),
Reservation.status == ReservationStatus.CONFIRMED Reservation.status == ReservationStatus.CONFIRMED.value
).order_by(Reservation.start_time).limit(10).all() ).order_by(Reservation.start_time).limit(10).all()
return render_template('classrooms/view.html', return render_template('classrooms/view.html',
@@ -146,7 +145,6 @@ def edit_classroom(id):
# classroom.campus_id = form.campus_id.data # classroom.campus_id = form.campus_id.data
classroom.building = form.building.data classroom.building = form.building.data
classroom.code = form.room_number.data classroom.code = form.room_number.data
classroom.name = f"{form.building.data}-{form.room_number.data}"
classroom.floor = form.floor.data classroom.floor = form.floor.data
classroom.capacity = form.capacity.data classroom.capacity = form.capacity.data
classroom.description = form.description.data classroom.description = form.description.data
@@ -210,7 +208,7 @@ def get_available_classrooms():
# Check if classroom has conflicting reservations # Check if classroom has conflicting reservations
conflicts = Reservation.query.filter( conflicts = Reservation.query.filter(
Reservation.classroom_id == classroom.id, Reservation.classroom_id == classroom.id,
Reservation.status == ReservationStatus.CONFIRMED, Reservation.status == ReservationStatus.CONFIRMED.value,
Reservation.start_time < end_dt, Reservation.start_time < end_dt,
Reservation.end_time > start_dt Reservation.end_time > start_dt
).all() ).all()
+1 -1
View File
@@ -210,7 +210,7 @@ def get_algorithm_status():
total_classrooms = Classroom.query.filter_by(is_active=True).count() total_classrooms = Classroom.query.filter_by(is_active=True).count()
total_commissions = Commission.query.filter_by(active=True).count() total_commissions = Commission.query.filter_by(active=True).count()
total_reservations = Reservation.query.filter_by(status=ReservationStatus.CONFIRMED).count() total_reservations = Reservation.query.filter_by(status=ReservationStatus.CONFIRMED.value).count()
return jsonify({ return jsonify({
'success': True, 'success': True,
+8 -8
View File
@@ -27,7 +27,7 @@ def today_schedule():
).filter( ).filter(
Reservation.start_time >= today_start, Reservation.start_time >= today_start,
Reservation.start_time <= today_end, Reservation.start_time <= today_end,
Reservation.status.in_([ReservationStatus.CONFIRMED, ReservationStatus.PENDING]) Reservation.status.in_([ReservationStatus.CONFIRMED.value, ReservationStatus.PENDING.value])
).order_by(Reservation.start_time).all() ).order_by(Reservation.start_time).all()
# Create time blocks for timeline view # Create time blocks for timeline view
@@ -49,7 +49,7 @@ def today_schedule():
# Calculate stats # Calculate stats
total_reservations = len(reservations) total_reservations = len(reservations)
confirmed = len([r for r in reservations if r.status == ReservationStatus.CONFIRMED]) confirmed = len([r for r in reservations if r.status == ReservationStatus.CONFIRMED.value])
pending = len([r for r in reservations if r.status == ReservationStatus.PENDING]) pending = len([r for r in reservations if r.status == ReservationStatus.PENDING])
# Get total classrooms and calculate occupied ones # Get total classrooms and calculate occupied ones
@@ -158,7 +158,7 @@ def add_reservation():
from app.models.reservation import ReservationStatus from app.models.reservation import ReservationStatus
existing_reservation = Reservation.query.filter_by( existing_reservation = Reservation.query.filter_by(
classroom_id=form.classroom_id.data, classroom_id=form.classroom_id.data,
status=ReservationStatus.CONFIRMED status=ReservationStatus.CONFIRMED.value
).filter( ).filter(
Reservation.start_time < form.end_time.data, Reservation.start_time < form.end_time.data,
Reservation.end_time > form.start_time.data Reservation.end_time > form.start_time.data
@@ -177,7 +177,7 @@ def add_reservation():
end_time=form.end_time.data, end_time=form.end_time.data,
purpose=form.purpose.data, purpose=form.purpose.data,
notes=form.notes.data, notes=form.notes.data,
status=ReservationStatus.PENDING, status=ReservationStatus.PENDING.value,
expected_attendees=form.expected_attendees.data expected_attendees=form.expected_attendees.data
) )
@@ -209,11 +209,11 @@ def confirm_reservation(id):
reservation = Reservation.query.get_or_404(id) reservation = Reservation.query.get_or_404(id)
# Validación de seguridad: Solo confirmar si está pendiente # Validación de seguridad: Solo confirmar si está pendiente
if reservation.status != ReservationStatus.PENDING: if reservation.status != ReservationStatus.PENDING.value:
flash('Only pending reservations can be confirmed.', 'warning') flash('Only pending reservations can be confirmed.', 'warning')
return redirect(url_for('schedule.today_schedule')) return redirect(url_for('schedule.today_schedule'))
reservation.status = ReservationStatus.CONFIRMED reservation.status = ReservationStatus.CONFIRMED.value
db.session.commit() db.session.commit()
flash( flash(
@@ -343,7 +343,7 @@ def calendar_data():
).filter( ).filter(
Reservation.start_time >= start_date, Reservation.start_time >= start_date,
Reservation.start_time <= end_date, Reservation.start_time <= end_date,
Reservation.status.in_([ReservationStatus.CONFIRMED, ReservationStatus.PENDING]) Reservation.status.in_([ReservationStatus.CONFIRMED.value, ReservationStatus.PENDING.value])
).order_by(Reservation.start_time).all() ).order_by(Reservation.start_time).all()
events = [] events = []
@@ -384,7 +384,7 @@ def api_today_events():
).filter( ).filter(
Reservation.start_time >= today_start, Reservation.start_time >= today_start,
Reservation.start_time <= today_end, Reservation.start_time <= today_end,
Reservation.status == ReservationStatus.CONFIRMED Reservation.status == ReservationStatus.CONFIRMED.value
).order_by(Reservation.start_time).all() ).order_by(Reservation.start_time).all()
events = [] events = []