Skip to content

Commit cd48545

Browse files
Merge pull request #592 from maykinmedia/feature/529-subidentificator-filter
✨ [#529] Add filtering by subIdentificatorVan in partijen en…
2 parents 774917c + 635b797 commit cd48545

6 files changed

Lines changed: 337 additions & 2 deletions

File tree

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

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,46 @@ class PartijFilterSet(FilterSet):
6060
help_text=_("Zoek partij object op basis van categorie namen."),
6161
method="filter_categorierelatie_categorie_naam",
6262
)
63+
sub_identificator_van__object_id = filters.CharFilter(
64+
help_text=_(
65+
"Zoek partij object op basis van het ``subIdentificatorVan`` object ID. "
66+
"Deze parameter kan gecombineerd worden met de ``partijIdentificator__`` "
67+
"parameters om een specifieke vestiging te vinden, door bij ``partijIdentificator__`` "
68+
"de vestigingspecifieke informatie mee te geven en bij ``subIdentificatorVan__`` "
69+
"de informatie van de rechtspersoon waaraan deze vestiging gekoppeld is."
70+
),
71+
method="filter_sub_identificator_object_id",
72+
)
73+
sub_identificator_van__code_objecttype = filters.CharFilter(
74+
help_text=_(
75+
"Zoek partij object op basis van het ``subIdentificatorVan`` objecttype. "
76+
"Deze parameter kan gecombineerd worden met de ``partijIdentificator__`` "
77+
"parameters om een specifieke vestiging te vinden, door bij ``partijIdentificator__`` "
78+
"de vestigingspecifieke informatie mee te geven en bij ``subIdentificatorVan__`` "
79+
"de informatie van de rechtspersoon waaraan deze vestiging gekoppeld is."
80+
),
81+
method="filter_sub_identificator_code_objecttype",
82+
)
83+
sub_identificator_van__code_soort_object_id = filters.CharFilter(
84+
help_text=_(
85+
"Zoek partij object op basis van het ``subIdentificatorVan`` soort object ID. "
86+
"Deze parameter kan gecombineerd worden met de ``partijIdentificator__`` "
87+
"parameters om een specifieke vestiging te vinden, door bij ``partijIdentificator__`` "
88+
"de vestigingspecifieke informatie mee te geven en bij ``subIdentificatorVan__`` "
89+
"de informatie van de rechtspersoon waaraan deze vestiging gekoppeld is."
90+
),
91+
method="filter_sub_identificator_code_soort_object_id",
92+
)
93+
sub_identificator_van__code_register = filters.CharFilter(
94+
help_text=_(
95+
"Zoek partij object op basis van het ``subIdentificatorVan`` register. "
96+
"Deze parameter kan gecombineerd worden met de ``partijIdentificator__`` "
97+
"parameters om een specifieke vestiging te vinden, door bij ``partijIdentificator__`` "
98+
"de vestigingspecifieke informatie mee te geven en bij ``subIdentificatorVan__`` "
99+
"de informatie van de rechtspersoon waaraan deze vestiging gekoppeld is."
100+
),
101+
method="filter_sub_identificator_code_register",
102+
)
63103

64104
expand = ExpandFilter(serializer_class=PartijSerializer)
65105

@@ -72,6 +112,10 @@ class Meta:
72112
"partij_identificator__code_soort_object_id",
73113
"partij_identificator__object_id",
74114
"partij_identificator__code_register",
115+
"sub_identificator_van__code_objecttype",
116+
"sub_identificator_van__code_soort_object_id",
117+
"sub_identificator_van__object_id",
118+
"sub_identificator_van__code_register",
75119
"categorierelatie__categorie__naam",
76120
"nummer",
77121
"indicatie_geheimhouding",
@@ -130,6 +174,38 @@ def filter_categorierelatie_categorie_naam(self, queryset, name, value):
130174
except ValueError:
131175
return queryset.none()
132176

177+
def filter_sub_identificator_object_id(self, queryset, name, value):
178+
try:
179+
return queryset.filter(
180+
partijidentificator__sub_identificator_van__partij_identificator_object_id=value
181+
).distinct()
182+
except ValueError:
183+
return queryset.none()
184+
185+
def filter_sub_identificator_code_objecttype(self, queryset, name, value):
186+
try:
187+
return queryset.filter(
188+
partijidentificator__sub_identificator_van__partij_identificator_code_objecttype=value
189+
).distinct()
190+
except ValueError:
191+
return queryset.none()
192+
193+
def filter_sub_identificator_code_soort_object_id(self, queryset, name, value):
194+
try:
195+
return queryset.filter(
196+
partijidentificator__sub_identificator_van__partij_identificator_code_soort_object_id=value
197+
).distinct()
198+
except ValueError:
199+
return queryset.none()
200+
201+
def filter_sub_identificator_code_register(self, queryset, name, value):
202+
try:
203+
return queryset.filter(
204+
partijidentificator__sub_identificator_van__partij_identificator_code_register=value
205+
).distinct()
206+
except ValueError:
207+
return queryset.none()
208+
133209

