Skip to content

Commit

Permalink
Merge pull request #1351 from maykinmedia/implement-zgw-natural-key-s…
Browse files Browse the repository at this point in the history
…upport

Implement zgw natural key support
  • Loading branch information
alextreme authored Aug 15, 2024
2 parents da884ce + a7d6097 commit bc7fa1a
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 1 deletion.
65 changes: 65 additions & 0 deletions src/open_inwoner/openzaak/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,28 @@ def record_if_unique_notification(
return self.attempt_create(**kwargs)


class CatalogusConfigManager(models.Manager):
def get_by_natural_key(self, url):
return self.get(url=url)


class ZaakTypeInformatieObjectTypeConfigQueryset(models.QuerySet):
def get_by_natural_key(
self,
informatieobjecttype_url,
zaak_type_config_identificatie,
catalogus_url,
):
from .models import ZaakTypeConfig

return self.get(
zaaktype_config=ZaakTypeConfig.objects.get(
identificatie=zaak_type_config_identificatie,
catalogus__url=catalogus_url,
),
informatieobjecttype_url=informatieobjecttype_url,
)

def filter_catalogus(self, case_type: ZaakType):
# support both url and resolved dataclass
catalogus_url = (
Expand Down Expand Up @@ -123,6 +144,16 @@ def get_for_case_and_info_type(


class ZaakTypeConfigQueryset(models.QuerySet):
def get_by_natural_key(
self,
identificatie,
catalogus_url,
):
return self.get(
identificatie=identificatie,
catalogus__url=catalogus_url,
)

def filter_catalogus(self, case_type: ZaakType):
# support both url and resolved dataclass
catalogus_url = (
Expand Down Expand Up @@ -172,6 +203,22 @@ def filter_questions_enabled_for_case_type(self, case_type: ZaakType):


class ZaakTypeStatusTypeConfigQuerySet(models.QuerySet):
def get_by_natural_key(
self,
statustype_url,
zaak_type_config_identificatie,
catalogus_url,
):
from .models import ZaakTypeConfig

return self.get(
zaaktype_config=ZaakTypeConfig.objects.get(
identificatie=zaak_type_config_identificatie,
catalogus__url=catalogus_url,
),
statustype_url=statustype_url,
)

def find_for(self, case: Zaak, status: Status):
return self.find_for_types(case.zaaktype, status.statustype)

Expand All @@ -196,6 +243,24 @@ def find_for_types_from_str(
).first()


class ZaakTypeResultaatTypeConfigManger(models.Manager):
def get_by_natural_key(
self,
resultaattype_url,
zaak_type_config_identificatie,
catalogus_url,
):
from .models import ZaakTypeConfig

return self.get(
zaaktype_config=ZaakTypeConfig.objects.get(
identificatie=zaak_type_config_identificatie,
catalogus__url=catalogus_url,
),
resultaattype_url=resultaattype_url,
)


class StatusTranslationQuerySet(models.QuerySet):
def get_lookup(self):
return TranslationLookup(self.values_list("status", "translation"))
30 changes: 30 additions & 0 deletions src/open_inwoner/openzaak/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
from zgw_consumers.models import Service

from open_inwoner.openzaak.managers import (
CatalogusConfigManager,
UserCaseInfoObjectNotificationManager,
UserCaseStatusNotificationManager,
ZaakTypeConfigQueryset,
ZaakTypeInformatieObjectTypeConfigQueryset,
ZaakTypeResultaatTypeConfigManger,
ZaakTypeStatusTypeConfigQuerySet,
)

Expand Down Expand Up @@ -434,6 +436,9 @@ class Meta:


class CatalogusConfig(models.Model):

objects = CatalogusConfigManager()

url = models.URLField(
verbose_name=_("Catalogus URL"),
unique=True,
Expand Down Expand Up @@ -466,6 +471,9 @@ def base_url(self):
def __str__(self):
return f"{self.domein} - {self.rsin} [{self.base_url}]"

def natural_key(self) -> tuple[str]:
return (self.url,)


class ZaakTypeConfig(models.Model):
urls = ArrayField(
Expand Down Expand Up @@ -560,6 +568,11 @@ def __str__(self):
)
return " - ".join(b for b in bits if b) + f" [{self.catalogus.base_url}]"

def natural_key(self):
return (self.identificatie,) + self.catalogus.natural_key()

natural_key.dependencies = ["openzaak.catalogusconfig"]


class ZaakTypeInformatieObjectTypeConfig(models.Model):
zaaktype_config = models.ForeignKey(
Expand Down Expand Up @@ -623,6 +636,11 @@ def informatieobjecttype_uuid(self):
def __str__(self):
return f"{self.omschrijving} [{self.zaaktype_config.catalogus.base_url}]"

def natural_key(self):
return (self.informatieobjecttype_url,) + self.zaaktype_config.natural_key()

natural_key.dependencies = ["openzaak.zaaktypeconfig"]


class ZaakTypeStatusTypeConfig(models.Model):
zaaktype_config = models.ForeignKey(
Expand Down Expand Up @@ -743,8 +761,15 @@ class Meta:
def __str__(self):
return f"{self.zaaktype_config.identificatie} - {self.omschrijving} [{self.zaaktype_config.catalogus.base_url}]"

def natural_key(self):
return (self.statustype_url,) + self.zaaktype_config.natural_key()

natural_key.dependencies = ["openzaak.zaaktypeconfig"]


class ZaakTypeResultaatTypeConfig(models.Model):
objects = ZaakTypeResultaatTypeConfigManger()

zaaktype_config = models.ForeignKey(
"openzaak.ZaakTypeConfig",
on_delete=models.CASCADE,
Expand Down Expand Up @@ -787,6 +812,11 @@ class Meta:
def __str__(self):
return f"{self.zaaktype_config.identificatie} - {self.omschrijving} [{self.zaaktype_config.catalogus.base_url}]"

def natural_key(self):
return (self.resultaattype_url,) + self.zaaktype_config.natural_key()

natural_key.dependencies = ["openzaak.zaaktypeconfig"]


class UserCaseStatusNotificationBase(models.Model):
user = models.ForeignKey(
Expand Down
3 changes: 2 additions & 1 deletion src/open_inwoner/openzaak/tests/factories.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import factory
import faker
from notifications_api_common.models import Subscription
from simple_certmanager.constants import CertificateTypes
from simple_certmanager.models import Certificate
Expand Down Expand Up @@ -82,7 +83,7 @@ class Meta:


class ZaakTypeConfigFactory(factory.django.DjangoModelFactory):
urls = [factory.Faker("url")]
urls = factory.LazyFunction(lambda: [faker.Faker().url()])
catalogus = factory.SubFactory(CatalogusConfigFactory)
identificatie = factory.Faker("pystr", max_chars=50)
omschrijving = factory.Faker("pystr", max_chars=80)
Expand Down
146 changes: 146 additions & 0 deletions src/open_inwoner/openzaak/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from datetime import timedelta
from uuid import uuid4

from django.db import IntegrityError
from django.test import TestCase

from freezegun import freeze_time
Expand All @@ -10,20 +11,73 @@
from open_inwoner.accounts.tests.factories import UserFactory
from open_inwoner.openzaak.api_models import ZaakType
from open_inwoner.openzaak.models import (
CatalogusConfig,
ZaakTypeConfig,
ZaakTypeInformatieObjectTypeConfig,
ZaakTypeResultaatTypeConfig,
ZaakTypeStatusTypeConfig,
)
from open_inwoner.openzaak.tests.factories import (
CatalogusConfigFactory,
UserCaseInfoObjectNotificationFactory,
UserCaseStatusNotificationFactory,
ZaakTypeConfigFactory,
ZaakTypeInformatieObjectTypeConfigFactory,
ZaakTypeResultaatTypeConfigFactory,
ZaakTypeStatusTypeConfigFactory,
)
from open_inwoner.openzaak.tests.shared import CATALOGI_ROOT


class CatalogusConfigManagerTestCase(TestCase):
def test_fields_used_for_natural_key_are_unique(self):

with self.assertRaises(IntegrityError):
for _ in range(2):
CatalogusConfigFactory(url="http://foo.maykinmedia.nl")

def test_get_by_natural_key_returns_expected_instance(self):
config = CatalogusConfigFactory()

self.assertEqual(
CatalogusConfig.objects.get_by_natural_key(*config.natural_key()),
config,
)

def test_get_by_natural_key_not_found(self):
with self.assertRaises(CatalogusConfig.DoesNotExist):
CatalogusConfig.objects.get_by_natural_key(
"http://non-existent.maykinmedia.nl"
)


class ZaakTypeConfigModelTestCase(TestCase):
def test_fields_used_for_natural_key_are_unique(self):
catalogus = CatalogusConfigFactory()

with self.assertRaises(IntegrityError):
for _ in range(2):
ZaakTypeConfigFactory(
identificatie="AAAA", catalogus__url=catalogus.url
)

def test_get_by_natural_key_returns_expected_instance(self):
zaak_type_config = ZaakTypeConfigFactory(
identificatie="AAAA",
)

self.assertEqual(
ZaakTypeConfig.objects.get_by_natural_key(*zaak_type_config.natural_key()),
zaak_type_config,
)

def test_get_by_natural_key_not_found(self):
unused_catalogus = CatalogusConfig()
with self.assertRaises(ZaakTypeConfig.DoesNotExist):
ZaakTypeConfig.objects.get_by_natural_key(
identificatie="FOO", catalogus_url=unused_catalogus.url
)

def test_queryset_filter_case_type_with_catalog(self):
catalog = CatalogusConfigFactory(
url=f"{CATALOGI_ROOT}catalogussen/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
Expand All @@ -48,7 +102,99 @@ def test_queryset_filter_case_type_with_catalog(self):
self.assertEqual(actual, [zaak_type_config])


class ZaakTypeStatusTypeConfigModelTestCase(TestCase):
def test_fields_used_for_natural_key_are_unique(self):
zt = ZaakTypeConfigFactory()
with self.assertRaises(IntegrityError):
for _ in range(2):
ZaakTypeStatusTypeConfigFactory(
zaaktype_config=zt,
statustype_url="http://foo.maykinmedia.nl",
)

def test_get_by_natural_key_returns_expected_instance(self):
zt = ZaakTypeConfigFactory()
zt_status_type_config = ZaakTypeStatusTypeConfigFactory(
zaaktype_config=zt,
statustype_url="http://foo.maykinmedia.nl",
)

self.assertEqual(
ZaakTypeStatusTypeConfig.objects.get_by_natural_key(
"http://foo.maykinmedia.nl", *zt.natural_key()
),
zt_status_type_config,
)

def test_get_by_natural_key_not_found(self):
unused_zt = ZaakTypeConfigFactory()
with self.assertRaises(ZaakTypeStatusTypeConfig.DoesNotExist):
ZaakTypeStatusTypeConfig.objects.get_by_natural_key(
"http://foo.maykinmedia.nl",
*unused_zt.natural_key(),
)


class ZaakTypeResultaatTypeConfigModelTestCase(TestCase):
def test_fields_used_for_natural_key_are_unique(self):
zt = ZaakTypeConfigFactory()
with self.assertRaises(IntegrityError):
for _ in range(2):
ZaakTypeResultaatTypeConfigFactory(
zaaktype_config=zt, resultaattype_url="http://foo.maykinmedia.nl"
)

def test_get_by_natural_key_returns_expected_instance(self):
zt = ZaakTypeConfigFactory()
zt_status_type_config = ZaakTypeResultaatTypeConfigFactory(
zaaktype_config=zt, resultaattype_url="http://foo.maykinmedia.nl"
)

self.assertEqual(
ZaakTypeResultaatTypeConfig.objects.get_by_natural_key(
"http://foo.maykinmedia.nl", *zt.natural_key()
),
zt_status_type_config,
)

def test_get_by_natural_key_not_found(self):
unused_zt = ZaakTypeConfigFactory()
with self.assertRaises(ZaakTypeResultaatTypeConfig.DoesNotExist):
ZaakTypeResultaatTypeConfig.objects.get_by_natural_key(
"http://foo.maykinmedia.nl", *unused_zt.natural_key()
)


class ZaakTypeInformatieObjectTypeConfigFactoryModelTestCase(TestCase):
def test_fields_used_for_natural_key_are_unique(self):
zt = ZaakTypeConfigFactory()
with self.assertRaises(IntegrityError):
for _ in range(2):
ZaakTypeInformatieObjectTypeConfigFactory(
zaaktype_config=zt,
informatieobjecttype_url="http://foo.maykinmedia.nl",
)

def test_get_by_natural_key_returns_expected_instance(self):
zt = ZaakTypeConfigFactory()
zt_io_type = ZaakTypeInformatieObjectTypeConfigFactory(
zaaktype_config=zt, informatieobjecttype_url="http://foo.maykinmedia.nl"
)

self.assertEqual(
ZaakTypeInformatieObjectTypeConfig.objects.get_by_natural_key(
"http://foo.maykinmedia.nl", *zt.natural_key()
),
zt_io_type,
)

def test_get_by_natural_key_not_found(self):
unused_zt = ZaakTypeConfigFactory()
with self.assertRaises(ZaakTypeInformatieObjectTypeConfig.DoesNotExist):
ZaakTypeInformatieObjectTypeConfig.objects.get_by_natural_key(
"http://foo.maykinmedia.nl", *unused_zt.natural_key()
)

def test_queryset_filter_case_type_with_catalog(self):
catalog = CatalogusConfigFactory(
url=f"{CATALOGI_ROOT}catalogussen/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
Expand Down

0 comments on commit bc7fa1a

Please sign in to comment.