703 lines
37 KiB
HTML
703 lines
37 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}{{ equipment.name }} — GMAO Collège{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<!-- En-tête avec type indicator -->
|
|
<div class="d-flex justify-content-between align-items-start mb-4">
|
|
<div>
|
|
<div class="mb-2">
|
|
{% if equipment.is_group %}
|
|
{% if equipment.parent_id %}
|
|
<span class="badge bg-success fs-6"><i class="bi bi-diagram-3 me-1"></i>Sous-groupe</span>
|
|
{% else %}
|
|
<span class="badge bg-primary fs-6"><i class="bi bi-collection me-1"></i>Groupe</span>
|
|
{% endif %}
|
|
{% elif equipment.parent_id %}
|
|
<span class="badge bg-warning text-dark fs-6"><i class="bi bi-box me-1"></i>Suivi individuel</span>
|
|
{% else %}
|
|
<span class="badge bg-secondary fs-6"><i class="bi bi-box me-1"></i>Équipement simple</span>
|
|
{% endif %}
|
|
</div>
|
|
<h1 class="h2 mb-1">
|
|
<i class="bi bi-pc-display me-2"></i>{{ equipment.name }}
|
|
{% if equipment.code %}<small class="text-muted">({{ equipment.code }})</small>{% endif %}
|
|
</h1>
|
|
{% if equipment.parent %}
|
|
<small class="text-muted">
|
|
<i class="bi bi-arrow-up-circle me-1"></i>
|
|
Parent: <a href="{{ url_for('equipments.detail', id=equipment.parent.id) }}">{{ equipment.parent.name }}</a>
|
|
</small>
|
|
{% endif %}
|
|
{% if equipment.tree_depth > 0 %}
|
|
<div class="small text-muted mt-1">
|
|
<i class="bi bi-diagram-2 me-1"></i> Hiérarchie :
|
|
{% for i in range(equipment.tree_depth) %} <i class="bi bi-arrow-return-right text-muted"></i>{% endfor %}
|
|
<strong>{{ equipment.tree_path }}</strong>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<div>
|
|
{% if equipment.status != 'jete' %}
|
|
<a href="{{ url_for('equipments.edit', id=equipment.id) }}" class="btn btn-outline-primary">
|
|
<i class="bi bi-pencil"></i> Modifier
|
|
</a>
|
|
<a href="{{ url_for('equipments_restrictions.restrictions', id=equipment.id) }}" class="btn btn-outline-warning">
|
|
<i class="bi bi-shield-exclamation"></i> Restrictions
|
|
</a>
|
|
<a href="{{ url_for('interventions.create') }}?equipment_id={{ equipment.id }}" class="btn btn-danger">
|
|
<i class="bi bi-wrench"></i> Intervention
|
|
</a>
|
|
{% if equipment.mobility != 'fixe' %}<a href="{{ url_for('equipments.move_to_room', id=equipment.id) }}" class="btn btn-outline-secondary"><i class="bi bi-arrow-left-right"></i> Déplacer</a>{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Alertes -->
|
|
{% if equipment.lifecycle_status == 'en_reparation' %}
|
|
<div class="alert alert-warning d-flex justify-content-between align-items-center"><span><i class="bi bi-tools"></i> Retiré provisoirement pour réparation depuis {{ equipment.unavailable_since|datetime_fmt }}.</span><form method="post" action="{{ url_for('equipments.complete_repair', id=equipment.id) }}"><button class="btn btn-success btn-sm" type="submit">Réparation terminée</button></form></div>
|
|
{% elif equipment.status != 'jete' %}
|
|
<div class="d-flex gap-2 mb-3">
|
|
<form method="post" action="{{ url_for('equipments.start_repair', id=equipment.id) }}"><button class="btn btn-outline-warning btn-sm" type="submit"><i class="bi bi-tools"></i> Retirer pour réparation</button></form>
|
|
<form method="post" action="{{ url_for('equipments.mark_as_trash', id=equipment.id) }}" class="row g-2">
|
|
<div class="col-auto"><input class="form-control form-control-sm" type="date" name="planned_disposal_date" title="Date prévue"></div>
|
|
<div class="col-auto"><input class="form-control form-control-sm" name="reason" placeholder="Motif de mise au rebut"></div>
|
|
<div class="col-auto"><button class="btn btn-outline-danger btn-sm" type="submit">Prévoir la mise au rebut</button></div>
|
|
</form>
|
|
</div>
|
|
{% endif %}
|
|
{% if equipment.status == 'a_jeter' %}
|
|
<div class="alert alert-danger d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<i class="bi bi-exclamation-triangle me-2"></i>
|
|
<strong>Cet équipement est marqué comme à jeter.</strong>
|
|
{% if equipment.planned_disposal_date %}<span>Date prévue : {{ equipment.planned_disposal_date|date_fmt }}.</span>{% endif %}
|
|
{% if equipment.disposal_reason %}<span>Motif : {{ equipment.disposal_reason }}.</span>{% endif %}
|
|
</div>
|
|
<div>
|
|
<form action="{{ url_for('equipments.confirm_trashed', id=equipment.id) }}" method="POST" style="display:inline;">
|
|
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Confirmer la mise au rebut ?')">
|
|
<i class="bi bi-trash"></i> Confirmer
|
|
</button>
|
|
</form>
|
|
<form action="{{ url_for('equipments.cancel_trash', id=equipment.id) }}" method="POST" style="display:inline;">
|
|
<button type="submit" class="btn btn-success btn-sm">
|
|
<i class="bi bi-arrow-counterclockwise"></i> Annuler
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% elif equipment.status == 'jete' %}
|
|
<div class="alert alert-dark">
|
|
<i class="bi bi-archive me-2"></i>
|
|
<strong>Équipement mis au rebut.</strong>
|
|
<span class="text-muted">L'historique reste consultable.</span>
|
|
</div>
|
|
{% elif equipment.needs_deep_work %}
|
|
<div class="alert alert-warning">
|
|
<i class="bi bi-exclamation-octagon me-2"></i>
|
|
<strong>Alerte récurrence :</strong> {{ equipment.curative_count }} interventions curatives. Travaux profonds recommandés.
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="row">
|
|
<!-- Colonne principale -->
|
|
<div class="col-lg-8">
|
|
<!-- Informations principales -->
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<i class="bi bi-info-circle me-1"></i> Informations
|
|
</div>
|
|
<div class="card-body">
|
|
<table class="table table-sm mb-0">
|
|
<tr>
|
|
<th style="width: 30%;">Statut</th>
|
|
<td><span class="badge {{ equipment.status|status_badge }}">{{ equipment.status|format_status }}</span></td>
|
|
</tr>
|
|
<tr><th>Mobilité</th><td>{{ equipment.mobility|replace('_', ' ')|title }}</td></tr>
|
|
{% if equipment.serial_number %}<tr><th>Numéro de série</th><td><code>{{ equipment.serial_number }}</code></td></tr>{% endif %}
|
|
{% if equipment.manufacturer or equipment.model_reference %}<tr><th>Fabricant / modèle</th><td>{{ equipment.manufacturer or '—' }} / {{ equipment.model_reference or '—' }}</td></tr>{% endif %}
|
|
{% if equipment.supplier %}<tr><th>Fournisseur</th><td><a href="{{ url_for('companies.detail', id=equipment.supplier.id) }}">{{ equipment.supplier.name }}</a></td></tr>{% endif %}
|
|
|
|
{% if equipment.is_group %}
|
|
<tr>
|
|
<th>Quantité déclarée</th>
|
|
<td>
|
|
<span class="badge bg-primary fs-5">{{ equipment.quantity }}</span> unités
|
|
<div class="small text-muted mt-1">
|
|
{{ equipment.individualized_quantity }} individualisée(s),
|
|
{{ equipment.unindividualized_quantity }} encore gérée(s) en quantité
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Suivi individuel</th>
|
|
<td>
|
|
{% if equipment.tracked_individually %}
|
|
<span class="badge bg-success"><i class="bi bi-check-circle me-1"></i>Obligatoire</span>
|
|
{% else %}
|
|
<span class="badge bg-secondary"><i class="bi bi-dash-circle me-1"></i>Optionnel</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% elif equipment.is_individual %}
|
|
<tr>
|
|
<th>Numéro</th>
|
|
<td>
|
|
{% if equipment.individual_number %}
|
|
<span class="badge bg-warning text-dark fs-5">#{{ equipment.individual_number }}</span>
|
|
{% else %}
|
|
<span class="text-muted">Non numéroté</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% if equipment.position %}
|
|
<tr>
|
|
<th>Position</th>
|
|
<td>{{ equipment.position }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
<tr>
|
|
<th>Catégorie</th>
|
|
<td>
|
|
{% if equipment.category %}
|
|
<span class="badge bg-secondary">{{ equipment.category.name }}</span>
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
{% if equipment.parent and equipment.parent.category %}
|
|
<small class="text-muted ms-1">(héritée du parent)</small>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th>Localisation</th>
|
|
<td>
|
|
{% if equipment.effective_room %}
|
|
<i class="bi bi-geo-alt me-1 text-danger"></i>
|
|
<a href="{{ url_for('rooms.detail', id=equipment.effective_room.id) }}">
|
|
{{ equipment.effective_room.name }}
|
|
</a>
|
|
{% if equipment.parent and equipment.room_id %}
|
|
<small class="text-muted">(propre)</small>
|
|
{% elif equipment.parent and not equipment.room_id %}
|
|
<small class="text-muted">(héritée du parent)</small>
|
|
{% endif %}
|
|
{% elif equipment.is_group and not equipment.parent %}
|
|
<span class="text-muted"><i class="bi bi-dash me-1"></i>Non localisé (groupe parent)</span>
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
|
|
{% if equipment.code %}
|
|
<tr>
|
|
<th>Code / N° série</th>
|
|
<td><code>{{ equipment.code }}</code></td>
|
|
</tr>
|
|
{% endif %}
|
|
|
|
<tr>
|
|
<th>Lot</th>
|
|
<td>
|
|
{% if equipment.effective_lot %}
|
|
<a href="{{ url_for('lots.detail', id=equipment.effective_lot.id) }}" class="badge bg-info text-dark text-decoration-none">
|
|
<i class="bi bi-box-se me-1"></i>{{ equipment.effective_lot.name }}
|
|
</a>
|
|
{% if equipment.lot %}
|
|
<small class="text-muted ms-1">(propre)</small>
|
|
{% elif equipment.parent %}
|
|
<small class="text-muted ms-1">(hérité du parent)</small>
|
|
{% endif %}
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{% if quantity_movements %}
|
|
<div class="card mb-3"><div class="card-header"><i class="bi bi-arrow-left-right"></i> Mouvements quantitatifs</div><div class="table-responsive"><table class="table table-sm mb-0"><thead><tr><th>Date</th><th>Origine</th><th>Destination</th><th>Quantité</th><th>Motif</th></tr></thead><tbody>{% for movement in quantity_movements %}<tr><td>{{ movement.moved_at|datetime_fmt }}</td><td>{{ movement.source_room.full_name if movement.source_room else 'Stock non localisé' }}</td><td>{{ movement.target_room.full_name }}</td><td><strong>{{ movement.quantity }}</strong></td><td>{{ movement.reason or '—' }}</td></tr>{% endfor %}</tbody></table></div></div>
|
|
{% endif %}
|
|
|
|
<!-- Compteurs -->
|
|
{% set meters_list = equipment.meters.all() %}
|
|
{% if meters_list %}
|
|
<div class="card mb-3">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<span><i class="bi bi-speedometer2 me-1"></i> Compteurs</span>
|
|
<span class="badge bg-primary">{{ meters_list|length }}</span>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Nom</th>
|
|
<th>Type</th>
|
|
<th>Valeur</th>
|
|
<th>Unité</th>
|
|
<th>Dernier relevé</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for meter in meters_list %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ url_for('meters.detail', meter_id=meter.id) }}">
|
|
{{ meter.name }}
|
|
</a>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-secondary">{{ meter.type|title }}</span>
|
|
</td>
|
|
<td><strong>{{ meter.current_value }}</strong></td>
|
|
<td>{{ meter.unit }}</td>
|
|
<td>
|
|
{% if meter.last_reading_date %}
|
|
{{ meter.last_reading_date.strftime('%d/%m/%Y') }}
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<a href="{{ url_for('meters.detail', meter_id=meter.id) }}" class="btn btn-sm btn-outline-primary">
|
|
<i class="bi bi-eye"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Consommables -->
|
|
{% set consumables_list = equipment.consumables.all() %}
|
|
<div class="card mb-3">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<span><i class="bi bi-boxes me-1"></i> Consommables</span>
|
|
<span class="badge bg-primary">{{ consumables_list|length }}</span>
|
|
</div>
|
|
{% if consumables_list %}
|
|
<div class="table-responsive">
|
|
<table class="table table-sm table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Nom</th>
|
|
<th>Référence</th>
|
|
<th>Intervalle remplacement</th>
|
|
<th>Notes</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for ec in consumables_list %}
|
|
<tr>
|
|
<td>
|
|
{% if ec.consumable %}
|
|
<a href="{{ url_for('planning.consumables') }}">
|
|
{{ ec.consumable.name }}
|
|
</a>
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if ec.consumable and ec.consumable.reference %}
|
|
<code>{{ ec.consumable.reference }}</code>
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if ec.replacement_interval_days %}
|
|
{{ ec.replacement_interval_days }} jours
|
|
{% elif ec.replacement_interval_hours %}
|
|
{{ ec.replacement_interval_hours }} heures
|
|
{% elif ec.replacement_interval_cycles %}
|
|
{{ ec.replacement_interval_cycles }} cycles
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if ec.notes %}
|
|
<small>{{ ec.notes[:50] }}{% if ec.notes|length > 50 %}...{% endif %}</small>
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="card-body text-center text-muted">
|
|
<i class="bi bi-inbox fs-4 d-block mb-2"></i>
|
|
<p class="mb-0">Aucun consommable associé</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Documents -->
|
|
{% set documents_list = equipment.documents %}
|
|
<div class="card mb-3">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<span><i class="bi bi-file-earmark me-1"></i> Documents</span>
|
|
<span class="badge bg-primary">{{ documents_list|length }}</span>
|
|
</div>
|
|
{% if documents_list %}
|
|
<div class="table-responsive">
|
|
<table class="table table-sm table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Nom</th>
|
|
<th>Type</th>
|
|
<th>Ajouté le</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for doc in documents_list %}
|
|
<tr>
|
|
<td>
|
|
<i class="bi bi-file-earmark-text me-1"></i>
|
|
{{ doc.name or doc.filename }}
|
|
</td>
|
|
<td>
|
|
{% if doc.file_type %}
|
|
<span class="badge bg-secondary">{{ doc.file_type }}</span>
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if doc.uploaded_at %}
|
|
{{ doc.uploaded_at.strftime('%d/%m/%Y') }}
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<a href="{{ url_for('equipments_documents.download_document', id=equipment.id, doc_id=doc.id) }}"
|
|
class="btn btn-sm btn-outline-primary" title="Télécharger">
|
|
<i class="bi bi-download"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="card-body text-center text-muted">
|
|
<i class="bi bi-file-earmark-x fs-4 d-block mb-2"></i>
|
|
<p class="mb-0">Aucun document associé</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Tâches préventives -->
|
|
{% set scheduled_tasks = equipment.scheduled_tasks.all() if equipment.scheduled_tasks else [] %}
|
|
<div class="card mb-3">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<span><i class="bi bi-calendar-check me-1"></i> Tâches préventives</span>
|
|
<div>
|
|
<a href="{{ url_for('equipments.init_scheduled_tasks', id=equipment.id) }}" class="btn btn-sm btn-outline-primary me-1">
|
|
<i class="bi bi-list-ul"></i> Gérer
|
|
</a>
|
|
<span class="badge bg-primary">{{ scheduled_tasks|length }}</span>
|
|
</div>
|
|
</div>
|
|
{% if scheduled_tasks %}
|
|
<div class="table-responsive">
|
|
<table class="table table-sm table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>N°</th>
|
|
<th>Tâche</th>
|
|
<th>Périodicité</th>
|
|
<th>Prochaine date</th>
|
|
<th>Statut</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for task in scheduled_tasks %}
|
|
<tr>
|
|
<td>{{ task.lot_task.num_tache if task.lot_task else '—' }}</td>
|
|
<td>{{ task.lot_task.tache if task.lot_task else '—' }}</td>
|
|
<td>{{ task.lot_task.periodicite if task.lot_task else '—' }}</td>
|
|
<td>
|
|
{% if task.scheduled_date %}
|
|
{{ task.scheduled_date.strftime('%d/%m/%Y') }}
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if task.status == 'planned' %}
|
|
<span class="badge bg-info">Planifiée</span>
|
|
{% elif task.status == 'completed' %}
|
|
<span class="badge bg-success">Terminée</span>
|
|
{% elif task.status == 'postponed' %}
|
|
<span class="badge bg-warning">Reportée</span>
|
|
{% else %}
|
|
<span class="badge bg-secondary">{{ task.status }}</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="card-body text-center text-muted">
|
|
<i class="bi bi-calendar-x fs-4 d-block mb-2"></i>
|
|
<p class="mb-0">Aucune tâche préventive associée</p>
|
|
{% if not equipment.lot_id %}
|
|
<small>Associez un lot à cet équipement pour hériter de ses tâches préventives</small>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Actions selon le type -->
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<i class="bi bi-lightning me-1"></i> Actions rapides
|
|
</div>
|
|
<div class="card-body">
|
|
{% if equipment.is_group %}
|
|
<div class="row g-2">
|
|
{% if equipment.unindividualized_quantity > 0 %}
|
|
<div class="col-md-4">
|
|
<a href="{{ url_for('equipments.individualize', id=equipment.id) }}" class="btn btn-outline-primary w-100">
|
|
<i class="bi bi-box-arrow-up-right me-1"></i>Individualiser une unité
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
{% if not equipment.parent %}
|
|
<div class="col-md-4">
|
|
<a href="{{ url_for('equipments.create') }}?parent_id={{ equipment.id }}" class="btn btn-outline-success w-100">
|
|
<i class="bi bi-plus-circle me-1"></i>Ajouter un enfant
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
<div class="col-md-4">
|
|
<a href="{{ url_for('equipments.add_elements', id=equipment.id) }}" class="btn btn-outline-primary w-100">
|
|
<i class="bi bi-list-ol me-1"></i>Ajouter des éléments
|
|
</a>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<a href="{{ url_for('interventions.create') }}?equipment_id={{ equipment.id }}" class="btn btn-outline-danger w-100">
|
|
<i class="bi bi-wrench me-1"></i>Intervention groupe
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% elif equipment.parent %}
|
|
<div class="row g-2">
|
|
<div class="col-md-6">
|
|
<a href="{{ url_for('equipments.move_to_room', id=equipment.id) }}" class="btn btn-outline-secondary w-100">
|
|
<i class="bi bi-arrow-left-right me-1"></i>Déplacer
|
|
</a>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<a href="{{ url_for('interventions.create') }}?equipment_id={{ equipment.id }}" class="btn btn-outline-danger w-100">
|
|
<i class="bi bi-wrench me-1"></i>Intervention
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="row g-2">
|
|
<div class="col-md-6">
|
|
<a href="{{ url_for('equipments.move_to_room', id=equipment.id) }}" class="btn btn-outline-secondary w-100">
|
|
<i class="bi bi-arrow-left-right me-1"></i>Déplacer
|
|
</a>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<a href="{{ url_for('interventions.create') }}?equipment_id={{ equipment.id }}" class="btn btn-outline-danger w-100">
|
|
<i class="bi bi-wrench me-1"></i>Intervention
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Enfants pour les groupes -->
|
|
{% if equipment.is_group and equipment.children_count > 0 %}
|
|
<div class="card mb-3">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<span><i class="bi bi-diagram-3 me-1"></i> Éléments du groupe</span>
|
|
<span class="badge bg-primary">{{ equipment.children_count }}</span>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table table-hover table-sm mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>N°</th>
|
|
<th>Nom</th>
|
|
<th>Localisation</th>
|
|
<th>Statut</th>
|
|
<th>Curatives</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for child in equipment.children.limit(10) %}
|
|
<tr>
|
|
<td>
|
|
{% if child.individual_number %}#{{ child.individual_number }}{% else %}—{% endif %}
|
|
</td>
|
|
<td>
|
|
<a href="{{ url_for('equipments.detail', id=child.id) }}">
|
|
{{ child.name or '—' }}
|
|
</a>
|
|
</td>
|
|
<td>
|
|
{% if child.effective_room %}
|
|
{{ child.effective_room.name }}
|
|
{% else %}
|
|
<span class="text-muted">—</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<span class="badge {{ child.status|status_badge }}">{{ child.status|format_status }}</span>
|
|
</td>
|
|
<td>
|
|
{% if child.curative_count > 0 %}
|
|
<span class="badge bg-warning text-dark">{{ child.curative_count }}</span>
|
|
{% else %}
|
|
<span class="text-muted">0</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% if equipment.children_count > 10 %}
|
|
<div class="card-footer">
|
|
<a href="{{ url_for('equipments.children', id=equipment.id) }}" class="btn btn-sm btn-outline-primary">
|
|
Voir les {{ equipment.children_count }} éléments
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Description -->
|
|
{% if equipment.description %}
|
|
<div class="card mb-3">
|
|
<div class="card-header"><i class="bi bi-text-left me-1"></i> Description</div>
|
|
<div class="card-body">
|
|
<p class="mb-0">{{ equipment.description|nl2br }}</p>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Interventions récentes -->
|
|
<div class="card mb-3">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<span><i class="bi bi-wrench me-1"></i> Interventions récentes</span>
|
|
<a href="{{ url_for('interventions.index') }}?equipment_id={{ equipment.id }}" class="btn btn-sm btn-outline-primary">
|
|
Voir tout
|
|
</a>
|
|
</div>
|
|
{% if equipment.interventions %}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover table-sm mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Type</th>
|
|
<th>Statut</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for intervention in equipment.interventions[:5] %}
|
|
<tr>
|
|
<td>{{ intervention.created_at.strftime('%d/%m/%Y') }}</td>
|
|
<td>
|
|
<span class="badge {{ 'bg-danger' if intervention.intervention_type == 'curative' else 'bg-success' }}">
|
|
{{ intervention.intervention_type|title }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<span class="badge {{ intervention.status|status_badge }}">{{ intervention.status|format_status }}</span>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="card-body text-center text-muted">
|
|
<i class="bi bi-inbox fs-1"></i>
|
|
<p class="mb-0">Aucune intervention enregistrée</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Colonne latérale -->
|
|
<div class="col-lg-4">
|
|
<!-- Statistiques -->
|
|
<div class="card mb-3">
|
|
<div class="card-header"><i class="bi bi-graph-up me-1"></i> Statistiques</div>
|
|
<div class="card-body">
|
|
<ul class="list-group list-group-flush">
|
|
<li class="list-group-item d-flex justify-content-between">
|
|
<span>Interventions curatives</span>
|
|
<span class="badge bg-warning text-dark">{{ equipment.curative_count }}</span>
|
|
</li>
|
|
<li class="list-group-item d-flex justify-content-between">
|
|
<span>Interventions préventives</span>
|
|
<span class="badge bg-success">{{ equipment.preventive_count }}</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Historique des déplacements -->
|
|
{% if equipment.room_history %}
|
|
<div class="card mb-3">
|
|
<div class="card-header"><i class="bi bi-clock-history me-1"></i> Historique des déplacements</div>
|
|
<ul class="list-group list-group-flush">
|
|
{% for history in equipment.room_history[:5] %}
|
|
<li class="list-group-item">
|
|
<small class="text-muted">{{ history.changed_at.strftime('%d/%m/%Y') }}</small><br>
|
|
{% if history.old_room %}
|
|
{{ history.old_room.name }} →
|
|
{% endif %}
|
|
{{ history.new_room.name if history.new_room else '' }}
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Actions dangereuses -->
|
|
<div class="card border-danger mb-3">
|
|
<div class="card-header text-danger"><i class="bi bi-exclamation-triangle me-1"></i> Zone dangereuse</div>
|
|
<div class="card-body">
|
|
{% if equipment.status != 'a_jeter' and equipment.status != 'jete' %}
|
|
<form action="{{ url_for('equipments.mark_as_trash', id=equipment.id) }}" method="POST">
|
|
<button type="submit" class="btn btn-outline-danger btn-sm w-100" onclick="return confirm('Marquer comme à jeter ?')">
|
|
<i class="bi bi-trash me-1"></i>Marquer à jeter
|
|
</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|