From 9f9926da14b9230077c9df0216563f123e09cf77 Mon Sep 17 00:00:00 2001 From: jain Date: Wed, 19 Jul 2023 17:45:20 +0530 Subject: [PATCH] jira-34 referral code validation API --- base/messages.py | 5 ++-- guardian/serializers.py | 12 +++++---- guardian/utils.py | 18 +++++++++++++ guardian/views.py | 4 +-- junior/admin.py | 2 +- ...l_task_points_juniorpoints_total_points.py | 18 +++++++++++++ .../0016_juniorpoints_referral_points.py | 18 +++++++++++++ junior/models.py | 6 +++-- junior/serializers.py | 8 +++--- junior/urls.py | 4 ++- junior/views.py | 27 +++++++++++++++++++ 11 files changed, 106 insertions(+), 16 deletions(-) create mode 100644 junior/migrations/0015_rename_total_task_points_juniorpoints_total_points.py create mode 100644 junior/migrations/0016_juniorpoints_referral_points.py diff --git a/base/messages.py b/base/messages.py index f04c2b8..998a5b2 100644 --- a/base/messages.py +++ b/base/messages.py @@ -42,7 +42,7 @@ ERROR_CODE = { "2016": "Invalid search.", "2017": "{model} object with {pk} does not exist", "2018": "Attached File not found", - "2019": "Either File extension or File size doesn't meet the requirements", + "2019": "Invalid Referral code", "2020": "Enter valid mobile number", "2021": "Already register", "2022": "Invalid Guardian code", @@ -120,7 +120,8 @@ SUCCESS_CODE = { "3029": "Article has been deleted successfully.", "3030": "Article Card has been removed successfully.", "3031": "Article Survey has been removed successfully.", - "3032": "Task request sent successfully" + "3032": "Task request sent successfully", + "3033": "Valid Referral code", } """status code error""" STATUS_CODE_ERROR = { diff --git a/guardian/serializers.py b/guardian/serializers.py index ff9edaf..a5ad978 100644 --- a/guardian/serializers.py +++ b/guardian/serializers.py @@ -24,7 +24,7 @@ from junior.serializers import JuniorDetailSerializer from base.messages import ERROR_CODE, SUCCESS_CODE from base.constants import NUMBER, JUN, ZOD, GRD from junior.models import Junior, JuniorPoints -from .utils import real_time, convert_timedelta_into_datetime +from .utils import real_time, convert_timedelta_into_datetime, update_referral_points @@ -141,7 +141,6 @@ class CreateGuardianSerializer(serializers.ModelSerializer): guardian.country_code = validated_data.get('country_code', guardian.country_code) guardian.passcode = validated_data.get('passcode', guardian.passcode) guardian.country_name = validated_data.get('country_name', guardian.country_name) - guardian.referral_code_used = validated_data.get('referral_code_used', guardian.referral_code_used) guardian.image = validated_data.get('image', guardian.image) """Complete profile of the junior if below all data are filled""" complete_profile_field = all([guardian.gender, guardian.country_name, @@ -150,6 +149,9 @@ class CreateGuardianSerializer(serializers.ModelSerializer): guardian.is_complete_profile = False if complete_profile_field: guardian.is_complete_profile = True + referral_code_used = validated_data.get('referral_code_used') + update_referral_points(guardian.referral_code, referral_code_used) + guardian.referral_code_used = validated_data.get('referral_code_used', guardian.referral_code_used) guardian.save() return guardian @@ -235,7 +237,7 @@ class TopJuniorSerializer(serializers.ModelSerializer): class Meta(object): """Meta info""" model = JuniorPoints - fields = ['id', 'junior', 'total_task_points', 'position', 'created_at', 'updated_at'] + fields = ['id', 'junior', 'total_points', 'position', 'created_at', 'updated_at'] def to_representation(self, instance): """Convert instance to representation""" @@ -322,7 +324,7 @@ class ApproveTaskSerializer(serializers.ModelSerializer): instance.task_status = str(NUMBER['five']) instance.is_approved = True # update total task point - junior_data.total_task_points = junior_data.total_task_points + instance.points + junior_data.total_points = junior_data.total_points + instance.points # update complete time of task instance.completed_on = real_time() else: @@ -330,7 +332,7 @@ class ApproveTaskSerializer(serializers.ModelSerializer): instance.task_status = str(NUMBER['three']) instance.is_approved = False # update total task point - junior_data.total_task_points = junior_data.total_task_points - instance.points + junior_data.total_points = junior_data.total_points - instance.points # update reject time of task instance.rejected_on = real_time() instance.save() diff --git a/guardian/utils.py b/guardian/utils.py index f45caa8..45bf69b 100644 --- a/guardian/utils.py +++ b/guardian/utils.py @@ -11,6 +11,8 @@ from datetime import datetime, time import ntplib # import Number constant from base.constants import NUMBER +# Import Junior's model +from junior.models import Junior, JuniorPoints # Define upload image on # ali baba cloud @@ -21,6 +23,10 @@ from base.constants import NUMBER # bucket and reform the image url""" # fetch real time data without depend on system time # convert time delta into date time object +# update junior total points +# update referral points +# if any one use referral code of the junior +# junior earn 5 points def upload_image_to_alibaba(image, filename): """upload image on oss alibaba bucket""" @@ -59,3 +65,15 @@ def convert_timedelta_into_datetime(time_difference): # Create a new time object with the extracted time components time_only = time(hours, minutes, seconds, microseconds) return time_only + +def update_referral_points(referral_code, referral_code_used): + """Update benefit of referral points""" + junior_queryset = Junior.objects.filter(referral_code=referral_code_used).last() + if junior_queryset and junior_queryset.referral_code != referral_code: + # create data if junior points is not exist + junior_query, created = JuniorPoints.objects.get_or_create(junior=junior_queryset) + if junior_query: + # update junior total points and referral points + junior_query.total_points = junior_query.total_points + NUMBER['five'] + junior_query.referral_points = junior_query.referral_points + NUMBER['five'] + junior_query.save() diff --git a/guardian/views.py b/guardian/views.py index b0e2c34..725eab2 100644 --- a/guardian/views.py +++ b/guardian/views.py @@ -94,7 +94,7 @@ class UpdateGuardianProfile(viewsets.ViewSet): if serializer.is_valid(): """save serializer""" serializer.save() - return custom_response(None, serializer.data,response_status=status.HTTP_200_OK) + return custom_response(None, serializer.data, response_status=status.HTTP_200_OK) return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST) @@ -206,7 +206,7 @@ class TopJuniorListAPIView(viewsets.ModelViewSet): def list(self, request, *args, **kwargs): """Fetch junior list of those who complete their tasks""" - junior_total_points = self.get_queryset().order_by('-total_task_points') + junior_total_points = self.get_queryset().order_by('-total_points') # Update the position field for each JuniorPoints object for index, junior in enumerate(junior_total_points): diff --git a/junior/admin.py b/junior/admin.py index 3764f48..99f1cd0 100644 --- a/junior/admin.py +++ b/junior/admin.py @@ -16,7 +16,7 @@ class JuniorAdmin(admin.ModelAdmin): @admin.register(JuniorPoints) class JuniorPointsAdmin(admin.ModelAdmin): """Junior Points Admin""" - list_display = ['junior', 'total_task_points', 'position'] + list_display = ['junior', 'total_points', 'position'] def __str__(self): """Return email id""" diff --git a/junior/migrations/0015_rename_total_task_points_juniorpoints_total_points.py b/junior/migrations/0015_rename_total_task_points_juniorpoints_total_points.py new file mode 100644 index 0000000..038adba --- /dev/null +++ b/junior/migrations/0015_rename_total_task_points_juniorpoints_total_points.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.2 on 2023-07-19 09:40 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('junior', '0014_junior_is_password_set'), + ] + + operations = [ + migrations.RenameField( + model_name='juniorpoints', + old_name='total_task_points', + new_name='total_points', + ), + ] diff --git a/junior/migrations/0016_juniorpoints_referral_points.py b/junior/migrations/0016_juniorpoints_referral_points.py new file mode 100644 index 0000000..a70f45d --- /dev/null +++ b/junior/migrations/0016_juniorpoints_referral_points.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.2 on 2023-07-19 11:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('junior', '0015_rename_total_task_points_juniorpoints_total_points'), + ] + + operations = [ + migrations.AddField( + model_name='juniorpoints', + name='referral_points', + field=models.IntegerField(blank=True, default=0, null=True), + ), + ] diff --git a/junior/models.py b/junior/models.py index f4ef488..28754b1 100644 --- a/junior/models.py +++ b/junior/models.py @@ -89,8 +89,10 @@ class Junior(models.Model): class JuniorPoints(models.Model): """Junior model""" junior = models.OneToOneField(Junior, on_delete=models.CASCADE, related_name='junior_points') - # Contact details""" - total_task_points = models.IntegerField(blank=True, null=True, default=0) + # Total earned points""" + total_points = models.IntegerField(blank=True, null=True, default=0) + # referral points""" + referral_points = models.IntegerField(blank=True, null=True, default=0) # position of the junior""" position = models.IntegerField(blank=True, null=True, default=99999) # Profile created and updated time""" diff --git a/junior/serializers.py b/junior/serializers.py index cd12a2e..b0ddfa1 100644 --- a/junior/serializers.py +++ b/junior/serializers.py @@ -16,7 +16,7 @@ from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, from guardian.models import Guardian, JuniorTask from account.models import UserEmailOtp from junior.utils import junior_notification_email, junior_approval_mail -from guardian.utils import real_time +from guardian.utils import real_time, update_referral_points class ListCharField(serializers.ListField): @@ -92,7 +92,6 @@ class CreateJuniorSerializer(serializers.ModelSerializer): """Update country code and phone number""" junior.phone = validated_data.get('phone', junior.phone) junior.country_code = validated_data.get('country_code', junior.country_code) - junior.referral_code_used = validated_data.get('referral_code_used', junior.referral_code_used) junior.image = validated_data.get('image', junior.image) """Complete profile of the junior if below all data are filled""" complete_profile_field = all([junior.gender, junior.country_name, junior.image, @@ -100,6 +99,9 @@ class CreateJuniorSerializer(serializers.ModelSerializer): junior.is_complete_profile = False if complete_profile_field: junior.is_complete_profile = True + referral_code_used = validated_data.get('referral_code_used') + update_referral_points(junior.referral_code, referral_code_used) + junior.referral_code_used = validated_data.get('referral_code_used', junior.referral_code_used) junior.save() return junior @@ -346,7 +348,7 @@ class JuniorPointsSerializer(serializers.ModelSerializer): """total points""" points = JuniorPoints.objects.filter(junior=obj.junior).last() if points: - return points.total_task_points + return points.total_points def get_in_progress_task(self, obj): return JuniorTask.objects.filter(junior=obj.junior, task_status=IN_PROGRESS).count() diff --git a/junior/urls.py b/junior/urls.py index 6057c05..e4a160d 100644 --- a/junior/urls.py +++ b/junior/urls.py @@ -3,7 +3,7 @@ from django.urls import path, include from .views import (UpdateJuniorProfile, ValidateGuardianCode, JuniorListAPIView, AddJuniorAPIView, InvitedJuniorAPIView, FilterJuniorAPIView, RemoveJuniorAPIView, JuniorTaskListAPIView, - CompleteJuniorTaskAPIView, JuniorPointsListAPIView) + CompleteJuniorTaskAPIView, JuniorPointsListAPIView, ValidateReferralCode) """Third party import""" from rest_framework import routers @@ -36,6 +36,8 @@ router.register('filter-junior', FilterJuniorAPIView, basename='filter-junior') router.register('junior-task-list', JuniorTaskListAPIView, basename='junior-task-list') # junior's task list API""" router.register('junior-points', JuniorPointsListAPIView, basename='junior-points') +# validate referral code API""" +router.register('validate-referral-code', ValidateReferralCode, basename='validate-referral-code') # Define url pattern""" urlpatterns = [ path('api/v1/', include(router.urls)), diff --git a/junior/views.py b/junior/views.py index e1064af..29f8331 100644 --- a/junior/views.py +++ b/junior/views.py @@ -37,6 +37,8 @@ from guardian.utils import upload_image_to_alibaba # search junior API # remove junior API, # approve junior API +# create referral code +# validation API # Create your views here. class UpdateJuniorProfile(viewsets.ViewSet): @@ -272,3 +274,28 @@ class JuniorPointsListAPIView(viewsets.ModelViewSet): requests.get(os.getenv('BASE_URL') + '/api/v1/top-junior/', headers=headers) serializer = JuniorPointsSerializer(queryset) return custom_response(None, serializer.data, response_status=status.HTTP_200_OK) + +class ValidateReferralCode(viewsets.ViewSet): + """Check guardian code exist or not""" + permission_classes = [IsAuthenticated] + + def get_queryset(self): + """Get queryset based on referral_code.""" + referral_code = self.request.GET.get('referral_code') + if referral_code: + # search referral code in guardian model + guardian_queryset = Guardian.objects.filter(referral_code=referral_code).last() + if guardian_queryset: + return guardian_queryset + else: + # search referral code in junior model + junior_queryset = Junior.objects.filter(referral_code=referral_code).last() + if junior_queryset: + return junior_queryset + return None + + def list(self, request, *args, **kwargs): + """check guardian code""" + if self.get_queryset(): + return custom_response(SUCCESS_CODE['3033'], response_status=status.HTTP_200_OK) + return custom_error_response(ERROR_CODE["2019"], response_status=status.HTTP_400_BAD_REQUEST)