From bb073734b379fae64966a34489e75ae9015e898d Mon Sep 17 00:00:00 2001
From: Tore Brede <Tore.Brede@uib.no>
Date: Mon, 6 Dec 2021 10:26:04 +0100
Subject: [PATCH] GREG-130: Allowing D-number in national ID-field

---
 greg/models.py                            |  2 +-
 greg/utils.py                             | 10 ++++++++-
 gregui/tests/api/views/test_invitation.py | 26 +++++++++++++++++++++++
 gregui/validation.py                      | 11 +++++-----
 4 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/greg/models.py b/greg/models.py
index 6591172b..dd7bb127 100644
--- a/greg/models.py
+++ b/greg/models.py
@@ -270,7 +270,7 @@ class Identity(BaseModel):
         FEIDE_ID = "feide_id"
         FEIDE_EMAIL = "feide_email"
         PASSPORT_NUMBER = "passport_number"
-        # Norwegian national ID - "fødselsnummer"
+        # Norwegian national ID - "fødselsnummer" or D-number
         NORWEGIAN_NATIONAL_ID_NUMBER = "norwegian_national_id_number"
         PRIVATE_EMAIL = "private_email"
         PRIVATE_MOBILE_NUMBER = "private_mobile"
diff --git a/greg/utils.py b/greg/utils.py
index 9d547238..c6480303 100644
--- a/greg/utils.py
+++ b/greg/utils.py
@@ -9,9 +9,17 @@ def camel_to_snake(s: str) -> str:
     return re.sub("([A-Z])", "_\\1", s).lower().lstrip("_")
 
 
+def is_valid_id_number(input_digits: str) -> bool:
+    """
+    Checks whether the input represents a valid national ID number (fødselsnummer) or a valid D-number.
+    """
+    is_dnumber = int(input_digits[0:1]) >= 4
+    return is_valid_norwegian_national_id_number(input_digits, is_dnumber)
+
+
 def is_valid_norwegian_national_id_number(input_digits: str, is_dnumber: bool) -> bool:
     """
-    Checks whether input_digits is a valid national ID number of D-number.
+    Checks whether input_digits is a valid national ID number or D-number.
 
     It is based on the code found here:
     https://github.com/navikt/fnrvalidator/blob/master/src/validator.js
diff --git a/gregui/tests/api/views/test_invitation.py b/gregui/tests/api/views/test_invitation.py
index fba3f5d0..8a10b372 100644
--- a/gregui/tests/api/views/test_invitation.py
+++ b/gregui/tests/api/views/test_invitation.py
@@ -467,3 +467,29 @@ def test_saves_consents(client, invited_person, consent_type_foo, consent_type_b
         type=consent_type_bar,
         choice=consent_type_bar.choices.filter(value="yes").first(),
     ).exists()
+
+
+@pytest.mark.django_db
+def test_post_invited_info_valid_dnumber(client, invited_person):
+    person, invitation_link = invited_person
+    d_number = "53097248016"
+    data = {
+        "person": {
+            "mobile_phone": "+4797543992",
+            "email": "test@example.com",
+            "fnr": d_number,
+        }
+    }
+    url = reverse("gregui-v1:invited-info")
+
+    assert person.fnr is None
+
+    session = client.session
+    session["invite_id"] = str(invitation_link.uuid)
+    session.save()
+
+    response = client.post(url, data, format="json")
+
+    assert response.status_code == status.HTTP_200_OK, response.data
+    person.refresh_from_db()
+    assert person.fnr.value == d_number
diff --git a/gregui/validation.py b/gregui/validation.py
index ecdfca28..0034f48b 100644
--- a/gregui/validation.py
+++ b/gregui/validation.py
@@ -3,16 +3,17 @@ from typing import Optional
 import phonenumbers
 from rest_framework import serializers
 
-from greg.utils import is_valid_norwegian_national_id_number
+from greg.utils import is_valid_id_number
 
 _valid_email_regex = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"
 
 
 def validate_norwegian_national_id_number(value):
-    # Not excepted that D-numbers will be entered through the form, so only
-    # accept national ID numbers
-    if not is_valid_norwegian_national_id_number(value, False):
-        raise serializers.ValidationError("Not a valid Norwegian national ID number")
+    """
+    Both fødselsnummer and D-nummer are accepted
+    """
+    if not is_valid_id_number(value):
+        raise serializers.ValidationError("Not a valid ID number")
 
 
 def validate_phone_number(value):
-- 
GitLab