gmao/app_new/templates/lots/detail.html
root 4f8237aba9
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run
Lier le cycle de vie à la maintenance préventive
2026-08-19 22:49:15 +00:00

239 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}{{ lot.name }} — GMAO{% endblock %}
{% block content %}
<div class="container-fluid">
<div class="row mb-4">
<div class="col">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ url_for('lots.index') }}">Lots</a></li>
<li class="breadcrumb-item active">{{ lot.name }}</li>
</ol>
</nav>
<h1 class="h3">
<i class="fas fa-layer-group me-2"></i>{{ lot.name }}
</h1>
{% if lot.company %}
<p class="text-muted">
<i class="fas fa-building me-1"></i>{{ lot.company.trade_name or lot.company.specialty }}
</p>
{% endif %}
</div>
<div class="col-auto">
<a href="{{ url_for('lots.edit', id=lot.id) }}" class="btn btn-outline-primary">
<i class="fas fa-edit me-1"></i>Modifier
</a>
</div>
</div>
<div class="row">
<div class="col-lg-8">
{% if lot.needs_equipment_attention %}
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle me-1"></i>
<strong>Lot présent sans équipement.</strong> Rattachez au moins un équipement ou marquez ce lot comme non présent.
</div>
{% elif not lot.is_present %}
<div class="alert alert-secondary">
<i class="bi bi-dash-circle me-1"></i>
<strong>Ce lot nest pas présent dans létablissement.</strong>
{% if lot.absence_reason %}<div class="mt-1">{{ lot.absence_reason }}</div>{% endif %}
</div>
{% endif %}
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">Informations</h5>
</div>
<div class="card-body">
<dl class="row">
<dt class="col-sm-4">Nom</dt>
<dd class="col-sm-8">{{ lot.name }}</dd>
<dt class="col-sm-4">Présence</dt>
<dd class="col-sm-8">
{% if lot.is_present %}<span class="badge bg-success">Présent</span>
{% else %}<span class="badge bg-secondary">Non présent</span>{% endif %}
</dd>
{% if lot.description %}
<dt class="col-sm-4">Description</dt>
<dd class="col-sm-8">{{ lot.description }}</dd>
{% endif %}
{% if lot.company %}
<dt class="col-sm-4">Entreprise</dt>
<dd class="col-sm-8">
<a href="{{ url_for('companies.detail', id=lot.company.id) }}">
{{ lot.company.trade_name or lot.company.specialty }}
</a>
</dd>
{% endif %}
<dt class="col-sm-4">Catégorie</dt>
<dd class="col-sm-8">
{% if lot.category %}
<a href="{{ url_for('equipments.category_detail', id=lot.category.id) }}">
{{ lot.category.name }}
</a>
{% else %}
<span class="text-muted">Non assignée</span>
{% endif %}
</dd>
</dl>
</div>
</div>
{% if not lot.active_equipment_count %}
<div class="card mb-4">
<div class="card-header">Statut du lot</div>
<div class="card-body">
<form method="POST" action="{{ url_for('lots.set_presence', id=lot.id) }}">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
{% if lot.is_present %}
<input type="hidden" name="action" value="absent">
<div class="mb-3">
<label class="form-label" for="absence_reason">Raison facultative</label>
<input class="form-control" id="absence_reason" name="absence_reason" placeholder="Ex. aucun ascenseur dans létablissement">
</div>
<button class="btn btn-outline-secondary">Marquer le lot comme non présent</button>
{% else %}
<input type="hidden" name="action" value="present">
<button class="btn btn-outline-success">Marquer le lot comme présent</button>
{% endif %}
</form>
</div>
</div>
{% endif %}
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<div><h5 class="mb-0"><i class="bi bi-calendar2-check me-2"></i>Maintenance préventive</h5><small class="text-muted">Le lot définit les règles héritées par ses équipements.</small></div>
<a class="btn btn-sm btn-primary" href="{{ url_for('lots.task_create', lot_id=lot.id) }}"><i class="bi bi-plus-lg"></i> Ajouter une tâche</a>
</div>
<div class="card-body border-bottom">
<div class="row text-center g-2">
<div class="col"><div class="fw-bold fs-4">{{ lot.tasks|length }}</div><small class="text-muted">règles</small></div>
<div class="col"><div class="fw-bold fs-4 text-primary">{{ task_counts.planned }}</div><small class="text-muted">planifiées</small></div>
<div class="col"><div class="fw-bold fs-4 text-warning">{{ task_counts.suspended }}</div><small class="text-muted">suspendues</small></div>
<div class="col"><div class="fw-bold fs-4 text-danger">{{ task_counts.overdue }}</div><small class="text-muted">en retard</small></div>
</div>
</div>
{% if lot.tasks %}<div class="table-responsive"><table class="table table-sm align-middle mb-0"><thead><tr><th></th><th>Tâche</th><th>Déclenchement</th><th>Portée</th><th>Indisponibilité</th><th></th></tr></thead><tbody>
{% for task in lot.tasks %}<tr class="{{ 'table-secondary' if not task.is_active }}"><td>{{ task.num_tache or '—' }}</td><td><strong>{{ task.tache or 'Tâche sans nom' }}</strong><div class="small text-muted">{{ task.periodicite or (task.jours_entre_interventions|string + ' jours' if task.jours_entre_interventions else 'Périodicité à définir') }}</div>{% if task.is_safety_critical %}<span class="badge bg-danger">Sécurité</span>{% endif %}</td><td>{{ task.trigger_type|replace('calendar','calendrier')|replace('season','saison')|replace('event','événement')|replace('weather','météo')|replace('meter','compteur')|title }}</td><td>{{ {'auto':'Automatique','group':'Groupe / salle','unit':'Par unité'}.get(task.application_scope, task.application_scope) }}</td><td>{{ {'suspend':'Suspendre','keep':'Maintenir','postpone':'Reporter'}.get(task.unavailable_policy, task.unavailable_policy) }}</td><td><a class="btn btn-sm btn-outline-primary" href="{{ url_for('lots.task_edit', lot_id=lot.id, task_id=task.id) }}"><i class="bi bi-pencil"></i></a></td></tr>{% endfor %}
</tbody></table></div>{% else %}<div class="card-body text-muted">Aucune règle préventive. Ajoutez-en une pour générer les échéances.</div>{% endif %}
<div class="card-footer"><form method="post" action="{{ url_for('lots.generate_tasks', lot_id=lot.id) }}"><input type="hidden" name="csrf_token" value="{{ csrf_token() }}"><button class="btn btn-success" {% if not lot.is_present %}disabled{% endif %}><i class="bi bi-magic"></i> Générer les échéances maintenant</button></form></div>
</div>
{# Équipements du lot #}
{% if equipments %}
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0"><i class="bi bi-hdd-stack me-2"></i>Équipements ({{ equipments|length }})</h5>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-sm table-hover mb-0">
<thead>
<tr>
<th>Nom</th>
<th>Localisation</th>
<th>Statut</th>
<th>Compteurs</th>
<th></th>
</tr>
</thead>
<tbody>
{% for eq in equipments %}
<tr>
<td>
<a href="{{ url_for('equipments.detail', id=eq.id) }}">
{{ eq.name }}
</a>
</td>
<td>
{% if eq.room %}
<a href="{{ url_for('rooms.detail', id=eq.room.id) }}">
{{ eq.room.name }}
</a>
{% elif eq.location %}
{{ eq.location }}
{% else %}
<span class="text-muted"></span>
{% endif %}
</td>
<td>
{% if eq.status == 'active' %}
<span class="badge bg-success">En service</span>
{% elif eq.status == 'inactive' %}
<span class="badge bg-secondary">Inactif</span>
{% elif eq.status == 'maintenance' %}
<span class="badge bg-warning text-dark">Maintenance</span>
{% elif eq.status == 'retired' %}
<span class="badge bg-danger">Retiré</span>
{% else %}
<span class="badge bg-secondary">{{ eq.status }}</span>
{% endif %}
</td>
<td>
{% if eq.meters %}
{% for meter in eq.meters %}
<a href="{{ url_for('meters.detail', meter_id=meter.id) }}"
class="badge bg-info text-dark text-decoration-none me-1">
{{ meter.name }}: {{ meter.current_value }} {{ meter.unit }}
</a>
{% endfor %}
{% else %}
<span class="text-muted"></span>
{% endif %}
</td>
<td>
<a href="{{ url_for('equipments.detail', id=eq.id) }}"
class="btn btn-sm btn-outline-primary">
<i class="bi bi-eye"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% else %}
<div class="card mb-4">
<div class="card-body text-muted">
<i class="bi bi-info-circle me-2"></i>Aucun équipement dans ce lot.
<a href="{{ url_for('equipments.index') }}">Rechercher un équipement</a> pour l'ajouter à ce lot.
</div>
</div>
{% endif %}
</div>
<div class="col-lg-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">Actions</h5>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="{{ url_for('lots.edit', id=lot.id) }}" class="btn btn-outline-primary">
<i class="fas fa-edit me-1"></i>Modifier le lot
</a>
<a href="{{ url_for('equipments.lifecycle_dashboard', status='all') }}" class="btn btn-outline-secondary"><i class="bi bi-activity"></i> Cycle de vie</a>
<form method="POST" action="{{ url_for('lots.delete', id=lot.id) }}"
onsubmit="return confirm('Confirmer la suppression ?');">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<button type="submit" class="btn btn-outline-danger w-100">
<i class="fas fa-trash me-1"></i>Supprimer
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}