From 685f62770752ac8a136cf95ea6412a097a6207f3 Mon Sep 17 00:00:00 2001 From: abutalib-kiwi Date: Wed, 2 Aug 2023 19:16:29 +0530 Subject: [PATCH 1/4] change method to get real time --- guardian/serializers.py | 21 ++++++++++++--------- junior/serializers.py | 15 +++++++++++---- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/guardian/serializers.py b/guardian/serializers.py index c81744a..4d0ea65 100644 --- a/guardian/serializers.py +++ b/guardian/serializers.py @@ -1,5 +1,5 @@ """Serializer of Guardian""" -"""Third party Django app""" +# third party imports import logging from rest_framework import serializers # Import Refresh token of jwt @@ -7,7 +7,8 @@ from rest_framework_simplejwt.tokens import RefreshToken from django.db import transaction from django.contrib.auth.models import User from datetime import datetime, time -"""Import Django app""" +import pytz +from django.utils import timezone # Import guardian's model, # Import junior's model, # Import account's model, @@ -16,7 +17,7 @@ from datetime import datetime, time # Import messages from # base package, # Import some functions -# from utils file""" +# local imports from .models import Guardian, JuniorTask from account.models import UserProfile, UserEmailOtp, UserNotification from account.utils import generate_code @@ -222,12 +223,9 @@ class TaskDetailsSerializer(serializers.ModelSerializer): def get_remaining_time(self, obj): """ remaining time to complete task""" - import pytz - from django.utils import timezone due_date_datetime = datetime.combine(obj.due_date, datetime.max.time()) # fetch real time # current_datetime = real_time() - print(due_date_datetime.astimezone(pytz.utc), datetime.now(pytz.utc), timezone.now().astimezone(pytz.utc)) # new code due_date_datetime = due_date_datetime.astimezone(pytz.utc) current_datetime = timezone.now().astimezone(pytz.utc) @@ -260,7 +258,10 @@ class TaskDetailsjuniorSerializer(serializers.ModelSerializer): """ remaining time to complete task""" due_date_datetime = datetime.combine(obj.due_date, datetime.max.time()) # fetch real time - current_datetime = real_time() + # current_datetime = real_time() + # new code + due_date_datetime = due_date_datetime.astimezone(pytz.utc) + current_datetime = timezone.now().astimezone(pytz.utc) # Perform the subtraction if due_date_datetime > current_datetime: time_difference = due_date_datetime - current_datetime @@ -377,7 +378,8 @@ class ApproveTaskSerializer(serializers.ModelSerializer): # update total task point junior_data.total_points = junior_data.total_points + instance.points # update complete time of task - instance.completed_on = real_time() + # instance.completed_on = real_time() + instance.completed_on = timezone.now().astimezone(pytz.utc) send_notification.delay(TASK_POINTS, None, junior_details.auth.id, {}) else: # reject the task @@ -386,7 +388,8 @@ class ApproveTaskSerializer(serializers.ModelSerializer): # update total task point junior_data.total_points = junior_data.total_points - instance.points # update reject time of task - instance.rejected_on = real_time() + # instance.rejected_on = real_time() + instance.rejected_on = timezone.now().astimezone(pytz.utc) send_notification.delay(TASK_REJECTED, None, junior_details.auth.id, {}) instance.save() junior_data.save() diff --git a/junior/serializers.py b/junior/serializers.py index 1dc04da..bdedbb5 100644 --- a/junior/serializers.py +++ b/junior/serializers.py @@ -1,5 +1,8 @@ """Serializer file for junior""" -"""Import Django 3rd party app""" +# third party imports +import pytz + +# django imports from rest_framework import serializers from django.contrib.auth.models import User from django.db import transaction @@ -7,7 +10,7 @@ from datetime import datetime from django.utils import timezone from rest_framework_simplejwt.tokens import RefreshToken -"""Import django app""" +# local imports from account.utils import send_otp_email, generate_code from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship from guardian.tasks import generate_otp @@ -320,7 +323,8 @@ class CompleteTaskSerializer(serializers.ModelSerializer): fields = ('id', 'image') def update(self, instance, validated_data): instance.image = validated_data.get('image', instance.image) - instance.requested_on = real_time() + # instance.requested_on = real_time() + instance.requested_on = timezone.now().astimezone(pytz.utc) instance.task_status = str(NUMBER['four']) instance.is_approved = False instance.save() @@ -445,7 +449,10 @@ class StartTaskSerializer(serializers.ModelSerializer): """ remaining time to complete task""" due_date = datetime.combine(obj.due_date, datetime.max.time()) # fetch real time - real_datetime = real_time() + # real_datetime = real_time() + # new code + due_date = due_date.astimezone(pytz.utc) + real_datetime = timezone.now().astimezone(pytz.utc) # Perform the subtraction if due_date > real_datetime: time_difference = due_date - real_datetime From f3e2ab9a346ca28e3acc7b9b37db6fc32167906b Mon Sep 17 00:00:00 2001 From: abutalib-kiwi Date: Wed, 2 Aug 2023 20:45:46 +0530 Subject: [PATCH 2/4] notification list modified and mark as read method changed --- notifications/serializers.py | 4 +++- notifications/views.py | 25 +++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/notifications/serializers.py b/notifications/serializers.py index ff05dcd..a061369 100644 --- a/notifications/serializers.py +++ b/notifications/serializers.py @@ -8,6 +8,7 @@ from rest_framework import serializers from notifications.utils import register_fcm_token from notifications.models import Notification + class RegisterDevice(serializers.Serializer): """ used to create and validate register device token @@ -27,7 +28,8 @@ class RegisterDevice(serializers.Serializer): return register_fcm_token(self.context['user_id'], registration_id, validated_data['device_id'], device_type) -class NotificationListSerailizer(serializers.ModelSerializer): + +class NotificationListSerializer(serializers.ModelSerializer): """List of notification""" class Meta(object): diff --git a/notifications/views.py b/notifications/views.py index 3d2ff4a..4644e62 100644 --- a/notifications/views.py +++ b/notifications/views.py @@ -11,15 +11,32 @@ from rest_framework import viewsets, status, views from account.utils import custom_response, custom_error_response from base.messages import SUCCESS_CODE, ERROR_CODE from notifications.constants import TEST_NOTIFICATION -from notifications.serializers import RegisterDevice, NotificationListSerailizer, ReadNotificationSerializer +from notifications.serializers import RegisterDevice, NotificationListSerializer, ReadNotificationSerializer from notifications.utils import send_notification from notifications.models import Notification + class NotificationViewSet(viewsets.GenericViewSet): """ used to do the notification actions """ - serializer_class = RegisterDevice + serializer_class = NotificationListSerializer permission_classes = [IsAuthenticated, ] + def list(self, request, *args, **kwargs) -> Response: + """ list the notifications """ + queryset = Notification.objects.filter(notification_to_id=request.auth.payload['user_id'] + ).select_related('notification_to').order_by('-id') + paginator = self.pagination_class() + paginated_queryset = paginator.paginate_queryset(queryset, request) + serializer = self.serializer_class(paginated_queryset, many=True) + self.mark_notifications_as_read(serializer.data) + return custom_response(None, serializer.data) + + @staticmethod + def mark_notifications_as_read(data): + """ used to mark notification queryset as read """ + ids = [obj['id'] for obj in data] + Notification.objects.filter(id__in=ids).update(is_read=True) + @action(methods=['post'], detail=False, url_path='device', url_name='device', serializer_class=RegisterDevice) def fcm_registration(self, request): """ @@ -41,14 +58,14 @@ class NotificationViewSet(viewsets.GenericViewSet): return custom_response(SUCCESS_CODE["3000"]) @action(methods=['get'], detail=False, url_path='list', url_name='list', - serializer_class=NotificationListSerailizer) + serializer_class=NotificationListSerializer) def notification_list(self, request): """ notification list """ try: queryset = Notification.objects.filter(notification_to=request.user) - serializer = NotificationListSerailizer(queryset, many=True) + serializer = NotificationListSerializer(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) From dd0f2b027a84d9e510c6c1fd3b94da3dfef65dab Mon Sep 17 00:00:00 2001 From: abutalib-kiwi Date: Thu, 3 Aug 2023 18:17:01 +0530 Subject: [PATCH 3/4] task list api modified --- guardian/serializers.py | 8 ++++- guardian/views.py | 78 +++++++++++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/guardian/serializers.py b/guardian/serializers.py index db465ad..d92b637 100644 --- a/guardian/serializers.py +++ b/guardian/serializers.py @@ -222,9 +222,15 @@ class TaskDetailsSerializer(serializers.ModelSerializer): def get_remaining_time(self, obj): """ remaining time to complete task""" + import pytz + from django.utils import timezone due_date_datetime = datetime.combine(obj.due_date, datetime.max.time()) # fetch real time - current_datetime = real_time() + # current_datetime = real_time() + print(due_date_datetime.astimezone(pytz.utc), datetime.now(pytz.utc), timezone.now().astimezone(pytz.utc)) + # new code + due_date_datetime = due_date_datetime.astimezone(pytz.utc) + current_datetime = timezone.now().astimezone(pytz.utc) # Perform the subtraction if due_date_datetime > current_datetime: time_difference = due_date_datetime - current_datetime diff --git a/guardian/views.py b/guardian/views.py index 15b29c5..612f837 100644 --- a/guardian/views.py +++ b/guardian/views.py @@ -10,6 +10,8 @@ from rest_framework.permissions import IsAuthenticated from rest_framework import viewsets, status from rest_framework.pagination import PageNumberPagination from django.contrib.auth.models import User +from rest_framework.filters import SearchFilter + from django.utils import timezone # Import guardian's model, @@ -126,37 +128,69 @@ class AllTaskListAPIView(viewsets.ModelViewSet): serializer = TaskDetailsSerializer(queryset, many=True) 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): """Update guardian profile""" serializer_class = TaskDetailsSerializer permission_classes = [IsAuthenticated] + filter_backends = (SearchFilter,) + search_fields = ['task_name', ] pagination_class = PageNumberPagination http_method_names = ('get',) + def get_queryset(self): + queryset = JuniorTask.objects.filter(guardian__user=self.request.user + ).prefetch_related('junior', 'junior__auth' + ).order_by('due_date', 'created_at') + + queryset = self.filter_queryset(queryset) + return queryset + 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) + status_value = self.request.GET.get('status') + queryset = self.get_queryset() + if status_value and status_value != '0': + queryset = queryset.filter(task_status=status_value) + paginator = self.pagination_class() + # use Pagination + paginated_queryset = paginator.paginate_queryset(queryset, request) + # use TaskDetailsSerializer serializer + serializer = self.serializer_class(paginated_queryset, many=True) + return custom_response(None, serializer.data, response_status=status.HTTP_200_OK) + class CreateTaskAPIView(viewsets.ModelViewSet): """create task for junior""" From 10a1ea9b765728695bcc1fb622ffe67b17d7a2c2 Mon Sep 17 00:00:00 2001 From: abutalib-kiwi Date: Tue, 8 Aug 2023 14:29:57 +0530 Subject: [PATCH 4/4] change in admin login --- account/views.py | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/account/views.py b/account/views.py index 61c4e0e..853c43a 100644 --- a/account/views.py +++ b/account/views.py @@ -329,24 +329,17 @@ class UserLogin(viewsets.ViewSet): @action(methods=['post'], detail=False) def admin_login(self, request): - username = request.data.get('username') + email = request.data.get('email') password = request.data.get('password') - user = authenticate(request, username=username, password=password) - try: - if user is not None: - login(request, user) - if user.is_superuser: - serializer = SuperUserSerializer(user) - return custom_response(SUCCESS_CODE['3003'], serializer.data, response_status=status.HTTP_200_OK) - else: - return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_401_UNAUTHORIZED) - except Exception as e: - logging.error(e) - refresh = RefreshToken.for_user(user) - access_token = str(refresh.access_token) - refresh_token = str(refresh) - data = {"auth_token": access_token, "refresh_token":refresh_token, "user_type": '3'} - return custom_response(None, data, response_status=status.HTTP_200_OK) + 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["2063"], response_status=status.HTTP_400_BAD_REQUEST) + elif not user.check_password(password): + return custom_error_response(ERROR_CODE["2031"], response_status=status.HTTP_400_BAD_REQUEST) + serializer = SuperUserSerializer(user) + return custom_response(SUCCESS_CODE['3003'], serializer.data, response_status=status.HTTP_200_OK) class AdminLoginViewSet(viewsets.GenericViewSet):