csv/xls report

This commit is contained in:
abutalib-kiwi
2023-08-14 13:57:29 +05:30
parent 25eaee31a4
commit 4bc16c56bd
3 changed files with 258 additions and 9 deletions

View File

@ -2,11 +2,20 @@
web_admin analytics serializer file web_admin analytics serializer file
""" """
from rest_framework import serializers from rest_framework import serializers
from django.contrib.auth import get_user_model
from base.constants import USER_TYPE
from junior.models import JuniorPoints, Junior from junior.models import JuniorPoints, Junior
from web_admin.serializers.user_management_serializer import JuniorSerializer, GuardianSerializer
USER = get_user_model()
class JuniorLeaderboardSerializer(serializers.ModelSerializer): class JuniorLeaderboardSerializer(serializers.ModelSerializer):
"""
junior leaderboard serializer
"""
name = serializers.SerializerMethodField() name = serializers.SerializerMethodField()
first_name = serializers.SerializerMethodField() first_name = serializers.SerializerMethodField()
last_name = serializers.SerializerMethodField() last_name = serializers.SerializerMethodField()
@ -44,9 +53,70 @@ class JuniorLeaderboardSerializer(serializers.ModelSerializer):
class LeaderboardSerializer(serializers.ModelSerializer): class LeaderboardSerializer(serializers.ModelSerializer):
"""
leaderboard serializer
"""
junior = JuniorLeaderboardSerializer() junior = JuniorLeaderboardSerializer()
rank = serializers.IntegerField() rank = serializers.IntegerField()
class Meta: class Meta:
"""
meta class
"""
model = JuniorPoints model = JuniorPoints
fields = ('total_points', 'rank', 'junior') fields = ('total_points', 'rank', 'junior')
class UserCSVReportSerializer(serializers.ModelSerializer):
"""
user csv/xls report serializer
"""
phone_number = serializers.SerializerMethodField()
user_type = serializers.SerializerMethodField()
is_active = serializers.SerializerMethodField()
class Meta:
"""
meta class
"""
model = USER
fields = ('first_name', 'last_name', 'email', 'phone_number', 'user_type', 'is_active', 'date_joined')
@staticmethod
def get_phone_number(obj):
"""
:param obj: user object
:return: user phone number
"""
if profile := obj.guardian_profile.all().first():
return f"+{profile.country_code}{profile.phone}" \
if profile.country_code and profile.phone else profile.phone
elif profile := obj.junior_profile.all().first():
return f"+{profile.country_code}{profile.phone}" \
if profile.country_code and profile.phone else profile.phone
else:
return None
@staticmethod
def get_user_type(obj):
"""
:param obj: user object
:return: user type
"""
if obj.guardian_profile.all().first():
return dict(USER_TYPE).get('2')
elif obj.junior_profile.all().first():
return dict(USER_TYPE).get('1')
else:
return None
@staticmethod
def get_is_active(obj):
"""
:param obj: user object
:return: user type
"""
if profile := obj.guardian_profile.all().first():
return "Active" if profile.is_active else "Inactive"
elif profile := obj.junior_profile.all().first():
return "Active" if profile.is_active else "Inactive"

View File

