186 lines
7.4 KiB
Python
186 lines
7.4 KiB
Python
"""
|
|
Modèle College et Building - GMAO Collège
|
|
Gestion des collèges et bâtiments
|
|
Compatible avec la base de données existante
|
|
"""
|
|
from datetime import datetime, timezone
|
|
from ...extensions import db
|
|
|
|
|
|
class College(db.Model):
|
|
"""Collège."""
|
|
__tablename__ = "colleges"
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
name = db.Column(db.String(255), nullable=False)
|
|
address = db.Column(db.Text, nullable=True)
|
|
city = db.Column(db.String(100), nullable=True)
|
|
zip_code = db.Column(db.String(10), nullable=True)
|
|
phone = db.Column(db.String(20), nullable=True)
|
|
email = db.Column(db.String(100), nullable=True)
|
|
website = db.Column(db.String(255), nullable=True)
|
|
logo = db.Column(db.String(255), nullable=True)
|
|
is_active = db.Column(db.Boolean, default=True)
|
|
created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc))
|
|
updated_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
|
|
|
# Relations - buildings n'a pas de college_id, pas de relation directe
|
|
|
|
def __repr__(self):
|
|
return f"<College {self.name}>"
|
|
|
|
|
|
class Site(db.Model):
|
|
"""Site physique : collège, logements de fonction, annexe, etc."""
|
|
__tablename__ = "sites"
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
name = db.Column(db.String(120), nullable=False, unique=True)
|
|
site_type = db.Column(db.String(40), nullable=False, default="college")
|
|
address = db.Column(db.Text, nullable=True)
|
|
is_active = db.Column(db.Boolean, nullable=False, default=True)
|
|
created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc))
|
|
buildings = db.relationship("Building", back_populates="site", lazy="dynamic")
|
|
|
|
|
|
class Building(db.Model):
|
|
"""Bâtiment du collège."""
|
|
__tablename__ = "buildings"
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
name = db.Column(db.String(100), nullable=False)
|
|
description = db.Column(db.Text, nullable=True)
|
|
site_id = db.Column(db.Integer, db.ForeignKey("sites.id"), nullable=True, index=True)
|
|
|
|
# Relations - utiliser overlaps pour éviter warning SQLAlchemy
|
|
rooms = db.relationship("Room", overlaps="building", lazy="dynamic")
|
|
zones = db.relationship("Zone", back_populates="building", lazy="dynamic")
|
|
site = db.relationship("Site", back_populates="buildings")
|
|
|
|
@property
|
|
def room_count(self):
|
|
"""Nombre de salles dans le bâtiment."""
|
|
return self.rooms.count()
|
|
|
|
def __repr__(self):
|
|
return f"<Building {self.name}>"
|
|
|
|
|
|
class HousingUnit(db.Model):
|
|
"""Logement de fonction et historique courant de son occupation."""
|
|
__tablename__ = "housing_units"
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
name = db.Column(db.String(120), nullable=False)
|
|
code = db.Column(db.String(40), nullable=True, unique=True)
|
|
building_id = db.Column(db.Integer, db.ForeignKey("buildings.id"), nullable=False, index=True)
|
|
housing_type = db.Column(db.String(40), nullable=False, default="fonction")
|
|
occupancy_status = db.Column(db.String(30), nullable=False, default="vacant")
|
|
occupant_name = db.Column(db.String(150), nullable=True)
|
|
occupant_contact = db.Column(db.String(150), nullable=True)
|
|
occupancy_start = db.Column(db.Date, nullable=True)
|
|
occupancy_end = db.Column(db.Date, nullable=True)
|
|
notes = db.Column(db.Text, nullable=True)
|
|
is_active = db.Column(db.Boolean, nullable=False, default=True)
|
|
created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc))
|
|
updated_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
|
|
|
building = db.relationship("Building", backref=db.backref("housing_units", lazy="dynamic"))
|
|
rooms = db.relationship("Room", back_populates="housing_unit", lazy="dynamic")
|
|
|
|
|
|
class Zone(db.Model):
|
|
"""Zone dans un bâtiment."""
|
|
__tablename__ = "zones"
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
name = db.Column(db.String(100), nullable=False)
|
|
building_id = db.Column(db.Integer, db.ForeignKey("buildings.id"), nullable=False)
|
|
|
|
# Relations
|
|
building = db.relationship("Building", back_populates="zones")
|
|
rooms = db.relationship("Room", back_populates="zone")
|
|
|
|
@property
|
|
def full_name(self):
|
|
"""Nom complet avec bâtiment."""
|
|
if self.building:
|
|
return f"{self.building.name} - {self.name}"
|
|
return self.name
|
|
|
|
def __repr__(self):
|
|
return f"<Zone {self.name}>"
|
|
|
|
|
|
class Room(db.Model):
|
|
"""Salle du collège."""
|
|
__tablename__ = "rooms"
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
name = db.Column(db.String(100), nullable=False)
|
|
code = db.Column(db.String(20), nullable=True)
|
|
zone_id = db.Column(db.Integer, db.ForeignKey("zones.id"), nullable=True)
|
|
floor = db.Column(db.Integer, default=0)
|
|
building_id = db.Column(db.Integer, db.ForeignKey("buildings.id"), nullable=False)
|
|
room_type_id = db.Column(db.Integer, db.ForeignKey("room_types.id"), nullable=True)
|
|
housing_unit_id = db.Column(db.Integer, db.ForeignKey("housing_units.id"), nullable=True, index=True)
|
|
# Libelle historique conserve pour les imports anterieurs a zone_id.
|
|
legacy_zone_name = db.Column("zone", db.String(100), nullable=True)
|
|
|
|
# Relations - utiliser overlaps pour éviter warning SQLAlchemy
|
|
building = db.relationship("Building", overlaps="rooms")
|
|
zone = db.relationship("Zone", back_populates="rooms")
|
|
room_type = db.relationship("RoomType", back_populates="rooms")
|
|
equipments = db.relationship("Equipment", back_populates="room")
|
|
housing_unit = db.relationship("HousingUnit", back_populates="rooms")
|
|
|
|
@property
|
|
def full_name(self):
|
|
"""Nom complet avec bâtiment."""
|
|
if self.building:
|
|
return f"{self.building.name} - {self.name}"
|
|
return self.name
|
|
|
|
def __repr__(self):
|
|
return f"<Room {self.name}>"
|
|
|
|
|
|
class RoomType(db.Model):
|
|
"""Type de salle."""
|
|
__tablename__ = "room_types"
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
name = db.Column(db.String(100), nullable=False)
|
|
description = db.Column(db.Text, nullable=True)
|
|
is_teaching = db.Column(db.Boolean, default=False)
|
|
color = db.Column(db.String(20), nullable=True)
|
|
icon = db.Column(db.String(50), nullable=True)
|
|
|
|
# Relation vers les salles
|
|
rooms = db.relationship("Room", back_populates="room_type")
|
|
|
|
def __repr__(self):
|
|
return f"<RoomType {self.name}>"
|
|
|
|
|
|
class RoomSchedule(db.Model):
|
|
"""Emploi du temps d'une salle."""
|
|
__tablename__ = "room_schedules"
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
room_id = db.Column(db.Integer, db.ForeignKey("rooms.id"), nullable=False)
|
|
week_start = db.Column(db.Date, nullable=False)
|
|
day_of_week = db.Column(db.Integer, nullable=False)
|
|
start_time = db.Column(db.Time, nullable=False)
|
|
end_time = db.Column(db.Time, nullable=False)
|
|
subject = db.Column(db.String(100), nullable=True)
|
|
teacher = db.Column(db.String(100), nullable=True)
|
|
class_name = db.Column(db.String(50), nullable=True)
|
|
course_name = db.Column(db.String(255), nullable=True)
|
|
created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc))
|
|
|
|
# Relations
|
|
room = db.relationship("Room", backref="schedules")
|
|
|
|
def __repr__(self):
|
|
return f"<RoomSchedule {self.room.name} - {self.day_of_week}>"
|