Skip to content

Commit

Permalink
✨ [#5016] Add endpoint for referentielijst tabellen
Browse files Browse the repository at this point in the history
this endpoint is used by the formio builder to populate the select widget with tabellen to populate select/selectboxes/radio component options from
  • Loading branch information
stevenbal committed Feb 3, 2025
1 parent 22e4792 commit 40da627
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 1 deletion.
62 changes: 62 additions & 0 deletions src/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3715,6 +3715,44 @@ paths:
$ref: '#/components/headers/X-Is-Form-Designer'
Content-Language:
$ref: '#/components/headers/Content-Language'
/api/v2/referentielijst-tabellen/{service_slug}:
get:
operationId: referentielijst_tabellen_list
description: |-
Return a list of available (JSON) tabellen in a given Referentielijsten service configured in the backend.
Note that this endpoint is **EXPERIMENTAL**.
summary: List tabellen for a Referentielijsten service
parameters:
- in: path
name: service_slug
schema:
type: string
pattern: ^[-a-zA-Z0-9_]+$
required: true
tags:
- referentielijst-tabellen
security:
- cookieAuth: []
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/ReferentielijstTabellen'
description: ''
headers:
X-Session-Expires-In:
$ref: '#/components/headers/X-Session-Expires-In'
X-CSRFToken:
$ref: '#/components/headers/X-CSRFToken'
X-Is-Form-Designer:
$ref: '#/components/headers/X-Is-Form-Designer'
Content-Language:
$ref: '#/components/headers/Content-Language'
x-experimental: true
/api/v2/registration/attributes:
get:
operationId: registration_attributes_list
Expand Down Expand Up @@ -9657,6 +9695,30 @@ components:
required:
- name
- slug
ReferentielijstTabellen:
type: object
properties:
code:
type: string
description: The unique code that identifies the table.
naam:
type: string
description: The name of the table.
einddatumGeldigheid:
type: string
format: date-time
writeOnly: true
description: The timestamp on which the tabel expires.
isGeldig:
type: boolean
readOnly: true
description: Indicates whether or not the table is expired.
required:
- code
- einddatumGeldigheid
- isGeldig
- naam
x-experimental: true
RegistrationAttribute:
type: object
properties:
Expand Down
10 changes: 10 additions & 0 deletions src/openforms/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from rest_framework_nested.routers import NestedSimpleRouter

from openforms.config.api.viewsets import ThemeViewSet
from openforms.contrib.referentielijsten.api.viewsets import (
ReferentielijstenTabellenViewSet,
)
from openforms.forms.api.public_api.viewsets import CategoryViewSet
from openforms.forms.api.viewsets import (
FormDefinitionViewSet,
Expand Down Expand Up @@ -60,6 +63,13 @@
# services
router.register("services", ServiceViewSet)

# referentielijsten
router.register(
"referentielijst-tabellen",
ReferentielijstenTabellenViewSet,
basename="referentielijst-tabellen",
)

# service fetch configurations
router.register("service-fetch-configurations", ServiceFetchConfigurationViewSet)

Expand Down
Empty file.
29 changes: 29 additions & 0 deletions src/openforms/contrib/referentielijsten/api/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from datetime import datetime

from django.utils.translation import gettext_lazy as _

from rest_framework import serializers

from openforms.api.utils import mark_experimental


@mark_experimental
class ReferentielijstTabellenSerializer(serializers.Serializer):
code = serializers.CharField(
help_text=_("The unique code that identifies the table.")
)
naam = serializers.CharField(help_text=_("The name of the table."))
einddatumGeldigheid = serializers.DateTimeField(
help_text=_("The timestamp on which the tabel expires."), write_only=True
)

is_geldig = serializers.SerializerMethodField(
help_text=_("Indicates whether or not the table is expired.")
)

def get_is_geldig(self, attrs: dict) -> bool:
if einddatum := attrs.get("einddatumGeldigheid"):
parsed_datetime = datetime.fromisoformat(einddatum)
if parsed_datetime < datetime.now(tz=parsed_datetime.tzinfo):
return False
return True
55 changes: 55 additions & 0 deletions src/openforms/contrib/referentielijsten/api/viewsets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext_lazy as _

from drf_spectacular.utils import extend_schema, extend_schema_view
from requests.exceptions import RequestException
from rest_framework import authentication, permissions, serializers, status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from zgw_consumers.client import build_client
from zgw_consumers.models import Service

from openforms.api.utils import mark_experimental

from ..client import ReferentielijstenClient
from .serializers import ReferentielijstTabellenSerializer


@extend_schema_view(
get=extend_schema(
summary=_("List tabellen for a Referentielijsten service"),
description=_(
"Return a list of available (JSON) tabellen in a given Referentielijsten service configured "
"in the backend.\n\n"
"Note that this endpoint is **EXPERIMENTAL**."
),
responses={
200: ReferentielijstTabellenSerializer(many=True),
},
)
)
@mark_experimental
class ReferentielijstenTabellenViewSet(viewsets.ViewSet):
"""
List tabellen for a given Referentielijst service
"""

authentication_classes = (authentication.SessionAuthentication,)
permission_classes = (permissions.IsAdminUser,)
serializer_class = ReferentielijstTabellenSerializer

@action(detail=False, methods=["get"], url_path="(?P<service_slug>[-a-zA-Z0-9_]+)")
def get(self, request, service_slug: str | None = None):
service = get_object_or_404(Service, slug=service_slug)
try:
with build_client(
service, client_factory=ReferentielijstenClient
) as client:
result = client.get_tabellen()
except RequestException:
result = []

assert issubclass(self.serializer_class, serializers.Serializer)
serializer = self.serializer_class(data=result, many=True)
serializer.is_valid()
return Response(serializer.data, status=status.HTTP_200_OK)
21 changes: 21 additions & 0 deletions src/openforms/contrib/referentielijsten/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,28 @@ class TabelItem(TypedDict):
aanvullendeGegevens: Any


class Beheerder(TypedDict):
naam: str
email: str
afdeling: str
organisatie: str


class Tabel(TypedDict):
code: str
naam: str
beheerder: Beheerder
einddatumGeldigheid: str | None # ISO 8601 datetime string


class ReferentielijstenClient(APIClient):
def get_tabellen(self) -> list[Tabel]:
response = self.get("tabellen", timeout=10)
response.raise_for_status()
data = response.json()
all_data = list(pagination_helper(self, data))
return all_data

def get_items_for_tabel(self, code: str) -> list[TabelItem]:
response = self.get("items", params={"tabel__code": code}, timeout=10)
response.raise_for_status()
Expand Down
3 changes: 2 additions & 1 deletion src/openforms/js/components/formio_builder/WebformBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
getRegistrationAttributes,
getValidatorPlugins,
} from './plugins';
import {getServices} from './referentielijsten';
import {getReferentielijstenTabellen, getServices} from './referentielijsten';

let _supportedLanguages = undefined;
const getSupportedLanguages = () => {
Expand Down Expand Up @@ -169,6 +169,7 @@ class WebformBuilder extends WebformBuilderFormio {
getValidatorPlugins={getValidatorPlugins}
getRegistrationAttributes={getRegistrationAttributes}
getServices={getServices}
getReferentielijstenTabellen={getReferentielijstenTabellen}
getPrefillPlugins={getPrefillPlugins}
getPrefillAttributes={getPrefillAttributes}
getFileTypes={async () => FILE_TYPES}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ export const getServices = async type => {
const resp = await get(`/api/v2/services?type=${encodeURIComponent(type)}`);
return resp.data;
};

export const getReferentielijstenTabellen = async service => {
const resp = await get(`/api/v2/referentielijst-tabellen/${service}`);
return resp.data;
};

0 comments on commit 40da627

Please sign in to comment.