Skip to content
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
24 changes: 24 additions & 0 deletions docs/manual/registration/objects-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,27 @@ Op basis van sjablonen

Zie de rubriek in de :ref:`sjabloondocumentatie <objecten_api_registratie>`.

Gedeelde functionaliteit
========================

Bijlagen uploaden
-----------------

Bestanden die toegevoegd zijn door de gebruiker in "Bestandsupload"-velden worden
geüpload naar de Documenten API (mits :ref:`ingesteld <configuration_registration_objects>`).
De resulterende resource-URLs zijn vervolgens beschikbaar om op te nemen in het Object
wat aangemaakt wordt.

In de plugin-instellingen kan je een catalogus selecteren en vervolgens kies je het
standaard-documenttype wat voor dergelijke bijlagen gebruikt dient te worden. Per
"Bestandsupload"-veld kan je hiervan afwijken, indien nodig, via de "Registratie"-tab,
waar je de catalogus-identificatie en omschrijving van het documenttype kan opgeven.
Omdat dit omslachtig kan zijn als je veel uploadvelden hebt, kan je ook de
plugin-instellingen in bulk kopiëren naar (een deel van) de uploadvelden. Dit vind je
in de plugin-instellingen onder het kopje "Documenttypen".

.. versionadded:: 3.5.2

Sinds Open Formulieren 3.5.2 kan je de bijlage-uploads instellen met een
catalogusreferentie en documenttypeomschrijving in plaats van een URL naar een
informatieobjecttype.
29 changes: 29 additions & 0 deletions docs/manual/registration/zgw-apis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,32 @@ op.

.. note:: Indien je onvoldoende rechten hebt, vraag dan een functioneel beheerder om
deze instelling aan te passen.

Documenten
==========

Aan de zaak worden standaard een aantal documenten toegevoegd als zaakdocumenten:

* De bevestigings-PDF met de inzendingsgegevens.
* De bevestigingsmail die verstuurd is naar de inzender.
* Alle bestanden die door de gebruiker toegevoegd zijn in "Bestandsupload"-velden.

Gebruikersbijlagen
------------------

Bestanden die toegevoegd zijn door de gebruiker in "Bestandsupload"-velden worden
geüpload naar de Documenten API en aan de zaak gerelateerd.

In de plugin-instellingen kan je een catalogus selecteren en vervolgens kies je het
standaard-documenttype wat voor dergelijke bijlagen gebruikt dient te worden. Per
"Bestandsupload"-veld kan je hiervan afwijken, indien nodig, via de "Registratie"-tab,
waar je de catalogus-identificatie en omschrijving van het documenttype kan opgeven.
Omdat dit omslachtig kan zijn als je veel uploadvelden hebt, kan je ook de
plugin-instellingen in bulk kopiëren naar (een deel van) de uploadvelden. Dit vind je
in de plugin-instellingen onder het kopje "Bijlage-documenttypen".

.. versionadded:: 3.5.2

Sinds Open Formulieren 3.5.2 kan je de bijlage-uploads instellen met een
catalogusreferentie en documenttypeomschrijving in plaats van een URL naar een
informatieobjecttype.
30 changes: 15 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@formatjs/cli": "^6.6.1",
"@fortawesome/fontawesome-free": "^6.1.1",
"@open-formulieren/design-tokens": "^0.66.0",
"@open-formulieren/formio-builder": "^0.50.2",
"@open-formulieren/formio-builder": "^0.51.0",
"@open-formulieren/leaflet-tools": "^1.0.0",
"@open-formulieren/monaco-json-editor": "^0.2.0",
"@tinymce/tinymce-react": "^4.3.2",
Expand Down
81 changes: 81 additions & 0 deletions src/openforms/contrib/zgw/resolvers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from collections.abc import MutableMapping
from datetime import date
from typing import TypedDict

from .clients import CatalogiClient
from .clients.catalogi import Catalogus, InformatieObjectType


class CatalogueParams(TypedDict):
domain: str
rsin: str


# domain, RSIN
type CatalogueIdentifiers = tuple[str, str]

# catalogue url, description, valid on
type DocumentTypeIdentifiers = tuple[str, str, date]


class DocumentTypeResolver:
"""
Resolver helper that caches lookups to prevent identical network requests.

Resolver instances are intended to be short-lived (e.g. the duration of an HTTP
request-response cycle or celery task), so that the garbage collector cleans up the
internal in-memory cache.
"""

def __init__(self, client: CatalogiClient):
self.client = client
self._catalogue_cache: MutableMapping[
CatalogueIdentifiers, Catalogus | None
] = {}
self._document_type_cache: MutableMapping[
DocumentTypeIdentifiers, InformatieObjectType | None
] = {}

