gmao/app_new/configuration/routes.py
root 31434c5ca2
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run
Validate checkpoint B UI workflows
2026-08-23 18:10:40 +00:00

70 lines
4.4 KiB
Python

from flask import Blueprint, render_template
from flask_login import login_required
from app_new.core.models.college import Site, Building, Zone, Room, RoomProfile, RoomSchedule
from app_new.core.models.equipment import Equipment
from app_new.core.models.maintenance import LotTask
from app_new.core.models.user import User
from app_new.core.models.planning import WorkSchedule
from app_new.contracts.models import Contract
configuration_bp = Blueprint("configuration", __name__, template_folder="templates")
def _status(ok, label, url, detail=None, optional=False, attention=False):
if optional and not ok:
state = "Facultatif"
elif attention:
state = "Attention"
elif ok:
state = "Configuré"
else:
state = "À configurer"
return {"label": label, "state": state, "ok": ok, "url": url, "detail": detail or ""}
@configuration_bp.route("/")
@login_required
def index():
from flask import url_for
sites = Site.query.count()
buildings = Building.query.count()
zones = Zone.query.count()
rooms = Room.query.count()
profiles = RoomProfile.query.count()
unprofiled = Room.query.filter(Room.room_type_id.is_(None)).count()
equipment_without_lot = Equipment.query.filter(Equipment.is_deleted.is_(False), Equipment.lot_id.is_(None)).count()
technicians = User.query.filter_by(is_active=True).all()
scheduled_users = {row[0] for row in WorkSchedule.query.filter_by(is_active=True).with_entities(WorkSchedule.user_id).all()}
tasks_without_duration = LotTask.query.filter(LotTask.is_active.is_(True), (LotTask.duree_minutes.is_(None) | (LotTask.duree_minutes <= 0))).count()
contract_table = Contract.__table__.c
contracts_without_due = Contract.query.filter(contract_table.status == "actif", contract_table.end_date.is_(None)).count()
room_schedules = RoomSchedule.query.count()
sections = [
("ESSENTIEL", [
_status(User.query.filter_by(is_active=True).count() > 0, "Administrateur / utilisateurs", url_for("admin.users")),
_status(sites > 0, "Établissement / site", url_for("buildings.index"), f"{sites} site(s)"),
_status(buildings > 0, "Bâtiments", url_for("buildings.index"), f"{buildings} bâtiment(s)"),
_status(zones > 0, "Zones", url_for("zones.index"), f"{zones} zone(s)"),
_status(rooms > 0, "Locaux / emplacements", url_for("rooms.index"), f"{rooms} local(aux)"),
_status(len(scheduled_users) >= len(technicians) and bool(technicians), "Horaires techniciens", url_for("planning.work_schedules"), f"{len(technicians) - len(scheduled_users)} sans horaires" if technicians else "Aucun technicien actif", attention=bool(technicians) and len(scheduled_users) < len(technicians)),
]),
("MAINTENANCE", [
_status(profiles > 0, "Profils de locaux", url_for("room_profiles.index"), f"{profiles} profil(s)"),
_status(False, "Équipements sans lot (facultatif)", url_for("equipments.index"), f"{equipment_without_lot} équipement(s) sans lot — le lot peut être ajouté plus tard", optional=True),
_status(tasks_without_duration == 0, "Durées préventives", url_for("lots.index"), f"{tasks_without_duration} à renseigner", attention=tasks_without_duration > 0),
_status(room_schedules > 0, "Planning des salles", url_for("planning.room_schedules"), f"{room_schedules} créneau(x)"),
]),
("PATRIMOINE", [
_status(unprofiled == 0, "Locaux avec profil structurel", url_for("rooms.index"), f"{unprofiled} sans type", attention=unprofiled > 0),
_status(True, "Logements de fonction", url_for("housing.index"), "Facultatif", optional=True),
]),
("ENTREPRISES", [_status(contracts_without_due == 0, "Contrats avec échéance", url_for("companies.index"), f"{contracts_without_due} sans échéance", attention=contracts_without_due > 0)]),
("COMPTEURS", [_status(False, "Compteurs", url_for("meters.index"), "Non configuré", optional=True)]),
("CARTOGRAPHIE TECHNIQUE", [_status(False, "Relations techniques", url_for("equipments.index"), "Facultatif", optional=True)]),
("INTÉGRATIONS", [
_status(False, "Pronote", url_for("pronote.index"), "Non configuré", optional=True),
_status(False, "ENT / Outlook / Yeastar / IA", url_for("admin.settings"), "Facultatif", optional=True),
]),
]
return render_template("configuration/index.html", sections=sections)