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("//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("//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("//items//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("//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("//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))