Skip to content

Commit 8a72bea

Browse files
authored
Merge pull request #127 from maykinmedia/feature/121-expand
Feature/121 expand
2 parents 8330ab6 + 75f6632 commit 8a72bea

28 files changed

+1241
-162
lines changed

src/openklant/components/klantinteracties/api/filterset/__init__.py

Whitespace-only changes.

src/openklant/components/klantinteracties/api/filterset/klantcontacten.py

+11
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44

55
from django_filters.rest_framework import FilterSet, filters
66

7+
from openklant.components.klantinteracties.api.serializers.klantcontacten import (
8+
KlantcontactSerializer,
9+
)
710
from openklant.components.klantinteracties.models.klantcontacten import (
811
Betrokkene,
912
Klantcontact,
1013
)
14+
from openklant.components.utils.filters import ExpandFilter
1115

1216

1317
class KlantcontactFilterSet(FilterSet):
@@ -28,6 +32,13 @@ class KlantcontactFilterSet(FilterSet):
2832
help_text=_("Zoek klantcontacten met specifieke tekst in onderwerp"),
2933
)
3034

35+
expand = ExpandFilter(
36+
serializer_class=KlantcontactSerializer,
37+
help_text=_(
38+
"Sluit de gespecifieerde gerelateerde resources in in het antwoord."
39+
),
40+
)
41+
3142
class Meta:
3243
model = Klantcontact
3344
fields = (

src/openklant/components/klantinteracties/api/filterset/partijen.py

+11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44

55
from django_filters.rest_framework import FilterSet, filters
66

7+
from openklant.components.klantinteracties.api.serializers.partijen import (
8+
PartijSerializer,
9+
)
710
from openklant.components.klantinteracties.models.partijen import Partij
11+
from openklant.components.utils.filters import ExpandFilter
812

913

1014
class PartijFilterSet(FilterSet):
@@ -50,6 +54,13 @@ class PartijFilterSet(FilterSet):
5054
method="filter_identificator_register",
5155
)
5256

57+
expand = ExpandFilter(
58+
serializer_class=PartijSerializer,
59+
help_text=_(
60+
"Sluit de gespecifieerde gerelateerde resources in in het antwoord."
61+
),
62+
)
63+
5364
class Meta:
5465
model = Partij
5566
fields = (

src/openklant/components/klantinteracties/api/serializers/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SERIALIZER_PATH = "openklant.components.klantinteracties.api.serializers"

src/openklant/components/klantinteracties/api/serializers/klantcontacten.py

+25
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
from openklant.components.klantinteracties.api.serializers.actoren import (
88
ActorForeignKeySerializer,
99
)
10+
from openklant.components.klantinteracties.api.serializers.constants import (
11+
SERIALIZER_PATH,
12+
)
13+
from openklant.components.klantinteracties.api.serializers.digitaal_adres import (
14+
DigitaalAdresForeignKeySerializer,
15+
)
1016
from openklant.components.klantinteracties.api.validators import (
1117
betrokkene_exists,
1218
bijlage_exists,
@@ -150,6 +156,12 @@ class BetrokkeneSerializer(
150156
help_text=_("Persoon of organisatie die betrokken was bij een klantcontact."),
151157
source="klantcontact",
152158
)
159+
digitale_adressen = DigitaalAdresForeignKeySerializer(
160+
read_only=True,
161+
help_text=_("Digitale adressen van de betrokkene bij klantcontact."),
162+
source="digitaaladres_set",
163+
many=True,
164+
)
153165
bezoekadres = BezoekadresSerializer(
154166
required=False,
155167
allow_null=True,
@@ -185,6 +197,7 @@ class Meta:
185197
"url",
186198
"was_partij",
187199
"had_klantcontact",
200+
"digitale_adressen",
188201
"bezoekadres",
189202
"correspondentieadres",
190203
"contactnaam",
@@ -271,6 +284,18 @@ class KlantcontactSerializer(serializers.HyperlinkedModelSerializer):
271284
many=True,
272285
)
273286

287+
inclusion_serializers = {
288+
# 1 level
289+
"had_betrokkenen": f"{SERIALIZER_PATH}.klantcontacten.BetrokkeneSerializer",
290+
"had_betrokken_actoren": f"{SERIALIZER_PATH}.actoren.ActorSerializer",
291+
"leidde_tot_interne_taken": f"{SERIALIZER_PATH}.internetaken.InterneTaakSerializer",
292+
"ging_over_onderwerpobjecten": f"{SERIALIZER_PATH}.klantcontacten.OnderwerpobjectSerializer",
293+
"omvatte_bijlagen": f"{SERIALIZER_PATH}.klantcontacten.BijlageSerializer",
294+
# 2 levels
295+
"had_betrokkenen.was_partij": f"{SERIALIZER_PATH}.partijen.PartijSerializer",
296+
"had_betrokkenen.digitale_adressen": f"{SERIALIZER_PATH}.digitaal_adres.DigitaalAdresSerializer",
297+
}
298+
274299
class Meta:
275300
model = Klantcontact
276301
fields = (

src/openklant/components/klantinteracties/api/serializers/partijen.py

+13
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
Discriminator,
99
PolymorphicSerializer,
1010
)
11+
from openklant.components.klantinteracties.api.serializers.constants import (
12+
SERIALIZER_PATH,
13+
)
1114
from openklant.components.klantinteracties.api.serializers.digitaal_adres import (
1215
DigitaalAdresForeignKeySerializer,
1316
)
@@ -302,6 +305,16 @@ class PartijSerializer(NestedGegevensGroepMixin, PolymorphicSerializer):
302305
),
303306
)
304307

