Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
26 changes: 26 additions & 0 deletions openklant_client/_methods/maak_klant_contact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from typing import cast

from ape_pie import APIClient

from openklant_client._resources.base import ConvenienceMethodMixin
from openklant_client.types.methods.maak_klant_contact import (
MaakKlantContactCreateData,
MaakKlantContactResponse,
)


class MaakKlantContactConvenienceMethod(ConvenienceMethodMixin):
"""
Convenience endpoint to create of KlantContact, Betrokkene and OnderwerpObject
"""

http_client: APIClient
base_path: str = "maak-klantcontact"

def __call__(
self,
*,
data: MaakKlantContactCreateData,
) -> MaakKlantContactResponse:
response = self._post(self.base_path, data=data)
return cast(MaakKlantContactResponse, self.process_response(response))
12 changes: 12 additions & 0 deletions openklant_client/_resources/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,15 @@ def inner(*args: P.args, **kwargs: P.kwargs) -> Generator[T, Any, None]:
return self._paginator(f(*args, **kwargs))

return inner


class ConvenienceMethodMixin(ResourceMixin):
http_client: APIClient

def __init__(self, http_client: APIClient):
self.http_client = http_client

def __call__(self):
raise NotImplementedError(
"You must implement the _call__ method to invoke the convenience method"
)
15 changes: 15 additions & 0 deletions openklant_client/client.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from dataclasses import dataclass
from typing import Any

from ape_pie import APIClient
from ape_pie.typing import ConfigAdapter

from openklant_client._methods.maak_klant_contact import (
MaakKlantContactConvenienceMethod,
)
from openklant_client._resources.actor import ActorResource
from openklant_client._resources.betrokkene import BetrokkeneResource
from openklant_client._resources.digitaal_adres import DigitaalAdresResource
Expand All @@ -13,6 +17,13 @@
from openklant_client._resources.partij_identificator import PartijIdentificatorResource


@dataclass
class ConvenienceMethods:
"""Container for non-resource centric, convenience method endpoints."""

maak_klant_contact: MaakKlantContactConvenienceMethod


class OpenKlantClient(APIClient):
partij: PartijResource
partij_identificator: PartijIdentificatorResource
Expand All @@ -22,6 +33,7 @@ class OpenKlantClient(APIClient):
actor: ActorResource
interne_taak: InterneTaakResource
betrokkene: BetrokkeneResource
methods: ConvenienceMethods

