228 lines
14 KiB
HTML
228 lines
14 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}{{ meter.name }}{% if meter.equipment %} — {{ meter.equipment.name }}{% endif %} — GMAO{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<nav aria-label="breadcrumb" class="mb-3">
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{{ url_for('meters.index') }}">Compteurs</a></li>
|
|
<li class="breadcrumb-item">{% if meter.equipment %}<a href="{{ url_for('equipments.detail', id=meter.equipment.id) }}">{{ meter.equipment.name }}</a>{% elif meter.building %}{{ meter.building.name }}{% elif meter.zone %}{{ meter.zone.name }}{% elif meter.room %}{{ meter.room.name }}{% elif meter.housing_unit %}{{ meter.housing_unit.name }}{% else %}Patrimoine{% endif %}</li>
|
|
<li class="breadcrumb-item active">{{ meter.name }}</li>
|
|
</ol>
|
|
</nav>
|
|
|
|
<div class="row">
|
|
<div class="col-lg-4">
|
|
<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>{{ meter.name }}</span>
|
|
<a href="{{ url_for('meters.edit', meter_id=meter.id) }}" class="btn btn-sm btn-outline-primary">
|
|
<i class="bi bi-pencil me-1"></i>Modifier
|
|
</a>
|
|
</div>
|
|
<div class="card-body">
|
|
<dl class="row mb-0">
|
|
<dt class="col-sm-5">Rattachement</dt>
|
|
<dd class="col-sm-7">
|
|
{% if meter.equipment %}Équipement — {{ meter.equipment.name }}{% elif meter.building %}Bâtiment — {{ meter.building.name }}{% elif meter.zone %}Zone — {{ meter.zone.name }}{% elif meter.room %}Local — {{ meter.room.name }}{% elif meter.housing_unit %}Logement — {{ meter.housing_unit.name }}{% endif %}
|
|
</dd>
|
|
|
|
<dt class="col-sm-5">Usage</dt><dd class="col-sm-7">{{ meter.usage or '—' }}</dd>
|
|
<dt class="col-sm-5">Reste sous-compté</dt><dd class="col-sm-7">{{ meter.remainder_label or '—' }}</dd>
|
|
|
|
<dt class="col-sm-5">Type</dt>
|
|
<dd class="col-sm-7">{{ meter.meter_type }}</dd>
|
|
|
|
<dt class="col-sm-5">Unité</dt>
|
|
<dd class="col-sm-7">{{ meter.unit }}</dd>
|
|
|
|
<dt class="col-sm-5">Valeur initiale</dt>
|
|
<dd class="col-sm-7">{{ meter.initial_value }}</dd>
|
|
|
|
<dt class="col-sm-5">Valeur actuelle</dt>
|
|
<dd class="col-sm-7">
|
|
<strong class="fs-4">{{ meter.current_value }}</strong> {{ meter.unit }}
|
|
</dd>
|
|
|
|
<dt class="col-sm-5">Intervalle relevé</dt>
|
|
<dd class="col-sm-7">
|
|
{% if meter.reading_interval_days %}
|
|
Tous les {{ meter.reading_interval_days }} jours
|
|
{% else %}
|
|
—
|
|
{% endif %}
|
|
</dd>
|
|
|
|
<dt class="col-sm-5">Dernier relevé</dt>
|
|
<dd class="col-sm-7">
|
|
{% if meter.last_reading_date %}
|
|
{{ meter.last_reading_date.strftime('%d/%m/%Y') }}
|
|
{% else %}
|
|
—
|
|
{% endif %}
|
|
</dd>
|
|
|
|
<dt class="col-sm-5">Seuil alerte</dt>
|
|
<dd class="col-sm-7">{{ meter.warning_threshold or '—' }}</dd>
|
|
|
|
<dt class="col-sm-5">Seuil critique</dt>
|
|
<dd class="col-sm-7">{{ meter.critical_threshold or '—' }}</dd>
|
|
|
|
<dt class="col-sm-5">Intervalle maintenance</dt>
|
|
<dd class="col-sm-7">
|
|
{% if meter.maintenance_interval %}
|
|
{{ meter.maintenance_interval }} {{ meter.unit }}
|
|
{% else %}
|
|
—
|
|
{% endif %}
|
|
</dd>
|
|
|
|
<dt class="col-sm-5">Dernière maintenance</dt>
|
|
<dd class="col-sm-7">{{ meter.last_maintenance_value or '—' }}</dd>
|
|
|
|
<dt class="col-sm-5">Prochaine maintenance</dt>
|
|
<dd class="col-sm-7">
|
|
{% if meter.next_maintenance_at %}
|
|
{{ meter.next_maintenance_at }} {{ meter.unit }}
|
|
{% else %}
|
|
—
|
|
{% endif %}
|
|
</dd>
|
|
|
|
<dt class="col-sm-5">État du compteur</dt>
|
|
<dd class="col-sm-7">
|
|
{% if meter.status == 'replaced' %}
|
|
<span class="badge bg-secondary">Remplacé</span>
|
|
{% elif meter.status == 'active' %}
|
|
<span class="badge bg-success">Actif</span>
|
|
{% else %}
|
|
<span class="badge bg-secondary">{{ meter.status }}</span>
|
|
{% endif %}
|
|
</dd>
|
|
|
|
<dt class="col-sm-5">État des seuils historiques</dt>
|
|
<dd class="col-sm-7">
|
|
{% if meter.warning_level == 'critical' %}
|
|
<span class="badge bg-danger">Critique</span>
|
|
{% elif meter.warning_level == 'warning' %}
|
|
<span class="badge bg-warning text-dark">Alerte</span>
|
|
{% elif meter.warning_level == 'maintenance' %}
|
|
<span class="badge bg-info">Maintenance requise</span>
|
|
{% else %}
|
|
<span class="badge bg-success">OK</span>
|
|
{% endif %}
|
|
</dd>
|
|
|
|
{% if meter.replaced_meter %}
|
|
<dt class="col-sm-5">Remplace</dt>
|
|
<dd class="col-sm-7"><a href="{{ url_for('meters.detail', meter_id=meter.replaced_meter.id) }}">{{ meter.replaced_meter.name }}</a></dd>
|
|
{% endif %}
|
|
{% if meter.replacement %}
|
|
<dt class="col-sm-5">Remplacé par</dt>
|
|
<dd class="col-sm-7"><a href="{{ url_for('meters.detail', meter_id=meter.replacement.id) }}">{{ meter.replacement.name }}</a></dd>
|
|
{% endif %}
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
|
|
{% if meter.status == 'replaced' or not meter.is_active %}
|
|
<div class="alert alert-secondary" role="status">
|
|
<h5 class="alert-heading"><i class="bi bi-archive me-1"></i>Compteur remplacé</h5>
|
|
<p class="mb-1">Ce compteur n'accepte plus de nouveaux relevés. Son historique reste consultable.</p>
|
|
{% if meter.replacement %}
|
|
<p class="mb-0">Les nouveaux relevés doivent être saisis sur le compteur remplaçant :
|
|
<a href="{{ url_for('meters.detail', meter_id=meter.replacement.id) }}">{{ meter.replacement.name }}</a>.
|
|
</p>
|
|
{% else %}
|
|
<p class="mb-0">Les nouveaux relevés doivent être saisis sur le compteur actif.</p>
|
|
{% endif %}
|
|
</div>
|
|
{% else %}
|
|
<!-- Formulaire de relevé -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<i class="bi bi-pencil me-1"></i>Nouveau relevé
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="POST" enctype="multipart/form-data" action="{{ url_for('meters.add_reading', meter_id=meter.id) }}">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
|
|
<div class="mb-3">
|
|
<label for="value" class="form-label">Valeur *</label>
|
|
<div class="input-group">
|
|
<input type="number" step="0.01" class="form-control" id="value" name="value" required
|
|
value="{{ meter.current_value }}">
|
|
<span class="input-group-text">{{ meter.unit }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="form-check mb-2"><input class="form-check-input" type="checkbox" value="1" name="is_reset" id="is_reset"><label class="form-check-label" for="is_reset">Remise à zéro explicite</label></div>
|
|
<div class="mb-3"><input class="form-control" name="reset_reason" placeholder="Motif obligatoire si remise à zéro"></div>
|
|
|
|
<div class="mb-3">
|
|
<label for="notes" class="form-label">Notes</label>
|
|
<textarea class="form-control" id="notes" name="notes" rows="2"></textarea>
|
|
</div>
|
|
<div class="mb-3"><label class="form-label" for="photo">Photo facultative</label><input class="form-control" type="file" id="photo" name="photo" accept="image/jpeg,image/png,image/gif"></div>
|
|
|
|
<button type="submit" class="btn btn-primary w-100">
|
|
<i class="bi bi-check-lg me-1"></i>Enregistrer
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="col-lg-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<i class="bi bi-clock-history me-1"></i>Historique des relevés
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Valeur</th>
|
|
<th>Variation</th>
|
|
<th>Par</th>
|
|
<th>Notes / correction</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for reading in readings %}
|
|
<tr>
|
|
<td>{{ reading.reading_date|datetime_fmt if reading.reading_date else '-' }}</td>
|
|
<td><strong>{{ reading.value }}</strong> {{ meter.unit }}</td>
|
|
<td>
|
|
{% if loop.index0 < loop.length - 1 %}
|
|
{% set diff = reading.value - readings[loop.index0 + 1].value %}
|
|
{% if diff > 0 %}
|
|
<span class="text-success">+{{ diff | round(2) }}</span>
|
|
{% elif diff < 0 %}
|
|
<span class="text-danger">{{ diff | round(2) }}</span>
|
|
{% else %}
|
|
<span class="text-muted">0</span>
|
|
{% endif %}
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ reading.read_by.username if reading.read_by else '—' }}</td>
|
|
<td>{% if reading.is_reset %}<span class="badge bg-warning text-dark">RAZ</span> {{ reading.reset_reason }}{% else %}{{ reading.notes or '—' }}{% endif %}{% if reading.photo_path %}<div class="small"><a href="{{ url_for('meters.reading_photo', meter_id=meter.id, reading_id=reading.id) }}">Photo jointe</a></div>{% endif %}<details class="mt-1"><summary class="small">Corriger</summary><form method="post" action="{{ url_for('meters.correct_reading', meter_id=meter.id, reading_id=reading.id) }}" class="d-flex gap-1 mt-1"><input type="hidden" name="csrf_token" value="{{ csrf_token() }}"><input class="form-control form-control-sm" type="number" step="0.01" name="value" value="{{ reading.value }}" aria-label="Nouvelle valeur"><input class="form-control form-control-sm" name="reason" required placeholder="Justification"><button class="btn btn-sm btn-outline-warning">Enregistrer</button></form>{% for correction in reading.corrections %}<div class="small text-muted">{{ correction.old_value }} → {{ correction.new_value }} · {{ correction.reason }}</div>{% endfor %}</details></td>
|
|
</tr>
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="5" class="text-center text-muted py-4">
|
|
<i class="bi bi-clock-history fs-1"></i>
|
|
<p>Aucun relevé enregistré</p>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{% if meter.status != 'replaced' %}<div class="card mt-3"><div class="card-header">Remplacer ce compteur</div><div class="card-body"><form method="post" action="{{ url_for('meters.replace', meter_id=meter.id) }}" class="row g-2"><input type="hidden" name="csrf_token" value="{{ csrf_token() }}"><div class="col-md-5"><input class="form-control" name="name" required placeholder="Nom du nouveau compteur"></div><div class="col-md-3"><input class="form-control" name="meter_type" value="{{ meter.meter_type }}"></div><div class="col-md-2"><input class="form-control" name="unit" value="{{ meter.unit }}"></div><div class="col-md-2"><button class="btn btn-outline-danger w-100">Remplacer</button></div></form></div></div>{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|