Réparer les interventions et modifier leur localisation
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run

This commit is contained in:
root 2026-08-21 10:32:00 +00:00
parent d1fef99def
commit cfe242ee11
2 changed files with 97 additions and 6 deletions

View file

@ -3,7 +3,7 @@ from flask import Blueprint, render_template, redirect, url_for, request, flash,
from flask_login import login_required, current_user
from app_new.extensions import db
from ..core.models.maintenance import Intervention, InterventionComment
from ..core.models.equipment import Equipment
from ..core.models.equipment import Equipment, EquipmentCategory
from ..core.models.user import User
from datetime import datetime
@ -109,7 +109,6 @@ def index():
lots=lots,
users=users,
statuses=INTERVENTION_STATUSES,
workflow_status_order=WORKFLOW_STATUS_ORDERS.get(intervention.workflow_type, WORKFLOW_STATUS_ORDERS['corrective']),
workflow_types=WORKFLOW_TYPES,
priorities=PRIORITIES,
status_counts=status_counts,
@ -410,6 +409,10 @@ def detail(id):
statuses=INTERVENTION_STATUSES,
transitions=transitions,
history=history,
workflow_status_order=WORKFLOW_STATUS_ORDERS.get(intervention.workflow_type, WORKFLOW_STATUS_ORDERS['corrective']),
rooms=Room.query.order_by(Room.name).all(),
categories=EquipmentCategory.query.order_by(EquipmentCategory.name).all(),
equipment_choices=Equipment.query.filter_by(is_deleted=False).order_by(Equipment.name).all(),
services=Service.query.filter_by(is_active=True).order_by(Service.name).all(),
companies=Company.query.filter_by(is_active=True).order_by(Company.name).all())
@ -445,6 +448,34 @@ def save_work_details(id):
return redirect(url_for('interventions.detail', id=id))
@interventions_bp.route('/<int:id>/location', methods=['POST'])
@login_required
def update_location(id):
"""Modifie la localisation en cascade salle -> catégorie -> équipement."""
intervention = Intervention.query.get_or_404(id)
room_id = request.form.get('room_id', type=int)
category_id = request.form.get('category_id', type=int)
equipment_id = request.form.get('equipment_id', type=int)
room = Room.query.get(room_id) if room_id else None
category = EquipmentCategory.query.get(category_id) if category_id else None
equipment = Equipment.query.get(equipment_id) if equipment_id else None
if room_id and not room:
flash('Salle invalide.', 'danger')
return redirect(url_for('interventions.detail', id=id))
if equipment:
if room_id and equipment.room_id != room_id:
flash("L'équipement choisi n'est pas dans la salle sélectionnée.", 'danger')
return redirect(url_for('interventions.detail', id=id))
if category_id and equipment.effective_category_id != category_id:
flash("L'équipement choisi ne correspond pas à la catégorie sélectionnée.", 'danger')
return redirect(url_for('interventions.detail', id=id))
intervention.room_id = room.id if room else None
intervention.equipment_id = equipment.id if equipment else None
db.session.commit()
flash('Salle et équipement concernés mis à jour.', 'success')
return redirect(url_for('interventions.detail', id=id))
@interventions_bp.route('/<int:id>/edit', methods=['GET', 'POST'])
@login_required
def edit(id):

View file

@ -286,10 +286,47 @@
<span class="badge bg-secondary ms-1">{{ intervention.quantity_affected }} unité(s) concernée(s)</span>
</div>
{% endif %}
{% if intervention.equipment %}
<a href="{{ url_for('equipments.detail', id=intervention.equipment.id) }}" class="text-decoration-none">
{{ intervention.equipment.code or intervention.equipment.name }}
</a>
<br><span class="text-muted small">{{ intervention.equipment.full_path }}</span>
{% else %}
<span class="text-muted">Aucun équipement précis associé</span>
{% endif %}
</div>
</div>
<!-- Localisation modifiable en cascade -->
<div class="card border-0 shadow-sm mb-3 border-start border-success border-4">
<div class="card-body">
<h6 class="card-title"><i class="bi bi-geo-alt text-success"></i> Salle et équipement concernés</h6>
<form method="POST" action="{{ url_for('interventions.update_location', id=intervention.id) }}" id="intervention-location-form">
<div class="row g-2">
<div class="col-md-4">
<label class="form-label small">1. Salle</label>
<select name="room_id" id="intervention-room" class="form-select form-select-sm">
<option value="">— Aucune salle —</option>
{% for room in rooms %}<option value="{{ room.id }}" {% if intervention.room_id == room.id %}selected{% endif %}>{{ room.full_name }}</option>{% endfor %}
</select>
</div>
<div class="col-md-4">
<label class="form-label small">2. Type déquipement</label>
<select name="category_id" id="intervention-category" class="form-select form-select-sm">
<option value="">— Toutes les catégories —</option>
{% for category in categories %}<option value="{{ category.id }}" {% if intervention.equipment and intervention.equipment.effective_category_id == category.id %}selected{% endif %}>{{ category.name }}</option>{% endfor %}
</select>
</div>
<div class="col-md-4">
<label class="form-label small">3. Équipement précis</label>
<select name="equipment_id" id="intervention-equipment" class="form-select form-select-sm">
<option value="">— Aucun équipement précis —</option>
{% for equipment in equipment_choices %}<option value="{{ equipment.id }}" data-room="{{ equipment.room_id or '' }}" data-category="{{ equipment.effective_category_id or '' }}" {% if intervention.equipment_id == equipment.id %}selected{% endif %}>{{ equipment.name }}{% if equipment.code %} ({{ equipment.code }}){% endif %}</option>{% endfor %}
</select>
</div>
</div>
<button type="submit" class="btn btn-outline-success btn-sm mt-3"><i class="bi bi-save"></i> Enregistrer la localisation</button>
</form>
</div>
</div>
@ -552,6 +589,29 @@
</div>
</div>
<script>
(() => {
const room = document.getElementById('intervention-room');
const category = document.getElementById('intervention-category');
const equipment = document.getElementById('intervention-equipment');
if (!room || !category || !equipment) return;
const filter = () => {
const roomId = room.value;
const categoryId = category.value;
[...equipment.options].forEach(option => {
if (!option.value) { option.hidden = false; return; }
const matchesRoom = !roomId || option.dataset.room === roomId;
const matchesCategory = !categoryId || option.dataset.category === categoryId;
option.hidden = !(matchesRoom && matchesCategory);
if (option.hidden && option.selected) equipment.value = '';
});
};
room.addEventListener('change', filter);
category.addEventListener('change', filter);
filter();
})();
</script>
<!-- Modal Upload Document Intervention -->
<div class="modal fade" id="uploadInterventionDocumentModal" tabindex="-1">
<div class="modal-dialog">