Esempio n. 1
0
    def get_client_response(self) -> List[dict]:
        variables = self.task.get_variables()
        email_notification_list = variables.get("emailNotificationList", {})
        usernames = []
        groupnames = []
        emails = []
        try:
            assignees = check_variable(variables, "usernames")
            for assignee in assignees:
                # To not change normal expected behavior:
                # if no emailNotificationList is found in variables everybody gets an email
                if email_notification_list.get(
                        assignee) or not email_notification_list:
                    group_or_user, name = assignee.split(":", 1)
                    if group_or_user.lower() == "group":
                        groupnames.append(name)
                    else:
                        usernames.append(name)

        except MissingVariable:
            try:
                emails = check_variable(variables, "emailaddresses")
            except MissingVariable:
                raise MissingVariable(
                    "Missing one of the required variables usernames or emailaddresses."
                )

        users = []
        with get_client(self.task) as client:
            if usernames:
                username_assignees = client.get(
                    "api/accounts/users",
                    params={"include_username": usernames})
                for user in username_assignees["results"]:
                    user["assignee"] = f'user:{user["username"]}'
                users += username_assignees["results"]

            if groupnames:
                groups = {}

                def _get_group_users(group: str):
                    nonlocal groups, client
                    groups[group] = client.get(
                        "api/accounts/users",
                        params={"include_groups": [group]})

                with parallel() as executor:
                    list(executor.map(_get_group_users, groupnames))
                for group, groupusers in groups.items():
                    for user in groupusers["results"]:
                        user["assignee"] = f"group:{group}"

                    users += groupusers["results"]

            if emails:
                users += client.get("api/accounts/users",
                                    params={"include_email":
                                            emails})["results"]

        return users
Esempio n. 2
0
    def perform(self) -> dict:
        warnings.warn(
            "The `RelatedPand` task is deprected in favour of `CreateZaakObject`. "
            "It will be removed in 1.0.",
            DeprecationWarning,
        )
        # prep client
        zrc_client = self.get_client(APITypes.zrc)

        # get vars
        variables = self.task.get_variables()

        zaak_url = check_variable(variables, "zaakUrl")
        pand_urls = check_variable(variables, "panden", empty_allowed=True)

        # See https://zaken-api.vng.cloud/api/v1/schema/#operation/zaakobject_create
        bodies = [
            {
                "zaak": zaak_url,
                "object": self._clean_url(pand_url),
                "objectType": "pand",
                "relatieomschrijving": "",  # TODO -> process var?
            }
            for pand_url in pand_urls
        ]

        headers = get_nlx_headers(variables)

        def _api_call(body):
            zrc_client.create("zaakobject", body, request_kwargs={"headers": headers})

        with futures.ThreadPoolExecutor() as executor:
            executor.map(_api_call, bodies)

        return {}
Esempio n. 3
0
    def perform(self) -> dict:

        variables = self.task.get_variables()

        package_id = check_variable(variables, "packageId")
        email = check_variable(variables, "email")

        self.send_reminder(package_id, email)

        return {}
Esempio n. 4
0
 def create_zaakobject(self, variables: dict) -> dict:
     zrc_client = self.get_client(APITypes.zrc)
     data = {
         "zaak": check_variable(variables, "zaakUrl"),
         "object": check_variable(variables, "objectUrl"),
         "objectType": check_variable(variables, "objectType"),
         "objectTypeOverige": variables.get("objectTypeOverige", ""),
         "relatieomschrijving": variables.get("relatieomschrijving", ""),
     }
     zaakobject = zrc_client.create("zaakobject", data)
     return zaakobject