def resolve(
self,
*,
catalogue: CatalogueParams,
description: str,
on_date: date,
within_casetype: str = "",
) -> InformatieObjectType:
"""
Resolve a document type versio within a catalogue at a particular date.
"""
catalogus = self._resolve_catalogue(catalogue)
if catalogus is None:
raise RuntimeError(f"Could not resolve catalogue {catalogue}")

cache_key: DocumentTypeIdentifiers = (catalogus["url"], description, on_date)
if cache_key not in self._document_type_cache:
versions = self.client.find_informatieobjecttypen(
catalogus=catalogus["url"],
description=description,
valid_on=on_date,
within_casetype=within_casetype,
)
self._document_type_cache[cache_key] = (
None if versions is None else versions[0]
)

version = self._document_type_cache[cache_key]
if version is None:
raise RuntimeError(
"Could not find a document type with description "
f"'{description}' in the case type that is valid on "
f"{on_date.isoformat()}."
)
return version

# TODO: when expanding this to the zaaktypen, this can be extracted into a separate
# resolver class
def _resolve_catalogue(self, catalogue: CatalogueParams) -> Catalogus | None:
cache_key: CatalogueIdentifiers = (catalogue["domain"], catalogue["rsin"])
if cache_key not in self._catalogue_cache:
self._catalogue_cache[cache_key] = self.client.find_catalogus(**catalogue)
return self._catalogue_cache[cache_key]
9 changes: 9 additions & 0 deletions src/openforms/contrib/zgw/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@
from openforms.submissions.models import SubmissionFileAttachment, SubmissionReport

from .clients.documenten import DocumentenClient
from .resolvers import DocumentTypeResolver

__all__ = [
"DocumentOptions",
"DocumentTypeResolver",
"create_report_document",
"create_csv_document",
"create_attachment_document",
]

type SupportedLanguage = Literal["nl", "en"]

Expand Down
16 changes: 16 additions & 0 deletions src/openforms/formio/typing/vanilla.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from typing import Literal, NotRequired, TypedDict

from openforms.registrations.contrib.zgw_apis.typing import CatalogueOption

from .base import Component, OptionDict
from .dates import DatePickerConfig

Expand All @@ -13,13 +15,27 @@ class FileConfig(TypedDict):
type: NotRequired[list[str]]


class FileComponentRegistrationDocType(TypedDict):
catalogue: CatalogueOption
description: str


class FileComponentRegistration(TypedDict):
bronorganisatie: NotRequired[str]
docVertrouwelijkheidaanduiding: NotRequired[str]
titel: NotRequired[str]
documentType: NotRequired[FileComponentRegistrationDocType]
informatieobjecttype: NotRequired[str] # DeprecationWarning #4939


class FileComponent(Component):
storage: Literal["url"]
url: str
useConfigFiletypes: bool
filePattern: str
file: FileConfig
maxNumberOfFiles: NotRequired[int]
registration: NotRequired[FileComponentRegistration]


class FileData(TypedDict):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from asgiref.sync import sync_to_async
from furl import furl
from typing_extensions import deprecated

from openforms.contrib.objects_api.tests.factories import ObjectsAPIGroupConfigFactory
from openforms.registrations.contrib.zgw_apis.tests.factories import (
Expand All @@ -19,6 +20,9 @@
from .helpers import close_modal, open_component_options_modal, phase


@deprecated(
"Dropdown document type selection in file registration tab is being phased out."
)
class FormDesignerRegistrationBackendConfigTests(OFVCRMixin, E2ETestCase):
async def test_configuring_zgw_api_group(self):
"""
Expand Down Expand Up @@ -118,6 +122,7 @@ def collect_requests(request):

await open_component_options_modal(page, label="File upload test")
await modal.get_by_role("tab", name="Registration").click()
await modal.get_by_role("button", name="Legacy").click()
await close_modal(page, "Save")

with phase("Update the ZGW API group configured"):
Expand All @@ -136,6 +141,7 @@ def collect_requests(request):

await open_component_options_modal(page, label="File upload test")
await modal.get_by_role("tab", name="Registration").click()
await modal.get_by_role("button", name="Legacy").click()
await close_modal(page, "Save")

self.assertEqual(len(requests_to_endpoint), 2)
Expand Down Expand Up @@ -248,6 +254,7 @@ def collect_requests(request):

await open_component_options_modal(page, label="File upload test")
await modal.get_by_role("tab", name="Registration").click()
await modal.get_by_role("button", name="Legacy").click()
await close_modal(page, "Save")

with phase("Update the Objects API group configured"):
Expand All @@ -269,6 +276,7 @@ def collect_requests(request):

await open_component_options_modal(page, label="File upload test")
await modal.get_by_role("tab", name="Registration").click()
await modal.get_by_role("button", name="Legacy").click()
await close_modal(page, "Save")

self.assertEqual(len(requests_to_endpoint), 2)
Expand Down
Loading
Loading