mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-07-15 10:05:21 +00:00
changes in files
This commit is contained in:
@ -2,15 +2,30 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
"""Import django app"""
|
"""Import django app"""
|
||||||
from .models import UserProfile, UserEmailOtp, UserPhoneOtp
|
from .models import UserEmailOtp, UserPhoneOtp, DefaultTaskImages, UserNotification, UserDelete
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
@admin.register(UserProfile)
|
|
||||||
class UserProfileAdmin(admin.ModelAdmin):
|
@admin.register(UserDelete)
|
||||||
|
class UserDeleteAdmin(admin.ModelAdmin):
|
||||||
"""User profile admin"""
|
"""User profile admin"""
|
||||||
list_display = ['user']
|
list_display = ['user', 'old_email', 'd_email']
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.user__email
|
return self.user
|
||||||
|
@admin.register(UserNotification)
|
||||||
|
class UserNotificationAdmin(admin.ModelAdmin):
|
||||||
|
"""User profile admin"""
|
||||||
|
list_display = ['user', 'push_notification', 'email_notification', 'sms_notification']
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.image_url
|
||||||
|
@admin.register(DefaultTaskImages)
|
||||||
|
class DefaultTaskImagesAdmin(admin.ModelAdmin):
|
||||||
|
"""User profile admin"""
|
||||||
|
list_display = ['task_name', 'image_url']
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.image_url
|
||||||
|
|
||||||
@admin.register(UserEmailOtp)
|
@admin.register(UserEmailOtp)
|
||||||
class UserEmailOtpAdmin(admin.ModelAdmin):
|
class UserEmailOtpAdmin(admin.ModelAdmin):
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
"""Account app file"""
|
||||||
|
"""Import Django"""
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class AccountConfig(AppConfig):
|
class AccountConfig(AppConfig):
|
||||||
|
"""default configurations"""
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
name = 'account'
|
name = 'account'
|
||||||
|
26
account/migrations/0003_defaulttaskimages.py
Normal file
26
account/migrations/0003_defaulttaskimages.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-07 10:23
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('account', '0002_useremailotp_user_type'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='DefaultTaskImages',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('task_name', models.CharField(max_length=15)),
|
||||||
|
('image_url', models.URLField(blank=True, default=None, null=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'default_task_image',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
31
account/migrations/0004_userdelete.py
Normal file
31
account/migrations/0004_userdelete.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-10 09:24
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('account', '0003_defaulttaskimages'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UserDelete',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('old_email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='Original Email')),
|
||||||
|
('d_email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='Dummy Email')),
|
||||||
|
('is_active', models.BooleanField(default=True)),
|
||||||
|
('reason', models.TextField(blank=True, max_length=500, null=True, verbose_name='Reason for Leaving')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='delete_information_set', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'user_delete_information',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
31
account/migrations/0005_usernotification.py
Normal file
31
account/migrations/0005_usernotification.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-10 12:40
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('account', '0004_userdelete'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UserNotification',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('push_notification', models.BooleanField(default=True)),
|
||||||
|
('email_notification', models.BooleanField(default=True)),
|
||||||
|
('sms_notification', models.BooleanField(default=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='user_notification', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'user_notification',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
@ -1,6 +1,8 @@
|
|||||||
|
"""Account module file"""
|
||||||
|
"""Django import"""
|
||||||
from django.db import models
|
from django.db import models
|
||||||
import random
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
"""App import"""
|
||||||
from base.constants import USER_TYPE
|
from base.constants import USER_TYPE
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
||||||
@ -70,7 +72,71 @@ class UserEmailOtp(models.Model):
|
|||||||
class Meta(object):
|
class Meta(object):
|
||||||
""" Meta information """
|
""" Meta information """
|
||||||
db_table = 'user_email_otp'
|
db_table = 'user_email_otp'
|
||||||
|
verbose_name = 'User Email OTP'
|
||||||
|
verbose_name_plural = 'User Email OTP'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""return phone as an object"""
|
"""return phone as an object"""
|
||||||
return self.email
|
return self.email
|
||||||
|
|
||||||
|
class DefaultTaskImages(models.Model):
|
||||||
|
"""Default images upload in oss bucket"""
|
||||||
|
|
||||||
|
task_name = models.CharField(max_length=15)
|
||||||
|
image_url = models.URLField(null=True, blank=True, default=None)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
""" Meta information """
|
||||||
|
db_table = 'default_task_image'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""return phone as an object"""
|
||||||
|
return self.task_name
|
||||||
|
|
||||||
|
class UserDelete(models.Model):
|
||||||
|
"""
|
||||||
|
User delete information
|
||||||
|
"""
|
||||||
|
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='delete_information_set')
|
||||||
|
"""Old email"""
|
||||||
|
old_email = models.EmailField(blank=True, null=True, verbose_name='Original Email')
|
||||||
|
"""Dummy email"""
|
||||||
|
d_email = models.EmailField(blank=True, null=True, verbose_name='Dummy Email')
|
||||||
|
is_active = models.BooleanField(default=True)
|
||||||
|
"""reason for leaving"""
|
||||||
|
reason = models.TextField(max_length=500, blank=True, null=True, verbose_name='Reason for Leaving')
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
""" Meta information """
|
||||||
|
db_table = 'user_delete_information'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.user.email
|
||||||
|
|
||||||
|
|
||||||
|
class UserNotification(models.Model):
|
||||||
|
"""
|
||||||
|
User notification details
|
||||||
|
"""
|
||||||
|
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user_notification')
|
||||||
|
"""Push Notification"""
|
||||||
|
push_notification = models.BooleanField(default=True)
|
||||||
|
"""Email Notification"""
|
||||||
|
email_notification = models.BooleanField(default=True)
|
||||||
|
"""SMS Notification"""
|
||||||
|
sms_notification = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
""" Meta information """
|
||||||
|
db_table = 'user_notification'
|
||||||
|
verbose_name = 'User Notification'
|
||||||
|
verbose_name_plural = 'User Notification'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.user.email
|
||||||
|
@ -1,40 +1,47 @@
|
|||||||
|
"""Account serializer"""
|
||||||
|
"""Django Imoprt"""
|
||||||
|
import random
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from rest_framework_simplejwt.tokens import RefreshToken
|
||||||
|
"""App import"""
|
||||||
from guardian.models import Guardian
|
from guardian.models import Guardian
|
||||||
from junior.models import Junior
|
from junior.models import Junior
|
||||||
from account.models import UserProfile, UserEmailOtp, UserPhoneOtp
|
from account.models import UserEmailOtp, DefaultTaskImages, UserDelete, UserNotification, UserPhoneOtp
|
||||||
from base.constants import GUARDIAN, JUNIOR, SUPERUSER
|
from base.constants import GUARDIAN, JUNIOR, SUPERUSER
|
||||||
from django.db import transaction
|
|
||||||
from base.messages import ERROR_CODE_REQUIRED, ERROR_CODE, SUCCESS_CODE, STATUS_CODE_ERROR
|
from base.messages import ERROR_CODE_REQUIRED, ERROR_CODE, SUCCESS_CODE, STATUS_CODE_ERROR
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from .utils import junior_account_update, guardian_account_update
|
||||||
from django.contrib.auth import authenticate
|
|
||||||
from rest_framework import viewsets, status
|
|
||||||
from rest_framework.decorators import action
|
|
||||||
from django.contrib.auth import authenticate, login
|
|
||||||
from rest_framework_simplejwt.tokens import RefreshToken
|
|
||||||
from guardian.utils import upload_image_to_alibaba
|
|
||||||
|
|
||||||
class GoogleSignInSerializer(serializers.Serializer):
|
class GoogleLoginSerializer(serializers.Serializer):
|
||||||
"""Google login Serializer"""
|
"""google login serializer"""
|
||||||
email = serializers.EmailField()
|
access_token = serializers.CharField(max_length=5000, required=True)
|
||||||
|
|
||||||
def create(self, validated_data):
|
class Meta(object):
|
||||||
"""Create or update user model"""
|
"""meta class"""
|
||||||
with transaction.atomic():
|
fields = ('access_token',)
|
||||||
if User.objects.filter(email__iexact=self.validated_data['email']).exists():
|
|
||||||
return User.objects.get(email__iexact=self.validated_data['email'])
|
|
||||||
|
class UpdateJuniorProfileImageSerializer(serializers.ModelSerializer):
|
||||||
|
"""update junior image"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = Junior
|
||||||
|
fields = ['image']
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
"""update image """
|
||||||
|
junior_image = validated_data.get('image', instance.image)
|
||||||
|
instance.image = junior_image
|
||||||
|
instance.save()
|
||||||
|
return instance
|
||||||
|
|
||||||
if not User.objects.filter(email__iexact=self.validated_data['email']).exists():
|
|
||||||
instance = User.objects.create(username=self.validated_data['email'],
|
|
||||||
email=self.validated_data['email'])
|
|
||||||
return instance
|
|
||||||
|
|
||||||
class UpdateGuardianImageSerializer(serializers.ModelSerializer):
|
class UpdateGuardianImageSerializer(serializers.ModelSerializer):
|
||||||
"""Reset Password after verification"""
|
"""update guardian image"""
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
model = Guardian
|
model = Guardian
|
||||||
fields = '__all__'
|
fields = ['image']
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
"""update image """
|
"""update image """
|
||||||
@ -42,21 +49,7 @@ class UpdateGuardianImageSerializer(serializers.ModelSerializer):
|
|||||||
instance.save()
|
instance.save()
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
class UpdateJuniorProfileImageSerializer(serializers.ModelSerializer):
|
|
||||||
"""Reset Password after verification"""
|
|
||||||
class Meta(object):
|
|
||||||
"""Meta info"""
|
|
||||||
model = Junior
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
|
||||||
"""update image """
|
|
||||||
image = validated_data.get('image', instance.image)
|
|
||||||
filename = f"images/{image.name}"
|
|
||||||
image_url = upload_image_to_alibaba(image, filename)
|
|
||||||
instance.image = image_url
|
|
||||||
instance.save()
|
|
||||||
return instance
|
|
||||||
class ResetPasswordSerializer(serializers.Serializer):
|
class ResetPasswordSerializer(serializers.Serializer):
|
||||||
"""Reset Password after verification"""
|
"""Reset Password after verification"""
|
||||||
verification_code = serializers.CharField(max_length=10)
|
verification_code = serializers.CharField(max_length=10)
|
||||||
@ -90,10 +83,9 @@ class ChangePasswordSerializer(serializers.Serializer):
|
|||||||
|
|
||||||
def validate_current_password(self, value):
|
def validate_current_password(self, value):
|
||||||
user = self.context
|
user = self.context
|
||||||
if self.context.password not in ('', None):
|
if self.context.password not in ('', None) and user.check_password(value):
|
||||||
if user.check_password(value):
|
return value
|
||||||
return value
|
raise serializers.ValidationError(ERROR_CODE['2015'])
|
||||||
raise serializers.ValidationError({"details":ERROR_CODE['2015']})
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
new_password = validated_data.pop('new_password')
|
new_password = validated_data.pop('new_password')
|
||||||
current_password = validated_data.pop('current_password')
|
current_password = validated_data.pop('current_password')
|
||||||
@ -113,6 +105,7 @@ class ForgotPasswordSerializer(serializers.Serializer):
|
|||||||
email = serializers.EmailField()
|
email = serializers.EmailField()
|
||||||
|
|
||||||
class SuperUserSerializer(serializers.ModelSerializer):
|
class SuperUserSerializer(serializers.ModelSerializer):
|
||||||
|
"""Super admin serializer"""
|
||||||
user_type = serializers.SerializerMethodField('get_user_type')
|
user_type = serializers.SerializerMethodField('get_user_type')
|
||||||
|
|
||||||
def get_user_type(self, obj):
|
def get_user_type(self, obj):
|
||||||
@ -138,9 +131,13 @@ class GuardianSerializer(serializers.ModelSerializer):
|
|||||||
access_token = str(refresh.access_token)
|
access_token = str(refresh.access_token)
|
||||||
return access_token
|
return access_token
|
||||||
|
|
||||||
|
|
||||||
def get_user_type(self, obj):
|
def get_user_type(self, obj):
|
||||||
"""user type"""
|
"""user type"""
|
||||||
return GUARDIAN
|
email_verified = UserEmailOtp.objects.filter(email=obj.user.username).last()
|
||||||
|
if email_verified and email_verified.user_type != None:
|
||||||
|
return email_verified.user_type
|
||||||
|
return '2'
|
||||||
|
|
||||||
def get_auth(self, obj):
|
def get_auth(self, obj):
|
||||||
"""user email address"""
|
"""user email address"""
|
||||||
@ -157,9 +154,9 @@ class GuardianSerializer(serializers.ModelSerializer):
|
|||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
model = Guardian
|
model = Guardian
|
||||||
fields = ['auth_token', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'family_name', 'gender', 'dob',
|
fields = ['id', 'auth_token', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'family_name',
|
||||||
'referral_code', 'is_active', 'is_complete_profile', 'passcode',
|
'gender', 'dob', 'referral_code', 'is_active', 'is_complete_profile', 'passcode', 'image',
|
||||||
'created_at', 'updated_at', 'user_type']
|
'created_at', 'updated_at', 'user_type', 'country_name']
|
||||||
|
|
||||||
|
|
||||||
class JuniorSerializer(serializers.ModelSerializer):
|
class JuniorSerializer(serializers.ModelSerializer):
|
||||||
@ -176,7 +173,10 @@ class JuniorSerializer(serializers.ModelSerializer):
|
|||||||
return access_token
|
return access_token
|
||||||
|
|
||||||
def get_user_type(self, obj):
|
def get_user_type(self, obj):
|
||||||
return JUNIOR
|
email_verified = UserEmailOtp.objects.filter(email=obj.auth.username).last()
|
||||||
|
if email_verified and email_verified.user_type != None:
|
||||||
|
return email_verified.user_type
|
||||||
|
return '1'
|
||||||
|
|
||||||
def get_auth(self, obj):
|
def get_auth(self, obj):
|
||||||
return obj.auth.username
|
return obj.auth.username
|
||||||
@ -190,9 +190,9 @@ class JuniorSerializer(serializers.ModelSerializer):
|
|||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
model = Junior
|
model = Junior
|
||||||
fields = ['auth_token', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob',
|
fields = ['id', 'auth_token', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob',
|
||||||
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at',
|
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image',
|
||||||
'updated_at', 'user_type']
|
'updated_at', 'user_type', 'country_name']
|
||||||
|
|
||||||
class EmailVerificationSerializer(serializers.ModelSerializer):
|
class EmailVerificationSerializer(serializers.ModelSerializer):
|
||||||
"""Email verification serializer"""
|
"""Email verification serializer"""
|
||||||
@ -201,3 +201,89 @@ class EmailVerificationSerializer(serializers.ModelSerializer):
|
|||||||
model = UserEmailOtp
|
model = UserEmailOtp
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultTaskImagesSerializer(serializers.ModelSerializer):
|
||||||
|
"""Update Password after verification"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = DefaultTaskImages
|
||||||
|
fields = ['task_name', 'image_url']
|
||||||
|
def create(self, validated_data):
|
||||||
|
data = DefaultTaskImages.objects.create(**validated_data)
|
||||||
|
return data
|
||||||
|
|
||||||
|
class DefaultTaskImagesDetailsSerializer(serializers.ModelSerializer):
|
||||||
|
"""Update Password after verification"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = DefaultTaskImages
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
class UserDeleteSerializer(serializers.ModelSerializer):
|
||||||
|
"""User Delete Serializer"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta Information"""
|
||||||
|
model = UserDelete
|
||||||
|
fields = ['reason']
|
||||||
|
def create(self, validated_data):
|
||||||
|
user = self.context['user']
|
||||||
|
user_type = str(self.context['user_type'])
|
||||||
|
data = validated_data.get('reason')
|
||||||
|
passwd = self.context['password']
|
||||||
|
random_num = random.randint(0,10000)
|
||||||
|
user_tb = User.objects.filter(id=user.id).last()
|
||||||
|
if user_tb and user_tb.check_password(passwd):
|
||||||
|
user_type_data = UserEmailOtp.objects.filter(email=user.email).last()
|
||||||
|
if user_type == '1' and user_type_data.user_type == '1':
|
||||||
|
junior_account_update(user_tb)
|
||||||
|
elif user_type == '2' and user_type_data.user_type == '2':
|
||||||
|
guardian_account_update(user_tb)
|
||||||
|
else:
|
||||||
|
raise serializers.ValidationError({"details":ERROR_CODE['2030'],"code":"400", "status":"failed"})
|
||||||
|
user_tb.email = str(random_num) + str('@D_') + '{}'.format(user_tb.username).lower()
|
||||||
|
user_tb.username = str(random_num) + str('@D_') + '{}'.format(user_tb.username).lower()
|
||||||
|
user_tb.password = 'None'
|
||||||
|
d_email = user_tb.email
|
||||||
|
o_mail = user.email
|
||||||
|
instance = UserDelete.objects.create(user=user_tb, d_email=d_email, old_email=o_mail,
|
||||||
|
is_active=True, reason=data)
|
||||||
|
user_tb.save()
|
||||||
|
|
||||||
|
return instance
|
||||||
|
else:
|
||||||
|
raise serializers.ValidationError({"details": ERROR_CODE['2031'], "code": "400", "status": "failed"})
|
||||||
|
|
||||||
|
|
||||||
|
class UserNotificationSerializer(serializers.ModelSerializer):
|
||||||
|
"""User Notification serializer"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = UserNotification
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateUserNotificationSerializer(serializers.ModelSerializer):
|
||||||
|
"""Update User Notification serializer"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = UserNotification
|
||||||
|
fields = ['push_notification', 'email_notification', 'sms_notification']
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
instance = UserNotification.objects.filter(user=self.context).last()
|
||||||
|
if instance:
|
||||||
|
instance.push_notification = validated_data.get('push_notification',instance.push_notification)
|
||||||
|
instance.email_notification = validated_data.get('email_notification', instance.email_notification)
|
||||||
|
instance.sms_notification = validated_data.get('sms_notification', instance.sms_notification)
|
||||||
|
instance.save()
|
||||||
|
else:
|
||||||
|
instance = UserNotification.objects.create(user=self.context)
|
||||||
|
return instance
|
||||||
|
|
||||||
|
class UserPhoneOtpSerializer(serializers.ModelSerializer):
|
||||||
|
"""User Phone serializers"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = UserPhoneOtp
|
||||||
|
fields = '__all__'
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
"""Test cases file of account"""
|
||||||
|
"""Django import"""
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
# Create your tests here.
|
# Create your tests here.
|
||||||
|
@ -1,26 +1,47 @@
|
|||||||
""" Urls files"""
|
""" Urls files"""
|
||||||
"""Django import"""
|
"""Django import"""
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.decorators import api_view
|
|
||||||
"""Third party import"""
|
"""Third party import"""
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
"""Import view functions"""
|
||||||
from .views import (UserLogin, SendPhoneOtp, UserPhoneVerification, UserEmailVerification, ReSendEmailOtp,
|
from .views import (UserLogin, SendPhoneOtp, UserPhoneVerification, UserEmailVerification, ReSendEmailOtp,
|
||||||
ForgotPasswordAPIView, ResetPasswordAPIView, ChangePasswordAPIView, UpdateProfileImage)
|
ForgotPasswordAPIView, ResetPasswordAPIView, ChangePasswordAPIView, UpdateProfileImage,
|
||||||
|
GoogleLoginViewSet, SigninWithApple, ProfileAPIViewSet, UploadImageAPIViewSet,
|
||||||
|
DefaultImageAPIViewSet, DeleteUserProfileAPIViewSet, UserNotificationAPIViewSet,
|
||||||
|
UpdateUserNotificationAPIViewSet)
|
||||||
"""Router"""
|
"""Router"""
|
||||||
router = routers.SimpleRouter()
|
router = routers.SimpleRouter()
|
||||||
|
|
||||||
"""API End points with router"""
|
"""API End points with router"""
|
||||||
router.register('user', UserLogin, basename='user')
|
router.register('user', UserLogin, basename='user')
|
||||||
|
"""super admin login"""
|
||||||
router.register('admin', UserLogin, basename='admin')
|
router.register('admin', UserLogin, basename='admin')
|
||||||
# router.register('google-login', GoogleLoginAPIViewset, basename='admin')
|
"""google login end point"""
|
||||||
|
router.register('google-login', GoogleLoginViewSet, basename='admin')
|
||||||
router.register('send-phone-otp', SendPhoneOtp, basename='send-phone-otp')
|
router.register('send-phone-otp', SendPhoneOtp, basename='send-phone-otp')
|
||||||
router.register('user-phone-verification', UserPhoneVerification, basename='user-phone-verification')
|
router.register('user-phone-verification', UserPhoneVerification, basename='user-phone-verification')
|
||||||
|
"""email verification end point"""
|
||||||
router.register('user-email-verification', UserEmailVerification, basename='user-email-verification')
|
router.register('user-email-verification', UserEmailVerification, basename='user-email-verification')
|
||||||
|
"""Resend email otp end point"""
|
||||||
router.register('resend-email-otp', ReSendEmailOtp, basename='resend-email-otp')
|
router.register('resend-email-otp', ReSendEmailOtp, basename='resend-email-otp')
|
||||||
|
"""Profile end point"""
|
||||||
|
router.register('profile', ProfileAPIViewSet, basename='profile')
|
||||||
|
"""Upload default task image end point"""
|
||||||
|
router.register('upload-default-task-image', UploadImageAPIViewSet, basename='upload-default-task-image')
|
||||||
|
"""Fetch default task image end point"""
|
||||||
|
router.register('default-task-image', DefaultImageAPIViewSet, basename='default-task-image')
|
||||||
|
"""Delete user account"""
|
||||||
|
router.register('delete', DeleteUserProfileAPIViewSet, basename='delete')
|
||||||
|
"""user account notification"""
|
||||||
|
router.register('user-notification', UserNotificationAPIViewSet, basename='user-notification')
|
||||||
|
"""update user account notification"""
|
||||||
|
router.register('update-user-notification', UpdateUserNotificationAPIViewSet, basename='update-user-notification')
|
||||||
|
"""Define url pattern"""
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('api/v1/', include(router.urls)),
|
path('api/v1/', include(router.urls)),
|
||||||
path('api/v1/forgot-password/', ForgotPasswordAPIView.as_view()),
|
path('api/v1/forgot-password/', ForgotPasswordAPIView.as_view()),
|
||||||
path('api/v1/reset-password/', ResetPasswordAPIView.as_view()),
|
path('api/v1/reset-password/', ResetPasswordAPIView.as_view()),
|
||||||
path('api/v1/change-password/', ChangePasswordAPIView.as_view()),
|
path('api/v1/change-password/', ChangePasswordAPIView.as_view()),
|
||||||
path('api/v1/update-profile-image/', UpdateProfileImage.as_view())
|
path('api/v1/update-profile-image/', UpdateProfileImage.as_view()),
|
||||||
|
path('api/v1/apple-login/', SigninWithApple.as_view(), name='signup_with_apple'),
|
||||||
]
|
]
|
||||||
|
@ -1,11 +1,39 @@
|
|||||||
"""Account utils"""
|
"""Account utils"""
|
||||||
"""Third party Django app"""
|
"""Import django"""
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from rest_framework import viewsets, status
|
from rest_framework import viewsets, status
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
"""Third party Django app"""
|
||||||
from templated_email import send_templated_mail
|
from templated_email import send_templated_mail
|
||||||
|
import jwt
|
||||||
|
from datetime import datetime
|
||||||
|
from calendar import timegm
|
||||||
|
from uuid import uuid4
|
||||||
|
import secrets
|
||||||
|
from junior.models import Junior
|
||||||
|
from guardian.models import Guardian
|
||||||
|
def junior_account_update(user_tb):
|
||||||
|
"""junior account delete"""
|
||||||
|
junior_data = Junior.objects.filter(auth__email=user_tb.email).first()
|
||||||
|
if junior_data:
|
||||||
|
junior_data.is_active = False
|
||||||
|
junior_data.is_verified = False
|
||||||
|
junior_data.guardian_code = '{}'
|
||||||
|
junior_data.save()
|
||||||
|
|
||||||
|
def guardian_account_update(user_tb):
|
||||||
|
"""update guardian account after delete the user account"""
|
||||||
|
guardian_data = Guardian.objects.filter(user__email=user_tb.email).first()
|
||||||
|
if guardian_data:
|
||||||
|
guardian_data.is_active = False
|
||||||
|
guardian_data.is_verified = False
|
||||||
|
guardian_data.save()
|
||||||
|
jun_data = Junior.objects.filter(guardian_code__icontains=str(guardian_data.guardian_code))
|
||||||
|
for data in jun_data:
|
||||||
|
data.guardian_code.remove(guardian_data.guardian_code)
|
||||||
|
data.save()
|
||||||
def send_otp_email(recipient_email, otp):
|
def send_otp_email(recipient_email, otp):
|
||||||
|
"""Send otp on email with template"""
|
||||||
from_email = settings.EMAIL_FROM_ADDRESS
|
from_email = settings.EMAIL_FROM_ADDRESS
|
||||||
recipient_list = [recipient_email]
|
recipient_list = [recipient_email]
|
||||||
send_templated_mail(
|
send_templated_mail(
|
||||||
@ -21,8 +49,8 @@ def send_otp_email(recipient_email, otp):
|
|||||||
def custom_response(detail, data=None, response_status=status.HTTP_200_OK):
|
def custom_response(detail, data=None, response_status=status.HTTP_200_OK):
|
||||||
"""Custom response code"""
|
"""Custom response code"""
|
||||||
if not data:
|
if not data:
|
||||||
|
"""when data is none"""
|
||||||
data = None
|
data = None
|
||||||
|
|
||||||
return Response({"data": data, "message": detail, "status": "success", "code": response_status})
|
return Response({"data": data, "message": detail, "status": "success", "code": response_status})
|
||||||
|
|
||||||
|
|
||||||
@ -34,5 +62,62 @@ def custom_error_response(detail, response_status):
|
|||||||
:return: Json response
|
:return: Json response
|
||||||
"""
|
"""
|
||||||
if not detail:
|
if not detail:
|
||||||
|
"""when details is empty"""
|
||||||
detail = {}
|
detail = {}
|
||||||
return Response({"error": detail, "status": "failed", "code": response_status})
|
return Response({"error": detail, "status": "failed", "code": response_status})
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_data(attrs):
|
||||||
|
"""
|
||||||
|
used to decode token
|
||||||
|
"""
|
||||||
|
user_data = jwt.decode(jwt=attrs['token'], options={'verify_signature': False},
|
||||||
|
algorithms=['RS256'])
|
||||||
|
return user_data
|
||||||
|
|
||||||
|
|
||||||
|
def generate_jwt_token(token_type: str, now_time: int, data: dict = dict):
|
||||||
|
"""
|
||||||
|
used to generate jwt token
|
||||||
|
"""
|
||||||
|
if type(data) == type:
|
||||||
|
data = {}
|
||||||
|
"""Update data dictionary"""
|
||||||
|
data.update({
|
||||||
|
'token_type': token_type,
|
||||||
|
'iss': 'your_site_url',
|
||||||
|
'iat': timegm(datetime.utcnow().utctimetuple()),
|
||||||
|
'jti': uuid4().hex
|
||||||
|
})
|
||||||
|
"""Access and Refresh token"""
|
||||||
|
TOKEN_TYPE = ["access", "refresh"]
|
||||||
|
if token_type == TOKEN_TYPE[1]:
|
||||||
|
"""Refresh token"""
|
||||||
|
exp = now_time + settings.SIMPLE_JWT['REFRESH_TOKEN_LIFETIME']
|
||||||
|
else:
|
||||||
|
"""access token"""
|
||||||
|
exp = now_time + settings.SIMPLE_JWT['ACCESS_TOKEN_LIFETIME']
|
||||||
|
|
||||||
|
data.update({
|
||||||
|
"exp": timegm(exp.utctimetuple())
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
signing_key = secrets.token_hex(32)
|
||||||
|
|
||||||
|
return jwt.encode(payload=data, key=signing_key,
|
||||||
|
algorithm='HS256')
|
||||||
|
|
||||||
|
|
||||||
|
def get_token(data: dict = dict):
|
||||||
|
""" create access and refresh token """
|
||||||
|
now_time = datetime.utcnow()
|
||||||
|
"""generate access token"""
|
||||||
|
access = generate_jwt_token('access', now_time, data)
|
||||||
|
"""generate refresh token"""
|
||||||
|
refresh = generate_jwt_token('refresh', now_time, data)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'access': access,
|
||||||
|
'refresh': refresh
|
||||||
|
}
|
||||||
|
285
account/views.py
285
account/views.py
@ -1,64 +1,170 @@
|
|||||||
|
"""Account view """
|
||||||
|
"""Django import"""
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from rest_framework import viewsets, status, views
|
from rest_framework import viewsets, status, views
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
import random
|
import random
|
||||||
import logging
|
import logging
|
||||||
|
from django.utils import timezone
|
||||||
|
import jwt
|
||||||
|
"""App Import"""
|
||||||
|
from guardian.utils import upload_image_to_alibaba
|
||||||
from django.contrib.auth import authenticate, login
|
from django.contrib.auth import authenticate, login
|
||||||
from guardian.models import Guardian
|
from guardian.models import Guardian
|
||||||
from junior.models import Junior
|
from junior.models import Junior
|
||||||
from account.models import UserProfile, UserPhoneOtp, UserEmailOtp
|
from account.models import UserProfile, UserPhoneOtp, UserEmailOtp, DefaultTaskImages, UserNotification
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
"""Account serializer"""
|
||||||
from .serializers import (SuperUserSerializer, GuardianSerializer, JuniorSerializer, EmailVerificationSerializer,
|
from .serializers import (SuperUserSerializer, GuardianSerializer, JuniorSerializer, EmailVerificationSerializer,
|
||||||
ForgotPasswordSerializer, ResetPasswordSerializer, ChangePasswordSerializer,
|
ForgotPasswordSerializer, ResetPasswordSerializer, ChangePasswordSerializer,
|
||||||
GoogleSignInSerializer, UpdateGuardianImageSerializer, UpdateJuniorProfileImageSerializer)
|
GoogleLoginSerializer, UpdateGuardianImageSerializer, UpdateJuniorProfileImageSerializer,
|
||||||
|
DefaultTaskImagesSerializer, DefaultTaskImagesDetailsSerializer, UserDeleteSerializer,
|
||||||
|
UserNotificationSerializer, UpdateUserNotificationSerializer, UserPhoneOtpSerializer)
|
||||||
from rest_framework_simplejwt.tokens import RefreshToken
|
from rest_framework_simplejwt.tokens import RefreshToken
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
from guardian.tasks import generate_otp
|
from guardian.tasks import generate_otp
|
||||||
from django.conf import settings
|
|
||||||
from account.utils import send_otp_email
|
from account.utils import send_otp_email
|
||||||
from account.utils import custom_response, custom_error_response
|
from account.utils import custom_response, custom_error_response
|
||||||
from django.core.mail import EmailMessage
|
|
||||||
from django.core.mail import send_mail
|
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from templated_email import send_templated_mail
|
from templated_email import send_templated_mail
|
||||||
|
import google.oauth2.credentials
|
||||||
|
import google.auth.transport.requests
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.response import Response
|
||||||
|
import requests
|
||||||
|
from django.conf import settings
|
||||||
|
from junior.serializers import JuniorProfileSerializer
|
||||||
|
from guardian.serializers import GuardianProfileSerializer
|
||||||
|
|
||||||
|
class GoogleLoginMixin:
|
||||||
|
"""google login mixin"""
|
||||||
|
def google_login(self, request):
|
||||||
|
"""google login function"""
|
||||||
|
access_token = request.data.get('access_token')
|
||||||
|
user_type = request.data.get('user_type')
|
||||||
|
if not access_token:
|
||||||
|
return Response({'error': 'Access token is required.'}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Validate the access token and obtain the user's email and name
|
||||||
|
credentials = google.oauth2.credentials.Credentials.from_authorized_user_info(
|
||||||
|
info={
|
||||||
|
'access_token': access_token,
|
||||||
|
'token_uri': 'https://oauth2.googleapis.com/token',
|
||||||
|
'client_id': settings.GOOGLE_CLIENT_ID,
|
||||||
|
'client_secret': settings.GOOGLE_CLIENT_SECRET,
|
||||||
|
'refresh_token': None,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
user_info_endpoint = f'https://www.googleapis.com/oauth2/v3/userinfo?access_token={access_token}'
|
||||||
|
headers = {'Authorization': f'Bearer {credentials.token}'}
|
||||||
|
response = requests.get(user_info_endpoint, headers=headers)
|
||||||
|
response.raise_for_status()
|
||||||
|
user_info = response.json()
|
||||||
|
email = user_info['email']
|
||||||
|
first_name = user_info['given_name']
|
||||||
|
last_name = user_info['family_name']
|
||||||
|
profile_picture = user_info['picture']
|
||||||
|
except Exception as e:
|
||||||
|
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
# Check if the user exists in your database or create a new user
|
||||||
|
# ...
|
||||||
|
user_data = User.objects.filter(email__iexact=email)
|
||||||
|
if user_data.exists():
|
||||||
|
if str(user_type) == '1':
|
||||||
|
junior_query = Junior.objects.filter(auth=user_data.last()).last()
|
||||||
|
serializer = JuniorSerializer(junior_query)
|
||||||
|
if str(user_type) == '2':
|
||||||
|
guardian_query = Guardian.objects.filter(user=user_data.last()).last()
|
||||||
|
serializer = GuardianSerializer(guardian_query)
|
||||||
|
return custom_response(SUCCESS_CODE['3003'], serializer.data,
|
||||||
|
response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
if not User.objects.filter(email__iexact=email).exists():
|
||||||
|
user_obj = User.objects.create(username=email, email=email, first_name=first_name, last_name=last_name)
|
||||||
|
if str(user_type) == '1':
|
||||||
|
junior_query = Junior.objects.create(auth=user_obj, is_verified=True, is_active=True,
|
||||||
|
image=profile_picture)
|
||||||
|
serializer = JuniorSerializer(junior_query)
|
||||||
|
if str(user_type) == '2':
|
||||||
|
guardian_query = Guardian.objects.create(user=user_obj, is_verified=True, is_active=True,
|
||||||
|
image=profile_picture)
|
||||||
|
serializer = GuardianSerializer(guardian_query)
|
||||||
|
# Return a JSON response with the user's email and name
|
||||||
|
return custom_response(SUCCESS_CODE['3003'], serializer.data,
|
||||||
|
response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class GoogleLoginViewSet(GoogleLoginMixin, viewsets.GenericViewSet):
|
||||||
|
serializer_class = GoogleLoginSerializer
|
||||||
|
|
||||||
|
def create(self, request):
|
||||||
|
serializer = self.get_serializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
return self.google_login(request)
|
||||||
|
|
||||||
|
class SigninWithApple(views.APIView):
|
||||||
|
"""This API is for sign in with Apple for app."""
|
||||||
|
def post(self, request):
|
||||||
|
token = request.data.get("access_token")
|
||||||
|
user_type = request.data.get("user_type")
|
||||||
|
try:
|
||||||
|
decoded_data = jwt.decode(token, options={"verify_signature": False})
|
||||||
|
user_data = {"email": decoded_data.get('email'), "username": decoded_data.get('email'), "is_active": True}
|
||||||
|
if decoded_data.get("email"):
|
||||||
|
try:
|
||||||
|
user = User.objects.get(email=decoded_data.get("email"))
|
||||||
|
if str(user_type) == '1':
|
||||||
|
junior_query = Junior.objects.filter(auth=user).last()
|
||||||
|
serializer = JuniorSerializer(junior_query)
|
||||||
|
if str(user_type) == '2':
|
||||||
|
guardian_query = Guardian.objects.filter(user=user).last()
|
||||||
|
serializer = GuardianSerializer(guardian_query)
|
||||||
|
return custom_response(SUCCESS_CODE['3003'], serializer.data,
|
||||||
|
response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
except User.DoesNotExist:
|
||||||
|
user = User.objects.create(**user_data)
|
||||||
|
if str(user_type) == '1':
|
||||||
|
junior_query = Junior.objects.create(auth=user, is_verified=True, is_active=True)
|
||||||
|
serializer = JuniorSerializer(junior_query)
|
||||||
|
if str(user_type) == '2':
|
||||||
|
guardian_query = Guardian.objects.create(user=user, is_verified=True, is_active=True)
|
||||||
|
serializer = GuardianSerializer(guardian_query)
|
||||||
|
return custom_response(SUCCESS_CODE['3003'], serializer.data,
|
||||||
|
response_status=status.HTTP_200_OK)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(e)
|
||||||
|
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# class GoogleLoginAPIViewset(viewsets.ModelViewSet):
|
|
||||||
# """Google Login"""
|
|
||||||
# serializer_class = GoogleSignInSerializer
|
|
||||||
#
|
|
||||||
# def create(self, request, *args, **kwargs):
|
|
||||||
# """
|
|
||||||
# Override default behaviour of create method
|
|
||||||
# """
|
|
||||||
# provider_type = []
|
|
||||||
# serializer = self.get_serializer(data=request.data)
|
|
||||||
# if serializer.is_valid(raise_exception=True):
|
|
||||||
# # provider = self.get_provider_view(request.data.get('provider'))
|
|
||||||
# # if User is not authenticated then send error message
|
|
||||||
# # if not provider.is_authenticated(request):
|
|
||||||
# # return custom_error_response({}, status.HTTP_400_BAD_REQUEST)
|
|
||||||
#
|
|
||||||
# user = serializer.save()
|
|
||||||
# if User.objects.filter(email__iexact=user.email).exists():
|
|
||||||
# print("ppppppppppppp")
|
|
||||||
# return custom_response(SUCCESS_CODE["3003"], response_status=status.HTTP_200_OK)
|
|
||||||
# return custom_response(ERROR_CODE["2002"], response_status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
class UpdateProfileImage(views.APIView):
|
class UpdateProfileImage(views.APIView):
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
def put(self, request, format=None):
|
def put(self, request, format=None):
|
||||||
if request.data['user_type'] == '1':
|
if str(request.data['user_type']) == '1':
|
||||||
junior_query = Junior.objects.filter(auth=request.user).last()
|
junior_query = Junior.objects.filter(auth=request.user).last()
|
||||||
serializer = UpdateJuniorProfileImageSerializer(junior_query, data=request.data, partial=True)
|
image = request.data['image']
|
||||||
else:
|
filename = f"images/{image.name}"
|
||||||
|
image_url = upload_image_to_alibaba(image, filename)
|
||||||
|
image_data = image_url
|
||||||
|
serializer = UpdateJuniorProfileImageSerializer(junior_query,
|
||||||
|
data={'image':image_data}, partial=True)
|
||||||
|
if str(request.data['user_type']) == '2':
|
||||||
guardian_query = Guardian.objects.filter(user=request.user).last()
|
guardian_query = Guardian.objects.filter(user=request.user).last()
|
||||||
serializer = UpdateGuardianImageSerializer(guardian_query, data=request.data, partial=True)
|
image = request.data['image']
|
||||||
|
filename = f"images/{image.name}"
|
||||||
|
image_url = upload_image_to_alibaba(image, filename)
|
||||||
|
image_data = image_url
|
||||||
|
serializer = UpdateGuardianImageSerializer(guardian_query,
|
||||||
|
data={'image':image_data}, partial=True)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return custom_response(SUCCESS_CODE['3017'], serializer.data, response_status=status.HTTP_200_OK)
|
return custom_response(SUCCESS_CODE['3017'], serializer.data, response_status=status.HTTP_200_OK)
|
||||||
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
class ChangePasswordAPIView(views.APIView):
|
class ChangePasswordAPIView(views.APIView):
|
||||||
|
serializer_class = ChangePasswordSerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
serializer = ChangePasswordSerializer(context=request.user, data=request.data)
|
serializer = ChangePasswordSerializer(context=request.user, data=request.data)
|
||||||
@ -96,9 +202,15 @@ class ForgotPasswordAPIView(views.APIView):
|
|||||||
'verification_code': verification_code
|
'verification_code': verification_code
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
expiry = timezone.now() + timezone.timedelta(days=1)
|
||||||
user_data, created = UserEmailOtp.objects.get_or_create(email=email)
|
user_data, created = UserEmailOtp.objects.get_or_create(email=email)
|
||||||
|
if created:
|
||||||
|
user_data.expired_at = expiry
|
||||||
|
user_data.save()
|
||||||
if user_data:
|
if user_data:
|
||||||
user_data.otp = verification_code
|
user_data.otp = verification_code
|
||||||
|
user_data.expired_at = expiry
|
||||||
user_data.save()
|
user_data.save()
|
||||||
return custom_response(SUCCESS_CODE['3015'],
|
return custom_response(SUCCESS_CODE['3015'],
|
||||||
response_status=status.HTTP_200_OK)
|
response_status=status.HTTP_200_OK)
|
||||||
@ -106,6 +218,8 @@ class ForgotPasswordAPIView(views.APIView):
|
|||||||
|
|
||||||
class SendPhoneOtp(viewsets.ModelViewSet):
|
class SendPhoneOtp(viewsets.ModelViewSet):
|
||||||
"""Send otp on phone"""
|
"""Send otp on phone"""
|
||||||
|
queryset = UserPhoneOtp.objects.all()
|
||||||
|
serializer_class = UserPhoneOtpSerializer
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
otp = generate_otp()
|
otp = generate_otp()
|
||||||
phone_number = self.request.data['phone']
|
phone_number = self.request.data['phone']
|
||||||
@ -121,6 +235,8 @@ class SendPhoneOtp(viewsets.ModelViewSet):
|
|||||||
|
|
||||||
class UserPhoneVerification(viewsets.ModelViewSet):
|
class UserPhoneVerification(viewsets.ModelViewSet):
|
||||||
"""Send otp on phone"""
|
"""Send otp on phone"""
|
||||||
|
queryset = UserPhoneOtp.objects.all()
|
||||||
|
serializer_class = UserPhoneOtpSerializer
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
phone_data = UserPhoneOtp.objects.filter(phone=self.request.GET.get('phone'),
|
phone_data = UserPhoneOtp.objects.filter(phone=self.request.GET.get('phone'),
|
||||||
@ -199,6 +315,7 @@ class UserLogin(viewsets.ViewSet):
|
|||||||
class UserEmailVerification(viewsets.ModelViewSet):
|
class UserEmailVerification(viewsets.ModelViewSet):
|
||||||
"""User Email verification"""
|
"""User Email verification"""
|
||||||
serializer_class = EmailVerificationSerializer
|
serializer_class = EmailVerificationSerializer
|
||||||
|
queryset = UserEmailOtp.objects.all()
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
@ -206,6 +323,15 @@ class UserEmailVerification(viewsets.ModelViewSet):
|
|||||||
email_data = UserEmailOtp.objects.filter(email=self.request.GET.get('email'),
|
email_data = UserEmailOtp.objects.filter(email=self.request.GET.get('email'),
|
||||||
otp=self.request.GET.get('otp')).last()
|
otp=self.request.GET.get('otp')).last()
|
||||||
if email_data:
|
if email_data:
|
||||||
|
input_datetime_str = str(email_data.expired_at)
|
||||||
|
input_format = "%Y-%m-%d %H:%M:%S.%f%z"
|
||||||
|
output_format = "%Y-%m-%d %H:%M:%S.%f"
|
||||||
|
input_datetime = datetime.strptime(input_datetime_str, input_format)
|
||||||
|
output_datetime_str = input_datetime.strftime(output_format)
|
||||||
|
format_str = "%Y-%m-%d %H:%M:%S.%f"
|
||||||
|
datetime_obj = datetime.strptime(output_datetime_str, format_str)
|
||||||
|
if datetime.today() > datetime_obj:
|
||||||
|
return custom_error_response(ERROR_CODE["2029"], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
email_data.is_verified = True
|
email_data.is_verified = True
|
||||||
email_data.save()
|
email_data.save()
|
||||||
if email_data.user_type == '1':
|
if email_data.user_type == '1':
|
||||||
@ -220,7 +346,8 @@ class UserEmailVerification(viewsets.ModelViewSet):
|
|||||||
guardian_data.save()
|
guardian_data.save()
|
||||||
refresh = RefreshToken.for_user(user_obj)
|
refresh = RefreshToken.for_user(user_obj)
|
||||||
access_token = str(refresh.access_token)
|
access_token = str(refresh.access_token)
|
||||||
return custom_response(SUCCESS_CODE['3011'], {"auth_token":access_token}, response_status=status.HTTP_200_OK)
|
return custom_response(SUCCESS_CODE['3011'], {"auth_token":access_token},
|
||||||
|
response_status=status.HTTP_200_OK)
|
||||||
else:
|
else:
|
||||||
return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -229,14 +356,108 @@ class UserEmailVerification(viewsets.ModelViewSet):
|
|||||||
|
|
||||||
class ReSendEmailOtp(viewsets.ModelViewSet):
|
class ReSendEmailOtp(viewsets.ModelViewSet):
|
||||||
"""Send otp on phone"""
|
"""Send otp on phone"""
|
||||||
|
queryset = UserEmailOtp.objects.all()
|
||||||
|
serializer_class = EmailVerificationSerializer
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
otp = generate_otp()
|
otp = generate_otp()
|
||||||
if User.objects.filter(email=request.data['email']):
|
if User.objects.filter(email=request.data['email']):
|
||||||
|
expiry = timezone.now() + timezone.timedelta(days=1)
|
||||||
email_data, created = UserEmailOtp.objects.get_or_create(email=request.data['email'])
|
email_data, created = UserEmailOtp.objects.get_or_create(email=request.data['email'])
|
||||||
|
if created:
|
||||||
|
email_data.expired_at = expiry
|
||||||
|
email_data.save()
|
||||||
if email_data:
|
if email_data:
|
||||||
email_data.otp = otp
|
email_data.otp = otp
|
||||||
|
email_data.expired_at = expiry
|
||||||
email_data.save()
|
email_data.save()
|
||||||
send_otp_email(request.data['email'], otp)
|
send_otp_email(request.data['email'], otp)
|
||||||
return custom_response(SUCCESS_CODE['3016'], response_status=status.HTTP_200_OK)
|
return custom_response(SUCCESS_CODE['3016'], response_status=status.HTTP_200_OK)
|
||||||
else:
|
else:
|
||||||
return custom_error_response(ERROR_CODE["2023"], response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(ERROR_CODE["2023"], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
class ProfileAPIViewSet(viewsets.ModelViewSet):
|
||||||
|
"""Profile viewset"""
|
||||||
|
queryset = User.objects.all()
|
||||||
|
serializer_class = JuniorProfileSerializer
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
"""profile view"""
|
||||||
|
if str(self.request.GET.get('user_type')) == '1':
|
||||||
|
junior_data = Junior.objects.filter(auth=self.request.user).last()
|
||||||
|
if junior_data:
|
||||||
|
serializer = JuniorProfileSerializer(junior_data)
|
||||||
|
if str(self.request.GET.get('user_type')) == '2':
|
||||||
|
guardian_data = Guardian.objects.filter(user=self.request.user).last()
|
||||||
|
if guardian_data:
|
||||||
|
serializer = GuardianProfileSerializer(guardian_data)
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class UploadImageAPIViewSet(viewsets.ModelViewSet):
|
||||||
|
"""Profile viewset"""
|
||||||
|
queryset = DefaultTaskImages.objects.all()
|
||||||
|
serializer_class = DefaultTaskImagesSerializer
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
"""profile view"""
|
||||||
|
image_data = request.data['image_url']
|
||||||
|
filename = f"default_task_images/{image_data.name}"
|
||||||
|
image = upload_image_to_alibaba(image_data, filename)
|
||||||
|
image_data = image
|
||||||
|
request.data['image_url'] = image_data
|
||||||
|
serializer = DefaultTaskImagesSerializer(data=request.data)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
return custom_error_response(serializer.error, response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
class DefaultImageAPIViewSet(viewsets.ModelViewSet):
|
||||||
|
"""Profile viewset"""
|
||||||
|
queryset = DefaultTaskImages.objects.all()
|
||||||
|
serializer_class = DefaultTaskImagesDetailsSerializer
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
"""profile view"""
|
||||||
|
queryset = DefaultTaskImages.objects.all()
|
||||||
|
serializer = DefaultTaskImagesSerializer(queryset, many=True)
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteUserProfileAPIViewSet(viewsets.GenericViewSet):
|
||||||
|
""" Delete user API view set """
|
||||||
|
|
||||||
|
@action(detail=False, methods=['POST'], url_path='user-account',serializer_class=UserDeleteSerializer,
|
||||||
|
permission_classes=[IsAuthenticated])
|
||||||
|
def account(self, request):
|
||||||
|
user_type = str(request.data['user_type'])
|
||||||
|
password = request.data['password']
|
||||||
|
serializer = self.get_serializer(data=request.data, context={'request': request, 'user': request.user,
|
||||||
|
'user_type':user_type,
|
||||||
|
'password':password})
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return custom_response(SUCCESS_CODE['3005'], response_status=status.HTTP_200_OK)
|
||||||
|
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
|
class UserNotificationAPIViewSet(viewsets.ModelViewSet):
|
||||||
|
"""notification viewset"""
|
||||||
|
queryset = UserNotification.objects.all()
|
||||||
|
serializer_class = UserNotificationSerializer
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
"""profile view"""
|
||||||
|
queryset = self.queryset.filter(user=request.user)
|
||||||
|
serializer = UserNotificationSerializer(queryset, many=True)
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateUserNotificationAPIViewSet(viewsets.ModelViewSet):
|
||||||
|
"""Update notification viewset"""
|
||||||
|
queryset = UserNotification.objects.all()
|
||||||
|
serializer_class = UpdateUserNotificationSerializer
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
"""profile view"""
|
||||||
|
serializer = UpdateUserNotificationSerializer(data=request.data,
|
||||||
|
context=request.user)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
return custom_error_response(serializer.error, response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
@ -35,6 +35,20 @@ GENDERS = (
|
|||||||
('1', 'Male'),
|
('1', 'Male'),
|
||||||
('2', 'Female')
|
('2', 'Female')
|
||||||
)
|
)
|
||||||
|
TASK_STATUS = (
|
||||||
|
('1', 'pending'),
|
||||||
|
('2', 'in-progress'),
|
||||||
|
('3', 'rejected'),
|
||||||
|
('4', 'requested'),
|
||||||
|
('5', 'completed')
|
||||||
|
)
|
||||||
|
|
||||||
|
PENDING = 1
|
||||||
|
IN_PROGRESS = 2
|
||||||
|
REJECTED = 3
|
||||||
|
REQUESTED = 4
|
||||||
|
COMPLETED = 5
|
||||||
|
TASK_POINTS = 5
|
||||||
# duplicate name used defined in constant PROJECT_NAME
|
# duplicate name used defined in constant PROJECT_NAME
|
||||||
PROJECT_NAME = 'Zod Bank'
|
PROJECT_NAME = 'Zod Bank'
|
||||||
GUARDIAN = 'guardian'
|
GUARDIAN = 'guardian'
|
||||||
|
@ -45,11 +45,16 @@ ERROR_CODE = {
|
|||||||
"2019": "Either File extension or File size doesn't meet the requirements",
|
"2019": "Either File extension or File size doesn't meet the requirements",
|
||||||
"2020": "Enter valid mobile number",
|
"2020": "Enter valid mobile number",
|
||||||
"2021": "Already register",
|
"2021": "Already register",
|
||||||
"2022":"Invalid Guardian code",
|
"2022": "Invalid Guardian code",
|
||||||
"2023":"Invalid user",
|
"2023": "Invalid user",
|
||||||
"2024":"Email not verified",
|
"2024": "Email not verified",
|
||||||
"2025":"Invalid input. Expected a list of strings.",
|
"2025": "Invalid input. Expected a list of strings.",
|
||||||
"2026" : "New password should not same as old password"
|
"2026": "New password should not same as old password",
|
||||||
|
"2027": "data should contain `identityToken`",
|
||||||
|
"2028": "You are not authorized person to sign up on this platform",
|
||||||
|
"2029": "Validity of otp verification is expired",
|
||||||
|
"2030": "Use correct user type and token",
|
||||||
|
"2031":"Invalid password"
|
||||||
}
|
}
|
||||||
SUCCESS_CODE = {
|
SUCCESS_CODE = {
|
||||||
# Success code for password
|
# Success code for password
|
||||||
@ -61,7 +66,7 @@ SUCCESS_CODE = {
|
|||||||
# Success code for password reset
|
# Success code for password reset
|
||||||
"3004": "Password reset link has been sent to your email address",
|
"3004": "Password reset link has been sent to your email address",
|
||||||
# Success code for link verified
|
# Success code for link verified
|
||||||
"3005": "Your link has been verified, it's valid",
|
"3005": "Your account is deleted successfully.",
|
||||||
# Success code for password reset
|
# Success code for password reset
|
||||||
"3006": "Your password has been reset successfully.",
|
"3006": "Your password has been reset successfully.",
|
||||||
# Success code for password update
|
# Success code for password update
|
||||||
@ -78,7 +83,8 @@ SUCCESS_CODE = {
|
|||||||
"3014": "Password has been updated successfully.",
|
"3014": "Password has been updated successfully.",
|
||||||
"3015": "Verification code sent on your email.",
|
"3015": "Verification code sent on your email.",
|
||||||
"3016": "Send otp on your Email successfully",
|
"3016": "Send otp on your Email successfully",
|
||||||
"3017": "Profile image update successfully"
|
"3017": "Profile image update successfully",
|
||||||
|
"3018": "Task created successfully"
|
||||||
}
|
}
|
||||||
|
|
||||||
STATUS_CODE_ERROR = {
|
STATUS_CODE_ERROR = {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"""Third party Django app"""
|
"""Third party Django app"""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
"""Import Django app"""
|
"""Import Django app"""
|
||||||
from .models import Guardian
|
from .models import Guardian, JuniorTask
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
@admin.register(Guardian)
|
@admin.register(Guardian)
|
||||||
class GuardianAdmin(admin.ModelAdmin):
|
class GuardianAdmin(admin.ModelAdmin):
|
||||||
@ -12,3 +12,12 @@ class GuardianAdmin(admin.ModelAdmin):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Return email id"""
|
"""Return email id"""
|
||||||
return self.user__email
|
return self.user__email
|
||||||
|
|
||||||
|
@admin.register(JuniorTask)
|
||||||
|
class TaskAdmin(admin.ModelAdmin):
|
||||||
|
"""Junior Admin"""
|
||||||
|
list_display = ['id', 'task_name', 'task_status', 'junior', 'due_date', 'points', 'created_at', 'updated_at']
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return email id"""
|
||||||
|
return str(self.task_name) + str(self.points)
|
||||||
|
36
guardian/migrations/0008_juniortask.py
Normal file
36
guardian/migrations/0008_juniortask.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-04 09:24
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0006_alter_junior_country_name'),
|
||||||
|
('guardian', '0007_alter_guardian_country_name'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='JuniorTask',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('task_name', models.CharField(max_length=100)),
|
||||||
|
('task_description', models.CharField(max_length=500)),
|
||||||
|
('points', models.IntegerField(default=5)),
|
||||||
|
('due_date', models.DateField(blank=True, null=True)),
|
||||||
|
('image', models.ImageField(blank=True, default=None, null=True, upload_to='')),
|
||||||
|
('task_status', models.CharField(blank=True, choices=[('1', 'pending'), ('2', 'in-progress'), ('3', 'rejected'), ('4', 'requested'), ('5', 'completed')], default='pending', max_length=15, null=True)),
|
||||||
|
('is_active', models.BooleanField(default=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('guardian', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='guardian', to='guardian.guardian', verbose_name='Guardian')),
|
||||||
|
('junior', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='junior', to='junior.junior', verbose_name='Junior')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Junior Task',
|
||||||
|
'db_table': 'junior_task',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
18
guardian/migrations/0009_alter_juniortask_image.py
Normal file
18
guardian/migrations/0009_alter_juniortask_image.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-04 12:56
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0008_juniortask'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='juniortask',
|
||||||
|
name='image',
|
||||||
|
field=models.URLField(blank=True, default=None, null=True),
|
||||||
|
),
|
||||||
|
]
|
18
guardian/migrations/0010_alter_juniortask_task_status.py
Normal file
18
guardian/migrations/0010_alter_juniortask_task_status.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-04 13:41
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0009_alter_juniortask_image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='juniortask',
|
||||||
|
name='task_status',
|
||||||
|
field=models.CharField(choices=[('1', 'pending'), ('2', 'in-progress'), ('3', 'rejected'), ('4', 'requested'), ('5', 'completed')], default='pending', max_length=15),
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,28 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-05 11:17
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0010_alter_juniortask_task_status'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='juniortask',
|
||||||
|
name='default_image',
|
||||||
|
field=models.ImageField(blank=True, default=None, null=True, upload_to=''),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='juniortask',
|
||||||
|
name='is_approved',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='juniortask',
|
||||||
|
name='task_status',
|
||||||
|
field=models.CharField(choices=[('1', 'pending'), ('2', 'in-progress'), ('3', 'rejected'), ('4', 'requested'), ('5', 'completed')], default=1, max_length=15),
|
||||||
|
),
|
||||||
|
]
|
18
guardian/migrations/0012_alter_juniortask_default_image.py
Normal file
18
guardian/migrations/0012_alter_juniortask_default_image.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-06 05:12
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0011_juniortask_default_image_juniortask_is_approved_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='juniortask',
|
||||||
|
name='default_image',
|
||||||
|
field=models.URLField(blank=True, default=None, null=True),
|
||||||
|
),
|
||||||
|
]
|
18
guardian/migrations/0013_alter_guardian_image.py
Normal file
18
guardian/migrations/0013_alter_guardian_image.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-06 06:40
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0012_alter_juniortask_default_image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='guardian',
|
||||||
|
name='image',
|
||||||
|
field=models.URLField(blank=True, default=None, null=True),
|
||||||
|
),
|
||||||
|
]
|
@ -3,7 +3,9 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
"""Import Django app"""
|
"""Import Django app"""
|
||||||
from base.constants import GENDERS
|
from base.constants import GENDERS, TASK_STATUS, PENDING, TASK_POINTS
|
||||||
|
from junior.models import Junior
|
||||||
|
"""Add user model"""
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
||||||
@ -15,7 +17,7 @@ class Guardian(models.Model):
|
|||||||
phone = models.CharField(max_length=31, null=True, blank=True, default=None)
|
phone = models.CharField(max_length=31, null=True, blank=True, default=None)
|
||||||
country_name = models.CharField(max_length=100, null=True, blank=True, default=None)
|
country_name = models.CharField(max_length=100, null=True, blank=True, default=None)
|
||||||
"""Image info"""
|
"""Image info"""
|
||||||
image = models.ImageField(null=True, blank=True, default=None)
|
image = models.URLField(null=True, blank=True, default=None)
|
||||||
"""Personal info"""
|
"""Personal info"""
|
||||||
family_name = models.CharField(max_length=50, null=True, blank=True, default=None)
|
family_name = models.CharField(max_length=50, null=True, blank=True, default=None)
|
||||||
gender = models.CharField(choices=GENDERS, max_length=15, null=True, blank=True, default=None)
|
gender = models.CharField(choices=GENDERS, max_length=15, null=True, blank=True, default=None)
|
||||||
@ -41,3 +43,37 @@ class Guardian(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Return email id"""
|
"""Return email id"""
|
||||||
return f'{self.user}'
|
return f'{self.user}'
|
||||||
|
|
||||||
|
class JuniorTask(models.Model):
|
||||||
|
"""Junior Task details model"""
|
||||||
|
guardian = models.ForeignKey(Guardian, on_delete=models.CASCADE, related_name='guardian', verbose_name='Guardian')
|
||||||
|
"""task details"""
|
||||||
|
task_name = models.CharField(max_length=100)
|
||||||
|
task_description = models.CharField(max_length=500)
|
||||||
|
"""points of the task"""
|
||||||
|
points = models.IntegerField(default=TASK_POINTS)
|
||||||
|
due_date = models.DateField(auto_now_add=False, null=True, blank=True)
|
||||||
|
"""Images of task"""
|
||||||
|
default_image = models.URLField(null=True, blank=True, default=None)
|
||||||
|
image = models.URLField(null=True, blank=True, default=None)
|
||||||
|
"""associated junior with the task"""
|
||||||
|
junior = models.ForeignKey(Junior, on_delete=models.CASCADE, related_name='junior', verbose_name='Junior')
|
||||||
|
"""task status"""
|
||||||
|
task_status = models.CharField(choices=TASK_STATUS, max_length=15, default=PENDING)
|
||||||
|
"""task stage"""
|
||||||
|
is_active = models.BooleanField(default=True)
|
||||||
|
is_approved = models.BooleanField(default=False)
|
||||||
|
"""Profile created and updated time"""
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
""" Meta class """
|
||||||
|
db_table = 'junior_task'
|
||||||
|
verbose_name = 'Junior Task'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return email id"""
|
||||||
|
return f'{self.task_name}'
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,11 +7,13 @@ from rest_framework_simplejwt.tokens import RefreshToken
|
|||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
"""Import Django app"""
|
"""Import Django app"""
|
||||||
from .models import Guardian
|
from .models import Guardian, JuniorTask
|
||||||
from account.models import UserProfile, UserEmailOtp
|
from account.models import UserProfile, UserEmailOtp, UserNotification
|
||||||
|
from account.serializers import JuniorSerializer
|
||||||
|
from junior.serializers import JuniorDetailSerializer
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
from .utils import upload_image_to_alibaba
|
from .utils import upload_image_to_alibaba
|
||||||
from junior.models import Junior
|
from junior.models import Junior, JuniorPoints
|
||||||
class UserSerializer(serializers.ModelSerializer):
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
"""User serializer"""
|
"""User serializer"""
|
||||||
auth_token = serializers.SerializerMethodField('get_auth_token')
|
auth_token = serializers.SerializerMethodField('get_auth_token')
|
||||||
@ -34,11 +36,13 @@ class UserSerializer(serializers.ModelSerializer):
|
|||||||
try:
|
try:
|
||||||
"""Create user profile"""
|
"""Create user profile"""
|
||||||
user = User.objects.create_user(username=email, email=email, password=password)
|
user = User.objects.create_user(username=email, email=email, password=password)
|
||||||
UserProfile.objects.create(user=user, user_type=user_type)
|
UserNotification.objects.create(user=user)
|
||||||
if user_type == '1':
|
if user_type == '1':
|
||||||
Junior.objects.create(auth=user)
|
Junior.objects.create(auth=user, junior_code=''.join([str(random.randrange(9)) for _ in range(6)]),
|
||||||
|
referral_code=''.join([str(random.randrange(9)) for _ in range(6)]))
|
||||||
if user_type == '2':
|
if user_type == '2':
|
||||||
Guardian.objects.create(user=user)
|
Guardian.objects.create(user=user, guardian_code=''.join([str(random.randrange(9)) for _ in range(6)]),
|
||||||
|
referral_code=''.join([str(random.randrange(9)) for _ in range(6)]))
|
||||||
return user
|
return user
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
"""Error handling"""
|
"""Error handling"""
|
||||||
@ -63,7 +67,7 @@ class CreateGuardianSerializer(serializers.ModelSerializer):
|
|||||||
family_name = serializers.CharField(max_length=100, required=False)
|
family_name = serializers.CharField(max_length=100, required=False)
|
||||||
dob = serializers.DateField(required=False)
|
dob = serializers.DateField(required=False)
|
||||||
referral_code = serializers.CharField(max_length=100, required=False)
|
referral_code = serializers.CharField(max_length=100, required=False)
|
||||||
image = serializers.ImageField(required=False)
|
image = serializers.URLField(required=False)
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
@ -86,18 +90,14 @@ class CreateGuardianSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
"""Create guardian profile"""
|
"""Create guardian profile"""
|
||||||
# phone_number = validated_data.get('phone', None)
|
|
||||||
# guardian_data = Guardian.objects.filter(phone=phone_number)
|
|
||||||
# junior_data = Junior.objects.filter(phone=phone_number)
|
|
||||||
# if phone_number and (guardian_data or junior_data):
|
|
||||||
# raise serializers.ValidationError({"details": ERROR_CODE['2012']})
|
|
||||||
user = User.objects.filter(username=self.context['user']).last()
|
user = User.objects.filter(username=self.context['user']).last()
|
||||||
if user:
|
if user:
|
||||||
"""Save first and last name of guardian"""
|
"""Save first and last name of guardian"""
|
||||||
if self.context.get('first_name') != '' and self.context.get('last_name') != '':
|
if self.context.get('first_name') != '' and self.context.get('first_name') is not None:
|
||||||
user.first_name = self.context.get('first_name', user.first_name)
|
user.first_name = self.context.get('first_name')
|
||||||
user.last_name = self.context.get('last_name', user.last_name)
|
if self.context.get('last_name') != '' and self.context.get('last_name') is not None:
|
||||||
user.save()
|
user.last_name = self.context.get('last_name')
|
||||||
|
user.save()
|
||||||
"""Create guardian data"""
|
"""Create guardian data"""
|
||||||
guardian, created = Guardian.objects.get_or_create(user=self.context['user'])
|
guardian, created = Guardian.objects.get_or_create(user=self.context['user'])
|
||||||
if created:
|
if created:
|
||||||
@ -115,17 +115,14 @@ class CreateGuardianSerializer(serializers.ModelSerializer):
|
|||||||
guardian.passcode = validated_data.get('passcode', guardian.passcode)
|
guardian.passcode = validated_data.get('passcode', guardian.passcode)
|
||||||
guardian.country_name = validated_data.get('country_name', guardian.country_name)
|
guardian.country_name = validated_data.get('country_name', guardian.country_name)
|
||||||
guardian.referral_code_used = validated_data.get('referral_code_used', guardian.referral_code_used)
|
guardian.referral_code_used = validated_data.get('referral_code_used', guardian.referral_code_used)
|
||||||
|
guardian.image = validated_data.get('image', guardian.image)
|
||||||
"""Complete profile of the junior if below all data are filled"""
|
"""Complete profile of the junior if below all data are filled"""
|
||||||
complete_profile_field = all([guardian.phone, guardian.gender, guardian.family_name, guardian.country_name,
|
complete_profile_field = all([guardian.phone, guardian.gender, guardian.country_name,
|
||||||
guardian.dob, guardian.country_code, user.first_name, user.last_name])
|
guardian.dob, guardian.country_code, user.first_name, user.last_name,
|
||||||
|
user.email, guardian.image])
|
||||||
guardian.is_complete_profile = False
|
guardian.is_complete_profile = False
|
||||||
if complete_profile_field:
|
if complete_profile_field:
|
||||||
guardian.is_complete_profile = True
|
guardian.is_complete_profile = True
|
||||||
image = validated_data.pop('image', None)
|
|
||||||
if image:
|
|
||||||
filename = f"images/{image.name}"
|
|
||||||
image_url = upload_image_to_alibaba(image, filename)
|
|
||||||
guardian.image = image_url
|
|
||||||
guardian.save()
|
guardian.save()
|
||||||
return guardian
|
return guardian
|
||||||
|
|
||||||
@ -134,3 +131,115 @@ class CreateGuardianSerializer(serializers.ModelSerializer):
|
|||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
instance = super().save(**kwargs)
|
instance = super().save(**kwargs)
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TaskSerializer(serializers.ModelSerializer):
|
||||||
|
"""Task serializer"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = JuniorTask
|
||||||
|
fields = ['task_name','task_description','points', 'due_date', 'junior', 'default_image']
|
||||||
|
def create(self, validated_data):
|
||||||
|
"""create default task image data"""
|
||||||
|
validated_data['guardian'] = Guardian.objects.filter(user=self.context['user']).last()
|
||||||
|
images = self.context['image']
|
||||||
|
validated_data['default_image'] = images
|
||||||
|
instance = JuniorTask.objects.create(**validated_data)
|
||||||
|
return instance
|
||||||
|
|
||||||
|
class GuardianDetailSerializer(serializers.ModelSerializer):
|
||||||
|
"""junior serializer"""
|
||||||
|
|
||||||
|
email = serializers.SerializerMethodField('get_auth')
|
||||||
|
first_name = serializers.SerializerMethodField('get_first_name')
|
||||||
|
last_name = serializers.SerializerMethodField('get_last_name')
|
||||||
|
|
||||||
|
def get_auth(self, obj):
|
||||||
|
"""user email address"""
|
||||||
|
return obj.user.username
|
||||||
|
|
||||||
|
def get_first_name(self, obj):
|
||||||
|
"""user first name"""
|
||||||
|
return obj.user.first_name
|
||||||
|
|
||||||
|
def get_last_name(self, obj):
|
||||||
|
"""user last name"""
|
||||||
|
return obj.user.last_name
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = Guardian
|
||||||
|
fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob',
|
||||||
|
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image',
|
||||||
|
'updated_at']
|
||||||
|
class TaskDetailsSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
junior = JuniorDetailSerializer()
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = JuniorTask
|
||||||
|
fields = ['id', 'guardian', 'task_name', 'task_description', 'points', 'due_date','default_image', 'image',
|
||||||
|
'junior', 'task_status', 'is_active', 'created_at','updated_at']
|
||||||
|
|
||||||
|
|
||||||
|
class TopJuniorSerializer(serializers.ModelSerializer):
|
||||||
|
"""Top junior serializer"""
|
||||||
|
junior = JuniorDetailSerializer()
|
||||||
|
position = serializers.IntegerField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta info"""
|
||||||
|
model = JuniorPoints
|
||||||
|
fields = ['id', 'junior', 'total_task_points', 'position', 'created_at', 'updated_at']
|
||||||
|
|
||||||
|
def to_representation(self, instance):
|
||||||
|
"""Convert instance to representation"""
|
||||||
|
representation = super().to_representation(instance)
|
||||||
|
representation['position'] = instance.position
|
||||||
|
return representation
|
||||||
|
|
||||||
|
|
||||||
|
class GuardianProfileSerializer(serializers.ModelSerializer):
|
||||||
|
"""junior serializer"""
|
||||||
|
|
||||||
|
email = serializers.SerializerMethodField('get_auth')
|
||||||
|
first_name = serializers.SerializerMethodField('get_first_name')
|
||||||
|
last_name = serializers.SerializerMethodField('get_last_name')
|
||||||
|
total_count = serializers.SerializerMethodField('get_total_count')
|
||||||
|
complete_field_count = serializers.SerializerMethodField('get_complete_field_count')
|
||||||
|
notification_count = serializers.SerializerMethodField('get_notification_count')
|
||||||
|
|
||||||
|
def get_auth(self, obj):
|
||||||
|
"""user email address"""
|
||||||
|
return obj.user.username
|
||||||
|
|
||||||
|
def get_first_name(self, obj):
|
||||||
|
"""user first name"""
|
||||||
|
return obj.user.first_name
|
||||||
|
|
||||||
|
def get_last_name(self, obj):
|
||||||
|
"""user last name"""
|
||||||
|
return obj.user.last_name
|
||||||
|
|
||||||
|
def get_total_count(self, obj):
|
||||||
|
"""total fields count"""
|
||||||
|
return 9
|
||||||
|
|
||||||
|
def get_complete_field_count(self, obj):
|
||||||
|
"""total filled fields count"""
|
||||||
|
total_field_list = [obj.user.first_name, obj.user.last_name, obj.user.email, obj.country_name, obj.country_code,
|
||||||
|
obj.phone, obj.gender, obj.dob, obj.image]
|
||||||
|
total_complete_field = [data for data in total_field_list if data != '' and data is not None]
|
||||||
|
return len(total_complete_field)
|
||||||
|
|
||||||
|
def get_notification_count(self, obj):
|
||||||
|
"""total notification count"""
|
||||||
|
return 0
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = Guardian
|
||||||
|
fields = ['id', 'email', 'first_name', 'last_name', 'country_name','country_code', 'phone', 'gender', 'dob',
|
||||||
|
'guardian_code', 'notification_count', 'total_count', 'complete_field_count', 'referral_code',
|
||||||
|
'is_active', 'is_complete_profile', 'created_at', 'image',
|
||||||
|
'updated_at']
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
""" Urls files"""
|
""" Urls files"""
|
||||||
"""Django import"""
|
"""Django import"""
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from .views import SignupViewset, UpdateGuardianProfile
|
from .views import (SignupViewset, UpdateGuardianProfile, AllTaskListAPIView, CreateTaskAPIView, TaskListAPIView,
|
||||||
|
SearchTaskListAPIView, TopJuniorListAPIView)
|
||||||
"""Third party import"""
|
"""Third party import"""
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
@ -13,6 +14,16 @@ router = routers.SimpleRouter()
|
|||||||
router.register('sign-up', SignupViewset, basename='sign-up')
|
router.register('sign-up', SignupViewset, basename='sign-up')
|
||||||
"""Create guardian profile API"""
|
"""Create guardian profile API"""
|
||||||
router.register('create-guardian-profile', UpdateGuardianProfile, basename='update-guardian-profile')
|
router.register('create-guardian-profile', UpdateGuardianProfile, basename='update-guardian-profile')
|
||||||
|
"""Create Task API"""
|
||||||
|
router.register('create-task', CreateTaskAPIView, basename='create-task')
|
||||||
|
"""All Task list API"""
|
||||||
|
router.register('all-task-list', AllTaskListAPIView, basename='all-task-list')
|
||||||
|
"""Task list bases on the status API"""
|
||||||
|
router.register('task-list', TaskListAPIView, basename='task-list')
|
||||||
|
"""Leaderboard API"""
|
||||||
|
router.register('top-junior', TopJuniorListAPIView, basename='top-junior')
|
||||||
|
"""Search Task list on the bases of status, due date, and task title API"""
|
||||||
|
router.register('filter-task', SearchTaskListAPIView, basename='filter-task')
|
||||||
"""Define Url pattern"""
|
"""Define Url pattern"""
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('api/v1/', include(router.urls)),
|
path('api/v1/', include(router.urls)),
|
||||||
|
@ -1,13 +1,22 @@
|
|||||||
|
"""Utiles file of guardian"""
|
||||||
|
"""Django import"""
|
||||||
import oss2
|
import oss2
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
def upload_image_to_alibaba(image, filename):
|
def upload_image_to_alibaba(image, filename):
|
||||||
|
"""upload image on oss alibaba bucket"""
|
||||||
# Save the image object to a temporary file
|
# Save the image object to a temporary file
|
||||||
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
||||||
|
"""write image in temporary file"""
|
||||||
temp_file.write(image.read())
|
temp_file.write(image.read())
|
||||||
|
"""auth of bucket"""
|
||||||
auth = oss2.Auth(settings.ALIYUN_OSS_ACCESS_KEY_ID, settings.ALIYUN_OSS_ACCESS_KEY_SECRET)
|
auth = oss2.Auth(settings.ALIYUN_OSS_ACCESS_KEY_ID, settings.ALIYUN_OSS_ACCESS_KEY_SECRET)
|
||||||
|
"""fetch bucket details"""
|
||||||
bucket = oss2.Bucket(auth, settings.ALIYUN_OSS_ENDPOINT, settings.ALIYUN_OSS_BUCKET_NAME)
|
bucket = oss2.Bucket(auth, settings.ALIYUN_OSS_ENDPOINT, settings.ALIYUN_OSS_BUCKET_NAME)
|
||||||
# Upload the temporary file to Alibaba OSS
|
# Upload the temporary file to Alibaba OSS
|
||||||
bucket.put_object_from_file(filename, temp_file.name)
|
bucket.put_object_from_file(filename, temp_file.name)
|
||||||
return f"https://{settings.ALIYUN_OSS_BUCKET_NAME}.{settings.ALIYUN_OSS_ENDPOINT}/{filename}"
|
"""create perfect url for image"""
|
||||||
|
new_filename = filename.replace(' ', '%20')
|
||||||
|
return f"https://{settings.ALIYUN_OSS_BUCKET_NAME}.{settings.ALIYUN_OSS_ENDPOINT}/{new_filename}"
|
||||||
|
|
||||||
|
@ -2,47 +2,173 @@
|
|||||||
"""Third party Django app"""
|
"""Third party Django app"""
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from rest_framework import viewsets, status
|
from rest_framework import viewsets, status
|
||||||
|
from rest_framework.pagination import PageNumberPagination
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.utils import timezone
|
||||||
|
from datetime import datetime, timedelta
|
||||||
"""Import Django app"""
|
"""Import Django app"""
|
||||||
from .serializers import UserSerializer, CreateGuardianSerializer
|
from .serializers import (UserSerializer, CreateGuardianSerializer, TaskSerializer, TaskDetailsSerializer,
|
||||||
from .models import Guardian
|
TopJuniorSerializer)
|
||||||
from junior.models import Junior
|
from .models import Guardian, JuniorTask
|
||||||
from account.models import UserEmailOtp
|
from junior.models import Junior, JuniorPoints
|
||||||
|
from junior.serializers import JuniorDetailSerializer
|
||||||
|
from account.models import UserEmailOtp, UserNotification
|
||||||
from .tasks import generate_otp
|
from .tasks import generate_otp
|
||||||
from account.utils import send_otp_email
|
from account.utils import send_otp_email
|
||||||
from account.utils import custom_response, custom_error_response
|
from account.utils import custom_response, custom_error_response
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
|
from .utils import upload_image_to_alibaba
|
||||||
|
from django.db.models import Sum
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class SignupViewset(viewsets.ModelViewSet):
|
class SignupViewset(viewsets.ModelViewSet):
|
||||||
"""Signup view set"""
|
"""Signup view set"""
|
||||||
|
queryset = User.objects.all()
|
||||||
serializer_class = UserSerializer
|
serializer_class = UserSerializer
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
"""Create user profile"""
|
"""Create user profile"""
|
||||||
serializer = UserSerializer(context=request.data['user_type'], data=request.data)
|
if request.data['user_type'] in ['1', '2']:
|
||||||
if serializer.is_valid():
|
serializer = UserSerializer(context=request.data['user_type'], data=request.data)
|
||||||
serializer.save()
|
if serializer.is_valid():
|
||||||
"""Generate otp"""
|
serializer.save()
|
||||||
otp = generate_otp()
|
"""Generate otp"""
|
||||||
UserEmailOtp.objects.create(email=request.data['email'], otp=otp, user_type=str(request.data['user_type']))
|
otp = generate_otp()
|
||||||
"""Send email to the register user"""
|
expiry = timezone.now() + timezone.timedelta(days=1)
|
||||||
send_otp_email(request.data['email'], otp)
|
UserEmailOtp.objects.create(email=request.data['email'], otp=otp,
|
||||||
return custom_response(SUCCESS_CODE['3001'], {"email_otp": otp},
|
user_type=str(request.data['user_type']), expired_at=expiry)
|
||||||
response_status=status.HTTP_200_OK)
|
"""Send email to the register user"""
|
||||||
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
send_otp_email(request.data['email'], otp)
|
||||||
|
return custom_response(SUCCESS_CODE['3001'], {"email_otp": otp},
|
||||||
|
response_status=status.HTTP_200_OK)
|
||||||
|
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
else:
|
||||||
|
return custom_error_response(ERROR_CODE['2028'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
class UpdateGuardianProfile(viewsets.ViewSet):
|
class UpdateGuardianProfile(viewsets.ViewSet):
|
||||||
"""Update guardian profile"""
|
"""Update guardian profile"""
|
||||||
|
queryset = Guardian.objects.all()
|
||||||
serializer_class = CreateGuardianSerializer
|
serializer_class = CreateGuardianSerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
"""Create guardian profile"""
|
"""Create guardian profile"""
|
||||||
|
data = request.data
|
||||||
|
image = request.data.get('image')
|
||||||
|
image_url = ''
|
||||||
|
if image:
|
||||||
|
filename = f"images/{image.name}"
|
||||||
|
image_url = upload_image_to_alibaba(image, filename)
|
||||||
|
data = {"image":image_url}
|
||||||
serializer = CreateGuardianSerializer(context={"user":request.user,
|
serializer = CreateGuardianSerializer(context={"user":request.user,
|
||||||
"first_name":request.data.get('first_name', ''),
|
"first_name":request.data.get('first_name'),
|
||||||
"last_name": request.data.get('last_name',' ')},
|
"last_name": request.data.get('last_name'),
|
||||||
data=request.data)
|
"image":image_url},
|
||||||
|
data=data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
"""save serializer"""
|
"""save serializer"""
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return custom_response(None, serializer.data,response_status=status.HTTP_200_OK)
|
return custom_response(None, serializer.data,response_status=status.HTTP_200_OK)
|
||||||
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
|
class AllTaskListAPIView(viewsets.ModelViewSet):
|
||||||
|
"""Update guardian profile"""
|
||||||
|
serializer_class = TaskDetailsSerializer
|
||||||
|
queryset = JuniorTask.objects.all()
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
"""Create guardian profile"""
|
||||||
|
queryset = JuniorTask.objects.filter(guardian__user=request.user)
|
||||||
|
serializer = TaskDetailsSerializer(queryset, many=True)
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
class TaskListAPIView(viewsets.ModelViewSet):
|
||||||
|
"""Update guardian profile"""
|
||||||
|
serializer_class = TaskDetailsSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
pagination_class = PageNumberPagination
|
||||||
|
queryset = JuniorTask.objects.all()
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
"""Create guardian profile"""
|
||||||
|
status_value = self.request.GET.get('status')
|
||||||
|
if str(status_value) == '0':
|
||||||
|
queryset = JuniorTask.objects.filter(guardian__user=request.user).order_by('created_at')
|
||||||
|
else:
|
||||||
|
queryset = JuniorTask.objects.filter(guardian__user=request.user,
|
||||||
|
task_status=status_value).order_by('due_date','created_at')
|
||||||
|
paginator = self.pagination_class()
|
||||||
|
paginated_queryset = paginator.paginate_queryset(queryset, request)
|
||||||
|
serializer = TaskDetailsSerializer(paginated_queryset, many=True)
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
class CreateTaskAPIView(viewsets.ModelViewSet):
|
||||||
|
"""create task for junior"""
|
||||||
|
serializer_class = TaskSerializer
|
||||||
|
queryset = JuniorTask.objects.all()
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
image = request.data['default_image']
|
||||||
|
data = request.data
|
||||||
|
if 'https' in str(image):
|
||||||
|
image_data = image
|
||||||
|
else:
|
||||||
|
filename = f"images/{image}"
|
||||||
|
image_url = upload_image_to_alibaba(image, filename)
|
||||||
|
image_data = image_url
|
||||||
|
data.pop('default_image')
|
||||||
|
serializer = TaskSerializer(context={"user":request.user, "image":image_data}, data=data)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return custom_response(SUCCESS_CODE['3018'], serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
class SearchTaskListAPIView(viewsets.ModelViewSet):
|
||||||
|
"""Update guardian profile"""
|
||||||
|
serializer_class = TaskDetailsSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
pagination_class = PageNumberPagination
|
||||||
|
queryset = JuniorTask.objects.all()
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
"""Get the queryset for the view"""
|
||||||
|
title = self.request.GET.get('title')
|
||||||
|
junior_queryset = JuniorTask.objects.filter(guardian__user=self.request.user, task_name__icontains=title)\
|
||||||
|
.order_by('due_date', 'created_at')
|
||||||
|
return junior_queryset
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
"""Create guardian profile"""
|
||||||
|
queryset = self.get_queryset()
|
||||||
|
|
||||||
|
paginator = self.pagination_class()
|
||||||
|
paginated_queryset = paginator.paginate_queryset(queryset, request)
|
||||||
|
|
||||||
|
serializer = TaskDetailsSerializer(paginated_queryset, many=True)
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class TopJuniorListAPIView(viewsets.ModelViewSet):
|
||||||
|
"""Top juniors list"""
|
||||||
|
serializer_class = TopJuniorSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
queryset = JuniorPoints.objects.all()
|
||||||
|
|
||||||
|
def get_serializer_context(self):
|
||||||
|
context = super().get_serializer_context()
|
||||||
|
context.update({'view': self})
|
||||||
|
return context
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
"""Fetch junior list of those who complete their tasks"""
|
||||||
|
junior_total_points = self.get_queryset().order_by('-total_task_points')
|
||||||
|
|
||||||
|
# Update the position field for each JuniorPoints object
|
||||||
|
for index, junior in enumerate(junior_total_points):
|
||||||
|
junior.position = index + 1
|
||||||
|
junior.save()
|
||||||
|
|
||||||
|
serializer = self.get_serializer(junior_total_points, many=True)
|
||||||
|
return custom_response(serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,13 +2,22 @@
|
|||||||
"""Third party Django app"""
|
"""Third party Django app"""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
"""Import Django app"""
|
"""Import Django app"""
|
||||||
from .models import Junior
|
from .models import Junior, JuniorPoints
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
@admin.register(Junior)
|
@admin.register(Junior)
|
||||||
class JuniorAdmin(admin.ModelAdmin):
|
class JuniorAdmin(admin.ModelAdmin):
|
||||||
"""Junior Admin"""
|
"""Junior Admin"""
|
||||||
list_display = ['auth']
|
list_display = ['auth', 'guardian_code']
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Return email id"""
|
"""Return email id"""
|
||||||
return self.auth__email
|
return self.auth__email
|
||||||
|
|
||||||
|
@admin.register(JuniorPoints)
|
||||||
|
class JuniorPointsAdmin(admin.ModelAdmin):
|
||||||
|
"""Junior Points Admin"""
|
||||||
|
list_display = ['junior', 'total_task_points', 'position']
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return email id"""
|
||||||
|
return self.junior.auth.email
|
||||||
|
18
junior/migrations/0007_alter_junior_image.py
Normal file
18
junior/migrations/0007_alter_junior_image.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-06 12:18
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0006_alter_junior_country_name'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='junior',
|
||||||
|
name='image',
|
||||||
|
field=models.URLField(blank=True, default=None, null=True),
|
||||||
|
),
|
||||||
|
]
|
28
junior/migrations/0008_juniorpoints.py
Normal file
28
junior/migrations/0008_juniorpoints.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-09 12:40
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0007_alter_junior_image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='JuniorPoints',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('total_task_points', models.IntegerField(blank=True, default=0, null=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('junior', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='junior_points', to='junior.junior')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Junior Task Points',
|
||||||
|
'db_table': 'junior_task_points',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
18
junior/migrations/0009_juniorpoints_position.py
Normal file
18
junior/migrations/0009_juniorpoints_position.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-10 07:36
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0008_juniorpoints'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='juniorpoints',
|
||||||
|
name='position',
|
||||||
|
field=models.IntegerField(blank=True, default=99999, null=True),
|
||||||
|
),
|
||||||
|
]
|
@ -18,7 +18,7 @@ class Junior(models.Model):
|
|||||||
"""Personal info"""
|
"""Personal info"""
|
||||||
gender = models.CharField(max_length=10, choices=GENDERS, null=True, blank=True, default=None)
|
gender = models.CharField(max_length=10, choices=GENDERS, null=True, blank=True, default=None)
|
||||||
dob = models.DateField(max_length=15, null=True, blank=True, default=None)
|
dob = models.DateField(max_length=15, null=True, blank=True, default=None)
|
||||||
image = models.ImageField(null=True, blank=True, default=None)
|
image = models.URLField(null=True, blank=True, default=None)
|
||||||
"""Codes"""
|
"""Codes"""
|
||||||
junior_code = models.CharField(max_length=10, null=True, blank=True, default=None)
|
junior_code = models.CharField(max_length=10, null=True, blank=True, default=None)
|
||||||
guardian_code = ArrayField(models.CharField(max_length=10, null=True, blank=True, default=None),null=True)
|
guardian_code = ArrayField(models.CharField(max_length=10, null=True, blank=True, default=None),null=True)
|
||||||
@ -41,3 +41,23 @@ class Junior(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Return email id"""
|
"""Return email id"""
|
||||||
return f'{self.auth}'
|
return f'{self.auth}'
|
||||||
|
|
||||||
|
class JuniorPoints(models.Model):
|
||||||
|
"""Junior model"""
|
||||||
|
junior = models.OneToOneField(Junior, on_delete=models.CASCADE, related_name='junior_points')
|
||||||
|
"""Contact details"""
|
||||||
|
total_task_points = models.IntegerField(blank=True, null=True, default=0)
|
||||||
|
"""position of the junior"""
|
||||||
|
position = models.IntegerField(blank=True, null=True, default=99999)
|
||||||
|
"""Profile created and updated time"""
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
""" Meta class """
|
||||||
|
db_table = 'junior_task_points'
|
||||||
|
verbose_name = 'Junior Task Points'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return email id"""
|
||||||
|
return f'{self.junior.auth}'
|
||||||
|
@ -5,10 +5,11 @@ from django.contrib.auth.models import User
|
|||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
import random
|
import random
|
||||||
"""Import django app"""
|
"""Import django app"""
|
||||||
from junior.models import Junior
|
from junior.models import Junior, JuniorPoints
|
||||||
from guardian.utils import upload_image_to_alibaba
|
from guardian.utils import upload_image_to_alibaba
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
from guardian.models import Guardian
|
from guardian.models import Guardian, JuniorTask
|
||||||
|
from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED
|
||||||
|
|
||||||
class ListCharField(serializers.ListField):
|
class ListCharField(serializers.ListField):
|
||||||
"""Serializer for Array field"""
|
"""Serializer for Array field"""
|
||||||
@ -35,7 +36,7 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
|
|||||||
dob = serializers.DateField(required=False)
|
dob = serializers.DateField(required=False)
|
||||||
referral_code = serializers.CharField(max_length=100, required=False)
|
referral_code = serializers.CharField(max_length=100, required=False)
|
||||||
guardian_code = ListCharField(required=False)
|
guardian_code = ListCharField(required=False)
|
||||||
image = serializers.ImageField(required=False)
|
image = serializers.URLField(required=False)
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
@ -58,19 +59,15 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
"""Create junior profile"""
|
"""Create junior profile"""
|
||||||
image = validated_data.get('image', None)
|
guardian_code = validated_data.get('guardian_code',None)
|
||||||
# phone_number = validated_data.get('phone', None)
|
|
||||||
# guardian_data = Guardian.objects.filter(phone=phone_number)
|
|
||||||
# junior_data = Junior.objects.filter(phone=phone_number)
|
|
||||||
# if phone_number and (junior_data or guardian_data):
|
|
||||||
# raise serializers.ValidationError({"details":ERROR_CODE['2012']})
|
|
||||||
user = User.objects.filter(username=self.context['user']).last()
|
user = User.objects.filter(username=self.context['user']).last()
|
||||||
if user:
|
if user:
|
||||||
"""Save first and last name of junior"""
|
"""Save first and last name of junior"""
|
||||||
if self.context.get('first_name') != '' and self.context.get('last_name') != '':
|
if self.context.get('first_name') != '' and self.context.get('first_name') is not None:
|
||||||
user.first_name = self.context.get('first_name', user.first_name)
|
user.first_name = self.context.get('first_name')
|
||||||
user.last_name = self.context.get('last_name', user.last_name)
|
if self.context.get('last_name') != '' and self.context.get('last_name') is not None:
|
||||||
user.save()
|
user.last_name = self.context.get('last_name')
|
||||||
|
user.save()
|
||||||
"""Create junior data"""
|
"""Create junior data"""
|
||||||
junior, created = Junior.objects.get_or_create(auth=self.context['user'])
|
junior, created = Junior.objects.get_or_create(auth=self.context['user'])
|
||||||
if created:
|
if created:
|
||||||
@ -82,6 +79,9 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
|
|||||||
junior.gender = validated_data.get('gender',junior.gender)
|
junior.gender = validated_data.get('gender',junior.gender)
|
||||||
"""Update guardian code"""
|
"""Update guardian code"""
|
||||||
junior.guardian_code = validated_data.get('guardian_code', junior.guardian_code)
|
junior.guardian_code = validated_data.get('guardian_code', junior.guardian_code)
|
||||||
|
"""condition for guardian code"""
|
||||||
|
if guardian_code:
|
||||||
|
junior.guardian_code = guardian_code
|
||||||
junior.dob = validated_data.get('dob',junior.dob)
|
junior.dob = validated_data.get('dob',junior.dob)
|
||||||
junior.passcode = validated_data.get('passcode', junior.passcode)
|
junior.passcode = validated_data.get('passcode', junior.passcode)
|
||||||
junior.country_name = validated_data.get('country_name', junior.country_name)
|
junior.country_name = validated_data.get('country_name', junior.country_name)
|
||||||
@ -89,16 +89,14 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
|
|||||||
junior.phone = validated_data.get('phone', junior.phone)
|
junior.phone = validated_data.get('phone', junior.phone)
|
||||||
junior.country_code = validated_data.get('country_code', junior.country_code)
|
junior.country_code = validated_data.get('country_code', junior.country_code)
|
||||||
junior.referral_code_used = validated_data.get('referral_code_used', junior.referral_code_used)
|
junior.referral_code_used = validated_data.get('referral_code_used', junior.referral_code_used)
|
||||||
|
junior.image = validated_data.get('image', junior.image)
|
||||||
"""Complete profile of the junior if below all data are filled"""
|
"""Complete profile of the junior if below all data are filled"""
|
||||||
complete_profile_field = all([junior.phone, junior.gender, junior.country_name,
|
complete_profile_field = all([junior.phone, junior.gender, junior.country_name, junior.image,
|
||||||
junior.dob, junior.country_code, user.first_name, user.last_name])
|
junior.dob, junior.country_code, user.first_name, user.last_name,
|
||||||
|
user.email])
|
||||||
junior.is_complete_profile = False
|
junior.is_complete_profile = False
|
||||||
if complete_profile_field:
|
if complete_profile_field:
|
||||||
junior.is_complete_profile = True
|
junior.is_complete_profile = True
|
||||||
if image:
|
|
||||||
filename = f"images/{image.name}"
|
|
||||||
image_url = upload_image_to_alibaba(image, filename)
|
|
||||||
junior.image = image_url
|
|
||||||
junior.save()
|
junior.save()
|
||||||
return junior
|
return junior
|
||||||
|
|
||||||
@ -107,3 +105,136 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
|
|||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
instance = super().save(**kwargs)
|
instance = super().save(**kwargs)
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
class JuniorDetailSerializer(serializers.ModelSerializer):
|
||||||
|
"""junior serializer"""
|
||||||
|
email = serializers.SerializerMethodField('get_auth')
|
||||||
|
first_name = serializers.SerializerMethodField('get_first_name')
|
||||||
|
last_name = serializers.SerializerMethodField('get_last_name')
|
||||||
|
|
||||||
|
def get_auth(self, obj):
|
||||||
|
"""user email address"""
|
||||||
|
return obj.auth.username
|
||||||
|
|
||||||
|
def get_first_name(self, obj):
|
||||||
|
"""user first name"""
|
||||||
|
return obj.auth.first_name
|
||||||
|
|
||||||
|
def get_last_name(self, obj):
|
||||||
|
"""user last name"""
|
||||||
|
return obj.auth.last_name
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = Junior
|
||||||
|
fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob',
|
||||||
|
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image',
|
||||||
|
'updated_at']
|
||||||
|
|
||||||
|
class JuniorDetailListSerializer(serializers.ModelSerializer):
|
||||||
|
"""junior serializer"""
|
||||||
|
|
||||||
|
email = serializers.SerializerMethodField('get_auth')
|
||||||
|
first_name = serializers.SerializerMethodField('get_first_name')
|
||||||
|
last_name = serializers.SerializerMethodField('get_last_name')
|
||||||
|
assigned_task = serializers.SerializerMethodField('get_assigned_task')
|
||||||
|
points = serializers.SerializerMethodField('get_points')
|
||||||
|
in_progress_task = serializers.SerializerMethodField('get_in_progress_task')
|
||||||
|
completed_task = serializers.SerializerMethodField('get_completed_task')
|
||||||
|
requested_task = serializers.SerializerMethodField('get_requested_task')
|
||||||
|
rejected_task = serializers.SerializerMethodField('get_rejected_task')
|
||||||
|
pending_task = serializers.SerializerMethodField('get_pending_task')
|
||||||
|
position = serializers.SerializerMethodField('get_position')
|
||||||
|
|
||||||
|
|
||||||
|
def get_auth(self, obj):
|
||||||
|
return obj.auth.username
|
||||||
|
|
||||||
|
def get_first_name(self, obj):
|
||||||
|
return obj.auth.first_name
|
||||||
|
|
||||||
|
def get_last_name(self, obj):
|
||||||
|
return obj.auth.last_name
|
||||||
|
|
||||||
|
def get_assigned_task(self, obj):
|
||||||
|
data = JuniorTask.objects.filter(junior=obj).count()
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_position(self, obj):
|
||||||
|
data = JuniorPoints.objects.filter(junior=obj).last()
|
||||||
|
if data:
|
||||||
|
return data.position
|
||||||
|
return 99999
|
||||||
|
def get_points(self, obj):
|
||||||
|
data = sum(JuniorTask.objects.filter(junior=obj, task_status=COMPLETED).values_list('points', flat=True))
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_in_progress_task(self, obj):
|
||||||
|
data = JuniorTask.objects.filter(junior=obj, task_status=IN_PROGRESS).count()
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_completed_task(self, obj):
|
||||||
|
data = JuniorTask.objects.filter(junior=obj, task_status=COMPLETED).count()
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def get_requested_task(self, obj):
|
||||||
|
data = JuniorTask.objects.filter(junior=obj, task_status=REQUESTED).count()
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_rejected_task(self, obj):
|
||||||
|
data = JuniorTask.objects.filter(junior=obj, task_status=REJECTED).count()
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_pending_task(self, obj):
|
||||||
|
data = JuniorTask.objects.filter(junior=obj, task_status=PENDING).count()
|
||||||
|
return data
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = Junior
|
||||||
|
fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob',
|
||||||
|
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image',
|
||||||
|
'updated_at', 'assigned_task','points', 'pending_task', 'in_progress_task', 'completed_task',
|
||||||
|
'requested_task', 'rejected_task', 'position']
|
||||||
|
|
||||||
|
class JuniorProfileSerializer(serializers.ModelSerializer):
|
||||||
|
"""junior serializer"""
|
||||||
|
email = serializers.SerializerMethodField('get_auth')
|
||||||
|
first_name = serializers.SerializerMethodField('get_first_name')
|
||||||
|
last_name = serializers.SerializerMethodField('get_last_name')
|
||||||
|
notification_count = serializers.SerializerMethodField('get_notification_count')
|
||||||
|
total_count = serializers.SerializerMethodField('get_total_count')
|
||||||
|
complete_field_count = serializers.SerializerMethodField('get_complete_field_count')
|
||||||
|
|
||||||
|
def get_auth(self, obj):
|
||||||
|
"""user email address"""
|
||||||
|
return obj.auth.username
|
||||||
|
|
||||||
|
def get_first_name(self, obj):
|
||||||
|
"""user first name"""
|
||||||
|
return obj.auth.first_name
|
||||||
|
|
||||||
|
def get_last_name(self, obj):
|
||||||
|
"""user last name"""
|
||||||
|
return obj.auth.last_name
|
||||||
|
|
||||||
|
def get_notification_count(self, obj):
|
||||||
|
"""total notification count"""
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def get_total_count(self, obj):
|
||||||
|
"""total fields count"""
|
||||||
|
return 9
|
||||||
|
|
||||||
|
def get_complete_field_count(self, obj):
|
||||||
|
"""total filled fields count"""
|
||||||
|
field_list = [obj.auth.first_name, obj.auth.last_name, obj.auth.email, obj.country_name, obj.country_code,
|
||||||
|
obj.phone, obj.gender, obj.dob, obj.image]
|
||||||
|
complete_field = [data for data in field_list if data is not None and data != '']
|
||||||
|
return len(complete_field)
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = Junior
|
||||||
|
fields = ['id', 'email', 'first_name', 'last_name', 'country_name', 'country_code', 'phone', 'gender', 'dob',
|
||||||
|
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image',
|
||||||
|
'updated_at', 'notification_count', 'total_count', 'complete_field_count']
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
""" Urls files"""
|
""" Urls files"""
|
||||||
"""Django import"""
|
"""Django import"""
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from .views import UpdateJuniorProfile, ValidateGuardianCode
|
from .views import UpdateJuniorProfile, ValidateGuardianCode, JuniorListAPIView
|
||||||
"""Third party import"""
|
"""Third party import"""
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
@ -13,6 +13,8 @@ router = routers.SimpleRouter()
|
|||||||
router.register('create-junior-profile', UpdateJuniorProfile, basename='profile-update')
|
router.register('create-junior-profile', UpdateJuniorProfile, basename='profile-update')
|
||||||
"""validate guardian code API"""
|
"""validate guardian code API"""
|
||||||
router.register('validate-guardian-code', ValidateGuardianCode, basename='validate-guardian-code')
|
router.register('validate-guardian-code', ValidateGuardianCode, basename='validate-guardian-code')
|
||||||
|
"""junior list API"""
|
||||||
|
router.register('junior-list', JuniorListAPIView, basename='junior-list')
|
||||||
"""Define url pattern"""
|
"""Define url pattern"""
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('api/v1/', include(router.urls)),
|
path('api/v1/', include(router.urls)),
|
||||||
|
@ -3,22 +3,32 @@ from rest_framework import viewsets, status
|
|||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
"""Django app import"""
|
"""Django app import"""
|
||||||
from junior.models import Junior
|
from junior.models import Junior
|
||||||
from .serializers import CreateJuniorSerializer
|
from .serializers import CreateJuniorSerializer, JuniorDetailListSerializer
|
||||||
from guardian.models import Guardian
|
from guardian.models import Guardian
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
from account.utils import custom_response, custom_error_response
|
from account.utils import custom_response, custom_error_response
|
||||||
|
from guardian.utils import upload_image_to_alibaba
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class UpdateJuniorProfile(viewsets.ViewSet):
|
class UpdateJuniorProfile(viewsets.ViewSet):
|
||||||
"""Update junior profile"""
|
"""Update junior profile"""
|
||||||
|
queryset = Junior.objects.all()
|
||||||
serializer_class = CreateJuniorSerializer
|
serializer_class = CreateJuniorSerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
"""Use CreateJuniorSerializer"""
|
"""Use CreateJuniorSerializer"""
|
||||||
serializer = CreateJuniorSerializer(context={"user":request.user,
|
request_data = request.data
|
||||||
"first_name":request.data.get('first_name', ''),
|
image = request.data.get('image')
|
||||||
"last_name": request.data.get('last_name',' ')},
|
image_url = ''
|
||||||
data=request.data)
|
if image:
|
||||||
|
filename = f"images/{image.name}"
|
||||||
|
image_url = upload_image_to_alibaba(image, filename)
|
||||||
|
request_data = {"image": image_url}
|
||||||
|
serializer = CreateJuniorSerializer(context={"user":request.user, "image":image_url,
|
||||||
|
"first_name": request.data.get('first_name'),
|
||||||
|
"last_name": request.data.get('last_name')
|
||||||
|
},
|
||||||
|
data=request_data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
"""save serializer"""
|
"""save serializer"""
|
||||||
serializer.save()
|
serializer.save()
|
||||||
@ -27,6 +37,7 @@ class UpdateJuniorProfile(viewsets.ViewSet):
|
|||||||
|
|
||||||
class ValidateGuardianCode(viewsets.ViewSet):
|
class ValidateGuardianCode(viewsets.ViewSet):
|
||||||
"""Check guardian code exist or not"""
|
"""Check guardian code exist or not"""
|
||||||
|
queryset = Guardian.objects.all()
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
@ -38,3 +49,15 @@ class ValidateGuardianCode(viewsets.ViewSet):
|
|||||||
return custom_response(SUCCESS_CODE['3013'], response_status=status.HTTP_200_OK)
|
return custom_response(SUCCESS_CODE['3013'], response_status=status.HTTP_200_OK)
|
||||||
else:
|
else:
|
||||||
return custom_error_response(ERROR_CODE["2022"], response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(ERROR_CODE["2022"], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
class JuniorListAPIView(viewsets.ModelViewSet):
|
||||||
|
"""Junior list of assosicated guardian"""
|
||||||
|
|
||||||
|
serializer_class = JuniorDetailListSerializer
|
||||||
|
queryset = Junior.objects.all()
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
""" junior list"""
|
||||||
|
guardian_data = Guardian.objects.filter(user__email=request.user).last()
|
||||||
|
queryset = Junior.objects.filter(guardian_code__icontains=str(guardian_data.guardian_code))
|
||||||
|
serializer = JuniorDetailListSerializer(queryset, many=True)
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
"""Django's command-line utility for administrative tasks."""
|
"""Django's command-line utility for administrative tasks."""
|
||||||
"""Django import"""
|
"""Django import"""
|
||||||
|
"""Import OS module"""
|
||||||
import os
|
import os
|
||||||
|
"""Import sys module"""
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
@ -18,6 +20,7 @@ def main():
|
|||||||
"available on your PYTHONPATH environment variable? Did you "
|
"available on your PYTHONPATH environment variable? Did you "
|
||||||
"forget to activate a virtual environment?"
|
"forget to activate a virtual environment?"
|
||||||
) from exc
|
) from exc
|
||||||
|
"""execute command line function"""
|
||||||
execute_from_command_line(sys.argv)
|
execute_from_command_line(sys.argv)
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ async-timeout==4.0.2
|
|||||||
billiard==4.1.0
|
billiard==4.1.0
|
||||||
boto3==1.26.157
|
boto3==1.26.157
|
||||||
botocore==1.29.157
|
botocore==1.29.157
|
||||||
|
cachetools==5.3.1
|
||||||
celery==5.3.1
|
celery==5.3.1
|
||||||
certifi==2023.5.7
|
certifi==2023.5.7
|
||||||
cffi==1.15.1
|
cffi==1.15.1
|
||||||
@ -18,6 +19,8 @@ click==8.1.3
|
|||||||
click-didyoumean==0.3.0
|
click-didyoumean==0.3.0
|
||||||
click-plugins==1.1.1
|
click-plugins==1.1.1
|
||||||
click-repl==0.3.0
|
click-repl==0.3.0
|
||||||
|
coreapi==2.3.3
|
||||||
|
coreschema==0.0.4
|
||||||
crcmod==1.7
|
crcmod==1.7
|
||||||
cron-descriptor==1.4.0
|
cron-descriptor==1.4.0
|
||||||
cryptography==41.0.1
|
cryptography==41.0.1
|
||||||
@ -38,11 +41,15 @@ django-timezone-field==5.1
|
|||||||
djangorestframework==3.14.0
|
djangorestframework==3.14.0
|
||||||
djangorestframework-simplejwt==5.2.2
|
djangorestframework-simplejwt==5.2.2
|
||||||
drf-yasg==1.21.6
|
drf-yasg==1.21.6
|
||||||
|
google-auth==2.21.0
|
||||||
gunicorn==20.1.0
|
gunicorn==20.1.0
|
||||||
idna==3.4
|
idna==3.4
|
||||||
inflection==0.5.1
|
inflection==0.5.1
|
||||||
|
itypes==1.2.0
|
||||||
|
Jinja2==3.1.2
|
||||||
jmespath==0.10.0
|
jmespath==0.10.0
|
||||||
kombu==5.3.1
|
kombu==5.3.1
|
||||||
|
MarkupSafe==2.1.3
|
||||||
msgpack==1.0.5
|
msgpack==1.0.5
|
||||||
oss2==2.18.0
|
oss2==2.18.0
|
||||||
packaging==23.1
|
packaging==23.1
|
||||||
@ -50,6 +57,8 @@ phonenumbers==8.13.15
|
|||||||
Pillow==9.5.0
|
Pillow==9.5.0
|
||||||
prompt-toolkit==3.0.38
|
prompt-toolkit==3.0.38
|
||||||
psycopg==3.1.9
|
psycopg==3.1.9
|
||||||
|
pyasn1==0.5.0
|
||||||
|
pyasn1-modules==0.3.0
|
||||||
pycparser==2.21
|
pycparser==2.21
|
||||||
pycryptodome==3.18.0
|
pycryptodome==3.18.0
|
||||||
PyJWT==2.7.0
|
PyJWT==2.7.0
|
||||||
@ -60,6 +69,7 @@ pytz==2023.3
|
|||||||
PyYAML==6.0
|
PyYAML==6.0
|
||||||
redis==4.5.5
|
redis==4.5.5
|
||||||
requests==2.31.0
|
requests==2.31.0
|
||||||
|
rsa==4.9
|
||||||
s3transfer==0.6.1
|
s3transfer==0.6.1
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
sqlparse==0.4.4
|
sqlparse==0.4.4
|
||||||
|
@ -56,6 +56,7 @@ INSTALLED_APPS = [
|
|||||||
'account',
|
'account',
|
||||||
'junior',
|
'junior',
|
||||||
'guardian',
|
'guardian',
|
||||||
|
# 'social_django'
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@ -91,11 +92,12 @@ REST_FRAMEWORK = {
|
|||||||
'DEFAULT_AUTHENTICATION_CLASSES': [
|
'DEFAULT_AUTHENTICATION_CLASSES': [
|
||||||
# 'rest_framework.authentication.SessionAuthentication',
|
# 'rest_framework.authentication.SessionAuthentication',
|
||||||
'rest_framework.authentication.BasicAuthentication',
|
'rest_framework.authentication.BasicAuthentication',
|
||||||
'rest_framework_simplejwt.authentication.JWTAuthentication',
|
'rest_framework_simplejwt.authentication.JWTAuthentication',],
|
||||||
]
|
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
|
||||||
|
'PAGE_SIZE': 5,
|
||||||
}
|
}
|
||||||
SIMPLE_JWT = {
|
SIMPLE_JWT = {
|
||||||
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15),
|
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=50),
|
||||||
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
|
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
|
||||||
}
|
}
|
||||||
# Database
|
# Database
|
||||||
@ -110,6 +112,30 @@ DATABASES = {
|
|||||||
'PORT':os.getenv('DB_PORT'),
|
'PORT':os.getenv('DB_PORT'),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWAGGER_SETTINGS = {
|
||||||
|
"exclude_namespaces": [],
|
||||||
|
"api_version": '0.1',
|
||||||
|
"api_path": "",
|
||||||
|
"enabled_methods": [
|
||||||
|
'get',
|
||||||
|
'post',
|
||||||
|
'put',
|
||||||
|
'patch',
|
||||||
|
'delete'
|
||||||
|
],
|
||||||
|
"api_key": '',
|
||||||
|
"is_authenticated": True,
|
||||||
|
"is_superuser": False,
|
||||||
|
|
||||||
|
'SECURITY_DEFINITIONS': {
|
||||||
|
"api_key": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"name": "Authorization",
|
||||||
|
"in": "header",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
# Password validation
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
@ -172,33 +198,27 @@ CORS_ALLOW_HEADERS = (
|
|||||||
https://docs.djangoproject.com/en/3.0/howto/static-files/"""
|
https://docs.djangoproject.com/en/3.0/howto/static-files/"""
|
||||||
|
|
||||||
|
|
||||||
# EMAIL_BACKEND = os.getenv('EMAIL_BACKEND')
|
GOOGLE_CLIENT_ID = os.getenv('GOOGLE_CLIENT_ID')
|
||||||
# EMAIL_HOST = os.getenv('EMAIL_HOST')
|
GOOGLE_CLIENT_SECRET = os.getenv('GOOGLE_CLIENT_SECRET')
|
||||||
# EMAIL_PORT = os.getenv('EMAIL_PORT')
|
|
||||||
# EMAIL_USE_TLS = os.getenv('EMAIL_USE_TLS')
|
|
||||||
# EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER') # Replace with your Gmail email address
|
|
||||||
# EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD') # Replace with your Gmail email password or App password
|
|
||||||
# EMAIL_FROM_ADDRESS = os.getenv('EMAIL_FROM_ADDRESS')
|
|
||||||
|
|
||||||
EMAIL_BACKEND="django.core.mail.backends.smtp.EmailBackend"
|
EMAIL_BACKEND="django.core.mail.backends.smtp.EmailBackend"
|
||||||
EMAIL_HOST="smtp.sendgrid.net"
|
EMAIL_HOST="smtp.sendgrid.net"
|
||||||
EMAIL_PORT="587"
|
EMAIL_PORT="587"
|
||||||
EMAIL_USE_TLS="True"
|
EMAIL_USE_TLS="True"
|
||||||
EMAIL_HOST_USER="apikey" # Replace with your Gmail email address
|
EMAIL_HOST_USER="apikey"
|
||||||
EMAIL_HOST_PASSWORD="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"
|
EMAIL_HOST_PASSWORD="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"
|
||||||
EMAIL_FROM_ADDRESS="zodbank@yopmail.com"
|
EMAIL_FROM_ADDRESS="support@zodbank.com"
|
||||||
|
|
||||||
# ALIYUN_OSS_ACCESS_KEY_ID = os.getenv('ALIYUN_OSS_ACCESS_KEY_ID')
|
|
||||||
# ALIYUN_OSS_ACCESS_KEY_SECRET = os.getenv('ALIYUN_OSS_ACCESS_KEY_SECRET')
|
|
||||||
# ALIYUN_OSS_BUCKET_NAME = os.getenv('ALIYUN_OSS_BUCKET_NAME')
|
|
||||||
# ALIYUN_OSS_ENDPOINT = os.getenv('ALIYUN_OSS_ENDPOINT')
|
|
||||||
# ALIYUN_OSS_REGION = os.getenv('ALIYUN_OSS_REGION')
|
|
||||||
|
|
||||||
ALIYUN_OSS_ACCESS_KEY_ID="LTAI5t7w1gq1CswJtvxtEZTd"
|
|
||||||
ALIYUN_OSS_ACCESS_KEY_SECRET="6yknAFpP2gVMhCWAJwbAjCEw2eehpf"
|
ALIYUN_OSS_ACCESS_KEY_ID = os.getenv('ALIYUN_OSS_ACCESS_KEY_ID')
|
||||||
ALIYUN_OSS_BUCKET_NAME="zod-qa"
|
ALIYUN_OSS_ACCESS_KEY_SECRET = os.getenv('ALIYUN_OSS_ACCESS_KEY_SECRET')
|
||||||
ALIYUN_OSS_ENDPOINT="oss-me-central-1.aliyuncs.com"
|
ALIYUN_OSS_BUCKET_NAME = os.getenv('ALIYUN_OSS_BUCKET_NAME')
|
||||||
ALIYUN_OSS_REGION="Global"
|
ALIYUN_OSS_ENDPOINT = os.getenv('ALIYUN_OSS_ENDPOINT')
|
||||||
|
ALIYUN_OSS_REGION = os.getenv('ALIYUN_OSS_REGION')
|
||||||
|
|
||||||
|
|
||||||
STATIC_URL = 'static/'
|
STATIC_URL = 'static/'
|
||||||
STATIC_ROOT = 'static'
|
STATIC_ROOT = 'static'
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user