Esempio n. 5
0
    def perform(self) -> dict:
        # prep clients
        ztc_client = self.get_client(APITypes.ztc)
        zrc_client = self.get_client(APITypes.zrc)

        # get vars
        variables = self.task.get_variables()

        zaak_url = check_variable(variables, "zaakUrl")
        zaak_uuid = zaak_url.split("/")[-1]
        eigenschap = check_variable(variables, "eigenschap", empty_allowed=True)
        if not eigenschap:
            return {}

        naam = check_variable(eigenschap, "naam")
        waarde = check_variable(eigenschap, "waarde", empty_allowed=True)
        if not waarde:
            return {}

        # fetch zaaktype - either from process variable or derive from zaak
        zaaktype = variables.get("zaaktype")
        if zaaktype is None or not isinstance(zaaktype, str):
            zaak = zrc_client.retrieve("zaak", uuid=zaak_uuid)
            zaaktype = zaak["zaaktype"]

        # fetch eigenschappen
        eigenschappen = get_paginated_results(
            ztc_client, "eigenschap", query_params={"zaaktype": zaaktype}
        )
        try:
            eigenschap_url = next(
                (
                    eigenschap["url"]
                    for eigenschap in eigenschappen
                    if eigenschap["naam"] == naam
                )
            )
        except StopIteration:
            # eigenschap not found - abort
            logger.info("Eigenschap '%s' did not exist on the zaaktype, aborting.")
            return {}

        zrc_client.create(
            "zaakeigenschap",
            {
                "zaak": zaak_url,
                "eigenschap": eigenschap_url,
                "waarde": waarde,
            },
            zaak_uuid=zaak_uuid,
            request_kwargs={"headers": get_nlx_headers(variables)},
        )

        return {}
Esempio n. 6
0
    def create_rol(self) -> Optional[dict]:
        variables = self.task.get_variables()
        betrokkene = check_variable(variables, "betrokkene")
        omschrijving = check_variable(variables,
                                      "omschrijving",
                                      empty_allowed=True)

        if not omschrijving:
            logger.info(
                "Received empty rol-omschrijving process variable, skipping.")
            return

        zrc_client = self.get_client(APITypes.zrc)
        zaak_url = check_variable(variables, "zaakUrl")
        zaak = zrc_client.retrieve("zaak", url=zaak_url)

        ztc_client = self.get_client(APITypes.ztc)
        query_params = {
            "zaaktype": zaak["zaaktype"],
        }
        rol_typen = ztc_client.list("roltype", query_params)
        rol_typen = [
            rol_type for rol_type in rol_typen["results"]
            if rol_type["omschrijving"] == omschrijving
        ]
        if not rol_typen:
            raise ValueError(
                f"No matching roltype with zaaktype = {zaak['zaaktype']} and omschrijving = {omschrijving} is found"
            )

        data = {
            "zaak":
            zaak["url"],
            "betrokkene":
            betrokkene.get("betrokkene", ""),
            "betrokkeneType":
            betrokkene["betrokkeneType"],
            "roltype":
            rol_typen[0]["url"],
            "roltoelichting":
            betrokkene["roltoelichting"],
            "indicatieMachtiging":
            betrokkene.get("indicatieMachtiging", ""),
            "betrokkeneIdentificatie":
            betrokkene.get("betrokkeneIdentificatie", {}),
        }
        rol = zrc_client.create(
            "rol",
            data,
        )
        return rol
Esempio n. 7
0
    def perform(self) -> dict:
        variables = self.task.get_variables()

        # Retrieve document
        document_url = check_variable(variables, "informatieobject")
        lock_id = check_variable(variables, "lockId")
        drc_client = self.get_drc_client(document_url)

        # Unock document
        drc_client.operation(
            operation_id="enkelvoudiginformatieobject_unlock",
            uuid=get_document_uuid(document_url),
            data={"lock": lock_id},
        )

        return {}
Esempio n. 8
0
    def create_package(self) -> dict:
        """Create a ValidSign package with the name specified by the process variable and add the signers to it."""

        logger.debug("Creating ValidSign package")

        variables = self.task.get_variables()
        signers = self.format_signers(check_variable(variables, "signers"))
        package_name = check_variable(variables, "packageName")

        body = {
            "name": package_name,
            "type": "PACKAGE",
            "roles": signers,
        }

        package = self.client.request(path="api/packages",
                                      operation="api.packages.post",
                                      method="POST",
                                      json=body)

        return package
Esempio n. 9
0
def get_review_request(task: BaseTask) -> dict:
    """
    Get a single review request from kownsl.
    """

    # Get variables
    variables = task.get_variables()

    # Build url
    client = get_client(task)
    review_request_id = check_variable(variables, "kownslReviewRequestId")
    review_request = client.retrieve("review_requests", uuid=review_request_id)
    return review_request
