Skip to content

Commit

Permalink
[#2903] Support export of only select ZaakType configs
Browse files Browse the repository at this point in the history
  • Loading branch information
pi-sigma committed Dec 3, 2024
1 parent 0d82080 commit c4d1d34
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 27 deletions.
17 changes: 15 additions & 2 deletions src/open_inwoner/openzaak/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
from django.utils.html import format_html, format_html_join
from django.utils.translation import gettext_lazy as _, ngettext

from import_export.admin import ImportExportMixin
from privates.storages import PrivateMediaFileSystemStorage
from solo.admin import SingletonModelAdmin

from open_inwoner.ckeditor5.widgets import CKEditorWidget
from open_inwoner.openzaak.import_export import (
CatalogusConfigExport,
CatalogusConfigImport,
ZaakTypeConfigExport,
)
from open_inwoner.utils.forms import LimitedUploadFileField

Expand Down Expand Up @@ -374,7 +374,7 @@ def has_delete_permission(self, request, obj=None):


@admin.register(ZaakTypeConfig)
class ZaakTypeConfigAdmin(ImportExportMixin, admin.ModelAdmin):
class ZaakTypeConfigAdmin(admin.ModelAdmin):
inlines = [
ZaakTypeInformatieObjectTypeConfigInline,
ZaakTypeStatusTypeConfigInline,
Expand All @@ -383,6 +383,7 @@ class ZaakTypeConfigAdmin(ImportExportMixin, admin.ModelAdmin):
actions = [
"mark_as_notify_status_changes",
"mark_as_not_notify_status_changes",
"export_zaaktype_configs",
]
fields = [
"urls",
Expand Down Expand Up @@ -437,6 +438,18 @@ class ZaakTypeConfigAdmin(ImportExportMixin, admin.ModelAdmin):
]
ordering = ("identificatie", "catalogus__domein")

@admin.action(description=_("Export to file"))
def export_zaaktype_configs(modeladmin, request, queryset):
export = ZaakTypeConfigExport.from_zaaktype_configs(queryset)
response = StreamingHttpResponse(
export.as_jsonl_iter(),
content_type="application/json",
)
response[
"Content-Disposition"
] = 'attachment; filename="zgw-zaaktype-export.json"'
return response

def has_add_permission(self, request):
return False

Expand Down
84 changes: 59 additions & 25 deletions src/open_inwoner/openzaak/import_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,65 @@ def _update_nested_zgw_config(


@dataclasses.dataclass(frozen=True)
class CatalogusConfigExport:
class ZGWConfigExport:
def as_dicts_iter(self) -> Generator[dict, Any, None]:
for qs in self:
serialized_data = serializers.serialize(
queryset=qs,
format="json",
use_natural_foreign_keys=True,
use_natural_primary_keys=True,
)
json_data: list[dict] = json.loads(
serialized_data,
)
yield from json_data

def as_jsonl_iter(self) -> Generator[str, Any, None]:
for row in self.as_dicts():
yield json.dumps(row)
yield "\n"

def as_dicts(self) -> list[dict]:
return list(self.as_dicts_iter())

def as_jsonl(self) -> str:
return "".join(self.as_jsonl_iter())


@dataclasses.dataclass(frozen=True)
class ZaakTypeConfigExport(ZGWConfigExport):
"""Gather and export ZaakTypeConfig(s)."""

zaaktype_configs: QuerySet

def __iter__(self) -> Generator[QuerySet, Any, None]:
yield from (self.zaaktype_configs,)

def __eq__(self, other: QuerySet) -> bool:
for a, b in zip(self, other):
if a.difference(b).exists():
return False

return True

@classmethod
def from_zaaktype_configs(cls, zaaktype_configs: QuerySet) -> Self:
if not isinstance(zaaktype_configs, QuerySet):
raise TypeError(
f"`zaaktype_configs` is not a QuerySet, but a {type(zaaktype_configs)}"
)

if zaaktype_configs.model != ZaakTypeConfig:
raise ValueError(
f"`zaaktype_configs` is of type {zaaktype_configs.model}, not ZaakTypeConfig"
)

return cls(zaaktype_configs=zaaktype_configs)


@dataclasses.dataclass(frozen=True)
class CatalogusConfigExport(ZGWConfigExport):
"""Gather and export CatalogusConfig(s) and all associated relations."""

catalogus_configs: QuerySet
Expand Down Expand Up @@ -210,30 +268,6 @@ def from_catalogus_configs(cls, catalogus_configs: QuerySet) -> Self:
zaak_resultaat_type_configs=zaak_resultaat_type_configs,
)

def as_dicts_iter(self) -> Generator[dict, Any, None]:
for qs in self:
serialized_data = serializers.serialize(
queryset=qs,
format="json",
use_natural_foreign_keys=True,
use_natural_primary_keys=True,
)
json_data: list[dict] = json.loads(
serialized_data,
)
yield from json_data

def as_jsonl_iter(self) -> Generator[str, Any, None]:
for row in self.as_dicts():
yield json.dumps(row)
yield "\n"

def as_dicts(self) -> list[dict]:
return list(self.as_dicts_iter())

def as_jsonl(self) -> str:
return "".join(self.as_jsonl_iter())


@dataclasses.dataclass(frozen=True)
class CatalogusConfigImport:
Expand Down
32 changes: 32 additions & 0 deletions src/open_inwoner/openzaak/tests/test_import_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from open_inwoner.openzaak.import_export import (
CatalogusConfigExport,
CatalogusConfigImport,
ZaakTypeConfigExport,
)
from open_inwoner.openzaak.models import (
CatalogusConfig,
Expand Down Expand Up @@ -148,6 +149,37 @@ def test_only_models_related_to_exported_catalogus_config_are_included(self):
)


class ZaakTypeConfigExportTest(TestCase):
def setUp(self):
self.mocks = ZGWExportImportMockData(0)

def test_export_zaaktype_configs(self):
export = ZaakTypeConfigExport.from_zaaktype_configs(
ZaakTypeConfig.objects.filter(pk=self.mocks.ztc.pk)
)
rows = export.as_dicts()

expected = [
{
"model": "openzaak.zaaktypeconfig",
"fields": {
"urls": '["https://foo.0.maykinmedia.nl"]',
"catalogus": ["DM-0", "123456789"],
"identificatie": "ztc-id-a-0",
"omschrijving": "zaaktypeconfig",
"notify_status_changes": False,
"description": "",
"external_document_upload_url": "",
"document_upload_enabled": False,
"contact_form_enabled": False,
"contact_subject_code": "",
"relevante_zaakperiode": None,
},
}
]
self.assertEqual(rows, expected)


class TestCatalogusExport(TestCase):
def setUp(self):
self.mocks = [
Expand Down

0 comments on commit c4d1d34

Please sign in to comment.