365 lines
13 KiB
Python
365 lines
13 KiB
Python
import re
|
|
from django.utils import timezone
|
|
from django.contrib.auth.hashers import make_password
|
|
from rest_framework import serializers
|
|
|
|
from accounts.models import (
|
|
AppVersion,
|
|
IAmPrincipal,
|
|
IAmPrincipalType,
|
|
# IAmPrincipalKYCDetails,
|
|
)
|
|
from manage_events.models import EventPrincipalInteraction, PrincipalPreference
|
|
from manage_referrals.models import (
|
|
ReferralCode,
|
|
ReferralRecord,
|
|
)
|
|
from goodtimes import constants, date_utils
|
|
from manage_subscriptions.models import PrincipalSubscription, SubscriptionStatus
|
|
|
|
|
|
def clean_phone(number: str):
|
|
"""Validates number starts with +91 or 0, then 10 digits"""
|
|
number_pattern = re.compile(r"^(?:\+91|0)\d{10}$")
|
|
result = number_pattern.match(number)
|
|
if not result:
|
|
raise serializers.ValidationError({"phone_no": constants.PHONE_NUMBER_INVALID})
|
|
if number.startswith("0"):
|
|
return "+91" + number[1:]
|
|
return number
|
|
|
|
|
|
# class PhoneSerializer(serializers.Serializer):
|
|
# phone_no = serializers.CharField(max_length=15, required=True)
|
|
|
|
# def validate(self, attrs):
|
|
# phone_no = attrs.get("phone_no")
|
|
# cleaned_number = clean_phone(phone_no)
|
|
# attrs["phone_no"] = cleaned_number
|
|
# return super().validate(attrs)
|
|
|
|
|
|
class EmailSerializer(serializers.Serializer):
|
|
email = serializers.EmailField(
|
|
required=True,
|
|
)
|
|
principal_type = serializers.CharField(required=True, write_only=True)
|
|
|
|
def validate_principal_type_name(self, value):
|
|
"""
|
|
Check that the principal_type_name corresponds to a valid IAmPrincipalType.
|
|
"""
|
|
if not IAmPrincipalType.objects.filter(name=value).exists():
|
|
raise serializers.ValidationError("Invalid principal type name.")
|
|
return value
|
|
|
|
|
|
class BasePasswordSerializer(serializers.Serializer):
|
|
confirm_password = serializers.CharField(max_length=20, write_only=True)
|
|
|
|
def validate(self, attrs):
|
|
password = attrs.get("password")
|
|
confirm_password = attrs.pop("confirm_password", None)
|
|
|
|
if password != confirm_password:
|
|
raise serializers.ValidationError(
|
|
{"confirm_password": "Password do not match"}
|
|
)
|
|
|
|
return super().validate(attrs)
|
|
|
|
def update(self, instance, validated_data):
|
|
new_password = validated_data.get("password")
|
|
if new_password:
|
|
instance.password = make_password(new_password)
|
|
# instance.set_password(new_password)
|
|
instance.save()
|
|
return instance
|
|
|
|
|
|
class RegistrationSerializer(BasePasswordSerializer, serializers.ModelSerializer):
|
|
# email = serializers.EmailField(
|
|
# required=True,
|
|
# )
|
|
class Meta:
|
|
model = IAmPrincipal
|
|
fields = ["first_name", "last_name", "email", "password", "confirm_password"]
|
|
extra_kwargs = {
|
|
"first_name": {"required": True},
|
|
"last_name": {"required": True},
|
|
"email": {"required": True},
|
|
}
|
|
|
|
# def validate(self, attrs):
|
|
# email = attrs.get("email")
|
|
|
|
# # Check if the email is already associated with any user
|
|
# user_with_email = IAmPrincipal.objects.filter(email=email).first()
|
|
|
|
# if user_with_email:
|
|
# raise serializers.ValidationError({"email": [constants.EMAIL_EXISTS]})
|
|
# # # Check if the user has a different phone number
|
|
# # if user_with_email.phone_no != phone_no:
|
|
# # raise serializers.ValidationError({"email": [constants.EMAIL_EXISTS]})
|
|
|
|
# return attrs
|
|
|
|
def update(self, instance, validated_data):
|
|
# update prinicpal instance fiedls based on the validation data
|
|
instance.first_name = validated_data.get("first_name", instance.first_name)
|
|
instance.last_name = validated_data.get("last_name", instance.last_name)
|
|
instance.email = validated_data.get("email", instance.email)
|
|
instance.username = validated_data.get("email", instance.email)
|
|
# Set the new password (if provided) correctly using set_password method
|
|
if "password" in validated_data:
|
|
new_password = validated_data["password"]
|
|
print("new_password serializers: ", new_password)
|
|
instance.set_password(
|
|
new_password
|
|
) # Correctly use set_password without assignment
|
|
|
|
instance.save()
|
|
return instance
|
|
|
|
|
|
class RegistrationPasswordSerializer(
|
|
BasePasswordSerializer, serializers.ModelSerializer
|
|
):
|
|
class Meta:
|
|
model = IAmPrincipal
|
|
fields = ["email", "password", "confirm_password"]
|
|
|
|
|
|
class PasswordResetSerializer(BasePasswordSerializer, serializers.ModelSerializer):
|
|
class Meta:
|
|
model = IAmPrincipal
|
|
fields = ["password", "confirm_password"]
|
|
|
|
from phonenumbers import parse, phonenumberutil, NumberParseException
|
|
|
|
class ProfileSerializer(serializers.ModelSerializer):
|
|
profile_photo = serializers.ImageField(required=False)
|
|
email = serializers.CharField(read_only=True)
|
|
invite_count = serializers.SerializerMethodField(read_only=True)
|
|
principal_type_name = serializers.SerializerMethodField(read_only=True)
|
|
has_active_subscription = serializers.SerializerMethodField(read_only=True)
|
|
has_preferences = serializers.SerializerMethodField(read_only=True)
|
|
register_complete = serializers.BooleanField(read_only=True)
|
|
is_active = serializers.BooleanField(read_only=True)
|
|
going_events_count = serializers.SerializerMethodField(read_only=True)
|
|
interested_events_count = serializers.SerializerMethodField(read_only=True)
|
|
phone_no = serializers.CharField(required=True)
|
|
|
|
class Meta:
|
|
model = IAmPrincipal
|
|
fields = [
|
|
"principal_type",
|
|
"principal_type_name",
|
|
"profile_photo",
|
|
"player_id",
|
|
"first_name",
|
|
"last_name",
|
|
"phone_no",
|
|
"email",
|
|
"invite_count",
|
|
"register_complete",
|
|
"has_active_subscription",
|
|
"has_preferences",
|
|
"linkedin_profile",
|
|
"youtube_profile",
|
|
"facebook_profile",
|
|
"instagram_profile",
|
|
"website",
|
|
"is_active",
|
|
"going_events_count",
|
|
"interested_events_count",
|
|
]
|
|
|
|
# def validate_phone_no(self, value):
|
|
# try:
|
|
# # Parse the phone number
|
|
# phone_number = parse(value)
|
|
# # Check for validity
|
|
# if not phonenumberutil.is_valid_number(phone_number):
|
|
# raise serializers.ValidationError('Please enter a valid phone number.')
|
|
# return value
|
|
# except NumberParseException:
|
|
# raise serializers.ValidationError('The phone number format is invalid.')
|
|
|
|
def update(self, instance, validated_data):
|
|
instance.profile_photo = validated_data.get(
|
|
"profile_photo", instance.profile_photo
|
|
)
|
|
instance.first_name = validated_data.get("first_name", instance.first_name)
|
|
instance.last_name = validated_data.get("last_name", instance.last_name)
|
|
return super().update(instance, validated_data)
|
|
|
|
def get_going_events_count(self, obj):
|
|
return EventPrincipalInteraction.objects.filter(
|
|
principal=obj, status="going"
|
|
).count()
|
|
|
|
def get_interested_events_count(self, obj):
|
|
return EventPrincipalInteraction.objects.filter(
|
|
principal=obj, status="interested"
|
|
).count()
|
|
|
|
def get_invite_count(self, obj):
|
|
if obj:
|
|
return ReferralRecord.get_invite_count(obj)
|
|
return 0
|
|
|
|
def get_principal_type_name(self, obj):
|
|
return obj.principal_type.name if obj.principal_type else None
|
|
|
|
def get_has_preferences(self, obj):
|
|
return PrincipalPreference.objects.filter(principal=obj).exists()
|
|
|
|
def get_image_url(self, obj, field_name, request):
|
|
image_field = getattr(obj, field_name)
|
|
if image_field:
|
|
return request.build_absolute_uri(image_field.url)
|
|
return ""
|
|
|
|
def get_has_active_subscription(self, obj):
|
|
subscription_status = {
|
|
"has_active_subscription": False,
|
|
"in_grace_period": False,
|
|
"grace_period_end_date": None,
|
|
}
|
|
today = timezone.now().date()
|
|
|
|
# Attempt to find the active subscription with the furthest grace_period_end_date
|
|
latest_subscription = (
|
|
PrincipalSubscription.objects.filter(
|
|
principal=obj,
|
|
is_paid=True,
|
|
cancelled=False,
|
|
deleted=False,
|
|
active=True,
|
|
status=SubscriptionStatus.ACTIVE,
|
|
)
|
|
.order_by("-grace_period_end_date")
|
|
.first()
|
|
) # Order by descending grace_period_end_date and take the first
|
|
|
|
if latest_subscription:
|
|
# Check if we're within the grace period
|
|
if today <= latest_subscription.grace_period_end_date:
|
|
subscription_status["has_active_subscription"] = (
|
|
today <= latest_subscription.end_date
|
|
)
|
|
subscription_status["in_grace_period"] = (
|
|
latest_subscription.end_date
|
|
< today
|
|
<= latest_subscription.grace_period_end_date
|
|
)
|
|
subscription_status["grace_period_end_date"] = (
|
|
latest_subscription.grace_period_end_date
|
|
)
|
|
|
|
return subscription_status
|
|
|
|
def to_representation(self, instance):
|
|
data = super().to_representation(instance)
|
|
request = self.context.get("request")
|
|
data["profile_photo"] = self.get_image_url(instance, "profile_photo", request)
|
|
return data
|
|
|
|
|
|
# class PrincipalKYCDetailsSerializer(serializers.ModelSerializer):
|
|
# aadhar_front_image = serializers.ImageField(required=False)
|
|
# aadhar_back_image = serializers.ImageField(required=False)
|
|
# pan_image = serializers.ImageField(required=False)
|
|
|
|
# class Meta:
|
|
# model = IAmPrincipalKYCDetails
|
|
# fields = [
|
|
# "aadhar_front_image",
|
|
# "aadhar_back_image",
|
|
# "aadhar_number",
|
|
# "is_aadhar_verified",
|
|
# "pan_image",
|
|
# "pan_number",
|
|
# "is_pan_verified",
|
|
# "account_no",
|
|
# "bank_name",
|
|
# "branch_name",
|
|
# "ifsc_code",
|
|
# ]
|
|
|
|
# def create(self, validated_data):
|
|
# # Extract and set the principal (user) from the request context
|
|
# validated_data["principal"] = self.context.get("request").user
|
|
|
|
# return super(PrincipalKYCDetailsSerializer, self).create(validated_data)
|
|
|
|
# def get_image_url(self, obj, field_name, request):
|
|
# image_field = getattr(obj, field_name)
|
|
# if image_field:
|
|
# return request.build_absolute_uri(image_field.url)
|
|
# return ""
|
|
|
|
# def to_representation(self, instance):
|
|
# data = super().to_representation(instance)
|
|
# request = self.context.get("request")
|
|
# if request:
|
|
# data["aadhar_front_image"] = self.get_image_url(
|
|
# instance, "aadhar_front_image", request
|
|
# )
|
|
# data["aadhar_back_image"] = self.get_image_url(
|
|
# instance, "aadhar_back_image", request
|
|
# )
|
|
# data["pan_image"] = self.get_image_url(instance, "pan_image", request)
|
|
# return data
|
|
|
|
|
|
class ReferralCodeSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = ReferralCode
|
|
fields = ["referral_code"]
|
|
|
|
|
|
class ReferralRecordSerializer(serializers.ModelSerializer):
|
|
name = serializers.SerializerMethodField()
|
|
join_at = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = ReferralRecord
|
|
fields = ["name", "join_at"]
|
|
|
|
def get_name(self, obj):
|
|
# Check if the referred_principal is set (not None) and get the full name
|
|
if obj.referred_principal:
|
|
return obj.referred_principal.get_full_name()
|
|
return None
|
|
|
|
def get_join_at(self, obj):
|
|
return date_utils.format_date_to_string(obj.created_on)
|
|
|
|
|
|
# added 's' to differentiate with Email Serializer
|
|
class EmailSerializers(serializers.Serializer):
|
|
email = serializers.EmailField(required=True)
|
|
# otp = serializers.CharField(required=True)
|
|
|
|
|
|
class ProfilePhotoSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = IAmPrincipal
|
|
fields = ("email", "profile_photo", "first_name")
|
|
|
|
|
|
class PlayerIDSerializer(serializers.Serializer):
|
|
player_id = serializers.CharField(max_length=255)
|
|
|
|
|
|
class AppVersionSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = AppVersion
|
|
fields = [
|
|
"app_type",
|
|
"version",
|
|
"force_upgrade",
|
|
"recommend_upgrade",
|
|
] |