Esempio n. 10
0
    def perform(self) -> Dict[str, Optional[str]]:
        variables = self.task.get_variables()
        client_zrc = self.get_client(APITypes.zrc)

        identificatie = check_variable(variables, "identificatie")
        bronorganisatie = check_variable(variables, "bronorganisatie")

        zaken: dict = client_zrc.list(
            "zaak",
            {
                "bronorganisatie": bronorganisatie,
                "identificatie": identificatie,
            },
        )

        # paginated response
        if zaken["results"]:
            zaak_url = zaken["results"][0]["url"]
        else:
            zaak_url = None

        return {"zaakUrl": zaak_url}
Esempio n. 11
0
    def create_status(self) -> dict:
        variables = self.task.get_variables()

        zrc_client = self.get_client(APITypes.zrc)
        zaak_url = check_variable(variables, "zaakUrl")

        if "statusVolgnummer" in variables:
            volgnummer = int(variables["statusVolgnummer"])
            ztc_client = self.get_client(APITypes.ztc)

            logger.info("Deriving statustype URL from Catalogi API")
            zaak = zrc_client.retrieve("zaak", url=zaak_url)

            statustypen = ztc_client.list(
                "statustype", query_params={"zaaktype": zaak["zaaktype"]})

            if statustypen["next"]:
                raise NotImplementedError("Pagination not implemented yet")

            try:
                statustype = next(st["url"] for st in statustypen["results"]
                                  if st["volgnummer"] == volgnummer)
            except StopIteration:
                raise ValueError(
                    f"Statustype met volgnummer '{variables['statusVolgnummer']}' niet gevonden."
                )
        else:
            statustype = check_variable(variables, "statustype")

        toelichting = variables.get("toelichting", "")
        data = {
            "zaak": zaak_url,
            "statustype": statustype,
            "datumStatusGezet": timezone.now().isoformat(),
            "statustoelichting": toelichting,
        }
        status = zrc_client.create("status", data)
        return status
Esempio n. 12
0
 def _get_resultaattype(self, zaak_url: str, variables: dict) -> str:
     try:
         resultaattype = check_variable(variables, "resultaattype")
     except MissingVariable:
         try:
             omschrijving = check_variable(variables, "omschrijving")
         except MissingVariable:
             raise MissingVariable(
                 "Missing both resultaattype and omschrijving. One is required."
             )
         else:
             zrc_client = self.get_client(APITypes.zrc)
             zaak = zrc_client.retrieve("zaak", url=zaak_url)
             ztc_client = self.get_client(APITypes.ztc)
             resultaattypen = ztc_client.list(
                 "resultaattype",
                 request_kwargs={"params": {
                     "zaaktype": zaak["zaaktype"]
                 }},
             )
             if resultaattypen["count"] == 0:
                 raise ValueError(
                     "No resultaattypen were found for zaaktype %s." %
                     zaak["zaaktype"])
             resultaattype = [
                 rt for rt in resultaattypen["results"]
                 if rt["omschrijving"].lower() == omschrijving.lower()
             ]
             if len(resultaattype) != 1:
                 raise ValueError(
                     "No%s resultaattype was found with zaaktype %s and omschrijving %s."
                     % (
                         "" if len(resultaattype) == 0 else " unique",
                         zaak["zaaktype"],
                         omschrijving,
                     ))
             resultaattype = resultaattype[0]["url"]
     return resultaattype
Esempio n. 13
0
    def perform(self) -> Dict[str, str]:
        variables = self.task.get_variables()

        # Retrieve document
        document_url = check_variable(variables, "informatieobject")
        drc_client = self.get_drc_client(document_url)

        # Lock document
        response = drc_client.operation(
            operation_id="enkelvoudiginformatieobject_lock",
            uuid=get_document_uuid(document_url),
            data={},
        )

        return {"lockId": response["lock"]}
Esempio n. 14
0
    def relate_document(self) -> dict:
        variables = self.task.get_variables()

        informatieobject = check_variable(
            variables, "informatieobject", empty_allowed=True
        )
        if not informatieobject:
            return None

        # recently renamed zaak -> zaakUrl: handle correctly
        zaak = variables.get("zaakUrl", variables.get("zaak"))

        zrc_client = self.get_client(APITypes.zrc)
        data = {"zaak": zaak, "informatieobject": informatieobject}
        zio = zrc_client.create("zaakinformatieobject", data)
        return zio
