""" Shared validators used across multiple apps. """ import re from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ # Regex for a Saudi mobile number after stripping spaces/dashes/parens/plus. # Accepts any of: # 05XXXXXXXX (10 digits, local with trunk 0) # 5XXXXXXXX (9 digits, no trunk) # 9665XXXXXXXX (12 digits, country code without +) # +9665XXXXXXXX (13 digits, country code with +) SAUDI_MOBILE_REGEX = re.compile(r"^(?:\+?966|0)?5\d{8}$") # HTML5 form pattern equivalent (HTML anchors ^...$ implicitly). # Exposed for reuse in widget attrs and template . SAUDI_PHONE_HTML_PATTERN = r"(\+?966|0)?5[0-9]{8}" def validate_saudi_phone(value): """ Validate that ``value`` is a Saudi mobile number. Accepts the following formats (spaces, dashes and parentheses are ignored): 05XXXXXXXX 5XXXXXXXX 9665XXXXXXXX +9665XXXXXXXX Stored value is returned unchanged (no normalization). Raises ``ValidationError`` if the number is not a valid Saudi mobile. """ if value is None or value == "": return value cleaned = re.sub(r"[\s\-()]", "", str(value)) if not SAUDI_MOBILE_REGEX.match(cleaned): raise ValidationError( _("Please enter a valid Saudi mobile number " "(e.g. 05XXXXXXXX or +9665XXXXXXXX)."), code="invalid_saudi_phone", ) return value