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

Implement zgw natural key support #1351

Merged
merged 2 commits into from
Aug 15, 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
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
Loading