Esempio n. 15
0
    def perform(self) -> dict:
        variables = self.task.get_variables()
        subprocess_key = check_variable(variables, "subprocessDefinition")
        subprocess_version = variables.get("subprocessDefinitionVersion",
                                           "latest")
        mapping = variables.get("variablesMapping", {})

        if not isinstance(self.task, ExternalTask):
            raise CamundaRequired(
                "Only Camunda tasks support CallActivity task")

        # get parent process instance variables
        instance_id = self.task.get_process_instance_id()
        instance_variables = get_all_process_instance_variables(instance_id)
        serialized_variables = {
            k: serialize_variable(v)
            for k, v in instance_variables.items()
        }

        variables = self.construct_variables(serialized_variables, mapping)

        # determine which process version
        if subprocess_version == "latest":
            start_process_kwargs = {"process_key": subprocess_key}
        else:
            client = get_client()
            definitions = client.get(
                "process-definition",
                params={
                    "key": subprocess_key,
                    "version": subprocess_version,
                },
            )
            if len(definitions) != 1:
                raise ValueError(
                    f"Expected 1 process definition for key {subprocess_key} and version "
                    f"{subprocess_version}, got {len(definitions)}.")
            start_process_kwargs = {"process_id": definitions[0]["id"]}

        # start subprocess
        subprocess = start_process(variables=variables, **start_process_kwargs)

        return {"processInstanceId": subprocess["instance_id"]}
Esempio n. 16
0
def get_brt_service(task: BaseTask) -> Service:
    """
    Extract the BRT Service object to use for the client.
    """
    try:
        return get_alias_service(task, ALIAS, service__api_type=APITypes.orc)
    except NoService:
        warnings.warn(
            "Falling back to static configuration, this support will be removed "
            "in BPTL 1.1",
            DeprecationWarning,
        )
        variables = task.get_variables()
        return Service(
            api_root=API_ROOT,
            label="BRT",
            auth_type=AuthTypes.api_key,
            header_key="X-Api-Key",
            header_value=check_variable(variables, "BRTKey"),
            oas=API_ROOT,
        )
Esempio n. 17
0
    def perform(self) -> dict:
        variables = self.task.get_variables()

        # Retrieve io url
        zaak_url = check_variable(variables, "zaakUrl")
        zaak_informatieobjecten = self.get_zaak_informatieobjecten(zaak_url)
        zios = [zio["informatieobject"] for zio in zaak_informatieobjecten]

        # lock io and set data
        with parallel() as executor:
            responses = list(executor.map(self.lock_document, zios))

        # update io
        with parallel() as executor:
            list(executor.map(self.update_document, responses))

        # unlock io
        with parallel() as executor:
            list(executor.map(self.unlock_document, responses))

        return {}
Esempio n. 18
0
    def perform(self) -> Optional[dict]:
        # prep clients
        zrc_client = self.get_client(APITypes.zrc)

        # get vars
        variables = self.task.get_variables()

        zaak_url = variables.get("hoofdZaakUrl")
        if not zaak_url:
            logger.info("No 'hoofdZaakUrl' provided, skipping task execution.")
            return

        bijdrage_zaak_url = check_variable(variables, "zaakUrl")
        bijdrage_aard = check_variable(variables, "bijdrageAard")

        if bijdrage_aard not in AardRelatieChoices.values:
            raise ValueError(f"Unknown 'bijdrage_aard': '{bijdrage_aard}'")

        headers = get_nlx_headers(variables)

        zaak = zrc_client.retrieve("zaak", url=zaak_url, request_headers=headers)

        relevante_andere_zaken = zaak["relevanteAndereZaken"]
        relevante_andere_zaken.append(
            {
                "url": bijdrage_zaak_url,
                "aardRelatie": bijdrage_aard,
            }
        )

        zrc_client.partial_update(
            "zaak",
            {"relevanteAndereZaken": relevante_andere_zaken},
            url=zaak_url,
            request_headers=headers,
        )

        try:
            bijdrage_aard_omgekeerde_richting = check_variable(
                variables, "bijdrageAardOmgekeerdeRichting", empty_allowed=True
            )
            if (
                bijdrage_aard_omgekeerde_richting
                and bijdrage_aard_omgekeerde_richting not in AardRelatieChoices.values
            ):
                raise ValueError(
                    f"Unknown 'bijdrageAardOmgekeerdeRichting': '{bijdrage_aard_omgekeerde_richting}'"
                )
        except MissingVariable:
            # To avoid having to edit BPMN models - default of bijdrage_aard_omgekeerde_richting
            # is "onderwerp" if it isn't explicitly given in the variables.
            bijdrage_aard_omgekeerde_richting = AardRelatieChoices.onderwerp

        # Relating of secondary zaken to their main zaak.
        if (
            bijdrage_aard != AardRelatieChoices.onderwerp
            and bijdrage_aard_omgekeerde_richting
        ):
            bijdrage_zaak = zrc_client.retrieve(
                "zaak", url=bijdrage_zaak_url, request_headers=headers
            )
            relevante_andere_zaken_bijdrage_zaak = bijdrage_zaak["relevanteAndereZaken"]
            relevante_andere_zaken_bijdrage_zaak.append(
                {
                    "url": zaak_url,
                    "aardRelatie": bijdrage_aard_omgekeerde_richting,
                }
            )
            zrc_client.partial_update(
                "zaak",
                {"relevanteAndereZaken": relevante_andere_zaken_bijdrage_zaak},
                url=bijdrage_zaak_url,
                request_headers=headers,
            )

        return {}
