Merge pull request #286 from KiwiTechLLC/dev

Dev
This commit is contained in:
Abu Talib
2023-08-28 20:35:49 +05:30
committed by GitHub
13 changed files with 94 additions and 70 deletions

View File

@ -94,7 +94,7 @@ def junior_account_update(user_tb):
junior_data.is_active = False
junior_data.is_verified = False
junior_data.guardian_code = None
junior_data.guardian_code_status = str(NUMBER['one'])
junior_data.guardian_code_status = None
junior_data.is_deleted = True
junior_data.save()
JuniorPoints.objects.filter(junior=junior_data).delete()

View File

@ -546,7 +546,6 @@ class UserEmailVerification(viewsets.ModelViewSet):
class ReSendEmailOtp(viewsets.ModelViewSet):
"""Send otp on phone"""
serializer_class = EmailVerificationSerializer
permission_classes = [IsAuthenticated]
http_method_names = ('post',)
def create(self, request, *args, **kwargs):
"""Param

View File

@ -68,10 +68,14 @@ def notify_top_junior():
task to send notification for top leaderboard junior to all junior's
:return:
"""
junior_points_qs = JuniorPoints.objects.select_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_points_qs = JuniorPoints.objects.filter(
junior__is_verified=True
).select_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')
prev_top_position = junior_points_qs.filter(position=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
def get_queryset(self):
queryset = JuniorPoints.objects.select_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')
queryset = JuniorPoints.objects.filter(
junior__is_verified=True
).select_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):

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 guardian.utils import real_time, update_referral_points, convert_timedelta_into_datetime
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
@ -91,6 +91,9 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
# Update guardian code"""
# condition for guardian code
if guardian_code:
if junior.guardian_code and guardian_code:
if guardian_code[0] in junior.guardian_code:
raise serializers.ValidationError({"error":ERROR_CODE['2076'],"code":"400", "status":"failed"})
if not junior.guardian_code:
junior.guardian_code = []
junior.guardian_code_status = []
@ -104,9 +107,8 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
guardian_data = Guardian.objects.filter(guardian_code=guardian_code[0]).last()
if guardian_data:
JuniorGuardianRelationship.objects.get_or_create(guardian=guardian_data, junior=junior)
send_notification.delay(ASSOCIATE_REQUEST, junior.auth.id, JUNIOR, guardian_data.user.id, {})
junior_approval_mail.delay(user.email, user.first_name)
send_notification.delay(ASSOCIATE_REQUEST, junior.auth.id, JUNIOR, guardian_data.user.id, {})
junior.dob = validated_data.get('dob', junior.dob)
junior.passcode = validated_data.get('passcode', junior.passcode)
junior.country_name = validated_data.get('country_name', junior.country_name)
@ -321,7 +323,7 @@ class AddJuniorSerializer(serializers.ModelSerializer):
"""Notification email"""
junior_notification_email.delay(email, full_name, email, password)
# 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

View File

