Skip to content

Commit

Permalink
api: add departement_postes filter to SIAE endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
xavfernandez committed Jun 24, 2024
1 parent 4c87230 commit 9bd11ce
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
26 changes: 22 additions & 4 deletions itou/api/siae_api/viewsets.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging

from django.db.models import Prefetch
from django.db.models import Exists, OuterRef, Prefetch, Q
from django_filters.filters import CharFilter, ChoiceFilter, NumberFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
from drf_spectacular.types import OpenApiTypes
Expand Down Expand Up @@ -65,11 +65,29 @@ class CompanyFilterSet(FilterSet):
field_name="department", choices=list(DEPARTMENTS.items()), help_text="Département de la structure"
)

departement_postes = ChoiceFilter(
choices=list(DEPARTMENTS.items()),
help_text="Département d'un poste de la structure.",
method="having_job_in_department",
)

def having_job_in_department(self, queryset, name, value):
# Either a Job in one of the department cities
# or a Job without city when the company department matches
return queryset.filter(
Exists(JobDescription.objects.filter(company=OuterRef("pk"), location__department=value))
| (
Q(department=value)
& Exists(JobDescription.objects.filter(company=OuterRef("pk"), location__isnull=True))
)
)

def filter_queryset(self, queryset):
filtered_queryset = super().filter_queryset(queryset)
code_insee = self.form.cleaned_data.get("code_insee")
distance = self.form.cleaned_data.get("distance_max_km")
department = self.form.cleaned_data.get("departement")
job_department = self.form.cleaned_data.get("departement_postes")

if distance and code_insee:
try:
Expand All @@ -79,12 +97,12 @@ def filter_queryset(self, queryset):
# Ensure the error comes from a missing city, which may not be that clear
# with get_object_or_404
raise NotFound(f"Pas de ville avec pour code_insee {code_insee}")
elif not department:
elif not (department or job_department):
raise ValidationError(
f"Les paramètres `{CODE_INSEE_PARAM_NAME}` et `{DISTANCE_FROM_CODE_INSEE_PARAM_NAME}` sont "
"obligatoires si `departement` n'est pas spécifié."
"obligatoires si ni `departement` ni `departement_postes` ne sont spécifiés."
)
# Here the department filter has been applied
# Here the department/job_department filters have been applied
return filtered_queryset


Expand Down
20 changes: 19 additions & 1 deletion tests/api/siae_api/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ def test_fetch_siae_list_without_params(self):

assert response.status_code == 400
assert response.json() == [
"Les paramètres `code_insee` et `distance_max_km` sont obligatoires si `departement` n'est pas spécifié."
"Les paramètres `code_insee` et `distance_max_km` sont obligatoires si ni `departement` ni "
"`departement_postes` ne sont spécifiés."
]

def test_fetch_siae_list_with_too_high_distance(self):
Expand Down Expand Up @@ -196,6 +197,23 @@ def test_fetch_siae_list_by_department(self):
assert response.status_code == 200
assert company56.siret not in {company["siret"] for company in body["results"]}

def test_fetch_siae_list_by_job_department(self):
# Declare company in 56 despite its coordinates
_company56 = CompanyFactory(kind=CompanyKind.EI, department="56", coords=self.saint_andre.coords)
query_params = {"departement_postes": "56"}
response = self.client.get(ENDPOINT_URL, query_params, format="json")

assert response.status_code == 200
assert response.json()["count"] == 0 # No job in 56

query_params = {"departement_postes": "44"}
response = self.client.get(ENDPOINT_URL, query_params, format="json")

assert response.status_code == 200
body = response.json()
assert body["count"] == 1 # No job in 56
assert body["results"][0]["siret"] == self.company_with_jobs.siret

def test_fetch_siae_list_rate_limits(self):
query_params = {"code_insee": self.saint_andre.code_insee, "distance_max_km": 100}
# Declared in itou.api.siae_api.viewsets.RestrictedUserRateThrottle.
Expand Down

0 comments on commit 9bd11ce

Please sign in to comment.