Skip to content
Draft
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
10 changes: 10 additions & 0 deletions src/openklant/components/klantinteracties/admin/internetaken.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ class ActorInlineAdmin(admin.StackedInline):
@admin.register(InterneTaak)
class InterneTaakAdmin(admin.ModelAdmin):
readonly_fields = ("uuid",)
fields = (
"uuid",
"klantcontact",
"nummer",
"gevraagde_handeling",
"toelichting",
"status",
"toegewezen_op",
"afgehandeld_op",
)
list_display = (
"nummer",
"status",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from django.utils.translation import gettext_lazy as _

from drf_spectacular.utils import extend_schema_serializer
from glom import PathAccessError, glom
from rest_framework import serializers

from openklant.components.klantinteracties.api.serializers.actoren import (
Expand Down Expand Up @@ -37,13 +36,6 @@ class Meta:

@extend_schema_serializer(deprecate_fields=["toegewezen_aan_actor"])
class InterneTaakSerializer(serializers.HyperlinkedModelSerializer):
toegewezen_aan_actor = ActorForeignKeySerializer(
required=False,
allow_null=False,
help_text=_("Eerste actor die een interne taak toegewezen kreeg."),
source="actoren.first",
many=False,
)
toegewezen_aan_actoren = ActorForeignKeySerializer(
required=False,
allow_null=False,
Expand All @@ -66,7 +58,6 @@ class Meta:
"nummer",
"gevraagde_handeling",
"aanleidinggevend_klantcontact",
"toegewezen_aan_actor",
"toegewezen_aan_actoren",
"toelichting",
"status",
Expand All @@ -82,52 +73,7 @@ class Meta:
},
}

def to_representation(self, instance):
response = super().to_representation(instance)
response["toegewezen_aan_actor"] = ActorForeignKeySerializer(
instance.actoren.order_by("internetakenactorenthoughmodel__pk").first(),
context={**self.context},
).data

response["toegewezen_aan_actoren"] = ActorForeignKeySerializer(
instance.actoren.all().order_by("internetakenactorenthoughmodel__pk"),
context={**self.context},
many=True,
).data
return response

# TODO: remove when depricated actoren field gets removed
def _validate_actoren(self):
toegewezen_aan_actor = "toegewezen_aan_actor" in self.initial_data
toegewezen_aan_actoren = "toegewezen_aan_actoren" in self.initial_data

if toegewezen_aan_actor == toegewezen_aan_actoren:
if toegewezen_aan_actor:
message = _(
"`toegewezen_aan_actor` en `toegewezen_aan_actoren` mag niet beiden gebruikt worden."
)
else:
message = _(
"`toegewezen_aan_actor` of `toegewezen_aan_actoren` is required (mag niet beiden gebruiken)."
)

# If patch don't raise required error
if self.context.get("request").method == "PATCH":
return

raise serializers.ValidationError(message)

# TODO: remove when depricated actoren field gets removed
def _get_actoren(self, actoren):
if isinstance(actoren, list):
actor_uuids = [str(actor.get("uuid")) for actor in actoren]
else:
actor_uuids = [glom(actoren, "first.uuid", skip_exc=PathAccessError)]

return [Actor.objects.get(uuid=uuid) for uuid in actor_uuids]

def validate(self, attrs):
self._validate_actoren()
status = attrs.get("status", None)
if status is None and self.instance is not None:
status = self.instance.status
Expand All @@ -154,19 +100,21 @@ def create(self, validated_data):
)

internetaak = super().create(validated_data)

if actoren:
for actor in self._get_actoren(actoren):
internetaak.actoren.add(actor)
actoren = [actor["uuid"] for actor in actoren]
actoren_qs = Actor.objects.filter(uuid__in=actoren)
internetaak.actoren.set(actoren_qs)

return internetaak

