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

build exclusivite reparation filter when reparer is checked #718

Merged
merged 6 commits into from
Jul 18, 2024
Merged
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
105 changes: 52 additions & 53 deletions qfdmo/views/adresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,24 +114,15 @@ def get_form(self, form_class: type | None = None) -> BaseForm:
def get_context_data(self, **kwargs):
kwargs["location"] = "{}"
kwargs["carte"] = self.request.GET.get("carte") is not None

# TODO : voir pour utiliser davantage le form dans cette vue
form = self.get_form_class()(self.request.GET)
form.is_valid()
self.cleaned_data = form.cleaned_data

# Manage the selection of sous_categorie_objet and actions
acteurs = self._manage_sous_categorie_objet_and_actions()

if self.request.GET.get("ess"):
acteurs = acteurs.filter(labels__code="ess")

if self.request.GET.get("bonus"):
acteurs = acteurs.filter(labels__bonus=True)

if (
"reparer" not in form.cleaned_data["action_list"]
or form.cleaned_data["pas_exclusivite_reparation"]
):
acteurs = acteurs.exclude(exclusivite_de_reprisereparation=True)

# Case of digital acteurs
if self.request.GET.get("digital") and self.request.GET.get("digital") == "1":
kwargs["acteurs"] = (
Expand All @@ -142,6 +133,8 @@ def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs)

