""" Wizard de création d'équipements par lot - GMAO Collège """ from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, current_app from flask_login import login_required from app_new.extensions import db from app_new.core.models.equipment import Equipment, EquipmentCategory from app_new.core.models.maintenance import Lot from app_new.core.models.college import Room, Building, Zone, RoomType wizard_bp = Blueprint('wizard', __name__, url_prefix='/wizard', template_folder='templates') @wizard_bp.route('/equipments') @login_required def equipment_wizard(): """Page principale du wizard de création d'équipements.""" categories = EquipmentCategory.query.order_by(EquipmentCategory.name).all() buildings = Building.query.order_by(Building.name).all() room_types = RoomType.query.order_by(RoomType.name).all() # Récupérer les lots groupés par catégorie (relation directe) lots_by_category = {} for cat in categories: lots_by_category[cat.id] = [{'id': lot.id, 'name': lot.name} for lot in cat.lots] # Tous les lots pour fallback lots = Lot.query.order_by(Lot.name).all() return render_template('wizard/equipment_wizard.html', lots=lots, categories=categories, buildings=buildings, room_types=room_types, lots_by_category=lots_by_category) @wizard_bp.route('/api/rooms/') @login_required def get_rooms(building_id): """Récupère les salles d'un bâtiment.""" rooms = Room.query.filter_by(building_id=building_id).order_by(Room.name).all() return jsonify([{ 'id': r.id, 'name': r.name, 'zone': r.zone.name if r.zone else None } for r in rooms]) @wizard_bp.route('/api/zones/') @login_required def get_zones(building_id): """Récupère les zones d'un bâtiment.""" zones = Zone.query.filter_by(building_id=building_id).order_by(Zone.name).all() return jsonify([{ 'id': z.id, 'name': z.name } for z in zones]) @wizard_bp.route('/api/lot_tasks/') @login_required def get_lot_tasks(lot_id): """Récupère les tâches préventives d'un lot.""" from app_new.core.models.maintenance import LotTask tasks = LotTask.query.filter_by(lot_id=lot_id).order_by(LotTask.num_tache).all() return jsonify([{ 'id': t.id, 'num_tache': t.num_tache, 'tache': t.tache, 'periodicite': t.periodicite, 'contrat': t.contrat, 'gestionnaire': t.gestionnaire, 'type_maintenance': t.type_maintenance } for t in tasks]) @wizard_bp.route('/equipments/create', methods=['POST']) @login_required def create_equipments(): """Crée les équipements selon les paramètres du wizard.""" try: data = request.get_json() lot_id = data.get('lot_id') category_id = data.get('category_id') equipment_name = data.get('name', '').strip() # Nom personnalisé parent_name = data.get('parent_name') create_parent = data.get('create_parent', False) building_id = data.get('building_id') zone_id = data.get('zone_id') rooms_data = data.get('rooms', []) # [{room_id, count}, ...] tracked_individually = data.get('tracked_individually', False) # Debug current_app.logger.info(f"Création équipements: tracked_individually={tracked_individually}, rooms={rooms_data}") if not lot_id or not category_id: return jsonify({'error': 'Lot et catégorie requis'}), 400 if not rooms_data: return jsonify({'error': 'Au moins une salle requise'}), 400 lot = Lot.query.get(lot_id) category = EquipmentCategory.query.get(category_id) # Nom de base: personnalisé ou catégorie base_name = equipment_name if equipment_name else category.name created_equipments = [] # Étape 1: Créer le parent global (si demandé) parent = None if create_parent and parent_name: parent = Equipment( name=parent_name, lot_id=lot_id, category_id=category_id, is_group=True, parent_id=None ) db.session.add(parent) db.session.flush() # Pour avoir l'ID # Étape 2: Pour chaque salle, créer le groupe et les individuels for room_data in rooms_data: room_id = room_data.get('room_id') count = room_data.get('count', 1) room = Room.query.get(room_id) if not room: continue if tracked_individually: # Avec suivi individuel: créer un groupe + des individus room_group = Equipment( name=f"{base_name} {room.name}", lot_id=lot_id if not parent else None, category_id=category_id if not parent else None, is_group=True, parent_id=parent.id if parent else None, room_id=room_id, quantity=1 ) db.session.add(room_group) db.session.flush() created_equipments.append({ 'type': 'group', 'name': room_group.name, 'room': room.name, 'quantity': 1 }) # Créer les équipements individuels if count > 1: for i in range(1, count + 1): individual = Equipment( name=f"{base_name} {i}", lot_id=lot_id, # Hériter du lot category_id=category_id, # Hériter de la catégorie is_group=False, tracked_individually=True, parent_id=room_group.id, room_id=room_id, position=f"{base_name} n°{i}" ) db.session.add(individual) created_equipments.append({ 'type': 'individual', 'name': individual.name, 'room': room.name }) else: # Sans suivi individuel: créer un seul équipement avec quantity equipment = Equipment( name=f"{base_name} {room.name}", lot_id=lot_id if not parent else None, category_id=category_id if not parent else None, is_group=False, parent_id=parent.id if parent else None, room_id=room_id, quantity=count ) db.session.add(equipment) db.session.flush() created_equipments.append({ 'type': 'equipment', 'name': equipment.name, 'room': room.name, 'quantity': count }) db.session.commit() # Créer les tâches planifiées pour tous les équipements créés for eq in created_equipments: # Récupérer l'équipement depuis la DB pour avoir son ID equipment = Equipment.query.filter_by(name=eq['name']).first() if equipment and equipment.effective_lot_id: equipment.create_scheduled_tasks_from_lot() return jsonify({ 'success': True, 'count': len(created_equipments), 'equipments': created_equipments }) except Exception as e: db.session.rollback() return jsonify({'error': str(e)}), 500 @wizard_bp.route('/equipments/preview', methods=['POST']) @login_required def preview_equipments(): """Prévisualise les équipements qui seront créés.""" data = request.get_json() lot_id = data.get('lot_id') category_id = data.get('category_id') parent_name = data.get('parent_name') create_parent = data.get('create_parent', False) rooms_data = data.get('rooms', []) tracked_individually = data.get('tracked_individually', False) lot = Lot.query.get(lot_id) if lot_id else None category = EquipmentCategory.query.get(category_id) if category_id else None preview = [] # Parent global if create_parent and parent_name: preview.append({ 'level': 0, 'name': parent_name, 'type': 'Groupe parent', 'lot': lot.name if lot else '-', 'category': category.name if category else '-', 'room': '-' }) # Par salle for room_data in rooms_data: room_id = room_data.get('room_id') count = room_data.get('count', 1) room = Room.query.get(room_id) if not room: continue # Groupe salle level = 1 if create_parent else 0 preview.append({ 'level': level, 'name': f"{category.name} {room.name}", 'type': 'Groupe salle', 'lot': lot.name if lot else '-', 'category': category.name if category else '-', 'room': room.name }) # Individuels if tracked_individually: for i in range(1, count + 1): preview.append({ 'level': level + 1, 'name': f"{category.name} {i}", 'type': 'Individuel', 'lot': '(hérité)', 'category': '(hérité)', 'room': room.name }) return jsonify({ 'preview': preview, 'total': len(preview) })