From d573d56a357e51e49f8661c3cd3564bceee9db9d Mon Sep 17 00:00:00 2001 From: abutalib-kiwi Date: Tue, 22 Aug 2023 16:01:08 +0530 Subject: [PATCH 1/4] minor changes --- celerybeat-schedule | Bin 16384 -> 16384 bytes junior/serializers.py | 2 +- notifications/admin.py | 1 - notifications/constants.py | 10 +++++++++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/celerybeat-schedule b/celerybeat-schedule index cc8251c7500206755f61cdf0ff0b24e019ea84c5..68297a7db074145de61828e2a94f36b892493ec5 100644 GIT binary patch delta 470 zcmYk2!Aiq07{?p!+~zEbP7jW;DTvNPTorwR;X!(vdht@)F51wp9c?CVFziW0a*=-C zckl&dkKn@ydjXG{(g+5U{QmiW-^ZUM2}%+)ZFUPvzLw;@)6PMYT9JBH>V2uX)SjNh zTsCYSzv|mFzxl3e-_ojxit4Ps_ftZRSsizfrpX}-!dXxIN7D^9PSm%eoXHojuR4%6 z+q;JPj7h*EN@C$xQC=_szCs=bG$K8dS+NJa;t-!iBWx3k0oN`am-L1{ITx)XNa4Um zyp_JRTaUm?J&O@W`{X~S&{-~il{S~_1@)5)#~xCj(I5t1yd%tFED~dQX&eTG2DhQW z8-W)YiubZP3gl{;n)f7%X&9KM_>1!2UlmUA3DyCB=yUBC>S={~ delta 390 zcmX|5F;Buk7`>w)?Lk4om4uKOsRPo%!I_w--Kr*yOVb{wTqrGHdl)exb|MZsnEn9< zHz&i7@+Uaz5gNa5crWkey}UHVX^L0vP62IC&k^;vM5}G_$9y+0*FpQEsOz~^kxqTx zI`~!b=epG!VEr(6Hf4G?IbJng_kqO;k3!c?6{jTildRqEoGULq7K)g&BvlrGx=vME z>~YFtHgtuTi~&>10v6AEKJx^*q9Zn(1?)_Q<^&4e5q1n2$=>?LGbnWE2`2c2k$(ck z0V#j0jS4bU(}5E8XFL!*OvpVGo)9sC9r_f7jE8p-xs~K%L!j(vve%u3Q%=VL19b_S z4a8BTdUHL1iiMX@wLxD(&4#*#=xIJQ$u}m1#!)CdpTKU{LKbqc%pSqsNWOrE4b27Y O`^EyYvHALCYPCNqqGy2s diff --git a/junior/serializers.py b/junior/serializers.py index 1ca98e4..abb0ded 100644 --- a/junior/serializers.py +++ b/junior/serializers.py @@ -98,7 +98,7 @@ class CreateJuniorSerializer(serializers.ModelSerializer): JuniorGuardianRelationship.objects.get_or_create(guardian=guardian_data, junior=junior) junior.guardian_code_status = str(NUMBER['three']) junior_approval_mail(user.email, user.first_name) - send_notification_to_guardian.delay(APPROVED_JUNIOR, junior.auth.id, guardian_data.user.id, {}) + send_notification_to_guardian.delay(ASSOCIATE_REQUEST, junior.auth.id, guardian_data.user.id, {}) junior.dob = validated_data.get('dob', junior.dob) junior.passcode = validated_data.get('passcode', junior.passcode) junior.country_name = validated_data.get('country_name', junior.country_name) diff --git a/notifications/admin.py b/notifications/admin.py index aa57aac..c7cc895 100644 --- a/notifications/admin.py +++ b/notifications/admin.py @@ -11,4 +11,3 @@ class NotificationAdmin(admin.ModelAdmin): """Notification Admin""" list_display = ['id', 'notification_type', 'notification_to', 'data', 'is_read'] list_filter = ['notification_type'] - \ No newline at end of file diff --git a/notifications/constants.py b/notifications/constants.py index f4f8b86..8bb6a6d 100644 --- a/notifications/constants.py +++ b/notifications/constants.py @@ -32,15 +32,17 @@ NOTIFICATION_DICT = { "title": "Associate request!", "body": "You have request from {from_user} to associate with you." }, + # Juniors will receive Notifications for every Points earned by referrals REFERRAL_POINTS: { "title": "Earn Referral points!", "body": "You earn 5 points for referral." }, - # notification once any custodian adds junior in their account + # Juniors will receive notification once any custodians add them in their account SKIPPED_PROFILE_SETUP: { "title": "Profile already setup!", "body": "Your guardian has already setup your profile." }, + # Juniors will receive Notification for every Task Assign by Custodians TASK_ASSIGNED: { "title": "New task assigned!", "body": "{from_user} has assigned you a new task." @@ -49,10 +51,12 @@ NOTIFICATION_DICT = { "title": "Task submitted!", "body": "Your task has been submitted for approval." }, + # Guardian will receive notification as soon as junior send task for approval TASK_ACTION: { "title": "Task completion approval!", "body": "You have request from {from_user} for task completion." }, + # Juniors will receive notification as soon as their task is approved or reject by custodians TASK_REJECTED: { "title": "Task completion rejected!", "body": "Your task completion request has been rejected by {from_user}." @@ -61,14 +65,18 @@ NOTIFICATION_DICT = { "title": "Task completion approved!", "body": "Your task completion request has been approved by {from_user}." }, + # Juniors will receive Notifications for every Points earned either by Task completion + # Juniors will receive notification as soon as their task is approved or reject by custodians TASK_POINTS: { "title": "Earned Task points!", "body": "You earn 5 points for task." }, + # Juniors will receive Notification related to Leaderboard progress LEADERBOARD_RANKING: { "title": "Leader board rank!", "body": "Your rank is ." }, + # Juniors will receive notification as soon as their custodians remove them from account REMOVE_JUNIOR: { "title": "Disassociate by guardian!", "body": "Your guardian has disassociated you." From 19acef10ef0974e7401eb27a4a997bf085dd16d8 Mon Sep 17 00:00:00 2001 From: abutalib-kiwi Date: Tue, 22 Aug 2023 19:03:39 +0530 Subject: [PATCH 2/4] added notitifcation for association rejected, approved, added mark as read api --- guardian/serializers.py | 6 ++-- guardian/views.py | 5 ++-- junior/serializers.py | 9 ++---- notifications/constants.py | 56 ++++++++++++++++---------------------- notifications/views.py | 41 +++------------------------- 5 files changed, 37 insertions(+), 80 deletions(-) diff --git a/guardian/serializers.py b/guardian/serializers.py index 8db860b..af11acc 100644 --- a/guardian/serializers.py +++ b/guardian/serializers.py @@ -28,7 +28,7 @@ from base.constants import NUMBER, JUN, ZOD, GRD, Already_register_user from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship from .utils import real_time, convert_timedelta_into_datetime, update_referral_points # notification's constant -from notifications.constants import TASK_POINTS, TASK_REJECTED +from notifications.constants import TASK_APPROVED, TASK_REJECTED # send notification function from notifications.utils import send_notification, send_notification_to_junior from django.core.exceptions import ValidationError @@ -420,7 +420,7 @@ class ApproveTaskSerializer(serializers.ModelSerializer): # update complete time of task # instance.completed_on = real_time() instance.completed_on = timezone.now().astimezone(pytz.utc) - send_notification_to_junior.delay(TASK_POINTS, None, junior_details.auth.id, + send_notification_to_junior.delay(TASK_APPROVED, instance.guardian.user.id, junior_details.auth.id, {'task_id': instance.id}) else: # reject the task @@ -429,7 +429,7 @@ class ApproveTaskSerializer(serializers.ModelSerializer): # update reject time of task # instance.rejected_on = real_time() instance.rejected_on = timezone.now().astimezone(pytz.utc) - send_notification_to_junior.delay(TASK_REJECTED, None, junior_details.auth.id, + send_notification_to_junior.delay(TASK_REJECTED, instance.guardian.user.id, junior_details.auth.id, {'task_id': instance.id}) instance.save() junior_data.save() diff --git a/guardian/views.py b/guardian/views.py index 80c1d9b..3f1b49b 100644 --- a/guardian/views.py +++ b/guardian/views.py @@ -38,7 +38,7 @@ from account.utils import custom_response, custom_error_response, OTP_EXPIRY, se from base.messages import ERROR_CODE, SUCCESS_CODE from base.constants import NUMBER, GUARDIAN_CODE_STATUS from .utils import upload_image_to_alibaba -from notifications.constants import REGISTRATION, TASK_ASSIGNED, LEADERBOARD_RANKING +from notifications.constants import REGISTRATION, TASK_ASSIGNED, ASSOCIATE_APPROVED, ASSOCIATE_REJECTED from notifications.utils import send_notification_to_junior """ Define APIs """ @@ -259,7 +259,6 @@ 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, {}) 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) @@ -293,11 +292,13 @@ class ApproveJuniorAPIView(viewsets.ModelViewSet): if serializer.is_valid(): # save serializer serializer.save() + send_notification_to_junior.delay(ASSOCIATE_APPROVED, guardian.user.id, junior_queryset.auth.id) return custom_response(SUCCESS_CODE['3023'], serializer.data, response_status=status.HTTP_200_OK) else: junior_queryset.guardian_code = None junior_queryset.guardian_code_status = str(NUMBER['one']) junior_queryset.save() + send_notification_to_junior.delay(ASSOCIATE_REJECTED, guardian.user.id, junior_queryset.auth.id) return custom_response(SUCCESS_CODE['3024'], response_status=status.HTTP_200_OK) except Exception as e: return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) diff --git a/junior/serializers.py b/junior/serializers.py index 040896b..f105dc5 100644 --- a/junior/serializers.py +++ b/junior/serializers.py @@ -22,8 +22,8 @@ from account.models import UserEmailOtp, UserNotification from junior.utils import junior_notification_email, junior_approval_mail from guardian.utils import real_time, update_referral_points, convert_timedelta_into_datetime from notifications.utils import send_notification, send_notification_to_junior, send_notification_to_guardian -from notifications.constants import (INVITATION, ASSOCIATE_REQUEST, SKIPPED_PROFILE_SETUP, TASK_ACTION, - TASK_SUBMITTED) +from notifications.constants import (ASSOCIATE_REQUEST, JUNIOR_ADDED, TASK_ACTION, + ) from web_admin.models import ArticleCard class ListCharField(serializers.ListField): @@ -307,7 +307,7 @@ class AddJuniorSerializer(serializers.ModelSerializer): """Notification email""" junior_notification_email.delay(email, full_name, email, password) # push notification - send_notification_to_junior.delay(SKIPPED_PROFILE_SETUP, None, junior_data.auth.id, {}) + send_notification_to_junior.delay(JUNIOR_ADDED, None, junior_data.auth.id, {}) return junior_data @@ -339,8 +339,6 @@ class CompleteTaskSerializer(serializers.ModelSerializer): instance.task_status = str(NUMBER['four']) instance.is_approved = False instance.save() - send_notification_to_junior.delay(TASK_SUBMITTED, instance.guardian.user.id, - instance.junior.auth.id, {'task_id': instance.id}) send_notification_to_guardian.delay(TASK_ACTION, instance.junior.auth.id, instance.guardian.user.id, {'task_id': instance.id}) return instance @@ -452,7 +450,6 @@ class AddGuardianSerializer(serializers.ModelSerializer): """Notification email""" junior_notification_email(email, full_name, email, password) junior_approval_mail.delay(email, full_name) - send_notification_to_junior.delay(INVITATION, guardian_data.user.id, junior_data.auth.id, {}) send_notification_to_guardian.delay(ASSOCIATE_REQUEST, junior_data.auth.id, guardian_data.user.id, {}) return guardian_data diff --git a/notifications/constants.py b/notifications/constants.py index 8bb6a6d..0cc5a0f 100644 --- a/notifications/constants.py +++ b/notifications/constants.py @@ -2,19 +2,17 @@ notification constants file """ REGISTRATION = 1 -INVITATION = 2 ASSOCIATE_REQUEST = 3 -REFERRAL_POINTS = 4 -SKIPPED_PROFILE_SETUP = 5 +ASSOCIATE_REJECTED = 4 +ASSOCIATE_APPROVED = 5 +REFERRAL_POINTS = 6 +JUNIOR_ADDED = 7 -TASK_ASSIGNED = 6 -TASK_SUBMITTED = 7 -TASK_ACTION = 8 -TASK_REJECTED = 9 -TASK_APPROVED = 10 -TASK_POINTS = 11 +TASK_ASSIGNED = 8 +TASK_ACTION = 9 +TASK_REJECTED = 10 +TASK_APPROVED = 11 -LEADERBOARD_RANKING = 12 REMOVE_JUNIOR = 13 TEST_NOTIFICATION = 99 @@ -24,21 +22,27 @@ NOTIFICATION_DICT = { "title": "Successfully registered!", "body": "You have registered successfully. Now login and complete your profile." }, - INVITATION: { - "title": "Invitation sent!", - "body": "Invitation has been successfully sent." - }, ASSOCIATE_REQUEST: { "title": "Associate request!", "body": "You have request from {from_user} to associate with you." }, + + ASSOCIATE_REJECTED: { + "title": "Associate request rejected!", + "body": "Your request to associate has been rejected by {from_user}." + }, + + ASSOCIATE_APPROVED: { + "title": "Associate request approved!", + "body": "Your request to associate has been approved by {from_user}." + }, # Juniors will receive Notifications for every Points earned by referrals REFERRAL_POINTS: { "title": "Earn Referral points!", "body": "You earn 5 points for referral." }, # Juniors will receive notification once any custodians add them in their account - SKIPPED_PROFILE_SETUP: { + JUNIOR_ADDED: { "title": "Profile already setup!", "body": "Your guardian has already setup your profile." }, @@ -47,34 +51,22 @@ NOTIFICATION_DICT = { "title": "New task assigned!", "body": "{from_user} has assigned you a new task." }, - TASK_SUBMITTED: { - "title": "Task submitted!", - "body": "Your task has been submitted for approval." - }, # Guardian will receive notification as soon as junior send task for approval TASK_ACTION: { "title": "Task completion approval!", "body": "You have request from {from_user} for task completion." }, - # Juniors will receive notification as soon as their task is approved or reject by custodians + # Juniors will receive notification as soon as their task is rejected by custodians TASK_REJECTED: { "title": "Task completion rejected!", "body": "Your task completion request has been rejected by {from_user}." }, + # Juniors will receive notification as soon as their task is approved by custodians + # and for every Points earned by Task completion TASK_APPROVED: { "title": "Task completion approved!", - "body": "Your task completion request has been approved by {from_user}." - }, - # Juniors will receive Notifications for every Points earned either by Task completion - # Juniors will receive notification as soon as their task is approved or reject by custodians - TASK_POINTS: { - "title": "Earned Task points!", - "body": "You earn 5 points for task." - }, - # Juniors will receive Notification related to Leaderboard progress - LEADERBOARD_RANKING: { - "title": "Leader board rank!", - "body": "Your rank is ." + "body": "Your task completion request has been approved by {from_user}. " + "Also you earned 5 points for successful completion." }, # Juniors will receive notification as soon as their custodians remove them from account REMOVE_JUNIOR: { diff --git a/notifications/views.py b/notifications/views.py index 154751a..8674e85 100644 --- a/notifications/views.py +++ b/notifications/views.py @@ -30,15 +30,8 @@ class NotificationViewSet(viewsets.GenericViewSet): 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): """ @@ -62,36 +55,10 @@ class NotificationViewSet(viewsets.GenericViewSet): {'task_id': None}) return custom_response(SUCCESS_CODE["3000"]) - @action(methods=['get'], detail=False, url_path='list', url_name='list', - serializer_class=NotificationListSerializer) - def notification_list(self, request): + @action(methods=['get'], url_path='mark-as-read', url_name='mark-as-read', detail=True, ) + def mark_as_read(self, request, *args, **kwargs): """ notification list """ - try: - queryset = Notification.objects.filter(notification_to=request.user) - 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) - - -class ReadNotification(views.APIView): - """Update notification API - Payload - { - "notification_id": [] - }""" - serializer_class = ReadNotificationSerializer - model = Notification - permission_classes = [IsAuthenticated] - - def put(self, request, format=None): - try: - notification_id = self.request.data.get('notification_id') - notification_queryset = Notification.objects.filter(id__in=notification_id, - notification_to=self.request.user).update(is_read=True) - if notification_queryset: - return custom_response(SUCCESS_CODE['3039'], response_status=status.HTTP_200_OK) - except Exception as e: - return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) + Notification.objects.filter(id=kwargs['pk']).update(is_read=True) + return custom_response(SUCCESS_CODE['3039'], response_status=status.HTTP_200_OK) From 290089b9ef571f6de40209c4c92800d0bce4dcdd Mon Sep 17 00:00:00 2001 From: abutalib-kiwi Date: Tue, 22 Aug 2023 19:26:30 +0530 Subject: [PATCH 3/4] added notitifcation for association rejected, approved, added mark as read api --- notifications/urls.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/notifications/urls.py b/notifications/urls.py index 713aae3..b184d02 100644 --- a/notifications/urls.py +++ b/notifications/urls.py @@ -6,7 +6,7 @@ from django.urls import path, include from rest_framework import routers # local imports -from notifications.views import NotificationViewSet, ReadNotification +from notifications.views import NotificationViewSet # initiate router router = routers.SimpleRouter() @@ -15,5 +15,4 @@ router.register('notifications', NotificationViewSet, basename='notifications') urlpatterns = [ path('api/v1/', include(router.urls)), - path('api/v1/read-notification/', ReadNotification.as_view()), ] From 56e1484b87464d508532482acae5b8001b12472d Mon Sep 17 00:00:00 2001 From: abutalib-kiwi Date: Wed, 23 Aug 2023 12:54:39 +0530 Subject: [PATCH 4/4] mark ad read api modified --- notifications/serializers.py | 2 ++ notifications/views.py | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/notifications/serializers.py b/notifications/serializers.py index 14f1b20..2f0222f 100644 --- a/notifications/serializers.py +++ b/notifications/serializers.py @@ -40,6 +40,8 @@ class NotificationListSerializer(serializers.ModelSerializer): class ReadNotificationSerializer(serializers.ModelSerializer): """User task Serializer""" + id = serializers.ListSerializer(child=serializers.IntegerField()) + class Meta(object): """Meta class""" model = Notification diff --git a/notifications/views.py b/notifications/views.py index 8674e85..d60c429 100644 --- a/notifications/views.py +++ b/notifications/views.py @@ -55,10 +55,11 @@ class NotificationViewSet(viewsets.GenericViewSet): {'task_id': None}) return custom_response(SUCCESS_CODE["3000"]) - @action(methods=['get'], url_path='mark-as-read', url_name='mark-as-read', detail=True, ) + @action(methods=['patch'], url_path='mark-as-read', url_name='mark-as-read', detail=False, + serializer_class=ReadNotificationSerializer) def mark_as_read(self, request, *args, **kwargs): """ notification list """ - Notification.objects.filter(id=kwargs['pk']).update(is_read=True) + Notification.objects.filter(id__in=request.data.get('id')).update(is_read=True) return custom_response(SUCCESS_CODE['3039'], response_status=status.HTTP_200_OK)