Compare commits

..
Author SHA1 Message Date
abutalib-kiwi 2216411fd2 Merge branch 'dev' into ZBKADM-72-minor-changes 2023-08-21 14:33:36 +05:30
abutalib-kiwi 606c1fa6e6 minor changes in excel import api method 2023-08-21 14:28:06 +05:30
Ankitajain-kiwi 092cbfad3e Merge branch 'qa' into dev 2023-08-21 12:57:57 +05:30
dilipshrivastwa-kiwi 249a469d89 Merge pull request #230 from KiwiTechLLC/sprint5
resolve bugs
2023-08-21 12:54:46 +05:30
jain d202774df1 resolve bugs 2023-08-21 12:39:05 +05:30
jain 1adf0c2f70 resolve bugs 2023-08-21 12:24:01 +05:30
Ankitajain-kiwi b193166914 Merge pull request #229 from KiwiTechLLC/sprint5
login issue
2023-08-20 14:14:45 +05:30
jain 48b455e38a login issue 2023-08-20 14:12:17 +05:30
dilipshrivastwa-kiwi 6d54a718b9 Merge pull request #226 from KiwiTechLLC/ZBKBCK-346
[ZBKBCK-346] change password and forgot password api has been optimised
2023-08-18 20:26:02 +05:30
abutalib-kiwi e84180a6c2 Merge branch 'dev' into ZBKADM-72-minor-changes 2023-08-18 18:46:47 +05:30
jain 92e5104e3f expiry date of otp 2023-08-18 18:37:01 +05:30
Ankitajain-kiwi ed1b5dd453 Merge pull request #215 from KiwiTechLLC/dev
Dev
2023-08-16 16:34:54 +05:30
Ankitajain-kiwi 74328f37b2 Merge pull request #212 from KiwiTechLLC/dev
Dev
2023-08-16 11:38:39 +05:30
Ankitajain-kiwi d8f4467d98 Merge pull request #209 from KiwiTechLLC/dev
guardian code status
2023-08-14 18:23:41 +05:30
Ankitajain-kiwi a9cc05c675 Merge pull request #207 from KiwiTechLLC/dev
Dev
2023-08-14 17:33:56 +05:30
Ankitajain-kiwi 83d7d119be Merge pull request #203 from KiwiTechLLC/dev
Dev
2023-08-14 11:46:04 +05:30
Ankitajain-kiwi 19a6475097 Merge pull request #200 from KiwiTechLLC/dev
Dev
2023-08-11 16:55:51 +05:30
Ankitajain-kiwi 4ca60af5da Merge pull request #195 from KiwiTechLLC/dev
Dev
2023-08-11 13:50:53 +05:30
Ankitajain-kiwi 807526acfa Merge pull request #191 from KiwiTechLLC/dev
Dev
2023-08-11 12:24:28 +05:30
Ankitajain-kiwi f4149379c2 Merge pull request #188 from KiwiTechLLC/dev
Dev
2023-08-10 19:21:12 +05:30
Abu Talib b8f1acaed8 Merge pull request #185 from KiwiTechLLC/dev
Dev
2023-08-10 18:37:06 +05:30
Ankitajain-kiwi 9e5dd5e3d5 Merge pull request #183 from KiwiTechLLC/dev
Dev
2023-08-10 17:04:06 +05:30
Ankitajain-kiwi b961044e4d Merge pull request #179 from KiwiTechLLC/dev
Dev
2023-08-10 11:57:29 +05:30
Ankitajain-kiwi 2498394127 Merge pull request #177 from KiwiTechLLC/dev
Dev
2023-08-09 19:22:42 +05:30
Ankitajain-kiwi 2fc65d462d Merge pull request #174 from KiwiTechLLC/dev
Dev
2023-08-09 18:11:40 +05:30
Abu Talib cdf656fdad Merge pull request #170 from KiwiTechLLC/dev
Dev
2023-08-09 14:51:13 +05:30
Ankitajain-kiwi 8eaf8751c2 Merge pull request #165 from KiwiTechLLC/dev
Dev
2023-08-08 17:14:36 +05:30
Ankitajain-kiwi 6867920754 Merge pull request #163 from KiwiTechLLC/dev
Dev
2023-08-08 16:07:14 +05:30
Ankitajain-kiwi 22ba4288d9 Merge pull request #161 from KiwiTechLLC/dev
Dev
2023-08-08 15:04:50 +05:30
Abu Talib 7ab16cb3de Merge pull request #158 from KiwiTechLLC/dev
Dev
2023-08-08 14:24:44 +05:30
Abu Talib 07d150309b Merge pull request #146 from KiwiTechLLC/dev
Dev
2023-08-04 15:04:55 +05:30
Abu Talib 3801e6e027 Merge pull request #142 from KiwiTechLLC/dev
Dev
2023-08-03 14:59:49 +05:30
Ankitajain-kiwi e89fc513cb Merge pull request #138 from KiwiTechLLC/dev
Dev
2023-08-02 14:25:06 +05:30
Ankitajain-kiwi e1af1c200d Merge pull request #136 from KiwiTechLLC/dev
Dev
2023-08-02 11:33:29 +05:30
Abu Talib b238379a22 Merge pull request #130 from KiwiTechLLC/dev
Dev
2023-07-28 19:49:56 +05:30
Abu Talib c081bc621d Merge pull request #124 from KiwiTechLLC/dev
merging dev into qa
2023-07-27 22:04:51 +05:30
Abu Talib d2c8b18e3f Merge pull request #120 from KiwiTechLLC/dev
merging dev itno qa
2023-07-27 11:37:25 +05:30
Ankitajain-kiwi bdc0ba4fd5 Merge pull request #117 from KiwiTechLLC/dev
Dev
2023-07-26 16:58:38 +05:30
Ankitajain-kiwi 3af2584d6a Merge pull request #115 from KiwiTechLLC/dev
Dev
2023-07-26 11:09:40 +05:30
Abu Talib 62cf2b14bf Merge pull request #113 from KiwiTechLLC/dev
merging dev into qa
2023-07-26 11:01:45 +05:30
Ankitajain-kiwi cbd3d139a5 Merge pull request #110 from KiwiTechLLC/dev
Dev
2023-07-25 17:36:49 +05:30
Ankitajain-kiwi 7cb792c6cf Merge pull request #104 from KiwiTechLLC/dev
Dev
2023-07-25 11:52:36 +05:30
Ankitajain-kiwi 5ea28bbd75 Merge pull request #102 from KiwiTechLLC/dev
Dev
2023-07-24 15:56:54 +05:30
Ankitajain-kiwi 180104ece8 Merge pull request #100 from KiwiTechLLC/dev
Dev
2023-07-24 11:04:08 +05:30
7 changed files with 88 additions and 68 deletions
+11 -9
View File
@@ -234,6 +234,7 @@ class ForgotPasswordAPIView(views.APIView):
serializer_class = ForgotPasswordSerializer
def post(self, request):
"""
Post method to validate serializer
"""
@@ -262,7 +263,6 @@ class ForgotPasswordAPIView(views.APIView):
response_status=status.HTTP_200_OK
)
class SendPhoneOtp(viewsets.ModelViewSet):
"""Send otp on phone"""
serializer_class = UserPhoneOtpSerializer
@@ -310,22 +310,24 @@ class UserLogin(viewsets.ViewSet):
if user is not None:
login(request, user)
if str(user_type) == USER_TYPE_FLAG["TWO"]:
guardian_data = Guardian.objects.filter(user__username=username, is_verified=True).last()
guardian_data = Guardian.objects.filter(user__username=username).last()
if guardian_data:
serializer = GuardianSerializer(
guardian_data, context={'user_type': user_type}
).data
if guardian_data.is_verified:
serializer = GuardianSerializer(
guardian_data, context={'user_type': user_type}
).data
else:
return custom_error_response(
ERROR_CODE["2070"],
response_status=status.HTTP_401_UNAUTHORIZED
)
elif str(user_type) == USER_TYPE_FLAG["FIRST"]:
junior_data = Junior.objects.filter(auth__username=username, is_verified=True).last()
junior_data = Junior.objects.filter(auth__username=username).last()
if junior_data:
serializer = JuniorSerializer(
junior_data, context={'user_type': user_type}
).data
if junior_data.is_verified:
serializer = JuniorSerializer(
junior_data, context={'user_type': user_type}
).data
else:
return custom_error_response(
ERROR_CODE["2071"],
+1 -1
View File
@@ -27,7 +27,7 @@ NUMBER = {
'ninety_nine': 99, 'hundred': 100, 'thirty_six_hundred': 3600
}
none = "none"
# Super Admin string constant for 'role'
SUPER_ADMIN = "Super Admin"
+5 -1
View File
@@ -101,7 +101,11 @@ ERROR_CODE = {
"2072": "You can not approve or reject this task because junior does not exist in the system",
"2073": "You can not approve or reject this junior because junior does not exist in the system",
"2074": "You can not complete this task because you does not exist in the system",
"2075": "Your account is deactivated. Please contact with admin"
"2075": "Your account is deactivated. Please contact with admin",
"2076": "This junior already associate with you",
"2077": "You can not add guardian",
"2078": "This junior is not associate with you",
}
"""Success message code"""
SUCCESS_CODE = {
+6 -2
View File
@@ -166,6 +166,10 @@ class CreateTaskAPIView(viewsets.ModelViewSet):
try:
image = request.data['default_image']
junior = request.data['junior']
junior_id = Junior.objects.filter(id=junior).last()
guardian_data = Guardian.objects.filter(user=request.user).last()
if guardian_data.guardian_code in junior_id.guardian_code:
return custom_error_response(ERROR_CODE['2078'], response_status=status.HTTP_400_BAD_REQUEST)
allowed_extensions = ['.jpg', '.jpeg', '.png']
if not any(extension in str(image) for extension in allowed_extensions):
return custom_error_response(ERROR_CODE['2048'], response_status=status.HTTP_400_BAD_REQUEST)
@@ -187,7 +191,7 @@ class CreateTaskAPIView(viewsets.ModelViewSet):
if serializer.is_valid():
# save serializer
task = serializer.save()
junior_id = Junior.objects.filter(id=junior).last()
send_notification_to_junior.delay(TASK_ASSIGNED, request.auth.payload['user_id'],
junior_id.auth.id, {'task_id': task.id})
return custom_response(SUCCESS_CODE['3018'], serializer.data, response_status=status.HTTP_200_OK)
@@ -242,7 +246,7 @@ class TopJuniorListAPIView(viewsets.ModelViewSet):
# Update the position field for each JuniorPoints object
for index, junior in enumerate(junior_total_points):
junior.position = index + 1
send_notification_to_junior.delay(LEADERBOARD_RANKING, None, junior.junior.auth.id, {})
# send_notification_to_junior.delay(LEADERBOARD_RANKING, None, junior.junior.auth.id, {})
junior.save()
serializer = self.get_serializer(junior_total_points[:NUMBER['fifteen']], many=True)
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
+15 -4
View File
@@ -40,7 +40,7 @@ from .serializers import (CreateJuniorSerializer, JuniorDetailListSerializer, Ad
from guardian.models import Guardian, JuniorTask
from guardian.serializers import TaskDetailsSerializer, TaskDetailsjuniorSerializer
from base.messages import ERROR_CODE, SUCCESS_CODE
from base.constants import NUMBER, ARTICLE_STATUS
from base.constants import NUMBER, ARTICLE_STATUS, none
from account.utils import custom_response, custom_error_response
from guardian.utils import upload_image_to_alibaba
from .utils import update_positions_based_on_points
@@ -171,7 +171,11 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
image_url = upload_image_to_alibaba(profile_image, filename)
info_data.update({"image": image_url})
if user := User.objects.filter(username=request.data['email']).first():
self.associate_guardian(user)
data = self.associate_guardian(user)
if data == none:
return custom_error_response(ERROR_CODE['2077'], response_status=status.HTTP_400_BAD_REQUEST)
elif not data:
return custom_error_response(ERROR_CODE['2076'], response_status=status.HTTP_400_BAD_REQUEST)
return custom_response(SUCCESS_CODE['3021'], response_status=status.HTTP_200_OK)
# use AddJuniorSerializer serializer
serializer = AddJuniorSerializer(data=request.data, context=info_data)
@@ -184,9 +188,16 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
def associate_guardian(self, user):
junior = Junior.objects.filter(auth=user).first()
junior = Junior.objects.filter(auth__email=self.request.data['email']).first()
guardian = Guardian.objects.filter(user=self.request.user).first()
junior.guardian_code = [guardian.guardian_code]
if not junior:
return none
if guardian.guardian_code in junior.guardian_code:
return False
if type(junior.guardian_code) is list:
junior.guardian_code.append(guardian.guardian_code)
else:
junior.guardian_code = [guardian.guardian_code]
junior.guardian_code_status = str(NUMBER['two'])
junior.save()
JuniorGuardianRelationship.objects.get_or_create(guardian=guardian, junior=junior,
+20 -1
View File
@@ -2,8 +2,9 @@
web_utils file
"""
import base64
import datetime
from base.constants import ARTICLE_CARD_IMAGE_FOLDER
from base.constants import ARTICLE_CARD_IMAGE_FOLDER, DATE_FORMAT
from guardian.utils import upload_image_to_alibaba, upload_base64_image_to_alibaba
@@ -40,3 +41,21 @@ def get_image_url(data):
# upload image on ali baba
image_url = upload_image_to_alibaba(image, filename)
return image_url
def get_dates(start_date, end_date):
"""
to get start and end date
:param start_date: format (yyyy-mm-dd)
:param end_date: format (yyyy-mm-dd)
:return: start and end date
"""
if start_date and end_date:
start_date = datetime.datetime.strptime(start_date, DATE_FORMAT).date()
end_date = datetime.datetime.strptime(end_date, DATE_FORMAT).date()
else:
end_date = datetime.date.today()
start_date = end_date - datetime.timedelta(days=6)
return start_date, end_date
+30 -50
View File
@@ -6,9 +6,6 @@ import datetime
import io
import pandas as pd
import xlsxwriter
import tempfile
import oss2
from django.conf import settings
# third party imports
from rest_framework.viewsets import GenericViewSet
@@ -33,7 +30,7 @@ from junior.models import JuniorPoints
from web_admin.pagination import CustomPageNumberPagination
from web_admin.permission import AdminPermission
from web_admin.serializers.analytics_serializer import LeaderboardSerializer, UserCSVReportSerializer
from web_admin.serializers.user_management_serializer import UserManagementListSerializer
from web_admin.utils import get_dates
USER = get_user_model()
@@ -56,7 +53,7 @@ class AnalyticsViewSet(GenericViewSet):
).prefetch_related('guardian_profile',
'junior_profile'
).exclude(junior_profile__isnull=True,
guardian_profile__isnull=True).order_by('date_joined')
guardian_profile__isnull=True).order_by('-date_joined')
return user_qs
@action(methods=['get'], url_name='users-count', url_path='users-count', detail=False)
@@ -67,13 +64,8 @@ class AnalyticsViewSet(GenericViewSet):
:param request: 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'), DATE_FORMAT)
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), DATE_FORMAT)
start_date, end_date = get_dates(request.query_params.get('start_date'),
request.query_params.get('end_date'))
user_qs = self.get_queryset()
queryset = user_qs.filter(date_joined__range=(start_date, (end_date + datetime.timedelta(days=1))))
@@ -92,12 +84,8 @@ class AnalyticsViewSet(GenericViewSet):
:param request: 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'), DATE_FORMAT)
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), DATE_FORMAT)
start_date, end_date = get_dates(request.query_params.get('start_date'),
request.query_params.get('end_date'))
user_qs = self.get_queryset()
signup_data = user_qs.filter(date_joined__range=[start_date, (end_date + datetime.timedelta(days=1))]
@@ -114,12 +102,8 @@ class AnalyticsViewSet(GenericViewSet):
:param request: 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'), DATE_FORMAT)
end_date = datetime.datetime.strptime(request.query_params.get('end_date'), DATE_FORMAT)
start_date, end_date = get_dates(request.query_params.get('start_date'),
request.query_params.get('end_date'))
assign_tasks = JuniorTask.objects.filter(
created_at__range=[start_date, (end_date + datetime.timedelta(days=1))]
@@ -163,12 +147,8 @@ class AnalyticsViewSet(GenericViewSet):
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)
start_date, end_date = get_dates(request.query_params.get('start_date'),
request.query_params.get('end_date'))
# Use BytesIO for binary data
buffer = io.BytesIO()
@@ -177,7 +157,7 @@ class AnalyticsViewSet(GenericViewSet):
workbook = xlsxwriter.Workbook(buffer)
# Add sheets
sheets = ['Users', 'Assign Tasks', 'Juniors leaderboard']
sheets = ['Users', 'Assign Tasks', 'Juniors Leaderboard']
for sheet_name in sheets:
worksheet = workbook.add_worksheet(name=sheet_name)
@@ -195,12 +175,7 @@ class AnalyticsViewSet(GenericViewSet):
'Date Joined': user['date_joined']}
for user in serializer.data
])
for idx, col in enumerate(df_users.columns):
# Write header
worksheet.write(0, idx, col)
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)
write_excel_worksheet(worksheet, df_users)
# sheet 2 for Assign Task
elif sheet_name == 'Assign Tasks':
@@ -213,15 +188,10 @@ class AnalyticsViewSet(GenericViewSet):
for task in assign_tasks
])
for idx, col in enumerate(df_tasks.columns):
# Write header
worksheet.write(0, idx, col)
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)
write_excel_worksheet(worksheet, df_tasks)
# sheet 3 for Juniors Leaderboard and rank
elif sheet_name == 'Juniors leaderboard':
elif sheet_name == 'Juniors Leaderboard':
queryset = JuniorPoints.objects.prefetch_related('junior', 'junior__auth').annotate(rank=Window(
expression=Rank(),
order_by=[F('total_points').desc(), 'junior__created_at']
@@ -236,12 +206,7 @@ class AnalyticsViewSet(GenericViewSet):
for junior in queryset
])
for idx, col in enumerate(df_leaderboard.columns):
# Write header
worksheet.write(0, idx, col)
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)
write_excel_worksheet(worksheet, df_leaderboard)
# Close the workbook to save the content
workbook.close()
@@ -255,3 +220,18 @@ class AnalyticsViewSet(GenericViewSet):
file_link = upload_excel_file_to_alibaba(response, filename)
return custom_response(None, file_link)
def write_excel_worksheet(worksheet, dataframe):
"""
to perform write action on worksheets
:param worksheet:
:param dataframe:
:return: worksheet
"""
for idx, col in enumerate(dataframe.columns):
# Write header
worksheet.write(0, idx, col)
for row_num, row in enumerate(dataframe.values, start=1):
for col_num, value in enumerate(row):
worksheet.write(row_num, col_num, value)
return worksheet