@ -70,10 +70,12 @@ def get_junior_leaderboard_rank(junior_obj):
:param junior_obj:
:return: junior's position/rank
"""
queryset = JuniorPoints.objects.select_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')
queryset = JuniorPoints.objects.filter(
junior__is_verified=True
).select_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)

View File

@ -42,12 +42,12 @@ from .serializers import (CreateJuniorSerializer, JuniorDetailListSerializer, Ad
from guardian.models import Guardian, JuniorTask
from guardian.serializers import TaskDetailsSerializer, TaskDetailsjuniorSerializer
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 guardian.utils import upload_image_to_alibaba
from .utils import update_positions_based_on_points
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.serializers.article_serializer import (ArticleSerializer, ArticleListSerializer,
StartAssessmentSerializer)
@ -223,12 +223,16 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
junior.guardian_code.append(guardian.guardian_code)
else:
return "Max"
junior.guardian_code_status.append(str(NUMBER['two']))
if not junior.guardian_code_status:
junior.guardian_code_status = [str(NUMBER['two'])]
else:
junior.guardian_code_status.append(str(NUMBER['two']))
junior.save()
jun_data, created = JuniorGuardianRelationship.objects.get_or_create(guardian=guardian, junior=junior)
if jun_data:
jun_data.relationship = str(self.request.data['relationship'])
jun_data.save()
send_notification.delay(ASSOCIATE_EXISTING_JUNIOR, self.request.user.id, GUARDIAN, junior.auth.id, {})
return True
@ -326,6 +330,7 @@ class RemoveJuniorAPIView(views.APIView):
if serializer.is_valid():
# save serializer
serializer.save()
JuniorGuardianRelationship.objects.filter(guardian=guardian, junior=junior_queryset).delete()
send_notification.delay(REMOVE_JUNIOR, None, None, junior_queryset.auth.id, {})
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)
@ -744,6 +749,7 @@ class RemoveGuardianCodeAPIView(views.APIView):
def put(self, request, format=None):
try:
guardian_code = self.request.data.get("guardian_code")
guardian_data = Guardian.objects.filter(guardian_code=guardian_code).last()
junior_queryset = Junior.objects.filter(auth=self.request.user).last()
if junior_queryset:
# use RemoveGuardianCodeSerializer serializer
@ -752,6 +758,7 @@ class RemoveGuardianCodeAPIView(views.APIView):
if serializer.is_valid():
# save serializer
serializer.save()
JuniorGuardianRelationship.objects.filter(guardian=guardian_data, junior=junior_queryset).delete()
return custom_response(SUCCESS_CODE['3044'], response_status=status.HTTP_200_OK)
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
else:

View File

@ -6,19 +6,20 @@ ASSOCIATE_REQUEST = 3
ASSOCIATE_REJECTED = 4
ASSOCIATE_APPROVED = 5
REFERRAL_POINTS = 6
JUNIOR_ADDED = 7
ASSOCIATE_JUNIOR = 7
ASSOCIATE_EXISTING_JUNIOR = 8
TASK_ASSIGNED = 8
TASK_ACTION = 9
TASK_REJECTED = 10
TASK_APPROVED = 11
PENDING_TASK_EXPIRING = 12
IN_PROGRESS_TASK_EXPIRING = 13
TOP_JUNIOR = 14
TASK_ASSIGNED = 9
TASK_ACTION = 10
TASK_REJECTED = 11
TASK_APPROVED = 12
PENDING_TASK_EXPIRING = 13
IN_PROGRESS_TASK_EXPIRING = 14
TOP_JUNIOR = 15
NEW_ARTICLE_PUBLISHED = 15
ARTICLE_REWARD_POINTS = 16
REMOVE_JUNIOR = 17
NEW_ARTICLE_PUBLISHED = 16
ARTICLE_REWARD_POINTS = 17
REMOVE_JUNIOR = 18
TEST_NOTIFICATION = 99
@ -53,10 +54,14 @@ NOTIFICATION_DICT = {
},
# Juniors will receive notification
# once any custodians add them in their account
JUNIOR_ADDED: {
ASSOCIATE_JUNIOR: {
"title": "Profile already setup!",
"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
# for every Task Assign by Custodians
TASK_ASSIGNED: {

View File

@ -19,14 +19,13 @@ from junior.models import Junior
from notifications.constants import NOTIFICATION_DICT
from notifications.models import Notification
User = get_user_model()
def register_fcm_token(user_id, registration_id, device_id, device_type):
""" used to register the fcm device token"""
device, _ = FCMDevice.objects.update_or_create(device_id=device_id,
defaults={'user_id': user_id, 'type': device_type,
device, _ = FCMDevice.objects.update_or_create(user_id=user_id,
defaults={'device_id': device_id, 'type': device_type,
'active': True,
'registration_id': registration_id})
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.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
@ -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
).exclude(junior_profile__isnull=True, guardian_profile__isnull=True)
push_data = NOTIFICATION_DICT[notification_type].copy()
notification_data = push_data.copy()
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_data, push_data, from_user, _ = get_notification_data(notification_type, from_user_id,
from_user_type, None, extra_data)
notification_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_to=user,
notification_from=from_user,
data=notification_data))
data=notification_copy_data))
Notification.objects.bulk_create(notification_list)
to_user_list = to_user_list.filter(user_notification__push_notification=True)
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()
extra_data['from_user_image'] = from_user.image
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')
def send_test_notification(self, request):
"""
to send test notification
to test send notification, task expiry, top junior
:return:
"""
notify_task_expiry()
notify_top_junior()
send_notification(TEST_NOTIFICATION, None, None, request.auth.payload['user_id'],
{})
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)
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
# local imports
from base.constants import USER_TYPE
from base.constants import USER_TYPE, JUNIOR
from junior.models import JuniorPoints, Junior
@ -37,7 +37,7 @@ class JuniorLeaderboardSerializer(serializers.ModelSerializer):
:param obj: junior object
: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
def get_first_name(obj):
@ -60,6 +60,8 @@ class LeaderboardSerializer(serializers.ModelSerializer):
"""
leaderboard serializer
"""
user_id = serializers.SerializerMethodField()
user_type = serializers.SerializerMethodField()
junior = JuniorLeaderboardSerializer()
rank = serializers.IntegerField()
@ -68,7 +70,15 @@ class LeaderboardSerializer(serializers.ModelSerializer):
meta class
"""
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):

View File

@ -128,10 +128,12 @@ class AnalyticsViewSet(GenericViewSet):
:param request:
:return:
"""
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')
queryset = JuniorPoints.objects.filter(
junior__is_verified=True
).select_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')
paginator = CustomPageNumberPagination()
paginated_queryset = paginator.paginate_queryset(queryset, request)
serializer = self.serializer_class(paginated_queryset, many=True)
@ -199,10 +201,12 @@ class AnalyticsViewSet(GenericViewSet):
# 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]
queryset = JuniorPoints.objects.filter(
junior__is_verified=True
).select_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([
{
'Name': get_user_full_name(junior.junior.auth),