From 4a6c015c674adbcaf2a5cfede8226bab99e4a1e6 Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Wed, 8 Jan 2025 18:31:44 +0100 Subject: [PATCH 1/9] Fix and add zgw mappings --- .../mappings/xxllnc-v1-case-to-zgw-zaak.json | 17 +++++++++-- .../xxllnc-v1-casetype-to-zgw-zaaktype.json | 29 +++++++++++++++++-- ...-document-to-zgw-zaakinformatieobject.json | 15 +++++++++- .../xxllnc-v1-field-to-zgw-eigenschap.json | 20 +++++++++++++ ...-v1-field-to-zgw-informatieobjecttype.json | 15 ++++++++++ ...bjecttype-to-zgw-informatieobjecttype.json | 14 +++++++++ .../xxllnc-v1-milestone-to-zgw-status.json | 4 ++- .../xxllnc-v1-outcome-to-zgw-resultaat.json | 3 +- .../xxllnc-v1-phase-to-zgw-statustype.json | 20 +++++++++++++ ...xxllnc-v1-result-to-zgw-resultaattype.json | 18 ++++++++++++ .../xxllnc-v1-role-to-zgw-roltype.json | 14 +++++++++ .../xxllnc-v1-rolerequestor-to-zgw-rol.json | 26 ++++++++++++++++- ...xxllnc-v1-value-to-zgw-zaakeigenschap.json | 6 +++- lib/Service/CallService.php | 1 + lib/Service/SynchronizationService.php | 12 ++++---- 15 files changed, 199 insertions(+), 15 deletions(-) create mode 100644 configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-eigenschap.json create mode 100644 configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-informatieobjecttype.json create mode 100644 configurations/xxllnc-zgw/mappings/xxllnc-v1-informatieobjecttype-to-zgw-informatieobjecttype.json create mode 100644 configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json create mode 100644 configurations/xxllnc-zgw/mappings/xxllnc-v1-result-to-zgw-resultaattype.json create mode 100644 configurations/xxllnc-zgw/mappings/xxllnc-v1-role-to-zgw-roltype.json diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json index 129c219f..152d951b 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json @@ -20,7 +20,7 @@ "resultaat": "{% if instance.outcome|default %}{% set data = {'outcome': instance.outcome, 'resultaattypen': zaaktype.resultaattypen} %}{{ executeMapping(2, data)|json_encode }}{% endif %}", "rollen": "[{% if instance.route.instance.role|default %}{% set dataRol = {'requestor': instance.requestor, 'role': instance.route.instance.role, 'roltypen': zaaktype.roltypen} %}{{ executeMapping(3, dataRol)|json_encode }}{% endif %}]", "status": "{% if instance.milestone|default %}{% set data = {'milestone': instance.milestone, 'statustypen': zaaktype.statustypen} %}{{ executeMapping(4, data)|json_encode }}{% endif %}", - "zaaktype": "{% if casetype|default %}{{ executeMapping(5, casetype)|json_encode }}{% endif %}", + "zaaktype": "{% if casetype.result|default %}{{ executeMapping(5, casetype.result)|json_encode }}{% endif %}", "eigenschappen": "[{% set index=0 %}{% if zaaktype.eigenschappen|default %}{% for key, attribute in instance.attributes %}{% if index != 0 %},{% endif %}{% set data = {'name': key, 'value': attribute, 'eigenschappen': zaaktype.eigenschappen} %}{% if attribute[0][0]|default and attribute[0][0] is iterable %}{{ attribute|json_encode }}{% else %}{{ executeMapping(6, data)|json_encode }}{% endif %}{% set index=index+1 %}{% endfor %}{% endif %}]", "zaakinformatieobjecten": "[{% set index=0 %}{% if documents.result.instance.rows|default %}{% for document in documents.result.instance.rows %}{% set document = document|merge({'caseId': reference}) %}{% if index != 0 %},{% endif %}{{ executeMapping(7, document)|json_encode }}{% set index=index+1 %}{% endfor %}{% endif %}]", "bronorganisatie": "bronorganisatie", @@ -38,7 +38,20 @@ "opschorting.reden": "unsetIfValue==", "opschorting": "unsetIfValue==", "zaakinformatieobjecten": "jsonToArray", - "zaaktype": "jsonToArray" + "identificatie": "unsetIfValue==reference", + "omschrijving": "unsetIfValue==instance.subject", + "toelichting": "unsetIfValue==instance.subject_external", + "registratiedatum": "unsetIfValue==instance.date_of_registration", + "startdatum": "unsetIfValue==instance.date_of_registration", + "einddatum": "unsetIfValue==instance.date_of_completion", + "einddatumGepland": "unsetIfValue==instance.date_target", + "publicatiedatum": "unsetIfValue==instance.date_target", + "communicatiekanaal": "unsetIfValue==instance.channel_of_contact", + "vertrouwelijkheidaanduidng": "unsetIfValue==instance.confidentiality.mapped", + "kenmerken.0.kenmerk": "unsetIfValue==reference", + "resultaattoelichting": "unsetIfValue==", + "bronorganisatie": "unsetIfValue==bronorganisatie", + "verantwoordelijkeOrganisatie": "unsetIfValue==bronorganisatie" }, "passTrough": false } \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json index 1d4e5f02..d49c157f 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json @@ -17,11 +17,36 @@ "bronzaaktype.identificatie": "reference", "bronzaaktype.omschrijving": "instance.title", "referentieproces.naam": "preview", - "verantwoordelijke": "instance.properties.supervisor" + "verantwoordelijke": "instance.properties.supervisor", + "statustypen": "[{% for phase in instance.phases %}{% if not loop.first %},{% endif %}{{ executeMapping(8, phase)|json_encode }}{% endfor %}]", + "informatieobjecttypen": "[{% set index=0 %}{% for phase in instance.phases %}{% for field in phase.fields %}{% if field.type == 'file' %}{% if index != 0 %},{% endif %}{{ executeMapping(9, field)|json_encode }}{% set index=index+1 %}{% endif %}{% endfor %}{% endfor %}]", + "eigenschappen": "[{% set index=0 %}{% for phase in instance.phases %}{% for field in phase.fields %}{% if field.type != 'file' %}{% if index != 0 %},{% endif %}{{ executeMapping(10, field)|json_encode }}{% set index=index+1 %}{% endif %}{% endfor %}{% endfor %}]", + "roltypen": "[{% set index=0 %}{% for phase in instance.phases %}{% if phase.route.role|default %}{% set role = phase.route.role %}{% if index != 0 %},{% endif %}{{ executeMapping(11, role)|json_encode }}{% set index=index+1 %}{% endif %}{% endfor %}]", + "resultaattypen": "[{% if instance.results|default %}{% for result in instance.results %}{% if not loop.first %},{% endif %}{{ executeMapping(12, result)|json_encode }}{% endfor %}{% endif %}]" }, "unset": [], "cast": { - "identificatie": "unsetIfValue==instance.legacy.zaaktype_id" + "identificatie": "unsetIfValue==instance.legacy.zaaktype_id", + "statustypen": "jsonToArray", + "informatieobjecttypen": "jsonToArray", + "eigenschappen": "jsonToArray", + "roltypen": "jsonToArray", + "resultaattypen": "jsonToArray", + "catalogus": "unsetIfValue==_catalogus", + "onderwerp": "unsetIfValue==instance.title", + "indicatieInternOfExtern": "unsetIfValue==extern", + "doorlooptijd": "unsetIfValue==", + "servicenorm": "unsetIfValue==", + "verlengingMogelijk": "unsetIfValue==instance.properties.extension", + "publicatieIndicatie": "unsetIfValue==instance.properties.publication", + "omschrijving": "unsetIfValue==instance.title", + "opschortingEnAanhoudingMogelijk": "unsetIfValue==instance.properties.suspension", + "bronzaaktype.url": "unsetIfValue==url", + "bronzaaktype.identificatie": "unsetIfValue==reference", + "bronzaaktype.omschrijving": "unsetIfValue==instance.title", + "bronzaaktype.naam": "unsetIfValue==preview", + "referentieproces.naam": "unsetIfValue==preview", + "verantwoordelijke": "unsetIfValue==instance.properties.supervisor" }, "passTrough": false } \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-document-to-zgw-zaakinformatieobject.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-document-to-zgw-zaakinformatieobject.json index 56b8a012..5833a3e1 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-document-to-zgw-zaakinformatieobject.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-document-to-zgw-zaakinformatieobject.json @@ -23,7 +23,20 @@ "cast": { "informatieobject.versie": "integer", "informatieobject.bestandsomvang": "integer", - "informatieobject.inhoud": "jsonToArray" + "informatieobject.inhoud": "jsonToArray", + "titel": "unsetIfValue==instance.name", + "registratiedatum": "unsetIfValue==instance.file.instance.date_created", + "informatieobject.identificatie": "unsetIfValue==instance.number", + "informatieobject.creatiedatum": "unsetIfValue==instance.file.instance.date_created", + "informatieobject.titel": "unsetIfValue==instance.name", + "informatieobject.vertrouwelijksheidaanduiding": "unsetIfValue==", + "informatieobject.formaat": "unsetIfValue==instance.file.instance.mimetype", + "informatieobject.beginRegistratie": "unsetIfValue==instance.file.instance.date_modified", + "informatieobject.bestandsnaam": "unsetIfValue==instance.filename", + "informatieobject.verschijningsvorm": "unsetIfValue==", + "informatieobject.integriteit.algoritme": "unsetIfValue==", + "informatieobject.integriteit.waarde": "unsetIfValue==", + "informatieobject.integriteit.datum": "unsetIfValue==instance.file.instance.date_created" }, "passTrough": false } \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-eigenschap.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-eigenschap.json new file mode 100644 index 00000000..9cb1f571 --- /dev/null +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-eigenschap.json @@ -0,0 +1,20 @@ +{ + "name": "XxllncFieldToZGWEigenschap", + "version": "0.0.1", + "mapping": { + "naam": "magic_string", + "definitie": "{% if original_label|default %}{{ original_label }}{% elseif label|default %}{{ label }}{% else %}{{ magic_string }}{% endif %}", + "specificatie.formaat": "{% if type == 'date' %}datum{% elseif type == 'datetime' %}datum_tijd{% elseif type=='number' %}getal{% else %}tekst{% endif %}", + "kardinaliteit": "{% if limit_values|default %}{{ limit_values }}{% else %}1{% endif %}", + "catalogus": "_catalogus", + "zaaktypeIdentificatie": "_zaaktypeIdentificatie" + }, + "unset": [], + "cast": { + "naam": "unsetIfValue==magic_string", + "definitie": "unsetIfValue==", + "catalogus": "unsetIfValue==_catalogus", + "zaaktypeIdentificatie": "unsetIfValue==_zaaktypeIdentificatie" + }, + "passTrough": false +} \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-informatieobjecttype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-informatieobjecttype.json new file mode 100644 index 00000000..99319b1f --- /dev/null +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-informatieobjecttype.json @@ -0,0 +1,15 @@ +{ + "name": "XxllncFieldToZGWInformatieObjectType", + "version": "0.0.1", + "mapping": { + "omschrijving": "{% if original_label|default %}{{ original_label }}{% elseif label|default %}{{ label }}{% else %}{{ magic_string }}{% endif %}", + "vertrouwelijkheidsaanduiding": "{% if publish_public|default and publish_public == true %}openbaar{% else %}zaakvertrouwelijk{% endif %}", + "beginGeldigheid": "{{ 'now'|date('Y-m-d') }}", + "informatieobjectcategorie": "xxllnc informatieobject" + }, + "unset": [], + "cast": { + "omschrijving": "unsetIfValue==" + }, + "passTrough": false +} \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-informatieobjecttype-to-zgw-informatieobjecttype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-informatieobjecttype-to-zgw-informatieobjecttype.json new file mode 100644 index 00000000..68772769 --- /dev/null +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-informatieobjecttype-to-zgw-informatieobjecttype.json @@ -0,0 +1,14 @@ +{ + "name": "XxllncInformatieObjectTypeToZGWInformatieObjectType", + "version": "0.0.1", + "mapping": { + "omschrijving": "original_label", + "vertrouwelijkheidaanduiding": "public" + }, + "unset": [], + "cast": { + "omschrijving": "unsetIfValue==original_label", + "vertrouwelijkheidaanduiding": "unsetIfValue==public" + }, + "passTrough": false +} \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-milestone-to-zgw-status.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-milestone-to-zgw-status.json index ce2564de..e5ca2020 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-milestone-to-zgw-status.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-milestone-to-zgw-status.json @@ -10,7 +10,9 @@ "unset": [], "cast": { "indicatieLaatstGezetteStatus": "bool", - "statustype": "unsetIfValue==" + "statustype": "unsetIfValue==", + "datumStatusGezet": "unsetIfValue==milestone.instance.date_modified", + "statustoelichting": "unsetIfValue==milestone.instance.phase_label" }, "passTrough": false } \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-outcome-to-zgw-resultaat.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-outcome-to-zgw-resultaat.json index ea9754ab..8c1c45ca 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-outcome-to-zgw-resultaat.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-outcome-to-zgw-resultaat.json @@ -7,7 +7,8 @@ }, "unset": [], "cast": { - "resultaattype": "unsetIfValue==" + "resultaattype": "unsetIfValue==", + "toelichting": "unsetIfValue==" }, "passTrough": false } \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json new file mode 100644 index 00000000..2a0e6bb0 --- /dev/null +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json @@ -0,0 +1,20 @@ +{ + "name": "XxllncPhaseToZGWStatusType", + "version": "0.0.1", + "mapping": { + "volgnummer": "seq", + "omschrijving": "name", + "omschrijvingGeneriek": "{% if fields.0.label|default %}{{ fields.0.label }}{% else %}geen statustekst{% endif %}", + "statustekst": "{% if fields.0.help|default %}{{ fields.0.help }}{% else %}geen statustekst{% endif %}", + "catalogus": "_catalogus", + "zaaktypeIdentificatie": "_zaaktypeIdentificatie" + }, + "unset": [], + "cast": { + "volgnummer": "unsetIfValue==seq", + "omschrijving": "unsetIfValue==name", + "catalogus": "unsetIfValue==_catalogus", + "zaaktypeIdentificatie": "unsetIfValue==_zaaktypeIdentificatie" + }, + "passTrough": false +} \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-result-to-zgw-resultaattype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-result-to-zgw-resultaattype.json new file mode 100644 index 00000000..7f0728ef --- /dev/null +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-result-to-zgw-resultaattype.json @@ -0,0 +1,18 @@ +{ + "name": "XxllncResultToZGWResultaatType", + "version": "0.0.1", + "mapping": { + "omschrijving": "type", + "toelichting": "label", + "selectielijstklasse": "{% if selection_list|default %}https://inavigator.bizzib.nl/bsd/sl2020.gem.html#{{ selection_list_number|replace({'.': '_'}) }}{% else %}http://localhost{% endif %}", + "archiefnominatie": "{% if type_of_archiving == 'Bewaren (B)' or type_of_archiving == 'Conversie' %}blijvend_bewaren{% else %}vernietigen{% endif %}", + "archiefactietermijn": "{% if period_of_preservation|default %}P{{ period_of_preservation }}D{% endif %}" + }, + "unset": [], + "cast": { + "omschrijving": "unsetIfValue==type", + "toelichting": "unsetIfValue==label", + "archiefactietermijn": "unsetIfValue==" + }, + "passTrough": false +} \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-role-to-zgw-roltype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-role-to-zgw-roltype.json new file mode 100644 index 00000000..2b2015fd --- /dev/null +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-role-to-zgw-roltype.json @@ -0,0 +1,14 @@ +{ + "name": "XxllncRoleToZGWRolType", + "version": "0.0.1", + "mapping": { + "omschrijving": "{% if instance.description|default %}{{ instance.description }}{% endif %}", + "omschrijvingGeneriek": "{% if instance.name|default %}{{ instance.name|lower }}{% endif %}" + }, + "unset": [], + "cast": { + "omschrijving": "unsetIfValue==", + "omschrijvingGeneriek": "unsetIfValue==" + }, + "passTrough": false +} \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-rolerequestor-to-zgw-rol.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-rolerequestor-to-zgw-rol.json index 5369ed0e..98296e69 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-rolerequestor-to-zgw-rol.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-rolerequestor-to-zgw-rol.json @@ -31,7 +31,31 @@ "unset": [], "cast": { "roltype": "unsetIfValue==", - "betrokkeneIdentificatie": "unsetIfValue==" + "betrokkeneIdentificatie": "unsetIfValue==", + "omschrijving": "unsetIfValue==", + "omschrijvingGeneriek": "unsetIfValue==", + "roltoelichting": "unsetIfValue==", + "registratiedatum": "unsetIfValue==", + "contactpersoonRol.emailadres": "unsetIfValue==", + "contactpersoonRol.functie": "unsetIfValue==", + "contactpersoonRol.telefoonnummer": "unsetIfValue==", + "contactpersoonRol.naam": "unsetIfValue==", + "betrokkeneIdentificatie._sourceId": "unsetIfValue==", + "betrokkeneIdentificatie.inpBsn": "unsetIfValue==", + "betrokkeneIdentificatie.inpA_nummer": "unsetIfValue==", + "betrokkeneIdentificatie.geslachtsnaam": "unsetIfValue==", + "betrokkeneIdentificatie.voorvoegselGeslachtsnaam": "unsetIfValue==", + "betrokkeneIdentificatie.voorletters": "unsetIfValue==", + "betrokkeneIdentificatie.voornamen": "unsetIfValue==", + "betrokkeneIdentificatie.geslachtsaanduiding": "unsetIfValue==", + "betrokkeneIdentificatie.geboortedatum": "unsetIfValue==", + "betrokkeneIdentificatie.achternaam": "unsetIfValue==", + "betrokkeneIdentificatie.verblijfsadres.wplWoonplaatsNaam": "unsetIfValue==", + "betrokkeneIdentificatie.verblijfsadres.aoaPostcode": "unsetIfValue==", + "betrokkeneIdentificatie.verblijfsadres.aoaHuisnummer": "unsetIfValue==", + "betrokkeneIdentificatie.verblijfsadres.aoaHuisletter": "unsetIfValue==", + "betrokkeneIdentificatie.verblijfsadres.aoaHuisnummertoevoeging": "unsetIfValue==", + "betrokkeneIdentificatie.verblijfsadres": "unsetIfValue==" }, "passTrough": false } \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-value-to-zgw-zaakeigenschap.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-value-to-zgw-zaakeigenschap.json index 88828190..83f762dd 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-value-to-zgw-zaakeigenschap.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-value-to-zgw-zaakeigenschap.json @@ -7,6 +7,10 @@ "eigenschap": "{% for eigenschap in eigenschappen %}{% if eigenschap.naam == name %}{{ eigenschap['_self']['id'] }}{% endif %}{% endfor %}" }, "unset": [], - "cast": [], + "cast": { + "naam": "unsetIfValue==", + "waarde": "unsetIfValue==", + "eigenschap": "unsetIfValue==" + }, "passTrough": false } \ No newline at end of file diff --git a/lib/Service/CallService.php b/lib/Service/CallService.php index 24f84186..440b30d5 100644 --- a/lib/Service/CallService.php +++ b/lib/Service/CallService.php @@ -253,6 +253,7 @@ public function call( $time_end = microtime(true); $body = $response->getBody()->getContents(); + var_dump($url); // Let's create the data array $data = [ diff --git a/lib/Service/SynchronizationService.php b/lib/Service/SynchronizationService.php index 0220c67f..3ed28ac2 100644 --- a/lib/Service/SynchronizationService.php +++ b/lib/Service/SynchronizationService.php @@ -254,7 +254,7 @@ public function getObjectFromSource(Synchronization $synchronization, string $en $query = $sourceConfig['query'] ?? []; $config = [ 'headers' => $headers, - 'query' => $query, + 'query' => [], ]; if (str_starts_with($endpoint, $source->getLocation()) === true) { @@ -498,10 +498,10 @@ public function synchronizeContract(SynchronizationContract $synchronizationCont $originHash = md5(serialize($hashObject)); // Let's prevent pointless updates @todo account for omnidirectional sync, unless the config has been updated since last check then we do want to rebuild and check if the tagert object has changed - if ($originHash === $synchronizationContract->getOriginHash() && $synchronization->getUpdated() < $synchronizationContract->getSourceLastChecked()) { - // The object has not changed and the config has not been updated since last check - return $synchronizationContract; - } + // if ($originHash === $synchronizationContract->getOriginHash() && $synchronization->getUpdated() < $synchronizationContract->getSourceLastChecked()) { + // // The object has not changed and the config has not been updated since last check + // return $synchronizationContract; + // } // The object has changed, oke let do mappig and bla die bla $synchronizationContract->setOriginHash($originHash); @@ -721,7 +721,7 @@ public function getAllObjectsFromApi(Synchronization $synchronization, ?bool $is if ($source->getRateLimitLimit() !== null) { $currentPage = $synchronization->getCurrentPage() ?? 1; } - + // Fetch all pages recursively $objects = $this->fetchAllPages( From c6ecad68a314985b9800cc9412eb7ef5e413860e Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Thu, 9 Jan 2025 13:32:27 +0100 Subject: [PATCH 2/9] Mapping and config fixes --- .../xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json | 1 + .../xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-eigenschap.json | 2 +- .../mappings/xxllnc-v1-field-to-zgw-informatieobjecttype.json | 2 +- .../xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json | 2 +- .../mappings/xxllnc-v1-result-to-zgw-resultaattype.json | 2 +- .../xxllnc-zgw/mappings/xxllnc-v1-role-to-zgw-roltype.json | 2 +- .../synchronizations/xxllnc-v1-cases-to-zgw-zaken.json | 3 ++- 7 files changed, 8 insertions(+), 6 deletions(-) diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json index 152d951b..599f8284 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json @@ -30,6 +30,7 @@ }, "unset": [], "cast": { + "zaaktype": "jsonToArray", "resultaat": "jsonToArray", "rollen": "jsonToArray", "status": "jsonToArray", diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-eigenschap.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-eigenschap.json index 9cb1f571..1e791b51 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-eigenschap.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-eigenschap.json @@ -1,5 +1,5 @@ { - "name": "XxllncFieldToZGWEigenschap", + "name": "Xxllnc Field to ZGW Eigenschap", "version": "0.0.1", "mapping": { "naam": "magic_string", diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-informatieobjecttype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-informatieobjecttype.json index 99319b1f..35f7fb1c 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-informatieobjecttype.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-field-to-zgw-informatieobjecttype.json @@ -1,5 +1,5 @@ { - "name": "XxllncFieldToZGWInformatieObjectType", + "name": "Xxllnc Field to ZGW InformatieObjectType", "version": "0.0.1", "mapping": { "omschrijving": "{% if original_label|default %}{{ original_label }}{% elseif label|default %}{{ label }}{% else %}{{ magic_string }}{% endif %}", diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json index 2a0e6bb0..5335b9ab 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json @@ -1,5 +1,5 @@ { - "name": "XxllncPhaseToZGWStatusType", + "name": "Xxllnc Phase to ZGW StatusType", "version": "0.0.1", "mapping": { "volgnummer": "seq", diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-result-to-zgw-resultaattype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-result-to-zgw-resultaattype.json index 7f0728ef..b37e3822 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-result-to-zgw-resultaattype.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-result-to-zgw-resultaattype.json @@ -1,5 +1,5 @@ { - "name": "XxllncResultToZGWResultaatType", + "name": "Xxllnc Result to ZGW ResultaatType", "version": "0.0.1", "mapping": { "omschrijving": "type", diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-role-to-zgw-roltype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-role-to-zgw-roltype.json index 2b2015fd..91eecd23 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-role-to-zgw-roltype.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-role-to-zgw-roltype.json @@ -1,5 +1,5 @@ { - "name": "XxllncRoleToZGWRolType", + "name": "Xxllnc Role to ZGW RolType", "version": "0.0.1", "mapping": { "omschrijving": "{% if instance.description|default %}{{ instance.description }}{% endif %}", diff --git a/configurations/xxllnc-zgw/synchronizations/xxllnc-v1-cases-to-zgw-zaken.json b/configurations/xxllnc-zgw/synchronizations/xxllnc-v1-cases-to-zgw-zaken.json index c6fbc6cb..a56c52bf 100644 --- a/configurations/xxllnc-zgw/synchronizations/xxllnc-v1-cases-to-zgw-zaken.json +++ b/configurations/xxllnc-zgw/synchronizations/xxllnc-v1-cases-to-zgw-zaken.json @@ -18,7 +18,8 @@ "extraDataConfigs.1.staticEndpoint": "/casetype/{{ originId }}", "extraDataConfigs.1.endpointIdLocation": "instance.casetype.reference", "extraDataConfigs.1.mergeExtraData": "true", - "extraDataConfigs.1.keyToSetExtraData": "casetype" + "extraDataConfigs.1.keyToSetExtraData": "casetype", + "extraDataConfigs.1.unsetConfigKey": "query.zql" }, "currentPage": 1, "targetId": "1\/1", From 970d7a0c4519319f155eb067bf946fe8f6a49cad Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Thu, 9 Jan 2025 13:32:34 +0100 Subject: [PATCH 3/9] removed var_dump --- lib/Service/CallService.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Service/CallService.php b/lib/Service/CallService.php index 440b30d5..24f84186 100644 --- a/lib/Service/CallService.php +++ b/lib/Service/CallService.php @@ -253,7 +253,6 @@ public function call( $time_end = microtime(true); $body = $response->getBody()->getContents(); - var_dump($url); // Let's create the data array $data = [ From 45e3d00e54738652f4e3c52e84f56e96d539c33c Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Thu, 9 Jan 2025 13:32:56 +0100 Subject: [PATCH 4/9] added unset possibility on config for extraDataConfig --- lib/Service/SynchronizationService.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/Service/SynchronizationService.php b/lib/Service/SynchronizationService.php index 3ed28ac2..c3b53011 100644 --- a/lib/Service/SynchronizationService.php +++ b/lib/Service/SynchronizationService.php @@ -53,6 +53,7 @@ class SynchronizationService const EXTRA_DATA_STATIC_ENDPOINT_LOCATION = 'staticEndpoint'; const KEY_FOR_EXTRA_DATA_LOCATION = 'keyToSetExtraData'; const MERGE_EXTRA_DATA_OBJECT_LOCATION = 'mergeExtraData'; + const UNSET_CONFIG_KEY_LOCATION = 'UNSET_CONFIG_KEY'; public function __construct( @@ -341,6 +342,12 @@ private function fetchExtraDataForObject(Synchronization $synchronization, array ); } + $sourceConfig = $synchronization->getSourceConfig(); + if (isset($extraDataConfig[$this::UNSET_CONFIG_KEY_LOCATION]) === true && isset($sourceConfig[$extraDataConfig[$this::UNSET_CONFIG_KEY_LOCATION]]) === true) { + unset($sourceConfig[$extraDataConfig[$this::UNSET_CONFIG_KEY_LOCATION]]); + $synchronization->setSourceConfig($sourceConfig); + } + $extraData = $this->getObjectFromSource($synchronization, $endpoint); // Temporary fix, From 877de7511b137ac3c62bcbe12e934c9b855afebb Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Thu, 9 Jan 2025 13:43:57 +0100 Subject: [PATCH 5/9] Undo and fix --- lib/Service/SynchronizationService.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Service/SynchronizationService.php b/lib/Service/SynchronizationService.php index c3b53011..b7402869 100644 --- a/lib/Service/SynchronizationService.php +++ b/lib/Service/SynchronizationService.php @@ -53,7 +53,7 @@ class SynchronizationService const EXTRA_DATA_STATIC_ENDPOINT_LOCATION = 'staticEndpoint'; const KEY_FOR_EXTRA_DATA_LOCATION = 'keyToSetExtraData'; const MERGE_EXTRA_DATA_OBJECT_LOCATION = 'mergeExtraData'; - const UNSET_CONFIG_KEY_LOCATION = 'UNSET_CONFIG_KEY'; + const UNSET_CONFIG_KEY_LOCATION = 'unsetConfigKey'; public function __construct( @@ -255,7 +255,7 @@ public function getObjectFromSource(Synchronization $synchronization, string $en $query = $sourceConfig['query'] ?? []; $config = [ 'headers' => $headers, - 'query' => [], + 'query' => $query, ]; if (str_starts_with($endpoint, $source->getLocation()) === true) { @@ -505,10 +505,10 @@ public function synchronizeContract(SynchronizationContract $synchronizationCont $originHash = md5(serialize($hashObject)); // Let's prevent pointless updates @todo account for omnidirectional sync, unless the config has been updated since last check then we do want to rebuild and check if the tagert object has changed - // if ($originHash === $synchronizationContract->getOriginHash() && $synchronization->getUpdated() < $synchronizationContract->getSourceLastChecked()) { - // // The object has not changed and the config has not been updated since last check - // return $synchronizationContract; - // } + if ($originHash === $synchronizationContract->getOriginHash() && $synchronization->getUpdated() < $synchronizationContract->getSourceLastChecked()) { + // The object has not changed and the config has not been updated since last check + return $synchronizationContract; + } // The object has changed, oke let do mappig and bla die bla $synchronizationContract->setOriginHash($originHash); From c756caa138c3c141f9472c47c655f080fdb5848b Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Fri, 10 Jan 2025 18:00:50 +0100 Subject: [PATCH 6/9] Mappings, config, synchronizations --- .../mappings/publication-to-elastic.json | 21 ++++++++++ .../woo-elastic/sources/elastic.json | 22 +++++++++++ .../publication-to-elastic.json | 17 ++++++++ .../mappings/xxllnc-v1-case-to-zgw-zaak.json | 4 +- .../xxllnc-v1-casetype-to-zgw-zaaktype.json | 4 +- .../mappings/zgw-zaak-to-xxllnc-v1-case.json | 23 +++++++++++ ...w-zaakinformatieobject-to-xxllnc-file.json | 26 +++++++++++++ .../zgw-zaak-to-xxllnc-case.json | 39 +++++++++++++++++++ 8 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 configurations/woo-elastic/mappings/publication-to-elastic.json create mode 100644 configurations/woo-elastic/sources/elastic.json create mode 100644 configurations/woo-elastic/synchronizations/publication-to-elastic.json create mode 100644 configurations/xxllnc-zgw/mappings/zgw-zaak-to-xxllnc-v1-case.json create mode 100644 configurations/xxllnc-zgw/mappings/zgw-zaakinformatieobject-to-xxllnc-file.json create mode 100644 configurations/xxllnc-zgw/synchronizations/zgw-zaak-to-xxllnc-case.json diff --git a/configurations/woo-elastic/mappings/publication-to-elastic.json b/configurations/woo-elastic/mappings/publication-to-elastic.json new file mode 100644 index 00000000..24f4117f --- /dev/null +++ b/configurations/woo-elastic/mappings/publication-to-elastic.json @@ -0,0 +1,21 @@ +{ + "name": "Publication to Elastic", + "description": "", + "version": "0.0.1", + "mapping": { + "doctype": "{% if categorie is defined and categorie == 'Convenanten' %}{{ categorie }}{% else %}OpenWOO{% endif %}", + "title": "{{ titel | default('') }}", + "excerpt": "{{ samenvatting | default('') }}", + "date": "{{ publicatiedatum | default('') }}", + "link": "/openwoo/{{ titel | lower | strip_tags | preg_replace('/[^a-z0-9\\s-]/', '') | preg_replace('/[\\s-]+/', '-') | trim('-', '-') }}", + "content_filtered": "{{ beschrijving | default('') }}" + }, + "unset": [], + "cast": { + "title": "unsetIfValue==", + "excerpt": "unsetIfValue==", + "date": "unsetIfValue==", + "content_filtered": "unsetIfValue==" + }, + "passThrough": true +} diff --git a/configurations/woo-elastic/sources/elastic.json b/configurations/woo-elastic/sources/elastic.json new file mode 100644 index 00000000..c899adfa --- /dev/null +++ b/configurations/woo-elastic/sources/elastic.json @@ -0,0 +1,22 @@ +{ + "name": "Elastic API", + "description": "Elastic API", + "reference": null, + "version": "0.0.1", + "location": "", + "isEnabled": true, + "type": "api", + "authorizationHeader": "Authorization", + "auth": "none", + "authorizationPassthroughMethod": "header", + "authenticationConfig": [], + "configuration": { + "headers": { + "Authorization": "ApiKey ..", + "Content-Type": "application/json" + } + }, + "logRetention": 3600, + "errorRetention": 86400, + "test": false +} \ No newline at end of file diff --git a/configurations/woo-elastic/synchronizations/publication-to-elastic.json b/configurations/woo-elastic/synchronizations/publication-to-elastic.json new file mode 100644 index 00000000..ab3e68bd --- /dev/null +++ b/configurations/woo-elastic/synchronizations/publication-to-elastic.json @@ -0,0 +1,17 @@ +{ + "name": "Publication to Elastic", + "description": "This config might be currently incomplete", + "version": "0.0.1", + "sourceId": "1/1", + "sourceType": "register/schema", + "sourceHash": "", + "sourceTargetMapping": "1", + "targetConfig": { + "idPosition": "_id", + "endpoint": "/_doc", + "headers": [], + "query": [] + }, + "targetId": "1", + "targetType": "api" +} \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json index 599f8284..52881f0f 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json @@ -2,6 +2,7 @@ "name": "Xxllnc Case to ZGW Zaak", "version": "0.0.1", "mapping": { + "originId": "reference", "identificatie": "reference", "omschrijving": "instance.subject", "toelichting": "instance.subject_external", @@ -52,7 +53,8 @@ "kenmerken.0.kenmerk": "unsetIfValue==reference", "resultaattoelichting": "unsetIfValue==", "bronorganisatie": "unsetIfValue==bronorganisatie", - "verantwoordelijkeOrganisatie": "unsetIfValue==bronorganisatie" + "verantwoordelijkeOrganisatie": "unsetIfValue==bronorganisatie", + "originId": "unsetIfValue==reference" }, "passTrough": false } \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json index d49c157f..1ef86912 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json @@ -2,6 +2,7 @@ "name": "Xxllnc Casetype to ZGW ZaakType", "version": "0.0.1", "mapping": { + "originId": "reference", "identificatie": "instance.legacy.zaaktype_id", "catalogus": "_catalogus", "onderwerp": "instance.title", @@ -46,7 +47,8 @@ "bronzaaktype.omschrijving": "unsetIfValue==instance.title", "bronzaaktype.naam": "unsetIfValue==preview", "referentieproces.naam": "unsetIfValue==preview", - "verantwoordelijke": "unsetIfValue==instance.properties.supervisor" + "verantwoordelijke": "unsetIfValue==instance.properties.supervisor", + "originId": "unsetIfValue==reference" }, "passTrough": false } \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/zgw-zaak-to-xxllnc-v1-case.json b/configurations/xxllnc-zgw/mappings/zgw-zaak-to-xxllnc-v1-case.json new file mode 100644 index 00000000..c6b212f4 --- /dev/null +++ b/configurations/xxllnc-zgw/mappings/zgw-zaak-to-xxllnc-v1-case.json @@ -0,0 +1,23 @@ +{ + "name": "ZGW Zaak to Xxllnc Case", + "version": "0.0.1", + "mapping": { + "casetype_id": "{% if zaaktype.originId|default %}{{ zaaktype.originId }}{% endif %}", + "source": "behandelaar", + "date_of_registration": "{{ 'now'|date('Y-m-dTH:i:sZ') }}", + "confidentiality": "public", + "requestor.id": "{{ zaakArrayObject.rollen[0].betrokkeneIdentificatie.inpBsn ?? zaakArrayObject.verantwoordelijkeOrganisatie ?? '' }}", + "requestor.type": "{% if zaakArrayObject.rollen[0].betrokkeneIdentificatie.inpBsn|default or zaakArrayObject.verantwoordelijkeOrganisatie|default %}person{% endif %}", + "files": "[{% set index = 0 %}{% for infoObject in thiswontwork %}{% if index > 0 %}, {% endif %}{{ executeMapping(1, infoObject)|json_encode }}{% set index = index + 1 %}{% endfor %}]", + "values": "{ {% set index = 0 %}{% for zaakEigenschap in eigenschappen %}{% if zaakEigenschap.eigenschap.naam|default %}{% if index > 0 %}, {% endif %}\"{{ zaakEigenschap.eigenschap.naam }}\":{% if zaakEigenschap.eigenschap.waarde|default and zaakEigenschap.eigenschap.specificatie.formaat|default and zaakEigenschap.eigenschap.specificatie.formaat == 'checkbox' %}[[\"{{ zaakEigenschap.eigenschap.waarde }}\"]]{% else %}[\"{{ zaakEigenschap.waarde }}\"]{% endif %}{% set index = index + 1 %}{% endif %}{% endfor %} }" + }, + "unset": [], + "cast": { + "files": "jsonToArray", + "values": "jsonToArray", + "requestor.id": "unsetIfValue==", + "requestor.type": "unsetIfValue==", + "requestor": "unsetIfValue==" + }, + "passTrough": false +} \ No newline at end of file diff --git a/configurations/xxllnc-zgw/mappings/zgw-zaakinformatieobject-to-xxllnc-file.json b/configurations/xxllnc-zgw/mappings/zgw-zaakinformatieobject-to-xxllnc-file.json new file mode 100644 index 00000000..63e28407 --- /dev/null +++ b/configurations/xxllnc-zgw/mappings/zgw-zaakinformatieobject-to-xxllnc-file.json @@ -0,0 +1,26 @@ +{ + "name": "ZGW ZaakInformatieObject to Xxllnc File", + "version": "0.0.1", + "mapping": { + "reference": "xxllncReferenceId", + "type": "metadata", + "name": "titel", + "number": "xxllncDocumentNumber", + "metadata.type": "metadata", + "metadata.instance.appearance": "informatieobject.bestandsnaam", + "metadata.instance.description": "informatieobject.beschrijving", + "metadata.instance.origin": "Inkomend", + "metadata.instance.origin_date": "informatieobject.creatiedatum", + "metadata.instance.pronom_format": "informatieobject.formaat", + "metadata.instance.structure": "text", + "metadata.instance.trust_level": "{% if integriteit.waarde|default %}{{ integriteit.waarde }}{% else %}Openbaar{% endif %}", + "metadata.instance.status": "original", + "metadata.instance.creation_date": "informatieobject.creatiedatum" + }, + "unset": [], + "cast": { + "files": "jsonToArray", + "values": "jsonToArray" + }, + "passTrough": false +} \ No newline at end of file diff --git a/configurations/xxllnc-zgw/synchronizations/zgw-zaak-to-xxllnc-case.json b/configurations/xxllnc-zgw/synchronizations/zgw-zaak-to-xxllnc-case.json new file mode 100644 index 00000000..5fa4369a --- /dev/null +++ b/configurations/xxllnc-zgw/synchronizations/zgw-zaak-to-xxllnc-case.json @@ -0,0 +1,39 @@ +{ + "name": "ZGW Zaak to Xxllnc Case", + "description": "", + "version": "0.0.1", + "sourceId": "1/1", + "sourceType": "register\/schema", + "sourceHash": "", + "sourceHashMapping": "", + "sourceTargetMapping": "1", + "sourceConfig": {}, + "currentPage": 1, + "targetId": "1", + "targetType": "api", + "targetHash": "", + "targetSourceMapping": "", + "targetConfig": { + "endpoint": "/case/create", + "updateEndpoint": "/case/{{ originId }}/update", + "idPosition": "reference", + "resultsPosition": "result" + }, + "followUps": [], + "conditions": { + "and": [ + { + "!": { "has": [ { "var": "" }, "originId" ] } + }, + { + "!": { "!!": { "var": "originId" } } + }, + { + "and": [ + { "has": [ { "var": "zaaktype" }, "originId" ] }, + { "!!": { "var": "zaaktype.originId" } } + ] + } + ] + } +} \ No newline at end of file From b8115cd3e863cd2d21a213484d6caceb578426b9 Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Thu, 16 Jan 2025 01:52:52 +0100 Subject: [PATCH 7/9] added updating sub objects and sub contracts --- lib/Db/SynchronizationContractMapper.php | 29 ++++ lib/Service/SynchronizationService.php | 203 ++++++++++++++++++++++- 2 files changed, 230 insertions(+), 2 deletions(-) diff --git a/lib/Db/SynchronizationContractMapper.php b/lib/Db/SynchronizationContractMapper.php index 227ef839..afad9e72 100644 --- a/lib/Db/SynchronizationContractMapper.php +++ b/lib/Db/SynchronizationContractMapper.php @@ -117,6 +117,35 @@ public function findOnTarget(string $synchronization, string $targetId): Synchro } } + /** + * Find a synchronization contract by origin ID and target ID + * + * @param string $originId The origin ID + * @param string $targetId The target ID + * @return SynchronizationContract|bool|null The found contract, false, or null if not found + */ + public function findByOriginAndTarget(string $originId, string $targetId): SynchronizationContract|bool|null + { + // Create query builder + $qb = $this->db->getQueryBuilder(); + + // Build select query with synchronization and target ID filters + $qb->select('*') + ->from('openconnector_synchronization_contracts') + ->where( + $qb->expr()->eq('origin_id', $qb->createNamedParameter($originId)) + ) + ->andWhere( + $qb->expr()->eq('target_id', $qb->createNamedParameter($targetId)) + ); + + try { + return $this->findEntity($qb); + } catch (\OCP\AppFramework\Db\DoesNotExistException $e) { + return null; + } + } + /** * Find all target IDs of synchronization contracts by synchronization ID * diff --git a/lib/Service/SynchronizationService.php b/lib/Service/SynchronizationService.php index b143271e..1341066f 100644 --- a/lib/Service/SynchronizationService.php +++ b/lib/Service/SynchronizationService.php @@ -96,6 +96,8 @@ public function __construct( */ public function synchronize(Synchronization $synchronization, ?bool $isTest = false): array { + $sourceConfig = $this->callService->applyConfigDot($synchronization->getSourceConfig()); + if (empty($synchronization->getSourceId()) === true) { $log = [ 'synchronizationId' => $synchronization->getId(), @@ -172,7 +174,10 @@ public function synchronize(Synchronization $synchronization, ?bool $isTest = fa $synchronizedTargetIds[] = $synchronizationContract->getTargetId(); } - $this->deleteInvalidObjects(synchronization: $synchronization, synchronizedTargetIds: $synchronizedTargetIds); + if (isset($sourceConfig['deleteInvalidObjects']) === false || + (isset($sourceConfig['deleteInvalidObjects']) === true && $sourceConfig['deleteInvalidObjects'] === true && $sourceConfig['deleteInvalidObjects'] !== 'true')) { + $this->deleteInvalidObjects(synchronization: $synchronization, synchronizedTargetIds: $synchronizedTargetIds); + } // @todo log deleted objects count @@ -347,7 +352,7 @@ private function fetchExtraDataForObject(Synchronization $synchronization, array $sourceConfig = $synchronization->getSourceConfig(); if (isset($extraDataConfig[$this::UNSET_CONFIG_KEY_LOCATION]) === true && isset($sourceConfig[$extraDataConfig[$this::UNSET_CONFIG_KEY_LOCATION]]) === true) { - unset($sourceConfig[$extraDataConfig[$this::UNSET_CONFIG_KEY_LOCATION]]); + unset($sourceConfig[$extraDataConfig[$this::UNSET_CONFIG_KEY_LOCATION]]); $synchronization->setSourceConfig($sourceConfig); } @@ -467,6 +472,9 @@ public function deleteInvalidObjects(Synchronization $synchronization, array $sy foreach ($targetIdsToDelete as $targetIdToDelete) { try { $synchronizationContract = $this->synchronizationContractMapper->findOnTarget(synchronization: $synchronization->getId(), targetId: $targetIdToDelete); + if ($synchronizationContract === null) { + continue; + } $synchronizationContract = $this->updateTarget(synchronizationContract: $synchronizationContract, targetObject: [], action: 'delete'); $this->synchronizationContractMapper->update($synchronizationContract); $deletedObjectsCount++; @@ -605,12 +613,17 @@ private function updateTargetOpenRegister(SynchronizationContract $synchronizati { // Setup the object service $objectService = $this->containerInterface->get('OCA\OpenRegister\Service\ObjectService'); + $sourceConfig = $this->callService->applyConfigDot($synchronization->getSourceConfig()); // if we already have an id, we need to get the object and update it if ($synchronizationContract->getTargetId() !== null) { $targetObject['id'] = $synchronizationContract->getTargetId(); } + if (isset($sourceConfig['subObjects']) === true) { + $targetObject = $this->updateIdsOnSubObjects(subObjectsConfig: $sourceConfig['subObjects'], synchronizationId: $synchronization->getId(), targetObject: $targetObject); + } + // Extract register and schema from the targetId // The targetId needs to be filled in as: {registerId} + / + {schemaId} for example: 1/1 $targetId = $synchronization->getTargetId(); @@ -622,6 +635,13 @@ private function updateTargetOpenRegister(SynchronizationContract $synchronizati $target = $objectService->saveObject($register, $schema, $targetObject); // Get the id form the target object $synchronizationContract->setTargetId($target->getUuid()); + + // Handle sub-objects synchronization if sourceConfig is defined + if (isset($sourceConfig['subObjects']) === true) { + $targetObject = $objectService->extendEntity($target->jsonSerialize(), ['all']); + $this->updateContractsForSubObjects(subObjectsConfig: $sourceConfig['subObjects'], synchronizationId: $synchronization->getId(), targetObject: $targetObject); + } + break; case 'delete': $objectService->deleteObject(register: $register, schema: $schema, uuid: $synchronizationContract->getTargetId()); @@ -632,6 +652,185 @@ private function updateTargetOpenRegister(SynchronizationContract $synchronizati return $synchronizationContract; } + /** + * Handles the synchronization of subObjects based on source configuration. + * + * @param array $subObjectsConfig The configuration for subObjects. + * @param string $synchronizationId The ID of the synchronization. + * @param array $targetObject The target object containing subObjects to be processed. + * + * @return void + */ + private function updateContractsForSubObjects(array $subObjectsConfig, string $synchronizationId, array $targetObject): void + { + foreach ($subObjectsConfig as $propertyName => $subObjectConfig) { + if (isset($targetObject[$propertyName]) === false) { + continue; + } + + $propertyData = $targetObject[$propertyName]; + + // If property data is an array of subObjects, iterate and process + if (is_array($propertyData) && $this->isAssociativeArray($propertyData)) { + if (isset($propertyData['originId'])) { + $this->processSyncContract($synchronizationId, $propertyData); + } + + // Recursively process any nested subObjects within the associative array + foreach ($propertyData as $key => $value) { + if (is_array($value) === true && isset($subObjectConfig['subObjects']) === true) { + $this->updateContractsForSubObjects($subObjectConfig['subObjects'], $synchronizationId, [$key => $value]); + } + } + } + + // Process if it's an indexed array (list) of associative arrays + if (is_array($propertyData) === true && !$this->isAssociativeArray($propertyData)) { + foreach ($propertyData as $subObjectData) { + if (is_array($subObjectData) === true && isset($subObjectData['originId']) === true) { + $this->processSyncContract($synchronizationId, $subObjectData); + } + + // Recursively process nested sub-objects + if (is_array($subObjectData) === true && isset($subObjectConfig['subObjects']) === true) { + $this->updateContractsForSubObjects($subObjectConfig['subObjects'], $synchronizationId, $subObjectData); + } + } + } + } + } + /** + * Processes a single synchronization contract for a subObject. + * + * @param string $synchronizationId The ID of the synchronization. + * @param array $subObjectData The data of the subObject to process. + * + * @return void + */ + private function processSyncContract(string $synchronizationId, array $subObjectData): void + { + $id = $subObjectData['id']['id']['id']['id'] ?? $subObjectData['id']['id']['id'] ?? $subObjectData['id']['id'] ?? $subObjectData['id']; + $subContract = $this->synchronizationContractMapper->findByOriginId( + originId: $subObjectData['originId'] + ); + + if (!$subContract) { + $subContract = new SynchronizationContract(); + $subContract->setSynchronizationId($synchronizationId); + $subContract->setOriginId($subObjectData['originId']); + $subContract->setTargetId($id); + $subContract->setUuid(Uuid::V4()); + $subContract->setTargetHash(md5(serialize($subObjectData))); + $subContract->setTargetLastChanged(new DateTime()); + $subContract->setTargetLastSynced(new DateTime()); + $subContract->setSourceLastSynced(new DateTime()); + + $subContract = $this->synchronizationContractMapper->insert($subContract); + } else { + $subContract = $this->synchronizationContractMapper->updateFromArray( + id: $subContract->getId(), + object: [ + 'synchronizationId' => $synchronizationId, + 'originId' => $subObjectData['originId'], + 'targetId' => $id, + 'targetHash' => md5(serialize($subObjectData)), + 'targetLastChanged' => new DateTime(), + 'targetLastSynced' => new DateTime(), + 'sourceLastSynced' => new DateTime() + ] + ); + } + + $this->synchronizationContractLogMapper->createFromArray([ + 'synchronizationId' => $subContract->getSynchronizationId(), + 'synchronizationContractId' => $subContract->getId(), + 'target' => $subObjectData, + 'expires' => new DateTime('+1 day') + ]); + } + + /** + * Checks if an array is associative. + * + * @param array $array The array to check. + * + * @return bool True if the array is associative, false otherwise. + */ + private function isAssociativeArray(array $array): bool + { + // Check if the array is associative + return count(array_filter(array_keys($array), 'is_string')) > 0; + } + + /** + * Processes subObjects update their arrays with existing targetId's so OpenRegister can update the objects instead of duplicate them. + * + * @param array $subObjectsConfig The configuration for subObjects. + * @param string $synchronizationId The ID of the synchronization. + * @param array $targetObject The target object containing subObjects to be processed. + * @param bool|null $parentIsNumericArray Whether the parent object is a numeric array (default false). + * + * @return array The updated target object with IDs updated on subObjects. + */ + private function updateIdsOnSubObjects(array $subObjectsConfig, string $synchronizationId, array $targetObject, ?bool $parentIsNumericArray = false): array + { + foreach ($subObjectsConfig as $propertyName => $subObjectConfig) { + if (isset($targetObject[$propertyName]) === false) { + continue; + } + + // If property data is an array of sub-objects, iterate and process + if (is_array($targetObject[$propertyName]) === true) { + if (isset($targetObject[$propertyName]['originId']) === true) { + $targetObject[$propertyName] = $this->updateIdOnSubObject($synchronizationId, $targetObject[$propertyName]); + } + + // Recursively process any nested sub-objects within the associative array + foreach ($targetObject[$propertyName] as $key => $value) { + if (is_array($value) === true && isset($subObjectConfig['subObjects'][$key]) === true) { + if ($this->isAssociativeArray($value) === true) { + $targetObject[$propertyName][$key] = $this->updateIdsOnSubObjects($subObjectConfig['subObjects'], $synchronizationId, [$key => $value]); + } elseif (is_array($value) === true && $this->isAssociativeArray(reset($value)) === true) { + foreach ($value as $iterativeSubArrayKey => $iterativeSubArray) { + $targetObject[$propertyName][$key][$iterativeSubArrayKey] = $this->updateIdsOnSubObjects($subObjectConfig['subObjects'], $synchronizationId, [$key => $iterativeSubArray], true); + } + } + } + } + } + } + + if ($parentIsNumericArray === true) { + return reset($targetObject); + } + + return $targetObject; + } + + /** + * Updates the ID of a single subObject based on its synchronization contract so OpenRegister can update the object . + * + * @param string $synchronizationId The ID of the synchronization. + * @param array $subObject The subObject to update. + * + * @return array The updated subObject with the ID set based on the synchronization contract. + */ + private function updateIdOnSubObject(string $synchronizationId, array $subObject): array + { + if (isset($subObject['originId']) === true) { + $subObjectContract = $this->synchronizationContractMapper->findSyncContractByOriginId( + synchronizationId: $synchronizationId, + originId: $subObject['originId'] + ); + + if ($subObjectContract !== null) { + $subObject['id'] = $subObjectContract->getTargetId(); + } + } + + return $subObject; + } + /** * Write the data to the target * From 44824033a88b763fed6abf634f59572904280074 Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Thu, 16 Jan 2025 01:53:10 +0100 Subject: [PATCH 8/9] config updates --- .../xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json | 1 + .../mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json | 3 ++- .../xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json | 2 ++ .../synchronizations/xxllnc-zoek-endpoint-to-publications.json | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json index 52881f0f..5143ad57 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-case-to-zgw-zaak.json @@ -3,6 +3,7 @@ "version": "0.0.1", "mapping": { "originId": "reference", + "_sourceId": "reference", "identificatie": "reference", "omschrijving": "instance.subject", "toelichting": "instance.subject_external", diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json index 1ef86912..736a64be 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-casetype-to-zgw-zaaktype.json @@ -3,6 +3,7 @@ "version": "0.0.1", "mapping": { "originId": "reference", + "_sourceId": "reference", "identificatie": "instance.legacy.zaaktype_id", "catalogus": "_catalogus", "onderwerp": "instance.title", @@ -19,7 +20,7 @@ "bronzaaktype.omschrijving": "instance.title", "referentieproces.naam": "preview", "verantwoordelijke": "instance.properties.supervisor", - "statustypen": "[{% for phase in instance.phases %}{% if not loop.first %},{% endif %}{{ executeMapping(8, phase)|json_encode }}{% endfor %}]", + "statustypen": "[{% for phase in instance.phases %}{% if not loop.first %},{% endif %}{% set phase = phase|merge({'casetypeReference': reference}) %}{{ executeMapping(8, phase)|json_encode }}{% endfor %}]", "informatieobjecttypen": "[{% set index=0 %}{% for phase in instance.phases %}{% for field in phase.fields %}{% if field.type == 'file' %}{% if index != 0 %},{% endif %}{{ executeMapping(9, field)|json_encode }}{% set index=index+1 %}{% endif %}{% endfor %}{% endfor %}]", "eigenschappen": "[{% set index=0 %}{% for phase in instance.phases %}{% for field in phase.fields %}{% if field.type != 'file' %}{% if index != 0 %},{% endif %}{{ executeMapping(10, field)|json_encode }}{% set index=index+1 %}{% endif %}{% endfor %}{% endfor %}]", "roltypen": "[{% set index=0 %}{% for phase in instance.phases %}{% if phase.route.role|default %}{% set role = phase.route.role %}{% if index != 0 %},{% endif %}{{ executeMapping(11, role)|json_encode }}{% set index=index+1 %}{% endif %}{% endfor %}]", diff --git a/configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json b/configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json index 5335b9ab..92b89871 100644 --- a/configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json +++ b/configurations/xxllnc-zgw/mappings/xxllnc-v1-phase-to-zgw-statustype.json @@ -2,6 +2,7 @@ "name": "Xxllnc Phase to ZGW StatusType", "version": "0.0.1", "mapping": { + "_sourceId": "{% if fields.0.label|default and casetypeReference|default %}{{ casetypeReference~fields.0.label }}{% endif %}", "volgnummer": "seq", "omschrijving": "name", "omschrijvingGeneriek": "{% if fields.0.label|default %}{{ fields.0.label }}{% else %}geen statustekst{% endif %}", @@ -11,6 +12,7 @@ }, "unset": [], "cast": { + "_sourceId": "unsetIfValue==", "volgnummer": "unsetIfValue==seq", "omschrijving": "unsetIfValue==name", "catalogus": "unsetIfValue==_catalogus", diff --git a/configurations/xxllnc-zoekendpoint-woo/synchronizations/xxllnc-zoek-endpoint-to-publications.json b/configurations/xxllnc-zoekendpoint-woo/synchronizations/xxllnc-zoek-endpoint-to-publications.json index e89bd7c4..35be006f 100644 --- a/configurations/xxllnc-zoekendpoint-woo/synchronizations/xxllnc-zoek-endpoint-to-publications.json +++ b/configurations/xxllnc-zoekendpoint-woo/synchronizations/xxllnc-zoek-endpoint-to-publications.json @@ -9,6 +9,7 @@ "idPosition": "id", "resultsPosition": "result", "endpoint": "/public_search/x/search", + "deleteInvalidObjects": "false", "headers": [], "query": [] }, From 8e28781397c6d484a5f3a4186714f983a0a488ca Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Thu, 16 Jan 2025 09:49:32 +0100 Subject: [PATCH 9/9] fix if statement --- lib/Service/SynchronizationService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Service/SynchronizationService.php b/lib/Service/SynchronizationService.php index 1341066f..e2d19361 100644 --- a/lib/Service/SynchronizationService.php +++ b/lib/Service/SynchronizationService.php @@ -175,7 +175,7 @@ public function synchronize(Synchronization $synchronization, ?bool $isTest = fa } if (isset($sourceConfig['deleteInvalidObjects']) === false || - (isset($sourceConfig['deleteInvalidObjects']) === true && $sourceConfig['deleteInvalidObjects'] === true && $sourceConfig['deleteInvalidObjects'] !== 'true')) { + (isset($sourceConfig['deleteInvalidObjects']) === true && ($sourceConfig['deleteInvalidObjects'] === true || $sourceConfig['deleteInvalidObjects'] === 'true'))) { $this->deleteInvalidObjects(synchronization: $synchronization, synchronizedTargetIds: $synchronizedTargetIds); } // @todo log deleted objects count