Merge branch 'dev' of github.com:KiwiTechLLC/ZODBank-Backend into sprint5

This commit is contained in:
jain
2023-08-24 11:27:13 +05:30
9 changed files with 48 additions and 81 deletions

Binary file not shown.

View File

@ -28,7 +28,7 @@ from base.constants import NUMBER, JUN, ZOD, GRD, Already_register_user
from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship
from .utils import real_time, convert_timedelta_into_datetime, update_referral_points from .utils import real_time, convert_timedelta_into_datetime, update_referral_points
# notification's constant # notification's constant
from notifications.constants import TASK_POINTS, TASK_REJECTED from notifications.constants import TASK_APPROVED, TASK_REJECTED
# send notification function # send notification function
from notifications.utils import send_notification, send_notification_to_junior from notifications.utils import send_notification, send_notification_to_junior
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@ -420,7 +420,7 @@ class ApproveTaskSerializer(serializers.ModelSerializer):
# update complete time of task # update complete time of task
# instance.completed_on = real_time() # instance.completed_on = real_time()
instance.completed_on = timezone.now().astimezone(pytz.utc) 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}) {'task_id': instance.id})
else: else:
# reject the task # reject the task
@ -429,7 +429,7 @@ class ApproveTaskSerializer(serializers.ModelSerializer):
# update reject time of task # update reject time of task
# instance.rejected_on = real_time() # instance.rejected_on = real_time()
instance.rejected_on = timezone.now().astimezone(pytz.utc) 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}) {'task_id': instance.id})
instance.save() instance.save()
junior_data.save() junior_data.save()

View File

@ -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.messages import ERROR_CODE, SUCCESS_CODE
from base.constants import NUMBER, GUARDIAN_CODE_STATUS from base.constants import NUMBER, GUARDIAN_CODE_STATUS
from .utils import upload_image_to_alibaba 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 from notifications.utils import send_notification_to_junior
""" Define APIs """ """ Define APIs """
@ -259,7 +259,6 @@ class TopJuniorListAPIView(viewsets.ModelViewSet):
# Update the position field for each JuniorPoints object # Update the position field for each JuniorPoints object
for index, junior in enumerate(junior_total_points): for index, junior in enumerate(junior_total_points):
junior.position = index + 1 junior.position = index + 1
# send_notification_to_junior.delay(LEADERBOARD_RANKING, None, junior.junior.auth.id, {})
junior.save() junior.save()
serializer = self.get_serializer(junior_total_points[:NUMBER['fifteen']], many=True) serializer = self.get_serializer(junior_total_points[:NUMBER['fifteen']], many=True)
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK) return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
@ -293,11 +292,13 @@ class ApproveJuniorAPIView(viewsets.ModelViewSet):
if serializer.is_valid(): if serializer.is_valid():
# save serializer # save serializer
serializer.save() 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) return custom_response(SUCCESS_CODE['3023'], serializer.data, response_status=status.HTTP_200_OK)
else: else:
junior_queryset.guardian_code = None junior_queryset.guardian_code = None
junior_queryset.guardian_code_status = str(NUMBER['one']) junior_queryset.guardian_code_status = str(NUMBER['one'])
junior_queryset.save() 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) return custom_response(SUCCESS_CODE['3024'], response_status=status.HTTP_200_OK)
except Exception as e: except Exception as e:
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)

View File