# Case of physical acteurs
# TODO : refactoriser ci-dessous pour passer dans
# _manage_sous_categorie_objet_and_actions ou autre
else:
# Exclude digital acteurs
acteurs = acteurs.exclude(
Expand Down Expand Up @@ -306,7 +299,14 @@ def _get_selected_action_code(self):
return []

def _get_selected_action_ids(self):
return [a.id for a in self._get_selected_action()]
if self.request.GET.get("carte") is not None:
return [a.id for a in self._get_selected_action()]

return [a["id"] for a in self.get_action_list()]

def _get_reparer_action_id(self):
"""Sert essentiellement à faciliter le teste de AddressesView"""
return CachedDirectionAction.get_reparer_action_id()

def _get_selected_action(self) -> List[Action]:
"""
Expand Down Expand Up @@ -357,60 +357,58 @@ def get_action_list(self) -> List[dict]:
return [model_to_dict(a, exclude=["directions"]) for a in actions]

def _manage_sous_categorie_objet_and_actions(self) -> QuerySet[DisplayedActeur]:
sous_categorie_id = None
if (
self.request.GET.get("sous_categorie_objet")
and self.request.GET.get("sc_id", "").isnumeric()
):
sous_categorie_id = int(self.request.GET.get("sc_id", "0"))

action_selection_ids = (
self._get_selected_action_ids()
if self.request.GET.get("carte") is not None
else [a["id"] for a in self.get_action_list()]
)

ps_filter = self._build_ps_filter(action_selection_ids, sous_categorie_id)

acteurs = DisplayedActeur.objects.filter(ps_filter)

filters, excludes = self._compile_acteurs_queryset()
acteurs = DisplayedActeur.objects.filter(filters).exclude(excludes)
acteurs = acteurs.prefetch_related(
"proposition_services__sous_categories",
"proposition_services__sous_categories__categorie",
"proposition_services__action",
"proposition_services__acteur_service",
).distinct()

if sous_categorie_id:
acteurs = acteurs.filter(
proposition_services__sous_categories__id=sous_categorie_id
)

return acteurs

def _build_ps_filter(self, action_selection_ids, sous_categorie_id: int | None):
reparer_action_id = None
def _compile_acteurs_queryset(self):
filters = Q()
excludes = Q()

selected_actions_ids = self._get_selected_action_ids()
reparer_action_id = self._get_reparer_action_id()
reparer_is_checked = reparer_action_id in selected_actions_ids

if (
self.request.GET.get("label_reparacteur")
and CachedDirectionAction.get_reparer_action_id() in action_selection_ids
self.cleaned_data["pas_exclusivite_reparation"] is not False
or not reparer_is_checked
):
reparer_action_id = CachedDirectionAction.get_reparer_action_id()
action_selection_ids = [
a for a in action_selection_ids if a != reparer_action_id
excludes |= Q(exclusivite_de_reprisereparation=True)

if self.cleaned_data["label_reparacteur"] and reparer_is_checked:
selected_actions_ids = [
a for a in selected_actions_ids if a != reparer_action_id
]

ps_filter = Q()
if sous_categorie_id:
if action_selection_ids:
ps_filter = ps_filter | Q(
if self.cleaned_data["ess"]:
filters |= Q(labels__code="ess")

if self.cleaned_data["bonus"]:
filters |= Q(labels__bonus=True)

if self.cleaned_data.get("sous_categorie_objet") and self.cleaned_data.get(
"sc_id"
):
sous_categorie_id = self.cleaned_data.get("sc_id", 0)
filters |= Q(proposition_services__sous_categories__id=sous_categorie_id)

if selected_actions_ids:
filters |= Q(
proposition_services__in=DisplayedPropositionService.objects.filter(
action_id__in=action_selection_ids,
action_id__in=selected_actions_ids,
sous_categories__id=sous_categorie_id,
),
statut=ActeurStatus.ACTIF,
)
if reparer_action_id:
ps_filter = ps_filter | Q(
filters |= Q(
proposition_services__in=DisplayedPropositionService.objects.filter(
action_id=reparer_action_id,
sous_categories__id=sous_categorie_id,
Expand All @@ -419,18 +417,19 @@ def _build_ps_filter(self, action_selection_ids, sous_categorie_id: int | None):
statut=ActeurStatus.ACTIF,
)
else:
if action_selection_ids:
ps_filter = ps_filter | Q(
proposition_services__action_id__in=action_selection_ids,
if selected_actions_ids:
filters |= Q(
proposition_services__action_id__in=selected_actions_ids,
statut=ActeurStatus.ACTIF,
)
if reparer_action_id:
ps_filter = ps_filter | Q(
filters |= Q(
proposition_services__action_id=reparer_action_id,
labels__code="reparacteur",
statut=ActeurStatus.ACTIF,
)
return ps_filter

return filters, excludes

def _get_grouped_action_choices(
self, action_displayed: list[Action]
Expand Down
4 changes: 3 additions & 1 deletion unit_tests/qfdmo/acteur_factory.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import factory.fuzzy
from django.contrib.gis.geos import Point
from factory import SubFactory
from factory import SubFactory, Faker
from factory.django import DjangoModelFactory as Factory

from qfdmo.models import (
Expand All @@ -20,6 +20,8 @@ class SourceFactory(Factory):
class Meta:
model = Source

libelle = Faker("word")
code = Faker("word")
afficher = True


Expand Down
31 changes: 22 additions & 9 deletions unit_tests/qfdmo/test_addresses_view.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from django.contrib.gis.geos import Point
import pytest
from unittest.mock import MagicMock
import pytest
from django.http import HttpRequest

from qfdmo.models.acteur import DisplayedActeur
from qfdmo.models.acteur import ActeurStatus
from qfdmo.views.adresses import AddressesView
from unit_tests.core.test_utils import query_dict_from
from unit_tests.qfdmo.acteur_factory import DisplayedActeurFactory
from unit_tests.qfdmo.acteur_factory import (
DisplayedActeurFactory,
DisplayedPropositionServiceFactory,
LabelQualiteFactory,
)
from unit_tests.qfdmo.action_factory import ActionFactory


class TestAdessesViewGetActionList:
Expand Down Expand Up @@ -69,14 +74,21 @@ def test_get_action_list(self, params, action_list):

@pytest.fixture
def adresses_view():
DisplayedActeurFactory(
reparacteur = LabelQualiteFactory(code="reparacteur")
action = ActionFactory()

displayed_acteur = DisplayedActeurFactory(
exclusivite_de_reprisereparation=True,
location=Point(1, 1),
statut=ActeurStatus.ACTIF,
)
display_proposition_service = DisplayedPropositionServiceFactory(action=action)
displayed_acteur.labels.add(reparacteur)
displayed_acteur.proposition_services.add(display_proposition_service)

adresses_view = AddressesView()
adresses_view._manage_sous_categorie_objet_and_actions = MagicMock(
return_value=DisplayedActeur.objects.all()
)
adresses_view._get_reparer_action_id = MagicMock(return_value=action.id)
adresses_view._get_selected_action_ids = MagicMock(return_value=[action.id])
return adresses_view


Expand All @@ -89,7 +101,7 @@ def test_pas_action_reparer_exclut_acteurs_avec_exclusivite(self, adresses_view)
"action_list": ["preter"],
"latitude": [1],
"longitude": [1],
"pas_exclusivite_reparation": ["on"],
"pas_exclusivite_reparation": ["true"],
}
)
adresses_view.request = request
Expand All @@ -104,9 +116,9 @@ def test_action_reparer_exclut_par_defaut_acteurs_avec_exclusivite(
request.GET = query_dict_from(
{
"action_list": ["preter|reparer"],
"pas_exclusivite_reparation": ["on"],
"latitude": [1],
"longitude": [1],
"pas_exclusivite_reparation": ["true"],
}
)
adresses_view.request = request
Expand All @@ -123,6 +135,7 @@ def test_action_reparer_et_exclusivite_inclut_acteurs_avec_exclusivite(
"action_list": ["preter|reparer"],
"latitude": [1],
"longitude": [1],
"pas_exclusivite_reparation": ["false"],
}
)
adresses_view.request = request
Expand Down
Loading