Skip to content

Commit

Permalink
Merge pull request #54 from maykinmedia/issue-53-optional-klantnummer
Browse files Browse the repository at this point in the history
[#53] Making klantnummer optional and auto-generating klantnummer if not provided
  • Loading branch information
alextreme authored Sep 5, 2023
2 parents d481f5f + 17854d1 commit 19da052
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/openklant/components/klanten/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ class Meta:
"url": {"lookup_field": "uuid"},
"subject": {"required": False, "validators": [URLValidator()]},
"subject_type": {"validators": [IsImmutableValidator()]},
"klantnummer": {"required": False},
# Disabled for now, should return once logic is implemented
# "geverifieerd": {"validators": [IsImmutableValidator()]},
# Disabled for now, see https://github.com/maykinmedia/open-klant/pull/11#pullrequestreview-805051480
Expand Down Expand Up @@ -331,7 +332,6 @@ def validate(self, attrs):
_("subject or subjectIdentificatie must be provided"),
code="invalid-subject",
)

return validated_attrs

def to_internal_value(self, data):
Expand Down
104 changes: 104 additions & 0 deletions src/openklant/components/klanten/api/tests/test_klant.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,110 @@ def test_create_klant_website_url_optional(self):
self.assertEqual(klant.bronorganisatie, "950428139")
self.assertEqual(klant.website_url, "")

def test_create_klant_website_url_optional_klantnummer(self):
list_url = reverse(Klant)
data = {
"bronorganisatie": "950428139",
"voornaam": "Xavier",
"achternaam": "Jackson",
"emailadres": "[email protected]",
"adres": {
"straatnaam": "Keizersgracht",
"huisnummer": "117",
"huisletter": "A",
"postcode": "1015CJ",
"woonplaatsnaam": "test",
"landcode": "1234",
},
"subjectType": KlantType.natuurlijk_persoon,
"subject": SUBJECT,
}

with requests_mock.Mocker() as m:
m.get(SUBJECT, json={})
response = self.client.post(list_url, data)

self.assertEqual(response.status_code, status.HTTP_201_CREATED)

klant = Klant.objects.get()

self.assertEqual(klant.bronorganisatie, "950428139")
self.assertEqual(klant.website_url, "")
self.assertEqual(klant.klantnummer, "1")

with requests_mock.Mocker() as m:
m.get(SUBJECT, json={})
response = self.client.post(list_url, data)

self.assertEqual(response.status_code, status.HTTP_201_CREATED)

klant = Klant.objects.get(klantnummer__gt=1)
self.assertEqual(klant.klantnummer, "2")

def test_create_klant_website_url_duplicate_klantnummer(self):
list_url = reverse(Klant)
data = {
"bronorganisatie": "950428139",
"subjectType": KlantType.natuurlijk_persoon,
"klantnummer": "123",
"subject": SUBJECT,
}

with requests_mock.Mocker() as m:
m.get(SUBJECT, json={})
response = self.client.post(list_url, data)

self.assertEqual(response.status_code, status.HTTP_201_CREATED)

klant = Klant.objects.get()

self.assertEqual(klant.bronorganisatie, "950428139")
self.assertEqual(klant.website_url, "")
self.assertEqual(klant.klantnummer, "123")

with requests_mock.Mocker() as m:
m.get(SUBJECT, json={})
response = self.client.post(list_url, data)

self.assertEqual(response.status_code, 409)
klant = Klant.objects.get()

def test_create_klant_website_url_invalid_klantnummer(self):
list_url = reverse(Klant)
data = {
"bronorganisatie": "950428139",
"subjectType": KlantType.natuurlijk_persoon,
"klantnummer": "123456789",
"subject": SUBJECT,
}

with requests_mock.Mocker() as m:
m.get(SUBJECT, json={})
response = self.client.post(list_url, data)

self.assertEqual(response.status_code, 400)

klanten = Klant.objects.all()

self.assertFalse(klanten)

data = {
"bronorganisatie": "950428139",
"subjectType": KlantType.natuurlijk_persoon,
"klantnummer": "KLANT1",
"subject": SUBJECT,
}

with requests_mock.Mocker() as m:
m.get(SUBJECT, json={})
response = self.client.post(list_url, data)

self.assertEqual(response.status_code, 400)

klanten = Klant.objects.all()

self.assertFalse(klanten)

def test_create_klant_natuurlijkpersoon(self):
list_url = reverse(Klant)
data = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Generated by Django 3.2.18 on 2023-09-05 12:15

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("klanten", "0004_klant_geverifieerd"),
]

operations = [
migrations.AlterField(
model_name="klant",
name="klantnummer",
field=models.CharField(
help_text="De unieke identificatie van de klant binnen de bronorganisatie.",
max_length=8,
validators=[
django.core.validators.RegexValidator(
code="only-digits",
message="Waarde moet numeriek zijn.",
regex="^[0-9]+$",
)
],
),
),
migrations.AlterUniqueTogether(
name="klant",
unique_together=set(),
),
]
22 changes: 21 additions & 1 deletion src/openklant/components/klanten/models/klanten.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,22 @@
from django.db import models
from django.utils.translation import gettext_lazy as _

from vng_api_common.exceptions import Conflict
from vng_api_common.fields import BSNField, RSINField
from vng_api_common.models import APIMixin
from vng_api_common.validators import validate_digits

from .constants import GeslachtsAanduiding, KlantType, SoortRechtsvorm


class KlantManager(models.Manager):
def get_next_klantnummer(self):
id_max = Klant.objects.all().aggregate(models.Max("klantnummer"))[
"klantnummer__max"
]
return int(id_max) + 1 if id_max else 1


class Klant(APIMixin, models.Model):
uuid = models.UUIDField(
unique=True,
Expand All @@ -29,6 +39,7 @@ class Klant(APIMixin, models.Model):
klantnummer = models.CharField(
max_length=8,
help_text=_("De unieke identificatie van de klant binnen de bronorganisatie."),
validators=[validate_digits],
)
bedrijfsnaam = models.CharField(
max_length=200,
Expand Down Expand Up @@ -88,10 +99,19 @@ class Klant(APIMixin, models.Model):
default=False, help_text=_("Geeft aan of de KLANT wel of niet geverifieerd is.")
)

objects = KlantManager()

class Meta:
verbose_name = "klant"
verbose_name_plural = "klanten"
unique_together = ("bronorganisatie", "klantnummer")

def save(self, *args, **kwargs):
if not self.klantnummer:
self.klantnummer = Klant.objects.get_next_klantnummer()
if not self.pk:
if Klant.objects.filter(klantnummer=self.klantnummer):
raise Conflict("Klantnummer bestaat al")
return super().save(*args, **kwargs)

@property
def subject_identificatie(self):
Expand Down

0 comments on commit 19da052

Please sign in to comment.