gmao/app_new/equipments/rooms.py

200 lines
7.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Routes salles - GMAO Collège"""
from datetime import date, datetime, timedelta
from flask import Blueprint, render_template, redirect, url_for, request, flash
from flask_login import login_required
from app_new.extensions import db
from app_new.core.models.college import Room, Zone, Building, RoomType, RoomSchedule
from app_new.core.models.equipment import Equipment
rooms_bp = Blueprint('rooms', __name__, template_folder='templates')
def _room_form_context(room=None):
"""Return all reference data used by the room form.
The building list is deliberately loaded independently from the zone
list. Previously the GET route only supplied ``zones`` which left the
required building select empty and made every room creation impossible.
"""
return {
'room': room,
'buildings': Building.query.order_by(Building.name).all(),
'zones': Zone.query.join(Building).order_by(Building.name, Zone.name).all(),
'room_types': RoomType.query.order_by(RoomType.name).all(),
}
@rooms_bp.route('/')
@login_required
def index():
"""Liste des salles."""
zones_filter = request.args.getlist('zone') or None
room_type_id = request.args.get('room_type', type=int)
query = Room.query.join(Zone).join(Building)
if zones_filter:
query = query.filter(Zone.id.in_(zones_filter))
if room_type_id:
query = query.filter_by(room_type_id=room_type_id)
rooms = query.order_by(Building.name, Zone.name, Room.name).all()
zones = Zone.query.join(Building).order_by(Building.name, Zone.name).all()
room_types = RoomType.query.order_by(RoomType.name).all()
return render_template('equipments/rooms.html',
rooms=rooms, zones=zones, room_types=room_types,
selected_zones=[int(z) for z in zones_filter] if zones_filter else [])
@rooms_bp.route('/<int:id>')
@login_required
def detail(id):
"""Détail d'une salle."""
room = Room.query.get_or_404(id)
today = date.today()
week_start = today - timedelta(days=today.weekday())
courses = RoomSchedule.query.filter_by(
room_id=room.id,
week_start=week_start,
day_of_week=today.weekday(),
).order_by(RoomSchedule.start_time).all()
current_time = datetime.now().time()
current_course = next(
(course for course in courses
if course.start_time <= current_time <= course.end_time),
None,
)
next_course = next(
(course for course in courses if course.start_time > current_time),
None,
)
if current_course:
room_status = {
'status': 'occupee',
'message': 'Salle actuellement occupée',
'course': current_course,
'next_occupied': None,
}
elif courses:
room_status = {
'status': 'libre',
'message': 'Salle libre actuellement',
'course': None,
'next_occupied': next_course.start_time.strftime('%H:%M') if next_course else None,
}
else:
room_status = {
'status': 'inconnu',
'message': "Aucun emploi du temps importé pour cette salle aujourd'hui.",
'course': None,
'next_occupied': None,
}
equipments = Equipment.query.filter(
Equipment.room_id == room.id,
Equipment.is_deleted.is_(False),
).order_by(Equipment.name, Equipment.individual_number).all()
return render_template('equipments/room_detail.html',
room=room, equipments=equipments,
courses=courses, room_status=room_status)
@rooms_bp.route('/new', methods=['GET', 'POST'])
@login_required
def create():
"""Créer une salle."""
if request.method == 'POST':
name = (request.form.get('name') or '').strip()
building_id = request.form.get('building_id', type=int)
zone_id = request.form.get('zone_id', type=int)
building = db.session.get(Building, building_id) if building_id else None
zone = db.session.get(Zone, zone_id) if zone_id else None
errors = []
if not name:
errors.append('Le nom de la salle est obligatoire.')
if not building:
errors.append('Sélectionnez un bâtiment valide.')
if zone and building and zone.building_id != building.id:
errors.append('La zone sélectionnée nappartient pas au bâtiment choisi.')
if errors:
for error in errors:
flash(error, 'danger')
context = _room_form_context()
context['form_data'] = request.form
return render_template('equipments/room_form.html', **context), 400
room = Room(
name=name,
code=request.form.get('code') or None,
zone_id=zone_id,
building_id=building.id,
room_type_id=request.form.get('room_type_id', type=int),
floor=request.form.get('floor', 0, type=int)
)
db.session.add(room)
try:
db.session.commit()
except Exception:
db.session.rollback()
flash('Impossible denregistrer cette salle. Vérifiez les valeurs saisies.', 'danger')
context = _room_form_context()
context['form_data'] = request.form
return render_template('equipments/room_form.html', **context), 400
flash(f"Salle '{room.name}' créée.", 'success')
return redirect(url_for('rooms.index'))
context = _room_form_context()
context['form_data'] = {}
context['title'] = 'Nouvelle salle'
return render_template('equipments/room_form.html', **context)
@rooms_bp.route('/<int:id>/edit', methods=['GET', 'POST'])
@login_required
def edit(id):
"""Modifier une salle."""
room = Room.query.get_or_404(id)
if request.method == 'POST':
name = (request.form.get('name') or '').strip()
building_id = request.form.get('building_id', type=int)
zone_id = request.form.get('zone_id', type=int)
building = db.session.get(Building, building_id) if building_id else None
zone = db.session.get(Zone, zone_id) if zone_id else None
if not name or not building or (zone and zone.building_id != building.id):
flash('Le nom, le bâtiment et une zone cohérente sont obligatoires.', 'danger')
context = _room_form_context(room)
context['form_data'] = request.form
context['title'] = 'Modifier la salle'
return render_template('equipments/room_form.html', **context), 400
room.name = name
room.code = request.form.get('code') or None
room.zone_id = zone_id
room.building_id = building.id
room.room_type_id = request.form.get('room_type_id', type=int)
room.floor = request.form.get('floor', 0, type=int)
try:
db.session.commit()
except Exception:
db.session.rollback()
flash('Impossible denregistrer cette salle. Vérifiez les valeurs saisies.', 'danger')
context = _room_form_context(room)
context['form_data'] = request.form
context['title'] = 'Modifier la salle'
return render_template('equipments/room_form.html', **context), 400
flash(f"Salle '{room.name}' mise à jour.", 'success')
return redirect(url_for('rooms.index'))
context = _room_form_context(room)
context['form_data'] = {}
context['title'] = 'Modifier la salle'
return render_template('equipments/room_form.html', **context)
@rooms_bp.route('/<int:id>/delete', methods=['POST'])
@login_required
def delete(id):
"""Supprimer une salle."""
room = Room.query.get_or_404(id)
db.session.delete(room)
db.session.commit()
flash(f"Salle '{room.name}' supprimée.", 'success')
return redirect(url_for('rooms.index'))