Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#4031] Set geometry as part of the JSON Schema #4102

Closed
wants to merge 4 commits into from
Closed
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
8 changes: 8 additions & 0 deletions src/openforms/contrib/objects_api/clients/objecttypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ def list_objecttypes(
page_size=page_size,
)

def get_objecttype(
self,
objecttype_uuid: str | UUID,
) -> dict[str, Any]:
response = self.get(f"objecttypes/{objecttype_uuid}")
response.raise_for_status()
return response.json()

def list_objecttype_versions(
self,
objecttype_uuid: str | UUID,
Expand Down
7 changes: 6 additions & 1 deletion src/openforms/contrib/objects_api/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@ def prepare_data_for_registration(
record_data: dict[str, Any],
objecttype: str,
objecttype_version: int,
geometry_data: dict[str, Any] | None = None,
) -> dict[str, Any]:
"""Prepare the submission data for sending it to the Objects API."""

return {
data = {
"type": objecttype,
"record": {
"typeVersion": objecttype_version,
"data": record_data,
"startAt": get_today(),
},
}
if geometry_data is not None:
data["record"]["geometry"] = geometry_data

return data
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ const ObjectsApiOptionsFormFields = ({index, name, schema, formData, onChange})
draft.version = realVersion;
if (realVersion === 2) {
draft.variablesMapping = [];
draft.geometryVariableKey = '';
} else {
delete draft.variablesMapping;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {FormattedMessage} from 'react-intl';
*
* @typedef {{
* variablesMapping: {variableKey: string, targetPath: string[]}[],
* geometryVariableKey: string,
* }} ObjectsAPIV2Options
*
* @param {Object} p
Expand All @@ -15,18 +14,6 @@ import {FormattedMessage} from 'react-intl';
* @returns {JSX.Element} - The summary, represented as the parts of the target path separated by '>'
*/
const ObjectsApiSummaryHandler = ({variable, backendOptions}) => {
const geometryVariableKey = backendOptions.geometryVariableKey;

if (geometryVariableKey === variable.key) {
return (
<FormattedMessage
description="'Mapped to geometry' registration summary message"
defaultMessage="Mapped to the {geometryPath} attribute"
values={{geometryPath: <code>record.geometry</code>}}
/>
);
}

const variableMapping = backendOptions.variablesMapping.find(
mapping => mapping.variableKey === variable.key
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {asJsonSchema} from './utils';
* objecttype: string;
* objecttypeVersion: number;
* variablesMapping: {variableKey: string, targetPath: string[]}[];
* geometryVariableKey: string;
* }} ObjectsAPIRegistrationBackendOptions
*
* @param {Object} p
Expand All @@ -39,13 +38,10 @@ const ObjectsApiVariableConfigurationEditor = ({variable}) => {
const {values: backendOptions, getFieldProps, setFieldValue} = useFormikContext();

/** @type {ObjectsAPIRegistrationBackendOptions} */
const {objecttype, objecttypeVersion, geometryVariableKey, variablesMapping, version} =
backendOptions;
const {objecttype, objecttypeVersion, variablesMapping, version} = backendOptions;

if (version !== 2) throw new Error('Not supported, must be config version 2.');

const isGeometry = geometryVariableKey === variable.key;

// get the index of our variable in the mapping, if it exists
let index = variablesMapping.findIndex(
mappedVariable => mappedVariable.variableKey === variable.key
Expand Down Expand Up @@ -115,33 +111,6 @@ const ObjectsApiVariableConfigurationEditor = ({variable}) => {
/>
</Field>
</FormRow>
<FormRow>
<Field
label={
<FormattedMessage
defaultMessage="Map to geometry field"
description="'Map to geometry field' checkbox label"
/>
}
helpText={
<FormattedMessage
description="'Map to geometry field' checkbox help text"
defaultMessage="Whether to map this variable to the {geometryPath} attribute"
values={{geometryPath: <code>record.geometry</code>}}
/>
}
name="geometryVariableKey"
disabled={!!mappedVariable.targetPath}
>
<Checkbox
checked={isGeometry}
onChange={event => {
const newValue = event.target.checked ? variable.key : undefined;
setFieldValue('geometryVariableKey', newValue);
}}
/>
</Field>
</FormRow>
<FormRow>
<Field
name={`${namePrefix}.targetPath`}
Expand All @@ -151,14 +120,12 @@ const ObjectsApiVariableConfigurationEditor = ({variable}) => {
description="'JSON Schema target' label"
/>
}
disabled={isGeometry}
>
<TargetPathSelect
name={`${namePrefix}.targetPath`}
index={index}
choices={choices}
mappedVariable={mappedVariable}
disabled={isGeometry}
/>
</Field>
</FormRow>
Expand Down
14 changes: 13 additions & 1 deletion src/openforms/registrations/contrib/objects_api/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,22 @@ def post(self, request: Request, *args: Any, **kwargs: Any):

with get_objecttypes_client() as client:

json_schema = client.get_objecttype_version(
allow_geometry = client.get_objecttype(objecttype_uuid).get(
"allowGeometry", True
)

_json_schema = client.get_objecttype_version(
objecttype_uuid, input_serializer.validated_data["objecttype_version"]
)["jsonSchema"]

json_schema = {
"type": "object",
"properties": {"data": {"type": "object", "properties": _json_schema}},
}

if allow_geometry:
json_schema["properties"]["geometry"] = {"type": "object"}

return_data = [
{
"target_path": json_path.segments,
Expand Down
12 changes: 1 addition & 11 deletions src/openforms/registrations/contrib/objects_api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,23 +150,13 @@ class ObjectsAPIOptionsSerializer(JsonSchemaSerializerMixin, serializers.Seriali
required=False,
)

# As `record.geometry` is outside `record.data`, we special case this attribute:
geometry_variable_key = FormioVariableKeyField(
label=_("geometry variable"),
help_text=_(
"The 'dotted' path to a form variable key that should be mapped to the `record.geometry` attribute."
),
required=False,
allow_blank=True,
)

def validate(self, attrs: dict[str, Any]) -> dict[str, Any]:
v1_only_fields = {
"productaanvraag_type",
"content_json",
"payment_status_update_json",
}
v2_only_fields = {"variables_mapping", "geometry_variable_key"}
v2_only_fields = {"variables_mapping"}

version = get_from_serializer_data_or_instance("version", attrs, self)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
SubmissionFileAttachment,
SubmissionReport,
)
from openforms.typing import JSONObject
from openforms.variables.constants import FormVariableSources
from openforms.variables.service import get_static_variables
from openforms.variables.utils import get_variables_for_context
Expand Down Expand Up @@ -363,10 +362,10 @@ def get_update_payment_status_data(
class ObjectsAPIV2Handler(ObjectsAPIRegistrationHandler[RegistrationOptionsV2]):

@staticmethod
def _get_record_data(
def _get_payload_data(
variables_values: FormioData, variables_mapping: list[ObjecttypeVariableMapping]
) -> JSONObject:
record_data: JSONObject = {}
) -> dict[str, Any]:
payload_data: dict[str, Any] = {}

for mapping in variables_mapping:
variable_key = mapping["variable_key"]
Expand All @@ -383,9 +382,9 @@ def _get_record_data(
if isinstance(value, (datetime, date)):
value = value.isoformat()

glom.assign(record_data, glom.Path(*target_path), value, missing=dict)
glom.assign(payload_data, glom.Path(*target_path), value, missing=dict)

return record_data
return payload_data

@staticmethod
def _process_value(value: Any, component: Component) -> Any:
Expand Down Expand Up @@ -455,17 +454,15 @@ def get_object_data(

variables_values = FormioData({**dynamic_values, **static_values})
variables_mapping = options["variables_mapping"]
record_data = self._get_record_data(variables_values, variables_mapping)
payload_data = self._get_payload_data(variables_values, variables_mapping)

object_data = prepare_data_for_registration(
record_data=record_data,
record_data=payload_data.get("data", {}),
geometry_data=payload_data.get("geometry"),
objecttype=options["objecttype"],
objecttype_version=options["objecttype_version"],
)

if geometry_variable_key := options.get("geometry_variable_key"):
object_data["record"]["geometry"] = variables_values[geometry_variable_key]

return object_data

@override
Expand All @@ -485,10 +482,11 @@ def get_update_payment_status_data(

variables_values = FormioData(values)
variables_mapping = options["variables_mapping"]
record_data = self._get_record_data(variables_values, variables_mapping)
payload_data = self._get_payload_data(variables_values, variables_mapping)

object_data = prepare_data_for_registration(
record_data=record_data,
record_data=payload_data.get("data", {}),
geometry_data=payload_data.get("geometry"),
objecttype=options["objecttype"],
objecttype_version=options["objecttype_version"],
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,41 +100,44 @@ def test_submission_with_objects_api_v2(self):
"organisatie_rsin": "000000000",
"variables_mapping": [
# fmt: off
{
"variable_key": "location",
"target_path": ["geometry"],
},
{
"variable_key": "age",
"target_path": ["age"],
"target_path": ["data", "age"],
},
{
"variable_key": "lastname",
"target_path": ["name", "last.name"]
"target_path": ["data", "name", "last.name"]
},
{
"variable_key": "now",
"target_path": ["submission_date"],
"target_path": ["data", "submission_date"],
},
{
"variable_key": "pdf_url",
"target_path": ["submission_pdf_url"],
"target_path": ["data", "submission_pdf_url"],
},
{
"variable_key": "csv_url",
"target_path": ["submission_csv_url"],
"target_path": ["data", "submission_csv_url"],
},
{
"variable_key": "payment_completed",
"target_path": ["submission_payment_completed"],
"target_path": ["data", "submission_payment_completed"],
},
{
"variable_key": "payment_amount",
"target_path": ["submission_payment_amount"],
"target_path": ["data", "submission_payment_amount"],
},
{
"variable_key": "payment_public_order_ids",
"target_path": ["submission_payment_public_ids"],
"target_path": ["data", "submission_payment_public_ids"],
},
# fmt: on
],
"geometry_variable_key": "location",
}

plugin = ObjectsAPIRegistration(PLUGIN_IDENTIFIER)
Expand Down Expand Up @@ -213,11 +216,11 @@ def test_submission_with_file_components(self):
# fmt: off
{
"variable_key": "single_file",
"target_path": ["single_file"],
"target_path": ["data", "single_file"],
},
{
"variable_key": "multiple_files",
"target_path": ["multiple_files"]
"target_path": ["data", "multiple_files"]
},
# fmt: on
],
Expand Down Expand Up @@ -275,7 +278,7 @@ def test_submission_with_map_component_inside_data(self):
# fmt: off
{
"variable_key": "location",
"target_path": ["pointCoordinates"],
"target_path": ["data", "pointCoordinates"],
},
# fmt: on
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,41 +114,44 @@ def test_update_payment_status(self):
"organisatie_rsin": "000000000",
"variables_mapping": [
# fmt: off
{
"variable_key": "location",
"target_path": ["geometry"],
},
{
"variable_key": "age",
"target_path": ["age"],
"target_path": ["data", "age"],
},
{
"variable_key": "lastname",
"target_path": ["name", "last.name"]
"target_path": ["data", "name", "last.name"]
},
{
"variable_key": "now",
"target_path": ["submission_date"],
"target_path": ["data", "submission_date"],
},
{
"variable_key": "pdf_url",
"target_path": ["submission_pdf_url"],
"target_path": ["data", "submission_pdf_url"],
},
{
"variable_key": "csv_url",
"target_path": ["submission_csv_url"],
"target_path": ["data", "submission_csv_url"],
},
{
"variable_key": "payment_completed",
"target_path": ["submission_payment_completed"],
"target_path": ["data", "submission_payment_completed"],
},
{
"variable_key": "payment_amount",
"target_path": ["nested", "submission_payment_amount"],
"target_path": ["data", "nested", "submission_payment_amount"],
},
{
"variable_key": "payment_public_order_ids",
"target_path": ["submission_payment_public_ids"],
"target_path": ["data", "submission_payment_public_ids"],
},
# fmt: on
],
"geometry_variable_key": "location",
}

SubmissionPaymentFactory.create(
Expand Down
1 change: 0 additions & 1 deletion src/openforms/registrations/contrib/objects_api/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ class ObjecttypeVariableMapping(TypedDict):
class RegistrationOptionsV2(_BaseRegistrationOptions, total=False):
version: Required[Literal[2]]
variables_mapping: Required[list[ObjecttypeVariableMapping]]
geometry_variable_key: str


RegistrationOptions: TypeAlias = RegistrationOptionsV1 | RegistrationOptionsV2
Expand Down
Loading