diff --git a/streetup/home/locale/en/LC_MESSAGES/django.mo b/streetup/home/locale/en/LC_MESSAGES/django.mo index 4b1176d..e7d15ee 100644 Binary files a/streetup/home/locale/en/LC_MESSAGES/django.mo and b/streetup/home/locale/en/LC_MESSAGES/django.mo differ diff --git a/streetup/home/locale/en/LC_MESSAGES/django.po b/streetup/home/locale/en/LC_MESSAGES/django.po index 9732d1a..0d9753d 100644 --- a/streetup/home/locale/en/LC_MESSAGES/django.po +++ b/streetup/home/locale/en/LC_MESSAGES/django.po @@ -69,6 +69,10 @@ msgid "Compteur interventions terminées" msgstr "Incidents to be processed counter" #: streetup/home/models.py:20 +msgid "Compteur interventions en pause" +msgstr "Paused interventions counter" + +#: streetup/home/models.py:21 #: streetup/home/templates/home/widgets/stock_actions.html:9 msgid "Actions stock" msgstr "Stock actions" @@ -543,6 +547,18 @@ msgstr "No incidents to process" msgid "Voir toutes les interventions terminées" msgstr "See all my observations" +#: streetup/home/templates/home/widgets/intervention_on_pause.html:8 +msgid "Interventions en pause" +msgstr "Paused interventions" + +#: streetup/home/templates/home/widgets/intervention_on_pause.html:40 +msgid "Aucune intervention en pause" +msgstr "No paused interventions" + +#: streetup/home/templates/home/widgets/intervention_on_pause.html:48 +msgid "Voir toutes les interventions en pause" +msgstr "View all paused interventions" + #: streetup/home/templates/home/widgets/intervention_stats.html:13 msgid "Interventions" msgstr "Interventions" diff --git a/streetup/home/locale/fr/LC_MESSAGES/django.mo b/streetup/home/locale/fr/LC_MESSAGES/django.mo index 1bfc676..e32cede 100644 Binary files a/streetup/home/locale/fr/LC_MESSAGES/django.mo and b/streetup/home/locale/fr/LC_MESSAGES/django.mo differ diff --git a/streetup/home/locale/fr/LC_MESSAGES/django.po b/streetup/home/locale/fr/LC_MESSAGES/django.po index 36c3add..4de794c 100644 --- a/streetup/home/locale/fr/LC_MESSAGES/django.po +++ b/streetup/home/locale/fr/LC_MESSAGES/django.po @@ -69,6 +69,10 @@ msgid "Compteur interventions terminées" msgstr "Compteur interventions terminées" #: streetup/home/models.py:20 +msgid "Compteur interventions en pause" +msgstr "Compteur interventions en pause" + +#: streetup/home/models.py:21 #: streetup/home/templates/home/widgets/stock_actions.html:9 msgid "Actions stock" msgstr "Actions stock" @@ -550,6 +554,18 @@ msgstr "Aucune intervention terminée" msgid "Voir toutes les interventions terminées" msgstr "Voir toutes les interventions terminées" +#: streetup/home/templates/home/widgets/intervention_on_pause.html:8 +msgid "Interventions en pause" +msgstr "Interventions en pause" + +#: streetup/home/templates/home/widgets/intervention_on_pause.html:40 +msgid "Aucune intervention en pause" +msgstr "Aucune intervention en pause" + +#: streetup/home/templates/home/widgets/intervention_on_pause.html:48 +msgid "Voir toutes les interventions en pause" +msgstr "Voir toutes les interventions en pause" + #: streetup/home/templates/home/widgets/intervention_stats.html:13 msgid "Interventions" msgstr "Interventions" diff --git a/streetup/home/locale/nl/LC_MESSAGES/django.mo b/streetup/home/locale/nl/LC_MESSAGES/django.mo index c4c2f9a..013885a 100644 Binary files a/streetup/home/locale/nl/LC_MESSAGES/django.mo and b/streetup/home/locale/nl/LC_MESSAGES/django.mo differ diff --git a/streetup/home/locale/nl/LC_MESSAGES/django.po b/streetup/home/locale/nl/LC_MESSAGES/django.po index af1c261..71d126e 100644 --- a/streetup/home/locale/nl/LC_MESSAGES/django.po +++ b/streetup/home/locale/nl/LC_MESSAGES/django.po @@ -68,7 +68,11 @@ msgstr "Tegengeverifieerde interventies moeten worden goedgekeurd" msgid "Compteur interventions terminées" msgstr "Aantal te behandelen incidenten" -#: home/models.py:20 home/templates/home/widgets/stock_actions.html:9 +#: home/models.py:20 +msgid "Compteur interventions en pause" +msgstr "Teller gepauzeerde interventies" + +#: home/models.py:21 home/templates/home/widgets/stock_actions.html:9 msgid "Actions stock" msgstr "Voorraadacties" @@ -544,6 +548,18 @@ msgstr "Geen incidenten te behandelen" msgid "Voir toutes les interventions terminées" msgstr "Bekijk al mijn observaties" +#: home/templates/home/widgets/intervention_on_pause.html:8 +msgid "Interventions en pause" +msgstr "Gepauzeerde interventies" + +#: home/templates/home/widgets/intervention_on_pause.html:40 +msgid "Aucune intervention en pause" +msgstr "Geen gepauzeerde interventies" + +#: home/templates/home/widgets/intervention_on_pause.html:48 +msgid "Voir toutes les interventions en pause" +msgstr "Bekijk alle gepauzeerde interventies" + #: home/templates/home/widgets/intervention_stats.html:13 msgid "Interventions" msgstr "Interventies" diff --git a/streetup/home/migrations/0003_alter_homewidget_widget_code.py b/streetup/home/migrations/0003_alter_homewidget_widget_code.py new file mode 100644 index 0000000..bee4dfe --- /dev/null +++ b/streetup/home/migrations/0003_alter_homewidget_widget_code.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0.7 on 2026-08-14 20:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0002_delete_teambuildingvote'), + ] + + operations = [ + migrations.AlterField( + model_name='homewidget', + name='widget_code', + field=models.CharField(choices=[('intervention_stats', 'Statistiques interventions'), ('contracts_summary', 'Résumé contrats'), ('map_today', 'Carte du jour'), ('operator_shortcuts', 'Raccourcis opérateur'), ('assets_links', 'Liens assets'), ('stock_summary', 'Résumé stock'), ('observer_shortcuts', 'Raccourcis observateur'), ('incident_counter', 'Compteur incidents à traiter'), ('intervention_to_verify', 'Compteur interventions à vérifier'), ('intervention_to_plan', 'Compteur interventions à planifier'), ('intervention_to_approve', 'Compteur interventions à approuver'), ('intervention_checked_to_approve', 'Compteur interventions vérifiées à approuver'), ('intervention_finished', 'Compteur interventions terminées'), ('intervention_on_pause', 'Compteur interventions en pause'), ('stock_actions', 'Actions stock')], max_length=50, unique=True, verbose_name='Code du widget'), + ), + ] diff --git a/streetup/home/models.py b/streetup/home/models.py index 0e490d8..deed03b 100644 --- a/streetup/home/models.py +++ b/streetup/home/models.py @@ -17,6 +17,7 @@ WIDGET_CODE_CHOICES = [ ('intervention_to_approve', _('Compteur interventions à approuver')), ('intervention_checked_to_approve', _('Compteur interventions vérifiées à approuver')), ('intervention_finished', _('Compteur interventions terminées')), + ('intervention_on_pause', _('Compteur interventions en pause')), ('stock_actions', _('Actions stock')), ] diff --git a/streetup/home/templates/home/widgets/intervention_on_pause.html b/streetup/home/templates/home/widgets/intervention_on_pause.html new file mode 100644 index 0000000..ade2b66 --- /dev/null +++ b/streetup/home/templates/home/widgets/intervention_on_pause.html @@ -0,0 +1,51 @@ +{% load i18n %} + +{# ========== Widget compteur d'interventions en pause ========== #} +
+
+ + {% translate "Interventions en pause" %} + +
+ + {# --- Compteur --- #} +
+ + {{ intervention_on_pause_count }} + {% if is_manager_filter_applied %} + {% translate "(gestionnaire)" %} + {% endif %} + +
+ + {# --- Liste des 5 premières interventions --- #} + + + +
diff --git a/streetup/home/tests.py b/streetup/home/tests.py index f857255..60d13a7 100644 --- a/streetup/home/tests.py +++ b/streetup/home/tests.py @@ -231,4 +231,24 @@ class HomeIndexViewTests(TestCase): self.assertContains(response, 'id="home-unread-notifications-alert"') self.assertContains(response, 'Vous avez 1 notification non lue.') + def test_home_index_intervention_on_pause_widget(self): + from django.urls import reverse + from django.contrib.auth import get_user_model + from common.models import UserConfig + from home.models import HomeWidget + + User = get_user_model() + user = User.objects.create_user('pause_widget_user', password='pass') + UserConfig.objects.create(user=user) + self.client.force_login(user) + + # Create the widget + HomeWidget.objects.create(widget_code='intervention_on_pause') + + response = self.client.get(reverse('home:index')) + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'Interventions en pause') + self.assertContains(response, 'status=on_pause') + + diff --git a/streetup/home/views.py b/streetup/home/views.py index b183bd6..52d85dd 100644 --- a/streetup/home/views.py +++ b/streetup/home/views.py @@ -631,6 +631,17 @@ def index(request): .order_by('-code')[:5] ) + intervention_on_pause_qs = interventions.filter(status='on_pause').exclude( + Q(contract__uses_intervention_manager=True) & + ~Q(intervention_manager=request.user) + ) + intervention_on_pause_count = intervention_on_pause_qs.count() + intervention_on_pause_list = list( + intervention_on_pause_qs + .select_related('thematic') + .order_by('-code')[:5] + ) + if home_contract_ids is not None: is_manager_filter_applied = user_contracts.filter( id__in=home_contract_ids, uses_intervention_manager=True @@ -641,6 +652,7 @@ def index(request): ).exists() total_finished_count = interventions.filter(status='finished').count() + total_on_pause_count = interventions.filter(status='on_pause').count() is_inspector = 'inspector' in user_roles inspection_configs = [] @@ -710,8 +722,11 @@ def index(request): 'intervention_to_plan_list': intervention_to_plan_list, 'intervention_finished_count': intervention_finished_count, 'intervention_finished_list': intervention_finished_list, + 'intervention_on_pause_count': intervention_on_pause_count, + 'intervention_on_pause_list': intervention_on_pause_list, 'is_manager_filter_applied': is_manager_filter_applied, 'total_finished_count': total_finished_count, + 'total_on_pause_count': total_on_pause_count, 'intervention_to_approve_count': intervention_to_approve_count, 'intervention_to_approve_list': intervention_to_approve_list, 'intervention_checked_to_approve_count': intervention_checked_to_approve_count, diff --git a/streetup/interventions/tests/test_general.py b/streetup/interventions/tests/test_general.py index 418a65d..90c9623 100644 --- a/streetup/interventions/tests/test_general.py +++ b/streetup/interventions/tests/test_general.py @@ -628,6 +628,63 @@ class InterventionManagerTests(TestCase): response2 = self.client.get(reverse('home:index')) self.assertFalse(response2.context['is_manager_filter_applied']) + def test_homepage_on_pause_interventions_filtering(self): + # Create an intervention on_pause, with contract using manager, but manager is None (not this user) + itv_other_mgr = Intervention.objects.create( + title='Other Manager on pause', + status='on_pause', + contract=self.contract, + thematic=self.thematic, + intervention_manager=None, + symptom=self.symptom, + ) + # Create an intervention on_pause, with contract using manager, managed by self.user + itv_self_mgr = Intervention.objects.create( + title='Self Manager on pause', + status='on_pause', + contract=self.contract, + thematic=self.thematic, + intervention_manager=self.user, + symptom=self.symptom, + ) + # Create an intervention on_pause, but contract does not use manager + contract_no_mgr = Contract.objects.create( + company=self.company, + contract_number='C-NOMGR-PAUSE', + start_date=self.contract.start_date, + end_date=self.contract.end_date, + uses_intervention_manager=False + ) + # Grant view permission for the no-manager contract + from common.models import UserContractAccess + UserContractAccess.objects.create( + user_config=self.user_config, + contract=contract_no_mgr, + can_view_interventions=True, + ) + + itv_no_mgr = Intervention.objects.create( + title='No Manager on pause', + status='on_pause', + contract=contract_no_mgr, + thematic=self.thematic, + symptom=self.symptom, + ) + + # Access the homepage + response = self.client.get(reverse('home:index')) + self.assertEqual(response.status_code, 200) + + # On pause list/counter should only contain self-managed and no-manager interventions + on_pause_list = response.context['intervention_on_pause_list'] + self.assertIn(itv_self_mgr, on_pause_list) + self.assertIn(itv_no_mgr, on_pause_list) + self.assertNotIn(itv_other_mgr, on_pause_list) + + self.assertEqual(response.context['intervention_on_pause_count'], 2) + self.assertEqual(response.context['total_on_pause_count'], 3) + self.assertTrue(response.context['is_manager_filter_applied']) + def test_geojson_filtering_by_manager(self): # Create an intervention finished managed by self.user itv_self_mgr = Intervention.objects.create(