Compare commits

...
Author SHA1 Message Date
jain d3b0be953e login api with user type 2023-08-14 15:16:16 +05:30
jain 11b9f00285 Merge branch 'login_api_reduced_queries' of github.com:KiwiTechLLC/ZODBank-Backend into login_api_reduced_queries 2023-08-14 15:01:43 +05:30
jain 6373d1e02c sonar fixes 2023-08-14 12:13:14 +05:30
jain 070637bf1d is complete key 2023-08-14 11:43:59 +05:30
Ankitajain-kiwi fd9a4902ae Merge pull request #199 from KiwiTechLLC/sprint4
guardian code chnages
2023-08-11 16:55:21 +05:30
jain 082f93ff9d guardian code chnages 2023-08-11 16:54:27 +05:30
dilipshrivastwa-kiwi 25eaee31a4 Merge pull request #198 from KiwiTechLLC/ZBKADM-71
added pagination in leaderboard admin
2023-08-11 16:02:13 +05:30
Ankitajain-kiwi cae28e0b54 Merge pull request #197 from KiwiTechLLC/sprint4
is complete article key
2023-08-11 15:41:35 +05:30
jain 54200dba52 is complete article key 2023-08-11 15:39:25 +05:30
dilipshrivastwa-kiwi 846a9d42d4 Merge pull request #196 from KiwiTechLLC/ZBKADM-72-sonar-issues
sonar issues
2023-08-11 14:44:25 +05:30
abutalib-kiwi 69c19cf097 sonar issues 2023-08-11 14:40:49 +05:30
Ruman Siddiqui 4f02cef0f9 Optimised login api 2023-08-10 18:43:03 +05:30
12 changed files with 131 additions and 89 deletions
+13 -5
View File
@@ -152,7 +152,8 @@ class AdminLoginSerializer(serializers.ModelSerializer):
def validate(self, attrs): def validate(self, attrs):
user = User.objects.filter(email__iexact=attrs['email'], is_superuser=True user = User.objects.filter(email__iexact=attrs['email'], is_superuser=True
).only('id', 'first_name', 'last_name', 'email', 'is_superuser').first() ).only('id', 'first_name', 'last_name', 'email',
'username', 'is_active', 'is_superuser').first()
if not user or not user.check_password(attrs['password']): if not user or not user.check_password(attrs['password']):
raise serializers.ValidationError({'details': ERROR_CODE['2002']}) raise serializers.ValidationError({'details': ERROR_CODE['2002']})
@@ -215,10 +216,17 @@ class GuardianSerializer(serializers.ModelSerializer):
def get_user_type(self, obj): def get_user_type(self, obj):
"""user type""" """user type"""
email_verified = UserEmailOtp.objects.filter(email=obj.user.username).last() if self.context.get('user_type', ''):
if email_verified and email_verified.user_type is not None: return self.context.get('user_type')
return email_verified.user_type # remove the below code once user_type can be passed
return str(NUMBER['two']) # from everywhere from where this serializer is being called
else:
email_verified = UserEmailOtp.objects.filter(
email=obj.user.username
).last()
if email_verified and email_verified.user_type is not None:
return email_verified.user_type
return str(NUMBER['two'])
def get_auth(self, obj): def get_auth(self, obj):
"""user email address""" """user email address"""
+19 -2
View File
@@ -1,4 +1,6 @@
"""Account utils""" """Account utils"""
from celery import shared_task
"""Import django""" """Import django"""
from django.conf import settings from django.conf import settings
from rest_framework import viewsets, status from rest_framework import viewsets, status
@@ -20,7 +22,7 @@ from rest_framework import serializers
# Import messages from base package""" # Import messages from base package"""
from junior.models import Junior from junior.models import Junior
from guardian.models import Guardian from guardian.models import Guardian
from account.models import UserDelete from account.models import UserDelete, UserDeviceDetails
from base.messages import ERROR_CODE from base.messages import ERROR_CODE
from django.utils import timezone from django.utils import timezone
from base.constants import NUMBER from base.constants import NUMBER
@@ -44,7 +46,7 @@ from junior.models import JuniorPoints
# referral code, # referral code,
# Define function for generating # Define function for generating
# alphanumeric code # alphanumeric code
# otp expiry
def delete_user_account_condition(user, user_type_data, user_type, user_tb, data, random_num): def delete_user_account_condition(user, user_type_data, user_type, user_tb, data, random_num):
"""delete user account""" """delete user account"""
if user_type == '1' and user_type_data == '1': if user_type == '1' and user_type_data == '1':
@@ -109,6 +111,7 @@ def guardian_account_update(user_tb):
for data in jun_data: for data in jun_data:
data.guardian_code.remove(guardian_data.guardian_code) data.guardian_code.remove(guardian_data.guardian_code)
data.save() data.save()
@shared_task()
def send_otp_email(recipient_email, otp): def send_otp_email(recipient_email, otp):
"""Send otp on email with template""" """Send otp on email with template"""
from_email = settings.EMAIL_FROM_ADDRESS from_email = settings.EMAIL_FROM_ADDRESS
@@ -124,6 +127,20 @@ def send_otp_email(recipient_email, otp):
) )
return otp return otp
@shared_task
def user_device_details(user, device_id):
"""
Used to store the device id of the user
user: user object
device_id: string
return
"""
device_details, created = UserDeviceDetails.objects.get_or_create(user=user)
if device_details:
device_details.device_id = device_id
device_details.save()
def send_support_email(name, sender, subject, message): def send_support_email(name, sender, subject, message):
"""Send otp on email with template""" """Send otp on email with template"""
to_email = [settings.EMAIL_FROM_ADDRESS] to_email = [settings.EMAIL_FROM_ADDRESS]
+53 -21
View File
@@ -1,4 +1,6 @@
"""Account view """ """Account view """
import threading
from notifications.utils import remove_fcm_token from notifications.utils import remove_fcm_token
# django imports # django imports
@@ -35,10 +37,10 @@ from .serializers import (SuperUserSerializer, GuardianSerializer, JuniorSeriali
AdminLoginSerializer) AdminLoginSerializer)
from rest_framework_simplejwt.tokens import RefreshToken from rest_framework_simplejwt.tokens import RefreshToken
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
from base.constants import NUMBER, ZOD, JUN, GRD from base.constants import NUMBER, ZOD, JUN, GRD, USER_TYPE_FLAG
from guardian.tasks import generate_otp from guardian.tasks import generate_otp
from account.utils import (send_otp_email, send_support_email, custom_response, custom_error_response, from account.utils import (send_otp_email, send_support_email, custom_response, custom_error_response,
generate_code, OTP_EXPIRY) generate_code, OTP_EXPIRY, user_device_details)
from junior.serializers import JuniorProfileSerializer from junior.serializers import JuniorProfileSerializer
from guardian.serializers import GuardianProfileSerializer from guardian.serializers import GuardianProfileSerializer
@@ -280,29 +282,48 @@ class UserPhoneVerification(viewsets.ModelViewSet):
return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST)
class UserLogin(viewsets.ViewSet): class UserLogin(viewsets.ViewSet):
"""User login""" """User login"""
@action(methods=['post'], detail=False) @action(methods=['post'], detail=False)
def login(self, request): def login(self, request):
username = request.data.get('username') username = request.data.get('username')
password = request.data.get('password') password = request.data.get('password')
user_type = request.data.get('user_type')
device_id = request.META.get('HTTP_DEVICE_ID') device_id = request.META.get('HTTP_DEVICE_ID')
user = authenticate(request, username=username, password=password) user = authenticate(request, username=username, password=password)
try: try:
if user is not None: if user is not None:
login(request, user) login(request, user)
guardian_data = Guardian.objects.filter(user__username=username, is_verified=True).last() if user_type == USER_TYPE_FLAG["TWO"]:
if guardian_data: guardian_data = Guardian.objects.filter(user__username=username, is_verified=True).last()
serializer = GuardianSerializer(guardian_data).data if guardian_data:
junior_data = Junior.objects.filter(auth__username=username, is_verified=True).last() serializer = GuardianSerializer(
if junior_data: guardian_data, context={'user_type': user_type}
serializer = JuniorSerializer(junior_data).data ).data
device_details, created = UserDeviceDetails.objects.get_or_create(user=user) else:
if device_details: return custom_error_response(
device_details.device_id = device_id ERROR_CODE["2070"],
device_details.save() response_status=status.HTTP_401_UNAUTHORIZED
)
elif user_type == USER_TYPE_FLAG["FIRST"]:
junior_data = Junior.objects.filter(auth__username=username, is_verified=True).last()
if junior_data:
serializer = JuniorSerializer(
junior_data, context={'user_type': user_type}
).data
else:
return custom_error_response(
ERROR_CODE["2071"],
response_status=status.HTTP_401_UNAUTHORIZED
)
else:
return custom_error_response(
ERROR_CODE["2069"],
response_status=status.HTTP_401_UNAUTHORIZED
)
# storing device id in using thread so the time would be reduced
threading.Thread(target=user_device_details, args=(user, device_id))
return custom_response(SUCCESS_CODE['3003'], serializer, response_status=status.HTTP_200_OK) return custom_response(SUCCESS_CODE['3003'], serializer, response_status=status.HTTP_200_OK)
else: else:
return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_401_UNAUTHORIZED) return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_401_UNAUTHORIZED)
@@ -312,9 +333,12 @@ class UserLogin(viewsets.ViewSet):
refresh = RefreshToken.for_user(user) refresh = RefreshToken.for_user(user)
access_token = str(refresh.access_token) access_token = str(refresh.access_token)
refresh_token = str(refresh) refresh_token = str(refresh)
data = {"auth_token":access_token, "refresh_token":refresh_token, "is_profile_complete": False, data = {
"user_type": email_verified.user_type, "auth_token":access_token,
} "refresh_token":refresh_token,
"is_profile_complete": False,
"user_type": user_type,
}
is_verified = False is_verified = False
if email_verified: if email_verified:
is_verified = email_verified.is_verified is_verified = email_verified.is_verified
@@ -323,18 +347,26 @@ class UserLogin(viewsets.ViewSet):
email_verified.otp = otp email_verified.otp = otp
email_verified.save() email_verified.save()
data.update({"email_otp":otp}) data.update({"email_otp":otp})
send_otp_email(username, otp) send_otp_email.delay(username, otp)
return custom_response(ERROR_CODE['2024'], {"email_otp": otp, "is_email_verified": is_verified}, return custom_response(
response_status=status.HTTP_200_OK) ERROR_CODE['2024'],
{"email_otp": otp, "is_email_verified": is_verified},
response_status=status.HTTP_200_OK
)
data.update({"is_email_verified": is_verified}) data.update({"is_email_verified": is_verified})
return custom_response(SUCCESS_CODE['3003'], data, response_status=status.HTTP_200_OK) return custom_response(
SUCCESS_CODE['3003'],
data,
response_status=status.HTTP_200_OK
)
@action(methods=['post'], detail=False) @action(methods=['post'], detail=False)
def admin_login(self, request): def admin_login(self, request):
email = request.data.get('email') email = request.data.get('email')
password = request.data.get('password') password = request.data.get('password')
user = User.objects.filter(email__iexact=email, is_superuser=True user = User.objects.filter(email__iexact=email, is_superuser=True
).only('id', 'first_name', 'last_name', 'email', 'is_superuser').first() ).only('id', 'first_name', 'last_name', 'email',
'username', 'is_active', 'is_superuser').first()
if not user or not user.check_password(password): if not user or not user.check_password(password):
return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_400_BAD_REQUEST)
+9
View File
@@ -50,6 +50,13 @@ USER_TYPE = (
('2', 'guardian'), ('2', 'guardian'),
('3', 'superuser') ('3', 'superuser')
) )
USER_TYPE_FLAG = {
"FIRST" : "1",
"TWO" : "2",
"THREE": "3"
}
"""gender""" """gender"""
GENDERS = ( GENDERS = (
('1', 'Male'), ('1', 'Male'),
@@ -122,3 +129,5 @@ MAX_ARTICLE_SURVEY = 10
Already_register_user = "duplicate key value violates unique constraint" Already_register_user = "duplicate key value violates unique constraint"
ARTICLE_CARD_IMAGE_FOLDER = 'article-card-images' ARTICLE_CARD_IMAGE_FOLDER = 'article-card-images'
DATE_FORMAT = '%Y-%m-%d'
+4 -1
View File
@@ -94,7 +94,10 @@ ERROR_CODE = {
"2065": "Passwords do not match. Please try again.", "2065": "Passwords do not match. Please try again.",
"2066": "Task does not exist or not in expired state", "2066": "Task does not exist or not in expired state",
"2067": "Action not allowed. User type missing.", "2067": "Action not allowed. User type missing.",
"2068": "No guardian associated with this junior" "2068": "No guardian associated with this junior",
"2069": "Invalid user type",
"2070": "You did not find as a guardian",
"2071": "You did not find as a junior"
} }
"""Success message code""" """Success message code"""
-32
View File
@@ -124,38 +124,6 @@ class AllTaskListAPIView(viewsets.ModelViewSet):
serializer = TaskDetailsSerializer(queryset, many=True) serializer = TaskDetailsSerializer(queryset, 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)
# class TaskListAPIView(viewsets.ModelViewSet):
# """Update guardian profile"""
# serializer_class = TaskDetailsSerializer
# permission_classes = [IsAuthenticated]
# pagination_class = PageNumberPagination
# http_method_names = ('get',)
#
# def list(self, request, *args, **kwargs):
# """Create guardian profile"""
# try:
# status_value = self.request.GET.get('status')
# search = self.request.GET.get('search')
# if search and str(status_value) == '0':
# queryset = JuniorTask.objects.filter(guardian__user=request.user,
# task_name__icontains=search).order_by('due_date', 'created_at')
# elif search and str(status_value) != '0':
# queryset = JuniorTask.objects.filter(guardian__user=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':
# queryset = JuniorTask.objects.filter(guardian__user=request.user).order_by('due_date', 'created_at')
# elif search is None and str(status_value) != '0':
# queryset = JuniorTask.objects.filter(guardian__user=request.user,
# task_status=status_value).order_by('due_date','created_at')
# paginator = self.pagination_class()
# # use Pagination
# paginated_queryset = paginator.paginate_queryset(queryset, request)
# # use TaskDetailsSerializer serializer
# serializer = TaskDetailsSerializer(paginated_queryset, many=True)
# return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
# except Exception as e:
# return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
class TaskListAPIView(viewsets.ModelViewSet): class TaskListAPIView(viewsets.ModelViewSet):
"""Update guardian profile""" """Update guardian profile"""
+3 -3
View File
@@ -146,8 +146,8 @@ class JuniorDetailSerializer(serializers.ModelSerializer):
"""Meta info""" """Meta info"""
model = Junior model = Junior
fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob', fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob',
'guardian_code', 'image', 'is_invited', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'guardian_code', 'image', 'is_invited', 'referral_code','is_active', 'is_complete_profile',
'image', 'updated_at'] 'created_at', 'image', 'updated_at']
class JuniorDetailListSerializer(serializers.ModelSerializer): class JuniorDetailListSerializer(serializers.ModelSerializer):
"""junior serializer""" """junior serializer"""
@@ -333,7 +333,6 @@ class CompleteTaskSerializer(serializers.ModelSerializer):
fields = ('id', 'image') fields = ('id', 'image')
def update(self, instance, validated_data): def update(self, instance, validated_data):
instance.image = validated_data.get('image', instance.image) instance.image = validated_data.get('image', instance.image)
# instance.requested_on = real_time()
instance.requested_on = timezone.now().astimezone(pytz.utc) instance.requested_on = timezone.now().astimezone(pytz.utc)
instance.task_status = str(NUMBER['four']) instance.task_status = str(NUMBER['four'])
instance.is_approved = False instance.is_approved = False
@@ -503,6 +502,7 @@ class RemoveGuardianCodeSerializer(serializers.ModelSerializer):
model = Junior model = Junior
fields = ('id', ) fields = ('id', )
def update(self, instance, validated_data): def update(self, instance, validated_data):
instance.guardian_code = None
instance.guardian_code_status = str(NUMBER['one']) instance.guardian_code_status = str(NUMBER['one'])
instance.save() instance.save()
return instance return instance
+2
View File
@@ -11,8 +11,10 @@ from rest_framework import viewsets, status, views
from account.utils import custom_response, custom_error_response from account.utils import custom_response, custom_error_response
from base.messages import SUCCESS_CODE, ERROR_CODE from base.messages import SUCCESS_CODE, ERROR_CODE
from notifications.constants import TEST_NOTIFICATION from notifications.constants import TEST_NOTIFICATION
# Import serializer
from notifications.serializers import RegisterDevice, NotificationListSerializer, ReadNotificationSerializer from notifications.serializers import RegisterDevice, NotificationListSerializer, ReadNotificationSerializer
from notifications.utils import send_notification from notifications.utils import send_notification
# Import model
from notifications.models import Notification from notifications.models import Notification
@@ -4,7 +4,6 @@ web_admin analytics serializer file
from rest_framework import serializers from rest_framework import serializers
from junior.models import JuniorPoints, Junior from junior.models import JuniorPoints, Junior
from web_admin.serializers.user_management_serializer import JuniorSerializer
class JuniorLeaderboardSerializer(serializers.ModelSerializer): class JuniorLeaderboardSerializer(serializers.ModelSerializer):
+7 -6
View File
@@ -224,7 +224,7 @@ class ArticleListSerializer(serializers.ModelSerializer):
total_points = serializers.SerializerMethodField('get_total_points') total_points = serializers.SerializerMethodField('get_total_points')
is_completed = serializers.SerializerMethodField('get_is_completed') is_completed = serializers.SerializerMethodField('get_is_completed')
class Meta: class Meta(object):
""" """
meta class meta class
""" """
@@ -238,9 +238,10 @@ class ArticleListSerializer(serializers.ModelSerializer):
def get_is_completed(self, obj): def get_is_completed(self, obj):
"""complete all question""" """complete all question"""
junior_article = JuniorArticle.objects.filter(article=obj).last() context_data = self.context.get('user')
junior_article = JuniorArticle.objects.filter(junior__auth=context_data, article=obj).last()
if junior_article: if junior_article:
junior_article.is_completed return junior_article.is_completed
return False return False
class ArticleQuestionSerializer(serializers.ModelSerializer): class ArticleQuestionSerializer(serializers.ModelSerializer):
@@ -278,7 +279,7 @@ class ArticleQuestionSerializer(serializers.ModelSerializer):
return junior_article_obj.submitted_answer.id return junior_article_obj.submitted_answer.id
return None return None
class Meta: class Meta(object):
""" """
meta class meta class
""" """
@@ -299,7 +300,7 @@ class StartAssessmentSerializer(serializers.ModelSerializer):
if data: if data:
return data.current_que_page return data.current_que_page
return NUMBER['zero'] return NUMBER['zero']
class Meta: class Meta(object):
""" """
meta class meta class
""" """
@@ -325,7 +326,7 @@ class ArticleCardlistSerializer(serializers.ModelSerializer):
return data.current_card_page return data.current_card_page
return NUMBER['zero'] return NUMBER['zero']
class Meta: class Meta(object):
""" """
meta class meta class
""" """
+20 -14
View File
@@ -12,14 +12,14 @@ from rest_framework.permissions import IsAuthenticated
# django imports # django imports
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db.models import Q from django.db.models import Q
from django.db.models import Count, OuterRef, Subquery, Sum from django.db.models import Count
from django.db.models.functions import TruncDate from django.db.models.functions import TruncDate
from django.db.models import F, Window from django.db.models import F, Window
from django.db.models.functions.window import Rank from django.db.models.functions.window import Rank
# local imports # local imports
from account.utils import custom_response from account.utils import custom_response
from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, EXPIRED from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, EXPIRED, DATE_FORMAT
from guardian.models import JuniorTask from guardian.models import JuniorTask
from junior.models import JuniorPoints from junior.models import JuniorPoints
from web_admin.pagination import CustomPageNumberPagination from web_admin.pagination import CustomPageNumberPagination
@@ -32,6 +32,10 @@ USER = get_user_model()
class AnalyticsViewSet(GenericViewSet): class AnalyticsViewSet(GenericViewSet):
""" """
analytics api view analytics api view
to get user report (active users, guardians and juniors counts)
to get new user sign up report
to get task report (completed, in-progress, requested and rejected tasks count)
to get junior leaderboard and ranking
""" """
serializer_class = None serializer_class = None
permission_classes = [IsAuthenticated, AdminPermission] permission_classes = [IsAuthenticated, AdminPermission]
@@ -50,7 +54,8 @@ class AnalyticsViewSet(GenericViewSet):
def total_users_count(self, request, *args, **kwargs): def total_users_count(self, request, *args, **kwargs):
""" """
api method to get total users, guardians and juniors api method to get total users, guardians and juniors
:param request: query params {start_date and end_date}, date format (yyyy-mm-dd) :param request: start_date: date format (yyyy-mm-dd)
:param request: end_date: date format (yyyy-mm-dd)
:return: :return:
""" """
@@ -58,8 +63,8 @@ class AnalyticsViewSet(GenericViewSet):
start_date = end_date - datetime.timedelta(days=6) start_date = end_date - datetime.timedelta(days=6)
if request.query_params.get('start_date') and request.query_params.get('end_date'): if request.query_params.get('start_date') and request.query_params.get('end_date'):
start_date = datetime.datetime.strptime(request.query_params.get('start_date'), '%Y-%m-%d') start_date = datetime.datetime.strptime(request.query_params.get('start_date'), DATE_FORMAT)
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), '%Y-%m-%d') end_date = datetime.datetime.strptime(request.query_params.get('end_date'), DATE_FORMAT)
user_qs = self.get_queryset() user_qs = self.get_queryset()
queryset = user_qs.filter(date_joined__range=(start_date, (end_date + datetime.timedelta(days=1)))) queryset = user_qs.filter(date_joined__range=(start_date, (end_date + datetime.timedelta(days=1))))
@@ -74,15 +79,16 @@ class AnalyticsViewSet(GenericViewSet):
def new_signups(self, request, *args, **kwargs): def new_signups(self, request, *args, **kwargs):
""" """
api method to get new signups api method to get new signups
:param request: query params {start_date and end_date}, date format (yyyy-mm-dd) :param request: start_date: date format (yyyy-mm-dd)
:param request: end_date: date format (yyyy-mm-dd)
:return: :return:
""" """
end_date = datetime.date.today() end_date = datetime.date.today()
start_date = end_date - datetime.timedelta(days=6) start_date = end_date - datetime.timedelta(days=6)
if request.query_params.get('start_date') and request.query_params.get('end_date'): if request.query_params.get('start_date') and request.query_params.get('end_date'):
start_date = datetime.datetime.strptime(request.query_params.get('start_date'), '%Y-%m-%d') start_date = datetime.datetime.strptime(request.query_params.get('start_date'), DATE_FORMAT)
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), '%Y-%m-%d') end_date = datetime.datetime.strptime(request.query_params.get('end_date'), DATE_FORMAT)
user_qs = self.get_queryset() user_qs = self.get_queryset()
signup_data = user_qs.filter(date_joined__range=[start_date, (end_date + datetime.timedelta(days=1))] signup_data = user_qs.filter(date_joined__range=[start_date, (end_date + datetime.timedelta(days=1))]
@@ -94,16 +100,17 @@ class AnalyticsViewSet(GenericViewSet):
@action(methods=['get'], url_name='assign-tasks', url_path='assign-tasks', detail=False) @action(methods=['get'], url_name='assign-tasks', url_path='assign-tasks', detail=False)
def assign_tasks_report(self, request, *args, **kwargs): def assign_tasks_report(self, request, *args, **kwargs):
""" """
api method to get assign tasks api method to get assign tasks count for (completed, in-progress, requested and rejected) task
:param request: query params {start_date and end_date}, date format (yyyy-mm-dd) :param request: start_date: date format (yyyy-mm-dd)
:param request: end_date: date format (yyyy-mm-dd)
:return: :return:
""" """
end_date = datetime.date.today() end_date = datetime.date.today()
start_date = end_date - datetime.timedelta(days=6) start_date = end_date - datetime.timedelta(days=6)
if request.query_params.get('start_date') and request.query_params.get('end_date'): if request.query_params.get('start_date') and request.query_params.get('end_date'):
start_date = datetime.datetime.strptime(request.query_params.get('start_date'), '%Y-%m-%d') start_date = datetime.datetime.strptime(request.query_params.get('start_date'), DATE_FORMAT)
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), '%Y-%m-%d') end_date = datetime.datetime.strptime(request.query_params.get('end_date'), DATE_FORMAT)
assign_tasks = JuniorTask.objects.filter( assign_tasks = JuniorTask.objects.filter(
created_at__range=[start_date, (end_date + datetime.timedelta(days=1))] created_at__range=[start_date, (end_date + datetime.timedelta(days=1))]
@@ -122,11 +129,10 @@ class AnalyticsViewSet(GenericViewSet):
serializer_class=LeaderboardSerializer) serializer_class=LeaderboardSerializer)
def junior_leaderboard(self, request): def junior_leaderboard(self, request):
""" """
to get junior leaderboard and rank
:param request: :param request:
:return: :return:
""" """
# queryset = JuniorPoints.objects.all().order_by('-total_points', 'junior__created_at')
queryset = JuniorPoints.objects.prefetch_related('junior', 'junior__auth').annotate(rank=Window( queryset = JuniorPoints.objects.prefetch_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']
+1 -4
View File
@@ -221,10 +221,7 @@ class ArticleListViewSet(GenericViewSet, mixins.ListModelMixin):
:return: list of article :return: list of article
""" """
queryset = self.get_queryset() queryset = self.get_queryset()
count = queryset.count() serializer = self.serializer_class(queryset, context={"user": request.user}, many=True)
paginator = self.pagination_class()
paginated_queryset = paginator.paginate_queryset(queryset, request)
serializer = self.serializer_class(paginated_queryset, many=True)
return custom_response(None, data=serializer.data) return custom_response(None, data=serializer.data)
class ArticleCardListViewSet(viewsets.ModelViewSet): class ArticleCardListViewSet(viewsets.ModelViewSet):