134210
class VertegenwoordigdenFilterSet(FilterSet):
135211
vertegenwoordigende_partij__url = URLViewFilter(

src/openklant/components/klantinteracties/api/tests/test_filters.py

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,202 @@ def test_invalid_filters(self):
13211321
self.assertEqual(error["code"], UNKNOWN_PARAMETERS_CODE)
13221322
self.assertEqual(error["reason"], ("Onbekende query parameters: invalid"))
13231323

1324+
def test_filter_by_vestigingsnummer_and_kvk_returns_correct_partij(self):
1325+
company_a, company_b = PartijFactory.create_batch(2)
1326+
1327+
kvk_a = PartijIdentificatorFactory.create(
1328+
partij=company_a,
1329+
partij_identificator_code_objecttype="niet_natuurlijk_persoon",
1330+
partij_identificator_code_soort_object_id="kvk_nummer",
1331+
partij_identificator_object_id="12345678",
1332+
)
1333+
1334+
kvk_b = PartijIdentificatorFactory.create(
1335+
partij=company_b,
1336+
partij_identificator_code_objecttype="niet_natuurlijk_persoon",
1337+
partij_identificator_code_soort_object_id="kvk_nummer",
1338+
partij_identificator_object_id="87654321",
1339+
)
1340+
1341+
vestiging_a = PartijFactory.create()
1342+
vestiging_b = PartijFactory.create()
1343+
1344+
PartijIdentificatorFactory.create(
1345+
partij=vestiging_a,
1346+
sub_identificator_van=kvk_a,
1347+
partij_identificator_code_objecttype="vestiging",
1348+
partij_identificator_code_soort_object_id="vestigingsnummer",
1349+
partij_identificator_object_id="000012345678",
1350+
)
1351+
1352+
PartijIdentificatorFactory.create(
1353+
partij=vestiging_b,
1354+
sub_identificator_van=kvk_b,
1355+
partij_identificator_code_objecttype="vestiging",
1356+
partij_identificator_code_soort_object_id="vestigingsnummer",
1357+
partij_identificator_object_id="000012345678",
1358+
)
1359+
1360+
response = self.client.get(
1361+
self.url,
1362+
{
1363+
"subIdentificatorVan__objectId": "12345678",
1364+
"partijIdentificator__objectId": "000012345678",
1365+
},
1366+
)
1367+
1368+
self.assertEqual(response.status_code, status.HTTP_200_OK)
1369+
1370+
data = response.json()["results"]
1371+
1372+
self.assertEqual(1, len(data))
1373+
self.assertEqual(str(vestiging_a.uuid), data[0]["uuid"])
1374+
1375+
def test_filter_only_by_vestigingsnummer_returns_multiple(self):
1376+
company_a, company_b = PartijFactory.create_batch(2)
1377+
1378+
kvk_a = PartijIdentificatorFactory.create(
1379+
partij=company_a,
1380+
partij_identificator_code_objecttype="niet_natuurlijk_persoon",
1381+
partij_identificator_code_soort_object_id="kvk_nummer",
1382+
partij_identificator_object_id="12345678",
1383+
)
1384+
1385+
kvk_b = PartijIdentificatorFactory.create(
1386+
partij=company_b,
1387+
partij_identificator_code_objecttype="niet_natuurlijk_persoon",
1388+
partij_identificator_code_soort_object_id="kvk_nummer",
1389+
partij_identificator_object_id="87654321",
1390+
)
1391+
1392+
vestiging_a = PartijFactory.create()
1393+
vestiging_b = PartijFactory.create()
1394+
1395+
PartijIdentificatorFactory.create(
1396+
partij=vestiging_a,
1397+
sub_identificator_van=kvk_a,
1398+
partij_identificator_code_objecttype="vestiging",
1399+
partij_identificator_code_soort_object_id="vestigingsnummer",
1400+
partij_identificator_object_id="000012345678",
1401+
)
1402+
1403+
PartijIdentificatorFactory.create(
1404+
partij=vestiging_b,
1405+
sub_identificator_van=kvk_b,
1406+
partij_identificator_code_objecttype="vestiging",
1407+
partij_identificator_code_soort_object_id="vestigingsnummer",
1408+
partij_identificator_object_id="000012345678",
1409+
)
1410+
1411+
response = self.client.get(
1412+
self.url,
1413+
{"partijIdentificator__objectId": "000012345678"},
1414+
)
1415+
1416+
self.assertEqual(response.status_code, status.HTTP_200_OK)
1417+
1418+
data = response.json()["results"]
1419+
1420+
self.assertEqual(2, len(data))
1421+
self.assertEqual(data[0]["uuid"], str(vestiging_b.uuid))
1422+
self.assertEqual(data[1]["uuid"], str(vestiging_a.uuid))
1423+
1424+
def test_filter_by_sub_identificator_code_objecttype(self):
1425+
company = PartijFactory.create()
1426+
1427+
kvk = PartijIdentificatorFactory.create(
1428+
partij=company,
1429+
partij_identificator_code_objecttype="niet_natuurlijk_persoon",
1430+
partij_identificator_code_soort_object_id="kvk_nummer",
1431+
partij_identificator_object_id="12345678",
1432+
)
1433+
1434+
vestiging = PartijFactory.create()
1435+
1436+
PartijIdentificatorFactory.create(
1437+
partij=vestiging,
1438+
sub_identificator_van=kvk,
1439+
partij_identificator_code_objecttype="vestiging",
1440+
partij_identificator_code_soort_object_id="vestigingsnummer",
1441+
partij_identificator_object_id="000012345678",
1442+
)
1443+
1444+
response = self.client.get(
1445+
self.url, {"subIdentificatorVan__codeObjecttype": "niet_natuurlijk_persoon"}
1446+
)
1447+
1448+
self.assertEqual(response.status_code, status.HTTP_200_OK)
1449+
1450+
data = response.json()["results"]
1451+
1452+
self.assertEqual(1, len(data))
1453+
self.assertEqual(str(vestiging.uuid), data[0]["uuid"])
1454+
1455+
def test_filter_by_sub_identificator_code_soort_object_id(self):
1456+
company = PartijFactory.create()
1457+
1458+
kvk = PartijIdentificatorFactory.create(
1459+
partij=company,
1460+
partij_identificator_code_objecttype="niet_natuurlijk_persoon",
1461+
partij_identificator_code_soort_object_id="kvk_nummer",
1462+
partij_identificator_object_id="12345678",
1463+
)
1464+
1465+
vestiging = PartijFactory.create()
1466+
1467+
PartijIdentificatorFactory.create(
1468+
partij=vestiging,
1469+
sub_identificator_van=kvk,
1470+
partij_identificator_code_objecttype="vestiging",
1471+
partij_identificator_code_soort_object_id="vestigingsnummer",
1472+
partij_identificator_object_id="000012345678",
1473+
)
1474+
1475+
response = self.client.get(
1476+
self.url, {"subIdentificatorVan__codeSoortObjectId": "kvk_nummer"}
1477+
)
1478+
1479+
self.assertEqual(response.status_code, status.HTTP_200_OK)
1480+
1481+
data = response.json()["results"]
1482+
1483+
self.assertEqual(1, len(data))
1484+
self.assertEqual(str(vestiging.uuid), data[0]["uuid"])
1485+
1486+
def test_filter_by_sub_identificator_code_register(self):
1487+
company = PartijFactory.create()
1488+
1489+
kvk = PartijIdentificatorFactory.create(
1490+
partij=company,
1491+
partij_identificator_code_objecttype="niet_natuurlijk_persoon",
1492+
partij_identificator_code_soort_object_id="kvk_nummer",
1493+
partij_identificator_object_id="12345678",
1494+
partij_identificator_code_register="hr",
1495+
)
1496+
1497+
vestiging = PartijFactory.create()
1498+
1499+
PartijIdentificatorFactory.create(
1500+
partij=vestiging,
1501+
sub_identificator_van=kvk,
1502+
partij_identificator_code_objecttype="vestiging",
1503+
partij_identificator_code_soort_object_id="vestigingsnummer",
1504+
partij_identificator_object_id="000012345678",
1505+
partij_identificator_code_register="hr",
1506+
)
1507+
1508+
response = self.client.get(
1509+
self.url,
1510+
{"subIdentificatorVan__codeRegister": "hr"},
1511+
)
1512+
1513+
self.assertEqual(response.status_code, status.HTTP_200_OK)
1514+
1515+
data = response.json()["results"]
1516+
1517+
self.assertEqual(1, len(data))
1518+
self.assertEqual(str(vestiging.uuid), data[0]["uuid"])
1519+
13241520

13251521
class CategorieRelatieFiltersetTests(APITestCase):
13261522
url = reverse("klantinteracties:categorierelatie-list")
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Generated by Django 5.2.12 on 2026-04-09 10:18
2+
3+
import django.db.models.deletion
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
("klantinteracties", "0042_klantcontact_reactie_alter_klantcontact_inhoud"),
11+
]
12+
13+
operations = [
14+
migrations.AlterField(
15+
model_name="partijidentificator",
16+
name="sub_identificator_van",
17+
field=models.ForeignKey(
18+
blank=True,
19+
help_text="The parent PartijIdentificator under which this PartijIdentificator is unique (e.g. the parent identificator could specify a KVK number and the child identificator could specify a vestigingsnummer that is unique for the KVK number).",
20+
null=True,
21+
on_delete=django.db.models.deletion.PROTECT,
22+
related_name="sub_partij_identificatoren",
23+
to="klantinteracties.partijidentificator",
24+
verbose_name="sub identificator van",
25+
),
26+
),
27+
]

