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 flask_login import login_required, current_user
from app_new.extensions import db from app_new.extensions import db
from ..core.models.maintenance import Intervention, InterventionComment 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 ..core.models.user import User
from datetime import datetime from datetime import datetime
@ -109,7 +109,6 @@ def index():
lots=lots, lots=lots,
users=users, users=users,
statuses=INTERVENTION_STATUSES, statuses=INTERVENTION_STATUSES,
workflow_status_order=WORKFLOW_STATUS_ORDERS.get(intervention.workflow_type, WORKFLOW_STATUS_ORDERS['corrective']),
workflow_types=WORKFLOW_TYPES, workflow_types=WORKFLOW_TYPES,
priorities=PRIORITIES, priorities=PRIORITIES,
status_counts=status_counts, status_counts=status_counts,
@ -410,6 +409,10 @@ def detail(id):
statuses=INTERVENTION_STATUSES, statuses=INTERVENTION_STATUSES,
transitions=transitions, transitions=transitions,
history=history, 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(), 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()) 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)) 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']) @interventions_bp.route('/<int:id>/edit', methods=['GET', 'POST'])
@login_required @login_required
def edit(id): 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> <span class="badge bg-secondary ms-1">{{ intervention.quantity_affected }} unité(s) concernée(s)</span>
</div> </div>
{% endif %} {% endif %}
{% if intervention.equipment %}
<a href="{{ url_for('equipments.detail', id=intervention.equipment.id) }}" class="text-decoration-none"> <a href="{{ url_for('equipments.detail', id=intervention.equipment.id) }}" class="text-decoration-none">
{{ intervention.equipment.code or intervention.equipment.name }} {{ intervention.equipment.code or intervention.equipment.name }}
</a> </a>
<br><span class="text-muted small">{{ intervention.equipment.full_path }}</span> <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>
</div> </div>
@ -552,6 +589,29 @@
</div> </div>
</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 --> <!-- Modal Upload Document Intervention -->
<div class="modal fade" id="uploadInterventionDocumentModal" tabindex="-1"> <div class="modal fade" id="uploadInterventionDocumentModal" tabindex="-1">
<div class="modal-dialog"> <div class="modal-dialog">