Skip to content

Commit

Permalink
✨ [#234] Validate DigitaalAdres.adres if type is email
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenbal committed Oct 18, 2024
1 parent 8edfb3e commit ba2051f
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
from openklant.components.klantinteracties.api.serializers.constants import (
SERIALIZER_PATH,
)
from openklant.components.klantinteracties.api.validators import digitaal_adres_exists
from openklant.components.klantinteracties.api.validators import (
OptionalEmailValidator,
digitaal_adres_exists,
)
from openklant.components.klantinteracties.models.digitaal_adres import DigitaalAdres
from openklant.components.klantinteracties.models.klantcontacten import Betrokkene
from openklant.components.klantinteracties.models.partijen import Partij
Expand Down Expand Up @@ -85,6 +88,7 @@ class Meta:
"help_text": _("De unieke URL van dit digitaal adres binnen deze API."),
},
}
validators = [OptionalEmailValidator()]

@transaction.atomic
def update(self, instance, validated_data):
Expand Down
25 changes: 24 additions & 1 deletion src/openklant/components/klantinteracties/api/validators.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from django.core.exceptions import ValidationError
from django.core.validators import EmailValidator
from django.db import models
from django.utils.translation import gettext_lazy as _

from rest_framework import serializers
from rest_framework import exceptions, serializers
from rest_framework.validators import UniqueTogetherValidator, qs_filter

from openklant.components.klantinteracties.constants import SoortDigitaalAdres
from openklant.components.klantinteracties.models.actoren import Actor
from openklant.components.klantinteracties.models.constants import SoortPartij
from openklant.components.klantinteracties.models.digitaal_adres import DigitaalAdres
Expand All @@ -23,6 +26,7 @@
PartijIdentificator,
)
from openklant.components.klantinteracties.models.rekeningnummers import Rekeningnummer
from openklant.utils.serializers import get_field_value


class FKUniqueTogetherValidator(UniqueTogetherValidator):
Expand Down Expand Up @@ -166,3 +170,22 @@ def Rekeningnummer_exists(value):
Rekeningnummer.objects.get(uuid=str(value))
except Rekeningnummer.DoesNotExist:
raise serializers.ValidationError(_("Rekeningnummer object bestaat niet."))


class OptionalEmailValidator(EmailValidator):
"""
EmailValidator for SoortDigitaalAdres that only attempts to validate if
`SoortDigitaalAdres` is `email
"""

requires_context = True

def __call__(self, attrs: dict, serializer):
if (
get_field_value(serializer, attrs, "soort_digitaal_adres")
== SoortDigitaalAdres.email
):
try:
super().__call__(get_field_value(serializer, attrs, "adres"))
except ValidationError as e:
raise exceptions.ValidationError({"adres": e.message})
23 changes: 23 additions & 0 deletions src/openklant/utils/serializers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from typing import Any

from django.utils.module_loading import import_string

from rest_framework.serializers import Serializer
from rest_framework_nested.serializers import NestedHyperlinkedRelatedField


Expand Down Expand Up @@ -46,3 +49,23 @@ def to_representation(self, value):
value = value.all()

return serializer.to_representation(value)


def get_field_value(
serializer: Serializer, attrs: dict[str, Any], field_name: str
) -> Any:
"""
Helper function to retrieve a field value from either the attrs (new data)
or the instance (existing data during updates).
:param serializer: The serializer instance
:param attrs: The attributes passed to `.validate`
:param field_name: The name of the field to retrieve
:return: The value of the field, or None if not present
"""
if field_name in attrs:
return attrs.get(field_name)
# Fallback to instance value if it exists
if serializer.instance:
return getattr(serializer.instance, field_name, None)
return None

0 comments on commit ba2051f

Please sign in to comment.