From cd00ad53ee48cd4777f53fc1d73b648054e74c89 Mon Sep 17 00:00:00 2001 From: Baptiste Lefeuvre Date: Tue, 23 Jun 2026 14:46:33 +0200 Subject: [PATCH 1/3] Fix #64 : Add defects severity --- main/admin.py | 1 + main/fixtures/main/initial_data.json | 6 +++--- main/migrations/0015_defect_severity.py | 24 +++++++++++++++++++++++ main/models.py | 7 +++++++ main/static/css/main.css | 26 +++++++++++++++++++++++++ main/templates/main/vehicle_detail.html | 22 +++++++++++++++------ main/views.py | 4 ++++ 7 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 main/migrations/0015_defect_severity.py diff --git a/main/admin.py b/main/admin.py index 6da2ba2..129098c 100644 --- a/main/admin.py +++ b/main/admin.py @@ -46,6 +46,7 @@ class DefectInline(admin.TabularInline): "solution_date", "reporter_name", "status", + "severity", ) readonly_fields = ["creation_date", "solution_date"] diff --git a/main/fixtures/main/initial_data.json b/main/fixtures/main/initial_data.json index be7b76c..1c9ba92 100644 --- a/main/fixtures/main/initial_data.json +++ b/main/fixtures/main/initial_data.json @@ -93,11 +93,11 @@ "pk": 2, "fields": { "vehicle": "3a8798e8-c193-4e75-868c-982e2f24b576", - "type": "bulb", - "status": "OPEN", + "status": "CONFIRMED", "creation_date": "2024-05-28", "solution_date": null, - "comment": "Clignotant AVG", + "comment": "Clignotant AVG non fonctionnel", + "severity": "MAJOR", "reporter_name": "Baptiste" } }, diff --git a/main/migrations/0015_defect_severity.py b/main/migrations/0015_defect_severity.py new file mode 100644 index 0000000..fda275d --- /dev/null +++ b/main/migrations/0015_defect_severity.py @@ -0,0 +1,24 @@ +# Generated by Django 5.2.8 on 2026-06-23 13:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("main", "0014_remove_defect_type"), + ] + + operations = [ + migrations.AddField( + model_name="defect", + name="severity", + field=models.CharField( + blank=True, + choices=[("MAJOR", "Majeure"), ("MINOR", "Mineure")], + max_length=255, + null=True, + verbose_name="gravité", + ), + ), + ] diff --git a/main/models.py b/main/models.py index 40f6fc8..5c0445e 100644 --- a/main/models.py +++ b/main/models.py @@ -98,10 +98,17 @@ class DefectStatus(models.TextChoices): SOLVED = "SOLVED", _("Résolu") CANCELLED = "CANCELLED", _("Annulé") + class DefectSeverity(models.TextChoices): + MAJOR = "MAJOR", _("Majeure") + MINOR = "MINOR", _("Mineure") + vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE) status = models.CharField( _("statut"), max_length=255, choices=DefectStatus, default=DefectStatus.OPEN ) + severity = models.CharField( + _("gravité"), max_length=255, choices=DefectSeverity, null=True, blank=True + ) creation_date = models.DateField(_("date de création"), auto_now_add=True) solution_date = models.DateField( _("date de résolution"), null=True, blank=True, editable=False diff --git a/main/static/css/main.css b/main/static/css/main.css index a2dfbcd..050715a 100644 --- a/main/static/css/main.css +++ b/main/static/css/main.css @@ -33,4 +33,30 @@ input:not([type=submit], [type=button], [type=reset])[readonly] { a { margin-top: var(--spacing); margin-bottom: var(--spacing); +} + +.status-tag { + padding: 5px 20px; + border-radius: 20px; + white-space: nowrap; + font-size: 20px; + font-weight: var(--font-weight); + line-height: var(--line-height); + color: var(--contrast); + margin-left: var(--spacing); +} + +.status-operational { + color: #1bc5bd; + background-color: #c9f7f5; +} + +.status-in_repair { + color: #f64e60; + background-color: #ffe2e5; +} + +.status-out_of_order { + color: #f64e60; + background-color: #ffe2e5; } \ No newline at end of file diff --git a/main/templates/main/vehicle_detail.html b/main/templates/main/vehicle_detail.html index 795f36b..27fef78 100644 --- a/main/templates/main/vehicle_detail.html +++ b/main/templates/main/vehicle_detail.html @@ -2,12 +2,21 @@ {% block title %}{{ block.super }} - {{ vehicle.name }}{% endblock %} {% block body %}
-