src/openklant/components/klantinteracties/models/partijen.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ class PartijIdentificator(models.Model):
316316
),
317317
blank=True,
318318
null=True,
319-
related_name="parent_partij_identificator",
319+
related_name="sub_partij_identificatoren",
320320
)
321321
partij = models.ForeignKey(
322322
Partij,

src/openklant/components/klantinteracties/models/validators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def check_related_partij_identificatoren(self):
7777
Checking the case where the `partij_identificator` with a specific codeSoortObjectId
7878
doesn't have any other `partij_identificatoren` attached to it
7979
"""
80-
if self.instance.parent_partij_identificator.exists():
80+
if self.instance.sub_partij_identificatoren.exists():
8181
raise ValidationError(
8282
{
8383
"partij_identificator_code_soort_object_id": _(

src/openklant/components/klantinteracties/openapi.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3118,6 +3118,42 @@ paths:
31183118
description: |+
31193119
Geeft aan van welke specifieke soort partij sprake is.
31203120
3121+
- in: query
3122+
name: subIdentificatorVan__codeObjecttype
3123+
schema:
3124+
type: string
3125+
description: Zoek partij object op basis van het ``subIdentificatorVan`` objecttype.
3126+
Deze parameter kan gecombineerd worden met de ``partijIdentificator__``
3127+
parameters om een specifieke vestiging te vinden, door bij ``partijIdentificator__``
3128+
de vestigingspecifieke informatie mee te geven en bij ``subIdentificatorVan__``
3129+
de informatie van de rechtspersoon waaraan deze vestiging gekoppeld is.
3130+
- in: query
3131+
name: subIdentificatorVan__codeRegister
3132+
schema:
3133+
type: string
3134+
description: Zoek partij object op basis van het ``subIdentificatorVan`` register.
3135+
Deze parameter kan gecombineerd worden met de ``partijIdentificator__``
3136+
parameters om een specifieke vestiging te vinden, door bij ``partijIdentificator__``
3137+
de vestigingspecifieke informatie mee te geven en bij ``subIdentificatorVan__``
3138+
de informatie van de rechtspersoon waaraan deze vestiging gekoppeld is.
3139+
- in: query
3140+
name: subIdentificatorVan__codeSoortObjectId
3141+
schema:
3142+
type: string
3143+
description: Zoek partij object op basis van het ``subIdentificatorVan`` soort
3144+
object ID. Deze parameter kan gecombineerd worden met de ``partijIdentificator__``
3145+
parameters om een specifieke vestiging te vinden, door bij ``partijIdentificator__``
3146+
de vestigingspecifieke informatie mee te geven en bij ``subIdentificatorVan__``
3147+
de informatie van de rechtspersoon waaraan deze vestiging gekoppeld is.
3148+
- in: query
3149+
name: subIdentificatorVan__objectId
3150+
schema:
3151+
type: string
3152+
description: Zoek partij object op basis van het ``subIdentificatorVan`` object
3153+
ID. Deze parameter kan gecombineerd worden met de ``partijIdentificator__``
3154+
parameters om een specifieke vestiging te vinden, door bij ``partijIdentificator__``
3155+
de vestigingspecifieke informatie mee te geven en bij ``subIdentificatorVan__``
3156+
de informatie van de rechtspersoon waaraan deze vestiging gekoppeld is.
31213157
- in: query
31223158
name: vertegenwoordigdePartij__url
31233159
schema:

0 commit comments

Comments
 (0)