@transaction.atomic
def update(self, instance, validated_data):
if "actoren" in validated_data:
actoren = validated_data.pop("actoren")
instance.actoren.clear()
for actor in self._get_actoren(actoren):
instance.actoren.add(actor)
actoren = [actor["uuid"] for actor in validated_data.pop("actoren")]
actoren_qs = Actor.objects.filter(uuid__in=actoren)
instance.actoren.set(actoren_qs)

if "klantcontact" in validated_data:
if klantcontact := validated_data.pop("klantcontact", None):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def test_create_internetaak(self):

list_url = reverse("klantinteracties:internetaak-list")
data = {
"toegewezenAanActor": {"uuid": str(actor.uuid)},
"toegewezenAanActoren": [{"uuid": str(actor.uuid)}],
"aanleidinggevendKlantcontact": {"uuid": str(klantcontact.uuid)},
"nummer": "1312312312",
"gevraagdeHandeling": "gevraagdeHandeling",
Expand All @@ -74,7 +74,6 @@ def test_create_internetaak(self):

response_data = response.json()

self.assertEqual(response_data["toegewezenAanActor"]["uuid"], str(actor.uuid))
self.assertEqual(len(response_data["toegewezenAanActoren"]), 1)
self.assertEqual(
response_data["toegewezenAanActoren"][0]["uuid"],
Expand Down Expand Up @@ -131,7 +130,7 @@ def test_create_internetaak_with_status_te_verwerken(self):

list_url = reverse("klantinteracties:internetaak-list")
data = {
"toegewezenAanActor": {"uuid": str(actor.uuid)},
"toegewezenAanActoren": [{"uuid": str(actor.uuid)}],
"aanleidinggevendKlantcontact": {"uuid": str(klantcontact.uuid)},
"nummer": "1312312312",
"gevraagdeHandeling": "gevraagdeHandeling",
Expand All @@ -145,7 +144,6 @@ def test_create_internetaak_with_status_te_verwerken(self):

response_data = response.json()

self.assertEqual(response_data["toegewezenAanActor"]["uuid"], str(actor.uuid))
self.assertEqual(len(response_data["toegewezenAanActoren"]), 1)
self.assertEqual(
response_data["toegewezenAanActoren"][0]["uuid"],
Expand Down Expand Up @@ -181,7 +179,7 @@ def test_create_internetaak_with_afgehandeld_op_date(self):

list_url = reverse("klantinteracties:internetaak-list")
data = {
"toegewezenAanActor": {"uuid": str(actor.uuid)},
"toegewezenAanActoren": [{"uuid": str(actor.uuid)}],
"aanleidinggevendKlantcontact": {"uuid": str(klantcontact.uuid)},
"nummer": "1312312312",
"gevraagdeHandeling": "gevraagdeHandeling",
Expand All @@ -196,7 +194,6 @@ def test_create_internetaak_with_afgehandeld_op_date(self):

response_data = response.json()

self.assertEqual(response_data["toegewezenAanActor"]["uuid"], str(actor.uuid))
self.assertEqual(len(response_data["toegewezenAanActoren"]), 1)
self.assertEqual(
response_data["toegewezenAanActoren"][0]["uuid"],
Expand Down Expand Up @@ -242,14 +239,13 @@ def test_create_internetaak_with_multiple_actoren(self):

response_data = response.json()

self.assertEqual(response_data["toegewezenAanActor"]["uuid"], str(actor2.uuid))
self.assertEqual(
response_data["toegewezenAanActoren"][0]["uuid"],
str(actor2.uuid),
str(actor.uuid),
)
self.assertEqual(
response_data["toegewezenAanActoren"][1]["uuid"],
str(actor.uuid),
str(actor2.uuid),
)
self.assertEqual(
response_data["aanleidinggevendKlantcontact"]["uuid"],
Expand Down Expand Up @@ -282,7 +278,6 @@ def test_update_internetaak(self):
response = self.client.get(detail_url)
data = response.json()

self.assertEqual(data["toegewezenAanActor"]["uuid"], str(actor.uuid))
self.assertEqual(len(data["toegewezenAanActoren"]), 1)
self.assertEqual(
data["toegewezenAanActoren"][0]["uuid"],
Expand Down Expand Up @@ -311,7 +306,6 @@ def test_update_internetaak(self):

data = response.json()

self.assertEqual(data["toegewezenAanActor"]["uuid"], str(actor2.uuid))
self.assertEqual(len(data["toegewezenAanActoren"]), 1)
self.assertEqual(
data["aanleidinggevendKlantcontact"]["uuid"], str(klantcontact2.uuid)
Expand Down Expand Up @@ -341,7 +335,7 @@ def test_update_internetaak(self):
"changing_status_back_to_te_verwerken_clears_afgehandeld_op_field"
):
data = {
"toegewezenAanActor": {"uuid": str(actor2.uuid)},
"toegewezenAanActoren": [{"uuid": str(actor2.uuid)}],
"aanleidinggevendKlantcontact": {"uuid": str(klantcontact2.uuid)},
"gevraagdeHandeling": "changed",
"status": "te_verwerken",
Expand All @@ -355,7 +349,7 @@ def test_update_internetaak(self):

with self.subTest("with_afgehandeld_op_data_value"):
data = {
"toegewezenAanActor": {"uuid": str(actor2.uuid)},
"toegewezenAanActoren": [{"uuid": str(actor2.uuid)}],
"aanleidinggevendKlantcontact": {"uuid": str(klantcontact2.uuid)},
"gevraagdeHandeling": "changed",
"status": "verwerkt",
Expand All @@ -365,7 +359,7 @@ def test_update_internetaak(self):
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()

self.assertEqual(data["toegewezenAanActor"]["uuid"], str(actor2.uuid))
self.assertEqual(data["toegewezenAanActoren"][0]["uuid"], str(actor2.uuid))
self.assertEqual(
data["aanleidinggevendKlantcontact"]["uuid"], str(klantcontact2.uuid)
)
Expand All @@ -381,7 +375,7 @@ def test_update_internetaak(self):

with self.subTest("validate_afgehandeld_op_error_with_te_verwerken_status"):
data = {
"toegewezenAanActor": {"uuid": str(actor2.uuid)},
"toegewezenAanActoren": [{"uuid": str(actor2.uuid)}],
"aanleidinggevendKlantcontact": {"uuid": str(klantcontact2.uuid)},
"gevraagdeHandeling": "changed",
"status": "te_verwerken",
Expand All @@ -396,42 +390,6 @@ def test_update_internetaak(self):
"De Internetaak kan geen afgehandeld op datum bevatten als de status niet op 'verwerkt' staat.",
)

with self.subTest("validate_acoren_field_required_neither_fields"):
# no toegewezen_aan_actoren and toegewezen_aan_actor
data = {
"aanleidinggevendKlantcontact": {"uuid": str(klantcontact2.uuid)},
"gevraagdeHandeling": "changed",
"status": "te_verwerken",
"afgehandeldOp": "2024-01-01T01:00:00Z",
}
response = self.client.put(detail_url, data)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
data = response.json()
self.assertEqual(data["invalidParams"][0]["name"], "nonFieldErrors")
self.assertEqual(
data["invalidParams"][0]["reason"],
"`toegewezen_aan_actor` of `toegewezen_aan_actoren` is required (mag niet beiden gebruiken).",
)

with self.subTest("validate_acoren_field_required_both_fields"):
# no toegewezen_aan_actoren and toegewezen_aan_actor
data = {
"toegewezenAanActor": {"uuid": str(actor2.uuid)},
"toegewezenAanActoren": [{"uuid": str(actor2.uuid)}],
"aanleidinggevendKlantcontact": {"uuid": str(klantcontact2.uuid)},
"gevraagdeHandeling": "changed",
"status": "te_verwerken",
"afgehandeldOp": "2024-01-01T01:00:00Z",
}
response = self.client.put(detail_url, data)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
data = response.json()
self.assertEqual(data["invalidParams"][0]["name"], "nonFieldErrors")
self.assertEqual(
data["invalidParams"][0]["reason"],
"`toegewezen_aan_actor` en `toegewezen_aan_actoren` mag niet beiden gebruikt worden.",
)

@freeze_time("2024-01-01T12:00:00Z")
def test_update_internetaak_with_multiple_actoren(self):
actor, actor2, actor3 = ActorFactory.create_batch(3)
Expand All @@ -451,7 +409,6 @@ def test_update_internetaak_with_multiple_actoren(self):
response = self.client.get(detail_url)
data = response.json()

self.assertEqual(data["toegewezenAanActor"]["uuid"], str(actor.uuid))
self.assertEqual(len(data["toegewezenAanActoren"]), 1)
self.assertEqual(
data["toegewezenAanActoren"][0]["uuid"],
Expand Down Expand Up @@ -481,15 +438,14 @@ def test_update_internetaak_with_multiple_actoren(self):
self.assertEqual(response.status_code, status.HTTP_200_OK)
response_data = response.json()

self.assertEqual(response_data["toegewezenAanActor"]["uuid"], str(actor3.uuid))
self.assertEqual(len(response_data["toegewezenAanActoren"]), 2)
self.assertEqual(
response_data["toegewezenAanActoren"][0]["uuid"],
str(actor3.uuid),
str(actor2.uuid),
)
self.assertEqual(
response_data["toegewezenAanActoren"][1]["uuid"],
str(actor2.uuid),
str(actor3.uuid),
)
self.assertEqual(
response_data["aanleidinggevendKlantcontact"]["uuid"],
Expand All @@ -503,27 +459,6 @@ def test_update_internetaak_with_multiple_actoren(self):
InterneTaak.objects.filter(afgehandeld_op="2024-01-01T12:00:00Z").exists()
)

with self.subTest(
"update_toegewezen_aan_actor_resoltes_in_one_actor_being_set"
):
# no toegewezen_aan_actoren and toegewezen_aan_actor
del data["toegewezenAanActoren"]
data = {
"toegewezenAanActor": {"uuid": str(actor.uuid)},
}
response = self.client.patch(detail_url, data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
response_data = response.json()

self.assertEqual(
response_data["toegewezenAanActor"]["uuid"], str(actor.uuid)
)
self.assertEqual(len(response_data["toegewezenAanActoren"]), 1)
self.assertEqual(
response_data["toegewezenAanActoren"][0]["uuid"],
str(actor.uuid),
)

def test_partial_update_internetaak(self):
actor = ActorFactory.create()
klantcontact = KlantcontactFactory.create()
Expand All @@ -542,7 +477,11 @@ def test_partial_update_internetaak(self):
response = self.client.get(detail_url)
data = response.json()

self.assertEqual(data["toegewezenAanActor"]["uuid"], str(actor.uuid))
self.assertEqual(len(data["toegewezenAanActoren"]), 1)
self.assertEqual(
data["toegewezenAanActoren"][0]["uuid"],
str(actor.uuid),
)
self.assertEqual(
data["aanleidinggevendKlantcontact"]["uuid"], str(klantcontact.uuid)
)
Expand All @@ -559,7 +498,6 @@ def test_partial_update_internetaak(self):

data = response.json()

self.assertEqual(data["toegewezenAanActor"]["uuid"], str(actor.uuid))
self.assertEqual(
data["aanleidinggevendKlantcontact"]["uuid"], str(klantcontact.uuid)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.19 on 2025-03-11 20:08

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("klantinteracties", "0029_betrokkene_bezoekadres_huisnummer_and_more"),
]

operations = [
migrations.AddField(
model_name="internetaak",
name="new_actoren",
field=models.ManyToManyField(
help_text="De actoren aan wie de interne taak werd toegewezen.",
related_name="temporary_related_name",
to="klantinteracties.actor",
verbose_name="actoren",
),
),
]
Loading
Loading