Skip to content

Commit

Permalink
Reformat phone numbers in the contact form
Browse files Browse the repository at this point in the history
  • Loading branch information
charludo committed Feb 6, 2025
1 parent 1753a82 commit 0c490a8
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 4 deletions.
6 changes: 3 additions & 3 deletions integreat_cms/cms/fixtures/test_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,7 @@
"name": "Martina Musterfrau",
"location": 6,
"email": "[email protected]",
"phone_number": "0123456789",
"phone_number": "+49 (0) 123456789",
"website": "",
"archived": false,
"last_updated": "2024-08-06T13:23:45.256Z",
Expand Down Expand Up @@ -1012,7 +1012,7 @@
"name": "Mariana Musterfrau",
"location": 6,
"email": "[email protected]",
"phone_number": "0123456789",
"phone_number": "+49 (0) 123456789",
"website": "https://integreat-app.de/",
"archived": false,
"last_updated": "2024-08-06T13:23:45.256Z",
Expand All @@ -1027,7 +1027,7 @@
"name": "",
"location": 6,
"email": "[email protected]",
"phone_number": "0123456789",
"phone_number": "+49 (0) 123456789",
"website": "https://integreat-app.de/",
"archived": false,
"last_updated": "2024-08-06T13:23:45.256Z",
Expand Down
26 changes: 26 additions & 0 deletions integreat_cms/cms/forms/contacts/contact_form.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from __future__ import annotations

import logging
import re

from django.conf import settings
from django.utils.translation import gettext_lazy as _

from ...models import Contact
Expand Down Expand Up @@ -36,3 +38,27 @@ class Meta:
error_messages = {
"location": {"invalid_choice": _("Location cannot be empty.")},
}

def clean_phone_number(self) -> str:
"""
Validate the phone number field (see :ref:`overriding-modelform-clean-method`).
The number will be converted to the international format, i.e. `+XX (X) XXXXXXXX`.
:return: The reformatted phone number
"""
phone_number = self.cleaned_data["phone_number"]
if not phone_number or re.fullmatch(r"^\+\d{2,3} \(0\) \d*$", phone_number):
return phone_number

phone_number = re.sub(r"[^0-9+]", "", phone_number)
prefix = settings.DEFAULT_PHONE_NUMBER_COUNTRY_CODE
if phone_number.startswith("00"):
prefix = f"+{phone_number[2:4]}"
phone_number = phone_number[4:]
elif phone_number.startswith("0"):
phone_number = phone_number[1:]
elif phone_number.startswith("+"):
prefix = phone_number[0:3]
phone_number = phone_number[3:]

return f"{prefix} (0) {phone_number}"
2 changes: 1 addition & 1 deletion integreat_cms/cms/templates/contacts/contact_card.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ <h4>
alt="Phone Number: "
width="15"
height="15" />
<a href="tel:{{ contact.phone_number }}">{{ contact.phone_number }}</a>
<a href="tel:{{ contact.phone_number|cut:" (0) " }}">{{ contact.phone_number }}</a>
</p>
{% endif %}
{% if contact.website and "website" in wanted %}
Expand Down
6 changes: 6 additions & 0 deletions integreat_cms/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,12 @@
"integreat_cms.core.formats",
]

#: The country code used for phone numbers when converting user input to a standardized international format,
#: if no country code is specified by the user.
DEFAULT_PHONE_NUMBER_COUNTRY_CODE: Final[str] = os.environ.get(
"INTEGREAT_CMS_DEFAULT_PHONE_NUMBER_COUNTRY_CODE", "+49"
)


#####################################
# MT Global - AUTOMATIC TRANSLATION #
Expand Down
35 changes: 35 additions & 0 deletions tests/cms/views/contacts/test_contact_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import pytest
from django.urls import reverse

from integreat_cms.cms.forms import ContactForm
from integreat_cms.cms.models import Contact, Region
from tests.conftest import ANONYMOUS, HIGH_PRIV_STAFF_ROLES
from tests.utils import assert_message_in_log
Expand Down Expand Up @@ -287,3 +288,37 @@ def test_one_primary_contact_per_poi(
)
else:
assert response.status_code == 403


@pytest.mark.django_db
def test_phone_number_conversion() -> None:
"""
Test that phone numbers are converted to the expected international format.
"""
variants = [
"+49123456789",
"0123456789",
"012 34/56789",
"01234-56789",
"0049123456789",
"00 (49) (1234) 56789",
" +49/1234-56789",
]
for variant in variants:
form_data = {
"location": POI_ID,
"point_of_contact_for": "test",
"name": "",
"email": "[email protected]",
"phone_number": variant,
"website": "https://integreat-app.de/",
}

form = ContactForm(
data=form_data,
instance=None,
additional_instance_attributes={"region": REGION_SLUG},
)
form.is_valid() # this is not an assert, because it would fail. calling is_valid() is required to populate cleaned_data.
cleaned = form.clean()
assert cleaned["phone_number"] == "+49 (0) 123456789"

0 comments on commit 0c490a8

Please sign in to comment.