Merge pull request #89 from KiwiTechLLC/sprint3

Sprint3
This commit is contained in:
dilipshrivastwa-kiwi
2023-07-19 18:05:07 +05:30
committed by GitHub
11 changed files with 121 additions and 16 deletions

View File

@ -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 = {

View File

@ -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()

View File

@ -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()

View File

@ -96,7 +96,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)
@ -208,7 +208,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):

View File

@ -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"""

View File

@ -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',
),
]

View File

@ -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),
),
]

View File

@ -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"""

View File

@ -16,7 +16,8 @@ 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 +93,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 +100,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 +349,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()

View File

@ -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)),

View File

@ -18,6 +18,7 @@ import requests
# from utils file
# Import account's serializer
# Import account's task
# import junior serializer
from junior.models import Junior
from .serializers import (CreateJuniorSerializer, JuniorDetailListSerializer, AddJuniorSerializer,\
RemoveJuniorSerializer, CompleteTaskSerializer, JuniorPointsSerializer)
@ -37,6 +38,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):
@ -53,6 +56,7 @@ class UpdateJuniorProfile(viewsets.ViewSet):
if image:
if image.size == NUMBER['zero']:
return custom_error_response(ERROR_CODE['2035'], response_status=status.HTTP_400_BAD_REQUEST)
# convert into file
filename = f"images/{image.name}"
# upload image on ali baba
image_url = upload_image_to_alibaba(image, filename)
@ -99,6 +103,7 @@ class JuniorListAPIView(viewsets.ModelViewSet):
}
requests.get(os.getenv('BASE_URL') + '/api/v1/top-junior/', headers=headers_token)
guardian_data = Guardian.objects.filter(user__email=request.user).last()
# fetch junior object
queryset = Junior.objects.filter(guardian_code__icontains=str(guardian_data.guardian_code))
# use JuniorDetailListSerializer serializer
serializer = JuniorDetailListSerializer(queryset, many=True)
@ -139,6 +144,7 @@ class InvitedJuniorAPIView(viewsets.ModelViewSet):
""" junior list"""
queryset = self.get_queryset()
paginator = self.pagination_class()
# pagination
paginated_queryset = paginator.paginate_queryset(queryset, request)
# use JuniorDetailListSerializer serializer
serializer = JuniorDetailListSerializer(paginated_queryset, many=True)
@ -156,6 +162,7 @@ class FilterJuniorAPIView(viewsets.ModelViewSet):
"""Get the queryset for the view"""
title = self.request.GET.get('title')
guardian_data = Guardian.objects.filter(user__email=self.request.user).last()
# fetch junior query
queryset = Junior.objects.filter(guardian_code__icontains=str(guardian_data.guardian_code),
is_invited=True, auth__first_name=title)
return queryset
@ -207,14 +214,18 @@ class JuniorTaskListAPIView(viewsets.ModelViewSet):
status_value = self.request.GET.get('status')
search = self.request.GET.get('search')
if search and str(status_value) == '0':
# search with title and for all task list
queryset = JuniorTask.objects.filter(junior__auth=request.user,
task_name__icontains=search).order_by('due_date', 'created_at')
elif search and str(status_value) != '0':
# search with title and fetch task list with status wise
queryset = JuniorTask.objects.filter(junior__auth=request.user, task_name__icontains=search,
task_status=status_value).order_by('due_date', 'created_at')
if search is None and str(status_value) == '0':
# fetch all task list
queryset = JuniorTask.objects.filter(junior__auth=request.user).order_by('due_date', 'created_at')
elif search is None and str(status_value) != '0':
# fetch task list with status wise
queryset = JuniorTask.objects.filter(junior__auth=request.user,
task_status=status_value).order_by('due_date','created_at')
paginator = self.pagination_class()
@ -237,7 +248,11 @@ class CompleteJuniorTaskAPIView(views.APIView):
image = request.data['image']
if image and image.size == NUMBER['zero']:
return custom_error_response(ERROR_CODE['2035'], response_status=status.HTTP_400_BAD_REQUEST)
# create file
filename = f"images/{image.name}"
# upload image
filename = f"images/{image.name}"
image_url = upload_image_to_alibaba(image, filename)
# fetch junior query
task_queryset = JuniorTask.objects.filter(id=task_id, junior__auth__email=self.request.user).last()
@ -265,6 +280,7 @@ class JuniorPointsListAPIView(viewsets.ModelViewSet):
def list(self, request, *args, **kwargs):
"""profile view"""
queryset = self.get_queryset()
# update position of junior
token = self.request.META['HTTP_AUTHORIZATION']
headers = {
'Authorization': token
@ -272,3 +288,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)