gmao/app_new/room_profiles/routes.py

155 lines
7.1 KiB
Python

from flask import Blueprint, render_template, request, redirect, url_for, flash
from flask_login import login_required
from app_new.extensions import db
from app_new.core.models.college import RoomProfile, RoomProfileItem, RoomType, Room, RoomSurface
from app_new.core.models.equipment import EquipmentCategory
from app_new.core.models.maintenance import Lot
from app_new.core.services.equipment_creation import create_equipment
room_profiles_bp = Blueprint("room_profiles", __name__, template_folder="templates")
def _context(profile=None):
return {
"profile": profile,
"room_types": RoomType.query.order_by(RoomType.name).all(),
"categories": EquipmentCategory.query.order_by(EquipmentCategory.name).all(),
"lots": Lot.query.order_by(Lot.name).all(),
}
@room_profiles_bp.route("/")
@login_required
def index():
return render_template("room_profiles/index.html", profiles=RoomProfile.query.order_by(RoomProfile.name).all())
@room_profiles_bp.route("/new", methods=["GET", "POST"])
@login_required
def new():
if request.method == "POST":
name = (request.form.get("name") or "").strip()
if not name:
flash("Le nom du profil est obligatoire.", "danger")
return render_template("room_profiles/form.html", title="Nouveau profil", **_context()), 400
if RoomProfile.query.filter(db.func.lower(RoomProfile.name) == name.lower()).first():
flash("Un profil porte déjà ce nom.", "danger")
return render_template("room_profiles/form.html", title="Nouveau profil", **_context()), 400
profile = RoomProfile(
name=name,
description=(request.form.get("description") or "").strip() or None,
room_type_id=request.form.get("room_type_id", type=int) or None,
)
db.session.add(profile)
db.session.commit()
flash("Profil créé. Ajoutez ses propositions puis prévisualisez avant toute création.", "success")
return redirect(url_for("room_profiles.edit", id=profile.id))
return render_template("room_profiles/form.html", title="Nouveau profil", **_context())
@room_profiles_bp.route("/<int:id>/edit", methods=["GET", "POST"])
@login_required
def edit(id):
profile = RoomProfile.query.get_or_404(id)
if request.method == "POST":
profile.name = (request.form.get("name") or "").strip()
profile.description = (request.form.get("description") or "").strip() or None
profile.room_type_id = request.form.get("room_type_id", type=int) or None
if not profile.name:
flash("Le nom du profil est obligatoire.", "danger")
return render_template("room_profiles/form.html", title="Modifier le profil", **_context(profile)), 400
db.session.commit()
flash("Profil mis à jour.", "success")
return redirect(url_for("room_profiles.edit", id=profile.id))
return render_template("room_profiles/form.html", title="Modifier le profil", **_context(profile))
@room_profiles_bp.route("/<int:id>/items", methods=["POST"])
@login_required
def add_item(id):
profile = RoomProfile.query.get_or_404(id)
label = (request.form.get("label") or "").strip()
quantity = request.form.get("quantity", 1, type=int)
if not label or not quantity or quantity < 1:
flash("Libellé et quantité positive sont obligatoires.", "danger")
return redirect(url_for("room_profiles.edit", id=id))
item = RoomProfileItem(
profile_id=profile.id,
label=label,
category_id=request.form.get("category_id", type=int) or None,
lot_id=request.form.get("lot_id", type=int) or None,
quantity=quantity,
is_group=request.form.get("is_group") == "1",
enabled_by_default=request.form.get("enabled_by_default") == "1",
sort_order=request.form.get("sort_order", 0, type=int),
)
db.session.add(item)
db.session.commit()
flash("Proposition ajoutée au profil.", "success")
return redirect(url_for("room_profiles.edit", id=id))
@room_profiles_bp.route("/<int:profile_id>/items/<int:item_id>/delete", methods=["POST"])
@login_required
def delete_item(profile_id, item_id):
item = RoomProfileItem.query.filter_by(id=item_id, profile_id=profile_id).first_or_404()
db.session.delete(item)
db.session.commit()
flash("Proposition retirée du profil.", "success")
return redirect(url_for("room_profiles.edit", id=profile_id))
@room_profiles_bp.route("/<int:id>/preview", methods=["GET", "POST"])
@login_required
def preview(id):
profile = RoomProfile.query.get(id)
if profile is None:
from flask import abort
abort(404)
room_ids = request.form.getlist("room_ids", type=int) if request.method == "POST" else request.args.getlist("room_id", type=int)
rooms = Room.query.filter(Room.id.in_(room_ids)).order_by(Room.name).all() if room_ids else []
items = [item for item in profile.items if item.enabled_by_default]
if request.method == "POST" and request.form.get("validate") == "1":
selected = {int(value) for value in request.form.getlist("item_ids") if value.isdigit()}
if not rooms or not selected:
flash("Sélectionnez au moins un local et une proposition.", "danger")
return render_template("room_profiles/preview.html", profile=profile, rooms=rooms, items=items)
created = 0
for room in rooms:
for item in items:
if item.id not in selected:
continue
quantity = request.form.get(f"quantity_{item.id}", item.quantity, type=int)
if quantity < 1:
continue
create_equipment(
name=item.label,
category_id=item.category_id,
lot_id=item.lot_id,
room_id=room.id,
quantity=quantity,
is_group=item.is_group,
)
created += 1
db.session.commit()
flash(f"{created} proposition(s) appliquée(s). Les équipements ont été créés via le service commun.", "success")
return redirect(url_for("rooms.index"))
return render_template("room_profiles/preview.html", profile=profile, rooms=rooms, items=items)
@room_profiles_bp.route("/<int:id>/surfaces", methods=["POST"])
@login_required
def add_surface(id):
profile = RoomProfile.query.get_or_404(id)
surface_type = request.form.get("surface_type")
material = (request.form.get("material") or "").strip()
if surface_type not in {"mur", "sol", "plafond"} or not material:
flash("Type et matériau de surface obligatoires.", "danger")
return redirect(url_for("room_profiles.edit", id=id))
db.session.add(RoomSurface(profile_id=profile.id, surface_type=surface_type, material=material,
finish=(request.form.get("finish") or "").strip() or None,
label=(request.form.get("label") or "").strip() or None))
db.session.commit()
flash("Composition proposée ajoutée.", "success")
return redirect(url_for("room_profiles.edit", id=id))