{{ vehicle.name }}

- {% if trip_started %}

Un trajet est en cours, pensez à le clôturer avant d'en commencer un nouveau

{% endif %} +

{{ vehicle.name }} {{ vehicle.get_status_display }}

{% if messages %} - {% for message in messages %} -

{{ message }}

- {% endfor %} + {% for message in messages %} +

{{ message }}

+ {% endfor %} + {% endif %} + {% if trip_started %} +

Un trajet est en cours, pensez à le clôturer avant d'en commencer un nouveau

+ {% endif %} + {% if major_defects %} +

Anomalies connues : + {% for defect in major_defects %} +
⚠️ {{ defect.comment }} + {% endfor %} +

{% endif %}
Détails du véhicule @@ -78,6 +87,7 @@

{{ vehicle.name }}

Commentaire Statut + Gravité Date @@ -86,11 +96,11 @@

{{ vehicle.name }}

{{ defect.comment }} {{ defect.get_status_display }} + {{ defect.get_severity_display|default_if_none:"-"}} {{ defect.creation_date }} {% endfor %} -
diff --git a/main/views.py b/main/views.py index dad4292..593be89 100644 --- a/main/views.py +++ b/main/views.py @@ -35,6 +35,10 @@ def get_context_data(self, **kwargs): Q(status=models.Defect.DefectStatus.OPEN) | Q(status=models.Defect.DefectStatus.CONFIRMED) ) + context["major_defects"] = context["vehicle"].defect_set.filter( + Q(status=models.Defect.DefectStatus.CONFIRMED) + & Q(severity=models.Defect.DefectSeverity.MAJOR) + ) delegated_forms: dict[str, type[ModelForm]] = { "defect_form": forms.DefectForm, From aacd0b875b54cf6c97208c4b19a2a21b61cf68c5 Mon Sep 17 00:00:00 2001 From: Rowin Date: Tue, 23 Jun 2026 23:26:21 +0200 Subject: [PATCH 2/3] =?UTF-8?q?Mutaliser=20l'utilisation=20des=20d=C3=A9fa?= =?UTF-8?q?uts=20dans=20le=20contexte?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/admin.py | 2 +- main/fixtures/main/initial_data.json | 2 -- main/models.py | 7 +++++++ main/templates/main/vehicle_detail.html | 12 ++++++------ main/views.py | 24 ++++++++++++------------ 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/main/admin.py b/main/admin.py index 129098c..6cd7a41 100644 --- a/main/admin.py +++ b/main/admin.py @@ -53,7 +53,7 @@ class DefectInline(admin.TabularInline): @admin.display(description="Nombre d'anomalies ouvertes") def open_defect_count(obj: Vehicle): - return obj.defect_set.filter(status=Defect.DefectStatus.OPEN).count() + return obj.open_defects.count() @admin.register(Vehicle) diff --git a/main/fixtures/main/initial_data.json b/main/fixtures/main/initial_data.json index 1c9ba92..0ebe18d 100644 --- a/main/fixtures/main/initial_data.json +++ b/main/fixtures/main/initial_data.json @@ -80,7 +80,6 @@ "pk": 1, "fields": { "vehicle": "94deae57-cbac-4911-bcdf-14aa4b10448d", - "type": "engine", "status": "OPEN", "creation_date": "2024-05-28", "solution_date": null, @@ -106,7 +105,6 @@ "pk": 3, "fields": { "vehicle": "3a8798e8-c193-4e75-868c-982e2f24b576", - "type": "bulb", "status": "SOLVED", "creation_date": "2024-05-28", "solution_date": null, diff --git a/main/models.py b/main/models.py index 5c0445e..8455cf8 100644 --- a/main/models.py +++ b/main/models.py @@ -87,6 +87,13 @@ def public_url(self) -> str: def __str__(self): return self.name + @property + def open_defects(self) -> models.QuerySet[Defect]: + return self.defect_set.filter( + models.Q(status=Defect.DefectStatus.OPEN) + | models.Q(status=Defect.DefectStatus.CONFIRMED) + ) + class Defect(models.Model): class Meta: diff --git a/main/templates/main/vehicle_detail.html b/main/templates/main/vehicle_detail.html index 27fef78..b20badd 100644 --- a/main/templates/main/vehicle_detail.html +++ b/main/templates/main/vehicle_detail.html @@ -11,13 +11,13 @@

{{ vehicle.name }} Un trajet est en cours, pensez à le clôturer avant d'en commencer un nouveau

{% endif %} - {% if major_defects %} -

Anomalies connues : - {% for defect in major_defects %} + {% for defect in open_defects %} + {% if defect.severity == "MAJOR" %} +

Anomalie connue :
⚠️ {{ defect.comment }} - {% endfor %} -

- {% endif %} +

+ {% endif %} + {% endfor %}
Détails du véhicule
diff --git a/main/views.py b/main/views.py index 593be89..cbf7c3a 100644 --- a/main/views.py +++ b/main/views.py @@ -9,7 +9,6 @@ from django.utils.translation import gettext as _ import django.shortcuts from django.forms import BooleanField, HiddenInput, ModelForm -from django.db.models import Q from django.views.generic import CreateView, DetailView, ListView, UpdateView from . import forms, models @@ -31,14 +30,7 @@ def get_context_data(self, **kwargs): self.object: models.Vehicle context = super().get_context_data(**kwargs) - context["open_defects"] = context["vehicle"].defect_set.filter( - Q(status=models.Defect.DefectStatus.OPEN) - | Q(status=models.Defect.DefectStatus.CONFIRMED) - ) - context["major_defects"] = context["vehicle"].defect_set.filter( - Q(status=models.Defect.DefectStatus.CONFIRMED) - & Q(severity=models.Defect.DefectSeverity.MAJOR) - ) + context["open_defects"] = context["vehicle"].open_defects() delegated_forms: dict[str, type[ModelForm]] = { "defect_form": forms.DefectForm, @@ -80,10 +72,18 @@ def get_context_data(self, **kwargs): context["trip_started"] = False except models.Trip.MultipleObjectsReturned: - raise models.Trip.MultipleObjectsReturned(_("Corruption de la base de données : plusieurs trajets sont en cours !")) - + raise models.Trip.MultipleObjectsReturned( + _( + "Corruption de la base de données : plusieurs trajets sont en cours !" + ) + ) + try: - context["last_trip_distance"] = self.object.trip_set.filter(finished=True).latest("ending_time").distance + context["last_trip_distance"] = ( + self.object.trip_set.filter(finished=True) + .latest("ending_time") + .distance + ) except models.Trip.DoesNotExist: pass From 5ce8bf07e76ee2671f4d615a1cf0de0674778883 Mon Sep 17 00:00:00 2001 From: Baptiste Lefeuvre Date: Wed, 24 Jun 2026 10:18:17 +0200 Subject: [PATCH 3/3] Fix open_defects property usage on vehicles --- main/templates/main/vehicle_detail.html | 2 +- main/views.py | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/main/templates/main/vehicle_detail.html b/main/templates/main/vehicle_detail.html index b20badd..99572a7 100644 --- a/main/templates/main/vehicle_detail.html +++ b/main/templates/main/vehicle_detail.html @@ -96,7 +96,7 @@

{{ vehicle.name }} + {{ defect.get_severity_display|default:"-"}} {{ defect.creation_date }} {% endfor %} diff --git a/main/views.py b/main/views.py index d8e7052..b7d952c 100644 --- a/main/views.py +++ b/main/views.py @@ -6,9 +6,8 @@ import django.urls from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin -from django.utils.translation import gettext as _ -import django.shortcuts from django.forms import BooleanField, HiddenInput, ModelForm +from django.utils.translation import gettext as _ from django.views.generic import CreateView, DetailView, ListView, UpdateView from . import forms, models @@ -30,7 +29,7 @@ def get_context_data(self, **kwargs): self.object: models.Vehicle context = super().get_context_data(**kwargs) - context["open_defects"] = context["vehicle"].open_defects() + context["open_defects"] = context["vehicle"].open_defects.all() delegated_forms: dict[str, type[ModelForm]] = { "defect_form": forms.DefectForm,