@ -3,6 +3,10 @@ web_admin analytics view file
""" """
# python imports # python imports
import datetime import datetime
import csv
import io
import pandas as pd
import xlsxwriter
# third party imports # third party imports
from rest_framework.viewsets import GenericViewSet from rest_framework.viewsets import GenericViewSet
@ -16,15 +20,17 @@ 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
from django.http import HttpResponse
# 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, DATE_FORMAT from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, EXPIRED, DATE_FORMAT, TASK_STATUS
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
from web_admin.permission import AdminPermission from web_admin.permission import AdminPermission
from web_admin.serializers.analytics_serializer import LeaderboardSerializer from web_admin.serializers.analytics_serializer import LeaderboardSerializer, UserCSVReportSerializer
from web_admin.serializers.user_management_serializer import UserManagementListSerializer
USER = get_user_model() USER = get_user_model()
@ -38,7 +44,7 @@ class AnalyticsViewSet(GenericViewSet):
to get junior leaderboard and ranking to get junior leaderboard and ranking
""" """
serializer_class = None serializer_class = None
permission_classes = [IsAuthenticated, AdminPermission] # permission_classes = [IsAuthenticated, AdminPermission]
def get_queryset(self): def get_queryset(self):
user_qs = USER.objects.filter( user_qs = USER.objects.filter(
@ -141,3 +147,176 @@ class AnalyticsViewSet(GenericViewSet):
paginated_queryset = paginator.paginate_queryset(queryset, request) paginated_queryset = paginator.paginate_queryset(queryset, request)
serializer = self.serializer_class(paginated_queryset, many=True) serializer = self.serializer_class(paginated_queryset, many=True)
return custom_response(None, serializer.data) return custom_response(None, serializer.data)
# @action(methods=['get'], url_name='generate-report', url_path='generate-report', detail=False)
# def generate_report(self, request):
#
# response = HttpResponse(content_type='text/csv')
# response['Content-Disposition'] = 'attachment; filename="ZOD_Bank_Analytics.csv"'
#
# 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'), DATE_FORMAT)
# end_date = datetime.datetime.strptime(request.query_params.get('end_date'), DATE_FORMAT)
#
# buffer = io.StringIO()
# csv_writer = csv.writer(buffer)
#
# # sheet 1 for Total Users
# user_qs = self.get_queryset()
# queryset = user_qs.filter(date_joined__range=(start_date, (end_date + datetime.timedelta(days=1))))
# serializer = UserCSVReportSerializer(queryset, many=True)
#
# # writer = csv.writer(response)
# csv_writer.writerow(['Users'])
# csv_writer.writerow([
# 'First Name', 'Last Name', 'Email', 'Phone Number', 'User Type', 'status', 'Date Joined',
# # Add more fields as needed
# ])
#
# for user_data in serializer.data:
# row = [
# user_data['first_name'], user_data['last_name'], user_data['email'],
# user_data['phone_number'], user_data['user_type'],
# user_data['is_active'], user_data['date_joined']
# ]
# csv_writer.writerow(row)
#
# response.write(buffer.getvalue())
# buffer.close()
#
# # sheet 2 for Assign Task
# assign_tasks = JuniorTask.objects.filter(
# created_at__range=[start_date, (end_date + datetime.timedelta(days=1))]
# ).exclude(task_status__in=[PENDING, EXPIRED])
# buffer = io.StringIO()
# csv_writer = csv.writer(buffer)
# csv_writer.writerow([])
# csv_writer.writerow(['Assign Tasks'])
# csv_writer.writerow([
# 'Task Name', 'Task Status'
# # Add more fields as needed
# ])
#
# for task in assign_tasks:
# row = [
# task.task_name, dict(TASK_STATUS).get(task.task_status).capitalize(),
# ]
# csv_writer.writerow(row)
# response.write(buffer.getvalue())
# buffer.close()
#
# # sheet 3 for Juniors Leaderboard and rank
# 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')
# buffer = io.StringIO()
# csv_writer = csv.writer(buffer)
# csv_writer.writerow([])
# csv_writer.writerow(['Top 15 Juniors'])
# csv_writer.writerow([
# 'Junior Name', 'Points', 'Rank'
# # Add more fields as needed
# ])
#
# for junior in queryset:
# row = [
# f"{junior.junior.auth.first_name}{junior.junior.auth.last_name}" if junior.junior.auth.last_name else junior.junior.auth.first_name,
# junior.total_points, junior.rank
# ]
# csv_writer.writerow(row)
# response.write(buffer.getvalue())
# buffer.close()
#
# return response
@action(methods=['get'], url_name='generate-report', url_path='generate-report', detail=False)
def generate_report(self, request):
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename="ZOD_Bank_Analytics.xlsx"'
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'), DATE_FORMAT)
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), DATE_FORMAT)
buffer = io.BytesIO() # Use BytesIO for binary data
# Create an XlsxWriter Workbook object
workbook = xlsxwriter.Workbook(buffer)
# Add sheets
sheets = ['Users', 'Assign Tasks', 'Top 15 Juniors']
for sheet_name in sheets:
worksheet = workbook.add_worksheet(name=sheet_name)
# sheet 1 for Total Users
if sheet_name == 'Users':
user_qs = self.get_queryset()
queryset = user_qs.filter(date_joined__range=(start_date, (end_date + datetime.timedelta(days=1))))
serializer = UserCSVReportSerializer(queryset, many=True)
df_users = pd.DataFrame(serializer.data)
for idx, col in enumerate(df_users.columns):
worksheet.write(0, idx, col) # Write header
for row_num, row in enumerate(df_users.values, start=1):
for col_num, value in enumerate(row):
worksheet.write(row_num, col_num, value)
# sheet 2 for Assign Task
elif sheet_name == 'Assign Tasks':
assign_tasks = JuniorTask.objects.filter(
created_at__range=[start_date, (end_date + datetime.timedelta(days=1))]
).exclude(task_status__in=[PENDING, EXPIRED])
df_tasks = pd.DataFrame([
{'Task Name': task.task_name, 'Task Status': dict(TASK_STATUS).get(task.task_status).capitalize()}
for task in assign_tasks
])
for idx, col in enumerate(df_tasks.columns):
worksheet.write(0, idx, col) # Write header
for row_num, row in enumerate(df_tasks.values, start=1):
for col_num, value in enumerate(row):
worksheet.write(row_num, col_num, value)
# sheet 3 for Juniors Leaderboard and rank
elif sheet_name == 'Top 15 Juniors':
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')
df_leaderboard = pd.DataFrame([
{
'Junior Name': f"{junior.junior.auth.first_name} {junior.junior.auth.last_name}"
if junior.junior.auth.last_name else junior.junior.auth.first_name,
'Points': junior.total_points,
'Rank': junior.rank
}
for junior in queryset
])
for idx, col in enumerate(df_leaderboard.columns):
worksheet.write(0, idx, col) # Write header
for row_num, row in enumerate(df_leaderboard.values, start=1):
for col_num, value in enumerate(row):
worksheet.write(row_num, col_num, value)
# Close the workbook to save the content
workbook.close()
# Reset the buffer position and write the content to the response
buffer.seek(0)
response.write(buffer.getvalue())
buffer.close()
return response

