diff --git a/itou/approvals/admin.py b/itou/approvals/admin.py index dce4455582c..69224db8464 100644 --- a/itou/approvals/admin.py +++ b/itou/approvals/admin.py @@ -232,7 +232,7 @@ class ApprovalAdmin(InconsistencyCheckMixin, ItouModelAdmin): "origin_sender_kind", "origin_siae_kind", "origin_siae_siret", - "remainder", + "get_remainder_display", ) fieldsets = ( ( @@ -242,7 +242,7 @@ class ApprovalAdmin(InconsistencyCheckMixin, ItouModelAdmin): "number", "start_at", "end_at", - "remainder", + "get_remainder_display", "user", "eligibility_diagnosis", "assigned_company", @@ -391,10 +391,6 @@ def assigned_company(self, obj): ) return "-" - @admin.display(description="Reliquat") - def remainder(self, obj): - return f"{obj.remainder.days} jour{pluralizefr(obj.duration.days)}" - class IsInProgressFilter(admin.SimpleListFilter): title = "En cours" diff --git a/itou/approvals/models.py b/itou/approvals/models.py index b23b019d22a..a5fe49388a3 100644 --- a/itou/approvals/models.py +++ b/itou/approvals/models.py @@ -27,6 +27,7 @@ from itou.utils.apis.pole_emploi import DATE_FORMAT, PoleEmploiAPIBadResponse, PoleEmploiAPIException from itou.utils.db import or_queries from itou.utils.models import DateRange +from itou.utils.templatetags.str_filters import pluralizefr from itou.utils.validators import alphanumeric, validate_siret from . import enums, notifications @@ -134,6 +135,28 @@ def _get_obj_remainder(self, obj): datetime.timedelta(0), ) - max(obj.start_at - timezone.localdate(), datetime.timedelta(0)) + def _get_human_readable_estimate(self, days): + split = [] + years = days // 365 + if years: + split.append(f"{years} an{pluralizefr(years)}") + days = days % 365 + months = days // 30 + if months: + split.append(f"{months} mois") + if years: + return "Environ " + " et ".join(split) + days = days % 30 + weeks = days // 7 + if weeks: + split.append(f"{weeks} semaine{pluralizefr(weeks)}") + if months: + return "Environ " + " et ".join(split) + days = days % 7 + if days: + split.append(f"{days} jour{pluralizefr(days)}") + return " et ".join(split) + @cached_property def remainder(self): """ @@ -149,6 +172,14 @@ def remainder(self): ) return result + def get_remainder_display(self): + remainder_display = f"{self.remainder.days} jour{pluralizefr(self.remainder.days)}" + if self.remainder.days: + remainder_display += f" ({self._get_human_readable_estimate(self.remainder.days)})" + return remainder_display + + get_remainder_display.short_description = "Reliquat" + @property def remainder_as_date(self): """ diff --git a/itou/templates/approvals/email/deliver_body.txt b/itou/templates/approvals/email/deliver_body.txt index 44ad02c1bfc..03605e924a6 100644 --- a/itou/templates/approvals/email/deliver_body.txt +++ b/itou/templates/approvals/email/deliver_body.txt @@ -5,7 +5,7 @@ Merci d'avoir confirmé l'embauche d'un candidat sur les emplois de l'inclusion. Vous trouverez ci-dessous votre PASS IAE (il équivaut à l'agrément Pôle emploi conformément aux articles L 5132-1 à L 5132-17 du code du travail) : PASS IAE N° : {{ job_application.approval.number_with_spaces }} -Nombre de jours restants sur le PASS IAE débutant le {{ job_application.approval.start_at|date:"d/m/Y" }} : {{ job_application.approval.remainder.days }} jours*. +Nombre de jours restants sur le PASS IAE débutant le {{ job_application.approval.start_at|date:"d/m/Y" }} : {{ job_application.approval.get_remainder_display }}*. Délivré pour l'embauche de : Nom : {{ job_application.approval.user.last_name|upper }} diff --git a/itou/templates/approvals/includes/list_card.html b/itou/templates/approvals/includes/list_card.html index f4b6dc9659c..707f25d4d73 100644 --- a/itou/templates/approvals/includes/list_card.html +++ b/itou/templates/approvals/includes/list_card.html @@ -49,13 +49,7 @@
Date de début : {{ common_approval.start_at|date:"d/m/Y" }}
Nombre de jours restants sur le PASS IAE : {{ approval.remainder.days }} jours*.
+Nombre de jours restants sur le PASS IAE : {{ approval.get_remainder_display }}*.
* Le reliquat est calculé sur la base d’un nombre de jours calendaires. Si le PASS IAE n'est pas suspendu, il décroit donc tous les jours (samedi, dimanche et jours fériés compris). diff --git a/tests/approvals/tests.py b/tests/approvals/tests.py index 856d94b6151..05d3c355295 100644 --- a/tests/approvals/tests.py +++ b/tests/approvals/tests.py @@ -529,6 +529,7 @@ def test_remainder(self): end_at=datetime.date(2023, 3, 24), ) assert approval.remainder == datetime.timedelta(days=123) + assert approval.get_remainder_display() == "123 jours (Environ 4 mois)" # Futur prolongation, adding 4 days to approval.end_date. ProlongationFactory( @@ -553,6 +554,7 @@ def test_remainder(self): approval.refresh_from_db() prolonged_remainder = 123 + 4 + 5 + 30 assert approval.remainder == datetime.timedelta(days=prolonged_remainder) + assert approval.get_remainder_display() == "162 jours (Environ 5 mois et 1 semaine)" # Past suspension (ignored), adding 5 days to approval.end_date. SuspensionFactory( @@ -571,6 +573,25 @@ def test_remainder(self): approval.refresh_from_db() # Substract to remainder the remaining suspension time assert approval.remainder == datetime.timedelta(days=(prolonged_remainder + 5 + 30 - 10)) + assert approval.get_remainder_display() == "187 jours (Environ 6 mois et 1 semaine)" + + def test_human_readable_estimate(self): + approval = Approval() + for days, expected_display in [ + (730, "Environ 2 ans"), + (705, "Environ 1 an et 11 mois"), + (380, "Environ 1 an"), + (235, "Environ 7 mois et 3 semaines"), + (158, "Environ 5 mois et 1 semaine"), + (121, "Environ 4 mois"), + (15, "2 semaines et 1 jour"), + (14, "2 semaines"), + (13, "1 semaine et 6 jours"), + (7, "1 semaine"), + (6, "6 jours"), + (1, "1 jour"), + ]: + assert approval._get_human_readable_estimate(days) == expected_display @freeze_time("2023-04-26") def test_remainder_as_date(self): @@ -730,12 +751,12 @@ def test_is_valid(self): assert approval.is_valid() @freeze_time("2022-11-22") - def test_remainder(self): + def test_get_remainder_display(self): pole_emploi_approval = PoleEmploiApprovalFactory( start_at=datetime.date(2021, 3, 25), end_at=datetime.date(2023, 3, 24), ) - assert pole_emploi_approval.remainder == datetime.timedelta(days=123) + assert pole_emploi_approval.get_remainder_display() == "123 jours (Environ 4 mois)" class PoleEmploiApprovalManagerTest(TestCase): diff --git a/tests/job_applications/tests.py b/tests/job_applications/tests.py index a6b82d3b2b5..e9ca2b26044 100644 --- a/tests/job_applications/tests.py +++ b/tests/job_applications/tests.py @@ -1036,7 +1036,7 @@ def test_notifications_deliver_approval(self): assert approval.user.get_full_name() in email.subject assert approval.number_with_spaces in email.body assert approval.start_at.strftime("%d/%m/%Y") in email.body - assert f"{approval.remainder.days} jours" in email.body + assert approval.get_remainder_display() in email.body assert approval.user.last_name.upper() in email.body assert approval.user.first_name.title() in email.body assert approval.user.birthdate.strftime("%d/%m/%Y") in email.body diff --git a/tests/www/approvals_views/__snapshots__/test_includes.ambr b/tests/www/approvals_views/__snapshots__/test_includes.ambr index ebb2e7159a1..3b27009d48e 100644 --- a/tests/www/approvals_views/__snapshots__/test_includes.ambr +++ b/tests/www/approvals_views/__snapshots__/test_includes.ambr @@ -208,7 +208,7 @@
Date de début : 01/01/2000
Date de début : 01/01/2000
Date de début : 01/01/2000