mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-07-15 10:05:21 +00:00
modified top-list api, junior-list api and junior-points api, nodified rank method, added mail for deactivating user from admin
This commit is contained in:
22
account/templates/templated_email/user_deactivate.email
Normal file
22
account/templates/templated_email/user_deactivate.email
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{% extends "templated_email/email_base.email" %}
|
||||||
|
|
||||||
|
{% block subject %}
|
||||||
|
Account Deactivated
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block plain %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 15px;">
|
||||||
|
<p style="margin: 0; font-size: 16px; line-height: 20px; padding: 36px 0 0; font-weight: 500; color: #1f2532;">
|
||||||
|
Hi User,
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 27px 22px;">
|
||||||
|
<p style="margin: 0;font-size: 14px; font-weight: 400; line-height: 21px; color: #1f2532;">
|
||||||
|
Your account has been deactivated by admin. Please reach out to the admin for assistance.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endblock %}
|
@ -18,27 +18,7 @@ from notifications.utils import send_notification
|
|||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def send_email_otp(email, verification_code):
|
def send_email(recipient_list, template, context: dict = None):
|
||||||
"""
|
|
||||||
used to send otp on email
|
|
||||||
:param email: e-mail
|
|
||||||
:param verification_code: otp
|
|
||||||
"""
|
|
||||||
from_email = settings.EMAIL_FROM_ADDRESS
|
|
||||||
recipient_list = [email]
|
|
||||||
send_templated_mail(
|
|
||||||
template_name='email_reset_verification.email',
|
|
||||||
from_email=from_email,
|
|
||||||
recipient_list=recipient_list,
|
|
||||||
context={
|
|
||||||
'verification_code': verification_code
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
|
||||||
def send_mail(recipient_list, template, context: dict = None):
|
|
||||||
"""
|
"""
|
||||||
used to send otp on email
|
used to send otp on email
|
||||||
:param context:
|
:param context:
|
||||||
@ -48,7 +28,6 @@ def send_mail(recipient_list, template, context: dict = None):
|
|||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
from_email = settings.EMAIL_FROM_ADDRESS
|
from_email = settings.EMAIL_FROM_ADDRESS
|
||||||
recipient_list = recipient_list
|
|
||||||
send_templated_mail(
|
send_templated_mail(
|
||||||
template_name=template,
|
template_name=template,
|
||||||
from_email=from_email,
|
from_email=from_email,
|
||||||
|
Binary file not shown.
@ -316,10 +316,11 @@ class TaskDetailsjuniorSerializer(serializers.ModelSerializer):
|
|||||||
'requested_on', 'rejected_on', 'completed_on',
|
'requested_on', 'rejected_on', 'completed_on',
|
||||||
'junior', 'task_status', 'is_active', 'remaining_time', 'created_at','updated_at']
|
'junior', 'task_status', 'is_active', 'remaining_time', 'created_at','updated_at']
|
||||||
|
|
||||||
|
|
||||||
class TopJuniorSerializer(serializers.ModelSerializer):
|
class TopJuniorSerializer(serializers.ModelSerializer):
|
||||||
"""Top junior serializer"""
|
"""Top junior serializer"""
|
||||||
junior = JuniorDetailSerializer()
|
junior = JuniorDetailSerializer()
|
||||||
position = serializers.IntegerField()
|
position = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
@ -329,9 +330,13 @@ class TopJuniorSerializer(serializers.ModelSerializer):
|
|||||||
def to_representation(self, instance):
|
def to_representation(self, instance):
|
||||||
"""Convert instance to representation"""
|
"""Convert instance to representation"""
|
||||||
representation = super().to_representation(instance)
|
representation = super().to_representation(instance)
|
||||||
representation['position'] = instance.position
|
|
||||||
return representation
|
return representation
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_position(obj):
|
||||||
|
""" get position/rank """
|
||||||
|
return obj.rank
|
||||||
|
|
||||||
|
|
||||||
class GuardianProfileSerializer(serializers.ModelSerializer):
|
class GuardianProfileSerializer(serializers.ModelSerializer):
|
||||||
"""junior serializer"""
|
"""junior serializer"""
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
# Import PageNumberPagination
|
# Import PageNumberPagination
|
||||||
# Import User
|
# Import User
|
||||||
# Import timezone
|
# Import timezone
|
||||||
|
from django.db.models import F, Window
|
||||||
|
from django.db.models.functions.window import Rank
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from rest_framework import viewsets, status
|
from rest_framework import viewsets, status
|
||||||
from rest_framework.pagination import PageNumberPagination
|
from rest_framework.pagination import PageNumberPagination
|
||||||
@ -242,7 +244,6 @@ class SearchTaskListAPIView(viewsets.ModelViewSet):
|
|||||||
class TopJuniorListAPIView(viewsets.ModelViewSet):
|
class TopJuniorListAPIView(viewsets.ModelViewSet):
|
||||||
"""Top juniors list
|
"""Top juniors list
|
||||||
No Params"""
|
No Params"""
|
||||||
queryset = JuniorPoints.objects.all()
|
|
||||||
serializer_class = TopJuniorSerializer
|
serializer_class = TopJuniorSerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
http_method_names = ('get',)
|
http_method_names = ('get',)
|
||||||
@ -253,15 +254,18 @@ class TopJuniorListAPIView(viewsets.ModelViewSet):
|
|||||||
context.update({'view': self})
|
context.update({'view': self})
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
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')
|
||||||
|
return queryset
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
"""Fetch junior list of those who complete their tasks"""
|
"""Fetch junior list of those who complete their tasks"""
|
||||||
try:
|
try:
|
||||||
junior_total_points = self.get_queryset().order_by('-total_points')
|
junior_total_points = self.get_queryset()[:15]
|
||||||
# Update the position field for each JuniorPoints object
|
serializer = self.get_serializer(junior_total_points, many=True)
|
||||||
for index, junior in enumerate(junior_total_points):
|
|
||||||
junior.position = index + 1
|
|
||||||
junior.save()
|
|
||||||
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)
|
||||||
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)
|
||||||
|
@ -19,7 +19,7 @@ from base.constants import (PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED
|
|||||||
GUARDIAN_CODE_STATUS, JUNIOR)
|
GUARDIAN_CODE_STATUS, JUNIOR)
|
||||||
from guardian.models import Guardian, JuniorTask
|
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, get_junior_leaderboard_rank
|
||||||
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
|
||||||
from notifications.constants import (ASSOCIATE_REQUEST, JUNIOR_ADDED, TASK_ACTION,
|
from notifications.constants import (ASSOCIATE_REQUEST, JUNIOR_ADDED, TASK_ACTION,
|
||||||
@ -185,9 +185,8 @@ class JuniorDetailListSerializer(serializers.ModelSerializer):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
def get_position(self, obj):
|
def get_position(self, obj):
|
||||||
data = JuniorPoints.objects.filter(junior=obj).last()
|
return get_junior_leaderboard_rank(obj)
|
||||||
if data:
|
|
||||||
return data.position
|
|
||||||
def get_points(self, obj):
|
def get_points(self, obj):
|
||||||
data = JuniorPoints.objects.filter(junior=obj).last()
|
data = JuniorPoints.objects.filter(junior=obj).last()
|
||||||
if data:
|
if data:
|
||||||
@ -365,10 +364,7 @@ class JuniorPointsSerializer(serializers.ModelSerializer):
|
|||||||
return obj.junior.id
|
return obj.junior.id
|
||||||
|
|
||||||
def get_position(self, obj):
|
def get_position(self, obj):
|
||||||
data = JuniorPoints.objects.filter(junior=obj.junior).last()
|
return get_junior_leaderboard_rank(obj.junior)
|
||||||
if data:
|
|
||||||
return data.position
|
|
||||||
return 99999
|
|
||||||
def get_points(self, obj):
|
def get_points(self, obj):
|
||||||
"""total points"""
|
"""total points"""
|
||||||
points = JuniorPoints.objects.filter(junior=obj.junior).last()
|
points = JuniorPoints.objects.filter(junior=obj.junior).last()
|
||||||
|
@ -5,7 +5,8 @@ from django.conf import settings
|
|||||||
from templated_email import send_templated_mail
|
from templated_email import send_templated_mail
|
||||||
from .models import JuniorPoints
|
from .models import JuniorPoints
|
||||||
from base.constants import NUMBER
|
from base.constants import NUMBER
|
||||||
from django.db.models import F
|
from django.db.models import F, Window
|
||||||
|
from django.db.models.functions.window import Rank
|
||||||
# junior notification
|
# junior notification
|
||||||
# email for sending email
|
# email for sending email
|
||||||
# when guardian create junior profile
|
# when guardian create junior profile
|
||||||
@ -61,3 +62,19 @@ def update_positions_based_on_points():
|
|||||||
junior_point.position = position
|
junior_point.position = position
|
||||||
junior_point.save()
|
junior_point.save()
|
||||||
position += NUMBER['one']
|
position += NUMBER['one']
|
||||||
|
|
||||||
|
|
||||||
|
def get_junior_leaderboard_rank(junior_obj):
|
||||||
|
"""
|
||||||
|
to get junior's position/rank
|
||||||
|
:param junior_obj:
|
||||||
|
:return: junior's position/rank
|
||||||
|
"""
|
||||||
|
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')
|
||||||
|
|
||||||
|
junior = next((query for query in queryset if query.junior == junior_obj), None)
|
||||||
|
|
||||||
|
return junior.rank if junior else None
|
||||||
|
@ -142,7 +142,7 @@ class JuniorListAPIView(viewsets.ModelViewSet):
|
|||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
""" junior list"""
|
""" junior list"""
|
||||||
try:
|
try:
|
||||||
update_positions_based_on_points()
|
# update_positions_based_on_points, function removed
|
||||||
guardian_data = Guardian.objects.filter(user__email=request.user).last()
|
guardian_data = Guardian.objects.filter(user__email=request.user).last()
|
||||||
# fetch junior object
|
# fetch junior object
|
||||||
if guardian_data:
|
if guardian_data:
|
||||||
@ -417,7 +417,7 @@ class JuniorPointsListAPIView(viewsets.ModelViewSet):
|
|||||||
"""Junior Points
|
"""Junior Points
|
||||||
No Params"""
|
No Params"""
|
||||||
try:
|
try:
|
||||||
update_positions_based_on_points()
|
# update_positions_based_on_points, function removed
|
||||||
queryset = JuniorPoints.objects.filter(junior__auth__email=self.request.user).last()
|
queryset = JuniorPoints.objects.filter(junior__auth__email=self.request.user).last()
|
||||||
# update position of junior
|
# update position of junior
|
||||||
serializer = JuniorPointsSerializer(queryset)
|
serializer = JuniorPointsSerializer(queryset)
|
||||||
|
@ -14,7 +14,7 @@ from account.models import UserEmailOtp
|
|||||||
from base.constants import USER_TYPE
|
from base.constants import USER_TYPE
|
||||||
from base.messages import ERROR_CODE
|
from base.messages import ERROR_CODE
|
||||||
from guardian.tasks import generate_otp
|
from guardian.tasks import generate_otp
|
||||||
from base.tasks import send_mail
|
from base.tasks import send_email
|
||||||
|
|
||||||
USER = get_user_model()
|
USER = get_user_model()
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ class AdminOTPSerializer(serializers.ModelSerializer):
|
|||||||
data = {
|
data = {
|
||||||
"verification_code": verification_code
|
"verification_code": verification_code
|
||||||
}
|
}
|
||||||
send_mail.delay([email], template, data)
|
send_email.delay([email], template, data)
|
||||||
|
|
||||||
expiry = timezone.now() + timezone.timedelta(days=1)
|
expiry = timezone.now() + timezone.timedelta(days=1)
|
||||||
user_data, created = UserEmailOtp.objects.update_or_create(email=email,
|
user_data, created = UserEmailOtp.objects.update_or_create(email=email,
|
||||||
|
@ -12,8 +12,9 @@ from django.db.models import Q
|
|||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
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, GUARDIAN, JUNIOR
|
||||||
from base.messages import SUCCESS_CODE, ERROR_CODE
|
from base.messages import SUCCESS_CODE, ERROR_CODE
|
||||||
|
from base.tasks import send_email
|
||||||
from guardian.models import Guardian
|
from guardian.models import Guardian
|
||||||
from junior.models import Junior
|
from junior.models import Junior
|
||||||
from web_admin.permission import AdminPermission
|
from web_admin.permission import AdminPermission
|
||||||
@ -92,12 +93,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)
|
||||||
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'):
|
||||||
guardian = Guardian.objects.filter(user_id=kwargs['pk'], is_verified=True).first()
|
guardian = Guardian.objects.filter(user_id=kwargs['pk'], is_verified=True
|
||||||
|
).select_related('user').first()
|
||||||
serializer = GuardianSerializer(guardian,
|
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'):
|
||||||
junior = Junior.objects.filter(auth_id=kwargs['pk'], is_verified=True).select_related('auth').first()
|
junior = Junior.objects.filter(auth_id=kwargs['pk'], is_verified=True
|
||||||
|
).select_related('auth').first()
|
||||||
serializer = JuniorSerializer(junior,
|
serializer = JuniorSerializer(junior,
|
||||||
request.data, context={'user_id': kwargs['pk']})
|
request.data, context={'user_id': kwargs['pk']})
|
||||||
|
|
||||||
@ -113,17 +116,21 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin,
|
|||||||
user_type {'guardian' for Guardian, 'junior' for Junior} mandatory
|
user_type {'guardian' for Guardian, 'junior' for Junior} mandatory
|
||||||
:return: success message
|
:return: success message
|
||||||
"""
|
"""
|
||||||
if self.request.query_params.get('user_type') not in [dict(USER_TYPE).get('1'), dict(USER_TYPE).get('2')]:
|
user_type = self.request.query_params.get('user_type')
|
||||||
|
if user_type not in [GUARDIAN, JUNIOR]:
|
||||||
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'):
|
email_template = 'user_deactivate.email'
|
||||||
user_obj = queryset.filter(id=kwargs['pk']).first()
|
|
||||||
obj = user_obj.guardian_profile.all().first()
|
if user_type == GUARDIAN:
|
||||||
obj.is_active = False if obj.is_active else True
|
obj = Guardian.objects.filter(user_id=kwargs['pk'], is_verified=True).select_related('user').first()
|
||||||
obj.save()
|
elif user_type == JUNIOR:
|
||||||
elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'):
|
obj = Junior.objects.filter(auth_id=kwargs['pk'], is_verified=True).select_related('auth').first()
|
||||||
user_obj = queryset.filter(id=kwargs['pk']).first()
|
|
||||||
obj = user_obj.junior_profile.all().first()
|
if obj.is_active:
|
||||||
obj.is_active = False if obj.is_active else True
|
obj.is_active = False
|
||||||
obj.save()
|
send_email([obj.user.email if user_type == GUARDIAN else obj.auth.email], email_template)
|
||||||
|
else:
|
||||||
|
obj.is_active = True
|
||||||
|
obj.save()
|
||||||
return custom_response(SUCCESS_CODE['3038'])
|
return custom_response(SUCCESS_CODE['3038'])
|
||||||
|
@ -28,9 +28,13 @@ app.config_from_object('django.conf:settings')
|
|||||||
app.autodiscover_tasks()
|
app.autodiscover_tasks()
|
||||||
|
|
||||||
app.conf.beat_schedule = {
|
app.conf.beat_schedule = {
|
||||||
|
"expired_task": {
|
||||||
|
"task": "guardian.utils.update_expired_task_status",
|
||||||
|
"schedule": crontab(minute=0, hour=0),
|
||||||
|
},
|
||||||
'notify_task_expiry': {
|
'notify_task_expiry': {
|
||||||
'task': 'base.tasks.notify_task_expiry',
|
'task': 'base.tasks.notify_task_expiry',
|
||||||
'schedule': crontab(minute='0', hour='*/1'),
|
'schedule': crontab(minute='30', hour='19'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,14 +43,3 @@ app.conf.beat_schedule = {
|
|||||||
def debug_task(self):
|
def debug_task(self):
|
||||||
""" celery debug task """
|
""" celery debug task """
|
||||||
print(f'Request: {self.request!r}')
|
print(f'Request: {self.request!r}')
|
||||||
|
|
||||||
|
|
||||||
"""cron task"""
|
|
||||||
|
|
||||||
|
|
||||||
app.conf.beat_schedule = {
|
|
||||||
"expired_task": {
|
|
||||||
"task": "guardian.utils.update_expired_task_status",
|
|
||||||
"schedule": crontab(minute=0, hour=0),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user