@ -22,8 +22,8 @@ from account.models import UserEmailOtp, UserNotification
from junior.utils import junior_notification_email, junior_approval_mail from junior.utils import junior_notification_email, junior_approval_mail
from guardian.utils import real_time, update_referral_points, convert_timedelta_into_datetime 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.utils import send_notification, send_notification_to_junior, send_notification_to_guardian
from notifications.constants import (INVITATION, ASSOCIATE_REQUEST, SKIPPED_PROFILE_SETUP, TASK_ACTION, from notifications.constants import (ASSOCIATE_REQUEST, JUNIOR_ADDED, TASK_ACTION,
TASK_SUBMITTED) )
from web_admin.models import ArticleCard from web_admin.models import ArticleCard
class ListCharField(serializers.ListField): class ListCharField(serializers.ListField):
@ -98,7 +98,8 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
JuniorGuardianRelationship.objects.get_or_create(guardian=guardian_data, junior=junior) JuniorGuardianRelationship.objects.get_or_create(guardian=guardian_data, junior=junior)
junior.guardian_code_status = str(NUMBER['three']) junior.guardian_code_status = str(NUMBER['three'])
junior_approval_mail.delay(user.email, user.first_name) junior_approval_mail.delay(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.dob = validated_data.get('dob', junior.dob)
junior.passcode = validated_data.get('passcode', junior.passcode) junior.passcode = validated_data.get('passcode', junior.passcode)
junior.country_name = validated_data.get('country_name', junior.country_name) junior.country_name = validated_data.get('country_name', junior.country_name)
@ -306,7 +307,7 @@ class AddJuniorSerializer(serializers.ModelSerializer):
"""Notification email""" """Notification email"""
junior_notification_email.delay(email, full_name, email, password) junior_notification_email.delay(email, full_name, email, password)
# push notification # 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 return junior_data
@ -338,8 +339,6 @@ class CompleteTaskSerializer(serializers.ModelSerializer):
instance.task_status = str(NUMBER['four']) instance.task_status = str(NUMBER['four'])
instance.is_approved = False instance.is_approved = False
instance.save() 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, send_notification_to_guardian.delay(TASK_ACTION, instance.junior.auth.id,
instance.guardian.user.id, {'task_id': instance.id}) instance.guardian.user.id, {'task_id': instance.id})
return instance return instance
@ -451,7 +450,6 @@ class AddGuardianSerializer(serializers.ModelSerializer):
"""Notification email""" """Notification email"""
junior_notification_email(email, full_name, email, password) junior_notification_email(email, full_name, email, password)
junior_approval_mail.delay(email, full_name) 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, {}) send_notification_to_guardian.delay(ASSOCIATE_REQUEST, junior_data.auth.id, guardian_data.user.id, {})
return guardian_data return guardian_data

View File

@ -11,4 +11,3 @@ class NotificationAdmin(admin.ModelAdmin):
"""Notification Admin""" """Notification Admin"""
list_display = ['id', 'notification_type', 'notification_to', 'data', 'is_read'] list_display = ['id', 'notification_type', 'notification_to', 'data', 'is_read']
list_filter = ['notification_type'] list_filter = ['notification_type']

View File

