Skip to content

Commit

Permalink
🚧 [#4993] Implement fetching select(boxes) options from Referentielij…
Browse files Browse the repository at this point in the history
…sten

this was previously possible with logic and service fetch, but this functionality provides a shortcut to more easily integrate with Referentielijsten API
  • Loading branch information
stevenbal committed Jan 7, 2025
1 parent a425cc6 commit 34743cc
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 16 deletions.
45 changes: 40 additions & 5 deletions src/openforms/formio/dynamic_config/dynamic_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@

from glom import assign, glom
from json_logic import jsonLogic
from zgw_consumers.models import Service

from openforms.logging import logevent
from openforms.submissions.logic.service_fetching import perform_service_fetch
from openforms.submissions.models import Submission
from openforms.typing import DataMapping, JSONValue
from openforms.variables.constants import DataMappingTypes, ServiceFetchMethods
from openforms.variables.models import ServiceFetchConfiguration

from ..typing import Component

Expand Down Expand Up @@ -46,12 +50,43 @@ def add_options_to_config(
submission: Submission,
options_path: str = "values",
) -> None:
if glom(component, "openForms.dataSrc", default=None) != "variable":
return
data_src = glom(component, "openForms.dataSrc", default=None)
# TODO make these constants/choices?
# TODO move the logic to a separate app?
if data_src == "referentielijsten":
items_expression = {
"map": [{"var": "results"}, [{"var": "code"}, {"var": "naam"}]]
}
service = glom(component, "openForms.service", default=None)
code = glom(component, "openForms.code", default=None)
if not service or not code:
# TODO warning/error?
return

# TODO error handling, also check if service is part of `referentielijsten_services`?
service = Service.objects.get(slug=service)
config = ServiceFetchConfiguration(
service=service,
path="items",
method=ServiceFetchMethods.get,
# TODO pass Accept-Language header here?
headers=None,
query_params={"tabel__code": code},
data_mapping_type=DataMappingTypes.json_logic,
mapping_expression=items_expression,
cache_timeout=60,
)

items_expression = glom(component, "openForms.itemsExpression")
items_array = jsonLogic(items_expression, data)
if not items_array:
# TODO handle non success cases
result = perform_service_fetch(config, data, str(submission.uuid))
if not (items_array := result.value):
return
elif data_src == "variable":
items_expression = glom(component, "openForms.itemsExpression")
items_array = jsonLogic(items_expression, data)
if not items_array:
return
else:
return

if not isinstance(items_array, list):
Expand Down
7 changes: 6 additions & 1 deletion src/openforms/submissions/logic/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,12 @@ def eval(
) -> DataMapping:
var = self.rule.form.formvariable_set.get(key=self.variable)
with log_errors({}, self.rule): # TODO proper error handling
result = perform_service_fetch(var, context, str(submission.uuid))
if not (fetch_config := var.service_fetch_configuration):
raise ValueError(
f"Can't perform service fetch on {var}. "
"It needs a service_fetch_configuration."
)
result = perform_service_fetch(fetch_config, context, str(submission.uuid))
return {var.key: result.value}


Expand Down
13 changes: 3 additions & 10 deletions src/openforms/submissions/logic/service_fetching.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from json_logic import jsonLogic
from zgw_consumers.client import build_client

from openforms.forms.models import FormVariable
from openforms.typing import DataMapping, JSONObject, JSONValue
from openforms.variables.models import DataMappingTypes, ServiceFetchConfiguration

Expand All @@ -24,7 +23,9 @@ class FetchResult:


def perform_service_fetch(
var: FormVariable, context: DataMapping, submission_uuid: str = ""
fetch_config: ServiceFetchConfiguration,
context: DataMapping,
submission_uuid: str = "",
) -> FetchResult:
"""Fetch a value from a http-service, perform a transformation on it and
return the result.
Expand All @@ -39,14 +40,6 @@ def perform_service_fetch(
The value returned by the request is cached using the submission UUID and the
arguments to the request (hashed to make a cache key).
"""

if not var.service_fetch_configuration:
raise ValueError(
f"Can't perform service fetch on {var}. "
"It needs a service_fetch_configuration."
)
fetch_config: ServiceFetchConfiguration = var.service_fetch_configuration

client = build_client(fetch_config.service)
request_args = fetch_config.request_arguments(context)

Expand Down

0 comments on commit 34743cc

Please sign in to comment.