Merge branch 'dev' of github.com:KiwiTechLLC/ZODBank-Backend into sprint6-bugs

This commit is contained in:
jain
2023-08-28 20:10:36 +05:30
11 changed files with 82 additions and 65 deletions

View File

@ -68,10 +68,14 @@ def notify_top_junior():
task to send notification for top leaderboard junior to all junior's task to send notification for top leaderboard junior to all junior's
:return: :return:
""" """
junior_points_qs = JuniorPoints.objects.select_related('junior', 'junior__auth').annotate(rank=Window( junior_points_qs = JuniorPoints.objects.filter(
junior__is_verified=True
).select_related(
'junior', 'junior__auth'
).annotate(rank=Window(
expression=Rank(), expression=Rank(),
order_by=[F('total_points').desc(), 'junior__created_at'] order_by=[F('total_points').desc(), 'junior__created_at'])
)).order_by('-total_points', 'junior__created_at') ).order_by('-total_points', 'junior__created_at')
prev_top_position = junior_points_qs.filter(position=1).first() prev_top_position = junior_points_qs.filter(position=1).first()
new_top_position = junior_points_qs.filter(rank=1).first() new_top_position = junior_points_qs.filter(rank=1).first()

Binary file not shown.

View File

@ -259,10 +259,14 @@ class TopJuniorListAPIView(viewsets.ModelViewSet):
return context return context
def get_queryset(self): def get_queryset(self):
queryset = JuniorPoints.objects.select_related('junior', 'junior__auth').annotate(rank=Window( queryset = JuniorPoints.objects.filter(
junior__is_verified=True
).select_related(
'junior', 'junior__auth'
).annotate(rank=Window(
expression=Rank(), expression=Rank(),
order_by=[F('total_points').desc(), 'junior__created_at'] order_by=[F('total_points').desc(), 'junior__created_at'])
)).order_by('-total_points', 'junior__created_at') ).order_by('-total_points', 'junior__created_at')
return queryset return queryset
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):

View File

@ -22,7 +22,7 @@ from account.models import UserEmailOtp, UserNotification
from junior.utils import junior_notification_email, junior_approval_mail, get_junior_leaderboard_rank 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, ASSOCIATE_JUNIOR, TASK_ACTION,
) )
from web_admin.models import ArticleCard from web_admin.models import ArticleCard
@ -323,7 +323,7 @@ class AddJuniorSerializer(serializers.ModelSerializer):
"""Notification email""" """Notification email"""
junior_notification_email.delay(email, full_name, email, password) junior_notification_email.delay(email, full_name, email, password)
# push notification # push notification
send_notification.delay(JUNIOR_ADDED, None, None, junior_data.auth.id, {}) send_notification.delay(ASSOCIATE_JUNIOR, None, None, junior_data.auth.id, {})
return junior_data return junior_data

View File

@ -70,7 +70,9 @@ def get_junior_leaderboard_rank(junior_obj):
:param junior_obj: :param junior_obj:
:return: junior's position/rank :return: junior's position/rank
""" """
queryset = JuniorPoints.objects.select_related('junior', 'junior__auth').annotate(rank=Window( queryset = JuniorPoints.objects.filter(
junior__is_verified=True
).select_related('junior', 'junior__auth').annotate(rank=Window(
expression=Rank(), expression=Rank(),
order_by=[F('total_points').desc(), 'junior__created_at'] order_by=[F('total_points').desc(), 'junior__created_at']
)).order_by('-total_points', 'junior__created_at') )).order_by('-total_points', 'junior__created_at')

View File

@ -42,12 +42,12 @@ from .serializers import (CreateJuniorSerializer, JuniorDetailListSerializer, Ad
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, none from base.constants import NUMBER, ARTICLE_STATUS, none, GUARDIAN
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
from notifications.constants import REMOVE_JUNIOR, ARTICLE_REWARD_POINTS from notifications.constants import REMOVE_JUNIOR, ARTICLE_REWARD_POINTS, ASSOCIATE_EXISTING_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,
StartAssessmentSerializer) StartAssessmentSerializer)
@ -232,6 +232,7 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
if jun_data: if jun_data:
jun_data.relationship = str(self.request.data['relationship']) jun_data.relationship = str(self.request.data['relationship'])
jun_data.save() jun_data.save()
send_notification.delay(ASSOCIATE_EXISTING_JUNIOR, self.request.user.id, GUARDIAN, junior.auth.id, {})
return True return True

View File

