mirror of
https://github.com/i701/sarlink-portal-api.git
synced 2025-10-08 09:11:36 +00:00
refactor(view): extract validation logic from CreateTemporaryUserView to
reduce cyclomatic complexity 🔨
This commit is contained in:
83
api/helpers.py
Normal file
83
api/helpers.py
Normal file
@@ -0,0 +1,83 @@
|
||||
from rest_framework.response import Response
|
||||
from typing import Optional
|
||||
from datetime import date
|
||||
from django.utils import timezone
|
||||
import re
|
||||
|
||||
|
||||
ID_CARD_PATTERN = r"^[A-Z]{1,2}[0-9]{6,7}$"
|
||||
MOBILE_PATTERN = r"^[7|9][0-9]{6}$"
|
||||
ACCOUNT_NUMBER_PATTERN = r"^(7\d{12}|9\d{16})$"
|
||||
|
||||
|
||||
class ErrorMessages:
|
||||
USERNAME_EXISTS = "Username already exists."
|
||||
MOBILE_EXISTS = "Mobile number already exists."
|
||||
INVALID_ID_CARD = "Please enter a valid ID card number."
|
||||
ID_CARD_EXISTS = "ID card already exists."
|
||||
INVALID_MOBILE = "Please enter a valid mobile number."
|
||||
INVALID_ACCOUNT = "Please enter a valid account number."
|
||||
UNDERAGE_ERROR = "You must be 18 and above to signup."
|
||||
|
||||
|
||||
def validate_required_fields(data) -> Optional[Response]:
|
||||
required_fields = {
|
||||
"firstname": "First name",
|
||||
"lastname": "Last name",
|
||||
"username": "Username",
|
||||
"address": "Address",
|
||||
"mobile": "Mobile number",
|
||||
"acc_no": "Account number",
|
||||
"id_card": "ID card",
|
||||
"dob": "Date of birth",
|
||||
"atoll": "Atoll",
|
||||
"island": "Island",
|
||||
}
|
||||
|
||||
for field, label in required_fields.items():
|
||||
if not data.get(field):
|
||||
return Response({"message": f"{label} is required."}, status=400)
|
||||
|
||||
if data.get("terms_accepted") is None:
|
||||
return Response({"message": "Terms acceptance is required."}, status=400)
|
||||
if data.get("policy_accepted") is None:
|
||||
return Response({"message": "Policy acceptance is required."}, status=400)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
from .models import TemporaryUser, User
|
||||
|
||||
def validate_unique_fields(username, mobile, id_card) -> Optional[Response]:
|
||||
if mobile and (TemporaryUser.objects.filter(t_mobile=mobile).exists() or User.objects.filter(mobile=mobile).exists()):
|
||||
return Response({"message": ErrorMessages.MOBILE_EXISTS}, status=400)
|
||||
|
||||
if username and (TemporaryUser.objects.filter(t_username=username).exists() or User.objects.filter(username=username).exists()):
|
||||
return Response({"message": ErrorMessages.USERNAME_EXISTS}, status=400)
|
||||
|
||||
if id_card and (TemporaryUser.objects.filter(t_id_card=id_card).exists() or User.objects.filter(id_card=id_card).exists()):
|
||||
return Response({"message": ErrorMessages.ID_CARD_EXISTS}, status=400)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
def validate_patterns(id_card, mobile, acc_no) -> Optional[Response]:
|
||||
if id_card and not re.match(ID_CARD_PATTERN, id_card):
|
||||
return Response({"message": ErrorMessages.INVALID_ID_CARD}, status=400)
|
||||
|
||||
if mobile is None or not re.match(MOBILE_PATTERN, mobile):
|
||||
return Response({"message": ErrorMessages.INVALID_MOBILE}, status=400)
|
||||
|
||||
if acc_no is None or not re.match(ACCOUNT_NUMBER_PATTERN, acc_no):
|
||||
return Response({"message": ErrorMessages.INVALID_ACCOUNT}, status=400)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
def calculate_age(dob: date) -> int:
|
||||
today = timezone.now().date()
|
||||
return today.year - dob.year - ((today.month, today.day) < (dob.month, dob.day))
|
Reference in New Issue
Block a user