@ -2,19 +2,17 @@
notification constants file notification constants file
""" """
REGISTRATION = 1 REGISTRATION = 1
INVITATION = 2
ASSOCIATE_REQUEST = 3 ASSOCIATE_REQUEST = 3
REFERRAL_POINTS = 4 ASSOCIATE_REJECTED = 4
SKIPPED_PROFILE_SETUP = 5 ASSOCIATE_APPROVED = 5
REFERRAL_POINTS = 6
JUNIOR_ADDED = 7
TASK_ASSIGNED = 6 TASK_ASSIGNED = 8
TASK_SUBMITTED = 7 TASK_ACTION = 9
TASK_ACTION = 8 TASK_REJECTED = 10
TASK_REJECTED = 9 TASK_APPROVED = 11
TASK_APPROVED = 10
TASK_POINTS = 11
LEADERBOARD_RANKING = 12
REMOVE_JUNIOR = 13 REMOVE_JUNIOR = 13
TEST_NOTIFICATION = 99 TEST_NOTIFICATION = 99
@ -24,51 +22,53 @@ NOTIFICATION_DICT = {
"title": "Successfully registered!", "title": "Successfully registered!",
"body": "You have registered successfully. Now login and complete your profile." "body": "You have registered successfully. Now login and complete your profile."
}, },
INVITATION: {
"title": "Invitation sent!",
"body": "Invitation has been successfully sent."
},
ASSOCIATE_REQUEST: { ASSOCIATE_REQUEST: {
"title": "Associate request!", "title": "Associate request!",
"body": "You have request from {from_user} to associate with you." "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: { REFERRAL_POINTS: {
"title": "Earn Referral points!", "title": "Earn Referral points!",
"body": "You earn 5 points for referral." "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: { JUNIOR_ADDED: {
"title": "Profile already setup!", "title": "Profile already setup!",
"body": "Your guardian has already setup your profile." "body": "Your guardian has already setup your profile."
}, },
# Juniors will receive Notification for every Task Assign by Custodians
TASK_ASSIGNED: { TASK_ASSIGNED: {
"title": "New task assigned!", "title": "New task assigned!",
"body": "{from_user} has assigned you a new task." "body": "{from_user} has assigned you a new task."
}, },
TASK_SUBMITTED: { # Guardian will receive notification as soon as junior send task for approval
"title": "Task submitted!",
"body": "Your task has been submitted for approval."
},
TASK_ACTION: { TASK_ACTION: {
"title": "Task completion approval!", "title": "Task completion approval!",
"body": "You have request from {from_user} for task completion." "body": "You have request from {from_user} for task completion."
}, },
# Juniors will receive notification as soon as their task is rejected by custodians
TASK_REJECTED: { TASK_REJECTED: {
"title": "Task completion rejected!", "title": "Task completion rejected!",
"body": "Your task completion request has been rejected by {from_user}." "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: { TASK_APPROVED: {
"title": "Task completion approved!", "title": "Task completion approved!",
"body": "Your task completion request has been approved by {from_user}." "body": "Your task completion request has been approved by {from_user}. "
}, "Also you earned 5 points for successful completion."
TASK_POINTS: {
"title": "Earned Task points!",
"body": "You earn 5 points for task."
},
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: { REMOVE_JUNIOR: {
"title": "Disassociate by guardian!", "title": "Disassociate by guardian!",
"body": "Your guardian has disassociated you." "body": "Your guardian has disassociated you."

View File

@ -40,6 +40,8 @@ class NotificationListSerializer(serializers.ModelSerializer):
class ReadNotificationSerializer(serializers.ModelSerializer): class ReadNotificationSerializer(serializers.ModelSerializer):
"""User task Serializer""" """User task Serializer"""
id = serializers.ListSerializer(child=serializers.IntegerField())
class Meta(object): class Meta(object):
"""Meta class""" """Meta class"""
model = Notification model = Notification

View File

@ -6,7 +6,7 @@ from django.urls import path, include
from rest_framework import routers from rest_framework import routers
# local imports # local imports
from notifications.views import NotificationViewSet, ReadNotification from notifications.views import NotificationViewSet
# initiate router # initiate router
router = routers.SimpleRouter() router = routers.SimpleRouter()
@ -15,5 +15,4 @@ router.register('notifications', NotificationViewSet, basename='notifications')
urlpatterns = [ urlpatterns = [
path('api/v1/', include(router.urls)), path('api/v1/', include(router.urls)),
path('api/v1/read-notification/', ReadNotification.as_view()),
] ]

View File

@ -30,15 +30,8 @@ class NotificationViewSet(viewsets.GenericViewSet):
paginator = self.pagination_class() paginator = self.pagination_class()
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)
self.mark_notifications_as_read(serializer.data)
return custom_response(None, 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) @action(methods=['post'], detail=False, url_path='device', url_name='device', serializer_class=RegisterDevice)
def fcm_registration(self, request): def fcm_registration(self, request):
""" """
@ -62,36 +55,11 @@ class NotificationViewSet(viewsets.GenericViewSet):
{'task_id': None}) {'task_id': None})
return custom_response(SUCCESS_CODE["3000"]) return custom_response(SUCCESS_CODE["3000"])
@action(methods=['get'], detail=False, url_path='list', url_name='list', @action(methods=['patch'], url_path='mark-as-read', url_name='mark-as-read', detail=False,
serializer_class=NotificationListSerializer) serializer_class=ReadNotificationSerializer)
def notification_list(self, request): def mark_as_read(self, request, *args, **kwargs):
""" """
notification list notification list
""" """
try: Notification.objects.filter(id__in=request.data.get('id')).update(is_read=True)
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) 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)