mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2026-10-23 09:47:56 +00:00
Compare commits
88
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2216411fd2 | ||
|
|
606c1fa6e6 | ||
|
|
092cbfad3e | ||
|
|
249a469d89 | ||
|
|
d202774df1 | ||
|
|
1adf0c2f70 | ||
|
|
b193166914 | ||
|
|
48b455e38a | ||
|
|
6d54a718b9 | ||
|
|
454f66b3a0 | ||
|
|
5045f5acda | ||
|
|
e84180a6c2 | ||
|
|
21e006ae2a | ||
|
|
92e5104e3f | ||
|
|
dfb73a7d36 | ||
|
|
3921f76f22 | ||
|
|
cdf1a7b74e | ||
|
|
b4026a4f11 | ||
|
|
71a3e36bf3 | ||
|
|
4bc91abebf | ||
|
|
5b236dfc81 | ||
|
|
150bb9250d | ||
|
|
51d3b77ff7 | ||
|
|
92c67dd455 | ||
|
|
9a5447bca2 | ||
|
|
392086760f | ||
|
|
ceaf584332 | ||
|
|
ef4c459229 | ||
|
|
dd2890bca6 | ||
|
|
b46109e487 | ||
|
|
3f6c9a2d99 | ||
|
|
f74302df04 | ||
|
|
9bdd324c4e | ||
|
|
04ed9c668c | ||
|
|
e1d092d663 | ||
|
|
4e8243c17e | ||
|
|
13ba311822 | ||
|
|
043c8c2f63 | ||
|
|
a5f239b9d9 | ||
|
|
36427b50c1 | ||
|
|
728d19da99 | ||
|
|
5da07002e0 | ||
|
|
3017b0ece0 | ||
|
|
e73113fcca | ||
|
|
ed1b5dd453 | ||
|
|
c278670c39 | ||
|
|
60af098e1e | ||
|
|
74328f37b2 | ||
|
|
d29a60558f | ||
|
|
451c3bdae7 | ||
|
|
d8f4467d98 | ||
|
|
7c809776b6 | ||
|
|
a9cc05c675 | ||
|
|
e46d649fdc | ||
|
|
adb827f5a0 | ||
|
|
a02dfd4e31 | ||
|
|
4bc16c56bd | ||
|
|
08dc9f8538 | ||
|
|
83d7d119be | ||
|
|
a1d959299a | ||
|
|
19a6475097 | ||
|
|
4ca60af5da | ||
|
|
807526acfa | ||
|
|
f4149379c2 | ||
|
|
b8f1acaed8 | ||
|
|
9e5dd5e3d5 | ||
|
|
b961044e4d | ||
|
|
2498394127 | ||
|
|
2fc65d462d | ||
|
|
cdf656fdad | ||
|
|
8eaf8751c2 | ||
|
|
6867920754 | ||
|
|
22ba4288d9 | ||
|
|
7ab16cb3de | ||
|
|
07d150309b | ||
|
|
3801e6e027 | ||
|
|
e89fc513cb | ||
|
|
e1af1c200d | ||
|
|
b238379a22 | ||
|
|
c081bc621d | ||
|
|
d2c8b18e3f | ||
|
|
bdc0ba4fd5 | ||
|
|
3af2584d6a | ||
|
|
62cf2b14bf | ||
|
|
cbd3d139a5 | ||
|
|
7cb792c6cf | ||
|
|
5ea28bbd75 | ||
|
|
180104ece8 |
@@ -7,7 +7,9 @@ from rest_framework.renderers import JSONRenderer
|
|||||||
from account.utils import custom_error_response
|
from account.utils import custom_error_response
|
||||||
from account.models import UserDeviceDetails
|
from account.models import UserDeviceDetails
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
|
from base.constants import NUMBER
|
||||||
|
from junior.models import Junior
|
||||||
|
from guardian.models import Guardian
|
||||||
# Custom middleware
|
# Custom middleware
|
||||||
# when user login with
|
# when user login with
|
||||||
# multiple device simultaneously
|
# multiple device simultaneously
|
||||||
@@ -15,6 +17,16 @@ from base.messages import ERROR_CODE, SUCCESS_CODE
|
|||||||
# multiple devices only
|
# multiple devices only
|
||||||
# user can login in single
|
# user can login in single
|
||||||
# device at a time"""
|
# device at a time"""
|
||||||
|
|
||||||
|
def custom_response(custom_error):
|
||||||
|
"""custom response"""
|
||||||
|
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
|
||||||
class CustomMiddleware(object):
|
class CustomMiddleware(object):
|
||||||
"""Custom middleware"""
|
"""Custom middleware"""
|
||||||
def __init__(self, get_response):
|
def __init__(self, get_response):
|
||||||
@@ -26,15 +38,22 @@ class CustomMiddleware(object):
|
|||||||
response = self.get_response(request)
|
response = self.get_response(request)
|
||||||
# Code to be executed after the view is called
|
# Code to be executed after the view is called
|
||||||
device_id = request.META.get('HTTP_DEVICE_ID')
|
device_id = request.META.get('HTTP_DEVICE_ID')
|
||||||
|
user_type = request.META.get('HTTP_USER_TYPE')
|
||||||
|
api_endpoint = request.path
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
"""device details"""
|
# device details
|
||||||
device_details = UserDeviceDetails.objects.filter(user=request.user, device_id=device_id).last()
|
device_details = UserDeviceDetails.objects.filter(user=request.user, device_id=device_id).last()
|
||||||
if device_id and not device_details:
|
if user_type and str(user_type) == str(NUMBER['one']):
|
||||||
|
junior = Junior.objects.filter(auth=request.user, is_active=False).last()
|
||||||
|
if junior:
|
||||||
|
custom_error = custom_error_response(ERROR_CODE['2075'], response_status=status.HTTP_404_NOT_FOUND)
|
||||||
|
response = custom_response(custom_error)
|
||||||
|
elif user_type and str(user_type) == str(NUMBER['two']):
|
||||||
|
guardian = Guardian.objects.filter(user=request.user, is_active=False).last()
|
||||||
|
if guardian:
|
||||||
|
custom_error = custom_error_response(ERROR_CODE['2075'], response_status=status.HTTP_404_NOT_FOUND)
|
||||||
|
response = custom_response(custom_error)
|
||||||
|
if device_id and not device_details and api_endpoint != '/api/v1/user/login/':
|
||||||
custom_error = custom_error_response(ERROR_CODE['2037'], response_status=status.HTTP_404_NOT_FOUND)
|
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)
|
response = custom_response(custom_error)
|
||||||
# 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
|
return response
|
||||||
|
|||||||
+25
-11
@@ -104,10 +104,12 @@ class ResetPasswordSerializer(serializers.Serializer):
|
|||||||
return user_opt_details
|
return user_opt_details
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
class ChangePasswordSerializer(serializers.Serializer):
|
class ChangePasswordSerializer(serializers.Serializer):
|
||||||
"""Update Password after verification"""
|
"""Update Password after verification"""
|
||||||
current_password = serializers.CharField(max_length=100)
|
current_password = serializers.CharField(max_length=100, required=True)
|
||||||
new_password = serializers.CharField(required=True)
|
new_password = serializers.CharField(required=True)
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
model = User
|
model = User
|
||||||
@@ -118,25 +120,36 @@ class ChangePasswordSerializer(serializers.Serializer):
|
|||||||
if self.context.password not in ('', None) and user.check_password(value):
|
if self.context.password not in ('', None) and user.check_password(value):
|
||||||
return value
|
return value
|
||||||
raise serializers.ValidationError(ERROR_CODE['2015'])
|
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')
|
current_password = validated_data.pop('current_password')
|
||||||
"""Check new password is different from current password"""
|
# Check new password is different from current password
|
||||||
if new_password == current_password:
|
if new_password == current_password:
|
||||||
raise serializers.ValidationError({"details": ERROR_CODE['2026']})
|
raise serializers.ValidationError({"details": ERROR_CODE['2026']})
|
||||||
user_details = User.objects.filter(email=self.context).last()
|
|
||||||
if user_details:
|
|
||||||
user_details.set_password(new_password)
|
|
||||||
user_details.save()
|
|
||||||
return {'password':new_password}
|
|
||||||
return ''
|
|
||||||
|
|
||||||
|
user_details = self.context
|
||||||
|
user_details.set_password(new_password)
|
||||||
|
user_details.save()
|
||||||
|
return {'password':new_password}
|
||||||
|
|
||||||
|
|
||||||
class ForgotPasswordSerializer(serializers.Serializer):
|
class ForgotPasswordSerializer(serializers.Serializer):
|
||||||
"""Forget password serializer"""
|
"""Forget password serializer"""
|
||||||
email = serializers.EmailField()
|
email = serializers.EmailField(required=True)
|
||||||
|
|
||||||
|
def validate_email(self, value):
|
||||||
|
"""
|
||||||
|
validate email exist ot not
|
||||||
|
value: string
|
||||||
|
return none
|
||||||
|
"""
|
||||||
|
if not User.objects.get(email=value):
|
||||||
|
raise serializers.ValidationError({'details': ERROR_CODE['2004']})
|
||||||
|
return value
|
||||||
|
|
||||||
class AdminLoginSerializer(serializers.ModelSerializer):
|
class AdminLoginSerializer(serializers.ModelSerializer):
|
||||||
"""admin login serializer"""
|
"""admin login serializer"""
|
||||||
@@ -244,7 +257,7 @@ class GuardianSerializer(serializers.ModelSerializer):
|
|||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
model = Guardian
|
model = Guardian
|
||||||
fields = ['id', 'auth_token', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code',
|
fields = ['id', 'auth_token', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code',
|
||||||
'phone', 'family_name', 'gender', 'dob', 'referral_code', 'is_active',
|
'phone', 'family_name', 'gender', 'dob', 'referral_code', 'is_active', 'is_deleted',
|
||||||
'is_complete_profile', 'passcode', 'image', 'created_at', 'updated_at', 'user_type', 'country_name']
|
'is_complete_profile', 'passcode', 'image', 'created_at', 'updated_at', 'user_type', 'country_name']
|
||||||
|
|
||||||
|
|
||||||
@@ -287,7 +300,8 @@ class JuniorSerializer(serializers.ModelSerializer):
|
|||||||
model = Junior
|
model = Junior
|
||||||
fields = ['id', 'auth_token', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code',
|
fields = ['id', 'auth_token', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code',
|
||||||
'phone', 'gender', 'dob', 'guardian_code', 'referral_code','is_active', 'is_password_set',
|
'phone', 'gender', 'dob', 'guardian_code', 'referral_code','is_active', 'is_password_set',
|
||||||
'is_complete_profile', 'created_at', 'image', 'updated_at', 'user_type', 'country_name','is_invited']
|
'is_complete_profile', 'created_at', 'image', 'updated_at', 'user_type', 'country_name','is_invited',
|
||||||
|
'is_deleted']
|
||||||
|
|
||||||
class EmailVerificationSerializer(serializers.ModelSerializer):
|
class EmailVerificationSerializer(serializers.ModelSerializer):
|
||||||
"""Email verification serializer"""
|
"""Email verification serializer"""
|
||||||
|
|||||||
@@ -8,14 +8,14 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td style="padding: 0 27px 15px;">
|
<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;">
|
<p style="margin: 0; font-size: 16px; line-height: 20px; padding: 36px 0 0; font-weight: 500; color: #1f2532;">
|
||||||
Hi {{name}},
|
Hi Support Team,
|
||||||
</p>
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding: 0 27px 22px;">
|
<td style="padding: 0 27px 22px;">
|
||||||
<p style="margin: 0;font-size: 14px; font-weight: 400; line-height: 21px; color: #1f2532;">
|
<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 }}
|
<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><li> {{ message }}</li>
|
||||||
</p>
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
+33
-1
@@ -95,6 +95,7 @@ def junior_account_update(user_tb):
|
|||||||
junior_data.is_verified = False
|
junior_data.is_verified = False
|
||||||
junior_data.guardian_code = '{}'
|
junior_data.guardian_code = '{}'
|
||||||
junior_data.guardian_code_status = str(NUMBER['one'])
|
junior_data.guardian_code_status = str(NUMBER['one'])
|
||||||
|
junior_data.is_deleted = True
|
||||||
junior_data.save()
|
junior_data.save()
|
||||||
JuniorPoints.objects.filter(junior=junior_data).delete()
|
JuniorPoints.objects.filter(junior=junior_data).delete()
|
||||||
|
|
||||||
@@ -105,6 +106,7 @@ def guardian_account_update(user_tb):
|
|||||||
# Update guardian account
|
# Update guardian account
|
||||||
guardian_data.is_active = False
|
guardian_data.is_active = False
|
||||||
guardian_data.is_verified = False
|
guardian_data.is_verified = False
|
||||||
|
guardian_data.is_deleted = True
|
||||||
guardian_data.save()
|
guardian_data.save()
|
||||||
jun_data = Junior.objects.filter(guardian_code__icontains=str(guardian_data.guardian_code))
|
jun_data = Junior.objects.filter(guardian_code__icontains=str(guardian_data.guardian_code))
|
||||||
"""Disassociate relation between guardian and junior"""
|
"""Disassociate relation between guardian and junior"""
|
||||||
@@ -127,6 +129,28 @@ def send_otp_email(recipient_email, otp):
|
|||||||
)
|
)
|
||||||
return otp
|
return otp
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task()
|
||||||
|
def send_all_email(template_name, email, otp):
|
||||||
|
"""
|
||||||
|
Send all type of email by passing template name
|
||||||
|
template_name: string
|
||||||
|
email: string
|
||||||
|
otp: string
|
||||||
|
"""
|
||||||
|
from_email = settings.EMAIL_FROM_ADDRESS
|
||||||
|
recipient_list = [email]
|
||||||
|
send_templated_mail(
|
||||||
|
template_name=template_name,
|
||||||
|
from_email=from_email,
|
||||||
|
recipient_list=recipient_list,
|
||||||
|
context={
|
||||||
|
'verification_code': otp
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return otp
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def user_device_details(user, device_id):
|
def user_device_details(user, device_id):
|
||||||
"""
|
"""
|
||||||
@@ -135,10 +159,12 @@ def user_device_details(user, device_id):
|
|||||||
device_id: string
|
device_id: string
|
||||||
return
|
return
|
||||||
"""
|
"""
|
||||||
device_details, created = UserDeviceDetails.objects.get_or_create(user=user)
|
device_details, created = UserDeviceDetails.objects.get_or_create(user__id=user)
|
||||||
if device_details:
|
if device_details:
|
||||||
device_details.device_id = device_id
|
device_details.device_id = device_id
|
||||||
device_details.save()
|
device_details.save()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def send_support_email(name, sender, subject, message):
|
def send_support_email(name, sender, subject, message):
|
||||||
@@ -251,3 +277,9 @@ def generate_code(value, user_id):
|
|||||||
|
|
||||||
|
|
||||||
OTP_EXPIRY = timezone.now() + timezone.timedelta(days=1)
|
OTP_EXPIRY = timezone.now() + timezone.timedelta(days=1)
|
||||||
|
|
||||||
|
def get_user_full_name(user_obj):
|
||||||
|
"""
|
||||||
|
to get user's full name
|
||||||
|
"""
|
||||||
|
return f"{user_obj.first_name} {user_obj.last_name}" if user_obj.last_name else user_obj.first_name
|
||||||
|
|||||||
+80
-59
@@ -7,7 +7,6 @@ from notifications.utils import remove_fcm_token
|
|||||||
from datetime import datetime, timedelta
|
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 logging
|
import logging
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
import jwt
|
import jwt
|
||||||
@@ -40,7 +39,7 @@ from base.messages import ERROR_CODE, SUCCESS_CODE
|
|||||||
from base.constants import NUMBER, ZOD, JUN, GRD, USER_TYPE_FLAG
|
from base.constants import NUMBER, ZOD, JUN, GRD, USER_TYPE_FLAG
|
||||||
from guardian.tasks import generate_otp
|
from guardian.tasks import generate_otp
|
||||||
from account.utils import (send_otp_email, send_support_email, custom_response, custom_error_response,
|
from account.utils import (send_otp_email, send_support_email, custom_response, custom_error_response,
|
||||||
generate_code, OTP_EXPIRY, user_device_details)
|
generate_code, OTP_EXPIRY, user_device_details, send_all_email)
|
||||||
from junior.serializers import JuniorProfileSerializer
|
from junior.serializers import JuniorProfileSerializer
|
||||||
from guardian.serializers import GuardianProfileSerializer
|
from guardian.serializers import GuardianProfileSerializer
|
||||||
|
|
||||||
@@ -194,15 +193,30 @@ class UpdateProfileImage(views.APIView):
|
|||||||
return custom_error_response(ERROR_CODE['2036'],response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(ERROR_CODE['2036'],response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
class ChangePasswordAPIView(views.APIView):
|
class ChangePasswordAPIView(views.APIView):
|
||||||
"""change password"""
|
"""
|
||||||
|
change password"
|
||||||
|
"""
|
||||||
serializer_class = ChangePasswordSerializer
|
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)
|
"""
|
||||||
|
POST request to change current login user password
|
||||||
|
"""
|
||||||
|
serializer = ChangePasswordSerializer(
|
||||||
|
context=request.user,
|
||||||
|
data=request.data
|
||||||
|
)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return custom_response(SUCCESS_CODE['3007'], response_status=status.HTTP_200_OK)
|
return custom_response(
|
||||||
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
SUCCESS_CODE['3007'],
|
||||||
|
response_status=status.HTTP_200_OK
|
||||||
|
)
|
||||||
|
return custom_error_response(
|
||||||
|
serializer.errors,
|
||||||
|
response_status=status.HTTP_400_BAD_REQUEST
|
||||||
|
)
|
||||||
|
|
||||||
class ResetPasswordAPIView(views.APIView):
|
class ResetPasswordAPIView(views.APIView):
|
||||||
"""Reset password"""
|
"""Reset password"""
|
||||||
@@ -214,40 +228,40 @@ 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"""
|
"""
|
||||||
|
Forgot password
|
||||||
|
"""
|
||||||
|
serializer_class = ForgotPasswordSerializer
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
serializer = ForgotPasswordSerializer(data=request.data)
|
|
||||||
if serializer.is_valid():
|
"""
|
||||||
email = serializer.validated_data['email']
|
Post method to validate serializer
|
||||||
try:
|
"""
|
||||||
User.objects.get(email=email)
|
serializer = self.serializer_class(data=request.data)
|
||||||
except User.DoesNotExist:
|
serializer.is_valid(raise_exception=True)
|
||||||
return custom_error_response(ERROR_CODE['2004'], response_status=status.HTTP_404_NOT_FOUND)
|
email = serializer.validated_data['email']
|
||||||
verification_code = generate_otp()
|
# generate otp
|
||||||
# Send the verification code to the user's email
|
verification_code = generate_otp()
|
||||||
from_email = settings.EMAIL_FROM_ADDRESS
|
# Send the verification code to the user's email
|
||||||
recipient_list = [email]
|
send_all_email.delay(
|
||||||
send_templated_mail(
|
'email_reset_verification.email', email, verification_code
|
||||||
template_name='email_reset_verification.email',
|
)
|
||||||
from_email=from_email,
|
expiry = OTP_EXPIRY
|
||||||
recipient_list=recipient_list,
|
user_data, created = UserEmailOtp.objects.get_or_create(
|
||||||
context={
|
email=email
|
||||||
'verification_code': verification_code
|
)
|
||||||
}
|
if created:
|
||||||
)
|
user_data.expired_at = expiry
|
||||||
expiry = OTP_EXPIRY
|
user_data.save()
|
||||||
user_data, created = UserEmailOtp.objects.get_or_create(email=email)
|
if user_data:
|
||||||
if created:
|
user_data.otp = verification_code
|
||||||
user_data.expired_at = expiry
|
user_data.expired_at = expiry
|
||||||
user_data.save()
|
user_data.save()
|
||||||
if user_data:
|
return custom_response(
|
||||||
user_data.otp = verification_code
|
SUCCESS_CODE['3015'],
|
||||||
user_data.expired_at = expiry
|
response_status=status.HTTP_200_OK
|
||||||
user_data.save()
|
)
|
||||||
return custom_response(SUCCESS_CODE['3015'],
|
|
||||||
response_status=status.HTTP_200_OK)
|
|
||||||
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
class SendPhoneOtp(viewsets.ModelViewSet):
|
class SendPhoneOtp(viewsets.ModelViewSet):
|
||||||
"""Send otp on phone"""
|
"""Send otp on phone"""
|
||||||
@@ -288,30 +302,32 @@ class UserLogin(viewsets.ViewSet):
|
|||||||
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')
|
||||||
user_type = request.data.get('user_type')
|
user_type = request.META.get('HTTP_USER_TYPE')
|
||||||
device_id = request.META.get('HTTP_DEVICE_ID')
|
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)
|
||||||
if user_type == USER_TYPE_FLAG["TWO"]:
|
if str(user_type) == USER_TYPE_FLAG["TWO"]:
|
||||||
guardian_data = Guardian.objects.filter(user__username=username, is_verified=True).last()
|
guardian_data = Guardian.objects.filter(user__username=username).last()
|
||||||
if guardian_data:
|
if guardian_data:
|
||||||
serializer = GuardianSerializer(
|
if guardian_data.is_verified:
|
||||||
guardian_data, context={'user_type': user_type}
|
serializer = GuardianSerializer(
|
||||||
).data
|
guardian_data, context={'user_type': user_type}
|
||||||
|
).data
|
||||||
else:
|
else:
|
||||||
return custom_error_response(
|
return custom_error_response(
|
||||||
ERROR_CODE["2070"],
|
ERROR_CODE["2070"],
|
||||||
response_status=status.HTTP_401_UNAUTHORIZED
|
response_status=status.HTTP_401_UNAUTHORIZED
|
||||||
)
|
)
|
||||||
elif user_type == USER_TYPE_FLAG["FIRST"]:
|
elif str(user_type) == USER_TYPE_FLAG["FIRST"]:
|
||||||
junior_data = Junior.objects.filter(auth__username=username, is_verified=True).last()
|
junior_data = Junior.objects.filter(auth__username=username).last()
|
||||||
if junior_data:
|
if junior_data:
|
||||||
serializer = JuniorSerializer(
|
if junior_data.is_verified:
|
||||||
junior_data, context={'user_type': user_type}
|
serializer = JuniorSerializer(
|
||||||
).data
|
junior_data, context={'user_type': user_type}
|
||||||
|
).data
|
||||||
else:
|
else:
|
||||||
return custom_error_response(
|
return custom_error_response(
|
||||||
ERROR_CODE["2071"],
|
ERROR_CODE["2071"],
|
||||||
@@ -322,8 +338,12 @@ class UserLogin(viewsets.ViewSet):
|
|||||||
ERROR_CODE["2069"],
|
ERROR_CODE["2069"],
|
||||||
response_status=status.HTTP_401_UNAUTHORIZED
|
response_status=status.HTTP_401_UNAUTHORIZED
|
||||||
)
|
)
|
||||||
# storing device id in using thread so the time would be reduced
|
# storing device id in using celery task so the time would be reduced
|
||||||
threading.Thread(target=user_device_details, args=(user, device_id))
|
# user_device_details.delay(user.id, device_id)
|
||||||
|
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)
|
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)
|
||||||
@@ -402,12 +422,13 @@ class AdminLoginViewSet(viewsets.GenericViewSet):
|
|||||||
class UserEmailVerification(viewsets.ModelViewSet):
|
class UserEmailVerification(viewsets.ModelViewSet):
|
||||||
"""User Email verification"""
|
"""User Email verification"""
|
||||||
serializer_class = EmailVerificationSerializer
|
serializer_class = EmailVerificationSerializer
|
||||||
|
http_method_names = ('post',)
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
user_obj = User.objects.filter(username=self.request.GET.get('email')).last()
|
user_obj = User.objects.filter(username=self.request.data.get('email')).last()
|
||||||
email_data = UserEmailOtp.objects.filter(email=self.request.GET.get('email'),
|
email_data = UserEmailOtp.objects.filter(email=self.request.data.get('email'),
|
||||||
otp=self.request.GET.get('otp')).last()
|
otp=self.request.data.get('otp')).last()
|
||||||
if email_data:
|
if email_data:
|
||||||
input_datetime_str = str(email_data.expired_at)
|
input_datetime_str = str(email_data.expired_at)
|
||||||
input_format = "%Y-%m-%d %H:%M:%S.%f%z"
|
input_format = "%Y-%m-%d %H:%M:%S.%f%z"
|
||||||
@@ -421,12 +442,12 @@ class UserEmailVerification(viewsets.ModelViewSet):
|
|||||||
email_data.is_verified = True
|
email_data.is_verified = True
|
||||||
email_data.save()
|
email_data.save()
|
||||||
if email_data.user_type == '1':
|
if email_data.user_type == '1':
|
||||||
junior_data = Junior.objects.filter(auth__email=self.request.GET.get('email')).last()
|
junior_data = Junior.objects.filter(auth__email=self.request.data.get('email')).last()
|
||||||
if junior_data:
|
if junior_data:
|
||||||
junior_data.is_verified = True
|
junior_data.is_verified = True
|
||||||
junior_data.save()
|
junior_data.save()
|
||||||
else:
|
else:
|
||||||
guardian_data = Guardian.objects.filter(user__email=self.request.GET.get('email')).last()
|
guardian_data = Guardian.objects.filter(user__email=self.request.data.get('email')).last()
|
||||||
if guardian_data:
|
if guardian_data:
|
||||||
guardian_data.is_verified = True
|
guardian_data.is_verified = True
|
||||||
guardian_data.save()
|
guardian_data.save()
|
||||||
@@ -450,7 +471,7 @@ class ReSendEmailOtp(viewsets.ModelViewSet):
|
|||||||
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 = OTP_EXPIRY
|
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:
|
if created:
|
||||||
email_data.expired_at = expiry
|
email_data.expired_at = expiry
|
||||||
@@ -536,7 +557,7 @@ class UserNotificationAPIViewSet(viewsets.ModelViewSet):
|
|||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
"""profile view"""
|
"""profile view"""
|
||||||
queryset = self.queryset.filter(user=request.user)
|
queryset = UserNotification.objects.filter(user=request.user)
|
||||||
serializer = UserNotificationSerializer(queryset, many=True)
|
serializer = UserNotificationSerializer(queryset, many=True)
|
||||||
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ NUMBER = {
|
|||||||
'ninety_nine': 99, 'hundred': 100, 'thirty_six_hundred': 3600
|
'ninety_nine': 99, 'hundred': 100, 'thirty_six_hundred': 3600
|
||||||
}
|
}
|
||||||
|
|
||||||
|
none = "none"
|
||||||
|
|
||||||
# Super Admin string constant for 'role'
|
# Super Admin string constant for 'role'
|
||||||
SUPER_ADMIN = "Super Admin"
|
SUPER_ADMIN = "Super Admin"
|
||||||
|
|||||||
+11
-2
@@ -96,8 +96,15 @@ ERROR_CODE = {
|
|||||||
"2067": "Action not allowed. User type missing.",
|
"2067": "Action not allowed. User type missing.",
|
||||||
"2068": "No guardian associated with this junior",
|
"2068": "No guardian associated with this junior",
|
||||||
"2069": "Invalid user type",
|
"2069": "Invalid user type",
|
||||||
"2070": "You did not find as a guardian",
|
"2070": "You do not find as a guardian",
|
||||||
"2071": "You did not find as a junior"
|
"2071": "You do not find as a junior",
|
||||||
|
"2072": "You can not approve or reject this task because junior does not exist in the system",
|
||||||
|
"2073": "You can not approve or reject this junior because junior does not exist in the system",
|
||||||
|
"2074": "You can not complete this task because you does not exist in the system",
|
||||||
|
"2075": "Your account is deactivated. Please contact with admin",
|
||||||
|
"2076": "This junior already associate with you",
|
||||||
|
"2077": "You can not add guardian",
|
||||||
|
"2078": "This junior is not associate with you",
|
||||||
|
|
||||||
}
|
}
|
||||||
"""Success message code"""
|
"""Success message code"""
|
||||||
@@ -163,6 +170,8 @@ SUCCESS_CODE = {
|
|||||||
"3043": "Read article card successfully",
|
"3043": "Read article card successfully",
|
||||||
# remove guardian code request
|
# remove guardian code request
|
||||||
"3044": "Remove guardian code request successfully",
|
"3044": "Remove guardian code request successfully",
|
||||||
|
# create faq
|
||||||
|
"3045": "Create FAQ data"
|
||||||
|
|
||||||
}
|
}
|
||||||
"""status code error"""
|
"""status code error"""
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-08-17 12:45
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('guardian', '0020_alter_juniortask_task_status'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='guardian',
|
||||||
|
name='is_deleted',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -57,6 +57,8 @@ class Guardian(models.Model):
|
|||||||
is_invited = models.BooleanField(default=False)
|
is_invited = models.BooleanField(default=False)
|
||||||
# Profile activity"""
|
# Profile activity"""
|
||||||
is_password_set = models.BooleanField(default=True)
|
is_password_set = models.BooleanField(default=True)
|
||||||
|
# guardian profile deleted or not"""
|
||||||
|
is_deleted = models.BooleanField(default=False)
|
||||||
"""Profile activity"""
|
"""Profile activity"""
|
||||||
is_active = models.BooleanField(default=True)
|
is_active = models.BooleanField(default=True)
|
||||||
"""guardian is verified or not"""
|
"""guardian is verified or not"""
|
||||||
|
|||||||
+45
-6
@@ -1,6 +1,7 @@
|
|||||||
"""Serializer of Guardian"""
|
"""Serializer of Guardian"""
|
||||||
# third party imports
|
# third party imports
|
||||||
import logging
|
import logging
|
||||||
|
from django.contrib.auth import password_validation
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
# Import Refresh token of jwt
|
# Import Refresh token of jwt
|
||||||
from rest_framework_simplejwt.tokens import RefreshToken
|
from rest_framework_simplejwt.tokens import RefreshToken
|
||||||
@@ -29,8 +30,9 @@ from .utils import real_time, convert_timedelta_into_datetime, update_referral_p
|
|||||||
# notification's constant
|
# notification's constant
|
||||||
from notifications.constants import TASK_POINTS, TASK_REJECTED
|
from notifications.constants import TASK_POINTS, TASK_REJECTED
|
||||||
# send notification function
|
# send notification function
|
||||||
from notifications.utils import send_notification
|
from notifications.utils import send_notification, send_notification_to_junior
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
# In this serializer file
|
# In this serializer file
|
||||||
# define user serializer,
|
# define user serializer,
|
||||||
@@ -42,10 +44,45 @@ from notifications.utils import send_notification
|
|||||||
# guardian profile serializer,
|
# guardian profile serializer,
|
||||||
# approve junior serializer,
|
# approve junior serializer,
|
||||||
# approve task serializer,
|
# approve task serializer,
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
class PasswordValidator:
|
||||||
|
def __init__(self, min_length=8, max_length=None, require_uppercase=True, require_numbers=True):
|
||||||
|
self.min_length = min_length
|
||||||
|
self.max_length = max_length
|
||||||
|
self.require_uppercase = require_uppercase
|
||||||
|
self.require_numbers = require_numbers
|
||||||
|
|
||||||
|
def __call__(self, value):
|
||||||
|
self.enforce_password_policy(value)
|
||||||
|
|
||||||
|
def enforce_password_policy(self, password):
|
||||||
|
special_characters = "!@#$%^&*()_-+=<>?/[]{}|"
|
||||||
|
if len(password) < self.min_length:
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
_("Password must be at least %(min_length)d characters long.") % {'min_length': self.min_length}
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.max_length is not None and len(password) > self.max_length:
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
_("Password must be at most %(max_length)d characters long.") % {'max_length': self.max_length}
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.require_uppercase and not any(char.isupper() for char in password):
|
||||||
|
raise serializers.ValidationError(_("Password must contain at least one uppercase letter."))
|
||||||
|
|
||||||
|
if self.require_numbers and not any(char.isdigit() for char in password):
|
||||||
|
raise serializers.ValidationError(_("Password must contain at least one digit."))
|
||||||
|
if self.require_numbers and not any(char in special_characters for char in password):
|
||||||
|
raise serializers.ValidationError(_("Password must contain at least one special character."))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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')
|
||||||
|
password = serializers.CharField(write_only=True, validators=[PasswordValidator()])
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
@@ -214,7 +251,7 @@ class GuardianDetailSerializer(serializers.ModelSerializer):
|
|||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
model = Guardian
|
model = Guardian
|
||||||
fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob',
|
fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob',
|
||||||
'guardian_code','is_active', 'is_complete_profile', 'created_at', 'image',
|
'guardian_code','is_active', 'is_complete_profile', 'created_at', 'image', 'is_deleted',
|
||||||
'updated_at']
|
'updated_at']
|
||||||
class TaskDetailsSerializer(serializers.ModelSerializer):
|
class TaskDetailsSerializer(serializers.ModelSerializer):
|
||||||
"""Task detail serializer"""
|
"""Task detail serializer"""
|
||||||
@@ -340,7 +377,7 @@ class GuardianProfileSerializer(serializers.ModelSerializer):
|
|||||||
fields = ['id', 'email', 'first_name', 'last_name', 'country_name','country_code', 'phone', 'gender', 'dob',
|
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',
|
'guardian_code', 'notification_count', 'total_count', 'complete_field_count', 'referral_code',
|
||||||
'is_active', 'is_complete_profile', 'created_at', 'image', 'signup_method',
|
'is_active', 'is_complete_profile', 'created_at', 'image', 'signup_method',
|
||||||
'updated_at', 'passcode']
|
'updated_at', 'passcode','is_deleted']
|
||||||
|
|
||||||
|
|
||||||
class ApproveJuniorSerializer(serializers.ModelSerializer):
|
class ApproveJuniorSerializer(serializers.ModelSerializer):
|
||||||
@@ -383,7 +420,8 @@ class ApproveTaskSerializer(serializers.ModelSerializer):
|
|||||||
# update complete time of task
|
# update complete time of task
|
||||||
# instance.completed_on = real_time()
|
# instance.completed_on = real_time()
|
||||||
instance.completed_on = timezone.now().astimezone(pytz.utc)
|
instance.completed_on = timezone.now().astimezone(pytz.utc)
|
||||||
send_notification.delay(TASK_POINTS, None, junior_details.auth.id, {})
|
send_notification_to_junior.delay(TASK_POINTS, None, junior_details.auth.id,
|
||||||
|
{'task_id': instance.id})
|
||||||
else:
|
else:
|
||||||
# reject the task
|
# reject the task
|
||||||
instance.task_status = str(NUMBER['three'])
|
instance.task_status = str(NUMBER['three'])
|
||||||
@@ -391,7 +429,8 @@ class ApproveTaskSerializer(serializers.ModelSerializer):
|
|||||||
# update reject time of task
|
# update reject time of task
|
||||||
# instance.rejected_on = real_time()
|
# instance.rejected_on = real_time()
|
||||||
instance.rejected_on = timezone.now().astimezone(pytz.utc)
|
instance.rejected_on = timezone.now().astimezone(pytz.utc)
|
||||||
send_notification.delay(TASK_REJECTED, None, junior_details.auth.id, {})
|
send_notification_to_junior.delay(TASK_REJECTED, None, junior_details.auth.id,
|
||||||
|
{'task_id': instance.id})
|
||||||
instance.save()
|
instance.save()
|
||||||
junior_data.save()
|
junior_data.save()
|
||||||
return junior_details
|
return junior_details
|
||||||
|
|||||||
+7
-2
@@ -1,7 +1,12 @@
|
|||||||
"""task files"""
|
"""task files"""
|
||||||
"""Django import"""
|
|
||||||
|
# Django import
|
||||||
import secrets
|
import secrets
|
||||||
|
|
||||||
|
|
||||||
def generate_otp():
|
def generate_otp():
|
||||||
"""generate random otp"""
|
"""
|
||||||
|
generate random otp
|
||||||
|
"""
|
||||||
digits = "0123456789"
|
digits = "0123456789"
|
||||||
return "".join(secrets.choice(digits) for _ in range(6))
|
return "".join(secrets.choice(digits) for _ in range(6))
|
||||||
|
|||||||
+39
-14
@@ -21,7 +21,9 @@ from zod_bank.celery import app
|
|||||||
# notification's constant
|
# notification's constant
|
||||||
from notifications.constants import REFERRAL_POINTS
|
from notifications.constants import REFERRAL_POINTS
|
||||||
# send notification function
|
# send notification function
|
||||||
from notifications.utils import send_notification
|
from notifications.utils import send_notification, send_notification_to_junior
|
||||||
|
|
||||||
|
|
||||||
# Define upload image on
|
# Define upload image on
|
||||||
# ali baba cloud
|
# ali baba cloud
|
||||||
# firstly save image
|
# firstly save image
|
||||||
@@ -41,18 +43,41 @@ def upload_image_to_alibaba(image, filename):
|
|||||||
# Save the image object to a temporary file
|
# Save the image object to a temporary file
|
||||||
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
||||||
"""write image in temporary file"""
|
"""write image in temporary file"""
|
||||||
if type(image) == bytes:
|
temp_file.write(image.read())
|
||||||
temp_file.write(image)
|
return upload_file_to_alibaba(temp_file, filename)
|
||||||
else:
|
|
||||||
temp_file.write(image.read())
|
|
||||||
"""auth of bucket"""
|
def upload_base64_image_to_alibaba(image, filename):
|
||||||
auth = oss2.Auth(settings.ALIYUN_OSS_ACCESS_KEY_ID, settings.ALIYUN_OSS_ACCESS_KEY_SECRET)
|
"""
|
||||||
"""fetch bucket details"""
|
upload image on oss alibaba bucket
|
||||||
bucket = oss2.Bucket(auth, settings.ALIYUN_OSS_ENDPOINT, settings.ALIYUN_OSS_BUCKET_NAME)
|
"""
|
||||||
# Upload the temporary file to Alibaba OSS
|
# Save the image object to a temporary file
|
||||||
bucket.put_object_from_file(filename, temp_file.name)
|
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
||||||
"""create perfect url for image"""
|
# write image in temporary file
|
||||||
new_filename = filename.replace(' ', '%20')
|
temp_file.write(image)
|
||||||
|
return upload_file_to_alibaba(temp_file, filename)
|
||||||
|
|
||||||
|
|
||||||
|
def upload_excel_file_to_alibaba(response, filename):
|
||||||
|
"""
|
||||||
|
upload excel file 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(response.content)
|
||||||
|
return upload_file_to_alibaba(temp_file, filename)
|
||||||
|
|
||||||
|
|
||||||
|
def upload_file_to_alibaba(temp_file, filename):
|
||||||
|
"""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}"
|
return f"https://{settings.ALIYUN_OSS_BUCKET_NAME}.{settings.ALIYUN_OSS_ENDPOINT}/{new_filename}"
|
||||||
|
|
||||||
|
|
||||||
@@ -92,7 +117,7 @@ def update_referral_points(referral_code, referral_code_used):
|
|||||||
junior_query.total_points = junior_query.total_points + NUMBER['five']
|
junior_query.total_points = junior_query.total_points + NUMBER['five']
|
||||||
junior_query.referral_points = junior_query.referral_points + NUMBER['five']
|
junior_query.referral_points = junior_query.referral_points + NUMBER['five']
|
||||||
junior_query.save()
|
junior_query.save()
|
||||||
send_notification.delay(REFERRAL_POINTS, None, junior_queryset.auth.id, {})
|
send_notification_to_junior.delay(REFERRAL_POINTS, None, junior_queryset.auth.id, {})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+37
-37
@@ -38,8 +38,8 @@ from account.utils import custom_response, custom_error_response, OTP_EXPIRY, se
|
|||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
from base.constants import NUMBER, GUARDIAN_CODE_STATUS
|
from base.constants import NUMBER, GUARDIAN_CODE_STATUS
|
||||||
from .utils import upload_image_to_alibaba
|
from .utils import upload_image_to_alibaba
|
||||||
from notifications.constants import REGISTRATION, TASK_CREATED, LEADERBOARD_RANKING
|
from notifications.constants import REGISTRATION, TASK_ASSIGNED, LEADERBOARD_RANKING
|
||||||
from notifications.utils import send_notification
|
from notifications.utils import send_notification_to_junior
|
||||||
|
|
||||||
""" Define APIs """
|
""" Define APIs """
|
||||||
# Define Signup API,
|
# Define Signup API,
|
||||||
@@ -62,18 +62,16 @@ class SignupViewset(viewsets.ModelViewSet):
|
|||||||
if request.data['user_type'] in [str(NUMBER['one']), str(NUMBER['two'])]:
|
if request.data['user_type'] in [str(NUMBER['one']), str(NUMBER['two'])]:
|
||||||
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():
|
||||||
user = serializer.save()
|
serializer.save()
|
||||||
"""Generate otp"""
|
"""Generate otp"""
|
||||||
otp = generate_otp()
|
otp = generate_otp()
|
||||||
# expire otp after 1 day
|
# expire otp after 1 day
|
||||||
expiry = OTP_EXPIRY
|
expiry = timezone.now() + timezone.timedelta(days=1)
|
||||||
# create user email otp object
|
# create user email otp object
|
||||||
UserEmailOtp.objects.create(email=request.data['email'], otp=otp,
|
UserEmailOtp.objects.create(email=request.data['email'], otp=otp,
|
||||||
user_type=str(request.data['user_type']), expired_at=expiry)
|
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)
|
||||||
# send push notification for registration
|
|
||||||
send_notification.delay(REGISTRATION, None, user.id, {})
|
|
||||||
return custom_response(SUCCESS_CODE['3001'],
|
return custom_response(SUCCESS_CODE['3001'],
|
||||||
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)
|
||||||
@@ -81,7 +79,9 @@ class SignupViewset(viewsets.ModelViewSet):
|
|||||||
return custom_error_response(ERROR_CODE['2028'], response_status=status.HTTP_400_BAD_REQUEST)
|
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
|
||||||
|
"""
|
||||||
serializer_class = CreateGuardianSerializer
|
serializer_class = CreateGuardianSerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
@@ -166,6 +166,10 @@ class CreateTaskAPIView(viewsets.ModelViewSet):
|
|||||||
try:
|
try:
|
||||||
image = request.data['default_image']
|
image = request.data['default_image']
|
||||||
junior = request.data['junior']
|
junior = request.data['junior']
|
||||||
|
junior_id = Junior.objects.filter(id=junior).last()
|
||||||
|
guardian_data = Guardian.objects.filter(user=request.user).last()
|
||||||
|
if guardian_data.guardian_code in junior_id.guardian_code:
|
||||||
|
return custom_error_response(ERROR_CODE['2078'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
allowed_extensions = ['.jpg', '.jpeg', '.png']
|
allowed_extensions = ['.jpg', '.jpeg', '.png']
|
||||||
if not any(extension in str(image) for extension in allowed_extensions):
|
if not any(extension in str(image) for extension in allowed_extensions):
|
||||||
return custom_error_response(ERROR_CODE['2048'], response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(ERROR_CODE['2048'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
@@ -186,9 +190,10 @@ class CreateTaskAPIView(viewsets.ModelViewSet):
|
|||||||
serializer = TaskSerializer(context={"user":request.user, "image":image_data}, data=data)
|
serializer = TaskSerializer(context={"user":request.user, "image":image_data}, data=data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
# save serializer
|
# save serializer
|
||||||
serializer.save()
|
task = serializer.save()
|
||||||
junior_id = Junior.objects.filter(id=junior).last()
|
|
||||||
send_notification.delay(TASK_CREATED, None, junior_id.auth.id, {})
|
send_notification_to_junior.delay(TASK_ASSIGNED, request.auth.payload['user_id'],
|
||||||
|
junior_id.auth.id, {'task_id': task.id})
|
||||||
return custom_response(SUCCESS_CODE['3018'], serializer.data, response_status=status.HTTP_200_OK)
|
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)
|
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -241,7 +246,7 @@ class TopJuniorListAPIView(viewsets.ModelViewSet):
|
|||||||
# Update the position field for each JuniorPoints object
|
# Update the position field for each JuniorPoints object
|
||||||
for index, junior in enumerate(junior_total_points):
|
for index, junior in enumerate(junior_total_points):
|
||||||
junior.position = index + 1
|
junior.position = index + 1
|
||||||
send_notification.delay(LEADERBOARD_RANKING, None, junior.junior.auth.id, {})
|
# send_notification_to_junior.delay(LEADERBOARD_RANKING, None, junior.junior.auth.id, {})
|
||||||
junior.save()
|
junior.save()
|
||||||
serializer = self.get_serializer(junior_total_points[:NUMBER['fifteen']], many=True)
|
serializer = self.get_serializer(junior_total_points[:NUMBER['fifteen']], many=True)
|
||||||
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
@@ -254,31 +259,29 @@ class ApproveJuniorAPIView(viewsets.ViewSet):
|
|||||||
serializer_class = ApproveJuniorSerializer
|
serializer_class = ApproveJuniorSerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
"""Get the queryset for the view"""
|
|
||||||
guardian = Guardian.objects.filter(user__email=self.request.user).last()
|
|
||||||
# fetch junior query
|
|
||||||
junior_queryset = Junior.objects.filter(id=self.request.data.get('junior_id')).last()
|
|
||||||
return guardian, junior_queryset
|
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
""" junior list"""
|
""" junior list"""
|
||||||
try:
|
try:
|
||||||
queryset = self.get_queryset()
|
guardian = Guardian.objects.filter(user__email=self.request.user).last()
|
||||||
|
# fetch junior query
|
||||||
|
junior_queryset = Junior.objects.filter(id=self.request.data.get('junior_id')).last()
|
||||||
|
if junior_queryset and (junior_queryset.is_deleted or not junior_queryset.is_active):
|
||||||
|
return custom_error_response(ERROR_CODE['2073'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
# action 1 is use for approve and 2 for reject
|
# action 1 is use for approve and 2 for reject
|
||||||
if request.data['action'] == '1':
|
if request.data['action'] == '1':
|
||||||
# use ApproveJuniorSerializer serializer
|
# use ApproveJuniorSerializer serializer
|
||||||
serializer = ApproveJuniorSerializer(context={"guardian_code": queryset[0].guardian_code,
|
serializer = ApproveJuniorSerializer(context={"guardian_code": guardian.guardian_code,
|
||||||
"junior": queryset[1], "action": request.data['action']},
|
"junior": junior_queryset, "action": request.data['action']},
|
||||||
data=request.data)
|
data=request.data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
# save serializer
|
# save serializer
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return custom_response(SUCCESS_CODE['3023'], serializer.data, response_status=status.HTTP_200_OK)
|
return custom_response(SUCCESS_CODE['3023'], serializer.data, response_status=status.HTTP_200_OK)
|
||||||
else:
|
else:
|
||||||
queryset[1].guardian_code = None
|
junior_queryset.guardian_code = None
|
||||||
queryset[1].guardian_code_status = str(NUMBER['one'])
|
junior_queryset.guardian_code_status = str(NUMBER['one'])
|
||||||
queryset[1].save()
|
junior_queryset.save()
|
||||||
return custom_response(SUCCESS_CODE['3024'], response_status=status.HTTP_200_OK)
|
return custom_response(SUCCESS_CODE['3024'], response_status=status.HTTP_200_OK)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
@@ -289,34 +292,31 @@ class ApproveTaskAPIView(viewsets.ViewSet):
|
|||||||
serializer_class = ApproveTaskSerializer
|
serializer_class = ApproveTaskSerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
"""Get the queryset for the view"""
|
|
||||||
guardian = Guardian.objects.filter(user__email=self.request.user).last()
|
|
||||||
# task query
|
|
||||||
task_queryset = JuniorTask.objects.filter(id=self.request.data.get('task_id'),
|
|
||||||
guardian=guardian,
|
|
||||||
junior=self.request.data.get('junior_id')).last()
|
|
||||||
return guardian, task_queryset
|
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
""" junior list"""
|
""" junior list"""
|
||||||
# action 1 is use for approve and 2 for reject
|
# action 1 is use for approve and 2 for reject
|
||||||
try:
|
try:
|
||||||
queryset = self.get_queryset()
|
guardian = Guardian.objects.filter(user__email=self.request.user).last()
|
||||||
|
# task query
|
||||||
|
task_queryset = JuniorTask.objects.filter(id=self.request.data.get('task_id'),
|
||||||
|
guardian=guardian,
|
||||||
|
junior=self.request.data.get('junior_id')).last()
|
||||||
|
if task_queryset and (task_queryset.junior.is_deleted or not task_queryset.junior.is_active):
|
||||||
|
return custom_error_response(ERROR_CODE['2072'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
# use ApproveJuniorSerializer serializer
|
# use ApproveJuniorSerializer serializer
|
||||||
serializer = ApproveTaskSerializer(context={"guardian_code": queryset[0].guardian_code,
|
serializer = ApproveTaskSerializer(context={"guardian_code": guardian.guardian_code,
|
||||||
"task_instance": queryset[1],
|
"task_instance": task_queryset,
|
||||||
"action": str(request.data['action']),
|
"action": str(request.data['action']),
|
||||||
"junior": self.request.data['junior_id']},
|
"junior": self.request.data['junior_id']},
|
||||||
data=request.data)
|
data=request.data)
|
||||||
unexpected_task_status = [str(NUMBER['five']), str(NUMBER['six'])]
|
unexpected_task_status = [str(NUMBER['five']), str(NUMBER['six'])]
|
||||||
if (str(request.data['action']) == str(NUMBER['one']) and serializer.is_valid()
|
if (str(request.data['action']) == str(NUMBER['one']) and serializer.is_valid()
|
||||||
and queryset[1] and queryset[1].task_status not in unexpected_task_status):
|
and task_queryset and task_queryset.task_status not in unexpected_task_status):
|
||||||
# save serializer
|
# save serializer
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return custom_response(SUCCESS_CODE['3025'], response_status=status.HTTP_200_OK)
|
return custom_response(SUCCESS_CODE['3025'], response_status=status.HTTP_200_OK)
|
||||||
elif (str(request.data['action']) == str(NUMBER['two']) and serializer.is_valid()
|
elif (str(request.data['action']) == str(NUMBER['two']) and serializer.is_valid()
|
||||||
and queryset[1] and queryset[1].task_status not in unexpected_task_status):
|
and task_queryset and task_queryset.task_status not in unexpected_task_status):
|
||||||
# save serializer
|
# save serializer
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return custom_response(SUCCESS_CODE['3026'], response_status=status.HTTP_200_OK)
|
return custom_response(SUCCESS_CODE['3026'], response_status=status.HTTP_200_OK)
|
||||||
|
|||||||
+2
-1
@@ -3,8 +3,9 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
"""Import Django app"""
|
"""Import Django app"""
|
||||||
from .models import (Junior, JuniorPoints, JuniorGuardianRelationship, JuniorArticlePoints, JuniorArticle,
|
from .models import (Junior, JuniorPoints, JuniorGuardianRelationship, JuniorArticlePoints, JuniorArticle,
|
||||||
JuniorArticleCard)
|
JuniorArticleCard, FAQ)
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
|
admin.site.register(FAQ)
|
||||||
@admin.register(JuniorArticle)
|
@admin.register(JuniorArticle)
|
||||||
class JuniorArticleAdmin(admin.ModelAdmin):
|
class JuniorArticleAdmin(admin.ModelAdmin):
|
||||||
"""Junior Admin"""
|
"""Junior Admin"""
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-08-17 09:04
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0025_alter_juniorarticle_junior'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='FAQ',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('question', models.IntegerField(max_length=100)),
|
||||||
|
('description', models.CharField(max_length=500)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'FAQ',
|
||||||
|
'verbose_name_plural': 'FAQ',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='juniorarticle',
|
||||||
|
options={'verbose_name': 'Junior Article', 'verbose_name_plural': 'Junior Article'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='juniorarticlecard',
|
||||||
|
options={'verbose_name': 'Junior Article Card', 'verbose_name_plural': 'Junior Article Card'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='juniorarticlepoints',
|
||||||
|
options={'verbose_name': 'Junior Article Points', 'verbose_name_plural': 'Junior Article Points'},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-08-17 09:37
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0026_faq_alter_juniorarticle_options_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='faq',
|
||||||
|
name='question',
|
||||||
|
field=models.CharField(max_length=100),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-08-17 10:28
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0027_alter_faq_question'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='faq',
|
||||||
|
name='status',
|
||||||
|
field=models.IntegerField(blank=True, default=1, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.2 on 2023-08-17 12:45
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('junior', '0028_faq_status'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='junior',
|
||||||
|
name='is_deleted',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -68,6 +68,8 @@ class Junior(models.Model):
|
|||||||
is_password_set = models.BooleanField(default=True)
|
is_password_set = models.BooleanField(default=True)
|
||||||
# junior profile is complete or not"""
|
# junior profile is complete or not"""
|
||||||
is_complete_profile = models.BooleanField(default=False)
|
is_complete_profile = models.BooleanField(default=False)
|
||||||
|
# junior profile deleted or not"""
|
||||||
|
is_deleted = models.BooleanField(default=False)
|
||||||
# passcode of the junior profile"""
|
# passcode of the junior profile"""
|
||||||
passcode = models.IntegerField(null=True, blank=True, default=None)
|
passcode = models.IntegerField(null=True, blank=True, default=None)
|
||||||
# junior is verified or not"""
|
# junior is verified or not"""
|
||||||
@@ -158,6 +160,12 @@ class JuniorArticlePoints(models.Model):
|
|||||||
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)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
""" Meta class """
|
||||||
|
verbose_name = 'Junior Article Points'
|
||||||
|
# another name of the model"""
|
||||||
|
verbose_name_plural = 'Junior Article Points'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Return title"""
|
"""Return title"""
|
||||||
return f'{self.id} | {self.question}'
|
return f'{self.id} | {self.question}'
|
||||||
@@ -178,6 +186,12 @@ class JuniorArticle(models.Model):
|
|||||||
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)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
""" Meta class """
|
||||||
|
verbose_name = 'Junior Article'
|
||||||
|
# another name of the model"""
|
||||||
|
verbose_name_plural = 'Junior Article'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Return title"""
|
"""Return title"""
|
||||||
return f'{self.id} | {self.article}'
|
return f'{self.id} | {self.article}'
|
||||||
@@ -197,6 +211,34 @@ class JuniorArticleCard(models.Model):
|
|||||||
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)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
""" Meta class """
|
||||||
|
verbose_name = 'Junior Article Card'
|
||||||
|
# another name of the model"""
|
||||||
|
verbose_name_plural = 'Junior Article Card'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Return title"""
|
"""Return title"""
|
||||||
return f'{self.id} | {self.article}'
|
return f'{self.id} | {self.article}'
|
||||||
|
|
||||||
|
|
||||||
|
class FAQ(models.Model):
|
||||||
|
"""FAQ model"""
|
||||||
|
# questions"""
|
||||||
|
question = models.CharField(max_length=100)
|
||||||
|
# answer"""
|
||||||
|
description = models.CharField(max_length=500)
|
||||||
|
# status
|
||||||
|
status = models.IntegerField(default=1, null=True, blank=True)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
""" Meta class """
|
||||||
|
verbose_name = 'FAQ'
|
||||||
|
# another name of the model"""
|
||||||
|
verbose_name_plural = 'FAQ'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""Return email id"""
|
||||||
|
return f'{self.question}'
|
||||||
|
|||||||
+25
-13
@@ -12,7 +12,7 @@ from rest_framework_simplejwt.tokens import RefreshToken
|
|||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from account.utils import send_otp_email, generate_code
|
from account.utils import send_otp_email, generate_code
|
||||||
from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship, JuniorArticlePoints
|
from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship, JuniorArticlePoints, FAQ
|
||||||
from guardian.tasks import generate_otp
|
from guardian.tasks import generate_otp
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
from base.constants import (PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, NUMBER, JUN, ZOD, EXPIRED,
|
from base.constants import (PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, NUMBER, JUN, ZOD, EXPIRED,
|
||||||
@@ -21,7 +21,7 @@ from guardian.models import Guardian, JuniorTask
|
|||||||
from account.models import UserEmailOtp, UserNotification
|
from account.models import UserEmailOtp, UserNotification
|
||||||
from junior.utils import junior_notification_email, junior_approval_mail
|
from junior.utils import junior_notification_email, junior_approval_mail
|
||||||
from guardian.utils import real_time, update_referral_points, convert_timedelta_into_datetime
|
from guardian.utils import real_time, update_referral_points, convert_timedelta_into_datetime
|
||||||
from notifications.utils import send_notification
|
from notifications.utils import send_notification, send_notification_to_junior, send_notification_to_guardian
|
||||||
from notifications.constants import (INVITED_GUARDIAN, APPROVED_JUNIOR, SKIPPED_PROFILE_SETUP, TASK_ACTION,
|
from notifications.constants import (INVITED_GUARDIAN, APPROVED_JUNIOR, SKIPPED_PROFILE_SETUP, TASK_ACTION,
|
||||||
TASK_SUBMITTED)
|
TASK_SUBMITTED)
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
|
|||||||
JuniorGuardianRelationship.objects.get_or_create(guardian=guardian_data, junior=junior)
|
JuniorGuardianRelationship.objects.get_or_create(guardian=guardian_data, junior=junior)
|
||||||
junior.guardian_code_status = str(NUMBER['three'])
|
junior.guardian_code_status = str(NUMBER['three'])
|
||||||
junior_approval_mail(user.email, user.first_name)
|
junior_approval_mail(user.email, user.first_name)
|
||||||
send_notification.delay(APPROVED_JUNIOR, None, guardian_data.user.id, {})
|
send_notification_to_guardian.delay(APPROVED_JUNIOR, junior.auth.id, guardian_data.user.id, {})
|
||||||
junior.dob = validated_data.get('dob', junior.dob)
|
junior.dob = validated_data.get('dob', junior.dob)
|
||||||
junior.passcode = validated_data.get('passcode', junior.passcode)
|
junior.passcode = validated_data.get('passcode', junior.passcode)
|
||||||
junior.country_name = validated_data.get('country_name', junior.country_name)
|
junior.country_name = validated_data.get('country_name', junior.country_name)
|
||||||
@@ -147,7 +147,7 @@ class JuniorDetailSerializer(serializers.ModelSerializer):
|
|||||||
model = Junior
|
model = Junior
|
||||||
fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob',
|
fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob',
|
||||||
'guardian_code', 'image', 'is_invited', 'referral_code','is_active', 'is_complete_profile',
|
'guardian_code', 'image', 'is_invited', 'referral_code','is_active', 'is_complete_profile',
|
||||||
'created_at', 'image', 'updated_at']
|
'created_at', 'image', 'is_deleted', 'updated_at']
|
||||||
|
|
||||||
class JuniorDetailListSerializer(serializers.ModelSerializer):
|
class JuniorDetailListSerializer(serializers.ModelSerializer):
|
||||||
"""junior serializer"""
|
"""junior serializer"""
|
||||||
@@ -214,7 +214,8 @@ class JuniorDetailListSerializer(serializers.ModelSerializer):
|
|||||||
fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'country_name', 'phone', 'gender', 'dob',
|
fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'country_name', 'phone', 'gender', 'dob',
|
||||||
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image',
|
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image',
|
||||||
'updated_at', 'assigned_task','points', 'pending_task', 'in_progress_task', 'completed_task',
|
'updated_at', 'assigned_task','points', 'pending_task', 'in_progress_task', 'completed_task',
|
||||||
'requested_task', 'rejected_task', 'position', 'is_invited', 'guardian_code_status']
|
'requested_task', 'rejected_task', 'position', 'is_invited', 'guardian_code_status',
|
||||||
|
'is_deleted']
|
||||||
|
|
||||||
class JuniorProfileSerializer(serializers.ModelSerializer):
|
class JuniorProfileSerializer(serializers.ModelSerializer):
|
||||||
"""junior serializer"""
|
"""junior serializer"""
|
||||||
@@ -257,7 +258,7 @@ class JuniorProfileSerializer(serializers.ModelSerializer):
|
|||||||
fields = ['id', 'email', 'first_name', 'last_name', 'country_name', 'country_code', 'phone', 'gender', 'dob',
|
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',
|
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image',
|
||||||
'updated_at', 'notification_count', 'total_count', 'complete_field_count', 'signup_method',
|
'updated_at', 'notification_count', 'total_count', 'complete_field_count', 'signup_method',
|
||||||
'is_invited', 'passcode', 'guardian_code_approved']
|
'is_invited', 'passcode', 'guardian_code_approved', 'is_deleted']
|
||||||
|
|
||||||
class AddJuniorSerializer(serializers.ModelSerializer):
|
class AddJuniorSerializer(serializers.ModelSerializer):
|
||||||
"""Add junior serializer"""
|
"""Add junior serializer"""
|
||||||
@@ -305,7 +306,7 @@ class AddJuniorSerializer(serializers.ModelSerializer):
|
|||||||
"""Notification email"""
|
"""Notification email"""
|
||||||
junior_notification_email(email, full_name, email, password)
|
junior_notification_email(email, full_name, email, password)
|
||||||
# push notification
|
# push notification
|
||||||
send_notification.delay(SKIPPED_PROFILE_SETUP, None, junior_data.auth.id, {})
|
send_notification_to_junior.delay(SKIPPED_PROFILE_SETUP, None, junior_data.auth.id, {})
|
||||||
return junior_data
|
return junior_data
|
||||||
|
|
||||||
|
|
||||||
@@ -320,7 +321,7 @@ class RemoveJuniorSerializer(serializers.ModelSerializer):
|
|||||||
if instance:
|
if instance:
|
||||||
instance.is_invited = False
|
instance.is_invited = False
|
||||||
instance.guardian_code = '{}'
|
instance.guardian_code = '{}'
|
||||||
instance.guardian_code_status = str(NUMBER['1'])
|
instance.guardian_code_status = str(NUMBER['one'])
|
||||||
instance.save()
|
instance.save()
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
@@ -337,8 +338,10 @@ class CompleteTaskSerializer(serializers.ModelSerializer):
|
|||||||
instance.task_status = str(NUMBER['four'])
|
instance.task_status = str(NUMBER['four'])
|
||||||
instance.is_approved = False
|
instance.is_approved = False
|
||||||
instance.save()
|
instance.save()
|
||||||
send_notification.delay(TASK_SUBMITTED, None, instance.junior.auth.id, {})
|
send_notification_to_junior.delay(TASK_SUBMITTED, instance.guardian.user.id,
|
||||||
send_notification.delay(TASK_ACTION, None, instance.guardian.user.id, {})
|
instance.junior.auth.id, {'task_id': instance.id})
|
||||||
|
send_notification_to_guardian.delay(TASK_ACTION, instance.junior.auth.id,
|
||||||
|
instance.guardian.user.id, {'task_id': instance.id})
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
class JuniorPointsSerializer(serializers.ModelSerializer):
|
class JuniorPointsSerializer(serializers.ModelSerializer):
|
||||||
@@ -393,7 +396,7 @@ class JuniorPointsSerializer(serializers.ModelSerializer):
|
|||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
model = Junior
|
model = Junior
|
||||||
fields = ['junior_id', 'total_points', 'position', 'pending_task', 'in_progress_task', 'completed_task',
|
fields = ['junior_id', 'total_points', 'position', 'pending_task', 'in_progress_task', 'completed_task',
|
||||||
'requested_task', 'rejected_task', 'expired_task']
|
'requested_task', 'rejected_task', 'expired_task', 'is_deleted']
|
||||||
|
|
||||||
class AddGuardianSerializer(serializers.ModelSerializer):
|
class AddGuardianSerializer(serializers.ModelSerializer):
|
||||||
"""Add guardian serializer"""
|
"""Add guardian serializer"""
|
||||||
@@ -448,8 +451,8 @@ class AddGuardianSerializer(serializers.ModelSerializer):
|
|||||||
"""Notification email"""
|
"""Notification email"""
|
||||||
junior_notification_email(email, full_name, email, password)
|
junior_notification_email(email, full_name, email, password)
|
||||||
junior_approval_mail(email, full_name)
|
junior_approval_mail(email, full_name)
|
||||||
send_notification.delay(INVITED_GUARDIAN, None, junior_data.auth.id, {})
|
send_notification_to_junior.delay(INVITED_GUARDIAN, guardian_data.user.id, junior_data.auth.id, {})
|
||||||
send_notification.delay(APPROVED_JUNIOR, None, guardian_data.user.id, {})
|
send_notification_to_guardian.delay(APPROVED_JUNIOR, junior_data.auth.id, guardian_data.user.id, {})
|
||||||
return guardian_data
|
return guardian_data
|
||||||
|
|
||||||
class StartTaskSerializer(serializers.ModelSerializer):
|
class StartTaskSerializer(serializers.ModelSerializer):
|
||||||
@@ -506,3 +509,12 @@ class RemoveGuardianCodeSerializer(serializers.ModelSerializer):
|
|||||||
instance.guardian_code_status = str(NUMBER['one'])
|
instance.guardian_code_status = str(NUMBER['one'])
|
||||||
instance.save()
|
instance.save()
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
class FAQSerializer(serializers.ModelSerializer):
|
||||||
|
# FAQ Serializer
|
||||||
|
|
||||||
|
class Meta(object):
|
||||||
|
# meta info
|
||||||
|
model = FAQ
|
||||||
|
fields = ('id', 'question', 'description')
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -6,7 +6,7 @@ from .views import (UpdateJuniorProfile, ValidateGuardianCode, JuniorListAPIView
|
|||||||
CompleteJuniorTaskAPIView, JuniorPointsListAPIView, ValidateReferralCode,
|
CompleteJuniorTaskAPIView, JuniorPointsListAPIView, ValidateReferralCode,
|
||||||
InviteGuardianAPIView, StartTaskAPIView, ReAssignJuniorTaskAPIView, StartArticleAPIView,
|
InviteGuardianAPIView, StartTaskAPIView, ReAssignJuniorTaskAPIView, StartArticleAPIView,
|
||||||
StartAssessmentAPIView, CheckAnswerAPIView, CompleteArticleAPIView, ReadArticleCardAPIView,
|
StartAssessmentAPIView, CheckAnswerAPIView, CompleteArticleAPIView, ReadArticleCardAPIView,
|
||||||
CreateArticleCardAPIView, RemoveGuardianCodeAPIView)
|
CreateArticleCardAPIView, RemoveGuardianCodeAPIView, FAQViewSet)
|
||||||
"""Third party import"""
|
"""Third party import"""
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
@@ -51,6 +51,8 @@ router.register('start-assessment', StartAssessmentAPIView, basename='start-asse
|
|||||||
router.register('check-answer', CheckAnswerAPIView, basename='check-answer')
|
router.register('check-answer', CheckAnswerAPIView, basename='check-answer')
|
||||||
# start article"""
|
# start article"""
|
||||||
router.register('create-article-card', CreateArticleCardAPIView, basename='create-article-card')
|
router.register('create-article-card', CreateArticleCardAPIView, basename='create-article-card')
|
||||||
|
# FAQ API
|
||||||
|
router.register('faq', FAQViewSet, basename='faq')
|
||||||
# Define url pattern"""
|
# Define url pattern"""
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('api/v1/', include(router.urls)),
|
path('api/v1/', include(router.urls)),
|
||||||
|
|||||||
+71
-9
@@ -10,6 +10,8 @@ from django.db.models import F
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
from rest_framework.viewsets import GenericViewSet, mixins
|
||||||
"""Django app import"""
|
"""Django app import"""
|
||||||
|
|
||||||
# Import guardian's model,
|
# Import guardian's model,
|
||||||
@@ -30,19 +32,19 @@ import requests
|
|||||||
# Import constants
|
# Import constants
|
||||||
from django.db.models import Sum
|
from django.db.models import Sum
|
||||||
from junior.models import (Junior, JuniorPoints, JuniorGuardianRelationship, JuniorArticlePoints, JuniorArticle,
|
from junior.models import (Junior, JuniorPoints, JuniorGuardianRelationship, JuniorArticlePoints, JuniorArticle,
|
||||||
JuniorArticleCard)
|
JuniorArticleCard, FAQ)
|
||||||
from .serializers import (CreateJuniorSerializer, JuniorDetailListSerializer, AddJuniorSerializer,
|
from .serializers import (CreateJuniorSerializer, JuniorDetailListSerializer, AddJuniorSerializer,
|
||||||
RemoveJuniorSerializer, CompleteTaskSerializer, JuniorPointsSerializer,
|
RemoveJuniorSerializer, CompleteTaskSerializer, JuniorPointsSerializer,
|
||||||
AddGuardianSerializer, StartTaskSerializer, ReAssignTaskSerializer,
|
AddGuardianSerializer, StartTaskSerializer, ReAssignTaskSerializer,
|
||||||
RemoveGuardianCodeSerializer)
|
RemoveGuardianCodeSerializer, FAQSerializer)
|
||||||
from guardian.models import Guardian, JuniorTask
|
from guardian.models import Guardian, JuniorTask
|
||||||
from guardian.serializers import TaskDetailsSerializer, TaskDetailsjuniorSerializer
|
from guardian.serializers import TaskDetailsSerializer, TaskDetailsjuniorSerializer
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
from base.constants import NUMBER, ARTICLE_STATUS
|
from base.constants import NUMBER, ARTICLE_STATUS, none
|
||||||
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
|
from guardian.utils import upload_image_to_alibaba
|
||||||
from .utils import update_positions_based_on_points
|
from .utils import update_positions_based_on_points
|
||||||
from notifications.utils import send_notification
|
from notifications.utils import send_notification, send_notification_to_junior
|
||||||
from notifications.constants import REMOVE_JUNIOR
|
from notifications.constants import REMOVE_JUNIOR
|
||||||
from web_admin.models import Article, ArticleSurvey, SurveyOption, ArticleCard
|
from web_admin.models import Article, ArticleSurvey, SurveyOption, ArticleCard
|
||||||
from web_admin.serializers.article_serializer import (ArticleSerializer, ArticleListSerializer,
|
from web_admin.serializers.article_serializer import (ArticleSerializer, ArticleListSerializer,
|
||||||
@@ -169,7 +171,11 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
|
|||||||
image_url = upload_image_to_alibaba(profile_image, filename)
|
image_url = upload_image_to_alibaba(profile_image, filename)
|
||||||
info_data.update({"image": image_url})
|
info_data.update({"image": image_url})
|
||||||
if user := User.objects.filter(username=request.data['email']).first():
|
if user := User.objects.filter(username=request.data['email']).first():
|
||||||
self.associate_guardian(user)
|
data = self.associate_guardian(user)
|
||||||
|
if data == none:
|
||||||
|
return custom_error_response(ERROR_CODE['2077'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
elif not data:
|
||||||
|
return custom_error_response(ERROR_CODE['2076'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
return custom_response(SUCCESS_CODE['3021'], response_status=status.HTTP_200_OK)
|
return custom_response(SUCCESS_CODE['3021'], response_status=status.HTTP_200_OK)
|
||||||
# use AddJuniorSerializer serializer
|
# use AddJuniorSerializer serializer
|
||||||
serializer = AddJuniorSerializer(data=request.data, context=info_data)
|
serializer = AddJuniorSerializer(data=request.data, context=info_data)
|
||||||
@@ -182,9 +188,16 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
|
|||||||
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
def associate_guardian(self, user):
|
def associate_guardian(self, user):
|
||||||
junior = Junior.objects.filter(auth=user).first()
|
junior = Junior.objects.filter(auth__email=self.request.data['email']).first()
|
||||||
guardian = Guardian.objects.filter(user=self.request.user).first()
|
guardian = Guardian.objects.filter(user=self.request.user).first()
|
||||||
junior.guardian_code = [guardian.guardian_code]
|
if not junior:
|
||||||
|
return none
|
||||||
|
if guardian.guardian_code in junior.guardian_code:
|
||||||
|
return False
|
||||||
|
if type(junior.guardian_code) is list:
|
||||||
|
junior.guardian_code.append(guardian.guardian_code)
|
||||||
|
else:
|
||||||
|
junior.guardian_code = [guardian.guardian_code]
|
||||||
junior.guardian_code_status = str(NUMBER['two'])
|
junior.guardian_code_status = str(NUMBER['two'])
|
||||||
junior.save()
|
junior.save()
|
||||||
JuniorGuardianRelationship.objects.get_or_create(guardian=guardian, junior=junior,
|
JuniorGuardianRelationship.objects.get_or_create(guardian=guardian, junior=junior,
|
||||||
@@ -269,7 +282,7 @@ class RemoveJuniorAPIView(views.APIView):
|
|||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
# save serializer
|
# save serializer
|
||||||
serializer.save()
|
serializer.save()
|
||||||
send_notification.delay(REMOVE_JUNIOR, None, junior_queryset.auth.id, {})
|
send_notification_to_junior.delay(REMOVE_JUNIOR, None, junior_queryset.auth.id, {})
|
||||||
return custom_response(SUCCESS_CODE['3022'], serializer.data, response_status=status.HTTP_200_OK)
|
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)
|
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
else:
|
else:
|
||||||
@@ -334,8 +347,11 @@ class CompleteJuniorTaskAPIView(views.APIView):
|
|||||||
|
|
||||||
image_url = upload_image_to_alibaba(image, filename)
|
image_url = upload_image_to_alibaba(image, filename)
|
||||||
# fetch junior query
|
# fetch junior query
|
||||||
task_queryset = JuniorTask.objects.filter(id=task_id, junior__auth__email=self.request.user).last()
|
task_queryset = JuniorTask.objects.filter(id=task_id, junior__auth__email=self.request.user
|
||||||
|
).select_related('guardian', 'junior').last()
|
||||||
if task_queryset:
|
if task_queryset:
|
||||||
|
if task_queryset.junior.is_deleted or not task_queryset.junior.is_active:
|
||||||
|
return custom_error_response(ERROR_CODE['2074'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
# use CompleteTaskSerializer serializer
|
# use CompleteTaskSerializer serializer
|
||||||
if task_queryset.task_status in [str(NUMBER['four']), str(NUMBER['five'])]:
|
if task_queryset.task_status in [str(NUMBER['four']), str(NUMBER['five'])]:
|
||||||
"""Already request send """
|
"""Already request send """
|
||||||
@@ -649,3 +665,49 @@ class RemoveGuardianCodeAPIView(views.APIView):
|
|||||||
return custom_error_response(ERROR_CODE['2047'], response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(ERROR_CODE['2047'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
|
class FAQViewSet(GenericViewSet, mixins.CreateModelMixin,
|
||||||
|
mixins.ListModelMixin):
|
||||||
|
"""FAQ view set"""
|
||||||
|
|
||||||
|
serializer_class = FAQSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
http_method_names = ['get', 'post']
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return FAQ.objects.all()
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
faq create api method
|
||||||
|
:param request:
|
||||||
|
:param args:
|
||||||
|
:param kwargs:
|
||||||
|
:return: success message
|
||||||
|
"""
|
||||||
|
obj_data = [FAQ(**item) for item in request.data]
|
||||||
|
try:
|
||||||
|
FAQ.objects.bulk_create(obj_data)
|
||||||
|
return custom_response(SUCCESS_CODE["3045"], response_status=status.HTTP_200_OK)
|
||||||
|
except Exception as e:
|
||||||
|
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
article list api method
|
||||||
|
:param request:
|
||||||
|
:param args:
|
||||||
|
:param kwargs:
|
||||||
|
:return: list of article
|
||||||
|
"""
|
||||||
|
queryset = self.get_queryset()
|
||||||
|
paginator = self.pagination_class()
|
||||||
|
paginated_queryset = paginator.paginate_queryset(queryset, request)
|
||||||
|
serializer = self.serializer_class(paginated_queryset, many=True)
|
||||||
|
return custom_response(None, data=serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -3,7 +3,7 @@ notification constants file
|
|||||||
"""
|
"""
|
||||||
from base.constants import NUMBER
|
from base.constants import NUMBER
|
||||||
REGISTRATION = NUMBER['one']
|
REGISTRATION = NUMBER['one']
|
||||||
TASK_CREATED = NUMBER['two']
|
TASK_ASSIGNED = NUMBER['two']
|
||||||
INVITED_GUARDIAN = NUMBER['three']
|
INVITED_GUARDIAN = NUMBER['three']
|
||||||
APPROVED_JUNIOR = NUMBER['four']
|
APPROVED_JUNIOR = NUMBER['four']
|
||||||
REFERRAL_POINTS = NUMBER['five']
|
REFERRAL_POINTS = NUMBER['five']
|
||||||
@@ -21,17 +21,17 @@ NOTIFICATION_DICT = {
|
|||||||
"title": "Successfully registered!",
|
"title": "Successfully registered!",
|
||||||
"body": "You have registered successfully. Now login and complete your profile."
|
"body": "You have registered successfully. Now login and complete your profile."
|
||||||
},
|
},
|
||||||
TASK_CREATED: {
|
TASK_ASSIGNED: {
|
||||||
"title": "Task created!",
|
"title": "New task assigned !!",
|
||||||
"body": "Task created successfully."
|
"body": "{from_user} has assigned you a new task."
|
||||||
},
|
},
|
||||||
INVITED_GUARDIAN: {
|
INVITED_GUARDIAN: {
|
||||||
"title": "Invite guardian",
|
"title": "Invite guardian",
|
||||||
"body": "Invite guardian successfully"
|
"body": "Invite guardian successfully"
|
||||||
},
|
},
|
||||||
APPROVED_JUNIOR: {
|
APPROVED_JUNIOR: {
|
||||||
"title": "Approve junior",
|
"title": "Approve junior !",
|
||||||
"body": "You have request from junior to associate with you"
|
"body": "You have request from {from_user} to associate with you."
|
||||||
},
|
},
|
||||||
REFERRAL_POINTS: {
|
REFERRAL_POINTS: {
|
||||||
"title": "Earn Referral points",
|
"title": "Earn Referral points",
|
||||||
@@ -47,15 +47,15 @@ NOTIFICATION_DICT = {
|
|||||||
},
|
},
|
||||||
SKIPPED_PROFILE_SETUP: {
|
SKIPPED_PROFILE_SETUP: {
|
||||||
"title": "Skipped profile setup!",
|
"title": "Skipped profile setup!",
|
||||||
"body": "Your guardian has been setup your profile."
|
"body": "Your guardian {from_user} has setup your profile."
|
||||||
},
|
},
|
||||||
TASK_SUBMITTED: {
|
TASK_SUBMITTED: {
|
||||||
"title": "Task submitted!",
|
"title": "Task submitted!",
|
||||||
"body": "Your task has been submitted successfully."
|
"body": "Your task has been submitted successfully."
|
||||||
},
|
},
|
||||||
TASK_ACTION: {
|
TASK_ACTION: {
|
||||||
"title": "Task approval!",
|
"title": "Task completion approval!",
|
||||||
"body": "You have request for task approval."
|
"body": "You have request from {from_user} for task approval."
|
||||||
},
|
},
|
||||||
LEADERBOARD_RANKING: {
|
LEADERBOARD_RANKING: {
|
||||||
"title": "Leader board rank!",
|
"title": "Leader board rank!",
|
||||||
@@ -67,6 +67,6 @@ NOTIFICATION_DICT = {
|
|||||||
},
|
},
|
||||||
TEST_NOTIFICATION: {
|
TEST_NOTIFICATION: {
|
||||||
"title": "Test Notification",
|
"title": "Test Notification",
|
||||||
"body": "This notification is for testing purpose"
|
"body": "This notification is for testing purpose from {from_user}."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ class NotificationListSerializer(serializers.ModelSerializer):
|
|||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""meta info"""
|
"""meta info"""
|
||||||
model = Notification
|
model = Notification
|
||||||
fields = ['id', 'data', 'is_read']
|
fields = ['id', 'data', 'is_read', 'created_at']
|
||||||
|
|
||||||
|
|
||||||
class ReadNotificationSerializer(serializers.ModelSerializer):
|
class ReadNotificationSerializer(serializers.ModelSerializer):
|
||||||
"""User task Serializer"""
|
"""User task Serializer"""
|
||||||
|
|||||||
+67
-14
@@ -10,6 +10,9 @@ from firebase_admin.messaging import Message, Notification as FirebaseNotificati
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from account.models import UserNotification
|
from account.models import UserNotification
|
||||||
|
from account.utils import get_user_full_name
|
||||||
|
from guardian.models import Guardian
|
||||||
|
from junior.models import Junior
|
||||||
from notifications.constants import NOTIFICATION_DICT
|
from notifications.constants import NOTIFICATION_DICT
|
||||||
from notifications.models import Notification
|
from notifications.models import Notification
|
||||||
|
|
||||||
@@ -39,30 +42,80 @@ def remove_fcm_token(user_id: int, access_token: str, registration_id) -> None:
|
|||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
|
|
||||||
def get_basic_detail(notification_type, from_user_id, to_user_id):
|
def get_basic_detail(from_user_id, to_user_id):
|
||||||
""" used to get the basic details """
|
"""
|
||||||
notification_data = NOTIFICATION_DICT[notification_type]
|
used to get the basic details
|
||||||
|
"""
|
||||||
from_user = User.objects.get(id=from_user_id) if from_user_id else None
|
from_user = User.objects.get(id=from_user_id) if from_user_id else None
|
||||||
to_user = User.objects.get(id=to_user_id)
|
to_user = User.objects.get(id=to_user_id)
|
||||||
return notification_data, from_user, to_user
|
return from_user, to_user
|
||||||
|
|
||||||
|
|
||||||
@shared_task()
|
def get_notification_data(notification_type, from_user, to_user, extra_data):
|
||||||
def send_notification(notification_type, from_user_id, to_user_id, extra_data):
|
"""
|
||||||
""" used to send the push for the given notification type """
|
get notification and push data
|
||||||
(notification_data, from_user, to_user) = get_basic_detail(notification_type, from_user_id, to_user_id)
|
:param notification_type: notification_type
|
||||||
|
:param from_user: from_user obj
|
||||||
|
:param to_user: to_user obj
|
||||||
|
:param extra_data: any extra data provided
|
||||||
|
:return: notification and push data
|
||||||
|
"""
|
||||||
|
push_data = NOTIFICATION_DICT[notification_type].copy()
|
||||||
|
notification_data = push_data.copy()
|
||||||
|
notification_data['to_user'] = get_user_full_name(to_user)
|
||||||
|
if from_user:
|
||||||
|
from_user_name = get_user_full_name(from_user)
|
||||||
|
push_data['body'] = push_data['body'].format(from_user=from_user_name)
|
||||||
|
notification_data['body'] = notification_data['body'].format(from_user=from_user_name)
|
||||||
|
notification_data['from_user'] = from_user_name
|
||||||
|
|
||||||
|
notification_data.update(extra_data)
|
||||||
|
|
||||||
|
return notification_data, push_data
|
||||||
|
|
||||||
|
|
||||||
|
def send_notification(notification_type, from_user, to_user, extra_data):
|
||||||
|
"""
|
||||||
|
used to send the push for the given notification type
|
||||||
|
"""
|
||||||
|
# (from_user, to_user) = get_basic_detail(from_user_id, to_user_id)
|
||||||
|
notification_data, push_data = get_notification_data(notification_type, from_user, to_user, extra_data)
|
||||||
user_notification_type = UserNotification.objects.filter(user=to_user).first()
|
user_notification_type = UserNotification.objects.filter(user=to_user).first()
|
||||||
data = notification_data
|
notification_data.update({'badge': Notification.objects.filter(notification_to=to_user, is_read=False).count()})
|
||||||
Notification.objects.create(notification_type=notification_type, notification_from=from_user,
|
Notification.objects.create(notification_type=notification_type, notification_from=from_user,
|
||||||
notification_to=to_user, data=data)
|
notification_to=to_user, data=notification_data)
|
||||||
if user_notification_type.push_notification:
|
if user_notification_type.push_notification:
|
||||||
data.update({'badge': Notification.objects.filter(notification_to=to_user, is_read=False).count()})
|
send_push(to_user, push_data)
|
||||||
send_push(to_user, data)
|
|
||||||
|
|
||||||
|
|
||||||
def send_push(user, data):
|
def send_push(user, data):
|
||||||
""" used to send push notification to specific user """
|
""" used to send push notification to specific user """
|
||||||
notification_data = data.pop('data', None)
|
|
||||||
user.fcmdevice_set.filter(active=True).send_message(
|
user.fcmdevice_set.filter(active=True).send_message(
|
||||||
Message(notification=FirebaseNotification(data['title'], data['body']), data=notification_data)
|
Message(notification=FirebaseNotification(data['title'], data['body']), data=data)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task()
|
||||||
|
def send_notification_to_guardian(notification_type, from_user_id, to_user_id, extra_data):
|
||||||
|
from_user = None
|
||||||
|
if from_user_id:
|
||||||
|
from_user = Junior.objects.filter(auth_id=from_user_id).select_related('auth').first()
|
||||||
|
extra_data['from_user_image'] = from_user.image
|
||||||
|
from_user = from_user.auth
|
||||||
|
to_user = Guardian.objects.filter(user_id=to_user_id).select_related('user').first()
|
||||||
|
extra_data['to_user_image'] = to_user.image
|
||||||
|
send_notification(notification_type, from_user, to_user.user, extra_data)
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task()
|
||||||
|
def send_notification_to_junior(notification_type, from_user_id, to_user_id, extra_data):
|
||||||
|
from_user = None
|
||||||
|
if from_user_id:
|
||||||
|
from_user = Guardian.objects.filter(user_id=from_user_id).select_related('user').first()
|
||||||
|
extra_data['from_user_image'] = from_user.image
|
||||||
|
from_user = from_user.user
|
||||||
|
to_user = Junior.objects.filter(auth_id=to_user_id).select_related('auth').first()
|
||||||
|
extra_data['to_user_image'] = to_user.image
|
||||||
|
send_notification(notification_type, from_user, to_user.auth, extra_data)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from base.messages import SUCCESS_CODE, ERROR_CODE
|
|||||||
from notifications.constants import TEST_NOTIFICATION
|
from notifications.constants import TEST_NOTIFICATION
|
||||||
# Import serializer
|
# Import serializer
|
||||||
from notifications.serializers import RegisterDevice, NotificationListSerializer, ReadNotificationSerializer
|
from notifications.serializers import RegisterDevice, NotificationListSerializer, ReadNotificationSerializer
|
||||||
from notifications.utils import send_notification
|
from notifications.utils import send_notification, send_notification_to_guardian, send_notification_to_junior
|
||||||
# Import model
|
# Import model
|
||||||
from notifications.models import Notification
|
from notifications.models import Notification
|
||||||
|
|
||||||
@@ -56,7 +56,10 @@ class NotificationViewSet(viewsets.GenericViewSet):
|
|||||||
to send test notification
|
to send test notification
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
send_notification.delay(TEST_NOTIFICATION, None, request.auth.payload['user_id'], {})
|
send_notification_to_guardian.delay(TEST_NOTIFICATION, None, request.auth.payload['user_id'],
|
||||||
|
{'task_id': None})
|
||||||
|
send_notification_to_junior.delay(TEST_NOTIFICATION, None, request.auth.payload['user_id'],
|
||||||
|
{'task_id': None})
|
||||||
return custom_response(SUCCESS_CODE["3000"])
|
return custom_response(SUCCESS_CODE["3000"])
|
||||||
|
|
||||||
@action(methods=['get'], detail=False, url_path='list', url_name='list',
|
@action(methods=['get'], detail=False, url_path='list', url_name='list',
|
||||||
|
|||||||
@@ -99,3 +99,6 @@ uritemplate==4.1.1
|
|||||||
urllib3==1.26.16
|
urllib3==1.26.16
|
||||||
vine==5.0.0
|
vine==5.0.0
|
||||||
wcwidth==0.2.6
|
wcwidth==0.2.6
|
||||||
|
|
||||||
|
pandas==2.0.3
|
||||||
|
XlsxWriter==3.1.2
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
"""
|
"""
|
||||||
web_admin pagination file
|
web_admin pagination file
|
||||||
"""
|
"""
|
||||||
|
# third party imports
|
||||||
from rest_framework.pagination import PageNumberPagination
|
from rest_framework.pagination import PageNumberPagination
|
||||||
|
|
||||||
|
from base.constants import NUMBER
|
||||||
|
|
||||||
|
|
||||||
class CustomPageNumberPagination(PageNumberPagination):
|
class CustomPageNumberPagination(PageNumberPagination):
|
||||||
"""
|
"""
|
||||||
custom paginator class
|
custom paginator class
|
||||||
"""
|
"""
|
||||||
page_size = 10 # Set the desired page size
|
# Set the desired page size
|
||||||
|
page_size = NUMBER['ten']
|
||||||
page_size_query_param = 'page_size'
|
page_size_query_param = 'page_size'
|
||||||
max_page_size = 100 # Set a maximum page size if needed
|
# Set a maximum page size if needed
|
||||||
|
max_page_size = NUMBER['hundred']
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
"""
|
"""
|
||||||
web_admin analytics serializer file
|
web_admin analytics serializer file
|
||||||
"""
|
"""
|
||||||
|
# third party imports
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
# django imports
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from base.constants import USER_TYPE
|
||||||
|
|
||||||
from junior.models import JuniorPoints, Junior
|
from junior.models import JuniorPoints, Junior
|
||||||
|
|
||||||
|
USER = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
class JuniorLeaderboardSerializer(serializers.ModelSerializer):
|
class JuniorLeaderboardSerializer(serializers.ModelSerializer):
|
||||||
|
"""
|
||||||
|
junior leaderboard serializer
|
||||||
|
"""
|
||||||
name = serializers.SerializerMethodField()
|
name = serializers.SerializerMethodField()
|
||||||
first_name = serializers.SerializerMethodField()
|
first_name = serializers.SerializerMethodField()
|
||||||
last_name = serializers.SerializerMethodField()
|
last_name = serializers.SerializerMethodField()
|
||||||
@@ -16,7 +28,7 @@ class JuniorLeaderboardSerializer(serializers.ModelSerializer):
|
|||||||
meta class
|
meta class
|
||||||
"""
|
"""
|
||||||
model = Junior
|
model = Junior
|
||||||
fields = ('id', 'name', 'first_name', 'last_name', 'is_active', 'image')
|
fields = ('id', 'name', 'first_name', 'last_name', 'is_active', 'image', 'is_deleted')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_name(obj):
|
def get_name(obj):
|
||||||
@@ -44,9 +56,75 @@ class JuniorLeaderboardSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class LeaderboardSerializer(serializers.ModelSerializer):
|
class LeaderboardSerializer(serializers.ModelSerializer):
|
||||||
|
"""
|
||||||
|
leaderboard serializer
|
||||||
|
"""
|
||||||
junior = JuniorLeaderboardSerializer()
|
junior = JuniorLeaderboardSerializer()
|
||||||
rank = serializers.IntegerField()
|
rank = serializers.IntegerField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
"""
|
||||||
|
meta class
|
||||||
|
"""
|
||||||
model = JuniorPoints
|
model = JuniorPoints
|
||||||
fields = ('total_points', 'rank', 'junior')
|
fields = ('total_points', 'rank', 'junior')
|
||||||
|
|
||||||
|
|
||||||
|
class UserCSVReportSerializer(serializers.ModelSerializer):
|
||||||
|
"""
|
||||||
|
user csv/xls report serializer
|
||||||
|
"""
|
||||||
|
phone_number = serializers.SerializerMethodField()
|
||||||
|
user_type = serializers.SerializerMethodField()
|
||||||
|
is_active = serializers.SerializerMethodField()
|
||||||
|
date_joined = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""
|
||||||
|
meta class
|
||||||
|
"""
|
||||||
|
model = USER
|
||||||
|
fields = ('first_name', 'last_name', 'email', 'phone_number', 'user_type', 'is_active', 'date_joined')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_phone_number(obj):
|
||||||
|
"""
|
||||||
|
:param obj: user object
|
||||||
|
:return: user phone number
|
||||||
|
"""
|
||||||
|
if profile := (obj.guardian_profile.all().first() or obj.junior_profile.all().first()):
|
||||||
|
return f"+{profile.country_code}{profile.phone}" \
|
||||||
|
if profile.country_code and profile.phone else profile.phone
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_user_type(obj):
|
||||||
|
"""
|
||||||
|
:param obj: user object
|
||||||
|
:return: user type
|
||||||
|
"""
|
||||||
|
if obj.guardian_profile.all().first():
|
||||||
|
return dict(USER_TYPE).get('2').capitalize()
|
||||||
|
elif obj.junior_profile.all().first():
|
||||||
|
return dict(USER_TYPE).get('1').capitalize()
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_is_active(obj):
|
||||||
|
"""
|
||||||
|
:param obj: user object
|
||||||
|
:return: user type
|
||||||
|
"""
|
||||||
|
if profile := (obj.guardian_profile.all().first() or obj.junior_profile.all().first()):
|
||||||
|
return "Active" if profile.is_active else "Inactive"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_date_joined(obj):
|
||||||
|
"""
|
||||||
|
:param obj: user obj
|
||||||
|
:return: formatted date
|
||||||
|
"""
|
||||||
|
date = obj.date_joined.strftime("%d %b %Y")
|
||||||
|
return date
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ web_admin user_management serializers file
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from base.constants import USER_TYPE
|
from base.constants import USER_TYPE, GUARDIAN, JUNIOR
|
||||||
# local imports
|
# local imports
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
from guardian.models import Guardian
|
from guardian.models import Guardian
|
||||||
@@ -108,7 +108,7 @@ class GuardianSerializer(serializers.ModelSerializer):
|
|||||||
"""
|
"""
|
||||||
model = Guardian
|
model = Guardian
|
||||||
fields = ('id', 'name', 'first_name', 'last_name', 'username', 'dob', 'gender', 'country_code', 'phone',
|
fields = ('id', 'name', 'first_name', 'last_name', 'username', 'dob', 'gender', 'country_code', 'phone',
|
||||||
'is_active', 'country_name', 'image', 'email')
|
'is_active', 'country_name', 'image', 'email', 'is_deleted')
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
"""
|
"""
|
||||||
@@ -187,7 +187,7 @@ class JuniorSerializer(serializers.ModelSerializer):
|
|||||||
"""
|
"""
|
||||||
model = Junior
|
model = Junior
|
||||||
fields = ('id', 'name', 'first_name', 'last_name', 'username', 'dob', 'gender', 'country_code', 'phone',
|
fields = ('id', 'name', 'first_name', 'last_name', 'username', 'dob', 'gender', 'country_code', 'phone',
|
||||||
'is_active', 'country_name', 'image', 'email')
|
'is_active', 'country_name', 'image', 'email', 'is_deleted')
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
"""
|
"""
|
||||||
@@ -210,10 +210,10 @@ class JuniorSerializer(serializers.ModelSerializer):
|
|||||||
"""
|
"""
|
||||||
instance.auth.email = self.validated_data.get('email', instance.auth.email)
|
instance.auth.email = self.validated_data.get('email', instance.auth.email)
|
||||||
instance.auth.username = self.validated_data.get('email', instance.auth.username)
|
instance.auth.username = self.validated_data.get('email', instance.auth.username)
|
||||||
instance.auth.save()
|
instance.auth.save(update_fields=['email', 'username'])
|
||||||
instance.country_code = validated_data.get('country_code', instance.country_code)
|
instance.country_code = validated_data.get('country_code', instance.country_code)
|
||||||
instance.phone = validated_data.get('phone', instance.phone)
|
instance.phone = validated_data.get('phone', instance.phone)
|
||||||
instance.save()
|
instance.save(update_fields=['country_code', 'phone'])
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -265,33 +265,30 @@ class UserManagementDetailSerializer(serializers.ModelSerializer):
|
|||||||
model = USER
|
model = USER
|
||||||
fields = ('id', 'user_type', 'email', 'guardian_profile', 'junior_profile', 'associated_users')
|
fields = ('id', 'user_type', 'email', 'guardian_profile', 'junior_profile', 'associated_users')
|
||||||
|
|
||||||
@staticmethod
|
def get_user_type(self, obj):
|
||||||
def get_user_type(obj):
|
|
||||||
"""
|
"""
|
||||||
:param obj: user object
|
:param obj: user object
|
||||||
:return: user type
|
:return: user type
|
||||||
"""
|
"""
|
||||||
if obj.guardian_profile.all().first():
|
return GUARDIAN if self.context['user_type'] == GUARDIAN else JUNIOR
|
||||||
return dict(USER_TYPE).get('2')
|
|
||||||
elif obj.junior_profile.all().first():
|
|
||||||
return dict(USER_TYPE).get('1')
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
@staticmethod
|
def get_associated_users(self, obj):
|
||||||
def get_associated_users(obj):
|
|
||||||
"""
|
"""
|
||||||
:param obj: user object
|
:param obj: user object
|
||||||
:return: associated user
|
:return: associated user
|
||||||
"""
|
"""
|
||||||
if profile := obj.guardian_profile.all().first():
|
if self.context['user_type'] == GUARDIAN:
|
||||||
|
profile = obj.guardian_profile.all().only('user_id', 'guardian_code').first()
|
||||||
if profile.guardian_code:
|
if profile.guardian_code:
|
||||||
junior = Junior.objects.filter(guardian_code__contains=[profile.guardian_code], is_verified=True)
|
junior = Junior.objects.filter(guardian_code__contains=[profile.guardian_code],
|
||||||
|
is_verified=True).select_related('auth')
|
||||||
serializer = JuniorSerializer(junior, many=True)
|
serializer = JuniorSerializer(junior, many=True)
|
||||||
return serializer.data
|
return serializer.data
|
||||||
elif profile := obj.junior_profile.all().first():
|
elif self.context['user_type'] == JUNIOR:
|
||||||
|
profile = obj.junior_profile.all().only('auth_id', 'guardian_code').first()
|
||||||
if profile.guardian_code:
|
if profile.guardian_code:
|
||||||
guardian = Guardian.objects.filter(guardian_code__in=profile.guardian_code, is_verified=True)
|
guardian = Guardian.objects.filter(guardian_code__in=profile.guardian_code,
|
||||||
|
is_verified=True).select_related('user')
|
||||||
serializer = GuardianSerializer(guardian, many=True)
|
serializer = GuardianSerializer(guardian, many=True)
|
||||||
return serializer.data
|
return serializer.data
|
||||||
else:
|
else:
|
||||||
|
|||||||
+23
-4
@@ -2,9 +2,10 @@
|
|||||||
web_utils file
|
web_utils file
|
||||||
"""
|
"""
|
||||||
import base64
|
import base64
|
||||||
|
import datetime
|
||||||
|
|
||||||
from base.constants import ARTICLE_CARD_IMAGE_FOLDER
|
from base.constants import ARTICLE_CARD_IMAGE_FOLDER, DATE_FORMAT
|
||||||
from guardian.utils import upload_image_to_alibaba
|
from guardian.utils import upload_image_to_alibaba, upload_base64_image_to_alibaba
|
||||||
|
|
||||||
|
|
||||||
def pop_id(data):
|
def pop_id(data):
|
||||||
@@ -29,10 +30,10 @@ def get_image_url(data):
|
|||||||
return data['image_url']
|
return data['image_url']
|
||||||
elif 'image_url' in data and type(data['image_url']) == str and data['image_url'].startswith('data:image'):
|
elif 'image_url' in data and type(data['image_url']) == str and data['image_url'].startswith('data:image'):
|
||||||
base64_image = base64.b64decode(data.get('image_url').split(',')[1])
|
base64_image = base64.b64decode(data.get('image_url').split(',')[1])
|
||||||
image_name = f"{data['title']} {data.pop('image_name')}" if 'image_name' in data else data['title']
|
image_name = data.pop('image_name') if 'image_name' in data else f"{data['title']}.jpg"
|
||||||
filename = f"{ARTICLE_CARD_IMAGE_FOLDER}/{image_name}"
|
filename = f"{ARTICLE_CARD_IMAGE_FOLDER}/{image_name}"
|
||||||
# upload image on ali baba
|
# upload image on ali baba
|
||||||
image_url = upload_image_to_alibaba(base64_image, filename)
|
image_url = upload_base64_image_to_alibaba(base64_image, filename)
|
||||||
return image_url
|
return image_url
|
||||||
elif 'image' in data and data['image'] is not None:
|
elif 'image' in data and data['image'] is not None:
|
||||||
image = data.pop('image')
|
image = data.pop('image')
|
||||||
@@ -40,3 +41,21 @@ def get_image_url(data):
|
|||||||
# upload image on ali baba
|
# upload image on ali baba
|
||||||
image_url = upload_image_to_alibaba(image, filename)
|
image_url = upload_image_to_alibaba(image, filename)
|
||||||
return image_url
|
return image_url
|
||||||
|
|
||||||
|
|
||||||
|
def get_dates(start_date, end_date):
|
||||||
|
"""
|
||||||
|
to get start and end date
|
||||||
|
:param start_date: format (yyyy-mm-dd)
|
||||||
|
:param end_date: format (yyyy-mm-dd)
|
||||||
|
:return: start and end date
|
||||||
|
"""
|
||||||
|
|
||||||
|
if start_date and end_date:
|
||||||
|
start_date = datetime.datetime.strptime(start_date, DATE_FORMAT).date()
|
||||||
|
end_date = datetime.datetime.strptime(end_date, DATE_FORMAT).date()
|
||||||
|
else:
|
||||||
|
end_date = datetime.date.today()
|
||||||
|
start_date = end_date - datetime.timedelta(days=6)
|
||||||
|
|
||||||
|
return start_date, end_date
|
||||||
|
|||||||
+116
-22
@@ -3,6 +3,9 @@ web_admin analytics view file
|
|||||||
"""
|
"""
|
||||||
# python imports
|
# python imports
|
||||||
import datetime
|
import datetime
|
||||||
|
import io
|
||||||
|
import pandas as pd
|
||||||
|
import xlsxwriter
|
||||||
|
|
||||||
# third party imports
|
# third party imports
|
||||||
from rest_framework.viewsets import GenericViewSet
|
from rest_framework.viewsets import GenericViewSet
|
||||||
@@ -16,15 +19,18 @@ from django.db.models import Count
|
|||||||
from django.db.models.functions import TruncDate
|
from django.db.models.functions import TruncDate
|
||||||
from django.db.models import F, Window
|
from django.db.models import F, Window
|
||||||
from django.db.models.functions.window import Rank
|
from django.db.models.functions.window import Rank
|
||||||
|
from django.http import HttpResponse
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from account.utils import custom_response
|
from account.utils import custom_response
|
||||||
from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, EXPIRED, DATE_FORMAT
|
from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, EXPIRED, DATE_FORMAT, TASK_STATUS
|
||||||
from guardian.models import JuniorTask
|
from guardian.models import JuniorTask
|
||||||
|
from guardian.utils import upload_excel_file_to_alibaba
|
||||||
from junior.models import JuniorPoints
|
from junior.models import JuniorPoints
|
||||||
from web_admin.pagination import CustomPageNumberPagination
|
from web_admin.pagination import CustomPageNumberPagination
|
||||||
from web_admin.permission import AdminPermission
|
from web_admin.permission import AdminPermission
|
||||||
from web_admin.serializers.analytics_serializer import LeaderboardSerializer
|
from web_admin.serializers.analytics_serializer import LeaderboardSerializer, UserCSVReportSerializer
|
||||||
|
from web_admin.utils import get_dates
|
||||||
|
|
||||||
USER = get_user_model()
|
USER = get_user_model()
|
||||||
|
|
||||||
@@ -47,7 +53,7 @@ class AnalyticsViewSet(GenericViewSet):
|
|||||||
).prefetch_related('guardian_profile',
|
).prefetch_related('guardian_profile',
|
||||||
'junior_profile'
|
'junior_profile'
|
||||||
).exclude(junior_profile__isnull=True,
|
).exclude(junior_profile__isnull=True,
|
||||||
guardian_profile__isnull=True).order_by('date_joined')
|
guardian_profile__isnull=True).order_by('-date_joined')
|
||||||
return user_qs
|
return user_qs
|
||||||
|
|
||||||
@action(methods=['get'], url_name='users-count', url_path='users-count', detail=False)
|
@action(methods=['get'], url_name='users-count', url_path='users-count', detail=False)
|
||||||
@@ -58,13 +64,8 @@ class AnalyticsViewSet(GenericViewSet):
|
|||||||
:param request: end_date: date format (yyyy-mm-dd)
|
:param request: end_date: date format (yyyy-mm-dd)
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
start_date, end_date = get_dates(request.query_params.get('start_date'),
|
||||||
end_date = datetime.date.today()
|
request.query_params.get('end_date'))
|
||||||
start_date = end_date - datetime.timedelta(days=6)
|
|
||||||
|
|
||||||
if request.query_params.get('start_date') and request.query_params.get('end_date'):
|
|
||||||
start_date = datetime.datetime.strptime(request.query_params.get('start_date'), DATE_FORMAT)
|
|
||||||
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), DATE_FORMAT)
|
|
||||||
|
|
||||||
user_qs = self.get_queryset()
|
user_qs = self.get_queryset()
|
||||||
queryset = user_qs.filter(date_joined__range=(start_date, (end_date + datetime.timedelta(days=1))))
|
queryset = user_qs.filter(date_joined__range=(start_date, (end_date + datetime.timedelta(days=1))))
|
||||||
@@ -83,12 +84,8 @@ class AnalyticsViewSet(GenericViewSet):
|
|||||||
:param request: end_date: date format (yyyy-mm-dd)
|
:param request: end_date: date format (yyyy-mm-dd)
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
end_date = datetime.date.today()
|
start_date, end_date = get_dates(request.query_params.get('start_date'),
|
||||||
start_date = end_date - datetime.timedelta(days=6)
|
request.query_params.get('end_date'))
|
||||||
|
|
||||||
if request.query_params.get('start_date') and request.query_params.get('end_date'):
|
|
||||||
start_date = datetime.datetime.strptime(request.query_params.get('start_date'), DATE_FORMAT)
|
|
||||||
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), DATE_FORMAT)
|
|
||||||
|
|
||||||
user_qs = self.get_queryset()
|
user_qs = self.get_queryset()
|
||||||
signup_data = user_qs.filter(date_joined__range=[start_date, (end_date + datetime.timedelta(days=1))]
|
signup_data = user_qs.filter(date_joined__range=[start_date, (end_date + datetime.timedelta(days=1))]
|
||||||
@@ -105,12 +102,8 @@ class AnalyticsViewSet(GenericViewSet):
|
|||||||
:param request: end_date: date format (yyyy-mm-dd)
|
:param request: end_date: date format (yyyy-mm-dd)
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
end_date = datetime.date.today()
|
start_date, end_date = get_dates(request.query_params.get('start_date'),
|
||||||
start_date = end_date - datetime.timedelta(days=6)
|
request.query_params.get('end_date'))
|
||||||
|
|
||||||
if request.query_params.get('start_date') and request.query_params.get('end_date'):
|
|
||||||
start_date = datetime.datetime.strptime(request.query_params.get('start_date'), DATE_FORMAT)
|
|
||||||
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), DATE_FORMAT)
|
|
||||||
|
|
||||||
assign_tasks = JuniorTask.objects.filter(
|
assign_tasks = JuniorTask.objects.filter(
|
||||||
created_at__range=[start_date, (end_date + datetime.timedelta(days=1))]
|
created_at__range=[start_date, (end_date + datetime.timedelta(days=1))]
|
||||||
@@ -141,3 +134,104 @@ class AnalyticsViewSet(GenericViewSet):
|
|||||||
paginated_queryset = paginator.paginate_queryset(queryset, request)
|
paginated_queryset = paginator.paginate_queryset(queryset, request)
|
||||||
serializer = self.serializer_class(paginated_queryset, many=True)
|
serializer = self.serializer_class(paginated_queryset, many=True)
|
||||||
return custom_response(None, serializer.data)
|
return custom_response(None, serializer.data)
|
||||||
|
|
||||||
|
@action(methods=['get'], url_name='export-excel', url_path='export-excel', detail=False)
|
||||||
|
def export_excel(self, request):
|
||||||
|
"""
|
||||||
|
to export users count, task details and top juniors in csv/excel file
|
||||||
|
:param request: start_date: date format (yyyy-mm-dd)
|
||||||
|
:param request: end_date: date format (yyyy-mm-dd)
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||||||
|
response['Content-Disposition'] = 'attachment; filename="ZOD_Bank_Analytics.xlsx"'
|
||||||
|
|
||||||
|
start_date, end_date = get_dates(request.query_params.get('start_date'),
|
||||||
|
request.query_params.get('end_date'))
|
||||||
|
|
||||||
|
# Use BytesIO for binary data
|
||||||
|
buffer = io.BytesIO()
|
||||||
|
|
||||||
|
# Create an XlsxWriter Workbook object
|
||||||
|
workbook = xlsxwriter.Workbook(buffer)
|
||||||
|
|
||||||
|
# Add sheets
|
||||||
|
sheets = ['Users', 'Assign Tasks', 'Juniors Leaderboard']
|
||||||
|
|
||||||
|
for sheet_name in sheets:
|
||||||
|
worksheet = workbook.add_worksheet(name=sheet_name)
|
||||||
|
|
||||||
|
# sheet 1 for Total Users
|
||||||
|
if sheet_name == 'Users':
|
||||||
|
user_qs = self.get_queryset()
|
||||||
|
queryset = user_qs.filter(date_joined__range=(start_date, (end_date + datetime.timedelta(days=1))))
|
||||||
|
serializer = UserCSVReportSerializer(queryset, many=True)
|
||||||
|
|
||||||
|
df_users = pd.DataFrame([
|
||||||
|
{'Name': f"{user['first_name']} {user['last_name']}",
|
||||||
|
'Email': user['email'], 'Phone Number': user['phone_number'],
|
||||||
|
'User Type': user['user_type'], 'Status': user['is_active'],
|
||||||
|
'Date Joined': user['date_joined']}
|
||||||
|
for user in serializer.data
|
||||||
|
])
|
||||||
|
write_excel_worksheet(worksheet, df_users)
|
||||||
|
|
||||||
|
# sheet 2 for Assign Task
|
||||||
|
elif sheet_name == 'Assign Tasks':
|
||||||
|
assign_tasks = JuniorTask.objects.filter(
|
||||||
|
created_at__range=[start_date, (end_date + datetime.timedelta(days=1))]
|
||||||
|
).exclude(task_status__in=[PENDING, EXPIRED])
|
||||||
|
|
||||||
|
df_tasks = pd.DataFrame([
|
||||||
|
{'Task Name': task.task_name, 'Task Status': dict(TASK_STATUS).get(task.task_status).capitalize()}
|
||||||
|
for task in assign_tasks
|
||||||
|
])
|
||||||
|
|
||||||
|
write_excel_worksheet(worksheet, df_tasks)
|
||||||
|
|
||||||
|
# sheet 3 for Juniors Leaderboard and rank
|
||||||
|
elif sheet_name == 'Juniors Leaderboard':
|
||||||
|
queryset = JuniorPoints.objects.prefetch_related('junior', 'junior__auth').annotate(rank=Window(
|
||||||
|
expression=Rank(),
|
||||||
|
order_by=[F('total_points').desc(), 'junior__created_at']
|
||||||
|
)).order_by('-total_points', 'junior__created_at')[:15]
|
||||||
|
df_leaderboard = pd.DataFrame([
|
||||||
|
{
|
||||||
|
'Junior Name': f"{junior.junior.auth.first_name} {junior.junior.auth.last_name}"
|
||||||
|
if junior.junior.auth.last_name else junior.junior.auth.first_name,
|
||||||
|
'Points': junior.total_points,
|
||||||
|
'Rank': junior.rank
|
||||||
|
}
|
||||||
|
for junior in queryset
|
||||||
|
])
|
||||||
|
|
||||||
|
write_excel_worksheet(worksheet, df_leaderboard)
|
||||||
|
|
||||||
|
# Close the workbook to save the content
|
||||||
|
workbook.close()
|
||||||
|
|
||||||
|
# Reset the buffer position and write the content to the response
|
||||||
|
buffer.seek(0)
|
||||||
|
response.write(buffer.getvalue())
|
||||||
|
buffer.close()
|
||||||
|
|
||||||
|
filename = f"{'analytics'}/{'ZOD_Bank_Analytics.xlsx'}"
|
||||||
|
file_link = upload_excel_file_to_alibaba(response, filename)
|
||||||
|
return custom_response(None, file_link)
|
||||||
|
|
||||||
|
|
||||||
|
def write_excel_worksheet(worksheet, dataframe):
|
||||||
|
"""
|
||||||
|
to perform write action on worksheets
|
||||||
|
:param worksheet:
|
||||||
|
:param dataframe:
|
||||||
|
:return: worksheet
|
||||||
|
"""
|
||||||
|
for idx, col in enumerate(dataframe.columns):
|
||||||
|
# Write header
|
||||||
|
worksheet.write(0, idx, col)
|
||||||
|
for row_num, row in enumerate(dataframe.values, start=1):
|
||||||
|
for col_num, value in enumerate(row):
|
||||||
|
worksheet.write(row_num, col_num, value)
|
||||||
|
return worksheet
|
||||||
|
|||||||
+38
-15
@@ -44,9 +44,20 @@ class ArticleViewSet(GenericViewSet, mixins.CreateModelMixin, mixins.UpdateModel
|
|||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
article create api method
|
article create api method
|
||||||
:param request:
|
:param request: { "title": "string", "description": "string",
|
||||||
:param args:
|
"article_cards": [
|
||||||
:param kwargs:
|
{ "title": "string",
|
||||||
|
"description": "string",
|
||||||
|
"image_name": "string",
|
||||||
|
"image_url": "string"
|
||||||
|
} ],
|
||||||
|
"article_survey": [
|
||||||
|
{ "question": "string",
|
||||||
|
"options": [
|
||||||
|
{ "option": "string",
|
||||||
|
"is_answer": true }
|
||||||
|
] }
|
||||||
|
] }
|
||||||
:return: success message
|
:return: success message
|
||||||
"""
|
"""
|
||||||
serializer = self.serializer_class(data=request.data)
|
serializer = self.serializer_class(data=request.data)
|
||||||
@@ -57,9 +68,24 @@ class ArticleViewSet(GenericViewSet, mixins.CreateModelMixin, mixins.UpdateModel
|
|||||||
def update(self, request, *args, **kwargs):
|
def update(self, request, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
article update api method
|
article update api method
|
||||||
:param request:
|
:param request: article_id,
|
||||||
:param args:
|
{ "title": "string", "description": "string",
|
||||||
:param kwargs:
|
"article_cards": [
|
||||||
|
{ "id": 0,
|
||||||
|
"title": "string",
|
||||||
|
"description": "string",
|
||||||
|
"image_name": "string",
|
||||||
|
"image_url": "string"
|
||||||
|
} ],
|
||||||
|
"article_survey": [
|
||||||
|
{ "id": 0,
|
||||||
|
"question": "string",
|
||||||
|
"options": [
|
||||||
|
{ "id": 0,
|
||||||
|
"option": "string",
|
||||||
|
"is_answer": true
|
||||||
|
} ]
|
||||||
|
} ] }
|
||||||
:return: success message
|
:return: success message
|
||||||
"""
|
"""
|
||||||
article = self.get_object()
|
article = self.get_object()
|
||||||
@@ -72,8 +98,6 @@ class ArticleViewSet(GenericViewSet, mixins.CreateModelMixin, mixins.UpdateModel
|
|||||||
"""
|
"""
|
||||||
article list api method
|
article list api method
|
||||||
:param request:
|
:param request:
|
||||||
:param args:
|
|
||||||
:param kwargs:
|
|
||||||
:return: list of article
|
:return: list of article
|
||||||
"""
|
"""
|
||||||
queryset = self.get_queryset()
|
queryset = self.get_queryset()
|
||||||
@@ -86,9 +110,7 @@ class ArticleViewSet(GenericViewSet, mixins.CreateModelMixin, mixins.UpdateModel
|
|||||||
def retrieve(self, request, *args, **kwargs):
|
def retrieve(self, request, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
article detail api method
|
article detail api method
|
||||||
:param request:
|
:param request: article_id
|
||||||
:param args:
|
|
||||||
:param kwargs:
|
|
||||||
:return: article detail data
|
:return: article detail data
|
||||||
"""
|
"""
|
||||||
queryset = self.get_object()
|
queryset = self.get_object()
|
||||||
@@ -98,9 +120,7 @@ class ArticleViewSet(GenericViewSet, mixins.CreateModelMixin, mixins.UpdateModel
|
|||||||
def destroy(self, request, *args, **kwargs):
|
def destroy(self, request, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
article delete (soft delete) api method
|
article delete (soft delete) api method
|
||||||
:param request:
|
:param request: article_id
|
||||||
:param args:
|
|
||||||
:param kwargs:
|
|
||||||
:return: success message
|
:return: success message
|
||||||
"""
|
"""
|
||||||
article = self.get_object()
|
article = self.get_object()
|
||||||
@@ -177,7 +197,10 @@ class DefaultArticleCardImagesViewSet(GenericViewSet, mixins.CreateModelMixin, m
|
|||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
api method to upload default article card images
|
api method to upload default article card images
|
||||||
:param request:
|
:param request: {
|
||||||
|
"image_name": "string",
|
||||||
|
"image": "image_file"
|
||||||
|
}
|
||||||
:return: success message
|
:return: success message
|
||||||
"""
|
"""
|
||||||
serializer = self.serializer_class(data=request.data)
|
serializer = self.serializer_class(data=request.data)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class ForgotAndResetPasswordViewSet(GenericViewSet):
|
|||||||
def admin_otp(self, request):
|
def admin_otp(self, request):
|
||||||
"""
|
"""
|
||||||
api method to send otp
|
api method to send otp
|
||||||
|
:param request: {"email": "string"}
|
||||||
:return: success message
|
:return: success message
|
||||||
"""
|
"""
|
||||||
serializer = self.serializer_class(data=request.data)
|
serializer = self.serializer_class(data=request.data)
|
||||||
@@ -40,6 +41,7 @@ class ForgotAndResetPasswordViewSet(GenericViewSet):
|
|||||||
def admin_verify_otp(self, request):
|
def admin_verify_otp(self, request):
|
||||||
"""
|
"""
|
||||||
api method to verify otp
|
api method to verify otp
|
||||||
|
:param request: {"email": "string", "otp": "otp"}
|
||||||
:return: success message
|
:return: success message
|
||||||
"""
|
"""
|
||||||
serializer = self.serializer_class(data=request.data)
|
serializer = self.serializer_class(data=request.data)
|
||||||
@@ -52,6 +54,7 @@ class ForgotAndResetPasswordViewSet(GenericViewSet):
|
|||||||
def admin_create_password(self, request):
|
def admin_create_password(self, request):
|
||||||
"""
|
"""
|
||||||
api method to create new password
|
api method to create new password
|
||||||
|
:param request: {"email": "string", "new_password": "string", "confirm_password": "string"}
|
||||||
:return: success message
|
:return: success message
|
||||||
"""
|
"""
|
||||||
serializer = self.serializer_class(data=request.data)
|
serializer = self.serializer_class(data=request.data)
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ from django.db.models import Q
|
|||||||
from account.utils import custom_response, custom_error_response
|
from account.utils import custom_response, custom_error_response
|
||||||
from base.constants import USER_TYPE
|
from base.constants import USER_TYPE
|
||||||
from base.messages import SUCCESS_CODE, ERROR_CODE
|
from base.messages import SUCCESS_CODE, ERROR_CODE
|
||||||
|
from guardian.models import Guardian
|
||||||
|
from junior.models import Junior
|
||||||
from web_admin.permission import AdminPermission
|
from web_admin.permission import AdminPermission
|
||||||
from web_admin.serializers.user_management_serializer import (UserManagementListSerializer,
|
from web_admin.serializers.user_management_serializer import (UserManagementListSerializer,
|
||||||
UserManagementDetailSerializer, GuardianSerializer,
|
UserManagementDetailSerializer, GuardianSerializer,
|
||||||
@@ -70,12 +72,14 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin,
|
|||||||
"""
|
"""
|
||||||
if self.request.query_params.get('user_type') not in [dict(USER_TYPE).get('1'), dict(USER_TYPE).get('2')]:
|
if self.request.query_params.get('user_type') not in [dict(USER_TYPE).get('1'), dict(USER_TYPE).get('2')]:
|
||||||
return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
queryset = self.queryset
|
queryset = self.queryset
|
||||||
if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'):
|
queryset = queryset.filter(id=kwargs['pk'])
|
||||||
queryset = queryset.filter(guardian_profile__user__id=kwargs['pk'])
|
|
||||||
elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'):
|
serializer = UserManagementDetailSerializer(
|
||||||
queryset = queryset.filter(junior_profile__auth__id=kwargs['pk'])
|
queryset, many=True,
|
||||||
serializer = UserManagementDetailSerializer(queryset, many=True)
|
context={'user_type': self.request.query_params.get('user_type')}
|
||||||
|
)
|
||||||
return custom_response(None, data=serializer.data)
|
return custom_response(None, data=serializer.data)
|
||||||
|
|
||||||
def partial_update(self, request, *args, **kwargs):
|
def partial_update(self, request, *args, **kwargs):
|
||||||
@@ -87,15 +91,14 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin,
|
|||||||
"""
|
"""
|
||||||
if self.request.query_params.get('user_type') not in [dict(USER_TYPE).get('1'), dict(USER_TYPE).get('2')]:
|
if self.request.query_params.get('user_type') not in [dict(USER_TYPE).get('1'), dict(USER_TYPE).get('2')]:
|
||||||
return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST)
|
||||||
queryset = self.queryset
|
|
||||||
if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'):
|
if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'):
|
||||||
user_obj = queryset.filter(guardian_profile__user__id=kwargs['pk']).first()
|
guardian = Guardian.objects.filter(user_id=kwargs['pk'], is_verified=True).first()
|
||||||
serializer = GuardianSerializer(user_obj.guardian_profile.all().first(),
|
serializer = GuardianSerializer(guardian,
|
||||||
request.data, context={'user_id': kwargs['pk']})
|
request.data, context={'user_id': kwargs['pk']})
|
||||||
|
|
||||||
elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'):
|
elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'):
|
||||||
user_obj = queryset.filter(junior_profile__auth__id=kwargs['pk']).first()
|
junior = Junior.objects.filter(auth_id=kwargs['pk'], is_verified=True).select_related('auth').first()
|
||||||
serializer = JuniorSerializer(user_obj.junior_profile.all().first(),
|
serializer = JuniorSerializer(junior,
|
||||||
request.data, context={'user_id': kwargs['pk']})
|
request.data, context={'user_id': kwargs['pk']})
|
||||||
|
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
@@ -114,12 +117,12 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin,
|
|||||||
return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST)
|
||||||
queryset = self.queryset
|
queryset = self.queryset
|
||||||
if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'):
|
if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'):
|
||||||
user_obj = queryset.filter(guardian_profile__user__id=kwargs['pk']).first()
|
user_obj = queryset.filter(id=kwargs['pk']).first()
|
||||||
obj = user_obj.guardian_profile.all().first()
|
obj = user_obj.guardian_profile.all().first()
|
||||||
obj.is_active = False if obj.is_active else True
|
obj.is_active = False if obj.is_active else True
|
||||||
obj.save()
|
obj.save()
|
||||||
elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'):
|
elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'):
|
||||||
user_obj = queryset.filter(junior_profile__auth__id=kwargs['pk']).first()
|
user_obj = queryset.filter(id=kwargs['pk']).first()
|
||||||
obj = user_obj.junior_profile.all().first()
|
obj = user_obj.junior_profile.all().first()
|
||||||
obj.is_active = False if obj.is_active else True
|
obj.is_active = False if obj.is_active else True
|
||||||
obj.save()
|
obj.save()
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ SIMPLE_JWT = {
|
|||||||
# Database
|
# Database
|
||||||
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
|
# default db setting
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.contrib.gis.db.backends.postgis',
|
'ENGINE': 'django.contrib.gis.db.backends.postgis',
|
||||||
'NAME':os.getenv('DB_NAME'),
|
'NAME':os.getenv('DB_NAME'),
|
||||||
@@ -177,6 +178,9 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# database query logs settings
|
||||||
|
# Allows us to check db hits
|
||||||
|
# useful to optimize db query and hit
|
||||||
LOGGING = {
|
LOGGING = {
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"filters": {
|
"filters": {
|
||||||
@@ -193,6 +197,7 @@ LOGGING = {
|
|||||||
"class": "logging.StreamHandler"
|
"class": "logging.StreamHandler"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
# database logger
|
||||||
"loggers": {
|
"loggers": {
|
||||||
"django.db.backends": {
|
"django.db.backends": {
|
||||||
"level": "DEBUG",
|
"level": "DEBUG",
|
||||||
@@ -242,6 +247,7 @@ CORS_ALLOW_HEADERS = (
|
|||||||
'x-requested-with',
|
'x-requested-with',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# CORS header settings
|
||||||
CORS_EXPOSE_HEADERS = (
|
CORS_EXPOSE_HEADERS = (
|
||||||
'Access-Control-Allow-Origin: *',
|
'Access-Control-Allow-Origin: *',
|
||||||
)
|
)
|
||||||
@@ -297,5 +303,7 @@ STATIC_URL = 'static/'
|
|||||||
# define static root
|
# define static root
|
||||||
STATIC_ROOT = 'static'
|
STATIC_ROOT = 'static'
|
||||||
|
|
||||||
|
# media url
|
||||||
MEDIA_URL = "/media/"
|
MEDIA_URL = "/media/"
|
||||||
|
# media path
|
||||||
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'media')
|
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'media')
|
||||||
|
|||||||
Reference in New Issue
Block a user