308+
inclusion_serializers = {
309+
# 1 level
310+
"digitale_adressen": f"{SERIALIZER_PATH}.digitaal_adres.DigitaalAdresSerializer",
311+
"betrokkenen": f"{SERIALIZER_PATH}.klantcontacten.BetrokkeneSerializer",
312+
# 2 levels
313+
"betrokkenen.had_klantcontact": f"{SERIALIZER_PATH}.klantcontacten.KlantcontactSerializer",
314+
# 3 levels
315+
"betrokkenen.had_klantcontact.had_betrokken_actoren": f"{SERIALIZER_PATH}.actoren.ActorSerializer",
316+
}
317+
305318
class Meta:
306319
model = Partij
307320
fields = (
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
from rest_framework import status
2+
from vng_api_common.tests import reverse
3+
4+
from openklant.components.klantinteracties.models.tests.factories.actoren import (
5+
ActorFactory,
6+
)
7+
from openklant.components.klantinteracties.models.tests.factories.digitaal_adres import (
8+
DigitaalAdresFactory,
9+
)
10+
from openklant.components.klantinteracties.models.tests.factories.internetaken import (
11+
InterneTaakFactory,
12+
)
13+
from openklant.components.klantinteracties.models.tests.factories.klantcontacten import (
14+
BetrokkeneFactory,
15+
BijlageFactory,
16+
KlantcontactFactory,
17+
OnderwerpobjectFactory,
18+
)
19+
from openklant.components.klantinteracties.models.tests.factories.partijen import (
20+
PartijFactory,
21+
)
22+
from openklant.components.token.tests.api_testcase import APITestCase
23+
24+
25+
class ExpandTests(APITestCase):
26+
def setUp(self):
27+
super().setUp()
28+
self.actor = ActorFactory.create()
29+
self.klantcontact = KlantcontactFactory.create(actoren=[self.actor])
30+
self.internetaak = InterneTaakFactory.create(klantcontact=self.klantcontact)
31+
self.onderwerpobject = OnderwerpobjectFactory.create(
32+
klantcontact=self.klantcontact, was_klantcontact=None
33+
)
34+
self.bijlage = BijlageFactory.create(klantcontact=self.klantcontact)
35+
36+
self.partij = PartijFactory.create(voorkeurs_digitaal_adres=None)
37+
self.digitaal_adres = DigitaalAdresFactory.create(
38+
partij=self.partij, betrokkene=None
39+
)
40+
self.betrokkene = BetrokkeneFactory.create(
41+
klantcontact=self.klantcontact, partij=self.partij
42+
)
43+
44+
def test_sinle_expansion(self):
45+
list_url = reverse("klantinteracties:klantcontact-list")
46+
response = self.client.get(list_url, {"expand": "had_betrokkenen"})
47+
48+
self.assertEqual(response.status_code, status.HTTP_200_OK)
49+
50+
data = response.json()
51+
self.assertEqual(len(data["results"]), 1)
52+
klantcontact = data["results"][0]
53+
54+
self.assertEqual(
55+
klantcontact["hadBetrokkenen"][0]["uuid"], str(self.betrokkene.uuid)
56+
)
57+
self.assertTrue(klantcontact["_expand"])
58+
expand = klantcontact["_expand"]["hadBetrokkenen"]
59+
60+
self.assertEqual(
61+
expand["bezoekadres"],
62+
{
63+
"nummeraanduidingId": self.betrokkene.bezoekadres_nummeraanduiding_id,
64+
"adresregel1": self.betrokkene.bezoekadres_adresregel1,
65+
"adresregel2": self.betrokkene.bezoekadres_adresregel2,
66+
"adresregel3": self.betrokkene.bezoekadres_adresregel3,
67+
"land": self.betrokkene.bezoekadres_land,
68+
},
69+
)
70+
self.assertEqual(
71+
expand["correspondentieadres"],
72+
{
73+
"nummeraanduidingId": self.betrokkene.correspondentieadres_nummeraanduiding_id,
74+
"adresregel1": self.betrokkene.correspondentieadres_adresregel1,
75+
"adresregel2": self.betrokkene.correspondentieadres_adresregel2,
76+
"adresregel3": self.betrokkene.correspondentieadres_adresregel3,
77+
"land": self.betrokkene.correspondentieadres_land,
78+
},
79+
)
80+
self.assertEqual(
81+
expand["contactnaam"],
82+
{
83+
"voorletters": self.betrokkene.contactnaam_voorletters,
84+
"voornaam": self.betrokkene.contactnaam_voornaam,
85+
"voorvoegselAchternaam": self.betrokkene.contactnaam_voorvoegsel_achternaam,
86+
"achternaam": self.betrokkene.contactnaam_achternaam,
87+
},
88+
)
89+
self.assertEqual(expand["rol"], self.betrokkene.rol)
90+
self.assertEqual(expand["organisatienaam"], self.betrokkene.organisatienaam)
91+
self.assertEqual(expand["initiator"], self.betrokkene.initiator)
92+
self.assertEqual(expand["wasPartij"]["uuid"], str(self.partij.uuid))
93+
94+
def test_multiple_level_expansion(self):
95+
list_url = reverse("klantinteracties:klantcontact-list")
96+
response = self.client.get(
97+
list_url, {"expand": "had_betrokkenen,had_betrokkenen.was_partij"}
98+
)
99+
100+
self.assertEqual(response.status_code, status.HTTP_200_OK)
101+
102+
data = response.json()
103+
self.assertEqual(len(data["results"]), 1)
104+
klantcontact = data["results"][0]
105+
106+
self.assertEqual(
107+
klantcontact["hadBetrokkenen"][0]["uuid"], str(self.betrokkene.uuid)
108+
)
109+
self.assertTrue(klantcontact["_expand"])
110+
expand = klantcontact["_expand"]["hadBetrokkenen"]
111+
112+
self.assertEqual(
113+
expand["bezoekadres"],
114+
{
115+
"nummeraanduidingId": self.betrokkene.bezoekadres_nummeraanduiding_id,
116+
"adresregel1": self.betrokkene.bezoekadres_adresregel1,
117+
"adresregel2": self.betrokkene.bezoekadres_adresregel2,
118+
"adresregel3": self.betrokkene.bezoekadres_adresregel3,
119+
"land": self.betrokkene.bezoekadres_land,
120+
},
121+
)
122+
self.assertEqual(
123+
expand["correspondentieadres"],
124+
{
125+
"nummeraanduidingId": self.betrokkene.correspondentieadres_nummeraanduiding_id,
126+
"adresregel1": self.betrokkene.correspondentieadres_adresregel1,
127+
"adresregel2": self.betrokkene.correspondentieadres_adresregel2,
128+
"adresregel3": self.betrokkene.correspondentieadres_adresregel3,
129+
"land": self.betrokkene.correspondentieadres_land,
130+
},
131+
)
132+
self.assertEqual(
133+
expand["contactnaam"],
134+
{
135+
"voorletters": self.betrokkene.contactnaam_voorletters,
136+
"voornaam": self.betrokkene.contactnaam_voornaam,
137+
"voorvoegselAchternaam": self.betrokkene.contactnaam_voorvoegsel_achternaam,
138+
"achternaam": self.betrokkene.contactnaam_achternaam,
139+
},
140+
)
141+
self.assertEqual(expand["rol"], self.betrokkene.rol)
142+
self.assertEqual(expand["organisatienaam"], self.betrokkene.organisatienaam)
143+
self.assertEqual(expand["initiator"], self.betrokkene.initiator)
144+
self.assertEqual(expand["wasPartij"]["uuid"], str(self.partij.uuid))
145+
self.assertTrue(expand["_expand"])
146+
147+
# second expand
148+
expand = expand["_expand"]["wasPartij"]
149+
150+
self.assertEqual(expand["nummer"], self.partij.nummer)
151+
self.assertEqual(expand["interneNotitie"], self.partij.interne_notitie)
152+
self.assertEqual(
153+
expand["digitaleAdressen"][0]["uuid"], str(self.digitaal_adres.uuid)
154+
)
155+
self.assertEqual(expand["vertegenwoordigde"], [])
156+
self.assertEqual(expand["soortPartij"], self.partij.soort_partij)
157+
self.assertEqual(
158+
expand["indicatieGeheimhouding"], self.partij.indicatie_geheimhouding
159+
)
160+
self.assertEqual(expand["voorkeurstaal"], self.partij.voorkeurstaal)
161+
self.assertEqual(expand["indicatieActief"], self.partij.indicatie_actief)
162+
self.assertEqual(
163+
expand["bezoekadres"],
164+
{
165+
"nummeraanduidingId": self.partij.bezoekadres_nummeraanduiding_id,
166+
"adresregel1": self.partij.bezoekadres_adresregel1,
167+
"adresregel2": self.partij.bezoekadres_adresregel2,
168+
"adresregel3": self.partij.bezoekadres_adresregel3,
169+
"land": self.partij.bezoekadres_land,
170+
},
171+
)
172+
self.assertEqual(
173+
expand["correspondentieadres"],
174+
{
175+
"nummeraanduidingId": self.partij.correspondentieadres_nummeraanduiding_id,
176+
"adresregel1": self.partij.correspondentieadres_adresregel1,
177+
"adresregel2": self.partij.correspondentieadres_adresregel2,
178+
"adresregel3": self.partij.correspondentieadres_adresregel3,
179+
"land": self.partij.correspondentieadres_land,
180+
},
181+
)

src/openklant/components/klantinteracties/api/viewsets/__init__.py

Whitespace-only changes.

src/openklant/components/klantinteracties/api/viewsets/actoren.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ class ActorViewSet(viewsets.ModelViewSet):
4545
Verwijder een actor.
4646
"""
4747

48-
queryset = Actor.objects.order_by("-pk")
48+
queryset = Actor.objects.order_by("-pk").select_related(
49+
"geautomatiseerdeactor",
50+
"medewerker",
51+
"organisatorischeeenheid",
52+
)
4953
serializer_class = ActorSerializer
5054
lookup_field = "uuid"
5155
pagination_class = PageNumberPagination

src/openklant/components/klantinteracties/api/viewsets/digitaal_adres.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ class DigitaalAdresViewSet(viewsets.ModelViewSet):
4545
Verwijder een digitaal adres.
4646
"""
4747

48-
queryset = DigitaalAdres.objects.order_by("-pk")
48+
queryset = DigitaalAdres.objects.order_by("-pk").select_related(
49+
"partij",
50+
"betrokkene",
51+
)
4952
serializer_class = DigitaalAdresSerializer
5053
lookup_field = "uuid"
5154
pagination_class = PageNumberPagination

src/openklant/components/klantinteracties/api/viewsets/internetaken.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ class InterneTaakViewSet(viewsets.ModelViewSet):
4545
Verwijder een interne taak.
4646
"""
4747

48-
queryset = InterneTaak.objects.order_by("-pk")
48+
queryset = InterneTaak.objects.order_by("-pk").select_related(
49+
"actor",
50+
"klantcontact",
51+
)
4952
serializer_class = InterneTaakSerializer
5053
lookup_field = "uuid"
5154
pagination_class = PageNumberPagination

0 commit comments

Comments
 (0)