Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Employeur: Réduction de la durée de validité du diagnostic d’éligibilité à 92 jours [GEN-2276] #5285

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions itou/eligibility/models/common.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import datetime
import logging

from dateutil.relativedelta import relativedelta
from django.conf import settings
from django.db import models
from django.utils import timezone
Expand Down Expand Up @@ -78,11 +77,6 @@ class Meta:
def __str__(self):
return str(self.pk)

def save(self, *args, **kwargs):
if not self.expires_at:
self.expires_at = timezone.localdate(self.created_at) + relativedelta(months=self.EXPIRATION_DELAY_MONTHS)
return super().save(*args, **kwargs)

@property
def is_valid(self):
return self.expires_at > timezone.localdate()
Expand Down
1 change: 1 addition & 0 deletions itou/eligibility/models/geiq.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ def create_eligibility_diagnosis(
author_kind=author_kind,
author_prescriber_organization=author_org,
author_geiq=author_geiq,
expires_at=timezone.localdate() + relativedelta(months=cls.EXPIRATION_DELAY_MONTHS),
)

if administrative_criteria:
Expand Down
16 changes: 13 additions & 3 deletions itou/eligibility/models/iae.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime
import logging

from dateutil.relativedelta import relativedelta
Expand Down Expand Up @@ -163,6 +164,16 @@ def considered_to_expire_at(self):
return self.job_seeker.latest_approval.end_at
return self.expires_at

@classmethod
def _expiration_date(cls, author):
now = timezone.localdate()
if author.is_employer:
# For siae_evaluations, employers must provide a proof for administrative criteria
# supporting the hire. A proof is valid for 3 months, align employer diagnosis
# duration with proof validity duration.
return now + datetime.timedelta(days=92)
return now + relativedelta(months=cls.EXPIRATION_DELAY_MONTHS)

@classmethod
@transaction.atomic()
def create_diagnosis(cls, job_seeker, *, author, author_organization, administrative_criteria=None):
Expand All @@ -180,6 +191,7 @@ def create_diagnosis(cls, job_seeker, *, author, author_organization, administra
author_kind=author.kind,
author_siae=author_organization if author.is_employer else None,
author_prescriber_organization=author_organization if author.is_prescriber else None,
expires_at=cls._expiration_date(author),
)
if administrative_criteria:
diagnosis.administrative_criteria.add(*administrative_criteria)
Expand All @@ -194,9 +206,7 @@ def update_diagnosis(cls, eligibility_diagnosis, *, author, author_organization,
set(eligibility_diagnosis.administrative_criteria.all()) == set(administrative_criteria),
]
if all(extend_conditions):
eligibility_diagnosis.expires_at = timezone.localdate() + relativedelta(
months=EligibilityDiagnosis.EXPIRATION_DELAY_MONTHS
)
eligibility_diagnosis.expires_at = cls._expiration_date(author)
eligibility_diagnosis.save(update_fields=["expires_at"])
return eligibility_diagnosis

Expand Down
25 changes: 12 additions & 13 deletions itou/www/apply/views/submit_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,19 +535,18 @@ def post(self, request, *args, **kwargs):
return self.render_to_response(self.get_context_data(**kwargs))

def get_context_data(self, **kwargs):
new_expires_at_if_updated = timezone.now() + relativedelta(months=EligibilityDiagnosis.EXPIRATION_DELAY_MONTHS)

return super().get_context_data(**kwargs) | {
"form": self.form,
"new_expires_at_if_updated": new_expires_at_if_updated,
"progress": 50,
"job_seeker": self.job_seeker,
"back_url": reverse(
"apply:application_jobs",
kwargs={"company_pk": self.company.pk, "job_seeker_public_id": self.job_seeker.public_id},
),
"full_content_width": True,
}
context = super().get_context_data(**kwargs)
context["form"] = self.form
context["progress"] = 50
context["job_seeker"] = self.job_seeker
context["back_url"] = reverse(
"apply:application_jobs",
kwargs={"company_pk": self.company.pk, "job_seeker_public_id": self.job_seeker.public_id},
)
context["full_content_width"] = True
if self.eligibility_diagnosis:
context["new_expires_at_if_updated"] = self.eligibility_diagnosis._expiration_date(self.request.user)
return context


class ApplicationGEIQEligibilityView(RequireApplySessionMixin, ApplicationBaseView):
Expand Down
6 changes: 6 additions & 0 deletions tests/eligibility/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
import random

import factory
from dateutil.relativedelta import relativedelta
from django.utils import timezone
from faker import Faker

from itou.companies.enums import CompanyKind
from itou.eligibility import models
from itou.eligibility.enums import AdministrativeCriteriaAnnex, AuthorKind
from itou.eligibility.models.common import AbstractEligibilityDiagnosisModel
from tests.companies.factories import CompanyFactory, CompanyWith2MembershipsFactory
from tests.prescribers.factories import PrescriberOrganizationWithMembershipFactory
from tests.users.factories import JobSeekerFactory
Expand Down Expand Up @@ -42,6 +44,10 @@ class Params:
)

created_at = factory.LazyFunction(timezone.now)
expires_at = factory.LazyAttribute(
lambda obj: timezone.localdate(obj.created_at)
+ relativedelta(months=AbstractEligibilityDiagnosisModel.EXPIRATION_DELAY_MONTHS)
)
job_seeker = factory.SubFactory(JobSeekerFactory)


Expand Down
26 changes: 25 additions & 1 deletion tests/eligibility/test_iae.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ def test_itou_diagnosis_expired_uses_the_most_recent(self):


