Skip to content

Commit

Permalink
API particulier: Update to breaking changes dateFin=null
Browse files Browse the repository at this point in the history
In an email on November 15th, 14:23, the following breaking regression
was announced:

> Vous utilisez l'API Revenu de solidarité active du bouquet API Particulier
> et avez prévu d'utiliser les API Allocation de soutien familial et
> Allocation adulte handicapé.
>
> Dans le Swagger et la documentation affichés actuellement sur API
> Particulier, nous indiquons que nous diffusons la date de fermeture du
> droit. Toutefois, cette date n'est pas toujours correcte. En effet, elle
> était calculée par notre API en se basant sur la date de début du droit.
> Cette date de début du droit correspond à la date de première attribution.
> Lorsque le droit est renouvelé, la date de début n'est pas modifiée. Cela
> peut donc renvoyer à une date de fin antérieure à la date à laquelle
> l'appel sur l'API a été effectué avec un Statut "Bénéficiaire".
>
> Pour éviter toute confusion, nous avons fait le choix de passer le champ
> "dateFin" à "null" dans la version actuelle de l'API.

The end date field will always be null in responses.
We were using the end date to set the validity period of a
certification. Since the API only gives “instantaneous” data (is the
person beneficiary now), and the proof must from the past 3 months
before a hire in the law, we can set the validity period to [today,
today + 92 days (~3 months)].
  • Loading branch information
francoisfreitag committed Jan 6, 2025
1 parent c1dc080 commit 5ac6c50
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 18 deletions.
8 changes: 6 additions & 2 deletions itou/eligibility/tasks.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime
import logging
from json import JSONDecodeError

Expand Down Expand Up @@ -77,8 +78,11 @@ def certify_criteria(eligibility_diagnosis):
criterion.certified_at = timezone.now()
criterion.data_returned_by_api = data["raw_response"]
criterion.certification_period = None
start_at, end_at = data["start_at"], data["end_at"]
if start_at and end_at:
if criterion.certified:
start_at = data["start_at"]
end_at = timezone.localdate(criterion.certified_at) + datetime.timedelta(
days=criterion.CERTIFICATION_GRACE_PERIOD_DAYS
)
criterion.certification_period = InclusiveDateRange(start_at, end_at)
SelectedAdministrativeCriteria.objects.bulk_update(
criteria,
Expand Down
13 changes: 4 additions & 9 deletions itou/utils/apis/api_particulier.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ def client():
)


def _parse_date(date: str) -> datetime.date | None:
if date:
return datetime.date.fromisoformat(date)
return None


