mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-11-27 17:14:55 +00:00
Compare commits
112 Commits
server_dem
...
sprint2
| Author | SHA1 | Date | |
|---|---|---|---|
| cfc36735d6 | |||
| 32e52e17f4 | |||
| 5bd865a685 | |||
| 485dc83911 | |||
| a0e1dc11fa | |||
| c798357952 | |||
| d163f43c85 | |||
| 7b9b5a2c6f | |||
| 5d528b885a | |||
| 52a0f4b590 | |||
| a16fecb1c9 | |||
| 1ac6c7c01d | |||
| ab06962b79 | |||
| 324a023d83 | |||
| d0430d7aad | |||
| 701961234d | |||
| 1fc02d17e6 | |||
| 81e314878e | |||
| a041028840 | |||
| 8720de4834 | |||
| 33101811ff | |||
| 18cb975d94 | |||
| 2e7ef5e69f | |||
| 7e7367e3a4 | |||
| 809f89bd42 | |||
| 68ce67d387 | |||
| efa121640f | |||
| 7d6dfb15a2 | |||
| 8b4db3e2e9 | |||
| c26e6140a7 | |||
| 41761f22e8 | |||
| cd0f1c72a1 | |||
| c0f20f732d | |||
| 628dbbf926 | |||
| 1ae81d4134 | |||
| 03fb774a7b | |||
| 4fb7a2fc6c | |||
| 0d4c9aae78 | |||
| c8925aad8e | |||
| 51153a09cc | |||
| 026bfb6da7 | |||
| 65a00ef090 | |||
| 3098de36b8 | |||
| 15cc3eca51 | |||
| 1b60d4344e | |||
| 3723e46be1 | |||
| 8bf4ad8352 | |||
| 413434496c | |||
| c7415c7760 | |||
| 9e8cde3516 | |||
| af5f0cf200 | |||
| ab435ef384 | |||
| 3f0e73771c | |||
| c6ffb1f039 | |||
| 2b783512a5 | |||
| bea4cbe376 | |||
| 34034dcdb8 | |||
| c7a5bf68a0 | |||
| 3b642fcc5f | |||
| 2edd8c4e00 | |||
| cf966a5250 | |||
| a80f603614 | |||
| 0d143a39ac | |||
| 5e5161a77e | |||
| 156dc496bd | |||
| 376bb89f20 | |||
| 1c7d6bac85 | |||
| abbe09731c | |||
| 22f1d01b94 | |||
| 69c06691c7 | |||
| a27c486c43 | |||
| 28cbdf9cfa | |||
| 014b5fe183 | |||
| d2498f82ad | |||
| 36cedf8c69 | |||
| 66bbe06686 | |||
| 79ac140ddd | |||
| 4a34dab570 | |||
| 245162b913 | |||
| 7376fc555b | |||
| ed2d7895ab | |||
| c57968b7c0 | |||
| e42d8af65b | |||
| d254c5e5fa | |||
| 118d73776b | |||
| c2713b8214 | |||
| 4dd95e74fb | |||
| 70c136dde4 | |||
| 88a9e925ed | |||
| 3d3ccfb146 | |||
| be6725c66d | |||
| f3c41043e0 | |||
| ea2bd635ca | |||
| eb4cde397f | |||
| 4864d3b499 | |||
| ef1f7ebeac | |||
| c1ae88c32f | |||
| 9d7f265f40 | |||
| f0a2a4bd4b | |||
| 4a982f1baf | |||
| d849153bec | |||
| 947119d4c2 | |||
| a41e3a6f14 | |||
| 7b02b7dfbc | |||
| 3852e9bf03 | |||
| d208e5252c | |||
| 7b6d34f334 | |||
| 0006208cf8 | |||
| 352de6d630 | |||
| 019d028cb6 | |||
| e1e5b1838a | |||
| 4537f1f4fa |
@ -2,15 +2,33 @@
|
|||||||
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, DefaultTaskImages, UserNotification, UserDelete, UserDeviceDetails
|
||||||
# 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 delete user"""
|
||||||
|
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 image url"""
|
||||||
|
return self.image_url
|
||||||
|
@admin.register(DefaultTaskImages)
|
||||||
|
class DefaultTaskImagesAdmin(admin.ModelAdmin):
|
||||||
|
"""User profile admin"""
|
||||||
|
list_display = ['task_name', 'image_url']
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return image url"""
|
||||||
|
return self.image_url
|
||||||
|
|
||||||
@admin.register(UserEmailOtp)
|
@admin.register(UserEmailOtp)
|
||||||
class UserEmailOtpAdmin(admin.ModelAdmin):
|
class UserEmailOtpAdmin(admin.ModelAdmin):
|
||||||
@ -21,11 +39,11 @@ class UserEmailOtpAdmin(admin.ModelAdmin):
|
|||||||
"""Return object in email and otp format"""
|
"""Return object in email and otp format"""
|
||||||
return self.email + '-' + self.otp
|
return self.email + '-' + self.otp
|
||||||
|
|
||||||
@admin.register(UserPhoneOtp)
|
@admin.register(UserDeviceDetails)
|
||||||
class UserPhoneOtpAdmin(admin.ModelAdmin):
|
class UserDeviceDetailsAdmin(admin.ModelAdmin):
|
||||||
"""User Phone otp admin"""
|
"""User profile admin"""
|
||||||
list_display = ['phone']
|
list_display = ['user', 'device_id']
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Return object in phone number and otp format"""
|
"""Return user email"""
|
||||||
return self.phone + '-' + self.otp
|
return self.user.email
|
||||||
|
|||||||
@ -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'
|
||||||
|
|||||||
40
account/custom_middleware.py
Normal file
40
account/custom_middleware.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
"""middleware file"""
|
||||||
|
"""Django import"""
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.renderers import JSONRenderer
|
||||||
|
"""App django"""
|
||||||
|
from account.utils import custom_error_response
|
||||||
|
from account.models import UserDeviceDetails
|
||||||
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
|
|
||||||
|
# Custom middleware
|
||||||
|
# when user login with
|
||||||
|
# multiple device simultaneously
|
||||||
|
# It restricted login in
|
||||||
|
# multiple devices only
|
||||||
|
# user can login in single
|
||||||
|
# device at a time"""
|
||||||
|
class CustomMiddleware(object):
|
||||||
|
"""Custom middleware"""
|
||||||
|
def __init__(self, get_response):
|
||||||
|
"""response"""
|
||||||
|
self.get_response = get_response
|
||||||
|
|
||||||
|
def __call__(self, request):
|
||||||
|
# Code to be executed before the view is called
|
||||||
|
response = self.get_response(request)
|
||||||
|
# Code to be executed after the view is called
|
||||||
|
device_id = request.META.get('HTTP_DEVICE_ID')
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
"""device details"""
|
||||||
|
device_details = UserDeviceDetails.objects.filter(user=request.user, device_id=device_id).last()
|
||||||
|
if device_id and not device_details:
|
||||||
|
custom_error = custom_error_response(ERROR_CODE['2037'], response_status=status.HTTP_404_NOT_FOUND)
|
||||||
|
response = Response(custom_error.data, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
# Set content type header to "application/json"
|
||||||
|
response['Content-Type'] = 'application/json'
|
||||||
|
# Render the response as JSON
|
||||||
|
renderer = JSONRenderer()
|
||||||
|
response.content = renderer.render(response.data)
|
||||||
|
return response
|
||||||
18
account/migrations/0002_useremailotp_user_type.py
Normal file
18
account/migrations/0002_useremailotp_user_type.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-29 12:10
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('account', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='useremailotp',
|
||||||
|
name='user_type',
|
||||||
|
field=models.CharField(blank=True, choices=[('1', 'junior'), ('2', 'guardian'), ('3', 'superuser')], default=None, max_length=15, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
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',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-11 11:26
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('account', '0005_usernotification'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='useremailotp',
|
||||||
|
options={'verbose_name': 'User Email OTP', 'verbose_name_plural': 'User Email OTP'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='usernotification',
|
||||||
|
options={'verbose_name': 'User Notification', 'verbose_name_plural': 'User Notification'},
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-14 09:34
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('account', '0006_alter_useremailotp_options_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='defaulttaskimages',
|
||||||
|
options={'verbose_name': 'Default Task images', 'verbose_name_plural': 'Default Task images'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='userdelete',
|
||||||
|
options={'verbose_name': 'Deleted User', 'verbose_name_plural': 'Deleted User'},
|
||||||
|
),
|
||||||
|
]
|
||||||
31
account/migrations/0008_userdevicedetails.py
Normal file
31
account/migrations/0008_userdevicedetails.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-14 11:08
|
||||||
|
|
||||||
|
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', '0007_alter_defaulttaskimages_options_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UserDeviceDetails',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('device_id', models.CharField(max_length=500)),
|
||||||
|
('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_device_details', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'User Device Details',
|
||||||
|
'verbose_name_plural': 'User Device Details',
|
||||||
|
'db_table': 'user_device_details',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -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.
|
||||||
|
|
||||||
@ -59,6 +61,7 @@ class UserEmailOtp(models.Model):
|
|||||||
"""otp details"""
|
"""otp details"""
|
||||||
otp = models.CharField(max_length=10)
|
otp = models.CharField(max_length=10)
|
||||||
is_verified = models.BooleanField(default=False)
|
is_verified = models.BooleanField(default=False)
|
||||||
|
user_type = models.CharField(max_length=15, choices=USER_TYPE, null=True, blank=True, default=None)
|
||||||
|
|
||||||
# OTP validity
|
# OTP validity
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
@ -69,7 +72,96 @@ 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'
|
||||||
|
verbose_name = 'Default Task images'
|
||||||
|
verbose_name_plural = 'Default Task images'
|
||||||
|
|
||||||
|
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'
|
||||||
|
verbose_name = 'Deleted User'
|
||||||
|
verbose_name_plural = 'Deleted User'
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
class UserDeviceDetails(models.Model):
|
||||||
|
"""
|
||||||
|
User notification details
|
||||||
|
"""
|
||||||
|
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user_device_details')
|
||||||
|
"""Device ID"""
|
||||||
|
device_id = models.CharField(max_length=500)
|
||||||
|
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
""" Meta information """
|
||||||
|
db_table = 'user_device_details'
|
||||||
|
verbose_name = 'User Device Details'
|
||||||
|
verbose_name_plural = 'User Device Details'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.user.email
|
||||||
|
|||||||
@ -1,17 +1,82 @@
|
|||||||
|
"""Account serializer"""
|
||||||
|
"""Django Import"""
|
||||||
|
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"""
|
||||||
|
# Import guardian's model,
|
||||||
|
# Import junior's model,
|
||||||
|
# Import account's model,
|
||||||
|
# Import constant from
|
||||||
|
# base package,
|
||||||
|
# Import messages from
|
||||||
|
# base package,
|
||||||
|
# Import some functions
|
||||||
|
# from utils file"""
|
||||||
|
|
||||||
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 delete_user_account_condition_social, delete_user_account_condition
|
||||||
from django.contrib.auth import authenticate
|
|
||||||
from rest_framework import viewsets, status
|
# In this serializer file
|
||||||
from rest_framework.decorators import action
|
# define google login serializer
|
||||||
from django.contrib.auth import authenticate, login
|
# update junior profile,
|
||||||
from rest_framework_simplejwt.tokens import RefreshToken
|
# update guardian profile,
|
||||||
|
# super admin serializer,
|
||||||
|
# reset password,
|
||||||
|
# forgot password,
|
||||||
|
# change password,
|
||||||
|
# basic junior serializer,
|
||||||
|
# basic guardian serializer,
|
||||||
|
# user delete account serializer,
|
||||||
|
# user notification serializer,
|
||||||
|
# update user notification serializer,
|
||||||
|
# default task's images serializer,
|
||||||
|
# upload default task's images serializer,
|
||||||
|
# email verification serializer,
|
||||||
|
# phone otp serializer
|
||||||
|
|
||||||
|
|
||||||
|
class GoogleLoginSerializer(serializers.Serializer):
|
||||||
|
"""google login serializer"""
|
||||||
|
access_token = serializers.CharField(max_length=5000, required=True)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
"""meta class"""
|
||||||
|
fields = ('access_token',)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateJuniorProfileImageSerializer(serializers.ModelSerializer):
|
||||||
|
"""update junior image"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = Junior
|
||||||
|
fields = ['id', '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
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateGuardianImageSerializer(serializers.ModelSerializer):
|
||||||
|
"""update guardian image"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = Guardian
|
||||||
|
fields = ['id','image']
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
"""update image """
|
||||||
|
instance.image = validated_data.get('image', instance.image)
|
||||||
|
instance.save()
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
class ResetPasswordSerializer(serializers.Serializer):
|
class ResetPasswordSerializer(serializers.Serializer):
|
||||||
@ -25,15 +90,12 @@ class ResetPasswordSerializer(serializers.Serializer):
|
|||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
verification_code = validated_data.pop('verification_code')
|
verification_code = validated_data.pop('verification_code')
|
||||||
password = validated_data.pop('password')
|
password = validated_data.pop('password')
|
||||||
print("verification_code===>",verification_code)
|
|
||||||
print("password===>", password)
|
|
||||||
user_opt_details = UserEmailOtp.objects.filter(otp=verification_code, is_verified=True).last()
|
user_opt_details = UserEmailOtp.objects.filter(otp=verification_code, is_verified=True).last()
|
||||||
print("user_opt_details===>",user_opt_details)
|
|
||||||
if user_opt_details:
|
if user_opt_details:
|
||||||
print("qqqqqqqqqq")
|
|
||||||
user_details = User.objects.filter(email=user_opt_details.email).last()
|
user_details = User.objects.filter(email=user_opt_details.email).last()
|
||||||
if user_details:
|
if user_details:
|
||||||
print("333333333==>",user_details.password)
|
if user_details.check_password(password):
|
||||||
|
raise serializers.ValidationError({"details":ERROR_CODE['2001'],"code":"400", "status":"failed"})
|
||||||
user_details.set_password(password)
|
user_details.set_password(password)
|
||||||
user_details.save()
|
user_details.save()
|
||||||
return {'password':password}
|
return {'password':password}
|
||||||
@ -50,16 +112,17 @@ 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":"Invalid Current password"})
|
raise serializers.ValidationError(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')
|
||||||
|
"""Check new password is different from current password"""
|
||||||
|
if new_password == current_password:
|
||||||
|
raise serializers.ValidationError({"details": ERROR_CODE['2026']})
|
||||||
user_details = User.objects.filter(email=self.context).last()
|
user_details = User.objects.filter(email=self.context).last()
|
||||||
print("user_details==>", user_details)
|
|
||||||
if user_details:
|
if user_details:
|
||||||
print("333333333==>",user_details.password)
|
|
||||||
user_details.set_password(new_password)
|
user_details.set_password(new_password)
|
||||||
user_details.save()
|
user_details.save()
|
||||||
return {'password':new_password}
|
return {'password':new_password}
|
||||||
@ -72,6 +135,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):
|
||||||
@ -91,15 +155,24 @@ class GuardianSerializer(serializers.ModelSerializer):
|
|||||||
first_name = serializers.SerializerMethodField('get_first_name')
|
first_name = serializers.SerializerMethodField('get_first_name')
|
||||||
last_name = serializers.SerializerMethodField('get_last_name')
|
last_name = serializers.SerializerMethodField('get_last_name')
|
||||||
auth_token = serializers.SerializerMethodField('get_auth_token')
|
auth_token = serializers.SerializerMethodField('get_auth_token')
|
||||||
|
refresh_token = serializers.SerializerMethodField('get_refresh_token')
|
||||||
|
|
||||||
def get_auth_token(self, obj):
|
def get_auth_token(self, obj):
|
||||||
refresh = RefreshToken.for_user(obj.user)
|
refresh = RefreshToken.for_user(obj.user)
|
||||||
access_token = str(refresh.access_token)
|
access_token = str(refresh.access_token)
|
||||||
return access_token
|
return access_token
|
||||||
|
|
||||||
|
def get_refresh_token(self, obj):
|
||||||
|
refresh = RefreshToken.for_user(obj.user)
|
||||||
|
refresh_token = str(refresh)
|
||||||
|
return refresh_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"""
|
||||||
@ -116,9 +189,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', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code',
|
||||||
'referral_code', 'is_active', 'is_complete_profile', 'passcode',
|
'phone', 'family_name', 'gender', 'dob', 'referral_code', 'is_active',
|
||||||
'created_at', 'updated_at', 'user_type']
|
'is_complete_profile', 'passcode', 'image', 'created_at', 'updated_at', 'user_type', 'country_name']
|
||||||
|
|
||||||
|
|
||||||
class JuniorSerializer(serializers.ModelSerializer):
|
class JuniorSerializer(serializers.ModelSerializer):
|
||||||
@ -128,14 +201,23 @@ class JuniorSerializer(serializers.ModelSerializer):
|
|||||||
first_name = serializers.SerializerMethodField('get_first_name')
|
first_name = serializers.SerializerMethodField('get_first_name')
|
||||||
last_name = serializers.SerializerMethodField('get_last_name')
|
last_name = serializers.SerializerMethodField('get_last_name')
|
||||||
auth_token = serializers.SerializerMethodField('get_auth_token')
|
auth_token = serializers.SerializerMethodField('get_auth_token')
|
||||||
|
refresh_token = serializers.SerializerMethodField('get_refresh_token')
|
||||||
|
|
||||||
def get_auth_token(self, obj):
|
def get_auth_token(self, obj):
|
||||||
refresh = RefreshToken.for_user(obj.auth)
|
refresh = RefreshToken.for_user(obj.auth)
|
||||||
access_token = str(refresh.access_token)
|
access_token = str(refresh.access_token)
|
||||||
return access_token
|
return access_token
|
||||||
|
|
||||||
|
def get_refresh_token(self, obj):
|
||||||
|
refresh = RefreshToken.for_user(obj.user)
|
||||||
|
refresh_token = str(refresh)
|
||||||
|
return refresh_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 is not 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
|
||||||
@ -149,9 +231,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', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code',
|
||||||
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at',
|
'phone', 'gender', 'dob', 'guardian_code', 'referral_code','is_active',
|
||||||
'updated_at', 'user_type']
|
'is_complete_profile', 'created_at', 'image', 'updated_at', 'user_type', 'country_name','is_invited']
|
||||||
|
|
||||||
class EmailVerificationSerializer(serializers.ModelSerializer):
|
class EmailVerificationSerializer(serializers.ModelSerializer):
|
||||||
"""Email verification serializer"""
|
"""Email verification serializer"""
|
||||||
@ -160,3 +242,80 @@ 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 = ['id', '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 = ['id','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']
|
||||||
|
signup_method = self.context['signup_method']
|
||||||
|
random_num = random.randint(0, 10000)
|
||||||
|
user_tb = User.objects.filter(id=user.id).last()
|
||||||
|
user_type_datas = UserEmailOtp.objects.filter(email=user.email).last()
|
||||||
|
if user_tb and user_tb.check_password(passwd) and signup_method == '1':
|
||||||
|
user_type_data = user_type_datas.user_type
|
||||||
|
instance = delete_user_account_condition(user, user_type_data, user_type, user_tb, data, random_num)
|
||||||
|
return instance
|
||||||
|
elif user_tb and passwd is None and signup_method in ['2','3']:
|
||||||
|
inst = delete_user_account_condition_social(user, user_type, user_tb, data, random_num)
|
||||||
|
return inst
|
||||||
|
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__'
|
||||||
|
|||||||
23
account/templates/templated_email/junior_approval_mail.email
Normal file
23
account/templates/templated_email/junior_approval_mail.email
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{% extends "templated_email/email_base.email" %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
Approval Email
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block plain %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 15px;">
|
||||||
|
<p style="margin: 0; font-size: 16px; line-height: 20px; padding: 36px 0 0; font-weight: 500; color: #1f2532;">
|
||||||
|
Hi {{full_name}},
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 22px;">
|
||||||
|
<p style="margin: 0;font-size: 14px; font-weight: 400; line-height: 21px; color: #1f2532;">
|
||||||
|
Please approve {{full_name}} for accessing the Zod bank platform as a junior.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endblock %}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
{% extends "templated_email/email_base.email" %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
Invitation Email
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block plain %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 15px;">
|
||||||
|
<p style="margin: 0; font-size: 16px; line-height: 20px; padding: 36px 0 0; font-weight: 500; color: #1f2532;">
|
||||||
|
Hi {{full_name}},
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 22px;">
|
||||||
|
<p style="margin: 0;font-size: 14px; font-weight: 400; line-height: 21px; color: #1f2532;">
|
||||||
|
You are receiving this email for join the ZOD bank platform. Please use <b>{{ url }} </b> link to join the platform.
|
||||||
|
<br> Your credentials are:- username = <b>{{email}}</b> and password <b>{{password}}</b><br> <br>Below are the steps to complete the account and how to use this platform.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endblock %}
|
||||||
22
account/templates/templated_email/support_mail.email
Normal file
22
account/templates/templated_email/support_mail.email
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{% extends "templated_email/email_base.email" %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
{{subject}}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block plain %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 15px;">
|
||||||
|
<p style="margin: 0; font-size: 16px; line-height: 20px; padding: 36px 0 0; font-weight: 500; color: #1f2532;">
|
||||||
|
Hi {{name}},
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 22px;">
|
||||||
|
<p style="margin: 0;font-size: 14px; font-weight: 400; line-height: 21px; color: #1f2532;">
|
||||||
|
<b>{{name}}</b> have some queries and need some support. Please support them by using their email address <b> {{sender}}</b>. <br> <br> <b>Queries are:- </b> <br> {{ message }}
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endblock %}
|
||||||
@ -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,25 +1,70 @@
|
|||||||
""" 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
|
||||||
|
# UserLogin views,
|
||||||
|
# SendPhoneOtp views,
|
||||||
|
# UserPhoneVerification views,
|
||||||
|
# UserEmailVerification views,
|
||||||
|
# ReSendEmailOtp views,
|
||||||
|
# ForgotPasswordAPIView views,
|
||||||
|
# ResetPasswordAPIView views,
|
||||||
|
# ChangePasswordAPIView views,
|
||||||
|
# UpdateProfileImage views,
|
||||||
|
# GoogleLoginViewSet views,
|
||||||
|
# SigninWithApple views,
|
||||||
|
# ProfileAPIViewSet views,
|
||||||
|
# UploadImageAPIViewSet views,
|
||||||
|
# DefaultImageAPIViewSet views,
|
||||||
|
# DeleteUserProfileAPIViewSet views,
|
||||||
|
# UserNotificationAPIViewSet views,
|
||||||
|
# UpdateUserNotificationAPIViewSet views,
|
||||||
|
# SendSupportEmail views,
|
||||||
|
# LogoutAPIView views,
|
||||||
|
# AccessTokenAPIView views"""
|
||||||
from .views import (UserLogin, SendPhoneOtp, UserPhoneVerification, UserEmailVerification, ReSendEmailOtp,
|
from .views import (UserLogin, SendPhoneOtp, UserPhoneVerification, UserEmailVerification, ReSendEmailOtp,
|
||||||
ForgotPasswordAPIView, ResetPasswordAPIView, ChangePasswordAPIView)
|
ForgotPasswordAPIView, ResetPasswordAPIView, ChangePasswordAPIView, UpdateProfileImage,
|
||||||
|
GoogleLoginViewSet, SigninWithApple, ProfileAPIViewSet, UploadImageAPIViewSet,
|
||||||
|
DefaultImageAPIViewSet, DeleteUserProfileAPIViewSet, UserNotificationAPIViewSet,
|
||||||
|
UpdateUserNotificationAPIViewSet, SendSupportEmail, LogoutAPIView, AccessTokenAPIView)
|
||||||
"""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')
|
||||||
|
"""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/apple-login/', SigninWithApple.as_view(), name='signup_with_apple'),
|
||||||
|
path('api/v1/send-support-email/', SendSupportEmail.as_view(), name='send-support-email'),
|
||||||
|
path('api/v1/logout/', LogoutAPIView.as_view(), name='logout'),
|
||||||
|
path('api/v1/generate-token/', AccessTokenAPIView.as_view(), name='generate-token')
|
||||||
]
|
]
|
||||||
|
|||||||
195
account/utils.py
195
account/utils.py
@ -1,13 +1,111 @@
|
|||||||
"""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
|
||||||
|
import string
|
||||||
|
from datetime import datetime
|
||||||
|
from calendar import timegm
|
||||||
|
from uuid import uuid4
|
||||||
|
import secrets
|
||||||
|
from rest_framework import serializers
|
||||||
|
# Django App Import
|
||||||
|
# Import models from junior App,
|
||||||
|
# Import models from guardian App,
|
||||||
|
# Import models from account App,
|
||||||
|
# Import messages from base package"""
|
||||||
|
from junior.models import Junior
|
||||||
|
from guardian.models import Guardian
|
||||||
|
from account.models import UserDelete
|
||||||
|
from base.messages import ERROR_CODE
|
||||||
|
|
||||||
|
|
||||||
|
# Define delete
|
||||||
|
# user account condition,
|
||||||
|
# Define delete
|
||||||
|
# user account
|
||||||
|
# condition for social
|
||||||
|
# login account,
|
||||||
|
# Update junior account,
|
||||||
|
# Update guardian account,
|
||||||
|
# Define custom email for otp verification,
|
||||||
|
# Define support email for user's query,
|
||||||
|
# Define custom success response,
|
||||||
|
# Define custom error response,
|
||||||
|
# Generate access token,
|
||||||
|
# refresh token by using jwt,
|
||||||
|
# Define function for generating
|
||||||
|
# guardian code, junior code,
|
||||||
|
# referral code,
|
||||||
|
# Define function for generating
|
||||||
|
# alphanumeric code
|
||||||
|
|
||||||
|
def delete_user_account_condition(user, user_type_data, user_type, user_tb, data, random_num):
|
||||||
|
"""delete user account"""
|
||||||
|
if user_type == '1' and user_type_data == '1':
|
||||||
|
junior_account_update(user_tb)
|
||||||
|
elif user_type == '2' and user_type_data == '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()
|
||||||
|
d_email = user_tb.email
|
||||||
|
o_mail = user.email
|
||||||
|
user_tb.save()
|
||||||
|
"""create object in user delete model"""
|
||||||
|
instance = UserDelete.objects.create(user=user_tb, d_email=d_email, old_email=o_mail,
|
||||||
|
is_active=True, reason=data)
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
def delete_user_account_condition_social(user, user_type,user_tb, data, random_num):
|
||||||
|
"""delete user account"""
|
||||||
|
if user_type == '1':
|
||||||
|
junior_account_update(user_tb)
|
||||||
|
elif 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()
|
||||||
|
dummy_email = user_tb.email
|
||||||
|
old_mail = user.email
|
||||||
|
user_tb.save()
|
||||||
|
"""create object in user delete model"""
|
||||||
|
instance_data = UserDelete.objects.create(user=user_tb, d_email=dummy_email, old_email=old_mail,
|
||||||
|
is_active=True, reason=data)
|
||||||
|
|
||||||
|
return instance_data
|
||||||
|
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))
|
||||||
|
"""Disassociate relation between guardian and junior"""
|
||||||
|
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):
|
||||||
from_email = settings.EMAIL_HOST_USER
|
"""Send otp on email with template"""
|
||||||
|
from_email = settings.EMAIL_FROM_ADDRESS
|
||||||
recipient_list = [recipient_email]
|
recipient_list = [recipient_email]
|
||||||
|
"""Send otp on email"""
|
||||||
send_templated_mail(
|
send_templated_mail(
|
||||||
template_name='email_otp_verification.email',
|
template_name='email_otp_verification.email',
|
||||||
from_email=from_email,
|
from_email=from_email,
|
||||||
@ -18,11 +116,28 @@ def send_otp_email(recipient_email, otp):
|
|||||||
)
|
)
|
||||||
return otp
|
return otp
|
||||||
|
|
||||||
|
def send_support_email(name, sender, subject, message):
|
||||||
|
"""Send otp on email with template"""
|
||||||
|
to_email = [settings.EMAIL_FROM_ADDRESS]
|
||||||
|
from_email = settings.DEFAULT_ADDRESS
|
||||||
|
"""Send support email to zod bank support team"""
|
||||||
|
send_templated_mail(
|
||||||
|
template_name='support_mail.email',
|
||||||
|
from_email=from_email,
|
||||||
|
recipient_list=to_email,
|
||||||
|
context={
|
||||||
|
'name': name.title(),
|
||||||
|
'sender': sender,
|
||||||
|
'subject': subject,
|
||||||
|
'message': message
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return name
|
||||||
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 +149,77 @@ 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def generate_alphanumeric_code(length):
|
||||||
|
"""Generate alphanumeric code"""
|
||||||
|
alphabet = string.ascii_letters + string.digits
|
||||||
|
code = ''.join(secrets.choice(alphabet) for _ in range(length))
|
||||||
|
return code
|
||||||
|
|
||||||
|
|
||||||
|
def generate_code(value, user_id):
|
||||||
|
"""generate referral, junior and guardian code"""
|
||||||
|
code = value + str(user_id).zfill(3)
|
||||||
|
return code
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
407
account/views.py
407
account/views.py
@ -1,28 +1,191 @@
|
|||||||
|
"""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
|
||||||
|
from django.contrib.auth import logout
|
||||||
from django.contrib.auth import authenticate, login
|
from django.contrib.auth import authenticate, login
|
||||||
from guardian.models import Guardian
|
|
||||||
from junior.models import Junior
|
|
||||||
from account.models import UserProfile, UserPhoneOtp, UserEmailOtp
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from .serializers import (SuperUserSerializer, GuardianSerializer, JuniorSerializer, EmailVerificationSerializer,
|
|
||||||
ForgotPasswordSerializer, ResetPasswordSerializer, ChangePasswordSerializer)
|
|
||||||
from rest_framework_simplejwt.tokens import RefreshToken
|
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
|
||||||
from guardian.tasks import generate_otp
|
|
||||||
from django.conf import settings
|
|
||||||
from account.utils import send_otp_email
|
|
||||||
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
|
||||||
|
import requests
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from django.conf import settings
|
||||||
|
"""App Import"""
|
||||||
|
from guardian.models import Guardian
|
||||||
|
from junior.models import Junior
|
||||||
|
from guardian.utils import upload_image_to_alibaba
|
||||||
|
from account.models import UserDeviceDetails, UserPhoneOtp, UserEmailOtp, DefaultTaskImages, UserNotification
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
"""Account serializer"""
|
||||||
|
from .serializers import (SuperUserSerializer, GuardianSerializer, JuniorSerializer, EmailVerificationSerializer,
|
||||||
|
ForgotPasswordSerializer, ResetPasswordSerializer, ChangePasswordSerializer,
|
||||||
|
GoogleLoginSerializer, UpdateGuardianImageSerializer, UpdateJuniorProfileImageSerializer,
|
||||||
|
DefaultTaskImagesSerializer, DefaultTaskImagesDetailsSerializer, UserDeleteSerializer,
|
||||||
|
UserNotificationSerializer, UpdateUserNotificationSerializer, UserPhoneOtpSerializer)
|
||||||
|
from rest_framework_simplejwt.tokens import RefreshToken
|
||||||
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
|
from base.constants import NUMBER, ZOD, JUN, GRD
|
||||||
|
from guardian.tasks import generate_otp
|
||||||
|
from account.utils import (send_otp_email, send_support_email, custom_response, custom_error_response,
|
||||||
|
generate_code)
|
||||||
|
from junior.serializers import JuniorProfileSerializer
|
||||||
|
from guardian.serializers import GuardianProfileSerializer
|
||||||
|
|
||||||
|
class GoogleLoginMixin:
|
||||||
|
"""google login mixin"""
|
||||||
|
@staticmethod
|
||||||
|
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, signup_method='2',
|
||||||
|
junior_code=generate_code(JUN, user_obj.id),
|
||||||
|
referral_code=generate_code(ZOD, user_obj.id)
|
||||||
|
)
|
||||||
|
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,signup_method='2',
|
||||||
|
guardian_code=generate_code(GRD, user_obj.id),
|
||||||
|
referral_code=generate_code(ZOD, user_obj.id)
|
||||||
|
)
|
||||||
|
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):
|
||||||
|
"""Google login viewset"""
|
||||||
|
serializer_class = GoogleLoginSerializer
|
||||||
|
|
||||||
|
def create(self, request):
|
||||||
|
"""create method"""
|
||||||
|
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,
|
||||||
|
signup_method='3',
|
||||||
|
junior_code=generate_code(JUN, user.id),
|
||||||
|
referral_code=generate_code(ZOD, user.id))
|
||||||
|
serializer = JuniorSerializer(junior_query)
|
||||||
|
if str(user_type) == '2':
|
||||||
|
guardian_query = Guardian.objects.create(user=user, is_verified=True, is_active=True,
|
||||||
|
signup_method='3',
|
||||||
|
guardian_code=generate_code(GRD, user.id),
|
||||||
|
referral_code=generate_code(ZOD, user.id))
|
||||||
|
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 UpdateProfileImage(views.APIView):
|
||||||
|
"""Update profile image"""
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
def put(self, request, format=None):
|
||||||
|
try:
|
||||||
|
image = request.data['image']
|
||||||
|
if image and image.size == NUMBER['zero']:
|
||||||
|
return custom_error_response(ERROR_CODE['2035'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
filename = f"images/{image.name}"
|
||||||
|
image_url = upload_image_to_alibaba(image, filename)
|
||||||
|
image_data = image_url
|
||||||
|
if str(request.data['user_type']) == '1':
|
||||||
|
junior_query = Junior.objects.filter(auth=request.user).last()
|
||||||
|
serializer = UpdateJuniorProfileImageSerializer(junior_query,
|
||||||
|
data={'image':image_data}, partial=True)
|
||||||
|
elif str(request.data['user_type']) == '2':
|
||||||
|
guardian_query = Guardian.objects.filter(user=request.user).last()
|
||||||
|
serializer = UpdateGuardianImageSerializer(guardian_query,
|
||||||
|
data={'image':image_data}, partial=True)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
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)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(e)
|
||||||
|
return custom_error_response(ERROR_CODE['2036'],response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
class ChangePasswordAPIView(views.APIView):
|
class ChangePasswordAPIView(views.APIView):
|
||||||
|
"""change password"""
|
||||||
|
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)
|
||||||
@ -32,6 +195,7 @@ class ChangePasswordAPIView(views.APIView):
|
|||||||
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 ResetPasswordAPIView(views.APIView):
|
class ResetPasswordAPIView(views.APIView):
|
||||||
|
"""Reset password"""
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
serializer = ResetPasswordSerializer(data=request.data)
|
serializer = ResetPasswordSerializer(data=request.data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
@ -40,6 +204,8 @@ class ResetPasswordAPIView(views.APIView):
|
|||||||
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 ForgotPasswordAPIView(views.APIView):
|
class ForgotPasswordAPIView(views.APIView):
|
||||||
|
"""Forgot password"""
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
serializer = ForgotPasswordSerializer(data=request.data)
|
serializer = ForgotPasswordSerializer(data=request.data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
@ -50,7 +216,7 @@ class ForgotPasswordAPIView(views.APIView):
|
|||||||
return custom_error_response(ERROR_CODE['2004'], response_status=status.HTTP_404_NOT_FOUND)
|
return custom_error_response(ERROR_CODE['2004'], response_status=status.HTTP_404_NOT_FOUND)
|
||||||
verification_code = ''.join([str(random.randrange(9)) for _ in range(6)])
|
verification_code = ''.join([str(random.randrange(9)) for _ in range(6)])
|
||||||
# Send the verification code to the user's email
|
# Send the verification code to the user's email
|
||||||
from_email = settings.EMAIL_HOST_USER
|
from_email = settings.EMAIL_FROM_ADDRESS
|
||||||
recipient_list = [email]
|
recipient_list = [email]
|
||||||
send_templated_mail(
|
send_templated_mail(
|
||||||
template_name='email_reset_verification.email',
|
template_name='email_reset_verification.email',
|
||||||
@ -60,9 +226,14 @@ 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)
|
||||||
@ -70,6 +241,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']
|
||||||
@ -85,6 +258,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'),
|
||||||
@ -101,31 +276,38 @@ class UserPhoneVerification(viewsets.ModelViewSet):
|
|||||||
|
|
||||||
|
|
||||||
class UserLogin(viewsets.ViewSet):
|
class UserLogin(viewsets.ViewSet):
|
||||||
|
"""User login"""
|
||||||
@action(methods=['post'], detail=False)
|
@action(methods=['post'], detail=False)
|
||||||
def login(self, request):
|
def login(self, request):
|
||||||
username = request.data.get('username')
|
username = request.data.get('username')
|
||||||
password = request.data.get('password')
|
password = request.data.get('password')
|
||||||
|
device_id = request.META.get('HTTP_DEVICE_ID')
|
||||||
user = authenticate(request, username=username, password=password)
|
user = authenticate(request, username=username, password=password)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if user is not None:
|
if user is not None:
|
||||||
login(request, user)
|
login(request, user)
|
||||||
guardian_data = Guardian.objects.filter(user__username=username, is_complete_profile=True).last()
|
guardian_data = Guardian.objects.filter(user__username=username, is_verified=True).last()
|
||||||
if guardian_data:
|
if guardian_data:
|
||||||
serializer = GuardianSerializer(guardian_data)
|
serializer = GuardianSerializer(guardian_data).data
|
||||||
junior_data = Junior.objects.filter(auth__username=username, is_complete_profile=True).last()
|
junior_data = Junior.objects.filter(auth__username=username, is_verified=True).last()
|
||||||
if junior_data:
|
if junior_data:
|
||||||
serializer = JuniorSerializer(junior_data)
|
serializer = JuniorSerializer(junior_data).data
|
||||||
return custom_response(SUCCESS_CODE['3003'], serializer.data, response_status=status.HTTP_200_OK)
|
device_details, created = UserDeviceDetails.objects.get_or_create(user=user)
|
||||||
|
if device_details:
|
||||||
|
device_details.device_id = device_id
|
||||||
|
device_details.save()
|
||||||
|
return custom_response(SUCCESS_CODE['3003'], serializer, response_status=status.HTTP_200_OK)
|
||||||
else:
|
else:
|
||||||
return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_401_UNAUTHORIZED)
|
return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_401_UNAUTHORIZED)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(e)
|
logging.error(e)
|
||||||
user_profile_data = UserProfile.objects.filter(user__username=username).last()
|
|
||||||
email_verified = UserEmailOtp.objects.filter(email=username).last()
|
email_verified = UserEmailOtp.objects.filter(email=username).last()
|
||||||
refresh = RefreshToken.for_user(user)
|
refresh = RefreshToken.for_user(user)
|
||||||
access_token = str(refresh.access_token)
|
access_token = str(refresh.access_token)
|
||||||
data = {"auth_token":access_token, "is_profile_complete": False,
|
refresh_token = str(refresh)
|
||||||
"user_role": user_profile_data.user_type,
|
data = {"auth_token":access_token, "refresh_token":refresh_token, "is_profile_complete": False,
|
||||||
|
"user_type": email_verified.user_type,
|
||||||
}
|
}
|
||||||
is_verified = False
|
is_verified = False
|
||||||
if email_verified:
|
if email_verified:
|
||||||
@ -135,6 +317,7 @@ class UserLogin(viewsets.ViewSet):
|
|||||||
email_verified.otp = otp
|
email_verified.otp = otp
|
||||||
email_verified.save()
|
email_verified.save()
|
||||||
data.update({"email_otp":otp})
|
data.update({"email_otp":otp})
|
||||||
|
send_otp_email(username, otp)
|
||||||
return custom_response(ERROR_CODE['2024'], {"email_otp": otp, "is_email_verified": is_verified},
|
return custom_response(ERROR_CODE['2024'], {"email_otp": otp, "is_email_verified": is_verified},
|
||||||
response_status=status.HTTP_200_OK)
|
response_status=status.HTTP_200_OK)
|
||||||
data.update({"is_email_verified": is_verified})
|
data.update({"is_email_verified": is_verified})
|
||||||
@ -157,12 +340,14 @@ class UserLogin(viewsets.ViewSet):
|
|||||||
logging.error(e)
|
logging.error(e)
|
||||||
refresh = RefreshToken.for_user(user)
|
refresh = RefreshToken.for_user(user)
|
||||||
access_token = str(refresh.access_token)
|
access_token = str(refresh.access_token)
|
||||||
data = {"auth_token": access_token, "user_role": '3'}
|
refresh_token = str(refresh)
|
||||||
|
data = {"auth_token": access_token, "refresh_token":refresh_token, "user_type": '3'}
|
||||||
return custom_response(None, data, response_status=status.HTTP_200_OK)
|
return custom_response(None, data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
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:
|
||||||
@ -170,11 +355,33 @@ 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':
|
||||||
|
junior_data = Junior.objects.filter(auth__email=self.request.GET.get('email')).last()
|
||||||
|
if junior_data:
|
||||||
|
junior_data.is_verified = True
|
||||||
|
junior_data.save()
|
||||||
|
else:
|
||||||
|
guardian_data = Guardian.objects.filter(user__email=self.request.GET.get('email')).last()
|
||||||
|
if guardian_data:
|
||||||
|
guardian_data.is_verified = True
|
||||||
|
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)
|
refresh_token = str(refresh)
|
||||||
|
return custom_response(SUCCESS_CODE['3011'], {"auth_token":access_token,
|
||||||
|
"refresh_token":refresh_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:
|
||||||
@ -183,14 +390,162 @@ 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
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
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
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
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)
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
elif 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}"
|
||||||
|
if image_data.size == NUMBER['zero']:
|
||||||
|
return custom_error_response(ERROR_CODE['2035'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
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
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
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.get('password')
|
||||||
|
signup_method = str(request.data.get('signup_method'))
|
||||||
|
serializer = self.get_serializer(data=request.data, context={'request': request, 'user': request.user,
|
||||||
|
'user_type': user_type,
|
||||||
|
'password': password,
|
||||||
|
'signup_method':signup_method})
|
||||||
|
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
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
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
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
class SendSupportEmail(views.APIView):
|
||||||
|
"""support email api"""
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
name = request.data.get('name')
|
||||||
|
sender = request.data.get('email')
|
||||||
|
subject = request.data.get('subject')
|
||||||
|
message = request.data.get('message')
|
||||||
|
if name and sender and subject and message:
|
||||||
|
try:
|
||||||
|
send_support_email(name, sender, subject, message)
|
||||||
|
return custom_response(SUCCESS_CODE['3019'], response_status=status.HTTP_200_OK)
|
||||||
|
except Exception as e:
|
||||||
|
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
else:
|
||||||
|
return custom_error_response(ERROR_CODE['2033'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
class LogoutAPIView(views.APIView):
|
||||||
|
"""Log out API"""
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
logout(request)
|
||||||
|
request.session.flush()
|
||||||
|
return custom_response(SUCCESS_CODE['3020'], response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class AccessTokenAPIView(views.APIView):
|
||||||
|
"""generate access token API"""
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
# Assuming you have a refresh_token string
|
||||||
|
refresh_token = request.data['refresh_token']
|
||||||
|
# Create a RefreshToken instance from the refresh token string
|
||||||
|
refresh = RefreshToken(refresh_token)
|
||||||
|
# Generate a new access token
|
||||||
|
access_token = str(refresh.access_token)
|
||||||
|
data = {"auth_token": access_token}
|
||||||
|
return custom_response(None, data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,49 @@ import os
|
|||||||
# GOOGLE_URL used for interact with google server to verify user existence.
|
# GOOGLE_URL used for interact with google server to verify user existence.
|
||||||
#GOOGLE_URL = "https://www.googleapis.com/plus/v1/"
|
#GOOGLE_URL = "https://www.googleapis.com/plus/v1/"
|
||||||
|
|
||||||
|
# Define Code prefix word
|
||||||
|
# for guardian code,
|
||||||
|
# junior code,
|
||||||
|
# referral code"""
|
||||||
|
ZOD = 'ZOD'
|
||||||
|
JUN = 'JUN'
|
||||||
|
GRD = 'GRD'
|
||||||
|
# Define number variable
|
||||||
|
# from zero to
|
||||||
|
# twenty and
|
||||||
|
# some standard
|
||||||
|
# number"""
|
||||||
|
NUMBER = {
|
||||||
|
'point_zero': 0.0, 'zero': 0, 'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7,
|
||||||
|
'eight': 8, 'nine': 9, 'ten': 10, 'eleven': 11, 'twelve': 12, 'thirteen': 13, 'fourteen': 14, 'fifteen': 15,
|
||||||
|
'sixteen': 16, 'seventeen': 17, 'eighteen': 18, 'nineteen': 19,
|
||||||
|
'twenty_four': 24,
|
||||||
|
'twenty_one': 21,
|
||||||
|
'twenty_two': 22,
|
||||||
|
'twenty_five': 25,
|
||||||
|
'thirty': 30,
|
||||||
|
'thirty_five': 35,
|
||||||
|
'thirty_six': 36,
|
||||||
|
'forty': 40,
|
||||||
|
'fifty': 50,
|
||||||
|
'fifty_nine': 59,
|
||||||
|
'sixty': 60,
|
||||||
|
'seventy_five': 75,
|
||||||
|
'eighty': 80,
|
||||||
|
'ninty_five': 95,
|
||||||
|
'ninty_six': 96,
|
||||||
|
'ninety_nine': 99,
|
||||||
|
'hundred': 100,
|
||||||
|
'one_one_nine': 119,
|
||||||
|
'one_twenty': 120,
|
||||||
|
'four_zero_four': 404,
|
||||||
|
'five_hundred': 500,
|
||||||
|
'minus_one': -1,
|
||||||
|
'point_three': 0.3,
|
||||||
|
'point_seven': 0.7
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Super Admin string constant for 'role'
|
# Super Admin string constant for 'role'
|
||||||
SUPER_ADMIN = "Super Admin"
|
SUPER_ADMIN = "Super Admin"
|
||||||
@ -26,15 +69,45 @@ sort_dict = {
|
|||||||
'1': 'name',
|
'1': 'name',
|
||||||
'2': '-name'
|
'2': '-name'
|
||||||
}
|
}
|
||||||
|
"""user type"""
|
||||||
USER_TYPE = (
|
USER_TYPE = (
|
||||||
('1', 'junior'),
|
('1', 'junior'),
|
||||||
('2', 'guardian'),
|
('2', 'guardian'),
|
||||||
('3', 'superuser')
|
('3', 'superuser')
|
||||||
)
|
)
|
||||||
|
"""gender"""
|
||||||
GENDERS = (
|
GENDERS = (
|
||||||
('1', 'Male'),
|
('1', 'Male'),
|
||||||
('2', 'Female')
|
('2', 'Female')
|
||||||
)
|
)
|
||||||
|
"""Task status"""
|
||||||
|
TASK_STATUS = (
|
||||||
|
('1', 'pending'),
|
||||||
|
('2', 'in-progress'),
|
||||||
|
('3', 'rejected'),
|
||||||
|
('4', 'requested'),
|
||||||
|
('5', 'completed')
|
||||||
|
)
|
||||||
|
"""sign up method"""
|
||||||
|
SIGNUP_METHODS = (
|
||||||
|
('1', 'manual'),
|
||||||
|
('2', 'google'),
|
||||||
|
('3', 'apple')
|
||||||
|
)
|
||||||
|
"""relationship"""
|
||||||
|
RELATIONSHIP = (
|
||||||
|
('1', 'parent'),
|
||||||
|
('2', 'legal_guardian')
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
Define task status
|
||||||
|
in a number"""
|
||||||
|
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'
|
||||||
@ -47,5 +120,3 @@ BYTE_IMAGE_SIZE = 1024
|
|||||||
|
|
||||||
# validate file size
|
# validate file size
|
||||||
MAX_FILE_SIZE = 1024 * 1024 * 5
|
MAX_FILE_SIZE = 1024 * 1024 * 5
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ ERROR_CODE_REQUIRED = {
|
|||||||
# Error code
|
# Error code
|
||||||
ERROR_CODE = {
|
ERROR_CODE = {
|
||||||
"2000": "Email not found.",
|
"2000": "Email not found.",
|
||||||
"2001": "Your account has not been verified. Please check your email and verify it.",
|
"2001": "This is your existing password. Please choose other one",
|
||||||
"2002": "Invalid login credentials.",
|
"2002": "Invalid login credentials.",
|
||||||
"2003": "An account already exists with this email address.",
|
"2003": "An account already exists with this email address.",
|
||||||
"2004": "User not found.",
|
"2004": "User not found.",
|
||||||
@ -35,7 +35,7 @@ ERROR_CODE = {
|
|||||||
"2009": "The user provided cannot be found or the reset password token has become invalid/timed out.",
|
"2009": "The user provided cannot be found or the reset password token has become invalid/timed out.",
|
||||||
"2010": "Invalid Link.",
|
"2010": "Invalid Link.",
|
||||||
"2011": "Your profile has not been completed yet.",
|
"2011": "Your profile has not been completed yet.",
|
||||||
"2012": "Password and Confirm password should be same.",
|
"2012": "Phone number already used",
|
||||||
"2013": "Invalid token.",
|
"2013": "Invalid token.",
|
||||||
"2014": "Your old password doesn't match.",
|
"2014": "Your old password doesn't match.",
|
||||||
"2015": "Invalid old password.",
|
"2015": "Invalid old password.",
|
||||||
@ -47,19 +47,35 @@ ERROR_CODE = {
|
|||||||
"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.",
|
||||||
|
"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",
|
||||||
|
"2032": "Failed to send email",
|
||||||
|
"2033": "Missing required fields",
|
||||||
|
"2034": "Junior is not associated",
|
||||||
|
# image size
|
||||||
|
"2035": "Image should not be 0 kb",
|
||||||
|
"2036": "Choose valid user",
|
||||||
|
# log in multiple device msg
|
||||||
|
"2037": "You are already log in another device"
|
||||||
}
|
}
|
||||||
|
"""Success message code"""
|
||||||
SUCCESS_CODE = {
|
SUCCESS_CODE = {
|
||||||
# Success code for password
|
# Success code for password
|
||||||
"3001": "Sign up successfully",
|
"3001": "Sign up successfully",
|
||||||
# Success code for Thank you
|
# Success code for Thank you
|
||||||
"3002": "Thank you for contacting us! Our Consumer Experience Team will reach out to you shortly.",
|
"3002": "Thank you for contacting us! Our Consumer Experience Team will reach out to you shortly.",
|
||||||
# Success code for account activation
|
# Success code for account activation
|
||||||
"3003": "Log in successfully",
|
"3003": "Log in successful",
|
||||||
# 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
|
||||||
@ -75,9 +91,17 @@ SUCCESS_CODE = {
|
|||||||
"3013": "Valid Guardian code",
|
"3013": "Valid Guardian 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",
|
||||||
|
"3018": "Task created successfully",
|
||||||
|
"3019": "Support Email sent successfully",
|
||||||
|
"3020": "Logged out successfully.",
|
||||||
|
"3021": "Add junior successfully",
|
||||||
|
"3022": "Remove junior successfully",
|
||||||
|
"3023": "Approved junior successfully",
|
||||||
|
"3024": "Reject junior request successfully"
|
||||||
}
|
}
|
||||||
|
"""status code error"""
|
||||||
STATUS_CODE_ERROR = {
|
STATUS_CODE_ERROR = {
|
||||||
# Status code for Invalid Input
|
# Status code for Invalid Input
|
||||||
"4001": ["Invalid input."],
|
"4001": ["Invalid input."],
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
18
guardian/migrations/0003_guardian_country_name.py
Normal file
18
guardian/migrations/0003_guardian_country_name.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-27 13:59
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0002_remove_guardian_junior_code'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='guardian',
|
||||||
|
name='country_name',
|
||||||
|
field=models.CharField(blank=True, default=None, max_length=30, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
guardian/migrations/0004_guardian_image.py
Normal file
18
guardian/migrations/0004_guardian_image.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-28 06:52
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0003_guardian_country_name'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='guardian',
|
||||||
|
name='image',
|
||||||
|
field=models.ImageField(blank=True, default=None, null=True, upload_to='images/'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
guardian/migrations/0005_alter_guardian_image.py
Normal file
18
guardian/migrations/0005_alter_guardian_image.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-29 06:14
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0004_guardian_image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='guardian',
|
||||||
|
name='image',
|
||||||
|
field=models.ImageField(blank=True, default=None, null=True, upload_to=''),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
guardian/migrations/0006_guardian_is_verified.py
Normal file
18
guardian/migrations/0006_guardian_is_verified.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-29 12:10
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0005_alter_guardian_image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='guardian',
|
||||||
|
name='is_verified',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
guardian/migrations/0007_alter_guardian_country_name.py
Normal file
18
guardian/migrations/0007_alter_guardian_country_name.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-30 10:53
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0006_guardian_is_verified'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='guardian',
|
||||||
|
name='country_name',
|
||||||
|
field=models.CharField(blank=True, default=None, max_length=100, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
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),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
guardian/migrations/0014_guardian_signup_method.py
Normal file
18
guardian/migrations/0014_guardian_signup_method.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-11 11:26
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0013_alter_guardian_image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='guardian',
|
||||||
|
name='signup_method',
|
||||||
|
field=models.CharField(choices=[('1', 'manual'), ('2', 'google'), ('3', 'apple')], default='1', max_length=31),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-14 09:34
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0014_guardian_signup_method'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='guardian',
|
||||||
|
options={'verbose_name': 'Guardian', 'verbose_name_plural': 'Guardian'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='juniortask',
|
||||||
|
options={'verbose_name': 'Junior Task', 'verbose_name_plural': 'Junior Task'},
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -3,7 +3,10 @@
|
|||||||
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, SIGNUP_METHODS
|
||||||
|
"""import Junior model"""
|
||||||
|
from junior.models import Junior
|
||||||
|
"""Add user model"""
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
||||||
@ -13,18 +16,32 @@ class Guardian(models.Model):
|
|||||||
"""Contact details"""
|
"""Contact details"""
|
||||||
country_code = models.IntegerField(blank=True, null=True)
|
country_code = models.IntegerField(blank=True, null=True)
|
||||||
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 of the guardian"""
|
||||||
|
country_name = models.CharField(max_length=100, null=True, blank=True, default=None)
|
||||||
|
"""Image info"""
|
||||||
|
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 of the guardian"""
|
||||||
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)
|
||||||
|
"""date of birth of the guardian"""
|
||||||
dob = models.DateField(max_length=15, null=True, blank=True, default=None)
|
dob = models.DateField(max_length=15, null=True, blank=True, default=None)
|
||||||
"""Codes"""
|
|
||||||
guardian_code = models.CharField(max_length=10, null=True, blank=True, default=None)
|
|
||||||
referral_code = models.CharField(max_length=10, null=True, blank=True, default=None)
|
|
||||||
referral_code_used = models.CharField(max_length=10, null=True, blank=True, default=None)
|
|
||||||
"""Profile activity"""
|
"""Profile activity"""
|
||||||
is_active = models.BooleanField(default=True)
|
is_active = models.BooleanField(default=True)
|
||||||
|
"""guardian is verified or not"""
|
||||||
|
is_verified = models.BooleanField(default=False)
|
||||||
|
"""guardian profile is complete or not"""
|
||||||
is_complete_profile = models.BooleanField(default=False)
|
is_complete_profile = models.BooleanField(default=False)
|
||||||
|
"""passcode of the guardian profile"""
|
||||||
passcode = models.IntegerField(null=True, blank=True, default=None)
|
passcode = models.IntegerField(null=True, blank=True, default=None)
|
||||||
|
"""Sign up method"""
|
||||||
|
signup_method = models.CharField(max_length=31, choices=SIGNUP_METHODS, default='1')
|
||||||
|
"""Guardian Codes"""
|
||||||
|
guardian_code = models.CharField(max_length=10, null=True, blank=True, default=None)
|
||||||
|
"""Referral code"""
|
||||||
|
referral_code = models.CharField(max_length=10, null=True, blank=True, default=None)
|
||||||
|
"""Referral code that is used by guardian while signup"""
|
||||||
|
referral_code_used = models.CharField(max_length=10, null=True, blank=True, default=None)
|
||||||
"""Profile created and updated time"""
|
"""Profile created and updated time"""
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
@ -32,8 +49,51 @@ class Guardian(models.Model):
|
|||||||
class Meta(object):
|
class Meta(object):
|
||||||
""" Meta class """
|
""" Meta class """
|
||||||
db_table = 'guardians'
|
db_table = 'guardians'
|
||||||
|
"""verbose name of the model"""
|
||||||
verbose_name = 'Guardian'
|
verbose_name = 'Guardian'
|
||||||
|
"""change another name"""
|
||||||
|
verbose_name_plural = 'Guardian'
|
||||||
|
|
||||||
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"""
|
||||||
|
task_description = models.CharField(max_length=500)
|
||||||
|
"""points of the task"""
|
||||||
|
points = models.IntegerField(default=TASK_POINTS)
|
||||||
|
"""last date of the task"""
|
||||||
|
due_date = models.DateField(auto_now_add=False, null=True, blank=True)
|
||||||
|
"""Images of task that is upload by guardian"""
|
||||||
|
default_image = models.URLField(null=True, blank=True, default=None)
|
||||||
|
"""image that is uploaded by junior"""
|
||||||
|
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 is active or not"""
|
||||||
|
is_active = models.BooleanField(default=True)
|
||||||
|
"""Task is approved or not"""
|
||||||
|
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 of the model"""
|
||||||
|
verbose_name = 'Junior Task'
|
||||||
|
verbose_name_plural = 'Junior Task'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return email id"""
|
||||||
|
return f'{self.task_name}'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -7,9 +7,14 @@ 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
|
from account.models import UserProfile, UserEmailOtp, UserNotification
|
||||||
|
from account.utils import generate_code
|
||||||
|
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 base.constants import NUMBER, JUN, ZOD, GRD
|
||||||
|
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')
|
||||||
@ -17,7 +22,7 @@ class UserSerializer(serializers.ModelSerializer):
|
|||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
model = User
|
model = User
|
||||||
fields = ['email', 'password', 'auth_token']
|
fields = ['id', 'email', 'password', 'auth_token']
|
||||||
|
|
||||||
def get_auth_token(self, obj):
|
def get_auth_token(self, obj):
|
||||||
"""generate auth token"""
|
"""generate auth token"""
|
||||||
@ -32,18 +37,24 @@ 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':
|
||||||
|
Junior.objects.create(auth=user, junior_code=generate_code(JUN, user.id),
|
||||||
|
referral_code=generate_code(ZOD, user.id))
|
||||||
|
if user_type == '2':
|
||||||
|
Guardian.objects.create(user=user, guardian_code=generate_code(GRD, user.id),
|
||||||
|
referral_code=generate_code(ZOD, user.id))
|
||||||
return user
|
return user
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
"""Error handling"""
|
"""Error handling"""
|
||||||
logging.error(e)
|
logging.error(e)
|
||||||
raise serializers.ValidationError({"details":ERROR_CODE['2021']})
|
otp = UserEmailOtp.objects.filter(email=email).last()
|
||||||
|
otp_verified = False
|
||||||
def save(self, **kwargs):
|
if otp and otp.is_verified:
|
||||||
"""save the data"""
|
otp_verified = True
|
||||||
with transaction.atomic():
|
raise serializers.ValidationError({"details":ERROR_CODE['2021'], "otp_verified":bool(otp_verified),
|
||||||
instance = super().save(**kwargs)
|
"code": 400, "status":"failed",
|
||||||
return instance
|
})
|
||||||
|
|
||||||
class CreateGuardianSerializer(serializers.ModelSerializer):
|
class CreateGuardianSerializer(serializers.ModelSerializer):
|
||||||
"""Create guardian serializer"""
|
"""Create guardian serializer"""
|
||||||
@ -57,12 +68,14 @@ 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.URLField(required=False)
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
model = Guardian
|
model = Guardian
|
||||||
fields = ['first_name', 'last_name', 'email', 'phone', 'family_name', 'gender', 'country_code',
|
fields = ['id', 'first_name', 'last_name', 'email', 'phone', 'family_name', 'gender', 'country_code',
|
||||||
'dob', 'referral_code', 'passcode', 'is_complete_profile']
|
'dob', 'referral_code', 'passcode', 'is_complete_profile', 'referral_code_used',
|
||||||
|
'country_name', 'image']
|
||||||
|
|
||||||
def get_first_name(self,obj):
|
def get_first_name(self,obj):
|
||||||
"""first name of guardian"""
|
"""first name of guardian"""
|
||||||
@ -81,15 +94,13 @@ class CreateGuardianSerializer(serializers.ModelSerializer):
|
|||||||
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"""
|
||||||
user.first_name = self.context.get('first_name', user.first_name)
|
if self.context.get('first_name') != '' and self.context.get('first_name') is not None:
|
||||||
user.last_name = self.context.get('last_name', user.last_name)
|
user.first_name = self.context.get('first_name')
|
||||||
|
if self.context.get('last_name') != '' and self.context.get('last_name') is not None:
|
||||||
|
user.last_name = self.context.get('last_name')
|
||||||
user.save()
|
user.save()
|
||||||
"""Create guardian data"""
|
"""Create guardian data"""
|
||||||
guardian, created = Guardian.objects.get_or_create(user=self.context['user'])
|
guardian = Guardian.objects.filter(user=self.context['user']).last()
|
||||||
if created:
|
|
||||||
"""Create referral code and guardian code"""
|
|
||||||
guardian.referral_code = ''.join([str(random.randrange(9)) for _ in range(4)])
|
|
||||||
guardian.guardian_code = ''.join([str(random.randrange(9)) for _ in range(4)])
|
|
||||||
if guardian:
|
if guardian:
|
||||||
"""update details according to the data get from request"""
|
"""update details according to the data get from request"""
|
||||||
guardian.gender = validated_data.get('gender',guardian.gender)
|
guardian.gender = validated_data.get('gender',guardian.gender)
|
||||||
@ -99,10 +110,13 @@ class CreateGuardianSerializer(serializers.ModelSerializer):
|
|||||||
guardian.phone = validated_data.get('phone', guardian.phone)
|
guardian.phone = validated_data.get('phone', guardian.phone)
|
||||||
guardian.country_code = validated_data.get('country_code', guardian.country_code)
|
guardian.country_code = validated_data.get('country_code', guardian.country_code)
|
||||||
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.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,
|
complete_profile_field = all([guardian.gender, guardian.country_name,
|
||||||
guardian.dob, guardian.country_code, user.first_name, user.last_name])
|
guardian.dob, user.first_name,
|
||||||
|
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
|
||||||
@ -114,3 +128,132 @@ 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 = ['id', '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):
|
||||||
|
"""Task detail serializer"""
|
||||||
|
|
||||||
|
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(object):
|
||||||
|
"""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 NUMBER['five']
|
||||||
|
|
||||||
|
def get_complete_field_count(self, obj):
|
||||||
|
"""total filled fields count"""
|
||||||
|
total_field_list = [obj.user.first_name, obj.country_name,
|
||||||
|
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', 'signup_method',
|
||||||
|
'updated_at', 'passcode']
|
||||||
|
|
||||||
|
class ApproveJuniorSerializer(serializers.ModelSerializer):
|
||||||
|
"""approve junior serializer"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = Junior
|
||||||
|
fields = ['id', 'guardian_code']
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
"""update guardian code"""
|
||||||
|
instance = self.context['junior']
|
||||||
|
instance.guardian_code = [self.context['guardian_code']]
|
||||||
|
instance.save()
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,19 +1,40 @@
|
|||||||
""" 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, ApproveJuniorAPIView)
|
||||||
"""Third party import"""
|
"""Third party import"""
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
"""Define Router"""
|
"""Define Router"""
|
||||||
router = routers.SimpleRouter()
|
router = routers.SimpleRouter()
|
||||||
|
|
||||||
"""API End points with router"""
|
# API End points with router
|
||||||
|
# in this file
|
||||||
|
# we define various api end point
|
||||||
|
# that is covered in this guardian
|
||||||
|
# section API:- like
|
||||||
|
# sign-up, create guardian profile,
|
||||||
|
# create-task,
|
||||||
|
# all task list, top junior,
|
||||||
|
# filter-task"""
|
||||||
"""Sign up API"""
|
"""Sign up API"""
|
||||||
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')
|
||||||
"""Define Url pattern"""
|
# 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')
|
||||||
|
# Approve junior API"""
|
||||||
|
router.register('approve-junior', ApproveJuniorAPIView, basename='approve-junior')
|
||||||
|
# Define Url pattern"""
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('api/v1/', include(router.urls)),
|
path('api/v1/', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|||||||
32
guardian/utils.py
Normal file
32
guardian/utils.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
"""Utiles file of guardian"""
|
||||||
|
"""Django import"""
|
||||||
|
import oss2
|
||||||
|
"""Import setting"""
|
||||||
|
from django.conf import settings
|
||||||
|
"""Import tempfile"""
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
# Define upload image on
|
||||||
|
# ali baba cloud
|
||||||
|
# firstly save image
|
||||||
|
# in temporary file
|
||||||
|
# then check bucket name
|
||||||
|
# then upload on ali baba
|
||||||
|
# bucket and reform the image url"""
|
||||||
|
|
||||||
|
def upload_image_to_alibaba(image, filename):
|
||||||
|
"""upload image on oss alibaba bucket"""
|
||||||
|
# Save the image object to a temporary file
|
||||||
|
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
||||||
|
"""write image in temporary file"""
|
||||||
|
temp_file.write(image.read())
|
||||||
|
"""auth of bucket"""
|
||||||
|
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)
|
||||||
|
# Upload the temporary file to Alibaba OSS
|
||||||
|
bucket.put_object_from_file(filename, temp_file.name)
|
||||||
|
"""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,46 +2,202 @@
|
|||||||
"""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 PIL import Image
|
||||||
|
from datetime import datetime, timedelta
|
||||||
"""Import Django app"""
|
"""Import Django app"""
|
||||||
from .serializers import UserSerializer
|
from .serializers import (UserSerializer, CreateGuardianSerializer, TaskSerializer, TaskDetailsSerializer,
|
||||||
from .serializers import CreateGuardianSerializer
|
TopJuniorSerializer, ApproveJuniorSerializer)
|
||||||
from account.models import UserEmailOtp
|
from .models import Guardian, JuniorTask
|
||||||
|
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 base.constants import NUMBER
|
||||||
|
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"""
|
||||||
|
if request.data['user_type'] in ['1', '2']:
|
||||||
serializer = UserSerializer(context=request.data['user_type'], data=request.data)
|
serializer = UserSerializer(context=request.data['user_type'], data=request.data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save()
|
serializer.save()
|
||||||
"""Generate otp"""
|
"""Generate otp"""
|
||||||
otp = generate_otp()
|
otp = generate_otp()
|
||||||
UserEmailOtp.objects.create(email=request.data['email'], otp=otp)
|
expiry = timezone.now() + timezone.timedelta(days=1)
|
||||||
|
UserEmailOtp.objects.create(email=request.data['email'], otp=otp,
|
||||||
|
user_type=str(request.data['user_type']), expired_at=expiry)
|
||||||
"""Send email to the register user"""
|
"""Send email to the register user"""
|
||||||
send_otp_email(request.data['email'], otp)
|
send_otp_email(request.data['email'], otp)
|
||||||
return custom_response(SUCCESS_CODE['3001'], {"email_otp": otp},
|
return custom_response(SUCCESS_CODE['3001'], {"email_otp": otp},
|
||||||
response_status=status.HTTP_200_OK)
|
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)
|
||||||
|
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:
|
||||||
|
if image and image.size == NUMBER['zero']:
|
||||||
|
return custom_error_response(ERROR_CODE['2035'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
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('due_date', '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}"
|
||||||
|
if image and image.size == NUMBER['zero']:
|
||||||
|
return custom_error_response(ERROR_CODE['2035'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
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(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class ApproveJuniorAPIView(viewsets.ViewSet):
|
||||||
|
"""approve junior by guardian"""
|
||||||
|
serializer_class = ApproveJuniorSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
"""Get the queryset for the view"""
|
||||||
|
guardian = Guardian.objects.filter(user__email=self.request.user).last()
|
||||||
|
junior_queryset = Junior.objects.filter(id=self.request.data.get('junior_id')).last()
|
||||||
|
return guardian, junior_queryset
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
""" junior list"""
|
||||||
|
queryset = self.get_queryset()
|
||||||
|
if request.data['action'] == '1':
|
||||||
|
serializer = ApproveJuniorSerializer(context={"guardian_code": queryset[0].guardian_code,
|
||||||
|
"junior": queryset[1], "action": request.data['action']},
|
||||||
|
data=request.data)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return custom_response(SUCCESS_CODE['3023'], serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
else:
|
||||||
|
return custom_response(SUCCESS_CODE['3024'], 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/0002_junior_country_name.py
Normal file
18
junior/migrations/0002_junior_country_name.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-27 13:59
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='junior',
|
||||||
|
name='country_name',
|
||||||
|
field=models.CharField(blank=True, default=None, max_length=30, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
junior/migrations/0003_junior_image.py
Normal file
18
junior/migrations/0003_junior_image.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-28 10:16
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0002_junior_country_name'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='junior',
|
||||||
|
name='image',
|
||||||
|
field=models.ImageField(blank=True, default=None, null=True, upload_to='images/'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
junior/migrations/0004_alter_junior_image.py
Normal file
18
junior/migrations/0004_alter_junior_image.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-29 06:14
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0003_junior_image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='junior',
|
||||||
|
name='image',
|
||||||
|
field=models.ImageField(blank=True, default=None, null=True, upload_to=''),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
junior/migrations/0005_junior_is_verified.py
Normal file
18
junior/migrations/0005_junior_is_verified.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-29 12:10
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0004_alter_junior_image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='junior',
|
||||||
|
name='is_verified',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
junior/migrations/0006_alter_junior_country_name.py
Normal file
18
junior/migrations/0006_alter_junior_country_name.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-06-30 10:53
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0005_junior_is_verified'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='junior',
|
||||||
|
name='country_name',
|
||||||
|
field=models.CharField(blank=True, default=None, max_length=100, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
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
junior/migrations/0010_junior_signup_method.py
Normal file
18
junior/migrations/0010_junior_signup_method.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-11 11:26
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0009_juniorpoints_position'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='junior',
|
||||||
|
name='signup_method',
|
||||||
|
field=models.CharField(choices=[('1', 'manual'), ('2', 'google'), ('3', 'apple')], default='1', max_length=31),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
junior/migrations/0011_junior_relationship.py
Normal file
18
junior/migrations/0011_junior_relationship.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-12 06:52
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0010_junior_signup_method'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='junior',
|
||||||
|
name='relationship',
|
||||||
|
field=models.CharField(blank=True, choices=[('1', 'parent'), ('2', 'legal_guardian')], default='1', max_length=31, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
junior/migrations/0012_junior_is_invited.py
Normal file
18
junior/migrations/0012_junior_is_invited.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-12 10:51
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0011_junior_relationship'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='junior',
|
||||||
|
name='is_invited',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-07-14 09:34
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0012_junior_is_invited'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='junior',
|
||||||
|
options={'verbose_name': 'Junior', 'verbose_name_plural': 'Junior'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='juniorpoints',
|
||||||
|
options={'verbose_name': 'Junior Task Points', 'verbose_name_plural': 'Junior Task Points'},
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,33 +1,75 @@
|
|||||||
"""Junior model """
|
"""Junior model """
|
||||||
"""Import django"""
|
"""Import django"""
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
"""Import get_user_model function"""
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
"""Import ArrayField"""
|
||||||
from django.contrib.postgres.fields import ArrayField
|
from django.contrib.postgres.fields import ArrayField
|
||||||
"""Import django app"""
|
"""Import django app"""
|
||||||
from base.constants import GENDERS
|
from base.constants import GENDERS, SIGNUP_METHODS, RELATIONSHIP
|
||||||
|
"""Define User model"""
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
# Define junior model with
|
||||||
|
# various fields like
|
||||||
|
# phone, country code,
|
||||||
|
# country name,
|
||||||
|
# gender,
|
||||||
|
# date of birth,
|
||||||
|
# profile image,
|
||||||
|
# relationship type of the guardian
|
||||||
|
# signup method,
|
||||||
|
# guardian code,
|
||||||
|
# junior code,
|
||||||
|
# referral code,
|
||||||
|
# referral code that used by the junior
|
||||||
|
# is invited junior
|
||||||
|
# profile is active or not
|
||||||
|
# profile is complete or not
|
||||||
|
# passcode
|
||||||
|
# junior is verified or not
|
||||||
|
"""Define junior points model"""
|
||||||
|
# points of the junior
|
||||||
|
# position of the junior
|
||||||
|
|
||||||
class Junior(models.Model):
|
class Junior(models.Model):
|
||||||
"""Junior model"""
|
"""Junior model"""
|
||||||
auth = models.ForeignKey(User, on_delete=models.CASCADE, related_name='junior_profile', verbose_name='Email')
|
auth = models.ForeignKey(User, on_delete=models.CASCADE, related_name='junior_profile', verbose_name='Email')
|
||||||
"""Contact details"""
|
# Contact details"""
|
||||||
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_code = models.IntegerField(blank=True, null=True)
|
country_code = models.IntegerField(blank=True, null=True)
|
||||||
"""Personal info"""
|
# country name of the guardian"""
|
||||||
|
country_name = models.CharField(max_length=100, null=True, blank=True, default=None)
|
||||||
|
# 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)
|
||||||
|
# Date of birth"""
|
||||||
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(upload_to='images/')
|
# Image of the junior"""
|
||||||
"""Codes"""
|
image = models.URLField(null=True, blank=True, default=None)
|
||||||
|
# relationship"""
|
||||||
|
relationship = models.CharField(max_length=31, choices=RELATIONSHIP, null=True, blank=True,
|
||||||
|
default='1')
|
||||||
|
# Sign up method"""
|
||||||
|
signup_method = models.CharField(max_length=31, choices=SIGNUP_METHODS, default='1')
|
||||||
|
# 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 Codes"""
|
||||||
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)
|
||||||
|
# Referral code"""
|
||||||
referral_code = models.CharField(max_length=10, null=True, blank=True, default=None)
|
referral_code = models.CharField(max_length=10, null=True, blank=True, default=None)
|
||||||
|
# Referral code that is used by junior while signup"""
|
||||||
referral_code_used = models.CharField(max_length=10, null=True, blank=True, default=None)
|
referral_code_used = models.CharField(max_length=10, null=True, blank=True, default=None)
|
||||||
"""Profile activity"""
|
# invited junior"""
|
||||||
|
is_invited = models.BooleanField(default=False)
|
||||||
|
# Profile activity"""
|
||||||
is_active = models.BooleanField(default=True)
|
is_active = models.BooleanField(default=True)
|
||||||
|
# junior profile is complete or not"""
|
||||||
is_complete_profile = models.BooleanField(default=False)
|
is_complete_profile = models.BooleanField(default=False)
|
||||||
|
# passcode of the junior profile"""
|
||||||
passcode = models.IntegerField(null=True, blank=True, default=None)
|
passcode = models.IntegerField(null=True, blank=True, default=None)
|
||||||
"""Profile created and updated time"""
|
# junior is verified or not"""
|
||||||
|
is_verified = models.BooleanField(default=False)
|
||||||
|
# Profile created and updated time"""
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
@ -35,7 +77,31 @@ class Junior(models.Model):
|
|||||||
""" Meta class """
|
""" Meta class """
|
||||||
db_table = 'junior'
|
db_table = 'junior'
|
||||||
verbose_name = 'Junior'
|
verbose_name = 'Junior'
|
||||||
|
# another name of the model"""
|
||||||
|
verbose_name_plural = 'Junior'
|
||||||
|
|
||||||
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'
|
||||||
|
# another name of the model"""
|
||||||
|
verbose_name_plural = 'Junior Task Points'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return email id"""
|
||||||
|
return f'{self.junior.auth}'
|
||||||
|
|||||||
@ -4,8 +4,19 @@ from rest_framework import serializers
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
import random
|
import random
|
||||||
|
from django.utils import timezone
|
||||||
|
from rest_framework_simplejwt.tokens import RefreshToken
|
||||||
|
|
||||||
"""Import django app"""
|
"""Import django app"""
|
||||||
from junior.models import Junior
|
from account.utils import send_otp_email, generate_code
|
||||||
|
from junior.models import Junior, JuniorPoints
|
||||||
|
from guardian.tasks import generate_otp
|
||||||
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
|
from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, NUMBER, JUN, ZOD
|
||||||
|
from guardian.models import Guardian, JuniorTask
|
||||||
|
from account.models import UserEmailOtp
|
||||||
|
from junior.utils import junior_notification_email, junior_approval_mail
|
||||||
|
|
||||||
|
|
||||||
class ListCharField(serializers.ListField):
|
class ListCharField(serializers.ListField):
|
||||||
"""Serializer for Array field"""
|
"""Serializer for Array field"""
|
||||||
@ -19,7 +30,7 @@ class ListCharField(serializers.ListField):
|
|||||||
"""internal value"""
|
"""internal value"""
|
||||||
if isinstance(data, list):
|
if isinstance(data, list):
|
||||||
return data
|
return data
|
||||||
raise serializers.ValidationError({"details":"Invalid input. Expected a list of strings."})
|
raise serializers.ValidationError({"details":ERROR_CODE['2025']})
|
||||||
|
|
||||||
|
|
||||||
class CreateJuniorSerializer(serializers.ModelSerializer):
|
class CreateJuniorSerializer(serializers.ModelSerializer):
|
||||||
@ -32,12 +43,14 @@ 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.URLField(required=False)
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
model = Junior
|
model = Junior
|
||||||
fields = ['first_name', 'last_name', 'email', 'phone', 'gender', 'country_code', 'dob', 'referral_code',
|
fields = ['id', 'first_name', 'last_name', 'email', 'phone', 'gender', 'country_code', 'dob', 'referral_code',
|
||||||
'passcode', 'is_complete_profile', 'guardian_code']
|
'passcode', 'is_complete_profile', 'guardian_code', 'referral_code_used',
|
||||||
|
'country_name', 'image', 'is_invited']
|
||||||
|
|
||||||
def get_first_name(self,obj):
|
def get_first_name(self,obj):
|
||||||
"""first name of junior"""
|
"""first name of junior"""
|
||||||
@ -53,32 +66,36 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
"""Create junior profile"""
|
"""Create junior profile"""
|
||||||
|
guardian_code = validated_data.get('guardian_code',None)
|
||||||
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"""
|
||||||
user.first_name = self.context.get('first_name', user.first_name)
|
if self.context.get('first_name') != '' and self.context.get('first_name') is not None:
|
||||||
user.last_name = self.context.get('last_name', user.last_name)
|
user.first_name = self.context.get('first_name')
|
||||||
|
if self.context.get('last_name') != '' and self.context.get('last_name') is not None:
|
||||||
|
user.last_name = self.context.get('last_name')
|
||||||
user.save()
|
user.save()
|
||||||
"""Create junior data"""
|
"""Create junior data"""
|
||||||
junior, created = Junior.objects.get_or_create(auth=self.context['user'])
|
junior = Junior.objects.filter(auth=self.context['user']).last()
|
||||||
if created:
|
|
||||||
"""Create referral code and junior code"""
|
|
||||||
junior.referral_code = ''.join([str(random.randrange(9)) for _ in range(4)])
|
|
||||||
junior.junior_code = ''.join([str(random.randrange(9)) for _ in range(4)])
|
|
||||||
if junior:
|
if junior:
|
||||||
"""update details according to the data get from request"""
|
"""update details according to the data get from request"""
|
||||||
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)
|
||||||
"""Update country code and phone number"""
|
"""Update country code and phone number"""
|
||||||
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.family_name,
|
complete_profile_field = all([junior.gender, junior.country_name, junior.image,
|
||||||
junior.dob, junior.country_code, user.first_name, user.last_name])
|
junior.dob, user.first_name])
|
||||||
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
|
||||||
@ -90,3 +107,201 @@ 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', 'is_invited', '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', 'is_invited']
|
||||||
|
|
||||||
|
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 NUMBER['five']
|
||||||
|
|
||||||
|
def get_complete_field_count(self, obj):
|
||||||
|
"""total filled fields count"""
|
||||||
|
field_list = [obj.auth.first_name, obj.country_name,
|
||||||
|
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', 'signup_method',
|
||||||
|
'is_invited', 'passcode']
|
||||||
|
|
||||||
|
class AddJuniorSerializer(serializers.ModelSerializer):
|
||||||
|
"""Add junior serializer"""
|
||||||
|
auth_token = serializers.SerializerMethodField('get_auth_token')
|
||||||
|
|
||||||
|
def get_auth_token(self, obj):
|
||||||
|
"""auth token"""
|
||||||
|
refresh = RefreshToken.for_user(obj)
|
||||||
|
access_token = str(refresh.access_token)
|
||||||
|
return access_token
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta info"""
|
||||||
|
model = Junior
|
||||||
|
fields = ['id', 'gender','dob', 'relationship', 'auth_token', 'is_invited']
|
||||||
|
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
""" create junior"""
|
||||||
|
with transaction.atomic():
|
||||||
|
email = self.context['email']
|
||||||
|
guardian = self.context['user']
|
||||||
|
full_name = self.context['first_name'] + ' ' + self.context['last_name']
|
||||||
|
guardian_data = Guardian.objects.filter(user__username=guardian).last()
|
||||||
|
user_data = User.objects.create(username=email, email=email,
|
||||||
|
first_name=self.context['first_name'],
|
||||||
|
last_name=self.context['last_name'])
|
||||||
|
|
||||||
|
password = User.objects.make_random_password()
|
||||||
|
user_data.set_password(password)
|
||||||
|
user_data.save()
|
||||||
|
junior_data = Junior.objects.create(auth=user_data, gender=validated_data.get('gender'),
|
||||||
|
dob=validated_data.get('dob'), is_invited=True,
|
||||||
|
relationship=validated_data.get('relationship'),
|
||||||
|
junior_code=generate_code(JUN, user_data.id),
|
||||||
|
referral_code=generate_code(ZOD, user_data.id),
|
||||||
|
referral_code_used=guardian_data.referral_code)
|
||||||
|
"""Generate otp"""
|
||||||
|
otp_value = generate_otp()
|
||||||
|
expiry_time = timezone.now() + timezone.timedelta(days=1)
|
||||||
|
UserEmailOtp.objects.create(email=email, otp=otp_value,
|
||||||
|
user_type='1', expired_at=expiry_time)
|
||||||
|
"""Send email to the register user"""
|
||||||
|
send_otp_email(email, otp_value)
|
||||||
|
"""Notification email"""
|
||||||
|
junior_notification_email(email, full_name, email, password)
|
||||||
|
junior_approval_mail(guardian, full_name)
|
||||||
|
return junior_data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveJuniorSerializer(serializers.ModelSerializer):
|
||||||
|
"""User Update Serializer"""
|
||||||
|
class Meta(object):
|
||||||
|
"""Meta class"""
|
||||||
|
model = Junior
|
||||||
|
fields = ('id', 'is_invited')
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
if instance:
|
||||||
|
instance.is_invited = False
|
||||||
|
instance.guardian_code = '{}'
|
||||||
|
instance.save()
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|||||||
@ -1,19 +1,37 @@
|
|||||||
""" 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, AddJuniorAPIView,
|
||||||
|
InvitedJuniorAPIView, FilterJuniorAPIView, RemoveJuniorAPIView)
|
||||||
"""Third party import"""
|
"""Third party import"""
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
"""Router"""
|
"""Router"""
|
||||||
router = routers.SimpleRouter()
|
router = routers.SimpleRouter()
|
||||||
|
# API End points with router
|
||||||
|
# in this file
|
||||||
|
# we define various api end point
|
||||||
|
# that is covered in this guardian
|
||||||
|
# section API:- like
|
||||||
|
# Create junior profile API, validate junior profile,
|
||||||
|
# junior list,
|
||||||
|
# add junior list, invited junior,
|
||||||
|
# filter-junior,
|
||||||
|
# remove junior"""
|
||||||
"""API End points with router"""
|
"""API End points with router"""
|
||||||
"""Create junior profile API"""
|
|
||||||
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')
|
||||||
"""Define url pattern"""
|
# junior list API"""
|
||||||
|
router.register('junior-list', JuniorListAPIView, basename='junior-list')
|
||||||
|
# Add junior list API"""
|
||||||
|
router.register('add-junior', AddJuniorAPIView, basename='add-junior')
|
||||||
|
# Invited junior list API"""
|
||||||
|
router.register('invited-junior', InvitedJuniorAPIView, basename='invited-junior')
|
||||||
|
# Filter junior list API"""
|
||||||
|
router.register('filter-junior', FilterJuniorAPIView, basename='filter-junior')
|
||||||
|
# Define url pattern"""
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('api/v1/', include(router.urls)),
|
path('api/v1/', include(router.urls)),
|
||||||
|
path('api/v1/remove-junior/', RemoveJuniorAPIView.as_view())
|
||||||
]
|
]
|
||||||
|
|||||||
47
junior/utils.py
Normal file
47
junior/utils.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
"""Account utils"""
|
||||||
|
"""Import django"""
|
||||||
|
from django.conf import settings
|
||||||
|
"""Third party Django app"""
|
||||||
|
from templated_email import send_templated_mail
|
||||||
|
|
||||||
|
# junior notification
|
||||||
|
# email for sending email
|
||||||
|
# when guardian create junior profile
|
||||||
|
# guardian get email when junior send
|
||||||
|
# request for approving the profile and
|
||||||
|
# being part of the zod bank and access the platform
|
||||||
|
# define junior notification email
|
||||||
|
# junior approval email
|
||||||
|
def junior_notification_email(recipient_email, full_name, email, password):
|
||||||
|
"""Notification email"""
|
||||||
|
from_email = settings.EMAIL_FROM_ADDRESS
|
||||||
|
# recipient email"""
|
||||||
|
recipient_list = [recipient_email]
|
||||||
|
# use send template mail for sending email"""
|
||||||
|
send_templated_mail(
|
||||||
|
template_name='junior_notification_email.email',
|
||||||
|
from_email=from_email,
|
||||||
|
recipient_list=recipient_list,
|
||||||
|
context={
|
||||||
|
'full_name': full_name,
|
||||||
|
'url':'link',
|
||||||
|
'email': email,
|
||||||
|
'password': password
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return full_name
|
||||||
|
|
||||||
|
def junior_approval_mail(guardian, full_name):
|
||||||
|
"""junior approval mail"""
|
||||||
|
from_email = settings.EMAIL_FROM_ADDRESS
|
||||||
|
recipient_list = [guardian]
|
||||||
|
# use send template mail for sending email"""
|
||||||
|
send_templated_mail(
|
||||||
|
template_name='junior_approval_mail.email',
|
||||||
|
from_email=from_email,
|
||||||
|
recipient_list=recipient_list,
|
||||||
|
context={
|
||||||
|
'full_name': full_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return full_name
|
||||||
126
junior/views.py
126
junior/views.py
@ -1,24 +1,41 @@
|
|||||||
"""Junior view file"""
|
"""Junior view file"""
|
||||||
from rest_framework import viewsets, status
|
from rest_framework import viewsets, status, generics,views
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
from rest_framework.pagination import PageNumberPagination
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from PIL import Image
|
||||||
"""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, AddJuniorSerializer,\
|
||||||
|
RemoveJuniorSerializer)
|
||||||
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 base.constants import NUMBER
|
||||||
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:
|
||||||
|
if image.size == NUMBER['zero']:
|
||||||
|
return custom_error_response(ERROR_CODE['2035'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
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 +44,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 +56,99 @@ 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()
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
class AddJuniorAPIView(viewsets.ModelViewSet):
|
||||||
|
"""Add Junior by guardian"""
|
||||||
|
queryset = Junior.objects.all()
|
||||||
|
serializer_class = AddJuniorSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
""" junior list"""
|
||||||
|
info = {'user': request.user, 'email': request.data['email'], 'first_name': request.data['first_name'],
|
||||||
|
'last_name': request.data['last_name']}
|
||||||
|
serializer = AddJuniorSerializer(data=request.data, context=info)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return custom_response(SUCCESS_CODE['3021'], serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
return custom_error_response(serializer.error, response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
class InvitedJuniorAPIView(viewsets.ModelViewSet):
|
||||||
|
"""Junior list of assosicated guardian"""
|
||||||
|
|
||||||
|
serializer_class = JuniorDetailListSerializer
|
||||||
|
queryset = Junior.objects.all()
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
pagination_class = PageNumberPagination
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
"""Get the queryset for the view"""
|
||||||
|
guardian = Guardian.objects.filter(user__email=self.request.user).last()
|
||||||
|
junior_queryset = Junior.objects.filter(guardian_code__icontains=str(guardian.guardian_code),
|
||||||
|
is_invited=True)
|
||||||
|
return junior_queryset
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
""" junior list"""
|
||||||
|
queryset = self.get_queryset()
|
||||||
|
paginator = self.pagination_class()
|
||||||
|
paginated_queryset = paginator.paginate_queryset(queryset, request)
|
||||||
|
serializer = JuniorDetailListSerializer(paginated_queryset, many=True)
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class FilterJuniorAPIView(viewsets.ModelViewSet):
|
||||||
|
"""Update guardian profile"""
|
||||||
|
serializer_class = JuniorDetailListSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
pagination_class = PageNumberPagination
|
||||||
|
queryset = Junior.objects.all()
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
"""Get the queryset for the view"""
|
||||||
|
title = self.request.GET.get('title')
|
||||||
|
guardian_data = Guardian.objects.filter(user__email=self.request.user).last()
|
||||||
|
queryset = Junior.objects.filter(guardian_code__icontains=str(guardian_data.guardian_code),
|
||||||
|
is_invited=True, auth__first_name=title)
|
||||||
|
return 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 = JuniorDetailListSerializer(paginated_queryset, many=True)
|
||||||
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveJuniorAPIView(views.APIView):
|
||||||
|
"""Eater Update API"""
|
||||||
|
serializer_class = RemoveJuniorSerializer
|
||||||
|
model = Junior
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def put(self, request, format=None):
|
||||||
|
junior_id = self.request.GET.get('id')
|
||||||
|
guardian = Guardian.objects.filter(user__email=self.request.user).last()
|
||||||
|
junior_queryset = Junior.objects.filter(id=junior_id, guardian_code__icontains=str(guardian.guardian_code),
|
||||||
|
is_invited=True).last()
|
||||||
|
if junior_queryset:
|
||||||
|
serializer = RemoveJuniorSerializer(junior_queryset, data=request.data, partial=True)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return custom_response(SUCCESS_CODE['3022'], serializer.data, 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['2034'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|||||||
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,6 @@ upstream web {
|
|||||||
|
|
||||||
location /static {
|
location /static {
|
||||||
autoindex on;
|
autoindex on;
|
||||||
alias /usr/src/app/zod_bank/static/;
|
alias /usr/src/app/static/;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,27 @@
|
|||||||
aliyun-python-sdk-core==2.13.36
|
aliyun-python-sdk-core==2.13.36
|
||||||
aliyun-python-sdk-dysmsapi==2.1.2
|
aliyun-python-sdk-dysmsapi==2.1.2
|
||||||
|
aliyun-python-sdk-kms==2.16.1
|
||||||
|
aliyun-python-sdk-sts==3.1.1
|
||||||
amqp==5.1.1
|
amqp==5.1.1
|
||||||
asgiref==3.7.2
|
asgiref==3.7.2
|
||||||
async-timeout==4.0.2
|
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
|
||||||
cffi==1.15.1
|
cffi==1.15.1
|
||||||
channels==4.0.0
|
channels==4.0.0
|
||||||
channels-redis==4.1.0
|
channels-redis==4.1.0
|
||||||
|
charset-normalizer==3.1.0
|
||||||
click==8.1.3
|
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
|
||||||
cron-descriptor==1.4.0
|
cron-descriptor==1.4.0
|
||||||
cryptography==41.0.1
|
cryptography==41.0.1
|
||||||
decouple==0.0.7
|
decouple==0.0.7
|
||||||
@ -33,16 +41,26 @@ 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
|
||||||
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
|
||||||
packaging==23.1
|
packaging==23.1
|
||||||
phonenumbers==8.13.15
|
phonenumbers==8.13.15
|
||||||
|
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
|
||||||
PyJWT==2.7.0
|
PyJWT==2.7.0
|
||||||
python-crontab==2.7.1
|
python-crontab==2.7.1
|
||||||
python-dateutil==2.8.2
|
python-dateutil==2.8.2
|
||||||
@ -50,6 +68,8 @@ python-dotenv==1.0.0
|
|||||||
pytz==2023.3
|
pytz==2023.3
|
||||||
PyYAML==6.0
|
PyYAML==6.0
|
||||||
redis==4.5.5
|
redis==4.5.5
|
||||||
|
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 = [
|
||||||
@ -66,6 +67,7 @@ MIDDLEWARE = [
|
|||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
'account.custom_middleware.CustomMiddleware'
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'zod_bank.urls'
|
ROOT_URLCONF = 'zod_bank.urls'
|
||||||
@ -91,12 +93,13 @@ 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(hours=2, minutes=59, seconds=59, microseconds=999999),
|
||||||
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
|
'REFRESH_TOKEN_LIFETIME': timedelta(hours=71, minutes=59, seconds=59, microseconds=999999),
|
||||||
}
|
}
|
||||||
# Database
|
# Database
|
||||||
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
||||||
@ -110,6 +113,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
|
||||||
|
|
||||||
@ -141,7 +168,6 @@ USE_I18N = True
|
|||||||
USE_L10N = True
|
USE_L10N = True
|
||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
# cors header settings
|
# cors header settings
|
||||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
||||||
|
|
||||||
@ -172,13 +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 settings
|
GOOGLE_CLIENT_ID = os.getenv('GOOGLE_CLIENT_ID')
|
||||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
GOOGLE_CLIENT_SECRET = os.getenv('GOOGLE_CLIENT_SECRET')
|
||||||
EMAIL_HOST = 'smtp.gmail.com'
|
|
||||||
EMAIL_PORT = 587
|
|
||||||
EMAIL_USE_TLS = True
|
EMAIL_BACKEND="django.core.mail.backends.smtp.EmailBackend"
|
||||||
EMAIL_HOST_USER = 'infozodbank@gmail.com'
|
EMAIL_HOST="smtp.sendgrid.net"
|
||||||
# Replace with your Gmail email password or App password
|
EMAIL_PORT="587"
|
||||||
EMAIL_HOST_PASSWORD = 'ghwdmznwwslvchga'
|
EMAIL_USE_TLS="True"
|
||||||
|
EMAIL_HOST_USER="apikey"
|
||||||
|
EMAIL_HOST_PASSWORD="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"
|
||||||
|
EMAIL_FROM_ADDRESS="support@zodbank.com"
|
||||||
|
DEFAULT_ADDRESS="zodbank@yopmail.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')
|
||||||
|
|
||||||
|
|
||||||
|
STATIC_URL = 'static/'
|
||||||
|
STATIC_ROOT = 'static'
|
||||||
|
|
||||||
STATIC_URL = '/static/'
|
|
||||||
|
|||||||
Reference in New Issue
Block a user