Esempio n. 19
0
    def _get_documents_from_api(self) -> List[Tuple[str, BytesIO]]:
        """Retrieve the documents and their content from the Documenten API."""

        logger.debug("Retrieving documents from Documenten API")

        variables = self.task.get_variables()
        document_urls = check_variable(variables, "documents")

        client_pool = DRCClientPool(variables)
        client_pool.populate_clients(self.task, document_urls)

        documents = []

        current_total_documents_size = 0
        for document_url in document_urls:
            # Getting the appropriate client
            document_client = client_pool.get_client_for(document_url)
            # Retrieving the document
            document_data = document_client.retrieve(
                resource="enkelvoudiginformatieobject",
                url=document_url,
            )

            # Retrieving the content of the document
            # Need use requests directly instead of `document_client.request()` since the response is not in JSON format
            response = requests.get(
                document_data["inhoud"],
                headers=document_client.auth_header,
                stream=True,
            )

            # Get the document size in bytes
            document_size = document_data["bestandsomvang"]

            # If the size of the document is above the max size or if all the documents together have already reached
            # the maximum size, write the file content to a temporary file
            if (document_size > settings.MAX_DOCUMENT_SIZE
                    or (current_total_documents_size + document_size) >
                    settings.MAX_TOTAL_DOCUMENT_SIZE):
                # The file is created with rb+ mode by default
                tmp_file_object = TemporaryUploadedFile(
                    name=
                    f"{document_data['titel']}-{get_random_string(length=5)}.tempfile",
                    content_type="application/octet-stream",
                    size=document_size,
                    charset=
                    None,  # Required argument in TemporaryUploadedFile, but not in parent class UploadedFile
                )
                for chunk in response.iter_content(
                        chunk_size=settings.CHUNK_SIZE):
                    tmp_file_object.write(chunk)
                tmp_file_object.flush()
                doc_tuple = (document_data["titel"], tmp_file_object)
            else:
                doc_tuple = (document_data["titel"], BytesIO(response.content))
                current_total_documents_size += document_size

            response.close()

            documents.append(doc_tuple)

        return documents
Esempio n. 20
0
    def test_check_bool_variable_false(self):
        variables = {"test_var": False}

        test_var = check_variable(variables, "test_var")

        self.assertFalse(test_var)
Esempio n. 21
0
    def test_check_bool_variable_true(self):
        variables = {"test_var": True}

        test_var = check_variable(variables, "test_var")

        self.assertTrue(test_var)
