Skip to content

Commit

Permalink
[#2564] Mark catalogus as a required field on ZaakTypeconfig
Browse files Browse the repository at this point in the history
This field was only optional because eSuite did not (always)
include a catalogus on its zaak types. That has since been
fixed. This commit removes some legacy behavior which assumes
that catalogus is nullable.
  • Loading branch information
swrichards committed Jun 20, 2024
1 parent cf03b3d commit ef78f3c
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 159 deletions.
58 changes: 20 additions & 38 deletions src/open_inwoner/openzaak/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,15 @@ def record_if_unique_notification(

class ZaakTypeInformatieObjectTypeConfigQueryset(models.QuerySet):
def filter_catalogus(self, case_type: ZaakType):
if case_type.catalogus:
# support both url and resolved dataclass
catalogus_url = (
case_type.catalogus
if isinstance(case_type.catalogus, str)
else case_type.catalogus.url
)
return self.filter(
zaaktype_config__catalogus__url=catalogus_url,
)
else:
return self.filter(
zaaktype_config__catalogus__isnull=True,
)
# support both url and resolved dataclass
catalogus_url = (
case_type.catalogus
if isinstance(case_type.catalogus, str)
else case_type.catalogus.url
)
return self.filter(
zaaktype_config__catalogus__url=catalogus_url,
)

def filter_case_type(self, case_type: ZaakType):
return self.filter_catalogus(case_type).filter(
Expand Down Expand Up @@ -129,37 +124,24 @@ def get_for_case_and_info_type(

class ZaakTypeConfigQueryset(models.QuerySet):
def filter_catalogus(self, case_type: ZaakType):
if case_type.catalogus:
# support both url and resolved dataclass
catalogus_url = (
case_type.catalogus
if isinstance(case_type.catalogus, str)
else case_type.catalogus.url
)
return self.filter(
catalogus__url=catalogus_url,
)
else:
return self.filter(
catalogus__isnull=True,
)
# support both url and resolved dataclass
catalogus_url = (
case_type.catalogus
if isinstance(case_type.catalogus, str)
else case_type.catalogus.url
)
return self.filter(
catalogus__url=catalogus_url,
)

def filter_case_type(self, case_type: ZaakType):
return self.filter_catalogus(case_type).filter(
identificatie=case_type.identificatie,
)

def filter_from_str(self, catalogus_url: str, case_type_identificatie: str):
qs = self
if catalogus_url:
qs = qs.filter(
catalogus__url=catalogus_url,
)
else:
qs = qs.filter(
catalogus__isnull=True,
)
return qs.filter(
return self.filter(
catalogus__url=catalogus_url,
identificatie=case_type_identificatie,
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Generated by Django 4.2.11 on 2024-06-18 12:04

from django.db import DataError, migrations, models
import django.db.models.deletion


def validate_no_missing_catalogus_fields(apps, schema_editor):
ZaakTypeConfig = apps.get_model("openzaak", "ZaakTypeConfig")

if rows_with_missing_catalogus := ZaakTypeConfig.objects.filter(
catalogus__isnull=True
).count():
raise DataError(
f"Your database contains {rows_with_missing_catalogus} ZaakTypeConfig"
" row(s) with a missing `catalogus` field. This field is now required:"
" please manually update all the affected rows or re-sync your ZGW"
" objects to ensure the field is included."
)


class Migration(migrations.Migration):

dependencies = [
("openzaak", "0051_drop_root_zgw_fields"),
]

operations = [
migrations.RunPython(
validate_no_missing_catalogus_fields,
reverse_code=lambda *args, **kwargs: None,
),
migrations.AlterField(
model_name="zaaktypeconfig",
name="catalogus",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="openzaak.catalogusconfig",
),
),
migrations.RemoveConstraint(
model_name="zaaktypeconfig",
name="unique_identificatie_in_catalogus",
),
migrations.RemoveConstraint(
model_name="zaaktypeconfig",
name="unique_identificatie_without_catalogus",
),
migrations.AddConstraint(
model_name="zaaktypeconfig",
constraint=models.UniqueConstraint(
fields=("catalogus", "identificatie"),
name="unique_identificatie_in_catalogus",
),
),
]
9 changes: 1 addition & 8 deletions src/open_inwoner/openzaak/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from datetime import timedelta

from django.db import models, transaction
from django.db.models import Q, UniqueConstraint
from django.db.models import UniqueConstraint
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

Expand Down Expand Up @@ -311,7 +311,6 @@ class ZaakTypeConfig(models.Model):
catalogus = models.ForeignKey(
"openzaak.CatalogusConfig",
on_delete=models.CASCADE,
null=True,
)

identificatie = models.CharField(
Expand Down Expand Up @@ -381,12 +380,6 @@ class Meta:
UniqueConstraint(
name="unique_identificatie_in_catalogus",
fields=["catalogus", "identificatie"],
condition=Q(catalogus__isnull=False),
),
UniqueConstraint(
name="unique_identificatie_without_catalogus",
fields=["identificatie"],
condition=Q(catalogus__isnull=True),
),
]

Expand Down
30 changes: 29 additions & 1 deletion src/open_inwoner/openzaak/tests/test_migrations.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
from django.db import DataError, connection
from django.db.migrations.executor import MigrationExecutor
from django.test import TestCase

from zgw_consumers.constants import APITypes

from open_inwoner.openzaak.tests.factories import ServiceFactory
from open_inwoner.utils.tests.test_migrations import TestSuccessfulMigrations
from open_inwoner.utils.tests.test_migrations import (
TestFailingMigrations,
TestSuccessfulMigrations,
)


class TestMultiZGWBackendMigrations(TestSuccessfulMigrations):
Expand Down Expand Up @@ -66,3 +73,24 @@ def test_migration_0048_to_0051_multi_zgw_backend(self):
expected,
msg="Service config should have been moved to a new ZGWApiGroupConfig",
)


class TestMakeZaakTypeConfigCatalogusRequired(TestFailingMigrations):
migrate_from = "0051_drop_root_zgw_fields"
migrate_to = "0052_zaaktypeconfig_catalogus_is_required"
app = "openzaak"

def setUpBeforeMigration(self, apps):
ZaakTypeConfig = apps.get_model("openzaak", "ZaakTypeConfig")
ZaakTypeConfig.objects.create(urls=[], catalogus=None, identificatie="foobar")

def test_migration_0051_to_0052_raises_with_descriptive_exception_message(self):
with self.assertRaises(DataError) as cm:
self.attempt_migration()

self.assertEqual(
str(cm.exception),
"Your database contains 1 ZaakTypeConfig row(s) with a missing `catalogus` field."
" This field is now required: please manually update all the affected rows or re-sync"
" your ZGW objects to ensure the field is included.",
)
63 changes: 0 additions & 63 deletions src/open_inwoner/openzaak/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,6 @@ def test_queryset_filter_case_type_with_catalog(self):
actual = list(ZaakTypeConfig.objects.filter_case_type(case_type))
self.assertEqual(actual, [zaak_type_config])

def test_queryset_filter_case_type_without_catalog(self):
zaak_type_config = ZaakTypeConfigFactory(
catalogus=None,
identificatie="AAAA",
)
case_type = factory(
ZaakType,
generate_oas_component(
"ztc",
"schemas/ZaakType",
uuid="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
url=f"{CATALOGI_ROOT}zaaktype/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
catalogus=None,
identificatie="AAAA",
),
)

actual = list(ZaakTypeConfig.objects.filter_case_type(case_type))
self.assertEqual(actual, [zaak_type_config])


class ZaakTypeInformatieObjectTypeConfigFactoryModelTestCase(TestCase):
def test_queryset_filter_case_type_with_catalog(self):
Expand Down Expand Up @@ -115,49 +95,6 @@ def test_queryset_filter_case_type_with_catalog(self):
)
self.assertEqual(actual, [a1])

def test_queryset_filter_case_type_without_catalog(self):
zaak_type_config = ZaakTypeConfigFactory(
catalogus=None,
identificatie="AAAA",
)
a1 = ZaakTypeInformatieObjectTypeConfigFactory(
zaaktype_config=zaak_type_config,
informatieobjecttype_url="https://example.com/v1/infoobject/a1",
zaaktype_uuids=["aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"],
)
a2 = ZaakTypeInformatieObjectTypeConfigFactory(
zaaktype_config=zaak_type_config,
informatieobjecttype_url="https://example.com/v1/infoobject/a2",
zaaktype_uuids=[],
)
b = ZaakTypeInformatieObjectTypeConfigFactory(
zaaktype_config=zaak_type_config,
informatieobjecttype_url="https://example.com/v1/infoobject/bbb",
zaaktype_uuids=["aaaaaaaa-aaaa-bbbb-aaaa-aaaaaaaaaaaa"],
)
c = ZaakTypeInformatieObjectTypeConfigFactory(
zaaktype_config__catalogus=None,
zaaktype_config__identificatie="CCC",
informatieobjecttype_url="https://example.com/v1/infoobject/bbb",
zaaktype_uuids=["aaaaaaaa-aaaa-bbbb-aaaa-aaaaaaaaaaaa"],
)
case_type = factory(
ZaakType,
generate_oas_component(
"ztc",
"schemas/ZaakType",
uuid="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
url=f"{CATALOGI_ROOT}zaaktype/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
catalogus=None,
identificatie="AAAA",
),
)

actual = list(
ZaakTypeInformatieObjectTypeConfig.objects.filter_case_type(case_type)
)
self.assertEqual(actual, [a1])


class UserCaseStatusNotificationTests(TestCase):
def test_status_has_received_similar_notes_within(self):
Expand Down
Loading

0 comments on commit ef78f3c

Please sign in to comment.