diff --git a/account/views.py b/account/views.py index 0c86aea..ba99f95 100644 --- a/account/views.py +++ b/account/views.py @@ -533,7 +533,13 @@ class DefaultImageAPIViewSet(viewsets.ModelViewSet): class DeleteUserProfileAPIViewSet(viewsets.GenericViewSet): - """ Delete user API view set """ + """ Delete user API view set + {"user_type":1, + "signup_method":"1", + "password":"Demo@123"} + signup_method 1 for manual + 2 for google login + 3 for apple login""" @action(detail=False, methods=['POST'], url_path='user-account',serializer_class=UserDeleteSerializer, permission_classes=[IsAuthenticated]) diff --git a/guardian/views.py b/guardian/views.py index 538ed4c..0ec7217 100644 --- a/guardian/views.py +++ b/guardian/views.py @@ -32,7 +32,7 @@ from .serializers import (UserSerializer, CreateGuardianSerializer, TaskSerializ GuardianDetailListSerializer) from .models import Guardian, JuniorTask from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship -from account.models import UserEmailOtp, UserNotification +from account.models import UserEmailOtp, UserNotification, UserDeviceDetails from .tasks import generate_otp from account.utils import custom_response, custom_error_response, OTP_EXPIRY, send_otp_email from base.messages import ERROR_CODE, SUCCESS_CODE @@ -59,10 +59,11 @@ class SignupViewset(viewsets.ModelViewSet): serializer_class = UserSerializer def create(self, request, *args, **kwargs): """Create user profile""" + device_id = request.META.get('HTTP_DEVICE_ID') if request.data['user_type'] in [str(NUMBER['one']), str(NUMBER['two'])]: serializer = UserSerializer(context=request.data['user_type'], data=request.data) if serializer.is_valid(): - serializer.save() + user = serializer.save() """Generate otp""" otp = generate_otp() # expire otp after 1 day @@ -72,18 +73,19 @@ class SignupViewset(viewsets.ModelViewSet): user_type=str(request.data['user_type']), expired_at=expiry) """Send email to the register user""" send_otp_email(request.data['email'], otp) + UserDeviceDetails.objects.create(user=user, device_id=device_id) return custom_response(SUCCESS_CODE['3001'], response_status=status.HTTP_200_OK) return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST) else: return custom_error_response(ERROR_CODE['2028'], response_status=status.HTTP_400_BAD_REQUEST) -class UpdateGuardianProfile(viewsets.ViewSet): - """ - Update guardian profile - """ + +class UpdateGuardianProfile(viewsets.ModelViewSet): + """Update guardian profile""" serializer_class = CreateGuardianSerializer permission_classes = [IsAuthenticated] + http_method_names = ('post',) def create(self, request, *args, **kwargs): """Create guardian profile""" @@ -163,6 +165,9 @@ class CreateTaskAPIView(viewsets.ModelViewSet): http_method_names = ('post', ) def create(self, request, *args, **kwargs): + """ + image should be in form data + """ try: image = request.data['default_image'] junior = request.data['junior'] @@ -254,14 +259,17 @@ class TopJuniorListAPIView(viewsets.ModelViewSet): return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) -class ApproveJuniorAPIView(viewsets.ViewSet): +class ApproveJuniorAPIView(viewsets.ModelViewSet): """approve junior by guardian""" serializer_class = ApproveJuniorSerializer permission_classes = [IsAuthenticated] - + http_method_names = ('post',) def create(self, request, *args, **kwargs): - """ junior list""" + """ Use below param + {"junior_id":"75", + "action":"1"} + """ try: guardian = Guardian.objects.filter(user__email=self.request.user).last() # fetch junior query @@ -287,13 +295,19 @@ class ApproveJuniorAPIView(viewsets.ViewSet): return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) -class ApproveTaskAPIView(viewsets.ViewSet): +class ApproveTaskAPIView(viewsets.ModelViewSet): """approve junior by guardian""" serializer_class = ApproveTaskSerializer permission_classes = [IsAuthenticated] - + http_method_names = ('post',) def create(self, request, *args, **kwargs): - """ junior list""" + """ Params + {"junior_id":"82", + "task_id":"43", + "action":"1"} + action 1 for approve + 2 for reject + """ # action 1 is use for approve and 2 for reject try: guardian = Guardian.objects.filter(user__email=self.request.user).last() diff --git a/junior/serializers.py b/junior/serializers.py index b4aa54f..f79cd46 100644 --- a/junior/serializers.py +++ b/junior/serializers.py @@ -24,7 +24,7 @@ from guardian.utils import real_time, update_referral_points, convert_timedelta_ from notifications.utils import send_notification, send_notification_to_junior, send_notification_to_guardian from notifications.constants import (INVITED_GUARDIAN, APPROVED_JUNIOR, SKIPPED_PROFILE_SETUP, TASK_ACTION, TASK_SUBMITTED) - +from web_admin.models import ArticleCard class ListCharField(serializers.ListField): """Serializer for Array field""" @@ -518,3 +518,11 @@ class FAQSerializer(serializers.ModelSerializer): model = FAQ fields = ('id', 'question', 'description') +class CreateArticleCardSerializer(serializers.ModelSerializer): + # Article card Serializer + + class Meta(object): + # meta info + model = ArticleCard + fields = ('id', 'article') + diff --git a/junior/views.py b/junior/views.py index 8df8a09..5eb15bd 100644 --- a/junior/views.py +++ b/junior/views.py @@ -36,7 +36,7 @@ from junior.models import (Junior, JuniorPoints, JuniorGuardianRelationship, Jun from .serializers import (CreateJuniorSerializer, JuniorDetailListSerializer, AddJuniorSerializer, RemoveJuniorSerializer, CompleteTaskSerializer, JuniorPointsSerializer, AddGuardianSerializer, StartTaskSerializer, ReAssignTaskSerializer, - RemoveGuardianCodeSerializer, FAQSerializer) + RemoveGuardianCodeSerializer, FAQSerializer, CreateArticleCardSerializer) from guardian.models import Guardian, JuniorTask from guardian.serializers import TaskDetailsSerializer, TaskDetailsjuniorSerializer from base.messages import ERROR_CODE, SUCCESS_CODE @@ -65,10 +65,11 @@ from web_admin.serializers.article_serializer import (ArticleSerializer, Article # Start task # by junior API # Create your views here. -class UpdateJuniorProfile(viewsets.ViewSet): +class UpdateJuniorProfile(viewsets.ModelViewSet): """Update junior profile""" serializer_class = CreateJuniorSerializer permission_classes = [IsAuthenticated] + http_method_names = ('post',) def create(self, request, *args, **kwargs): """Use CreateJuniorSerializer""" @@ -622,11 +623,14 @@ class ReadArticleCardAPIView(views.APIView): class CreateArticleCardAPIView(viewsets.ModelViewSet): """Start article""" + serializer_class = CreateArticleCardSerializer permission_classes = [IsAuthenticated] http_method_names = ('post',) def create(self, request, *args, **kwargs): - """ junior list""" + """ create article card + Params + {"article_id":1}""" try: junior_instance = Junior.objects.filter(auth=self.request.user).last() article_id = request.data.get('article_id') diff --git a/web_admin/utils.py b/web_admin/utils.py index 4170cf9..3dbb3b2 100644 --- a/web_admin/utils.py +++ b/web_admin/utils.py @@ -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 diff --git a/web_admin/views/analytics.py b/web_admin/views/analytics.py index ddc4e0d..face900 100644 --- a/web_admin/views/analytics.py +++ b/web_admin/views/analytics.py @@ -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