Esempio n. 22
0
def start_xential_template(task: BaseTask) -> dict:
    """
    Run Xential template with requested variables.

    If the ``interactive`` task variable is:

    * ``True``: it returns a URL in ``bptlDocumentUrl`` for building a document interactively
    * ``False``: it returns an empty string in ``bptlDocumentUrl``

    In the task binding, the service with alias ``xential`` must be connected, so that
    this task knows which endpoints to contact.

    **Required process variables**

    * ``bptlAppId``: the application ID in the BPTL credential store
    * ``templateUuid``: the id of the template which should be started
    * ``interactive``: bool, whether the process will be interactive or not
    * ``templateVariables``: a JSON-object containing the data to fill the template. In an interactive flow, this can be
      an empty object ``{}``:

      .. code-block:: json

         {
            "variable1": "String",
            "variable2": "String"
         }

    * ``documentMetadata``: a JSON-object containing the fields required to create a document in the Documenten API.
      The fields shown below are required. The property 'creatiedatum' defaults to the day in which the document is
      sent to the Documenten API and the property 'taal' defaults to 'nld' (dutch).

      .. code-block:: json

         {
            "bronorganisatie": "string",
            "titel": "string",
            "auteur": "string",
            "informatieobjecttype": "url"
         }

    **Optional process variable**

    * ``messageId``: string. The message ID to send back into the process when the
      document is sent to the Documenten API. You can use this to continue process execution.
      If left empty, then no message will be sent.

    **Sets the process variable**

    * ``bptlDocumentUrl``: BPTL specific URL for interactive documents.
      If the document creation is not interactive, this will be empty.

    """
    variables = task.get_variables()
    interactive = check_variable(variables, "interactive")
    template_uuid = check_variable(variables, "templateUuid")
    template_variables = check_variable(variables,
                                        "templateVariables",
                                        empty_allowed=True)
    xential_client = get_client(task, XENTIAL_ALIAS)

    check_document_api_required_fields(
        check_variable(variables, "documentMetadata"))

    # Step 1: Create a ticket
    create_ticket_url = "createTicket"

    # Make a bptl UUID for this ticket, so that later the task can be retrieved
    bptl_ticket_uuid = str(uuid.uuid4())

    # The `options` parameter needs *all* fields filled (even if empty), otherwise
    # a 500 response is given.
    config = XentialConfiguration.get_solo()
    options = {
        "printOption": {},
        "mailOption": {},
        "documentPropertiesOption": {},
        "valuesOption": {},
        "attachmentsOption": {},
        "ttlOption": {},
        "storageOption": {
            "fixed": True,
            "None": {}
        },
        "selectionOption": {
            "templateUuid": template_uuid
        },
        "webhooksOption": {
            "hooks": [{
                "event": "document.built",
                "retries": {
                    "count": 0,
                    "delayMs": 0
                },
                "request": {
                    "url":
                    get_callback_url(),
                    "method":
                    "POST",
                    "contentType":
                    "application/xml",
                    "headers": [{
                        "name": "Authorization",
                        "value": f"Basic {config.auth_key}",
                    }],
                    "requestBody":
                    f'<data xmlns:sup="nl.inext.statusupdates"><document><sup:param name="documentData"/></document><bptlTicketUuid>{bptl_ticket_uuid}</bptlTicketUuid></data>',
                },
            }]
        },
    }
    # `ticket_data` contains the template variables formatted as XML to fill the document
    ticket_data = make_xml_from_template_variables(template_variables)

    response_data = xential_client.post(
        create_ticket_url,
        files={
            "options": ("options", json.dumps(options), "application/json"),
            "ticketData": ("ticketData", ticket_data, "text/xml"),
        },
    )
    ticket_uuid = response_data["ticketId"]

    ticket = XentialTicket.objects.create(
        task=task,
        bptl_ticket_uuid=bptl_ticket_uuid,
        ticket_uuid=ticket_uuid,
        is_ticket_complete=False,
    )

    if not interactive:
        # Step 2: Start a document
        start_document_url = "document/startDocument"
        response_data = xential_client.post(start_document_url,
                                            params={"ticketUuid": ticket_uuid})
        document_uuid = response_data["documentUuid"]

        # It seems that if the buildDocument request is done too soon
        # after startDocument, the document is not sent to the callback
        sleep(5)

        # Step 3: Build document silently
        # If not all template variables are filled, building the document will not work.
        build_document_url = "document/buildDocument"
        params = {"documentUuid": document_uuid, "close": "true"}
        xential_client.post(build_document_url, params=params)

        ticket.document_uuid = document_uuid
        ticket.save()

        return {"bptlDocumentUrl": ""}

    token = token_generator.make_token(ticket)
    interactive_document_path = reverse("Xential:interactive-document",
                                        args=[bptl_ticket_uuid, token])

    return {"bptlDocumentUrl": get_absolute_url(interactive_document_path)}