@ -6,19 +6,20 @@ ASSOCIATE_REQUEST = 3
ASSOCIATE_REJECTED = 4 ASSOCIATE_REJECTED = 4
ASSOCIATE_APPROVED = 5 ASSOCIATE_APPROVED = 5
REFERRAL_POINTS = 6 REFERRAL_POINTS = 6
JUNIOR_ADDED = 7 ASSOCIATE_JUNIOR = 7
ASSOCIATE_EXISTING_JUNIOR = 8
TASK_ASSIGNED = 8 TASK_ASSIGNED = 9
TASK_ACTION = 9 TASK_ACTION = 10
TASK_REJECTED = 10 TASK_REJECTED = 11
TASK_APPROVED = 11 TASK_APPROVED = 12
PENDING_TASK_EXPIRING = 12 PENDING_TASK_EXPIRING = 13
IN_PROGRESS_TASK_EXPIRING = 13 IN_PROGRESS_TASK_EXPIRING = 14
TOP_JUNIOR = 14 TOP_JUNIOR = 15
NEW_ARTICLE_PUBLISHED = 15 NEW_ARTICLE_PUBLISHED = 16
ARTICLE_REWARD_POINTS = 16 ARTICLE_REWARD_POINTS = 17
REMOVE_JUNIOR = 17 REMOVE_JUNIOR = 18
TEST_NOTIFICATION = 99 TEST_NOTIFICATION = 99
@ -53,10 +54,14 @@ NOTIFICATION_DICT = {
}, },
# Juniors will receive notification # Juniors will receive notification
# once any custodians add them in their account # once any custodians add them in their account
JUNIOR_ADDED: { ASSOCIATE_JUNIOR: {
"title": "Profile already setup!", "title": "Profile already setup!",
"body": "Your guardian has already setup your profile." "body": "Your guardian has already setup your profile."
}, },
ASSOCIATE_EXISTING_JUNIOR: {
"title": "Associated to guardian",
"body": "Your are associated to your guardian {from_user}."
},
# Juniors will receive Notification # Juniors will receive Notification
# for every Task Assign by Custodians # for every Task Assign by Custodians
TASK_ASSIGNED: { TASK_ASSIGNED: {

View File

@ -19,14 +19,13 @@ 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
User = get_user_model() User = get_user_model()
def register_fcm_token(user_id, registration_id, device_id, device_type): def register_fcm_token(user_id, registration_id, device_id, device_type):
""" used to register the fcm device token""" """ used to register the fcm device token"""
device, _ = FCMDevice.objects.update_or_create(device_id=device_id, device, _ = FCMDevice.objects.update_or_create(user_id=user_id,
defaults={'user_id': user_id, 'type': device_type, defaults={'device_id': device_id, 'type': device_type,
'active': True, 'active': True,
'registration_id': registration_id}) 'registration_id': registration_id})
return device return device
@ -93,7 +92,7 @@ def get_notification_data(notification_type, from_user_id, from_user_type, to_us
notification_data['from_user_image'] = from_user_image notification_data['from_user_image'] = from_user_image
notification_data.update(extra_data) notification_data.update(extra_data)
to_user = User.objects.get(id=to_user_id) to_user = User.objects.filter(id=to_user_id).first()
return notification_data, push_data, from_user, to_user return notification_data, push_data, from_user, to_user
@ -135,21 +134,18 @@ def send_notification_multiple_user(notification_type, from_user_id, from_user_t
to_user_list = User.objects.filter(junior_profile__is_verified=True, is_superuser=False to_user_list = User.objects.filter(junior_profile__is_verified=True, is_superuser=False
).exclude(junior_profile__isnull=True, guardian_profile__isnull=True) ).exclude(junior_profile__isnull=True, guardian_profile__isnull=True)
push_data = NOTIFICATION_DICT[notification_type].copy() notification_data, push_data, from_user, _ = get_notification_data(notification_type, from_user_id,
notification_data = push_data.copy() from_user_type, None, extra_data)
points = extra_data.get('points', None)
from_user_name, from_user_image, from_user = get_from_user_details(from_user_id, from_user_type)
push_data['body'] = push_data['body'].format(from_user=from_user_name, points=points)
notification_data['body'] = notification_data['body'].format(from_user=from_user_name,
points=points)
notification_data['from_user'] = from_user_name
notification_data['from_user_image'] = from_user_image
notification_list = [] notification_list = []
for user in to_user_list: for user in to_user_list:
notification_copy_data = notification_data.copy()
notification_copy_data.update(
{'badge': Notification.objects.filter(notification_to=user, is_read=False).count()})
notification_list.append(Notification(notification_type=notification_type, notification_list.append(Notification(notification_type=notification_type,
notification_to=user, notification_to=user,
notification_from=from_user, notification_from=from_user,
data=notification_data)) data=notification_copy_data))
Notification.objects.bulk_create(notification_list) Notification.objects.bulk_create(notification_list)
to_user_list = to_user_list.filter(user_notification__push_notification=True) to_user_list = to_user_list.filter(user_notification__push_notification=True)
send_multiple_push(to_user_list, push_data) send_multiple_push(to_user_list, push_data)
@ -183,5 +179,3 @@ def send_notification_to_junior(notification_type, from_user_id, to_user_id, ext
from_user = Guardian.objects.filter(user_id=from_user_id).first() from_user = Guardian.objects.filter(user_id=from_user_id).first()
extra_data['from_user_image'] = from_user.image extra_data['from_user_image'] = from_user.image
send_notification(notification_type, from_user_id, to_user_id, extra_data) send_notification(notification_type, from_user_id, to_user_id, extra_data)

View File

@ -52,9 +52,11 @@ class NotificationViewSet(viewsets.GenericViewSet):
@action(methods=['get'], detail=False, url_path='test', url_name='test') @action(methods=['get'], detail=False, url_path='test', url_name='test')
def send_test_notification(self, request): def send_test_notification(self, request):
""" """
to send test notification to test send notification, task expiry, top junior
:return: :return:
""" """
notify_task_expiry()
notify_top_junior()
send_notification(TEST_NOTIFICATION, None, None, request.auth.payload['user_id'], send_notification(TEST_NOTIFICATION, None, None, request.auth.payload['user_id'],
{}) {})
return custom_response(SUCCESS_CODE["3000"]) return custom_response(SUCCESS_CODE["3000"])
@ -67,12 +69,3 @@ class NotificationViewSet(viewsets.GenericViewSet):
""" """
Notification.objects.filter(id__in=request.data.get('id')).update(is_read=True) Notification.objects.filter(id__in=request.data.get('id')).update(is_read=True)
return custom_response(SUCCESS_CODE['3039'], response_status=status.HTTP_200_OK) return custom_response(SUCCESS_CODE['3039'], response_status=status.HTTP_200_OK)
@action(methods=['get'], url_path='task', url_name='task', detail=False,
permission_classes=[AllowAny])
def task(self, request, *args, **kwargs):
"""
notification list
"""
notify_top_junior()
return custom_response(SUCCESS_CODE['3039'], response_status=status.HTTP_200_OK)

View File

@ -9,7 +9,7 @@ from django.contrib.auth import get_user_model
from account.utils import get_user_full_name from account.utils import get_user_full_name
# local imports # local imports
from base.constants import USER_TYPE from base.constants import USER_TYPE, JUNIOR
from junior.models import JuniorPoints, Junior from junior.models import JuniorPoints, Junior
@ -37,7 +37,7 @@ class JuniorLeaderboardSerializer(serializers.ModelSerializer):
:param obj: junior object :param obj: junior object
:return: full name :return: full name
""" """
return f"{obj.auth.first_name} {obj.auth.last_name}" if obj.auth.last_name else obj.auth.first_name return get_user_full_name(obj.auth)
@staticmethod @staticmethod
def get_first_name(obj): def get_first_name(obj):
@ -60,6 +60,8 @@ class LeaderboardSerializer(serializers.ModelSerializer):
""" """
leaderboard serializer leaderboard serializer
""" """
user_id = serializers.SerializerMethodField()
user_type = serializers.SerializerMethodField()
junior = JuniorLeaderboardSerializer() junior = JuniorLeaderboardSerializer()
rank = serializers.IntegerField() rank = serializers.IntegerField()
@ -68,7 +70,15 @@ class LeaderboardSerializer(serializers.ModelSerializer):
meta class meta class
""" """
model = JuniorPoints model = JuniorPoints
fields = ('total_points', 'rank', 'junior') fields = ('user_id', 'user_type', 'total_points', 'rank', 'junior')
@staticmethod
def get_user_id(obj):
return obj.junior.auth.id
@staticmethod
def get_user_type(obj):
return JUNIOR
class UserCSVReportSerializer(serializers.ModelSerializer): class UserCSVReportSerializer(serializers.ModelSerializer):

View File

@ -128,7 +128,9 @@ class AnalyticsViewSet(GenericViewSet):
:param request: :param request:
:return: :return:
""" """
queryset = JuniorPoints.objects.prefetch_related('junior', 'junior__auth').annotate(rank=Window( queryset = JuniorPoints.objects.filter(
junior__is_verified=True
).select_related('junior', 'junior__auth').annotate(rank=Window(
expression=Rank(), expression=Rank(),
order_by=[F('total_points').desc(), 'junior__created_at'] order_by=[F('total_points').desc(), 'junior__created_at']
)).order_by('-total_points', 'junior__created_at') )).order_by('-total_points', 'junior__created_at')
@ -199,7 +201,9 @@ class AnalyticsViewSet(GenericViewSet):
# sheet 3 for Juniors Leaderboard and rank # sheet 3 for Juniors Leaderboard and rank
elif sheet_name == 'Juniors Leaderboard': elif sheet_name == 'Juniors Leaderboard':
queryset = JuniorPoints.objects.prefetch_related('junior', 'junior__auth').annotate(rank=Window( queryset = JuniorPoints.objects.filter(
junior__is_verified=True
).select_related('junior', 'junior__auth').annotate(rank=Window(
expression=Rank(), expression=Rank(),
order_by=[F('total_points').desc(), 'junior__created_at'] order_by=[F('total_points').desc(), 'junior__created_at']
)).order_by('-total_points', 'junior__created_at')[:15] )).order_by('-total_points', 'junior__created_at')[:15]