Skip to content

Commit

Permalink
approvals: Improve remainder display
Browse files Browse the repository at this point in the history
  • Loading branch information
tonial committed Jul 16, 2024
1 parent 82ecb15 commit 8433b9c
Show file tree
Hide file tree
Showing 12 changed files with 71 additions and 29 deletions.
8 changes: 2 additions & 6 deletions itou/approvals/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ class ApprovalAdmin(InconsistencyCheckMixin, ItouModelAdmin):
"origin_sender_kind",
"origin_siae_kind",
"origin_siae_siret",
"remainder",
"get_remainder_display",
)
fieldsets = (
(
Expand All @@ -242,7 +242,7 @@ class ApprovalAdmin(InconsistencyCheckMixin, ItouModelAdmin):
"number",
"start_at",
"end_at",
"remainder",
"get_remainder_display",
"user",
"eligibility_diagnosis",
"assigned_company",
Expand Down Expand Up @@ -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"
Expand Down
31 changes: 31 additions & 0 deletions itou/approvals/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
"""
Expand All @@ -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):
"""
Expand Down
2 changes: 1 addition & 1 deletion itou/templates/approvals/email/deliver_body.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
8 changes: 1 addition & 7 deletions itou/templates/approvals/includes/list_card.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,7 @@ <h3>{{ approval.user.get_full_name }}</h3>
<i class="ri-information-line text-info"
data-bs-toggle="tooltip"
title="Le reliquat est calculé sur la base d'un nombre de jours calendaires. Si le PASS IAE n'est pas suspendu, il décroît donc tous les jours (samedi, dimanche et jours fériés compris)."></i></small>
<strong class="text-success">
{% if approval.is_valid %}
{{ approval.remainder.days }} jour{{ approval.remainder.days|pluralizefr }}
{% else %}
0 jour
{% endif %}
</strong>
<strong class="text-success">{{ approval.get_remainder_display }}</strong>

</li>

Expand Down
2 changes: 1 addition & 1 deletion itou/templates/approvals/includes/status.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
<p class="mb-1">Date de début : {{ common_approval.start_at|date:"d/m/Y" }}</p>
<ul class="list-unstyled">
<li class="h4 mt-4 mb-2">
Nombre de jours restants sur le PASS IAE : {{ common_approval.remainder.days }} jour{{ common_approval.remainder.days|pluralizefr }}
Nombre de jours restants sur le PASS IAE : {{ common_approval.get_remainder_display }}
<i class="ri-information-line ri-xl text-info"
data-bs-toggle="tooltip"
title="Le reliquat est calculé sur la base d'un nombre de jours calendaires. Si le PASS IAE n'est pas suspendu, il décroît donc tous les jours (samedi, dimanche et jours fériés compris)."></i>
Expand Down
2 changes: 1 addition & 1 deletion itou/templates/approvals/printable_approval.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ <h1 class="ff-base fs-base">
un PASS IAE pour un parcours d'insertion par l'activité économique,
conformément aux dispositions des articles L 5132-1 à L 5132-17 du code du travail.
</p>
<p>Nombre de jours restants sur le PASS IAE : {{ approval.remainder.days }} jours*.</p>
<p>Nombre de jours restants sur le PASS IAE : {{ approval.get_remainder_display }}*.</p>
<p class="font-italic">
* 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).
Expand Down
25 changes: 23 additions & 2 deletions tests/approvals/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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(
Expand All @@ -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):
Expand Down Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion tests/job_applications/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions tests/www/approvals_views/__snapshots__/test_includes.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@
<p class="mb-1">Date de début : 01/01/2000</p>
<ul class="list-unstyled">
<li class="h4 mt-4 mb-2">
Nombre de jours restants sur le PASS IAE : 357199 jours
Nombre de jours restants sur le PASS IAE : 357199 jours (Environ 978 ans et 7 mois)
<i class="ri-information-line ri-xl text-info"
data-bs-toggle="tooltip"
title="Le reliquat est calculé sur la base d'un nombre de jours calendaires. Si le PASS IAE n'est pas suspendu, il décroît donc tous les jours (samedi, dimanche et jours fériés compris)."></i>
Expand Down Expand Up @@ -274,7 +274,7 @@
<p class="mb-1">Date de début : 01/01/2000</p>
<ul class="list-unstyled">
<li class="h4 mt-4 mb-2">
Nombre de jours restants sur le PASS IAE : 357199 jours
Nombre de jours restants sur le PASS IAE : 357199 jours (Environ 978 ans et 7 mois)
<i class="ri-information-line ri-xl text-info"
data-bs-toggle="tooltip"
title="Le reliquat est calculé sur la base d'un nombre de jours calendaires. Si le PASS IAE n'est pas suspendu, il décroît donc tous les jours (samedi, dimanche et jours fériés compris)."></i>
Expand Down Expand Up @@ -340,7 +340,7 @@
<p class="mb-1">Date de début : 01/01/2000</p>
<ul class="list-unstyled">
<li class="h4 mt-4 mb-2">
Nombre de jours restants sur le PASS IAE : 357199 jours
Nombre de jours restants sur le PASS IAE : 357199 jours (Environ 978 ans et 7 mois)
<i class="ri-information-line ri-xl text-info"
data-bs-toggle="tooltip"
title="Le reliquat est calculé sur la base d'un nombre de jours calendaires. Si le PASS IAE n'est pas suspendu, il décroît donc tous les jours (samedi, dimanche et jours fériés compris)."></i>
Expand Down
6 changes: 3 additions & 3 deletions tests/www/approvals_views/test_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def test_approval_status_includes(self, client, snapshot):
+ 1 # approval.suspension active today
+ 1 # Suspension.can_be_handled_by_siae >> get_user_last_accepted_siae_job_application()
+ 1 # select latest approval for user (can_be_prolonged)
+ 1 # approval.remainder fetches approval suspensions to compute remaining days.
+ 1 # approval.get_remainder_display fetches approval suspensions to compute remaining days.
+ 1 # release savepoint before the template rendering
+ 1 # template: approval.suspensions_for_status_card lists approval suspensions
+ 1 # template: approval prolongations list.
Expand All @@ -151,7 +151,7 @@ def test_approval_status_includes(self, client, snapshot):
response = client.get(url)
assertContains(response, format_approval_number(approval))
assertContains(response, approval.start_at.strftime("%d/%m/%Y"))
assertContains(response, f"{approval.remainder.days} jours")
assertContains(response, approval.get_remainder_display())
assertNotContains(
response,
"PASS IAE valide jusqu’au 24/04/2025, si le contrat démarre aujourd’hui.",
Expand Down Expand Up @@ -212,7 +212,7 @@ def test_approval_status_includes(self, client, snapshot):
# context processors
+ 1 # siae membership (get_context_siae)
# template: approvals/includes/status.html
+ 1 # template: approval.remainder fetches approval suspensions to compute remaining days
+ 1 # template: approval.get_remainder_display fetches approval suspensions to compute remaining days
+ 1 # template: approval.prolongations_for_status_card
+ 1 # template: approval.prolongation_requests_for_status_card lists not accepted prolongation requests
# template: eligibility_diagnosis.html
Expand Down
2 changes: 1 addition & 1 deletion tests/www/approvals_views/test_display.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def test_display_job_app_approval(self, *args, **kwargs):
self.assertContains(response, global_constants.ITOU_HELP_CENTER_URL)
self.assertContains(response, "Imprimer ce PASS IAE")
self.assertContains(response, job_application.approval.start_at.strftime("%d/%m/%Y"))
self.assertContains(response, f"{job_application.approval.remainder.days} jours")
self.assertContains(response, job_application.approval.get_remainder_display())

def test_display_approval_multiple_job_applications(self, *args, **kwargs):
job_application = JobApplicationFactory(with_approval=True)
Expand Down
6 changes: 3 additions & 3 deletions tests/www/approvals_views/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,11 @@ def test_approval_state_filters(self, client):
)

# Check IAE pass remainder days
assertContains(response, "367 jours")
assertContains(response, "367 jours (Environ 1 an)")

assertContains(response, "365 jours")
assertContains(response, "365 jours (Environ 1 an)")

assertContains(response, "730 jours")
assertContains(response, "730 jours (Environ 2 ans)")

assertContains(response, "0 jour")

Expand Down

0 comments on commit 8433b9c

Please sign in to comment.