def _build_params_from(job_seeker):
jobseeker_profile = job_seeker.jobseeker_profile
params = {
Expand Down Expand Up @@ -58,9 +52,10 @@ def has_required_info(job_seeker):

def revenu_solidarite_active(client, job_seeker):
response = _request(client, "/v2/revenu-solidarite-active", job_seeker)
certified = response["status"] == "beneficiaire"
return {
"start_at": _parse_date(response["dateDebut"]),
"end_at": _parse_date(response["dateFin"]),
"is_certified": response["status"] == "beneficiaire",
"start_at": datetime.date.fromisoformat(response["dateDebut"]) if certified else None,
# Do not expose end_at, it’s always null.
"is_certified": certified,
"raw_response": response,
}
2 changes: 1 addition & 1 deletion itou/utils/mocks/api_particulier.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
def rsa_certified_mocker():
# https://github.com/etalab/siade_staging_data/blob/develop/payloads/api_particulier_v2_cnav_revenu_solidarite_active/200_beneficiaire_majoration.yaml
return {"status": "beneficiaire", "majoration": True, "dateDebut": "2024-08-01", "dateFin": "2024-10-31"}
return {"status": "beneficiaire", "majoration": True, "dateDebut": "2024-08-01", "dateFin": None}


def rsa_not_certified_mocker():
Expand Down
6 changes: 3 additions & 3 deletions tests/eligibility/test_iae.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ def test_eligibility_diagnosis_certify_criteria(mocker, EligibilityDiagnosisFact
assert criterion.certified is True
assert criterion.certified_at == timezone.now()
assert criterion.data_returned_by_api == rsa_certified_mocker()
assert criterion.certification_period == InclusiveDateRange(datetime.date(2024, 8, 1), datetime.date(2024, 10, 31))
assert criterion.certification_period == InclusiveDateRange(datetime.date(2024, 8, 1), datetime.date(2024, 12, 13))


@pytest.mark.parametrize(
Expand Down Expand Up @@ -589,7 +589,7 @@ def test_eligibility_diagnosis_certify_criteria_missing_info(respx_mock, Eligibi
pytest.param(
partial(IAEEligibilityDiagnosisFactory, from_employer=True),
{
"certification_period": InclusiveDateRange(datetime.date(2024, 8, 1), datetime.date(2024, 10, 31)),
"certification_period": InclusiveDateRange(datetime.date(2024, 8, 1), datetime.date(2024, 12, 13)),
"certified": True,
"certified_at": datetime.datetime(2024, 9, 12, tzinfo=datetime.UTC),
"data_returned_by_api": rsa_certified_mocker(),
Expand All @@ -601,7 +601,7 @@ def test_eligibility_diagnosis_certify_criteria_missing_info(respx_mock, Eligibi
pytest.param(
partial(GEIQEligibilityDiagnosisFactory, from_geiq=True),
{
"certification_period": InclusiveDateRange(datetime.date(2024, 8, 1), datetime.date(2024, 10, 31)),
"certification_period": InclusiveDateRange(datetime.date(2024, 8, 1), datetime.date(2024, 12, 13)),
"certified": True,
"certified_at": datetime.datetime(2024, 9, 12, tzinfo=datetime.UTC),
"data_returned_by_api": rsa_certified_mocker(),
Expand Down
3 changes: 2 additions & 1 deletion tests/eligibility/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def geiq_eligibility_factory():
],
)
class TestCertifyCriteria:
@freeze_time("2025-01-06")
def test_queue_task(self, factory, respx_mock):
eligibility_diagnosis = factory()
respx_mock.get(f"{settings.API_PARTICULIER_BASE_URL}v2/revenu-solidarite-active").respond(
Expand All @@ -54,7 +55,7 @@ def test_queue_task(self, factory, respx_mock):
assert criterion.certified_at is not None
assert criterion.data_returned_by_api == rsa_certified_mocker()
assert criterion.certification_period == InclusiveDateRange(
datetime.date(2024, 8, 1), datetime.date(2024, 10, 31)
datetime.date(2024, 8, 1), datetime.date(2025, 4, 8)
)

def test_retry_task_rate_limits(self, factory, respx_mock):
Expand Down
4 changes: 2 additions & 2 deletions tests/www/apply/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -2569,7 +2569,7 @@ def test_accept_iae__criteria_can_be_certified(self, client, mocker):
assert criterion.certified
assert criterion.data_returned_by_api == rsa_certified_mocker()
assert criterion.certification_period == InclusiveDateRange(
datetime.date(2024, 8, 1), datetime.date(2024, 10, 31)
datetime.date(2024, 8, 1), datetime.date(2024, 12, 12)
)
assert criterion.certified_at

Expand Down Expand Up @@ -2634,7 +2634,7 @@ def test_accept_geiq__criteria_can_be_certified(self, client, mocker):
assert criterion.certified
assert criterion.data_returned_by_api == rsa_certified_mocker()
assert criterion.certification_period == InclusiveDateRange(
datetime.date(2024, 8, 1), datetime.date(2024, 10, 31)
datetime.date(2024, 8, 1), datetime.date(2024, 12, 12)
)
assert criterion.certified_at

Expand Down

0 comments on commit 5ac6c50

Please sign in to comment.