Esempio n. 23
0
    def _get_zaaktype(self, variables: dict) -> str:
        if not hasattr(self, "_zaaktype"):
            if not (zaaktype_url := variables.get("zaaktype", "")):
                catalogus_domein = check_variable(variables, "catalogusDomein")
                catalogus_rsin = variables.get(
                    "catalogusRSIN") or check_variable(variables,
                                                       "organisatieRSIN")
                zaaktype_identificatie = check_variable(
                    variables, "zaaktypeIdentificatie")

                request_kwargs = {
                    "params": {
                        "domein": catalogus_domein,
                        "rsin": catalogus_rsin
                    }
                }
                client_ztc = self.get_client(APITypes.ztc)
                catalogus = client_ztc.list("catalogus",
                                            request_kwargs=request_kwargs)
                try:
                    catalogus_url = catalogus["results"][0]["url"]
                except (KeyError, IndexError):
                    raise ValueError(
                        "No catalogus found with domein %s and RSIN %s." %
                        (catalogus_domein, catalogus_rsin))

                request_kwargs = {
                    "params": {
                        "catalogus": catalogus_url,
                        "identificatie": zaaktype_identificatie,
                    }
                }
                zaaktypen = client_ztc.list("zaaktype",
                                            request_kwargs=request_kwargs)
                if zaaktypen["count"] == 0:
                    raise ValueError(
                        "No zaaktype was found with catalogus %s and identificatie %s."
                        % (
                            catalogus_url,
                            zaaktype_identificatie,
                        ))

                zaaktypen = [
                    factory(ZaakType, zaaktype)
                    for zaaktype in zaaktypen["results"]
                ]

                def _filter_on_geldigheid(zaaktype: ZaakType) -> bool:
                    if zaaktype.einde_geldigheid:
                        return (zaaktype.begin_geldigheid <= date.today() <=
                                zaaktype.einde_geldigheid)
                    else:
                        return zaaktype.begin_geldigheid <= date.today()

                zaaktypen = [
                    zt for zt in zaaktypen if _filter_on_geldigheid(zt)
                ]
                if len(zaaktypen) != 1:
                    raise ValueError(
                        "No%s zaaktype was found with catalogus %s, identificatie %s with begin_geldigheid <= %s <= einde_geldigheid."
                        % (
                            "" if len(zaaktypen) == 0 else " unique",
                            catalogus_url,
                            zaaktype_identificatie,
                            date.today(),
                        ))

                zaaktype_url = zaaktypen[0].url

            self._zaaktype = zaaktype_url
Esempio n. 24
0
def retrieve_openbare_ruimten(task: BaseTask) -> Dict[str, Any]:
    """
    Given a bounding box (or other polygon), retrieve the 'public space' objects
    contained/overlapping.

    This consumes the BRT API to fetch relevant objects, which are returned so that they
    can be drawn/selected on maps as GeoJSON.

    Checked resources:

    - Wegdeel
    - Terrein (in development)
    - Inrichtingselement (in development)

    **Required process variables**

    * ``geometry``: A GeoJSON geometry that is checked for overlap.

    **Optional process variables**

    * ``bptlAppId``: the application ID of the app that caused this task to be executed.
      The app-specific credentials will be used for the API calls, if provided.

    **Sets the following return/process variables**

    * ``features``: a list of GeoJSON features, in EPSG:4258 CRS. Properties contain
      feature-specific keys/values.

    .. note:: The kadaster geo query APIs have long response times (up to 40s) - this
       work unit takes a considerable time to execute.
    """
    variables = task.get_variables()
    geo = check_variable(variables, "geometry")

    resources = ["wegdelen"]  # , "inrichtingselementen"]
    formatters = {
        "wegdelen": format_wegdeel,
    }

    body = {"geometrie": {"intersects": geo}}
    headers = {
        "Accept-Crs": "epsg:4258",  # ~ WGS84
    }

    with get_client() as client:

        def fetch(resource: str, formatter: callable):
            resp_data = client.post(
                resource,
                params={"pageSize": 50},
                json=body,
                headers=headers,
            )
            results = resp_data["_embedded"][resource]
            results = [formatter(result) for result in results]
            return results

        features = [
            fetch(resource, formatters[resource]) for resource in resources
        ]
    return {"features": features}