mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-07-15 18:07:02 +00:00
analytics section api, users counts, new signup count, task report
This commit is contained in:
@ -154,10 +154,9 @@ class AdminLoginSerializer(serializers.ModelSerializer):
|
||||
user = User.objects.filter(email__iexact=attrs['email'], is_superuser=True
|
||||
).only('id', 'first_name', 'last_name', 'email', 'is_superuser').first()
|
||||
|
||||
if not user:
|
||||
raise serializers.ValidationError({'details': ERROR_CODE['2002']})
|
||||
elif not user.check_password(attrs['password']):
|
||||
if not user or not user.check_password(attrs['password']):
|
||||
raise serializers.ValidationError({'details': ERROR_CODE['2002']})
|
||||
|
||||
self.context.update({'user': user})
|
||||
return attrs
|
||||
|
||||
|
@ -334,10 +334,9 @@ class UserLogin(viewsets.ViewSet):
|
||||
user = User.objects.filter(email__iexact=email, is_superuser=True
|
||||
).only('id', 'first_name', 'last_name', 'email', 'is_superuser').first()
|
||||
|
||||
if not user:
|
||||
return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_400_BAD_REQUEST)
|
||||
elif 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)
|
||||
|
||||
serializer = SuperUserSerializer(user)
|
||||
return custom_response(SUCCESS_CODE['3003'], serializer.data, response_status=status.HTTP_200_OK)
|
||||
|
||||
|
3
web_admin/serializers/analytics_serializer.py
Normal file
3
web_admin/serializers/analytics_serializer.py
Normal file
@ -0,0 +1,3 @@
|
||||
"""
|
||||
web_admin analytics serializer file
|
||||
"""
|
@ -87,9 +87,9 @@ class AdminVerifyOTPSerializer(serializers.Serializer):
|
||||
# fetch email otp object of the user
|
||||
user_otp_details = UserEmailOtp.objects.filter(email=email, otp=otp).last()
|
||||
if not user_otp_details:
|
||||
raise serializers.ValidationError({'details': ERROR_CODE['2064']})
|
||||
raise serializers.ValidationError({'details': ERROR_CODE['2008']})
|
||||
if user_otp_details.user_type != dict(USER_TYPE).get('3'):
|
||||
raise serializers.ValidationError({'details': ERROR_CODE['2063']})
|
||||
raise serializers.ValidationError({'details': ERROR_CODE['2008']})
|
||||
if user_otp_details.expired_at.replace(tzinfo=None) < datetime.utcnow():
|
||||
raise serializers.ValidationError({'details': ERROR_CODE['2029']})
|
||||
user_otp_details.is_verified = True
|
||||
|
@ -6,6 +6,7 @@ from django.urls import path, include
|
||||
from rest_framework import routers
|
||||
|
||||
# local imports
|
||||
from web_admin.views.analytics import AnalyticsViewSet
|
||||
from web_admin.views.article import ArticleViewSet, DefaultArticleCardImagesViewSet, ArticleListViewSet
|
||||
from web_admin.views.auth import ForgotAndResetPasswordViewSet
|
||||
from web_admin.views.user_management import UserManagementViewSet
|
||||
@ -17,6 +18,9 @@ router.register('article', ArticleViewSet, basename='article')
|
||||
router.register('default-card-images', DefaultArticleCardImagesViewSet, basename='default-card-images')
|
||||
router.register('user-management', UserManagementViewSet, basename='user')
|
||||
router.register('article-list', ArticleListViewSet, basename='article-list')
|
||||
router.register('analytics', AnalyticsViewSet, basename='user-analytics')
|
||||
# router.register('task-analytics', TaskAnalyticsViewSet, basename='task-analytics')
|
||||
|
||||
# forgot and reset password api for admin
|
||||
router.register('admin', ForgotAndResetPasswordViewSet, basename='admin')
|
||||
|
||||
|
98
web_admin/views/analytics.py
Normal file
98
web_admin/views/analytics.py
Normal file
@ -0,0 +1,98 @@
|
||||
"""
|
||||
web_admin analytics view file
|
||||
"""
|
||||
import datetime
|
||||
|
||||
from rest_framework.viewsets import GenericViewSet
|
||||
from rest_framework.decorators import action
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db.models import Q
|
||||
from django.db.models import Count
|
||||
from django.db.models.functions import TruncDate
|
||||
|
||||
from account.utils import custom_response
|
||||
from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, EXPIRED
|
||||
from guardian.models import JuniorTask
|
||||
|
||||
USER = get_user_model()
|
||||
|
||||
|
||||
class AnalyticsViewSet(GenericViewSet):
|
||||
"""
|
||||
analytics api view
|
||||
"""
|
||||
serializer_class = None
|
||||
|
||||
def get_queryset(self):
|
||||
user_qs = USER.objects.filter(
|
||||
(Q(junior_profile__is_verified=True) | Q(guardian_profile__is_verified=True)),
|
||||
is_superuser=False
|
||||
).prefetch_related('guardian_profile',
|
||||
'junior_profile'
|
||||
).exclude(junior_profile__isnull=True,
|
||||
guardian_profile__isnull=True).order_by('date_joined')
|
||||
return user_qs
|
||||
|
||||
@action(methods=['get'], url_name='users-count', url_path='users-count', detail=False)
|
||||
def total_users_count(self, request, *args, **kwargs):
|
||||
"""
|
||||
api method to get total users, guardians and juniors
|
||||
:param request: query params {start_date and end_date}, date format (yyyy-mm-dd)
|
||||
:return:
|
||||
"""
|
||||
|
||||
end_date = datetime.date.today()
|
||||
start_date = end_date - datetime.timedelta(days=6)
|
||||
|
||||
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')
|
||||
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), '%Y-%m-%d')
|
||||
|
||||
user_qs = self.get_queryset()
|
||||
queryset = user_qs.filter(date_joined__range=(start_date, (end_date + datetime.timedelta(days=1))))
|
||||
|
||||
data = {'total_users': queryset.count(),
|
||||
'total_guardians': queryset.filter(junior_profile__isnull=True).count(),
|
||||
'total_juniors': queryset.filter(guardian_profile__isnull=True).count()}
|
||||
|
||||
return custom_response(None, data)
|
||||
|
||||
@action(methods=['get'], url_name='new-signups', url_path='new-signups', detail=False)
|
||||
def new_signups(self, request, *args, **kwargs):
|
||||
|
||||
end_date = datetime.date.today()
|
||||
start_date = end_date - datetime.timedelta(days=6)
|
||||
|
||||
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')
|
||||
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), '%Y-%m-%d')
|
||||
|
||||
user_qs = self.get_queryset()
|
||||
signup_data = user_qs.filter(date_joined__range=[start_date, (end_date + datetime.timedelta(days=1))]
|
||||
).annotate(date=TruncDate('date_joined')
|
||||
).values('date').annotate(signups=Count('id')).order_by('date')
|
||||
|
||||
return custom_response(None, signup_data)
|
||||
|
||||
@action(methods=['get'], url_name='assign-tasks', url_path='assign-tasks', detail=False)
|
||||
def assign_tasks_report(self, request, *args, **kwargs):
|
||||
|
||||
end_date = datetime.date.today()
|
||||
start_date = end_date - datetime.timedelta(days=6)
|
||||
|
||||
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')
|
||||
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), '%Y-%m-%d')
|
||||
|
||||
assign_tasks = JuniorTask.objects.filter(
|
||||
created_at__range=[start_date, (end_date + datetime.timedelta(days=1))]
|
||||
).exclude(task_status__in=[PENDING, EXPIRED])
|
||||
|
||||
data = {
|
||||
'task_completed': assign_tasks.filter(task_status=COMPLETED).count(),
|
||||
'task_in_progress': assign_tasks.filter(task_status=IN_PROGRESS).count(),
|
||||
'task_requested': assign_tasks.filter(task_status=REQUESTED).count(),
|
||||
'task_rejected': assign_tasks.filter(task_status=REJECTED).count(),
|
||||
}
|
||||
|
||||
return custom_response(None, data)
|
@ -29,11 +29,12 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin,
|
||||
"""
|
||||
serializer_class = UserManagementListSerializer
|
||||
permission_classes = [IsAuthenticated, AdminPermission]
|
||||
queryset = USER.objects.filter(is_superuser=False
|
||||
).prefetch_related('guardian_profile',
|
||||
'junior_profile'
|
||||
).exclude(junior_profile__isnull=True,
|
||||
guardian_profile__isnull=True).order_by('date_joined')
|
||||
queryset = USER.objects.filter(
|
||||
(Q(junior_profile__is_verified=True) | Q(guardian_profile__is_verified=True)),
|
||||
is_superuser=False).prefetch_related('guardian_profile',
|
||||
'junior_profile'
|
||||
).exclude(junior_profile__isnull=True,
|
||||
guardian_profile__isnull=True).order_by('date_joined')
|
||||
filter_backends = (SearchFilter,)
|
||||
search_fields = ['first_name', 'last_name']
|
||||
http_method_names = ['get', 'post', 'patch']
|
||||
@ -55,8 +56,6 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin,
|
||||
:return:
|
||||
"""
|
||||
queryset = self.get_queryset()
|
||||
queryset = queryset.filter(
|
||||
(Q(junior_profile__is_verified=True) | Q(guardian_profile__is_verified=True)))
|
||||
paginator = self.pagination_class()
|
||||
paginated_queryset = paginator.paginate_queryset(queryset, request)
|
||||
serializer = self.serializer_class(paginated_queryset, many=True)
|
||||
|
Reference in New Issue
Block a user