def __init__(
self,
Expand All @@ -48,6 +60,9 @@ def __init__(
self.actor = ActorResource(self)
self.interne_taak = InterneTaakResource(self)
self.betrokkene = BetrokkeneResource(self)
self.methods = ConvenienceMethods(
maak_klant_contact=MaakKlantContactConvenienceMethod(self)
)

@classmethod
def configure_from(cls, adapter: ConfigAdapter, **kwargs):
Expand Down
Empty file.
26 changes: 26 additions & 0 deletions openklant_client/types/methods/maak_klant_contact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from typing import NotRequired, TypedDict

from openklant_client.types.resources.betrokkene import (
Betrokkene,
BetrokkeneBaseCreateData,
)
from openklant_client.types.resources.klant_contact import (
CreateKlantContactData,
KlantContact,
)
from openklant_client.types.resources.onderwerp_object import (
OnderwerpObject,
OnderwerpObjectBaseCreateData,
)


class MaakKlantContactCreateData(TypedDict):
klantcontact: CreateKlantContactData
betrokkene: NotRequired[BetrokkeneBaseCreateData]
onderwerpobject: NotRequired[OnderwerpObjectBaseCreateData]


class MaakKlantContactResponse(TypedDict):
klantcontact: KlantContact
betrokkene: Betrokkene | None
onderwerpobject: OnderwerpObject | None
9 changes: 6 additions & 3 deletions openklant_client/types/resources/betrokkene.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ class CreateContactnaam(TypedDict):
achternaam: str


class BetrokkeneCreateData(TypedDict):
wasPartij: ForeignKeyRef | None
hadKlantcontact: ForeignKeyRef | None
class BetrokkeneBaseCreateData(TypedDict):
wasPartij: NotRequired[ForeignKeyRef | None]
bezoekadres: NotRequired[Adres]
correspondentieadres: NotRequired[Adres]
contactnaam: NotRequired[CreateContactnaam | None]
Expand All @@ -25,6 +24,10 @@ class BetrokkeneCreateData(TypedDict):
initiator: bool


class BetrokkeneCreateData(BetrokkeneBaseCreateData):
hadKlantcontact: ForeignKeyRef


class Betrokkene(TypedDict):
uuid: str
url: str
Expand Down
12 changes: 5 additions & 7 deletions openklant_client/types/resources/onderwerp_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@ class OnderwerpObjectIdentificator(TypedDict):
codeSoortObjectId: str


class BetrokkeneBase(TypedDict):
uuid: str
url: str
class OnderwerpObjectBaseCreateData(TypedDict):
wasKlantcontact: NotRequired[ForeignKeyRef | None]
onderwerpobjectidentificator: NotRequired[OnderwerpObjectIdentificator | None]


class CreateOnderwerpObjectData(TypedDict):
wasKlantcontact: ForeignKeyRef | None
klantcontact: ForeignKeyRef | None
onderwerpobjectidentificator: NotRequired[OnderwerpObjectIdentificator | None]
class CreateOnderwerpObjectData(OnderwerpObjectBaseCreateData):
klantcontact: NotRequired[ForeignKeyRef | None]


class OnderwerpObject(TypedDict):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
interactions:
- request:
body: '{"klantcontact": {"kanaal": "contactformulier", "onderwerp": "vraag", "inhoud":
"Dit is een vraag", "taal": "nld", "vertrouwelijk": true}}'
headers:
Authorization:
- Token b2eb1da9861da88743d72a3fb4344288fe2cba44
Content-Length:
- '138'
Content-Type:
- application/json
method: POST
uri: http://localhost:8338/klantinteracties/api/v1/maak-klantcontact
response:
body:
string: '{"klantcontact":{"uuid":"e2c6eeae-a899-4258-840b-82dd3cdd4576","url":"http://localhost:8338/klantinteracties/api/v1/klantcontacten/e2c6eeae-a899-4258-840b-82dd3cdd4576","gingOverOnderwerpobjecten":[],"hadBetrokkenActoren":[],"omvatteBijlagen":[],"hadBetrokkenen":[],"leiddeTotInterneTaken":[],"nummer":"0000000001","kanaal":"contactformulier","onderwerp":"vraag","inhoud":"Dit
is een vraag","indicatieContactGelukt":null,"taal":"nld","vertrouwelijk":true,"plaatsgevondenOp":"2025-11-21T12:08:44.795383Z"},"betrokkene":null,"onderwerpobject":null}'
headers:
API-version:
- 0.4.1
Allow:
- POST, OPTIONS
Content-Length:
- '546'
Content-Security-Policy:
- 'img-src ''self'' data: cdn.redoc.ly; style-src ''self'' ''unsafe-inline''
fonts.googleapis.com; form-action ''self''; object-src ''none''; script-src
''self'' ''unsafe-inline''; base-uri ''self''; worker-src ''self'' blob:;
frame-src ''self''; font-src ''self'' fonts.gstatic.com; default-src ''self'';
frame-ancestors ''none'''
Content-Type:
- application/json
Cross-Origin-Opener-Policy:
- same-origin
Referrer-Policy:
- same-origin
Vary:
- origin
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
status:
code: 201
message: Created
version: 1
5 changes: 3 additions & 2 deletions tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class OpenKlantServiceManager:
_api_root: str = "http://localhost:8338"
_api_path: str = "/klantinteracties/api/v1"
_api_token: str = "b2eb1da9861da88743d72a3fb4344288fe2cba44"
_docker_compose_project_name: str = "openklant2-api-test"
_docker_compose_project_name: str = "openklant-api-test"
_docker_compose_path: Path = BASE_DIR / "docker-compose.yaml"

def _docker_compose(
Expand All @@ -34,7 +34,8 @@ def _docker_compose(
try:
return subprocess.run(
args=[
"docker-compose",
"docker",
"compose",
"-f",
str(self._docker_compose_path),
"-p",
Expand Down
37 changes: 37 additions & 0 deletions tests/test_maak_klant_contact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import pytest

from tests.validators import (
MaakKlantContactCreateDataValidator,
MaakKlantContactResponseValidator,
)


@pytest.mark.vcr
def test_create_klant_contact(client) -> None:
data = MaakKlantContactCreateDataValidator.validate_python(
{
"klantcontact": {
"kanaal": "contactformulier",
"onderwerp": "vraag",
"inhoud": "Dit is een vraag",
"taal": "nld",
"vertrouwelijk": True,
},
"betrokkene": {
"rol": "klant",
"initiator": True,
"organisatienaam": "unknown",
},
"onderwerpobject": {
"onderwerpobjectidentificator": {
"objectId": "OF-12345",
"codeObjecttype": "form",
"codeRegister": "openforms",
"codeSoortObjectId": "public_reference",
}
},
}
)
resp = client.methods.maak_klant_contact(data=data)

MaakKlantContactResponseValidator.validate_python(resp)
8 changes: 8 additions & 0 deletions tests/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

from pydantic import TypeAdapter

from openklant_client.types.methods.maak_klant_contact import (
MaakKlantContactCreateData,
MaakKlantContactResponse,
)
from openklant_client.types.resources.actor import Actor, CreateActorData
from openklant_client.types.resources.betrokkene import Betrokkene, BetrokkeneCreateData
from openklant_client.types.resources.digitaal_adres import (
Expand Down Expand Up @@ -70,3 +74,7 @@
# Partij Identificator validators
PartijIdentificatorValidator = TypeAdapter(PartijIdentificator)
CreatePartijIdentificatorDataValidator = TypeAdapter(CreatePartijIdentificatorData)

# Maak Klant Contact validators
MaakKlantContactResponseValidator = TypeAdapter(MaakKlantContactResponse)
MaakKlantContactCreateDataValidator = TypeAdapter(MaakKlantContactCreateData)