From 415fa1792c8504842ef6efd8076db1dd1279eee0 Mon Sep 17 00:00:00 2001 From: joerivrij Date: Tue, 22 Aug 2023 12:49:14 +0200 Subject: [PATCH] Production release to version v1.5.0 (#272) * removed: unmutable put/patch validation on zaaktype * removed: unit test unmutable put/patch validation on zaaktype * Adds cicd pipeline with develop branch (#269) * Issue/#2192 inclusions (#267) **Enhancements, Bug Fixes, and Code Refactoring** - **Added:** Extension of list call functionality to accept expand parameters for enriched data retrieval. - **Added:** Introduction of 'ExpandField' class to manage and process expand parameters. - **Added:** 'Inclusion' class to facilitate data inclusion and enhance response customization. - **Added:** Method for building inclusion schemas. - **Added:** Recursion logic in later stages to support nested data inclusion. - **Added:** 'Inclusions' class for streamlined management of included external API calls. - **Added:** External API calls within the 'Inclusions' class for comprehensive data integration. - **Added:** Clear and descriptive text to the expand filter for better understanding. - **Added:** Validation mechanism and resolved issues with external API calls within 'Inclusions'. - **Added:** Regex validator to enhance input validation. - **Added:** Explanation regarding the use of regex validation. - **Added:** Support for nested dictionary types like 'relevante_andere_zaken' in the expansions model. - **Added:** Integration of the 'expand' feature into the OpenAPI Specification (OAS) and expanded GET detail endpoints. - **Changed:** Hard-coded mappings from 'expensions.py' for increased flexibility. - **Changed:** Relocated 'routers' import into a function to address circular import concerns. - **Changed:** Reworked the expansions model to resolve previous errors and improve reliability. - **Changed:** Various issues related to specific problem reports: #2280, #2279, #2269, #2270, #2271, #2288, #2287. - **Changed:** Updated OAS description and resolved a bug in the expansions. - **Updated:** Requirements files, including 'psyopg2' for proper functionality. These changes encompass a wide range of enhancements, bug fixes, and code clean-up, significantly improving the functionality, stability, and maintainability of the system. The introduction of expand parameters, 'ExpandField' class, 'Expand' class, and various bug fixes contribute to a more robust and efficient system. * Production release to version v1.5.0 (#271) --------- Co-authored-by: matthijsbekendam Co-authored-by: MatthijsBekendam <47739550+MatthijsBekendam@users.noreply.github.com> --- .bumpversion.cfg | 2 +- .github/workflows/ci.yml | 2 + CHANGELOG.rst | 36 +- INSTALL.rst | 2 +- README.rst | 6 +- package.json | 2 +- src/__init__.py | 0 src/openapi.yaml | 1066 +++++++++----------- src/zrc/api/expansions.py | 648 ++++++++++++ src/zrc/api/filters.py | 18 + src/zrc/api/serializers/core.py | 1 - src/zrc/api/tests/test_dso_api_strategy.py | 2 +- src/zrc/api/tests/test_validation.py | 13 - src/zrc/api/tests/test_zaken.py | 166 +++ src/zrc/api/utils.py | 5 +- src/zrc/api/viewsets.py | 5 +- src/zrc/conf/includes/api.py | 6 +- src/zrc/sync/signals.py | 1 - 18 files changed, 1375 insertions(+), 606 deletions(-) create mode 100644 src/__init__.py create mode 100644 src/zrc/api/expansions.py diff --git a/.bumpversion.cfg b/.bumpversion.cfg index cc0c7ac1..6352dcdc 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = False tag = False -current_version = 1.4.0 +current_version = 1.5.0 parse = (?P\d+)\.(?P\d+)\.(?P\d+)([-](?P(rc|alpha))+(?P\d+))? serialize = {major}.{minor}.{patch}-{release}{build} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5c1eaa8..a2062aa2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,8 +4,10 @@ on: push: branches: - "stable/*" + - "develop" pull_request: branches: + - "develop" - "master" env: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c5959b62..8ffd8cf1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,41 @@ =========== Wijzigingen =========== -1.4.0 (2022-03-27) +1.5.0 (2023-08-22) +=========== + +Implementation changes +---------------------- + +`Issue 2192`_: + +**Enhancements, Bug Fixes, and Code Refactoring** + +- **Added:** Extension of list call functionality to accept expand parameters for enriched data retrieval. +- **Added:** Introduction of 'ExpandField' class to manage and process expand parameters. +- **Added:** 'Inclusion' class to facilitate data inclusion and enhance response customization. +- **Added:** Method for building inclusion schemas. +- **Added:** Recursion logic in later stages to support nested data inclusion. +- **Added:** 'Inclusions' class for streamlined management of included external API calls. +- **Added:** External API calls within the 'Inclusions' class for comprehensive data integration. +- **Added:** Clear and descriptive text to the expand filter for better understanding. +- **Added:** Validation mechanism and resolved issues with external API calls within 'Inclusions'. +- **Added:** Regex validator to enhance input validation. +- **Added:** Explanation regarding the use of regex validation. +- **Added:** Support for nested dictionary types like 'relevante_andere_zaken' in the expansions model. +- **Added:** Integration of the 'expand' feature into the OpenAPI Specification (OAS) and expanded GET detail endpoints. +- **Changed:** Hard-coded mappings from 'expensions.py' for increased flexibility. +- **Changed:** Relocated 'routers' import into a function to address circular import concerns. +- **Changed:** Reworked the expansions model to resolve previous errors and improve reliability. +- **Changed:** Various issues related to specific problem reports: #2280, #2279, #2269, #2270, #2271, #2288, #2287. +- **Changed:** Updated OAS description and resolved a bug in the expansions. +- **Updated:** Requirements files, including 'psyopg2' for proper functionality. + +These changes encompass a wide range of enhancements, bug fixes, and code clean-up, significantly improving the functionality, stability, and maintainability of the system. The introduction of expand parameters, 'ExpandField' class, 'Expand' class, and various bug fixes contribute to a more robust and efficient system. + +.. _Issue 2192: https://github.com/VNG-Realisatie/gemma-zaken/issues/2192 + +1.4.0 (2023-03-27) =========== Implementation changes diff --git a/INSTALL.rst b/INSTALL.rst index 94734833..fff7018c 100644 --- a/INSTALL.rst +++ b/INSTALL.rst @@ -1,4 +1,4 @@ -============ +pip============ Installation ============ diff --git a/README.rst b/README.rst index 10d16912..2aa5a4e5 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,7 @@ Zaken API ========= -:Version: 1.4.0 +:Version: 1.5.0 :Source: https://github.com/VNG-Realisatie/zaken-api :Keywords: zaken, zaakgericht werken, GEMMA, RGBZ, ZRC @@ -16,14 +16,14 @@ zaken moeten ergens geregistreerd worden en opvraagbaar zijn. API specificaties ================= -|lint-oas| |generate-sdks| |generate-postman-collection| - ========== ============== ==================================================================================================================================================================================================== ======================================================================================================================= ================================================================================================================================= Versie Release datum API specificatie Autorisaties Notificaties ========== ============== ==================================================================================================================================================================================================== ======================================================================================================================= ================================================================================================================================= master n.v.t. `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ `Swagger `_ (`verschillen `_) +1.5.0 2023-08-22 `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ + `Swagger `_ 1.4.0 2023-03-27 `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ `Swagger `_ (`verschillen `_) diff --git a/package.json b/package.json index 9372e778..c37e37c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zrc", - "version": "1.4.0", + "version": "1.5.0", "description": "zrc referentie implementatie API", "directories": { "doc": "doc" diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/openapi.yaml b/src/openapi.yaml index 928cc0cc..9526e977 100644 --- a/src/openapi.yaml +++ b/src/openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: title: Zaken API - version: 1.4.0 + version: 1.5.0 description: "Een API om een zaakregistratiecomponent (ZRC) te benaderen. @@ -12,11 +12,6 @@ info: Zaakgericht werken om tot volledige functionaliteit te komen. - **Wat is nieuw?** - - * Query parameters en zoekvelden voor archivering. - - **Afhankelijkheden** @@ -2731,7 +2726,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/StatusRequestbody' + $ref: '#/components/schemas/Status' description: Created '400': headers: @@ -6551,7 +6546,6 @@ paths: verantwoordelijk is voor de behandeling van de ZAAK. schema: type: string - example: "zaak123" - name: bronorganisatie required: false in: query @@ -6561,7 +6555,6 @@ paths: en voldoen aan https://nl.wikipedia.org/wiki/Burgerservicenummer#11-proef schema: type: string - example: "000000000" - name: bronorganisatie__in required: false in: query @@ -6570,7 +6563,6 @@ paths: type: array items: type: string - example: ["000000000","479559740","875883461"] style: form explode: false - name: zaaktype @@ -6582,7 +6574,6 @@ paths: schema: type: string format: uri - example: "https://catalogi-api.test.vng.cloud/api/v1/zaaktypen/e80b7507-199a-484c-ad49-c41a1e43a6e7" - name: archiefnominatie required: false in: query @@ -6594,7 +6585,6 @@ paths: enum: - blijvend_bewaren - vernietigen - example: "blijvend_bewaren" - name: archiefnominatie__in required: false in: query @@ -6603,7 +6593,6 @@ paths: type: array items: type: string - example: ["blijvend_bewaren", "vernietigen"] style: form explode: false - name: archiefactiedatum @@ -6616,28 +6605,36 @@ paths: deze ZAAK indien nog leeg. schema: type: string - example: "2019-01-02" - - name: archiefactiedatum__isnull + - name: archiefactiedatum__lt required: false in: query - description: De archiefactiedatum is leeg. + description: + De datum waarop het gearchiveerde zaakdossier vernietigd moet + worden dan wel overgebracht moet worden naar een archiefbewaarplaats. Wordt + automatisch berekend bij het aanmaken of wijzigen van een RESULTAAT aan + deze ZAAK indien nog leeg. schema: - type: boolean - example: false - - name: archiefactiedatum__lt + type: string + - name: archiefactiedatum__gt required: false in: query - description: De archiefactiedatum is kleiner dan de opgegeven datum. + description: + De datum waarop het gearchiveerde zaakdossier vernietigd moet + worden dan wel overgebracht moet worden naar een archiefbewaarplaats. Wordt + automatisch berekend bij het aanmaken of wijzigen van een RESULTAAT aan + deze ZAAK indien nog leeg. schema: type: string - example: "2020-01-02" - - name: archiefactiedatum__gt + - name: archiefactiedatum__isnull required: false in: query - description: De archiefactiedatum is groter dan de opgegeven datum. + description: + De datum waarop het gearchiveerde zaakdossier vernietigd moet + worden dan wel overgebracht moet worden naar een archiefbewaarplaats. Wordt + automatisch berekend bij het aanmaken of wijzigen van een RESULTAAT aan + deze ZAAK indien nog leeg. schema: type: string - example: "2018-01-02" - name: archiefstatus required: false in: query @@ -6651,7 +6648,6 @@ paths: - gearchiveerd - gearchiveerd_procestermijn_onbekend - overgedragen - example: "nog_te_archiveren" - name: archiefstatus__in required: false in: query @@ -6660,7 +6656,6 @@ paths: type: array items: type: string - example: ["nog_te_archiveren","gearchiveerd","gearchiveerd_procestermijn_onbekend","overgedragen"] style: form explode: false - name: startdatum @@ -6669,35 +6664,30 @@ paths: description: De datum waarop met de uitvoering van de zaak is gestart schema: type: string - example: "2017-01-02" - name: startdatum__gt required: false in: query - description: De startdatum is groter dan de opgegeven datum. + description: De datum waarop met de uitvoering van de zaak is gestart schema: type: string - example: "2018-01-02" - name: startdatum__gte required: false in: query - description: De startdatum is groter dan of gelijk dan de opgegeven datum. + description: De datum waarop met de uitvoering van de zaak is gestart schema: type: string - example: "2016-01-02" - name: startdatum__lt required: false in: query - description: De startdatum is kleiner dan de opgegeven datum. + description: De datum waarop met de uitvoering van de zaak is gestart schema: type: string - example: "2018-01-02" - name: startdatum__lte required: false in: query - description: De startdatum is kleiner of gelijk dan de opgegeven datum. + description: De datum waarop met de uitvoering van de zaak is gestart schema: type: string - example: "2018-01-02" - name: registratiedatum required: false in: query @@ -6707,51 +6697,48 @@ paths: gebruikt. schema: type: string - example: "2015-01-02" - name: registratiedatum__gt required: false in: query description: - De registratiedatum is groter dan de opgegeven datum. + De datum waarop de zaakbehandelende organisatie de ZAAK heeft + geregistreerd. Indien deze niet opgegeven wordt, wordt de datum van vandaag + gebruikt. schema: type: string - example: "2014-01-02" - name: registratiedatum__lt required: false in: query description: - De registratiedatum is kleiner dan de opgegeven datum. + De datum waarop de zaakbehandelende organisatie de ZAAK heeft + geregistreerd. Indien deze niet opgegeven wordt, wordt de datum van vandaag + gebruikt. schema: type: string - example: "2016-01-02" - name: einddatum required: false in: query description: De datum waarop de uitvoering van de zaak afgerond is. schema: type: string - example: "2022-01-02" - - name: einddatum__isnull + - name: einddatum__gt required: false in: query - description: De einddatum is leeg. + description: De datum waarop de uitvoering van de zaak afgerond is. schema: - type: boolean - example: false - - name: einddatum__gt + type: string + - name: einddatum__lt required: false in: query - description: De einddatum is groter dan de opgegeven datum. + description: De datum waarop de uitvoering van de zaak afgerond is. schema: type: string - example: "2021-01-02" - - name: einddatum__lt + - name: einddatum__isnull required: false in: query - description: De einddatum is kleiner dan de opgegeven datum. + description: De datum waarop de uitvoering van de zaak afgerond is. schema: type: string - example: "2023-01-02" - name: einddatumGepland required: false in: query @@ -6760,23 +6747,22 @@ paths: afgerond wordt. schema: type: string - example: "2022-01-02" - name: einddatumGepland__gt required: false in: query description: - De geplande einddatum is groter dan de opgegeven datum. + De datum waarop volgens de planning verwacht wordt dat de zaak + afgerond wordt. schema: type: string - example: "2021-01-02" - name: einddatumGepland__lt required: false in: query description: - De geplande einddatum is kleiner dan de opgegeven datum. + De datum waarop volgens de planning verwacht wordt dat de zaak + afgerond wordt. schema: type: string - example: "2024-01-02" - name: uiterlijkeEinddatumAfdoening required: false in: query @@ -6785,23 +6771,22 @@ paths: dient te zijn. schema: type: string - example: "2024-01-02" - name: uiterlijkeEinddatumAfdoening__gt required: false in: query description: - De uiterlijke einddatumafdoening is groter dan de opgegeven datum. + De laatste datum waarop volgens wet- en regelgeving de zaak afgerond + dient te zijn. schema: type: string - example: "2023-01-02" - name: uiterlijkeEinddatumAfdoening__lt required: false in: query description: - De uiterlijke einddatumafdoening is kleiner dan de opgegeven datum. + De laatste datum waarop volgens wet- en regelgeving de zaak afgerond + dient te zijn. schema: type: string - example: "2025-01-02" - name: rol__betrokkeneType required: false in: query @@ -6814,7 +6799,6 @@ paths: - vestiging - organisatorische_eenheid - medewerker - example: "natuurlijk_persoon" - name: rol__betrokkene required: false in: query @@ -6822,7 +6806,6 @@ paths: schema: type: string format: uri - example: "https://example.com" - name: rol__omschrijvingGeneriek required: false in: query @@ -6840,7 +6823,6 @@ paths: - klantcontacter - zaakcoordinator - mede_initiator - example: "initiator" - name: maximaleVertrouwelijkheidaanduiding required: false in: query @@ -6858,7 +6840,6 @@ paths: - confidentieel - geheim - zeer_geheim - example: "zaakvertrouwelijk" - name: rol__betrokkeneIdentificatie__natuurlijkPersoon__inpBsn required: false in: query @@ -6868,7 +6849,6 @@ paths: schema: type: string maxLength: 9 - example: "123456789" - name: rol__betrokkeneIdentificatie__natuurlijkPersoon__anpIdentificatie required: false in: query @@ -6878,7 +6858,6 @@ paths: schema: type: string maxLength: 17 - example: "123456789" - name: rol__betrokkeneIdentificatie__natuurlijkPersoon__inpA_nummer required: false in: query @@ -6886,7 +6865,6 @@ paths: schema: type: string maxLength: 10 - example: "123456789" - name: rol__betrokkeneIdentificatie__nietNatuurlijkPersoon__innNnpId required: false in: query @@ -6895,7 +6873,6 @@ paths: NIET-NATUURLIJK PERSOON schema: type: string - example: "123456789" - name: rol__betrokkeneIdentificatie__nietNatuurlijkPersoon__annIdentificatie required: false in: query @@ -6905,7 +6882,6 @@ paths: schema: type: string maxLength: 17 - example: "123456789" - name: rol__betrokkeneIdentificatie__vestiging__vestigingsNummer required: false in: query @@ -6913,7 +6889,6 @@ paths: schema: type: string maxLength: 24 - example: "123456789" - name: rol__betrokkeneIdentificatie__medewerker__identificatie required: false in: query @@ -6921,45 +6896,48 @@ paths: schema: type: string maxLength: 24 - example: "123456789" - name: rol__betrokkeneIdentificatie__organisatorischeEenheid__identificatie required: false in: query description: Een korte identificatie van de organisatorische eenheid. schema: type: string - example: "123456789" - name: ordering required: false in: query - description: Het veld waarop de resultaten geordend worden. Het minnetje betekent omgekeerde volgorde. + description: Het veld waarop de resultaten geordend worden. schema: type: array items: type: string enum: - - startdatum - - -startdatum - - einddatum - - -einddatum - - publicatiedatum - - -publicatiedatum - - archiefactiedatum - - -archiefactiedatum - - registratiedatum - - -registratiedatum - - identificatie - - -identificatie - example: "-startdatum" + - - startdatum + - -startdatum + - einddatum + - -einddatum + - publicatiedatum + - -publicatiedatum + - archiefactiedatum + - -archiefactiedatum style: form explode: false + - name: expand + required: false + in: query + description: + "Examples: \n`expand=zaaktype, status, status.statustype, hoofdzaak.status.statustype,\ + \ hoofdzaak.deelzaken.status.statustype`\nHaal details van gelinkte resources\ + \ direct op. Als je meerdere resources tegelijk wilt ophalen kun je deze\ + \ scheiden met een komma. Voor het ophalen van resources die een laag dieper\ + \ genest zijn wordt de punt-notatie gebruikt." + schema: + type: string - name: page required: false in: query description: Een pagina binnen de gepagineerde set resultaten. schema: type: integer - example: 1 - in: header name: Accept-Crs schema: @@ -7433,6 +7411,31 @@ paths: vraag (request body). Volgens de GeoJSON spec is WGS84 de default (EPSG:4326 is hetzelfde als WGS84). required: true + - in: query + name: expand + schema: + type: string + description: + Haal details van gelinkte resources direct op. Als je meerdere + resources tegelijk wilt ophalen kun je deze scheiden met een komma. Voor + het ophalen van resources die een laag dieper genest zijn wordt de punt-notatie + gebruikt. + examples: + ExpandZaaktype: + value: zaaktype + summary: expand zaaktype + ExpandStatus: + value: status + summary: expand status + ExpandStatus.statustype: + value: status.statustype + summary: expand status.statustype + ExpandHoofdzaak.status.statustype: + value: hoofdzaak.status.statustype + summary: expand hoofdzaak.status.statustype + ExpandHoofdzaak.deelzaken.status.statustype: + value: hoofdzaak.deelzaken.status.statustype + summary: expand hoofdzaak.deelzaken.status.statustype tags: - zaken security: @@ -7601,14 +7604,13 @@ paths: put: operationId: zaak_update description: - "**Er wordt gevalideerd op** \n- `zaaktype` mag niet gewijzigd\ - \ worden.\n- `identificatie` mag niet gewijzigd worden.\n- `laatsteBetaaldatum`\ - \ mag niet in de toekomst liggen.\n- `laatsteBetaaldatum` mag niet gezet worden\ - \ als de betalingsindicatie\n\"nvt\" is.\n- `archiefnominatie` moet een waarde\ - \ hebben indien `archiefstatus` niet de\nwaarde \"nog_te_archiveren\" heeft.\n\ - - `archiefactiedatum` moet een waarde hebben indien `archiefstatus` niet de\n\ - \ waarde \"nog_te_archiveren\" heeft.\n- `archiefstatus` kan alleen een waarde\ - \ anders dan \"nog_te_archiveren\"\n hebben indien van alle gerelateeerde\ + "**Er wordt gevalideerd op** \n- `identificatie` mag niet gewijzigd\ + \ worden.\n- `laatsteBetaaldatum` mag niet in de toekomst liggen.\n- `laatsteBetaaldatum`\ + \ mag niet gezet worden als de betalingsindicatie\n\"nvt\" is.\n- `archiefnominatie`\ + \ moet een waarde hebben indien `archiefstatus` niet de\nwaarde \"nog_te_archiveren\"\ + \ heeft.\n- `archiefactiedatum` moet een waarde hebben indien `archiefstatus`\ + \ niet de\n waarde \"nog_te_archiveren\" heeft.\n- `archiefstatus` kan alleen\ + \ een waarde anders dan \"nog_te_archiveren\"\n hebben indien van alle gerelateeerde\ \ INFORMATIEOBJECTen het attribuut\n `status` de waarde \"gearchiveerd\"\ \ heeft.\n**Opmerkingen**\n- er worden enkel zaken getoond van de zaaktypes\ \ waar u toe geautoriseerd\n bent.\n- indien een zaak heropend moet worden,\ @@ -7844,14 +7846,13 @@ paths: patch: operationId: zaak_partial_update description: - "**Er wordt gevalideerd op** \n- `zaaktype` mag niet gewijzigd\ - \ worden.\n- `identificatie` mag niet gewijzigd worden.\n- `laatsteBetaaldatum`\ - \ mag niet in de toekomst liggen.\n- `laatsteBetaaldatum` mag niet gezet worden\ - \ als de betalingsindicatie\n\"nvt\" is.\n- `archiefnominatie` moet een waarde\ - \ hebben indien `archiefstatus` niet de\nwaarde \"nog_te_archiveren\" heeft.\n\ - - `archiefactiedatum` moet een waarde hebben indien `archiefstatus` niet de\n\ - \ waarde \"nog_te_archiveren\" heeft.\n- `archiefstatus` kan alleen een waarde\ - \ anders dan \"nog_te_archiveren\"\n hebben indien van alle gerelateeerde\ + "**Er wordt gevalideerd op** \n- `identificatie` mag niet gewijzigd\ + \ worden.\n- `laatsteBetaaldatum` mag niet in de toekomst liggen.\n- `laatsteBetaaldatum`\ + \ mag niet gezet worden als de betalingsindicatie\n\"nvt\" is.\n- `archiefnominatie`\ + \ moet een waarde hebben indien `archiefstatus` niet de\nwaarde \"nog_te_archiveren\"\ + \ heeft.\n- `archiefactiedatum` moet een waarde hebben indien `archiefstatus`\ + \ niet de\n waarde \"nog_te_archiveren\" heeft.\n- `archiefstatus` kan alleen\ + \ een waarde anders dan \"nog_te_archiveren\"\n hebben indien van alle gerelateeerde\ \ INFORMATIEOBJECTen het attribuut\n `status` de waarde \"gearchiveerd\"\ \ heeft.\n**Opmerkingen**\n- er worden enkel zaken getoond van de zaaktypes\ \ waar u toe geautoriseerd\n bent.\n- indien een zaak heropend moet worden,\ @@ -10912,14 +10913,6 @@ components: - gedeeltelijk - geheel type: string - BetrokkeneTypeEnum: - enum: - - natuurlijk_persoon - - niet_natuurlijk_persoon - - vestiging - - organisatorische_eenheid - - medewerker - type: string BlankEnum: enum: - '' @@ -10969,7 +10962,7 @@ components: type: string description: De opgemaakte naam van de contactpersoon namens de BETROKKENE. title: naam - maxLength: 40 + maxLength: 200 required: - naam nullable: true @@ -11196,6 +11189,17 @@ components: items: $ref: '#/components/schemas/Point2D' minItems: 2 + MaximaleVertrouwelijkheidaanduidingEnum: + enum: + - openbaar + - beperkt_openbaar + - intern + - zaakvertrouwelijk + - vertrouwelijk + - confidentieel + - geheim + - zeer_geheim + type: string MultiLineString: title: Multi-line string description: GeoJSON multi-line-string geometry @@ -11917,6 +11921,21 @@ components: - indicatie - reden nullable: true + OrderingEnum: + enum: + - startdatum + - -startdatum + - einddatum + - -einddatum + - publicatiedatum + - -publicatiedatum + - archiefactiedatum + - -archiefactiedatum + - registratiedatum + - -registratiedatum + - identificatie + - -identificatie + type: string PaginatedKlantContactList: type: object properties: @@ -12204,7 +12223,7 @@ components: title: producten of diensten vertrouwelijkheidaanduiding: allOf: - - $ref: '#/components/schemas/VertrouwelijkheidaanduidingEnum' + - $ref: '#/components/schemas/MaximaleVertrouwelijkheidaanduidingEnum' title: Vertrouwlijkheidaanduiding description: Aanduiding van de mate waarin het zaakdossier van de ZAAK voor @@ -12946,7 +12965,7 @@ components: maxLength: 1000 betrokkeneType: allOf: - - $ref: '#/components/schemas/BetrokkeneTypeEnum' + - $ref: '#/components/schemas/Rol_betrokkeneTypeEnum' description: 'Type van de `betrokkene`. @@ -13066,11 +13085,11 @@ components: discriminator: propertyName: betrokkeneType mapping: - medewerker: '#/components/schemas/medewerker_Rol' natuurlijk_persoon: '#/components/schemas/natuurlijk_persoon_Rol' niet_natuurlijk_persoon: '#/components/schemas/niet_natuurlijk_persoon_Rol' - organisatorische_eenheid: '#/components/schemas/organisatorische_eenheid_Rol' vestiging: '#/components/schemas/vestiging_Rol' + organisatorische_eenheid: '#/components/schemas/organisatorische_eenheid_Rol' + medewerker: '#/components/schemas/medewerker_Rol' RolMedewerker: type: object properties: @@ -13264,6 +13283,25 @@ components: description: Een uniek nummer gekoppeld aan de onderneming. title: kvk nummer maxLength: 8 + Rol_betrokkeneTypeEnum: + enum: + - natuurlijk_persoon + - niet_natuurlijk_persoon + - vestiging + - organisatorische_eenheid + - medewerker + type: string + Rol_omschrijvingGeneriekEnum: + enum: + - adviseur + - behandelaar + - belanghebbende + - beslisser + - initiator + - klantcontacter + - zaakcoordinator + - mede_initiator + type: string Status: type: object properties: @@ -13332,7 +13370,7 @@ components: minLength: 1 maxLength: 1000 readOnly: true - title: zaakInformatieobjecten + title: status uniqueItems: true required: - datumStatusGezet @@ -13342,73 +13380,6 @@ components: - uuid - zaak - zaakinformatieobjecten - StatusRequestbody: - type: object - properties: - url: - type: string - format: uri - readOnly: true - title: url - description: - URL-referentie naar dit object. Dit is de unieke identificatie - en locatie van dit object. - minLength: 1 - maxLength: 1000 - uuid: - type: string - format: uuid - readOnly: true - description: Unieke resource identifier (UUID4) - title: uuid - zaak: - type: string - format: uri - description: URL-referentie naar de ZAAK. - title: zaak - minLength: 1 - maxLength: 1000 - statustype: - type: string - format: uri - description: URL-referentie naar het STATUSTYPE (in de Catalogi API). - title: statustype - maxLength: 1000 - datumStatusGezet: - type: string - format: date-time - description: De datum waarop de ZAAK de status heeft verkregen. - title: datum status gezet - statustoelichting: - type: string - description: - Een, voor de initiator van de zaak relevante, toelichting op - de status van een zaak. - title: statustoelichting - maxLength: 1000 - indicatieLaatstGezetteStatus: - type: boolean - readOnly: true - description: - Het gegeven is afleidbaar uit de historie van de attribuutsoort - Datum status gezet van van alle statussen bij de desbetreffende zaak. - title: indicatieLaatstGezetteStatus - gezetdoor: - type: string - format: uri - title: Gezet door - description: - De BETROKKENE die in zijn/haar ROL in een ZAAK heeft geregistreerd - dat STATUSsen in die ZAAK bereikt zijn. - maxLength: 200 - required: - - datumStatusGezet - - indicatieLaatstGezetteStatus - - statustype - - url - - uuid - - zaak - - zaakinformatieobjecten SubVerblijfBuitenland: type: object properties: @@ -13609,17 +13580,6 @@ components: - duur - reden nullable: true - VertrouwelijkheidaanduidingEnum: - enum: - - openbaar - - beperkt_openbaar - - intern - - zaakvertrouwelijk - - vertrouwelijk - - confidentieel - - geheim - - zeer_geheim - type: string Wijzigingen: type: object properties: @@ -13810,7 +13770,7 @@ components: title: producten of diensten vertrouwelijkheidaanduiding: allOf: - - $ref: '#/components/schemas/VertrouwelijkheidaanduidingEnum' + - $ref: '#/components/schemas/MaximaleVertrouwelijkheidaanduidingEnum' title: Vertrouwlijkheidaanduiding description: Aanduiding van de mate waarin het zaakdossier van de ZAAK voor @@ -14536,312 +14496,268 @@ components: - verzoek - zaak ZaakZoek: - type: object - properties: - zaakgeometrie: - $ref: '#/components/schemas/GeoWithin' - uuid__in: - description: Array of unieke resource identifiers (UUID4) - type: array - items: - type: string - format: uuid - example: ["e80b7507-199a-484c-ad49-c41a1e43a6e7", "78e12133-c467-4202-91ba-4417baa52801"] - identificatie: - title: Identificatie - description: De unieke identificatie van de ZAAK binnen de organisatie die - verantwoordelijk is voor de behandeling van de ZAAK. - type: string - example: "zaak123" - bronorganisatie: - title: Bronorganisatie - description: Het RSIN van de Niet-natuurlijk persoon zijnde de organisatie - die de zaak heeft gecreeerd. Dit moet een geldig RSIN zijn van 9 nummers - en voldoen aan https://nl.wikipedia.org/wiki/Burgerservicenummer#11-proef - type: string - example: "000000000" - bronorganisatie__in: - description: Array van bronorganisaties. - type: array - items: - type: string - format: string - example: ["000000000","479559740","875883461"] - zaaktype: - title: Zaaktype - description: URL-referentie naar het ZAAKTYPE (in de Catalogi API) in de - CATALOGUS waar deze voorkomt - type: string - example: "https://catalogi-api.test.vng.cloud/api/v1/zaaktypen/e80b7507-199a-484c-ad49-c41a1e43a6e7" - zaaktype__in: - description: Array van zaaktypen. - type: array - items: - type: string - format: uri - example: ["https://catalogi-api.test.vng.cloud/api/v1/zaaktypen/e80b7507-199a-484c-ad49-c41a1e43a6e7","https://catalogi-api.test.vng.cloud/api/v1/zaaktypen/78e12133-c467-4202-91ba-4417baa52801"] - archiefnominatie: - title: Archiefnominatie - description: 'Aanduiding of het zaakdossier blijvend bewaard of na een bepaalde - termijn vernietigd moet worden. - Uitleg bij mogelijke waarden: - * `blijvend_bewaren` - Het zaakdossier moet bewaard blijven en op de Archiefactiedatum - overgedragen worden naar een archiefbewaarplaats. - * `vernietigen` - Het zaakdossier moet op of na de Archiefactiedatum vernietigd - worden.' - type: string - enum: - - blijvend_bewaren - - vernietigen - example: "blijvend_bewaren" - archiefnominatie__in: - title: Archiefnominatie in - description: Multiple values may be separated by commas. - type: array - items: - type: string - example: [ "blijvend_bewaren", "vernietigen" ] - archiefactiedatum: - title: Archiefactiedatum - description: De datum waarop het gearchiveerde zaakdossier vernietigd moet - worden dan wel overgebracht moet worden naar een archiefbewaarplaats. - Wordt automatisch berekend bij het aanmaken of wijzigen van een RESULTAAT - aan deze ZAAK indien nog leeg. - type: string - example: "2019-01-02" - archiefactiedatum__isnull: - title: Archiefactiedatum is leeg - type: boolean - example: false - archiefactiedatum__lt: - title: Archiefactiedatum kleiner dan - type: string - example: "2020-01-02" - archiefactiedatum__gt: - title: Archiefactiedatum groter dan - type: string - example: "2018-01-02" - archiefstatus: - title: Archiefstatus - description: 'Aanduiding of het zaakdossier blijvend bewaard of na een bepaalde - termijn vernietigd moet worden. - Uitleg bij mogelijke waarden: - * `nog_te_archiveren` - De zaak cq. het zaakdossier is nog niet als geheel - gearchiveerd. - * `gearchiveerd` - De zaak cq. het zaakdossier is als geheel niet-wijzigbaar - bewaarbaar gemaakt. - * `gearchiveerd_procestermijn_onbekend` - De zaak cq. het zaakdossier - is als geheel niet-wijzigbaar bewaarbaar gemaakt maar de vernietigingsdatum - kan nog niet bepaald worden. - * `overgedragen` - De zaak cq. het zaakdossier is overgebracht naar een - archiefbewaarplaats.' - type: string - enum: - - nog_te_archiveren - - gearchiveerd - - gearchiveerd_procestermijn_onbekend - - overgedragen - example: "nog_te_archiveren" - archiefstatus__in: - title: Archiefstatus in - description: Multiple values may be separated by commas. - type: array - items: - type: string - example: [ "nog_te_archiveren","gearchiveerd","gearchiveerd_procestermijn_onbekend","overgedragen" ] - startdatum: - title: Startdatum - description: De datum waarop met de uitvoering van de zaak is gestart - type: string - example: "2017-01-02" - startdatum__gt: - title: Startdatum groter dan - type: string - example: "2018-01-02" - startdatum__gte: - title: Startdatum groter dan of gelijk - type: string - example: "2016-01-02" - startdatum__lt: - title: Startdatum kleiner dan - type: string - example: "2018-01-02" - startdatum__lte: - title: Startdatum kleiner dan of gelijk - type: string - example: "2018-01-02" - registratiedatum: - title: Registratiedatum - description: De datum waarop de zaakbehandelende organisatie de ZAAK heeft geregistreerd. Indien deze niet opgegeven wordt, wordt de datum van vandaag gebruikt. - type: string - example: "2015-01-02" - registratiedatum__gt: - title: Registratiedatum groter dan - type: string - example: "2014-01-02" - registratiedatum__lt: - title: Registratiedatum kleiner dan - type: string - example: "2016-01-02" - einddatum: - title: Einddatum - description: De datum waarop de uitvoering van de zaak afgerond is. - type: string - example: "2022-01-02" - einddatum__isnull: - title: Einddatum is leeg - type: boolean - example: false - einddatum__gt: - title: Einddatum groter dan - type: string - example: "2021-01-02" - einddatum__lt: - title: Einddatum kleiner dan - type: string - minLength: 1 - example: "2023-01-02" - einddatumGepland: - title: Einddatum gepland - description: De datum waarop volgens de planning verwacht wordt dat de zaak afgerond wordt. - type: string - example: "2022-01-02" - einddatumGepland__gt: - title: Einddatum gepland groter dan - type: string - example: "2021-01-02" - einddatumGepland__lt: - title: Einddatum gepland kleiner dan - type: string - example: "2024-01-02" - uiterlijkeEinddatumAfdoening: - title: Uiterlijke einddatumAfdoening - description: De laatste datum waarop volgens wet- en regelgeving de zaak afgerond dient te zijn. - type: string - example: "2024-01-02" - uiterlijkeEinddatumAfdoening__gt: - title: Uiterlijke einddatumAfdoening groter dan - type: string - example: "2023-01-02" - uiterlijkeEinddatumAfdoening__lt: - title: Uiterlijke einddatumAfdoening kleiner dan - type: string - example: "2025-01-02" - rol__betrokkeneType: - title: Rol betrokkenetype - description: 'Type van de `betrokkene`. - Uitleg bij mogelijke waarden: - * `natuurlijk_persoon` - Natuurlijk persoon - * `niet_natuurlijk_persoon` - Niet-natuurlijk persoon - * `vestiging` - Vestiging - * `organisatorische_eenheid` - Organisatorische eenheid - * `medewerker` - Medewerker' - type: string - enum: - - natuurlijk_persoon - - niet_natuurlijk_persoon - - vestiging - - organisatorische_eenheid - - medewerker - example: "natuurlijk_persoon" - rol__betrokkene: - title: Rol betrokkene - description: URL-referentie naar een betrokkene gerelateerd aan de ZAAK. - type: string - example: "https://example.com" - rol__omschrijvingGeneriek: - title: Rol omschrijvinggeneriek - description: - Algemeen gehanteerde benaming van de aard van de ROL, afgeleid uit het ROLTYPE. - type: string - enum: - - adviseur - - behandelaar - - belanghebbende - - beslisser - - initiator - - klantcontacter - - zaakcoordinator - - mede_initiator - example: "initiator" - maximaleVertrouwelijkheidaanduiding: - title: Maximalevertrouwelijkheidaanduiding - description: - Zaken met een vertrouwelijkheidaanduiding die beperkter is - dan de aangegeven aanduiding worden uit de resultaten gefiltered. - type: string - enum: - - openbaar - - beperkt_openbaar - - intern - - zaakvertrouwelijk - - vertrouwelijk - - confidentieel - - geheim - - zeer_geheim - example: "zaakvertrouwelijk" - rol__betrokkeneIdentificatie__natuurlijkPersoon__inpBsn: - title: Rol betrokkeneidentificatie natuurlijkpersoon inpbsn - description: Het burgerservicenummer, bedoeld in artikel 1.1 van de Wet - algemene bepalingen burgerservicenummer. - type: string - example: "123456789" - rol__betrokkeneIdentificatie__natuurlijkPersoon__anpIdentificatie: - title: Rol betrokkeneidentificatie natuurlijkpersoon anpidentificatie - description: Het door de gemeente uitgegeven unieke nummer voor een ANDER - NATUURLIJK PERSOON - type: string - example: "123456789" - rol__betrokkeneIdentificatie__natuurlijkPersoon__inpA_nummer: - title: Rol betrokkeneidentificatie natuurlijkpersoon inpa nummer - description: Het administratienummer van de persoon, bedoeld in de Wet BRP - type: string - example: "123456789" - rol__betrokkeneIdentificatie__nietNatuurlijkPersoon__innNnpId: - title: Rol betrokkeneidentificatie nietnatuurlijkpersoon innnnpid - description: Het door een kamer toegekend uniek nummer voor de INGESCHREVEN - NIET-NATUURLIJK PERSOON - type: string - example: "123456789" - rol__betrokkeneIdentificatie__nietNatuurlijkPersoon__annIdentificatie: - title: Rol betrokkeneidentificatie nietnatuurlijkpersoon annidentificatie - description: Het door de gemeente uitgegeven unieke nummer voor een ANDER - NIET-NATUURLIJK PERSOON - type: string - example: "123456789" - rol__betrokkeneIdentificatie__vestiging__vestigingsNummer: - title: Rol betrokkeneidentificatie vestiging vestigingsnummer - description: Een korte unieke aanduiding van de Vestiging. - type: string - example: "123456789" - rol__betrokkeneIdentificatie__medewerker__identificatie: - title: Rol betrokkeneidentificatie medewerker identificatie - description: Een korte unieke aanduiding van de MEDEWERKER. - type: string - example: "123456789" - rol__betrokkeneIdentificatie__organisatorischeEenheid__identificatie: - title: Rol betrokkeneidentificatie organisatorischeeenheid identificatie - description: Een korte identificatie van de organisatorische eenheid. - type: string - example: "123456789" - ordering: - title: Ordering - description: Het veld waarop de resultaten geordend worden. Het minnetje betekent omgekeerde volgorde. - type: string - enum: - - startdatum - - -startdatum - - einddatum - - -einddatum - - publicatiedatum - - -publicatiedatum - - archiefactiedatum - - -archiefactiedatum - - registratiedatum - - -registratiedatum - - identificatie - - -identificatie - example: "-startdatum" + type: object + properties: + zaakgeometrie: + allOf: + - $ref: '#/components/schemas/GeoWithin' + title: GeoWithin + uuid__in: + type: array + items: + type: string + format: uuid + title: '' + description: Array of unieke resource identifiers (UUID4) + title: uuid__in + identificatie: + type: string + description: + De unieke identificatie van de ZAAK binnen de organisatie die + verantwoordelijk is voor de behandeling van de ZAAK. + title: identificatie + bronorganisatie: + type: string + description: + Het RSIN van de Niet-natuurlijk persoon zijnde de organisatie + die de zaak heeft gecreeerd. Dit moet een geldig RSIN zijn van 9 nummers + en voldoen aan https://nl.wikipedia.org/wiki/Burgerservicenummer#11-proef + title: bronorganisatie + bronorganisatie__in: + type: array + items: + type: string + title: '' + description: Array van bronorganisaties. + title: bronorganisatie__in + zaaktype: + type: string + format: uri + description: + URL-referentie naar het ZAAKTYPE (in de Catalogi API) in de + CATALOGUS waar deze voorkomt + title: zaaktype + zaaktype__in: + type: array + items: + type: string + format: uri + title: '' + description: Array van zaaktypen. + title: zaaktype__in + archiefnominatie: + allOf: + - $ref: '#/components/schemas/ArchiefnominatieEnum' + description: + 'Aanduiding of het zaakdossier blijvend bewaard of na een bepaalde + termijn vernietigd moet worden. Uitleg bij mogelijke waarden: * blijvend_bewaren + - Het zaakdossier moet bewaard blijven en op de Archiefactiedatum overgedragen + worden naar een archiefbewaarplaats. * vernietigen - Het zaakdossier moet + op of na de Archiefactiedatum vernietigd worden.' + title: archiefnominatie + archiefnominatie__in: + type: array + items: + type: string + title: '' + description: Multiple values may be separated by commas. + title: archiefnominatie__in + einddatum: + type: string + description: De datum waarop de uitvoering van de zaak afgerond is. + title: einddatum + einddatum__gt: + type: string + title: einddatum__gt + einddatum__lt: + type: string + title: einddatum__lt + einddatum__isnull: + type: boolean + title: einddatum__isnull + einddatumGepland: + type: string + description: + De datum waarop volgens de planning verwacht wordt dat de zaak + afgerond wordt. + title: einddatumGepland + einddatumGepland__gt: + type: string + title: einddatumGepland__gt + einddatumGepland__lt: + type: string + title: einddatumGepland__lt + uiterlijkeEinddatumAfdoening: + type: string + description: + De laatste datum waarop volgens wet- en regelgeving de zaak + afgerond dient te zijn. + title: uiterlijkeEinddatumAfdoening + uiterlijkeEinddatumAfdoening__gt: + type: string + title: uiterlijkeEinddatumAfdoening__gt + uiterlijkeEinddatumAfdoening__lt: + type: string + title: uiterlijkeEinddatumAfdoening__lt + archiefactiedatum: + type: string + description: + De datum waarop het gearchiveerde zaakdossier vernietigd moet + worden dan wel overgebracht moet worden naar een archiefbewaarplaats. + Wordt automatisch berekend bij het aanmaken of wijzigen van een RESULTAAT + aan deze ZAAK indien nog leeg. + title: archiefactiedatum + archiefactiedatum__lt: + type: string + title: Archiefactiedatum lt + archiefactiedatum__gt: + type: string + title: Archiefactiedatum gt + archiefactiedatum__isnull: + type: boolean + title: Archiefactiedatum is leeg + description: De archiefactiedatum is leeg + archiefstatus: + allOf: + - $ref: '#/components/schemas/ArchiefstatusEnum' + description: + 'Aanduiding of het zaakdossier blijvend bewaard of na een bepaalde + termijn vernietigd moet worden. Uitleg bij mogelijke waarden: * nog_te_archiveren + - De zaak cq. het zaakdossier is nog niet als geheel gearchiveerd. * gearchiveerd + - De zaak cq. het zaakdossier is als geheel niet-wijzigbaar bewaarbaar + gemaakt. * gearchiveerd_procestermijn_onbekend - De zaak cq. het zaakdossier + is als geheel niet-wijzigbaar bewaarbaar gemaakt maar de vernietigingsdatum + kan nog niet bepaald worden. * overgedragen - De zaak cq. het zaakdossier + is overgebracht naar een archiefbewaarplaats.' + title: archiefstatus + archiefstatus__in: + type: array + items: + type: string + title: '' + description: Multiple values may be separated by commas. + title: archiefstatus__in + startdatum: + type: string + description: De datum waarop met de uitvoering van de zaak is gestart + title: startdatum + startdatum__gt: + type: string + description: De datum waarop met de uitvoering van de zaak is gestart + title: startdatum__gt + startdatum__gte: + type: string + description: De datum waarop met de uitvoering van de zaak is gestart + title: startdatum__gte + startdatum__lt: + type: string + description: De datum waarop met de uitvoering van de zaak is gestart + title: startdatum__lt + startdatum__lte: + type: string + description: De datum waarop met de uitvoering van de zaak is gestart + title: startdatum__lte + rol__betrokkeneType: + allOf: + - $ref: '#/components/schemas/Rol_betrokkeneTypeEnum' + description: + 'Type van de betrokkene. Uitleg bij mogelijke waarden: * natuurlijk_persoon + - Natuurlijk persoon * niet_natuurlijk_persoon - Niet-natuurlijk persoon + * vestiging - Vestiging * organisatorische_eenheid - Organisatorische + eenheid * medewerker - Medewerker' + title: rol__betrokkeneType + rol__betrokkene: + type: string + description: URL-referentie naar een betrokkene gerelateerd aan de ZAAK. + title: rol__betrokkene + rol__omschrijvingGeneriek: + allOf: + - $ref: '#/components/schemas/Rol_omschrijvingGeneriekEnum' + description: + "Algemeen gehanteerde benaming van de aard van de ROL, afgeleid\ + \ uit het ROLTYPE. Uitleg bij mogelijke waarden:\n\n`adviseur` - Adviseur\n\ + \n`behandelaar` - Behandelaar\n\n`belanghebbende` - Belanghebbende\n\n\ + `beslisser` - Beslisser\n\n`initiator` - Initiator\n\n`klantcontacter`\ + \ - Klantcontacter\n\n`zaakcoordinator` - Zaakco\xF6rdinator\n \n`mede_initiator`\ + \ - Mede-initiator\n" + title: rol__omschrijvingGeneriek + maximaleVertrouwelijkheidaanduiding: + allOf: + - $ref: '#/components/schemas/MaximaleVertrouwelijkheidaanduidingEnum' + description: + 'Zaken met een vertrouwelijkheidaanduiding die beperkter is + dan de aangegeven aanduiding worden uit de resultaten gefiltered. Uitleg + bij mogelijke waarden: * `openbaar` - Openbaar * `beperkt_openbaar` - + Beperkt openbaar * `intern` - Intern * `zaakvertrouwelijk` - Zaakvertrouwelijk + * `vertrouwelijk` - Vertrouwelijk * `confidentieel` - Confidentieel * + `geheim` - Geheim * `zeer_geheim` - Zeer geheim' + title: maximaleVertrouwelijkheidaanduiding + rol__betrokkeneIdentificatie__natuurlijkPersoon__anpIdentificatie: + type: string + description: + Het door de gemeente uitgegeven unieke nummer voor een ANDER + NATUURLIJK PERSOON + title: rol__betrokkeneIdentificatie__natuurlijkPersoon__anpIdentificatie + maxLength: 17 + rol__betrokkeneIdentificatie__natuurlijkPersoon__inpBsn: + type: string + description: + Het burgerservicenummer, bedoeld in artikel 1.1 van de Wet + algemene bepalingen burgerservicenummer. + title: rol__betrokkeneIdentificatie__natuurlijkPersoon__inpBsn + maxLength: 9 + rol__betrokkeneIdentificatie__natuurlijkPersoon__inpA_nummer: + type: string + description: Het administratienummer van de persoon, bedoeld in de Wet BRP + title: rol__betrokkeneIdentificatie__natuurlijkPersoon__inpA_nummer + maxLength: 10 + rol__betrokkeneIdentificatie__nietNatuurlijkPersoon__innNnpId: + type: string + description: + Het door een kamer toegekend uniek nummer voor de INGESCHREVEN + NIET-NATUURLIJK PERSOON + title: rol__betrokkeneIdentificatie__nietNatuurlijkPersoon__innNnpId + rol__betrokkeneIdentificatie__nietNatuurlijkPersoon__annIdentificatie: + type: string + description: + Het door de gemeente uitgegeven unieke nummer voor een ANDER + NIET-NATUURLIJK PERSOON + title: rol__betrokkeneIdentificatie__nietNatuurlijkPersoon__annIdentificatie + maxLength: 17 + rol__betrokkeneIdentificatie__vestiging__vestigingsNummer: + type: string + description: Een korte unieke aanduiding van de Vestiging. + title: rol__betrokkeneIdentificatie__vestiging__vestigingsNummer + maxLength: 24 + rol__betrokkeneIdentificatie__medewerker__identificatie: + type: string + description: Een korte unieke aanduiding van de MEDEWERKER. + title: rol__betrokkeneIdentificatie__medewerker__identificatie + maxLength: 24 + rol__betrokkeneIdentificatie__organisatorischeEenheid__identificatie: + type: string + description: Een korte identificatie van de organisatorische eenheid. + title: rol__betrokkeneIdentificatie__organisatorischeEenheid__identificatie + registratiedatum: + type: string + description: + De datum waarop de zaakbehandelende organisatie de ZAAK heeft + geregistreerd. Indien deze niet opgegeven wordt, wordt de datum van vandaag + gebruikt. + title: registratiedatum + registratiedatum__gt: + type: string + title: registratiedatum__gt + registratiedatum__lt: + type: string + title: registratiedatum__lt + ordering: + allOf: + - $ref: '#/components/schemas/OrderingEnum' + description: + Het veld waarop de resultaten geordend worden. Het minnetje + betekent omgekeerde volgorde. + title: ordering ZakelijkRechtHeeftAlsGerechtigde: type: object properties: @@ -14853,20 +14769,20 @@ components: allOf: - $ref: '#/components/schemas/RolNietNatuurlijkPersoon' title: nietNatuurlijkPersoon - adres_ZaakObject: - allOf: - - $ref: '#/components/schemas/ZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectAdres' adres_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectAdres' - besluit_ZaakObject: + adres_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' + - $ref: '#/components/schemas/object_identificatie_ObjectAdres' besluit_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' + besluit_ZaakObject: + allOf: + - $ref: '#/components/schemas/ZaakObject' betrokkene_identificatie_RolMedewerker: type: object properties: @@ -14902,76 +14818,80 @@ components: allOf: - $ref: '#/components/schemas/RolVestiging' title: betrokkeneIdentificatie + buurt_PatchedZaakObject: + allOf: + - $ref: '#/components/schemas/PatchedZaakObject' + - $ref: '#/components/schemas/object_identificatie_ObjectBuurt' buurt_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectBuurt' - buurt_PatchedZaakObject: + enkelvoudig_document_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectBuurt' enkelvoudig_document_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - enkelvoudig_document_PatchedZaakObject: + gemeente_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' + - $ref: '#/components/schemas/object_identificatie_ObjectGemeente' gemeente_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectGemeente' - gemeente_PatchedZaakObject: + gemeentelijke_openbare_ruimte_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectGemeente' + - $ref: '#/components/schemas/object_identificatie_ObjectGemeentelijkeOpenbareRuimte' gemeentelijke_openbare_ruimte_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectGemeentelijkeOpenbareRuimte' - gemeentelijke_openbare_ruimte_PatchedZaakObject: + huishouden_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectGemeentelijkeOpenbareRuimte' + - $ref: '#/components/schemas/object_identificatie_ObjectHuishouden' huishouden_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectHuishouden' - huishouden_PatchedZaakObject: + inrichtingselement_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectHuishouden' + - $ref: '#/components/schemas/object_identificatie_ObjectInrichtingselement' inrichtingselement_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectInrichtingselement' - inrichtingselement_PatchedZaakObject: + kadastrale_onroerende_zaak_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectInrichtingselement' + - $ref: '#/components/schemas/object_identificatie_ObjectKadastraleOnroerendeZaak' kadastrale_onroerende_zaak_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectKadastraleOnroerendeZaak' - kadastrale_onroerende_zaak_PatchedZaakObject: + kunstwerkdeel_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectKadastraleOnroerendeZaak' + - $ref: '#/components/schemas/object_identificatie_ObjectKunstwerkdeel' kunstwerkdeel_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectKunstwerkdeel' - kunstwerkdeel_PatchedZaakObject: + maatschappelijke_activiteit_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectKunstwerkdeel' + - $ref: '#/components/schemas/object_identificatie_ObjectMaatschappelijkeActiviteit' maatschappelijke_activiteit_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectMaatschappelijkeActiviteit' - maatschappelijke_activiteit_PatchedZaakObject: + medewerker_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectMaatschappelijkeActiviteit' + - $ref: '#/components/schemas/object_identificatie_RolMedewerker' medewerker_Rol: allOf: - $ref: '#/components/schemas/Rol' @@ -14979,11 +14899,11 @@ components: medewerker_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - - $ref: '#/components/schemas/betrokkene_identificatie_RolMedewerker' - medewerker_PatchedZaakObject: + - $ref: '#/components/schemas/object_identificatie_RolMedewerker' + natuurlijk_persoon_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/betrokkene_identificatie_RolMedewerker' + - $ref: '#/components/schemas/object_identificatie_RolNatuurlijkPersoon' natuurlijk_persoon_Rol: allOf: - $ref: '#/components/schemas/Rol' @@ -14991,11 +14911,11 @@ components: natuurlijk_persoon_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - - $ref: '#/components/schemas/betrokkene_identificatie_RolNatuurlijkPersoon' - natuurlijk_persoon_PatchedZaakObject: + - $ref: '#/components/schemas/object_identificatie_RolNatuurlijkPersoon' + niet_natuurlijk_persoon_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/betrokkene_identificatie_RolNatuurlijkPersoon' + - $ref: '#/components/schemas/object_identificatie_RolNietNatuurlijkPersoon' niet_natuurlijk_persoon_Rol: allOf: - $ref: '#/components/schemas/Rol' @@ -15003,11 +14923,7 @@ components: niet_natuurlijk_persoon_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - - $ref: '#/components/schemas/betrokkene_identificatie_RolNietNatuurlijkPersoon' - niet_natuurlijk_persoon_PatchedZaakObject: - allOf: - - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/betrokkene_identificatie_RolNietNatuurlijkPersoon' + - $ref: '#/components/schemas/object_identificatie_RolNietNatuurlijkPersoon' object_identificatie_ObjectAdres: type: object properties: @@ -15204,14 +15120,18 @@ components: allOf: - $ref: '#/components/schemas/RolVestiging' title: objectIdentificatie + openbare_ruimte_PatchedZaakObject: + allOf: + - $ref: '#/components/schemas/PatchedZaakObject' + - $ref: '#/components/schemas/object_identificatie_ObjectOpenbareRuimte' openbare_ruimte_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectOpenbareRuimte' - openbare_ruimte_PatchedZaakObject: + organisatorische_eenheid_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectOpenbareRuimte' + - $ref: '#/components/schemas/object_identificatie_RolOrganisatorischeEenheid' organisatorische_eenheid_Rol: allOf: - $ref: '#/components/schemas/Rol' @@ -15219,57 +15139,57 @@ components: organisatorische_eenheid_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - - $ref: '#/components/schemas/betrokkene_identificatie_RolOrganisatorischeEenheid' - organisatorische_eenheid_PatchedZaakObject: + - $ref: '#/components/schemas/object_identificatie_RolOrganisatorischeEenheid' + overige_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/betrokkene_identificatie_RolOrganisatorischeEenheid' + - $ref: '#/components/schemas/object_identificatie_ObjectOverige' overige_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectOverige' - overige_PatchedZaakObject: + pand_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectOverige' + - $ref: '#/components/schemas/object_identificatie_ObjectPand' pand_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectPand' - pand_PatchedZaakObject: + spoorbaandeel_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectPand' + - $ref: '#/components/schemas/object_identificatie_ObjectSpoorbaandeel' spoorbaandeel_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectSpoorbaandeel' - spoorbaandeel_PatchedZaakObject: + status_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectSpoorbaandeel' status_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - status_PatchedZaakObject: + terrein_gebouwd_object_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' + - $ref: '#/components/schemas/object_identificatie_ObjectTerreinGebouwdObject' terrein_gebouwd_object_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectTerreinGebouwdObject' - terrein_gebouwd_object_PatchedZaakObject: + terreindeel_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectTerreinGebouwdObject' + - $ref: '#/components/schemas/object_identificatie_ObjectTerreindeel' terreindeel_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectTerreindeel' - terreindeel_PatchedZaakObject: + vestiging_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectTerreindeel' + - $ref: '#/components/schemas/object_identificatie_RolVestiging' vestiging_Rol: allOf: - $ref: '#/components/schemas/Rol' @@ -15277,83 +15197,79 @@ components: vestiging_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - - $ref: '#/components/schemas/betrokkene_identificatie_RolVestiging' - vestiging_PatchedZaakObject: + - $ref: '#/components/schemas/object_identificatie_RolVestiging' + waterdeel_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/betrokkene_identificatie_RolVestiging' + - $ref: '#/components/schemas/object_identificatie_ObjectWaterdeel' waterdeel_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectWaterdeel' - waterdeel_PatchedZaakObject: + wegdeel_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectWaterdeel' + - $ref: '#/components/schemas/object_identificatie_ObjectWegdeel' wegdeel_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectWegdeel' - wegdeel_PatchedZaakObject: + wijk_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectWegdeel' + - $ref: '#/components/schemas/object_identificatie_ObjectWijk' wijk_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectWijk' - wijk_PatchedZaakObject: + woonplaats_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectWijk' + - $ref: '#/components/schemas/object_identificatie_ObjectWoonplaats' woonplaats_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectWoonplaats' - woonplaats_PatchedZaakObject: + woz_deelobject_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectWoonplaats' + - $ref: '#/components/schemas/object_identificatie_ObjectWozDeelobject' woz_deelobject_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectWozDeelobject' - woz_deelobject_PatchedZaakObject: + woz_object_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectWozDeelobject' + - $ref: '#/components/schemas/object_identificatie_ObjectWozObject' woz_object_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectWozObject' - woz_object_PatchedZaakObject: + woz_waarde_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectWozObject' + - $ref: '#/components/schemas/object_identificatie_ObjectWozWaarde' woz_waarde_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectWozWaarde' - woz_waarde_PatchedZaakObject: + zakelijk_recht_PatchedZaakObject: allOf: - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectWozWaarde' + - $ref: '#/components/schemas/object_identificatie_ObjectZakelijkRecht' zakelijk_recht_ZaakObject: allOf: - $ref: '#/components/schemas/ZaakObject' - $ref: '#/components/schemas/object_identificatie_ObjectZakelijkRecht' - zakelijk_recht_PatchedZaakObject: - allOf: - - $ref: '#/components/schemas/PatchedZaakObject' - - $ref: '#/components/schemas/object_identificatie_ObjectZakelijkRecht' securitySchemes: JWT-Claims: type: http bearerFormat: JWT scheme: bearer servers: - - url: https://zaken-api.test.vng.cloud/api/v1 - - url: https://zaken-api.vng.cloud/api/v1 + - url: https://zaken-api.vng.cloud/api/v1/ + description: Productie Omgeving tags: - name: klantcontacten description: '' diff --git a/src/zrc/api/expansions.py b/src/zrc/api/expansions.py new file mode 100644 index 00000000..2cbf1928 --- /dev/null +++ b/src/zrc/api/expansions.py @@ -0,0 +1,648 @@ +import json +import logging +import re +import uuid +from dataclasses import dataclass +from urllib.request import Request, urlopen + +from django.contrib.contenttypes.models import ContentType +from django.urls import resolve +from django.urls.exceptions import Resolver404 +from django.utils.translation import ugettext_lazy as _ + +from drf_spectacular.types import OpenApiTypes +from drf_spectacular.utils import OpenApiExample, OpenApiParameter, extend_schema +from rest_framework import serializers + +logger = logging.getLogger(__name__) + + +def is_uri(s): + try: + from urllib.parse import urlparse + + result = urlparse(s) + return all([result.scheme, result.netloc]) + except: + return False + + +@dataclass +class ExpansionField: + def __init__( + self, + id, + parent, + sub_field_parent, + sub_field, + level, + struc_type, + value, + is_empty, + code=None, + parent_code=None, + ): + self.id: str = id + self.parent: str = parent + self.sub_field_parent: str = sub_field_parent + self.sub_field: str = sub_field + self.level: int = level + self.type: str = struc_type + self.value: dict = value + self.is_empty: bool = is_empty + self.code = code + self.parent_code = parent_code + + +EXPAND_QUERY_PARAM = OpenApiParameter( + name="expand", + location=OpenApiParameter.QUERY, + description="Haal details van gelinkte resources direct op. Als je meerdere resources tegelijk wilt ophalen kun je deze scheiden met een komma. Voor het ophalen van resources die een laag dieper genest zijn wordt de punt-notatie gebruikt.", + type=OpenApiTypes.STR, + examples=[ + OpenApiExample(name="expand zaaktype", value="zaaktype"), + OpenApiExample(name="expand status", value="status"), + OpenApiExample(name="expand status.statustype", value="status.statustype"), + OpenApiExample( + name="expand hoofdzaak.status.statustype", + value="hoofdzaak.status.statustype", + ), + OpenApiExample( + name="expand hoofdzaak.deelzaken.status.statustype", + value="hoofdzaak.deelzaken.status.statustype", + ), + ], +) + + +class ExpansionMixin: + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.expanded_fields = [] + self.called_external_uris = {} + self.expanded_fields_all = [] + + @extend_schema(parameters=[EXPAND_QUERY_PARAM]) + def retrieve(self, request, *args, **kwargs): + response = super().retrieve(request, *args, **kwargs) + response = self.inclusions(response) + return response + + def list(self, request, *args, **kwargs): + response = super().list(request, *args, **kwargs) + response = self.inclusions(response) + return response + + @staticmethod + def _convert_to_internal_url(url: str) -> str: + """Convert external uri (https://testserver/api/v1...) to internal uri (/api/v1...)""" + keyword = "api" + save_sentence = False + internal_url = "/" + if isinstance(url, dict): + if not url.get("url", None): + for key, value in url.items(): + if is_uri(value): + url = value + break + else: + url = url.get("url", None) + if not url: + return "" + for word in url.split("/"): + if word == keyword: + save_sentence = True + if save_sentence: + internal_url += word + "/" + + return internal_url[:-1] + + def _get_external_data(self, url): + if isinstance(url, dict): + if not url.get("url", None): + for key, value in url.items(): + if is_uri(value): + url = value + break + else: + url = url.get("url", None) + if not self.called_external_uris.get(url, None): + try: + access_token = self.request.jwt_auth.encoded + # access_token = "eyJhbGciOiJIUzI1NiIsImNsaWVudF9pZGVudGlmaWVyIjoiYWxsdGhlc2NvcGVzYXJlYmVsb25ndG91czIyMjIyMzEzMjUzMi14eXBhcGRTV3FqMVQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhbGx0aGVzY29wZXNhcmViZWxvbmd0b3VzMjIyMjIzMTMyNTMyLXh5cGFwZFNXcWoxVCIsImlhdCI6MTY5MjYwMTAwNiwiY2xpZW50X2lkIjoiYWxsdGhlc2NvcGVzYXJlYmVsb25ndG91czIyMjIyMzEzMjUzMi14eXBhcGRTV3FqMVQiLCJ1c2VyX2lkIjoiIiwidXNlcl9yZXByZXNlbnRhdGlvbiI6IiJ9.iOCqIi9IxTfTjBmk8YuQLK7Wc1LlzVUsiJPFIijEc0s" + headers = {"Authorization": f"Bearer {access_token}"} + + with urlopen(Request(url, headers=headers)) as response: + data = json.loads(response.read().decode("utf8")) + self.called_external_uris[url] = data + return data + + except: + self.called_external_uris[url] = {} + return {} + else: + return self.called_external_uris[url] + + def _get_internal_data(self, url): + resolver_match = resolve(self._convert_to_internal_url(url)) + + uuid = resolver_match.kwargs["uuid"] + + kwargs = {"uuid": uuid} + + content_type = ContentType.objects.get( + model=resolver_match.func.initkwargs["basename"] + ) + + obj = content_type.get_object_for_this_type(**kwargs) + + serializer = resolver_match.func.cls.serializer_class + + serializer_exp_field = serializer(obj, context={"request": self.request}) + + return serializer_exp_field.data + + def get_data( + self, + url: str, + ) -> dict: + """Get data from external url or from local database""" + + try: + return self._get_internal_data(url) + except Resolver404: + return self._get_external_data(url) + except Exception as e: + logger.error( + f"The following error occured while trying to get data from {url}: {e}" + ) + return {} + + def build_expand_schema( + self, + result: dict, + fields_to_expand: list, + ): + """Build the expand schema for the response. First, the fields to expand are split on the "." character. Then, the first part of the split is used to get the urls from the result. The urls are then used to get the corresponding data from the external api or from the local database. The data is then gathered/collected inside a list consisted of namedtuples. When all data is collected, it calls the _build_json method which builds the json response.""" + expansion = {"_expand": {}} + + for exp_field in fields_to_expand: + loop_id = str(uuid.uuid4()) + self.expanded_fields = [] + for depth, sub_field in enumerate(exp_field.split(".")): + if depth == 0: + try: + urls = result[self.convert_camel_to_snake(sub_field)] + except KeyError: + try: + urls = result[sub_field] + except KeyError: + raise self.validation_invalid_expand_field(sub_field) + + if isinstance(urls, list): + for x in urls: + self._add_to_expanded_fields( + loop_id, + exp_field, + sub_field, + depth, + data=self.get_data(x), + struc_type="list", + is_empty=False, + original_data=result, + ) + if not urls: + expansion["_expand"][sub_field] = [] + else: + if urls: + self._add_to_expanded_fields( + loop_id, + exp_field, + sub_field, + depth, + data=self.get_data(urls), + struc_type="dict", + is_empty=False, + original_data=result, + ) + else: + expansion["_expand"][sub_field] = {} + + else: + + for field in self.expanded_fields: + if ( + field.sub_field == exp_field.split(".")[depth - 1] + and field.level == depth - 1 + ): + if self.next_iter_if_value_is_empty(field.value): + continue + try: + urls = field.value[ + self.convert_camel_to_snake(sub_field) + ] + except KeyError: + try: + urls = field.value[sub_field] + except KeyError: + raise self.validation_invalid_expand_field( + sub_field + ) + if isinstance(urls, list): + if urls: + for x in urls: + self._add_to_expanded_fields( + loop_id, + exp_field, + sub_field, + depth, + data=self.get_data(x), + struc_type="list", + is_empty=False, + original_data=result, + field=field, + ) + else: + self._add_to_expanded_fields( + loop_id, + exp_field, + sub_field, + depth, + data={}, + struc_type="list", + is_empty=True, + original_data=result, + field=field, + ) + else: + if urls: + self._add_to_expanded_fields( + loop_id, + exp_field, + sub_field, + depth, + data=self.get_data(urls), + struc_type="dict", + is_empty=False, + original_data=result, + field=field, + ) + + else: + self._add_to_expanded_fields( + loop_id, + exp_field, + sub_field, + depth, + data={}, + struc_type="dict", + is_empty=True, + original_data=result, + field=field, + ) + else: + if self.next_iter_if_value_is_empty(field.value): + field.is_empty = True + + if not self.expanded_fields: + continue + expansion = self._build_json(expansion) + + for key in ["loop_id", "depth", "code", "parent_code"]: + self.remove_key(expansion, key) + + result["_expand"].update(expansion["_expand"]) + + def _build_json(self, expansion: dict) -> dict: + max_value = max(self.expanded_fields, key=lambda x: x.level).level + for i in range(max_value + 1): + specific_levels = [x for x in self.expanded_fields if x.level == i] + + for index, fields_of_level in enumerate(specific_levels): + if index == 0 and i == 0: + if fields_of_level.type == "list" and not expansion["_expand"].get( + fields_of_level.sub_field, None + ): + expansion["_expand"][fields_of_level.sub_field] = [] + elif fields_of_level.type == "dict" and not expansion[ + "_expand" + ].get(fields_of_level.sub_field, None): + expansion["_expand"][fields_of_level.sub_field] = {} + + if i == 0: + if fields_of_level.type == "list": + skip = False + for field_dict in expansion["_expand"][ + fields_of_level.sub_field + ]: + if fields_of_level.value["url"] == field_dict["url"]: + skip = True + if not skip: + expansion["_expand"][fields_of_level.sub_field].append( + fields_of_level.value + ) + + elif fields_of_level.type == "dict" and not expansion[ + "_expand" + ].get(fields_of_level.sub_field, None): + + expansion["_expand"][ + fields_of_level.sub_field + ] = fields_of_level.value + + else: + match = self.get_parent_dict( + expansion["_expand"], + target_key1="url", + target_key3="code", + target_value1=fields_of_level.parent, + target_value3=fields_of_level.parent_code, + level=i, + field_level=fields_of_level.level, + ) + + if not match: + continue + + for parent_dict in match: + if isinstance(parent_dict, str): + if parent_dict != fields_of_level.sub_field_parent: + continue + parent_dict = match[parent_dict] + if parent_dict.get("url", None) != fields_of_level.parent: + continue + + if not parent_dict.get("_expand", {}) and isinstance( + parent_dict[fields_of_level.sub_field], list + ): + + parent_dict["_expand"] = {fields_of_level.sub_field: []} + elif not parent_dict.get("_expand", {}).get( + fields_of_level.sub_field, None + ) and isinstance(parent_dict[fields_of_level.sub_field], list): + + parent_dict["_expand"].update( + {fields_of_level.sub_field: []} + ) + + elif not parent_dict.get("_expand", {}) and isinstance( + parent_dict[fields_of_level.sub_field], str + ): + parent_dict["_expand"] = {fields_of_level.sub_field: {}} + + elif not parent_dict.get("_expand", {}).get( + fields_of_level.sub_field, None + ) and isinstance(parent_dict[fields_of_level.sub_field], str): + parent_dict["_expand"].update( + {fields_of_level.sub_field: {}} + ) + + if isinstance(parent_dict[fields_of_level.sub_field], list): + add = True + for expand in parent_dict["_expand"][ + fields_of_level.sub_field + ]: + if expand["url"] == fields_of_level.value["url"]: + add = False + + if add: + if fields_of_level.is_empty: + parent_dict["_expand"][ + fields_of_level.sub_field + ] = [] + else: + parent_dict["_expand"][ + fields_of_level.sub_field + ].append(fields_of_level.value) + + elif isinstance(parent_dict[fields_of_level.sub_field], str): + if fields_of_level.is_empty: + parent_dict["_expand"].update( + {fields_of_level.sub_field: {}} + ) + else: + parent_dict["_expand"].update( + {fields_of_level.sub_field: fields_of_level.value} + ) + elif parent_dict[fields_of_level.sub_field] is None: + try: + parent_dict["_expand"].update( + {fields_of_level.sub_field: fields_of_level.value} + ) + except KeyError: + parent_dict["_expand"] = {fields_of_level.sub_field: {}} + + return expansion + + def get_parent_dict( + self, + data, + target_key1, + target_key3, + target_value1, + target_value3, + level, + field_level, + parent=None, + ): + """Get the parent dictionary of the target value.""" + + if isinstance(data, dict): + if target_value3: + to_compare = bool( + data.get(target_key1) == target_value1 + and data.get(target_key3) == target_value3 + and data.get("depth") == level - 1 + ) + elif not target_value3: + to_compare = bool( + data.get(target_key1) == target_value1 + and data.get("depth") == level - 1 + ) + + if to_compare: + return parent + + for key, value in data.items(): + if isinstance(value, (dict, list)): + parent_dict = self.get_parent_dict( + value, + target_key1, + target_key3, + target_value1, + target_value3, + level, + field_level, + parent=data, + ) + if parent_dict is not None: + return parent_dict + + elif isinstance(data, list): + for item in data: + if isinstance(item, (dict, list)): + parent_dict = self.get_parent_dict( + item, + target_key1, + target_key3, + target_value1, + target_value3, + level, + field_level, + parent=data, + ) + if parent_dict is not None: + return parent_dict + return None + + def remove_key(self, data, target_key): + if isinstance(data, dict): + for key in list(data.keys()): + if key == target_key: + del data[key] + elif isinstance(data[key], (dict, list)): + self.remove_key(data[key], target_key) + elif isinstance(data, list): + for item in data: + if isinstance(item, (dict, list)): + self.remove_key(item, target_key) + + def inclusions(self, response): + expand_filter = self.request.query_params.get("expand", "") + if expand_filter: + fields_to_expand = expand_filter.split(",") + if self.action == "list": + for response_data in response.data["results"]: + response_data["_expand"] = {} + self.build_expand_schema( + response_data, + fields_to_expand, + ) + elif self.action == "retrieve": + response.data["_expand"] = {} + self.build_expand_schema(response.data, fields_to_expand) + + return response + + @staticmethod + def convert_camel_to_snake(string): + # Insert underscore before each capital letter + import re + + snake_case = re.sub(r"(? 0 else unique_code, + ) + + field_to_add.value["loop_id"] = loop_id + field_to_add.value["depth"] = field_to_add.level + field_to_add.value["parent_code"] = field.code if depth > 0 else unique_code + field_to_add.value["code"] = unique_code if depth > 0 else unique_code + self.expanded_fields.append(field_to_add) + self.expanded_fields_all.append(field_to_add) + + +class ExpandFieldValidator: + MAX_STEPS_DEPTH = 10 + MAX_EXPANDED_FIELDS = 20 + REGEX = r"^[\w']+([.,][\w']+)*$" # regex checks for field names separated by . or , (e.g "rollen,rollen.statussen") + + def _validate_maximum_depth_reached(self, expanded_fields): + """Validate maximum iterations to prevent infinite recursion""" + for expand_combination in expanded_fields.split(","): + if len(expand_combination.split(".")) > self.MAX_STEPS_DEPTH: + raise serializers.ValidationError( + { + "expand": _( + f"The submitted fields have surpassed its maximum recursion limit of {self.MAX_STEPS_DEPTH}" + ) + }, + code="recursion-limit", + ) + elif len(expanded_fields.split(",")) > self.MAX_EXPANDED_FIELDS: + raise serializers.ValidationError( + { + "expand": _( + f"The submitted expansion string has surpassed its maximum limit of {self.MAX_EXPANDED_FIELDS}" + ) + }, + code="max-str-length", + ) + + def _validate_regex(self, expanded_fields): + if not re.match(self.REGEX, expanded_fields): + raise serializers.ValidationError( + { + "expand": _( + f"The submitted expand fields do not match the required regex of {self.REGEX}" + ) + }, + code="expand-format-error", + ) + + def list(self, request, *args, **kwargs): + expand_filter = request.query_params.get("expand", "") + + if not request.query_params or not expand_filter: + return super().list(request, *args, **kwargs) + + self._validate_regex(expand_filter) + self._validate_maximum_depth_reached(expand_filter) + return super().list(request, *args, **kwargs) diff --git a/src/zrc/api/filters.py b/src/zrc/api/filters.py index 300fb389..055987d6 100644 --- a/src/zrc/api/filters.py +++ b/src/zrc/api/filters.py @@ -1,6 +1,8 @@ from django.utils.translation import ugettext_lazy as _ from django_filters import filters +from drf_spectacular.types import OpenApiTypes +from drf_spectacular.utils import extend_schema_field from vng_api_common.constants import VertrouwelijkheidsAanduiding from vng_api_common.filtersets import FilterSet from vng_api_common.utils import get_field_attribute, get_help_text @@ -22,6 +24,11 @@ def get_most_recent_status(queryset, name, value): return queryset.order_by("-datum_status_gezet")[:1] +def expand_filter(queryset, name, value): + """expansion filter logic is placed at view level""" + return queryset + + class MaximaleVertrouwelijkheidaanduidingFilter(filters.ChoiceFilter): def __init__(self, *args, **kwargs): kwargs.setdefault("choices", VertrouwelijkheidsAanduiding.choices) @@ -126,6 +133,17 @@ class ZaakFilter(FilterSet): help_text="Het veld waarop de resultaten geordend worden.", ) + expand = extend_schema_field(OpenApiTypes.STR)( + filters.CharFilter( + method=expand_filter, + help_text=_( + "Examples: \n" + "`expand=zaaktype, status, status.statustype, hoofdzaak.status.statustype, hoofdzaak.deelzaken.status.statustype`\n" + "Haal details van gelinkte resources direct op. Als je meerdere resources tegelijk wilt ophalen kun je deze scheiden met een komma. Voor het ophalen van resources die een laag dieper genest zijn wordt de punt-notatie gebruikt.", + ), + ) + ) + class Meta: model = Zaak fields = { diff --git a/src/zrc/api/serializers/core.py b/src/zrc/api/serializers/core.py index 531bde20..84225b01 100644 --- a/src/zrc/api/serializers/core.py +++ b/src/zrc/api/serializers/core.py @@ -337,7 +337,6 @@ class Meta: "zaaktype": { # TODO: does order matter here with the default validators? "validators": [ - IsImmutableValidator(), PublishValidator( "ZaakType", settings.ZTC_API_SPEC, get_auth=get_auth ), diff --git a/src/zrc/api/tests/test_dso_api_strategy.py b/src/zrc/api/tests/test_dso_api_strategy.py index bfe6b70a..1491203e 100644 --- a/src/zrc/api/tests/test_dso_api_strategy.py +++ b/src/zrc/api/tests/test_dso_api_strategy.py @@ -23,7 +23,7 @@ def test_api_19_documentation_version_yaml(self): @override_settings(ROOT_URLCONF="zrc.api.tests.test_urls") def test_api_24_version_header(self): response = self.client.get("/test-view") - self.assertEqual(response["API-version"], "1.4.0") + self.assertEqual(response["API-version"], "1.5.0") class DSOApi50Tests(APITestCase): diff --git a/src/zrc/api/tests/test_validation.py b/src/zrc/api/tests/test_validation.py index 93478b5a..b5ad5489 100644 --- a/src/zrc/api/tests/test_validation.py +++ b/src/zrc/api/tests/test_validation.py @@ -618,19 +618,6 @@ def test_validate_verlenging_required_fields_partial_update(self): error = get_validation_errors(response, field) self.assertEqual(error["code"], "required") - @override_settings(LINK_FETCHER="vng_api_common.mocks.link_fetcher_200") - def test_not_allowed_to_change_zaaktype(self): - zaak = ZaakFactory.create() - url = reverse(zaak) - - response = self.client.patch( - url, {"zaaktype": "https://ander.zaaktype.nl/foo/bar"}, **ZAAK_WRITE_KWARGS - ) - - self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - validation_error = get_validation_errors(response, "zaaktype") - self.assertEqual(validation_error["code"], IsImmutableValidator.code) - @override_settings(LINK_FETCHER="vng_api_common.mocks.link_fetcher_200") def test_not_allowed_to_change_identificatie(self): zaak = ZaakFactory.create(identificatie="gibberish") diff --git a/src/zrc/api/tests/test_zaken.py b/src/zrc/api/tests/test_zaken.py index 24db5b00..a9928cef 100644 --- a/src/zrc/api/tests/test_zaken.py +++ b/src/zrc/api/tests/test_zaken.py @@ -1,4 +1,5 @@ import unittest +import uuid from datetime import date, timedelta from unittest.mock import patch @@ -15,6 +16,7 @@ RolOmschrijving, RolTypes, VertrouwelijkheidsAanduiding, + ZaakobjectTypes, ) from vng_api_common.tests import ( JWTAuthMixin, @@ -31,6 +33,7 @@ NatuurlijkPersoon, NietNatuurlijkPersoon, OrganisatorischeEenheid, + RelevanteZaakRelatie, Vestiging, Zaak, ) @@ -59,6 +62,7 @@ SCOPE_ZAKEN_CREATE, SCOPEN_ZAKEN_HEROPENEN, ) +from .test_zaakobject import OBJECT # ZTC ZTC_ROOT = "https://example.com/ztc/api/v1" @@ -1149,6 +1153,168 @@ def test_rol_vestiging_vestigings_nummer(self): self.assertEqual(response.data["count"], 1) +@override_settings( + LINK_FETCHER="vng_api_common.mocks.link_fetcher_200", + ZDS_CLIENT_CLASS="vng_api_common.mocks.MockClient", +) +class ZakenExpandTests(ZaakInformatieObjectSyncMixin, JWTAuthMixin, APITestCase): + heeft_alle_autorisaties = True + ZTC_ROOT = "https://example.com/ztc/api/v1" + CATALOGUS = f"{ZTC_ROOT}/catalogus/878a3318-5950-4642-8715-189745f91b04" + ZAAKTYPE = f"{CATALOGUS}/zaaktypen/283ffaf5-8470-457b-8064-90e5728f413f" + EIGENSCHAP = f"{ZTC_ROOT}/eigenschappen/f420c3e0-8345-44d9-a981-0f424538b9e9" + ZAAKOBJECTTYPE = ( + "http://testserver/api/v1/zaakobjecttypen/c340323d-31a5-46b4-93e8-fdc2d621be13" + ) + INFORMATIEOBJECT = f"http://example.com/drc/api/v1/enkelvoudiginformatieobjecten/{uuid.uuid4().hex}" + + @override_settings(ZDS_CLIENT_CLASS="vng_api_common.mocks.MockClient") + @patch("vng_api_common.validators.fetcher") + @patch("vng_api_common.validators.obj_has_shape", return_value=True) + def test_list_expand_filter_few_levels_deep(self, *mocks): + zaak = ZaakFactory.create() + + # zaak.zaaktype = "https://catalogi-api.test.vng.cloud/api/v1/zaaktypen/7e3353ef-d5da-4c1d-9155-a79c89194121" + # + # zaak2 = ZaakFactory.create() + # zaak2.zaaktype = "https://catalogi-api.test.vng.cloud/api/v1/zaaktypen/ed15c69d-15cd-4bc7-bc1a-b5d21d45dc36" + # zaak2.save() + + url = reverse("zaak-detail", kwargs={"uuid": zaak.uuid}) + + zaakrelatie = RelevanteZaakRelatie.objects.create( + zaak=zaak, url=url, aard_relatie="test" + ) + zaak.relevante_andere_zaken.add(zaakrelatie) + zaak.save() + + zaakeigenschap = ZaakEigenschapFactory.create( + zaak=zaak, eigenschap=self.EIGENSCHAP, waarde="This is a value" + ) + zaakeigenschap2 = ZaakEigenschapFactory.create( + zaak=zaak, eigenschap=self.EIGENSCHAP, waarde="This is a value" + ) + zaakeigenschap3 = ZaakEigenschapFactory.create( + zaak=zaak, eigenschap=self.EIGENSCHAP, waarde="This is a value" + ) + + # zaakeigenschap = ZaakEigenschapFactory.create( + # zaak=zaak2, eigenschap=self.EIGENSCHAP, waarde="This is a value" + # ) + zaakobject = ZaakObjectFactory.create( + zaak=zaak, + object=OBJECT, + object_type=ZaakobjectTypes.besluit, + zaakobjecttype=self.ZAAKOBJECTTYPE, + ) + # zaakobject = ZaakObjectFactory.create( + # zaak=zaak2, + # object=OBJECT, + # object_type=ZaakobjectTypes.besluit, + # zaakobjecttype=self.ZAAKOBJECTTYPE, + # ) + zio = ZaakInformatieObjectFactory.create(zaak=zaak) + # + rol = RolFactory.create( + zaak=zaak, + ) + # rol.roltype = "https://catalogi-api.test.vng.cloud/api/v1/roltypen/d03562e0-2feb-4d46-bf56-ed1d71122996" + # rol.save() + + # zaakobject.zaakobjecttype = "https://catalogi-api.test.vng.cloud/api/v1/zaakobjecttypen/f5a24710-6902-44f3-b4dd-9e75bd4c1403" + # zaakobject.save() + + status1 = StatusFactory.create(zaak=zaak) + rol.statussen.add(status1) + + rol2 = RolFactory.create( + zaak=zaak, + ) + rol3 = RolFactory.create( + zaak=zaak, + ) + rol4 = RolFactory.create( + zaak=zaak, + ) + rol2.statussen.add(status1) + + url = reverse("zaak-list") + expand_params = [ + "rollen.statussen.zaak.rollen,zaakinformatieobjecten,zaakobjecten.zaak,eigenschappen", + "relevanteAndereZaken.zaaktype", + "zaaktype.besluittypen,status.statustype,zaaktype.catalogus", + "rollen.zaak.rollen.zaak.rollen", + "zaaktype,rollen.statussen.zaak,status.zaak,zaakobjecten,zaakinformatieobjecten", + "zaaktype.catalogus.zaaktypen", + "zaaktype.besluittypen.zaaktypen", + "status.statustype,status.gezetdoor", + "zaaktype.gerelateerdeZaaktypen", + "zaaktype.zaakobjecttypen,zaaktype.statustypen", + "zaaktype.deelzaaktypen", + "zaaktype.eigenschappen.statustype", + "rollen.statussen,rollen.zaak", + "zaaktype.eigenschappen.catalogus,zaaktype.eigenschappen.zaaktype,zaaktype.eigenschappen.statustype", + "status,zaaktype", + "zaaktype,hoofdzaak,deelzaken,relevanteAndereZaken,eigenschappen,rollen,status,zaakobjecten,resultaat", + "status.zaak,status.statustype,status.gezetdoor", + "rollen.roltype", + "zaakobjecten.zaakobjecttype", + ] + for param in expand_params: + with self.subTest(param=param): + response = self.client.get( + url, + {"expand": param}, + **ZAAK_READ_KWARGS, + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + # from pprint import pprint + # + # pprint(response.json()["results"][0]["_expand"]) + + @override_settings(ZDS_CLIENT_CLASS="vng_api_common.mocks.MockClient") + @patch("vng_api_common.validators.fetcher") + @patch("vng_api_common.validators.obj_has_shape", return_value=True) + def test_get_expand_filter_few_levels_deep(self, *mocks): + zaak = ZaakFactory.create() + zaak2 = ZaakFactory.create() + + url = reverse("zaak-detail", kwargs={"uuid": zaak.uuid}) + + zaakrelatie = RelevanteZaakRelatie.objects.create( + zaak=zaak, url=url, aard_relatie="test" + ) + zaak.relevante_andere_zaken.add(zaakrelatie) + zaak.save() + + zaakobject = ZaakObjectFactory.create( + zaak=zaak, + object=OBJECT, + object_type=ZaakobjectTypes.besluit, + zaakobjecttype=self.ZAAKOBJECTTYPE, + ) + + zio = ZaakInformatieObjectFactory.create(zaak=zaak) + + rol = RolFactory.create( + zaak=zaak, + ) + + status1 = StatusFactory.create(zaak=zaak) + rol.statussen.add(status1) + + rol2 = RolFactory.create( + zaak=zaak, + ) + + response = self.client.get( + url, + {"expand": "rollen.statussen,rollen.zaak"}, + **ZAAK_READ_KWARGS, + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + class ZakenWerkVoorraadTests(JWTAuthMixin, APITestCase): """ Test that the queries to build up a 'werkvoorraad' work as expected. diff --git a/src/zrc/api/utils.py b/src/zrc/api/utils.py index 0b94c5f6..7ac30bc7 100644 --- a/src/zrc/api/utils.py +++ b/src/zrc/api/utils.py @@ -9,6 +9,5 @@ def get_absolute_url(url_name: str, uuid: str) -> str: url_name, kwargs={"version": settings.REST_FRAMEWORK["DEFAULT_VERSION"], "uuid": uuid}, ) - domain = Site.objects.get_current().domain - protocol = "https" if settings.IS_HTTPS else "http" - return f"{protocol}://{domain}{path}" + domain = settings.ZRC_BASE_URL + return f"{domain}{path}" diff --git a/src/zrc/api/viewsets.py b/src/zrc/api/viewsets.py index f916558e..801feaa8 100644 --- a/src/zrc/api/viewsets.py +++ b/src/zrc/api/viewsets.py @@ -48,6 +48,7 @@ from .audits import AUDIT_ZRC from .data_filtering import ListFilterByAuthorizationsMixin +from .expansions import ExpandFieldValidator, ExpansionMixin from .filters import ( KlantContactFilter, ResultaatFilter, @@ -124,7 +125,6 @@ summary=_("Werk een ZAAK deels bij."), description=_( "**Er wordt gevalideerd op** \n" - "- `zaaktype` mag niet gewijzigd worden.\n" "- `identificatie` mag niet gewijzigd worden.\n" "- `laatsteBetaaldatum` mag niet in de toekomst liggen.\n" "- `laatsteBetaaldatum` mag niet gezet worden als de betalingsindicatie\n" @@ -147,7 +147,6 @@ summary=_("Werk een ZAAK in zijn geheel bij."), description=_( "**Er wordt gevalideerd op** \n" - "- `zaaktype` mag niet gewijzigd worden.\n" "- `identificatie` mag niet gewijzigd worden.\n" "- `laatsteBetaaldatum` mag niet in de toekomst liggen.\n" "- `laatsteBetaaldatum` mag niet gezet worden als de betalingsindicatie\n" @@ -197,6 +196,8 @@ class ZaakViewSet( GeoMixin, SearchMixin, CheckQueryParamsMixin, + ExpandFieldValidator, + ExpansionMixin, ListFilterByAuthorizationsMixin, viewsets.ModelViewSet, ): diff --git a/src/zrc/conf/includes/api.py b/src/zrc/conf/includes/api.py index a7987986..f1ee1d8b 100644 --- a/src/zrc/conf/includes/api.py +++ b/src/zrc/conf/includes/api.py @@ -2,13 +2,13 @@ from vng_api_common.conf.api import * # noqa - imports white-listed -API_VERSION = "1.4.0" +API_VERSION = "1.5.0" REST_FRAMEWORK = BASE_REST_FRAMEWORK.copy() REST_FRAMEWORK["PAGE_SIZE"] = 100 DOCUMENTATION_INFO_MODULE = "zrc.api.schema" - +ZRC_BASE_URL = os.getenv("ZRC_BASE_URL", "https://zaken-api.test.vng.cloud") SPECTACULAR_SETTINGS = BASE_SPECTACULAR_SETTINGS.copy() SPECTACULAR_SETTINGS.update( { @@ -17,7 +17,7 @@ # e.g. [{'url': 'https://example.com/v1', 'description': 'Text'}, ...] "SERVERS": [ { - "url": "https://zaken-api.vng.cloud/api/v1", + "url": "https://zaken-api.vng.cloud/api/v1/", "description": "Productie Omgeving", } ], diff --git a/src/zrc/sync/signals.py b/src/zrc/sync/signals.py index 27d61a71..f5d6ea8c 100644 --- a/src/zrc/sync/signals.py +++ b/src/zrc/sync/signals.py @@ -20,7 +20,6 @@ class SyncError(Exception): def sync_create_zio(relation: ZaakInformatieObject): zaak_url = get_absolute_url("zaak-detail", relation.zaak.uuid) - logger.info("Zaak: %s", zaak_url) logger.info("Informatieobject: %s", relation.informatieobject)