View File

@ -72,9 +72,9 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin,
return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST)
queryset = self.queryset queryset = self.queryset
if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'): if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'):
queryset = queryset.filter(guardian_profile__user__id=kwargs['pk']) queryset = queryset.filter(id=kwargs['pk'])
elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'): elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'):
queryset = queryset.filter(junior_profile__auth__id=kwargs['pk']) queryset = queryset.filter(id=kwargs['pk'])
serializer = UserManagementDetailSerializer(queryset, many=True) serializer = UserManagementDetailSerializer(queryset, many=True)
return custom_response(None, data=serializer.data) return custom_response(None, data=serializer.data)
@ -89,12 +89,12 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin,
return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST)
queryset = self.queryset queryset = self.queryset
if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'): if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'):
user_obj = queryset.filter(guardian_profile__user__id=kwargs['pk']).first() user_obj = queryset.filter(id=kwargs['pk']).first()
serializer = GuardianSerializer(user_obj.guardian_profile.all().first(), serializer = GuardianSerializer(user_obj.guardian_profile.all().first(),
request.data, context={'user_id': kwargs['pk']}) request.data, context={'user_id': kwargs['pk']})
elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'): elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'):
user_obj = queryset.filter(junior_profile__auth__id=kwargs['pk']).first() user_obj = queryset.filter(id=kwargs['pk']).first()
serializer = JuniorSerializer(user_obj.junior_profile.all().first(), serializer = JuniorSerializer(user_obj.junior_profile.all().first(),
request.data, context={'user_id': kwargs['pk']}) request.data, context={'user_id': kwargs['pk']})
@ -114,12 +114,12 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin,
return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST)
queryset = self.queryset queryset = self.queryset
if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'): if self.request.query_params.get('user_type') == dict(USER_TYPE).get('2'):
user_obj = queryset.filter(guardian_profile__user__id=kwargs['pk']).first() user_obj = queryset.filter(id=kwargs['pk']).first()
obj = user_obj.guardian_profile.all().first() obj = user_obj.guardian_profile.all().first()
obj.is_active = False if obj.is_active else True obj.is_active = False if obj.is_active else True
obj.save() obj.save()
elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'): elif self.request.query_params.get('user_type') == dict(USER_TYPE).get('1'):
user_obj = queryset.filter(junior_profile__auth__id=kwargs['pk']).first() user_obj = queryset.filter(id=kwargs['pk']).first()
obj = user_obj.junior_profile.all().first() obj = user_obj.junior_profile.all().first()
obj.is_active = False if obj.is_active else True obj.is_active = False if obj.is_active else True
obj.save() obj.save()