diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 18284411..9f9a4d11 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,7 +1,7 @@ [bumpversion] commit = False tag = False -current_version = 1.4.1 +current_version = 1.4.2 parse = (?P\d+)\.(?P\d+)\.(?P\d+)([-](?P(rc|alpha))+(?P\d+))? serialize = {major}.{minor}.{patch}-{release}{build} diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 13af465b..bef7ec13 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,12 @@ =========== Wijzigingen +=========== +1.4.2 (2023-09-25) +=========== + +- **Changed:** added expand queryparameter to /zoek +- **Changed:** bestandsdeel serializer to include lock attribute + =========== 1.4.1 (2023-08-29) =========== diff --git a/README.rst b/README.rst index ece4cc7d..3c94fcb1 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,7 @@ Documenten API ============== -:Version: 1.4.0 +:Version: 1.4.2 :Source: https://github.com/VNG-Realisatie/documenten-api :Keywords: zaken, zaakgericht werken, GEMMA, RGBZ, DRC @@ -28,16 +28,16 @@ master n.v.t. `ReDoc `_ 1.4.0 2023-08-22 `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ `Swagger `_ -1.3.x 2023-03-29 `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ +1.3.0 2023-03-29 `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ `Swagger `_ (`verschillen `_) -1.2.x 2022-12-19 `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ +1.2.0 2022-12-19 `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ `Swagger `_ (`verschillen `_) -1.1.x 2022-06-30 `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ +1.1.0 2022-06-30 `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ `Swagger `_ (`verschillen `_) -1.0.x n.v.t. `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ +1.0.0 n.v.t. `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ `Swagger `_ (`verschillen `_) 1.0.1 2019-12-16 `ReDoc `_, `Scopes `_ `Berichtkenmerken `_ diff --git a/package.json b/package.json index 6b311002..b7a4c1dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "drc", - "version": "1.4.1", + "version": "1.4.2", "description": "drc referentie implementatie API", "main": "src/index.js", "directories": { diff --git a/src/drc/__init__.py b/src/drc/__init__.py index 17a00d60..1264f0ce 100644 --- a/src/drc/__init__.py +++ b/src/drc/__init__.py @@ -7,7 +7,7 @@ import re from collections import namedtuple -__version__ = "1.4.1" +__version__ = "1.4.2" __author__ = "VNG Realisatie" __homepage__ = "https://github.com/VNG-Realisatie/documenten-api" __docformat__ = "restructuredtext" diff --git a/src/drc/api/exclusions.py b/src/drc/api/exclusions.py index 11234cf1..f5b7373a 100644 --- a/src/drc/api/exclusions.py +++ b/src/drc/api/exclusions.py @@ -185,6 +185,7 @@ def build_expand_schema( ): """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": {}} + self.expanded_fields_all = [] for exp_field in fields_to_expand: loop_id = str(uuid.uuid4()) @@ -509,9 +510,11 @@ def remove_key(self, data, target_key): def inclusions(self, response): expand_filter = self.request.query_params.get("expand", "") + if self.action == "_zoek": + expand_filter = self.get_search_input().get("expand", "") if expand_filter: fields_to_expand = expand_filter.split(",") - if self.action == "list": + if self.action == "list" or self.action == "_zoek": for response_data in ( response.data if isinstance(response.data, list) diff --git a/src/drc/api/serializers/enkelvoudig_informatieobject.py b/src/drc/api/serializers/enkelvoudig_informatieobject.py index cf18b6d6..4d17de29 100644 --- a/src/drc/api/serializers/enkelvoudig_informatieobject.py +++ b/src/drc/api/serializers/enkelvoudig_informatieobject.py @@ -500,6 +500,14 @@ class EIOZoekSerializer(serializers.Serializer): child=serializers.UUIDField(), help_text=_("Array of unieke resource identifiers (UUID4)"), ) + expand = serializers.CharField( + 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.", + ), + required=False, + ) class SchemaEIOSerializer(EnkelvoudigInformatieObjectSerializer): diff --git a/src/drc/api/tests/test_dso_api_strategy.py b/src/drc/api/tests/test_dso_api_strategy.py index f5f5581e..a5b2a31f 100644 --- a/src/drc/api/tests/test_dso_api_strategy.py +++ b/src/drc/api/tests/test_dso_api_strategy.py @@ -23,7 +23,7 @@ def test_api_19_documentation_version_yaml(self): @override_settings(ROOT_URLCONF="drc.api.tests.test_urls") def test_api_24_version_header(self): response = self.client.get("/test-view") - self.assertEqual(response["API-version"], "1.4.1") + self.assertEqual(response["API-version"], "1.4.2") class DSOApi50Tests(APITestCase): diff --git a/src/drc/api/tests/test_enkelvoudiginformatieobject.py b/src/drc/api/tests/test_enkelvoudiginformatieobject.py index c8debc32..c6cecf2c 100644 --- a/src/drc/api/tests/test_enkelvoudiginformatieobject.py +++ b/src/drc/api/tests/test_enkelvoudiginformatieobject.py @@ -696,6 +696,19 @@ def test_zoek_uuid_in(self): self.assertEqual(data[0]["url"], f"http://testserver{reverse(eio1)}") self.assertEqual(data[1]["url"], f"http://testserver{reverse(eio2)}") + def test_zoek_expand(self): + eio1, eio2, eio3 = EnkelvoudigInformatieObjectFactory.create_batch(3) + url = get_operation_url("enkelvoudiginformatieobject__zoek") + data = {"uuid__in": [eio1.uuid, eio2.uuid], "expand": "url"} + response = self.client.post(url, data) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + data = response.json()["results"] + data = sorted(data, key=lambda eio: eio["identificatie"]) + self.assertEqual(len(data), 2) + self.assertTrue(bool(data[0]["_expand"])) + def test_zoek_without_params(self): url = get_operation_url("enkelvoudiginformatieobject__zoek") response = self.client.post(url, {}) diff --git a/src/drc/api/views/enkelvoudig_informatieobject.py b/src/drc/api/views/enkelvoudig_informatieobject.py index 43d5eb52..8da96a10 100644 --- a/src/drc/api/views/enkelvoudig_informatieobject.py +++ b/src/drc/api/views/enkelvoudig_informatieobject.py @@ -1,4 +1,4 @@ -from django.db import transaction +from django.db import models, transaction from django.utils.translation import gettext as _ from drf_spectacular.types import OpenApiTypes @@ -214,12 +214,18 @@ def _zoek(self, request, *args, **kwargs): search_input = self.get_search_input() queryset = self.filter_queryset(self.get_queryset()) for name, value in search_input.items(): + if name == "expand": + continue queryset = queryset.filter(**{name: value}) return self.get_search_output(queryset) _zoek.is_search_action = True + def get_search_output(self, queryset: models.QuerySet): + response = super().get_search_output(queryset) + return self.inclusions(response) + @transaction.atomic def perform_destroy(self, instance): if instance.canonical.objectinformatieobject_set.exists(): @@ -265,6 +271,12 @@ def get_serializer_class(self, *args, **kwargs): def retrieve(self, request, *args, **kwargs): return super().retrieve(request, *args, **kwargs) + @extend_schema( + responses=SchemaEIOSerializer, + ) + def create(self, request, *args, **kwargs): + return super().create(request, *args, **kwargs) + @extend_schema( # see https://swagger.io/docs/specification/2-0/describing-responses/ and # https://swagger.io/docs/specification/2-0/mime-types/ diff --git a/src/drc/conf/api.py b/src/drc/conf/api.py index b2956865..b5e85cc7 100644 --- a/src/drc/conf/api.py +++ b/src/drc/conf/api.py @@ -2,7 +2,8 @@ from vng_api_common.conf.api import * # noqa - imports white-listed -API_VERSION = "1.4.1" +API_VERSION = "1.4.2" + REST_FRAMEWORK = BASE_REST_FRAMEWORK.copy() REST_FRAMEWORK["PAGE_SIZE"] = 100 diff --git a/src/openapi.yaml b/src/openapi.yaml index ee9c461d..97060041 100644 --- a/src/openapi.yaml +++ b/src/openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: title: Documenten API - version: 1.4.1 + version: 1.4.2 description: "Een API om een documentregistratiecomponent (DRC) te benaderen.\n\n\ In een documentregistratiecomponent worden INFORMATIEOBJECTen opgeslagen. Een\n\ @@ -472,7 +472,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/EnkelvoudigInformatieObjectCreateLock' + $ref: '#/components/schemas/SchemaEIO' description: Created '400': headers: @@ -5825,279 +5825,21 @@ components: title: '' description: Array of unieke resource identifiers (UUID4) title: uuid__in - required: - - uuid_In - EnkelvoudigInformatieObject: - type: object - description: Serializer for the EnkelvoudigInformatieObject model - properties: - url: + expand: 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 - identificatie: - type: string - description: - Een binnen een gegeven context ondubbelzinnige referentie naar - het INFORMATIEOBJECT. - title: identificatie - maxLength: 40 - bronorganisatie: - type: string - description: - "Het RSIN van de Niet-natuurlijk persoon zijnde de organisatie\ - \ die het informatieobject heeft gecre\xEBerd of heeft ontvangen en als\ - \ eerste in een samenwerkingsketen heeft vastgelegd." - title: bronorganisatie - maxLength: 9 - creatiedatum: - type: string - format: date - description: Een datum of een gebeurtenis in de levenscyclus van het INFORMATIEOBJECT. - title: creatiedatum - titel: - type: string - description: De naam waaronder het INFORMATIEOBJECT formeel bekend is. - title: titel - maxLength: 200 - vertrouwelijkheidaanduiding: - description: - 'Aanduiding van de mate waarin het INFORMATIEOBJECT voor de - openbaarheid bestemd is. - - - 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: vertrouwelijkheidaanduiding - oneOf: - - $ref: '#/components/schemas/VertrouwelijkheidaanduidingEnum' - - $ref: '#/components/schemas/BlankEnum' - auteur: - type: string - description: - "De persoon of organisatie die in de eerste plaats verantwoordelijk\ - \ is voor het cre\xEBren van de inhoud van het INFORMATIEOBJECT." - title: auteur - maxLength: 200 - status: - description: - "Aanduiding van de stand van zaken van een INFORMATIEOBJECT. - De waarden 'in bewerking' en 'ter vaststelling' komen niet voor als - het attribuut `ontvangstdatum` van een waarde is voorzien. Wijziging van - de Status in 'gearchiveerd' impliceert dat het informatieobject een - duurzaam, niet-wijzigbaar Formaat dient te hebben. - - - Uitleg bij mogelijke waarden: - - - * `in_bewerking` - (In bewerking) Aan het informatieobject wordt nog gewerkt. - - * `ter_vaststelling` - (Ter vaststelling) Informatieobject gereed maar - moet nog vastgesteld worden. - - * `definitief` - (Definitief) Informatieobject door bevoegd iets of iemand - vastgesteld dan wel ontvangen. - - * `gearchiveerd` - (Gearchiveerd) Informatieobject duurzaam bewaarbaar - gemaakt; een gearchiveerd informatie-element." - title: status - oneOf: - - $ref: '#/components/schemas/StatusEnum' - - $ref: '#/components/schemas/BlankEnum' - formaat: - type: string - description: - 'Het "Media Type" (voorheen "MIME type") voor de wijze waaropde - inhoud van het INFORMATIEOBJECT is vastgelegd in een computerbestand. - Voorbeeld: `application/msword`. Zie: https://www.iana.org/assignments/media-types/media-types.xhtml' - title: formaat - maxLength: 255 - taal: - type: string - description: - 'Een ISO 639-2/B taalcode waarin de inhoud van het INFORMATIEOBJECT - is vastgelegd. Voorbeeld: `dut`. Zie: https://www.iso.org/standard/4767.html' - title: taal - maxLength: 3 - minLength: 3 - versie: - type: integer - readOnly: true - description: - Het (automatische) versienummer van het INFORMATIEOBJECT. Deze - begint bij 1 als het INFORMATIEOBJECT aangemaakt wordt. - title: versie - beginRegistratie: - type: string - format: date-time - readOnly: true - description: - Een datumtijd in ISO8601 formaat waarop deze versie van het - INFORMATIEOBJECT is aangemaakt of gewijzigd. - title: begin registratie - bestandsnaam: - type: string - description: - De naam van het fysieke bestand waarin de inhoud van het informatieobject - is vastgelegd, inclusief extensie. - title: bestandsnaam - maxLength: 255 - inhoud: - type: string - format: uri - description: Download URL van de binaire inhoud. - nullable: true - title: inhoud - bestandsomvang: - type: integer - maximum: 9223372036854775807 - minimum: 0 - format: int64 - nullable: true - description: Aantal bytes dat de inhoud van INFORMATIEOBJECT in beslag neemt. - title: bestandsomvang - link: - type: string - format: uri - description: - De URL waarmee de inhoud van het INFORMATIEOBJECT op te vragen - is. - title: link - maxLength: 200 - beschrijving: - type: string - description: Een generieke beschrijving van de inhoud van het INFORMATIEOBJECT. - title: beschrijving - maxLength: 1000 - ontvangstdatum: - type: string - format: date - nullable: true - description: - "**DEPRECATED** Dit attribuut is verplaatst naar resource Verzending.\ - \ \n\n De datum waarop het INFORMATIEOBJECT ontvangen is. Verplicht te\ - \ registreren voor INFORMATIEOBJECTen die van buiten de zaakbehandelende\ - \ organisatie(s) ontvangen zijn. Ontvangst en verzending is voorbehouden\ - \ aan documenten die van of naar andere personen ontvangen of verzonden\ - \ zijn waarbij die personen niet deel uit maken van de behandeling van\ - \ de zaak waarin het document een rol speelt." - title: ontvangstdatum - verzenddatum: - type: string - format: date - nullable: true - description: - "**DEPRECATED** Dit attribuut is verplaatst naar resource Verzending.\ - \ \n\n De datum waarop het INFORMATIEOBJECT verzonden is, zoals deze op\ - \ het INFORMATIEOBJECT vermeld is. Dit geldt voor zowel inkomende als\ - \ uitgaande INFORMATIEOBJECTen. Eenzelfde informatieobject kan niet tegelijk\ - \ inkomend en uitgaand zijn. Ontvangst en verzending is voorbehouden aan\ - \ documenten die van of naar andere personen ontvangen of verzonden zijn\ - \ waarbij die personen niet deel uit maken van de behandeling van de zaak\ - \ waarin het document een rol speelt." - title: verzenddatum - indicatieGebruiksrecht: - type: boolean - nullable: true - description: - Indicatie of er beperkingen gelden aangaande het gebruik van - het informatieobject anders dan raadpleging. Dit veld mag `null` zijn - om aan te geven dat de indicatie nog niet bekend is. Als de indicatie - gezet is, dan kan je de gebruiksrechten die van toepassing zijn raadplegen - via de GEBRUIKSRECHTen resource. - title: indicatie gebruiksrecht - verschijningsvorm: - type: string - description: "De essenti\xEBle opmaakaspecten van een INFORMATIEOBJECT." - title: verschijningsvorm - ondertekening: - allOf: - - $ref: '#/components/schemas/Ondertekening' - nullable: true - description: - Aanduiding van de rechtskracht van een informatieobject. Mag - niet van een waarde zijn voorzien als de `status` de waarde 'in bewerking' - of 'ter vaststelling' heeft. - title: ondertekening - integriteit: - allOf: - - $ref: '#/components/schemas/Integriteit' - nullable: true description: - Uitdrukking van mate van volledigheid en onbeschadigd zijn - van digitaal bestand. - title: integriteit - informatieobjecttype: - type: string - format: uri - description: - URL-referentie naar het INFORMATIEOBJECTTYPE (in de Catalogi - API). - title: informatieobjecttype - maxLength: 200 - locked: - type: boolean - readOnly: true - description: - Geeft aan of het document gelocked is. Alleen als een document - gelocked is, mogen er aanpassingen gemaakt worden. - title: locked - bestandsdelen: - type: array - items: - $ref: '#/components/schemas/BestandsDeel' - readOnly: true - title: bestandsdelen - trefwoorden: - type: array - items: - type: string - maxLength: 100 - nullable: true - description: Een lijst van trefwoorden gescheiden door comma's. - title: trefwoorden + "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." + title: expand required: - - auteur - - beginRegistratie - - bestandsdelen - - bronorganisatie - - creatiedatum - - informatieobjecttype - - locked - - taal - - titel - - url - - versie - EnkelvoudigInformatieObjectCreateLock: + - uuid_In + EnkelvoudigInformatieObject: type: object - description: - 'This serializer class is used by EnkelvoudigInformatieObjectViewSet - for - - create operation for large files' + description: Serializer for the EnkelvoudigInformatieObject model properties: url: type: string @@ -6347,14 +6089,6 @@ components: nullable: true description: Een lijst van trefwoorden gescheiden door comma's. title: trefwoorden - lock: - type: string - readOnly: true - description: - Lock id generated if the large file is created and should be - used while updating the document. Documents with base64 encoded files - are created without lock - title: lock required: - auteur - beginRegistratie @@ -6362,7 +6096,6 @@ components: - bronorganisatie - creatiedatum - informatieobjecttype - - lock - locked - taal - titel