class TestEligibilityDiagnosisModel:
def test_create_diagnosis(self):
@freeze_time("2024-12-03")
def test_create_diagnosis_employer(self):
job_seeker = JobSeekerFactory()
company = CompanyFactory(with_membership=True)
user = company.members.first()
Expand All @@ -273,6 +274,27 @@ def test_create_diagnosis(self):
assert diagnosis.author_siae == company
assert diagnosis.author_prescriber_organization is None
assert diagnosis.administrative_criteria.count() == 0
assert diagnosis.expires_at == datetime.date(2025, 3, 5)

@freeze_time("2024-12-03")
def test_create_diagnosis_prescriber(self):
job_seeker = JobSeekerFactory()
organization = PrescriberOrganizationWithMembershipFactory()
prescriber = organization.members.first()

diagnosis = EligibilityDiagnosis.create_diagnosis(
job_seeker,
author=prescriber,
author_organization=organization,
)

assert diagnosis.job_seeker == job_seeker
assert diagnosis.author == prescriber
assert diagnosis.author_kind == AuthorKind.PRESCRIBER
assert diagnosis.author_siae is None
assert diagnosis.author_prescriber_organization == organization
assert diagnosis.administrative_criteria.count() == 0
assert diagnosis.expires_at == datetime.date(2025, 6, 3)

def test_create_diagnosis_with_administrative_criteria(self):
job_seeker = JobSeekerFactory()
Expand Down Expand Up @@ -304,6 +326,7 @@ def test_create_diagnosis_with_administrative_criteria(self):
assert criteria2 in administrative_criteria
assert criteria3 in administrative_criteria

@freeze_time("2024-12-03")
def test_update_diagnosis(self):
company = CompanyFactory(with_membership=True)

Expand All @@ -321,6 +344,7 @@ def test_update_diagnosis(self):
assert new_diagnosis.author_siae == company
assert new_diagnosis.author_prescriber_organization is None
assert new_diagnosis.administrative_criteria.count() == 0
assert new_diagnosis.expires_at == datetime.date(2025, 3, 5)

# And the old diagnosis should now be expired (thus considered invalid)
assert current_diagnosis.expires_at == timezone.localdate(new_diagnosis.created_at)
Expand Down
12 changes: 11 additions & 1 deletion tests/www/apply/test_submit.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from django.core.files.storage import storages
from django.urls import resolve, reverse
from django.utils import timezone
from freezegun import freeze_time
from pytest_django.asserts import (
assertContains,
assertMessages,
Expand Down Expand Up @@ -1093,6 +1094,7 @@ def test_apply_as_prescriber_with_pending_authorization(self, client, pdf_file):
response = client.get(next_url)
assert response.status_code == 200

@freeze_time()
def test_apply_as_authorized_prescriber(self, client, pdf_file):
company = CompanyWithMembershipAndJobsFactory(romes=("N1101", "N1105"))
reset_url_company = reverse("companies_views:card", kwargs={"siae_id": company.pk})
Expand Down Expand Up @@ -1325,7 +1327,9 @@ def test_apply_as_authorized_prescriber(self, client, pdf_file):

response = client.post(next_url, {"level_1_1": True})
assert response.status_code == 302
assert EligibilityDiagnosis.objects.has_considered_valid(new_job_seeker, for_siae=company)
diag = EligibilityDiagnosis.objects.last_considered_valid(job_seeker=new_job_seeker, for_siae=company)
assert diag.is_valid is True
assert diag.expires_at == timezone.localdate() + relativedelta(months=6)

next_url = reverse(
"apply:application_resume",
Expand Down Expand Up @@ -2561,6 +2565,7 @@ def test_hire_as_siae_with_suspension_sanction(self, client):
@pytest.mark.ignore_unknown_variable_template_error(
"confirmation_needed", "is_subject_to_eligibility_rules", "job_seeker"
)
@freeze_time()
def test_hire_as_company(self, client):
"""Apply as company (and create new job seeker)"""

Expand Down Expand Up @@ -2812,6 +2817,8 @@ def test_hire_as_company(self, client):
kwargs={"company_pk": company.pk, "job_seeker_public_id": new_job_seeker.public_id},
)
assert response.url == next_url
diag = EligibilityDiagnosis.objects.last_considered_valid(job_seeker=new_job_seeker, for_siae=company)
assert diag.expires_at == timezone.localdate() + datetime.timedelta(days=92)

# Hire confirmation
# ----------------------------------------------------------------------
Expand Down Expand Up @@ -2879,6 +2886,7 @@ def test_hire_as_company(self, client):
assertTemplateUsed(response, "approvals/includes/box.html")
assert response.status_code == 200

@freeze_time()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pourquoi ces yeux ?

Copy link
Collaborator

@celine-m-s celine-m-s Dec 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah pardon, j'ai cru que c'étaient des oublis. Je me demandais pourquoi utiliser freeze_time sans passer de date en paramètre. Je n'ai rien vu dans la doc à ce sujet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, c’est voulu parce que je hardcode la date attendue (à +92j). C’est pour éviter des échecs autour de minuit.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah d'accord ! Merci !

def test_hire_as_geiq(self, client):
"""Apply as GEIQ with pre-existing job seeker without previous application"""
company = CompanyWithMembershipAndJobsFactory(romes=("N1101", "N1105"), kind=CompanyKind.GEIQ)
Expand Down Expand Up @@ -2967,6 +2975,8 @@ def test_hire_as_geiq(self, client):
},
)
assertRedirects(response, confirmation_url)
diag = GEIQEligibilityDiagnosis.objects.get(job_seeker=job_seeker)
assert diag.expires_at == timezone.localdate() + relativedelta(months=6)

# Hire confirmation
# ----------------------------------------------------------------------
Expand Down
Loading