Compare commits

...
Author SHA1 Message Date
abutalib-kiwi b1d8949b08 added status for login and sign up from google and apple 2023-10-27 12:05:47 +05:30
Abu Talib 801bc45bc5 Merge pull request #357 from KiwiTechLLC/ZBKBCK-54
to user type added
2023-10-06 18:12:47 +05:30
abutalib-kiwi d1927b24ee to user type added 2023-10-06 18:10:56 +05:30
gauravmishra-kiwi 012d93f70f Merge pull request #354 from KiwiTechLLC/ZBKBCK-54
added to user type as per required changes, handled apple signup for existing users
2023-10-06 17:55:01 +05:30
abutalib-kiwi a1f9f93654 added to user type as per required changes, handled apple signup for existing users 2023-10-06 17:29:41 +05:30
gauravmishra-kiwi 652fe9e680 Merge pull request #351 from KiwiTechLLC/ZBKBCK-54
fixed user notificatio setting issue
2023-10-05 17:43:19 +05:30
abutalib-kiwi 13665f4c9a fixed user notificatio setting issue 2023-10-05 17:38:57 +05:30
gauravmishra-kiwi bf5453c7b7 Merge pull request #348 from KiwiTechLLC/ZBKBCK-54
fixed login into another device issue
2023-10-05 13:24:56 +05:30
abutalib-kiwi 6e3166967e fixed login into another device issue 2023-10-05 13:07:42 +05:30
gauravmishra-kiwi 47a00f313a Merge pull request #345 from KiwiTechLLC/ZBKBCK-54
added mail for user activation, handled fcm token for deleted user
2023-10-03 18:57:55 +05:30
abutalib-kiwi ad4d782e72 added mail for user activation, handled fcm token for deleted user 2023-10-03 18:54:47 +05:30
dilipshrivastwa-kiwi 8050e70cf7 Merge pull request #342 from KiwiTechLLC/ZBKBCK-54
handled deactivated users for social login
2023-09-29 16:11:08 +05:30
abutalib-kiwi 18a53e1c48 handled deactivated users for social login 2023-09-29 16:09:22 +05:30
dilipshrivastwa-kiwi f1333491e0 Merge pull request #341 from KiwiTechLLC/ZBKBCK-54
notification mark as read api modified for clear all, list sorting set to updated at field, added same field
2023-09-29 15:09:47 +05:30
abutalib-kiwi bd7eddb275 notification mark as read api modified for clear all, list sorting set to updated at field, added same field 2023-09-29 14:58:06 +05:30
dilipshrivastwa-kiwi 4c34c2496b Merge pull request #340 from KiwiTechLLC/ZBKBCK-54
notification create modified to update or create
2023-09-28 19:35:16 +05:30
abutalib-kiwi e121c92fb4 notification create modified to update or create 2023-09-28 19:09:57 +05:30
abutalib-kiwi 18143e0219 modified send push method 2023-09-27 19:31:09 +05:30
abutalib-kiwi 251a912948 revert access token time to 3 hrs 2023-09-27 12:36:28 +05:30
abutalib-kiwi f7bb83cebb added notification type in serializer 2023-09-26 19:11:04 +05:30
dilipshrivastwa-kiwi 994e9a270e Merge pull request #339 from KiwiTechLLC/ZBKBCK-54
added notification type in push data
2023-09-26 17:27:10 +05:30
abutalib-kiwi 32c35f8649 added notification type in push data 2023-09-26 17:24:40 +05:30
abutalib-kiwi ea02d7f5bb token expire time 1 min for testing 2023-09-25 11:45:50 +05:30
abutalib-kiwi 648628d3ea Merge branch 'dev' of https://github.com/KiwiTechLLC/ZODBank-Backend into dev 2023-09-25 11:44:57 +05:30
abutalib-kiwi 6ba3d7d8db token expire time 1 min for testing 2023-09-25 11:44:04 +05:30
dilipshrivastwa-kiwi 651405ddef Merge pull request #336 from KiwiTechLLC/ZBKBCK-52
feedback changes and added mark all read
2023-09-22 23:29:38 +05:30
abutalib-kiwi 3afd7fecf3 feedback changes and added mark all read 2023-09-22 19:55:10 +05:30
dilipshrivastwa-kiwi c484669a2d Merge pull request #335 from KiwiTechLLC/ZBKBCK-52
fixed guardian reject issue, updated ids in notification method, remo…
2023-09-13 18:18:07 +05:30
abutalib-kiwi d1a4b86b09 fixed guardian reject issue, updated ids in notification method, remove unnecessary condition from analytics and user management 2023-09-13 18:15:07 +05:30
dilipshrivastwa-kiwi a3c2b68a0d Merge pull request #332 from KiwiTechLLC/ZBKBCK-52
fixed article reward points notification for 0 points earned
2023-09-13 14:50:24 +05:30
abutalib-kiwi e157e98a17 fixed article reward points notification for 0 points earned 2023-09-13 14:45:47 +05:30
abutalib-kiwi a653518cfd fixed article reward points notification for 0 points earned 2023-09-13 14:38:18 +05:30
dilipshrivastwa-kiwi af25dc4e82 Merge pull request #331 from KiwiTechLLC/ZBKBCK-52
modified get article card current page method
2023-09-13 14:05:55 +05:30
abutalib-kiwi eaf67b682f modified get article card current page method 2023-09-13 14:03:13 +05:30
dilipshrivastwa-kiwi 71bbef84aa Merge pull request #330 from KiwiTechLLC/ZBKBCK-52
modified get article card current page method
2023-09-13 13:40:10 +05:30
abutalib-kiwi 085607128b modified get article card current page method 2023-09-13 13:36:25 +05:30
abutalib-kiwi fbdef7c0c4 Merge branch 'dev' of https://github.com/KiwiTechLLC/ZODBank-Backend into dev 2023-09-13 13:34:14 +05:30
dilipshrivastwa-kiwi 535e2e7f56 Merge pull request #329 from KiwiTechLLC/ZBKADM-73-test-cases
added a test case, updated coverage file
2023-09-13 12:15:37 +05:30
dilipshrivastwa-kiwi de710c8a7b Merge pull request #328 from KiwiTechLLC/ZBKADM-73-test-cases
updated coverage file
2023-09-12 15:18:55 +05:30
abutalib-kiwi 0a9dde2038 Merge branch 'dev' of https://github.com/KiwiTechLLC/ZODBank-Backend into dev 2023-09-12 14:58:35 +05:30
dilipshrivastwa-kiwi f11959d6bc Merge pull request #327 from KiwiTechLLC/ZBKADM-73-test-cases
test cases for admin user management, analytics and notification
2023-09-12 14:54:26 +05:30
abutalib-kiwi 1dec5ace3f test cases for admin user management, analytics and notification 2023-09-12 14:42:44 +05:30
dilipshrivastwa-kiwi 3ecbc1d303 Merge pull request #324 from KiwiTechLLC/ZBKBCK-52
make special password method modified
2023-09-11 17:37:42 +05:30
abutalib-kiwi ca0041caa6 make special password method modified 2023-09-11 17:01:03 +05:30
abutalib-kiwi c800853e9b make special password method modified 2023-09-11 16:45:07 +05:30
dilipshrivastwa-kiwi 3a84b1ea75 Merge pull request #323 from KiwiTechLLC/ZBKADM-73-test-cases
test cases for web admin auth
2023-09-11 14:45:25 +05:30
23 changed files with 192 additions and 71 deletions
+19 -11
View File
@@ -216,6 +216,7 @@ class GuardianSerializer(serializers.ModelSerializer):
last_name = serializers.SerializerMethodField('get_last_name') last_name = serializers.SerializerMethodField('get_last_name')
auth_token = serializers.SerializerMethodField('get_auth_token') auth_token = serializers.SerializerMethodField('get_auth_token')
refresh_token = serializers.SerializerMethodField('get_refresh_token') refresh_token = serializers.SerializerMethodField('get_refresh_token')
sign_up = serializers.SerializerMethodField()
def get_auth_token(self, obj): def get_auth_token(self, obj):
refresh = RefreshToken.for_user(obj.user) refresh = RefreshToken.for_user(obj.user)
@@ -253,12 +254,16 @@ class GuardianSerializer(serializers.ModelSerializer):
"""user last name""" """user last name"""
return obj.user.last_name return obj.user.last_name
def get_sign_up(self, obj):
return True if self.context.get('sign_up', '') else False
class Meta(object): class Meta(object):
"""Meta info""" """Meta info"""
model = Guardian model = Guardian
fields = ['id', 'auth_token', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code', fields = ['id', 'auth_token', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code',
'phone', 'family_name', 'gender', 'dob', 'referral_code', 'is_active', 'is_deleted', 'phone', 'family_name', 'gender', 'dob', 'referral_code', 'is_active', 'is_deleted',
'is_complete_profile', 'passcode', 'image', 'created_at', 'updated_at', 'user_type', 'country_name'] 'is_complete_profile', 'passcode', 'image', 'created_at', 'updated_at', 'user_type',
'country_name', 'sign_up']
class JuniorSerializer(serializers.ModelSerializer): class JuniorSerializer(serializers.ModelSerializer):
@@ -269,6 +274,7 @@ class JuniorSerializer(serializers.ModelSerializer):
last_name = serializers.SerializerMethodField('get_last_name') last_name = serializers.SerializerMethodField('get_last_name')
auth_token = serializers.SerializerMethodField('get_auth_token') auth_token = serializers.SerializerMethodField('get_auth_token')
refresh_token = serializers.SerializerMethodField('get_refresh_token') refresh_token = serializers.SerializerMethodField('get_refresh_token')
sign_up = serializers.SerializerMethodField()
def get_auth_token(self, obj): def get_auth_token(self, obj):
refresh = RefreshToken.for_user(obj.auth) refresh = RefreshToken.for_user(obj.auth)
@@ -295,13 +301,16 @@ class JuniorSerializer(serializers.ModelSerializer):
def get_last_name(self, obj): def get_last_name(self, obj):
return obj.auth.last_name return obj.auth.last_name
def get_sign_up(self, obj):
return True if self.context.get('sign_up', '') else False
class Meta(object): class Meta(object):
"""Meta info""" """Meta info"""
model = Junior model = Junior
fields = ['id', 'auth_token', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code', fields = ['id', 'auth_token', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code',
'phone', 'gender', 'dob', 'guardian_code', 'referral_code','is_active', 'is_password_set', 'phone', 'gender', 'dob', 'guardian_code', 'referral_code','is_active', 'is_password_set',
'is_complete_profile', 'created_at', 'image', 'updated_at', 'user_type', 'country_name','is_invited', 'is_complete_profile', 'created_at', 'image', 'updated_at', 'user_type', 'country_name','is_invited',
'is_deleted'] 'is_deleted', 'sign_up']
class EmailVerificationSerializer(serializers.ModelSerializer): class EmailVerificationSerializer(serializers.ModelSerializer):
"""Email verification serializer""" """Email verification serializer"""
@@ -373,17 +382,16 @@ class UpdateUserNotificationSerializer(serializers.ModelSerializer):
fields = ['push_notification', 'email_notification', 'sms_notification'] fields = ['push_notification', 'email_notification', 'sms_notification']
def create(self, validated_data): def create(self, validated_data):
instance = UserNotification.objects.filter(user=self.context).last() instance, _ = UserNotification.objects.update_or_create(
if instance: user=self.context,
# change notification status defaults={
instance.push_notification = validated_data.get('push_notification',instance.push_notification) 'push_notification': validated_data.get('push_notification'),
instance.email_notification = validated_data.get('email_notification', instance.email_notification) 'email_notification': validated_data.get('email_notification'),
instance.sms_notification = validated_data.get('sms_notification', instance.sms_notification) 'sms_notification': validated_data.get('sms_notification'),
instance.save() })
else:
instance = UserNotification.objects.create(user=self.context)
return instance return instance
class UserPhoneOtpSerializer(serializers.ModelSerializer): class UserPhoneOtpSerializer(serializers.ModelSerializer):
"""User Phone serializers""" """User Phone serializers"""
class Meta(object): class Meta(object):
@@ -0,0 +1,22 @@
{% extends "templated_email/email_base.email" %}
{% block subject %}
Account Activated
{% endblock %}
{% block plain %}
<tr>
<td style="padding: 0 27px 15px;">
<p style="margin: 0; font-size: 16px; line-height: 20px; padding: 36px 0 0; font-weight: 500; color: #1f2532;">
Hi User,
</p>
</td>
</tr>
<tr>
<td style="padding: 0 27px 22px;">
<p style="margin: 0;font-size: 14px; font-weight: 400; line-height: 21px; color: #1f2532;">
We're pleased to inform you that your account has been successfully reactivated by our admin team. Welcome back to ZOD ! <br><br> You can now access all the features and services as before. If you have any questions or need assistance, please feel free to reach out to our support team. <br><br> Thank you for being a valued member of our community.
</p>
</td>
</tr>
{% endblock %}
+23 -5
View File
@@ -90,6 +90,11 @@ class GoogleLoginMixin(object):
ERROR_CODE["2071"], ERROR_CODE["2071"],
response_status=status.HTTP_400_BAD_REQUEST response_status=status.HTTP_400_BAD_REQUEST
) )
if not junior_query.is_active:
return custom_error_response(
ERROR_CODE["2075"],
response_status=status.HTTP_404_NOT_FOUND
)
serializer = JuniorSerializer(junior_query) serializer = JuniorSerializer(junior_query)
elif str(user_type) == '2': elif str(user_type) == '2':
guardian_query = Guardian.objects.filter(user=user_data.last()).last() guardian_query = Guardian.objects.filter(user=user_data.last()).last()
@@ -98,12 +103,21 @@ class GoogleLoginMixin(object):
ERROR_CODE["2070"], ERROR_CODE["2070"],
response_status=status.HTTP_400_BAD_REQUEST response_status=status.HTTP_400_BAD_REQUEST
) )
if not guardian_query.is_active:
return custom_error_response(
ERROR_CODE["2075"],
response_status=status.HTTP_404_NOT_FOUND
)
serializer = GuardianSerializer(guardian_query) serializer = GuardianSerializer(guardian_query)
else: else:
return custom_error_response( return custom_error_response(
ERROR_CODE["2069"], ERROR_CODE["2069"],
response_status=status.HTTP_400_BAD_REQUEST response_status=status.HTTP_400_BAD_REQUEST
) )
device_detail, created = UserDeviceDetails.objects.get_or_create(user=user_data.last())
if device_detail:
device_detail.device_id = device_id
device_detail.save()
return custom_response(SUCCESS_CODE['3003'], serializer.data, return custom_response(SUCCESS_CODE['3003'], serializer.data,
response_status=status.HTTP_200_OK) response_status=status.HTTP_200_OK)
@@ -115,7 +129,7 @@ class GoogleLoginMixin(object):
junior_code=generate_code(JUN, user_obj.id), junior_code=generate_code(JUN, user_obj.id),
referral_code=generate_code(ZOD, user_obj.id) referral_code=generate_code(ZOD, user_obj.id)
) )
serializer = JuniorSerializer(junior_query) serializer = JuniorSerializer(junior_query, context={'sign_up': True})
position = Junior.objects.all().count() position = Junior.objects.all().count()
JuniorPoints.objects.create(junior=junior_query, position=position) JuniorPoints.objects.create(junior=junior_query, position=position)
elif str(user_type) == '2': elif str(user_type) == '2':
@@ -124,7 +138,7 @@ class GoogleLoginMixin(object):
guardian_code=generate_code(GRD, user_obj.id), guardian_code=generate_code(GRD, user_obj.id),
referral_code=generate_code(ZOD, user_obj.id) referral_code=generate_code(ZOD, user_obj.id)
) )
serializer = GuardianSerializer(guardian_query) serializer = GuardianSerializer(guardian_query, context={'sign_up': True})
else: else:
user_obj.delete() user_obj.delete()
return custom_error_response( return custom_error_response(
@@ -170,7 +184,7 @@ class SigninWithApple(views.APIView):
user_data = {"email": decoded_data.get('email'), "username": decoded_data.get('email'), "is_active": True} user_data = {"email": decoded_data.get('email'), "username": decoded_data.get('email'), "is_active": True}
if decoded_data.get("email"): if decoded_data.get("email"):
try: try:
user = User.objects.get(email=decoded_data.get("email")) user = User.objects.get(email__iexact=decoded_data.get("email"))
if str(user_type) == '1': if str(user_type) == '1':
junior_data = Junior.objects.filter(auth=user).last() junior_data = Junior.objects.filter(auth=user).last()
if not junior_data: if not junior_data:
@@ -192,6 +206,10 @@ class SigninWithApple(views.APIView):
ERROR_CODE["2069"], ERROR_CODE["2069"],
response_status=status.HTTP_400_BAD_REQUEST response_status=status.HTTP_400_BAD_REQUEST
) )
device_detail, created = UserDeviceDetails.objects.get_or_create(user=user)
if device_detail:
device_detail.device_id = device_id
device_detail.save()
return custom_response(SUCCESS_CODE['3003'], serializer.data, return custom_response(SUCCESS_CODE['3003'], serializer.data,
response_status=status.HTTP_200_OK) response_status=status.HTTP_200_OK)
@@ -202,7 +220,7 @@ class SigninWithApple(views.APIView):
signup_method='3', signup_method='3',
junior_code=generate_code(JUN, user.id), junior_code=generate_code(JUN, user.id),
referral_code=generate_code(ZOD, user.id)) referral_code=generate_code(ZOD, user.id))
serializer = JuniorSerializer(junior_query) serializer = JuniorSerializer(junior_query, context={'sign_up': True})
position = Junior.objects.all().count() position = Junior.objects.all().count()
JuniorPoints.objects.create(junior=junior_query, position=position) JuniorPoints.objects.create(junior=junior_query, position=position)
elif str(user_type) == '2': elif str(user_type) == '2':
@@ -210,7 +228,7 @@ class SigninWithApple(views.APIView):
signup_method='3', signup_method='3',
guardian_code=generate_code(GRD, user.id), guardian_code=generate_code(GRD, user.id),
referral_code=generate_code(ZOD, user.id)) referral_code=generate_code(ZOD, user.id))
serializer = GuardianSerializer(guardian_query) serializer = GuardianSerializer(guardian_query, context={'sign_up': True})
else: else:
user.delete() user.delete()
return custom_error_response( return custom_error_response(
+1 -1
View File
@@ -44,7 +44,7 @@ ERROR_CODE = {
"2018": "Attached File not found", "2018": "Attached File not found",
"2019": "Invalid Referral code", "2019": "Invalid Referral code",
"2020": "Enter valid mobile number", "2020": "Enter valid mobile number",
"2021": "Already register", "2021": "User registered",
"2022": "Invalid Guardian code", "2022": "Invalid Guardian code",
"2023": "Invalid user", "2023": "Invalid user",
# email not verified # email not verified
+5 -4
View File
@@ -13,7 +13,7 @@ from django.db.models import F, Window
from django.db.models.functions.window import Rank from django.db.models.functions.window import Rank
# local imports # local imports
from base.constants import PENDING, IN_PROGRESS, JUNIOR from base.constants import PENDING, IN_PROGRESS, JUNIOR, GUARDIAN
from guardian.models import JuniorTask from guardian.models import JuniorTask
from junior.models import JuniorPoints from junior.models import JuniorPoints
from notifications.constants import PENDING_TASK_EXPIRING, IN_PROGRESS_TASK_EXPIRING, NOTIFICATION_DICT, TOP_JUNIOR from notifications.constants import PENDING_TASK_EXPIRING, IN_PROGRESS_TASK_EXPIRING, NOTIFICATION_DICT, TOP_JUNIOR
@@ -48,16 +48,17 @@ def notify_task_expiry():
:return: :return:
""" """
all_pending_tasks = JuniorTask.objects.filter( all_pending_tasks = JuniorTask.objects.filter(
junior__is_verified=True,
task_status__in=[PENDING, IN_PROGRESS], task_status__in=[PENDING, IN_PROGRESS],
due_date__range=[datetime.datetime.now().date(), due_date__range=[datetime.datetime.now().date(),
(datetime.datetime.now().date() + datetime.timedelta(days=1))]) (datetime.datetime.now().date() + datetime.timedelta(days=1))])
if pending_tasks := all_pending_tasks.filter(task_status=PENDING): if pending_tasks := all_pending_tasks.filter(task_status=PENDING):
for task in pending_tasks: for task in pending_tasks:
send_notification(PENDING_TASK_EXPIRING, None, None, task.junior.auth.id, send_notification(PENDING_TASK_EXPIRING, task.guardian.user_id, GUARDIAN, task.junior.auth_id,
{'task_id': task.id}) {'task_id': task.id})
if in_progress_tasks := all_pending_tasks.filter(task_status=IN_PROGRESS): if in_progress_tasks := all_pending_tasks.filter(task_status=IN_PROGRESS):
for task in in_progress_tasks: for task in in_progress_tasks:
send_notification(IN_PROGRESS_TASK_EXPIRING, task.junior.auth.id, JUNIOR, task.guardian.user.id, send_notification(IN_PROGRESS_TASK_EXPIRING, task.junior.auth_id, JUNIOR, task.guardian.user_id,
{'task_id': task.id}) {'task_id': task.id})
return True return True
@@ -80,7 +81,7 @@ def notify_top_junior():
prev_top_position = junior_points_qs.filter(position=1).first() prev_top_position = junior_points_qs.filter(position=1).first()
new_top_position = junior_points_qs.filter(rank=1).first() new_top_position = junior_points_qs.filter(rank=1).first()
if prev_top_position != new_top_position: if prev_top_position != new_top_position:
send_notification_multiple_user(TOP_JUNIOR, new_top_position.junior.auth.id, JUNIOR, send_notification_multiple_user(TOP_JUNIOR, new_top_position.junior.auth_id, JUNIOR,
{'points': new_top_position.total_points}) {'points': new_top_position.total_points})
for junior_point in junior_points_qs: for junior_point in junior_points_qs:
junior_point.position = junior_point.rank junior_point.position = junior_point.rank
Binary file not shown.
+6 -6
View File
@@ -243,8 +243,8 @@ class TaskSerializer(serializers.ModelSerializer):
task_data['junior'] = junior task_data['junior'] = junior
instance = JuniorTask.objects.create(**task_data) instance = JuniorTask.objects.create(**task_data)
tasks_created.append(instance) tasks_created.append(instance)
send_notification.delay(TASK_ASSIGNED, guardian.user.id, GUARDIAN, send_notification.delay(TASK_ASSIGNED, guardian.user_id, GUARDIAN,
junior.auth.id, {'task_id': instance.id}) junior.auth_id, {'task_id': instance.id})
return instance return instance
class GuardianDetailSerializer(serializers.ModelSerializer): class GuardianDetailSerializer(serializers.ModelSerializer):
@@ -443,8 +443,8 @@ 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.delay(TASK_APPROVED, instance.guardian.user.id, GUARDIAN, send_notification.delay(TASK_APPROVED, instance.guardian.user_id, GUARDIAN,
junior_details.auth.id, {'task_id': instance.id}) junior_details.auth_id, {'task_id': instance.id})
else: else:
# reject the task # reject the task
instance.task_status = str(NUMBER['three']) instance.task_status = str(NUMBER['three'])
@@ -452,8 +452,8 @@ 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.delay(TASK_REJECTED, instance.guardian.user.id, GUARDIAN, send_notification.delay(TASK_REJECTED, instance.guardian.user_id, GUARDIAN,
junior_details.auth.id, {'task_id': instance.id}) junior_details.auth_id, {'task_id': instance.id})
instance.save() instance.save()
junior_data.save() junior_data.save()
return junior_details return junior_details
+2 -2
View File
@@ -11,7 +11,7 @@ import tempfile
# Import date time module's function # Import date time module's function
from datetime import datetime, time from datetime import datetime, time
# import Number constant # import Number constant
from base.constants import NUMBER from base.constants import NUMBER, GUARDIAN
# Import Junior's model # Import Junior's model
from junior.models import Junior, JuniorPoints from junior.models import Junior, JuniorPoints
# Import guardian's model # Import guardian's model
@@ -117,7 +117,7 @@ def update_referral_points(referral_code, referral_code_used):
junior_query.total_points = junior_query.total_points + NUMBER['five'] junior_query.total_points = junior_query.total_points + NUMBER['five']
junior_query.referral_points = junior_query.referral_points + NUMBER['five'] junior_query.referral_points = junior_query.referral_points + NUMBER['five']
junior_query.save() junior_query.save()
send_notification.delay(REFERRAL_POINTS, None, None, junior_queryset.auth.id, {}) send_notification.delay(REFERRAL_POINTS, None, GUARDIAN, junior_queryset.auth_id, {})
+11 -6
View File
@@ -149,7 +149,7 @@ class TaskListAPIView(viewsets.ModelViewSet):
def get_queryset(self): def get_queryset(self):
queryset = JuniorTask.objects.filter(guardian__user=self.request.user queryset = JuniorTask.objects.filter(guardian__user=self.request.user
).select_related('junior', 'junior__auth' ).select_related('junior', 'junior__auth'
).order_by('due_date', 'created_at') ).order_by('-created_at')
queryset = self.filter_queryset(queryset) queryset = self.filter_queryset(queryset)
return queryset return queryset
@@ -304,9 +304,13 @@ class ApproveJuniorAPIView(viewsets.ModelViewSet):
"action":"1"} "action":"1"}
""" """
try: try:
guardian = Guardian.objects.filter(user__email=self.request.user).last() relation_obj = JuniorGuardianRelationship.objects.filter(
guardian__user__email=self.request.user,
junior__id=self.request.data.get('junior_id')
).select_related('guardian', 'junior').first()
guardian = relation_obj.guardian
# fetch junior query # fetch junior query
junior_queryset = Junior.objects.filter(id=self.request.data.get('junior_id')).last() junior_queryset = relation_obj.junior
if junior_queryset and (junior_queryset.is_deleted or not junior_queryset.is_active): if junior_queryset and (junior_queryset.is_deleted or not junior_queryset.is_active):
return custom_error_response(ERROR_CODE['2073'], response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE['2073'], response_status=status.HTTP_400_BAD_REQUEST)
# action 1 is use for approve and 2 for reject # action 1 is use for approve and 2 for reject
@@ -319,8 +323,8 @@ class ApproveJuniorAPIView(viewsets.ModelViewSet):
if serializer.is_valid(): if serializer.is_valid():
# save serializer # save serializer
serializer.save() serializer.save()
send_notification.delay(ASSOCIATE_APPROVED, guardian.user.id, GUARDIAN, send_notification.delay(ASSOCIATE_APPROVED, guardian.user_id, GUARDIAN,
junior_queryset.auth.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:
if junior_queryset.guardian_code and ('-' in junior_queryset.guardian_code): if junior_queryset.guardian_code and ('-' in junior_queryset.guardian_code):
@@ -331,7 +335,8 @@ class ApproveJuniorAPIView(viewsets.ModelViewSet):
junior_queryset.guardian_code.remove(guardian.guardian_code) junior_queryset.guardian_code.remove(guardian.guardian_code)
junior_queryset.guardian_code_status.pop(index) junior_queryset.guardian_code_status.pop(index)
junior_queryset.save() junior_queryset.save()
send_notification.delay(ASSOCIATE_REJECTED, guardian.user.id, GUARDIAN, junior_queryset.auth.id, {}) send_notification.delay(ASSOCIATE_REJECTED, guardian.user_id, GUARDIAN, junior_queryset.auth_id, {})
relation_obj.delete()
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)
+8 -8
View File
@@ -16,7 +16,7 @@ from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship, Juni
from guardian.tasks import generate_otp from guardian.tasks import generate_otp
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
from base.constants import (PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, NUMBER, JUN, ZOD, EXPIRED, from base.constants import (PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED, NUMBER, JUN, ZOD, EXPIRED,
GUARDIAN_CODE_STATUS, JUNIOR) GUARDIAN_CODE_STATUS, JUNIOR, GUARDIAN)
from guardian.models import Guardian, JuniorTask from guardian.models import Guardian, JuniorTask
from account.models import UserEmailOtp, UserNotification from account.models import UserEmailOtp, UserNotification
from junior.utils import junior_notification_email, junior_approval_mail, get_junior_leaderboard_rank from junior.utils import junior_notification_email, junior_approval_mail, get_junior_leaderboard_rank
@@ -107,8 +107,8 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
guardian_data = Guardian.objects.filter(guardian_code=guardian_code[0]).last() guardian_data = Guardian.objects.filter(guardian_code=guardian_code[0]).last()
if guardian_data: if guardian_data:
JuniorGuardianRelationship.objects.get_or_create(guardian=guardian_data, junior=junior) JuniorGuardianRelationship.objects.get_or_create(guardian=guardian_data, junior=junior)
send_notification.delay(ASSOCIATE_REQUEST, junior.auth.id, JUNIOR, guardian_data.user.id, {}) send_notification.delay(ASSOCIATE_REQUEST, junior.auth_id, JUNIOR, guardian_data.user_id, {})
junior_approval_mail.delay(user.email, user.first_name) # junior_approval_mail.delay(user.email, user.first_name) removed as per changes
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)
@@ -323,7 +323,7 @@ class AddJuniorSerializer(serializers.ModelSerializer):
"""Notification email""" """Notification email"""
junior_notification_email.delay(email, full_name, email, special_password) junior_notification_email.delay(email, full_name, email, special_password)
# push notification # push notification
send_notification.delay(ASSOCIATE_JUNIOR, None, None, junior_data.auth.id, {}) send_notification.delay(ASSOCIATE_JUNIOR, None, GUARDIAN, junior_data.auth_id, {})
return junior_data return junior_data
@@ -359,8 +359,8 @@ 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.delay(TASK_ACTION, instance.junior.auth.id, JUNIOR, send_notification.delay(TASK_ACTION, instance.junior.auth_id, JUNIOR,
instance.guardian.user.id, {'task_id': instance.id}) instance.guardian.user_id, {'task_id': instance.id})
return instance return instance
class JuniorPointsSerializer(serializers.ModelSerializer): class JuniorPointsSerializer(serializers.ModelSerializer):
@@ -466,8 +466,8 @@ 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) removed as per changes
send_notification.delay(ASSOCIATE_REQUEST, junior_data.auth.id, JUNIOR, guardian_data.user.id, {}) send_notification.delay(ASSOCIATE_REQUEST, junior_data.auth_id, JUNIOR, guardian_data.user_id, {})
return guardian_data return guardian_data
class StartTaskSerializer(serializers.ModelSerializer): class StartTaskSerializer(serializers.ModelSerializer):
+6 -5
View File
@@ -263,7 +263,7 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
if jun_data: if jun_data:
jun_data.relationship = str(self.request.data['relationship']) jun_data.relationship = str(self.request.data['relationship'])
jun_data.save() jun_data.save()
send_notification.delay(ASSOCIATE_EXISTING_JUNIOR, self.request.user.id, GUARDIAN, junior.auth.id, {}) send_notification.delay(ASSOCIATE_EXISTING_JUNIOR, guardian.user_id, GUARDIAN, junior.auth_id, {})
return True return True
@@ -362,7 +362,7 @@ class RemoveJuniorAPIView(views.APIView):
# save serializer # save serializer
serializer.save() serializer.save()
JuniorGuardianRelationship.objects.filter(guardian=guardian, junior=junior_queryset).delete() JuniorGuardianRelationship.objects.filter(guardian=guardian, junior=junior_queryset).delete()
send_notification.delay(REMOVE_JUNIOR, None, None, junior_queryset.auth.id, {}) send_notification.delay(REMOVE_JUNIOR, None, GUARDIAN, junior_queryset.auth_id, {})
return custom_response(SUCCESS_CODE['3022'], serializer.data, response_status=status.HTTP_200_OK) return custom_response(SUCCESS_CODE['3022'], serializer.data, response_status=status.HTTP_200_OK)
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
else: else:
@@ -383,7 +383,7 @@ class JuniorTaskListAPIView(viewsets.ModelViewSet):
def get_queryset(self): def get_queryset(self):
queryset = JuniorTask.objects.filter(junior__auth=self.request.user queryset = JuniorTask.objects.filter(junior__auth=self.request.user
).select_related('junior', 'junior__auth' ).select_related('junior', 'junior__auth'
).order_by('due_date', 'created_at') ).order_by('-created_at')
queryset = self.filter_queryset(queryset) queryset = self.filter_queryset(queryset)
return queryset return queryset
@@ -711,8 +711,9 @@ class CompleteArticleAPIView(views.APIView):
is_answer_correct=True).aggregate( is_answer_correct=True).aggregate(
total_earn_points=Sum('earn_points'))['total_earn_points'] total_earn_points=Sum('earn_points'))['total_earn_points']
data = {"total_earn_points":total_earn_points} data = {"total_earn_points":total_earn_points}
send_notification.delay(ARTICLE_REWARD_POINTS, None, None, if total_earn_points:
request.user.id, {'points': total_earn_points}) send_notification.delay(ARTICLE_REWARD_POINTS, None, GUARDIAN,
request.user.id, {'points': total_earn_points})
return custom_response(SUCCESS_CODE['3042'], data, response_status=status.HTTP_200_OK) return custom_response(SUCCESS_CODE['3042'], data, 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)
+1
View File
@@ -11,3 +11,4 @@ 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']
search_fields = ['notification_to']
+19
View File
@@ -22,79 +22,93 @@ ARTICLE_REWARD_POINTS = 17
REMOVE_JUNIOR = 18 REMOVE_JUNIOR = 18
TEST_NOTIFICATION = 99 TEST_NOTIFICATION = 99
# notification dictionary # notification dictionary
NOTIFICATION_DICT = { NOTIFICATION_DICT = {
REGISTRATION: { REGISTRATION: {
"notification_type": REGISTRATION,
"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."
}, },
# user will receive notification as soon junior # user will receive notification as soon junior
# sign up application using their guardian code for association # sign up application using their guardian code for association
ASSOCIATE_REQUEST: { ASSOCIATE_REQUEST: {
"notification_type": 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."
}, },
# Juniors will receive notification when # Juniors will receive notification when
# custodians reject their request for associate # custodians reject their request for associate
ASSOCIATE_REJECTED: { ASSOCIATE_REJECTED: {
"notification_type": ASSOCIATE_REJECTED,
"title": "Associate request rejected!", "title": "Associate request rejected!",
"body": "Your request to associate has been rejected by {from_user}." "body": "Your request to associate has been rejected by {from_user}."
}, },
# Juniors will receive notification when # Juniors will receive notification when
# custodians approve their request for associate # custodians approve their request for associate
ASSOCIATE_APPROVED: { ASSOCIATE_APPROVED: {
"notification_type": ASSOCIATE_APPROVED,
"title": "Associate request approved!", "title": "Associate request approved!",
"body": "Your request to associate has been approved by {from_user}." "body": "Your request to associate has been approved by {from_user}."
}, },
# Juniors will receive Notifications # Juniors will receive Notifications
# for every Points earned by referrals # for every Points earned by referrals
REFERRAL_POINTS: { REFERRAL_POINTS: {
"notification_type": REFERRAL_POINTS,
"title": "Earn Referral points!", "title": "Earn Referral points!",
"body": "You earn 5 points for referral." "body": "You earn 5 points for referral."
}, },
# Juniors will receive notification # Juniors will receive notification
# once any custodians add them in their account # once any custodians add them in their account
ASSOCIATE_JUNIOR: { ASSOCIATE_JUNIOR: {
"notification_type": ASSOCIATE_JUNIOR,
"title": "Profile already setup!", "title": "Profile already setup!",
"body": "Your guardian has already setup your profile." "body": "Your guardian has already setup your profile."
}, },
ASSOCIATE_EXISTING_JUNIOR: { ASSOCIATE_EXISTING_JUNIOR: {
"notification_type": ASSOCIATE_EXISTING_JUNIOR,
"title": "Associated to guardian", "title": "Associated to guardian",
"body": "Your are associated to your guardian {from_user}." "body": "Your are associated to your guardian {from_user}."
}, },
# Juniors will receive Notification # Juniors will receive Notification
# for every Task Assign by Custodians # for every Task Assign by Custodians
TASK_ASSIGNED: { TASK_ASSIGNED: {
"notification_type": 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."
}, },
# Guardian will receive notification as soon # Guardian will receive notification as soon
# as junior send task for approval # as junior send task for approval
TASK_ACTION: { TASK_ACTION: {
"notification_type": TASK_ACTION,
"title": "Task completion approval!", "title": "Task completion approval!",
"body": "{from_user} completed their task {task_name}." "body": "{from_user} completed their task {task_name}."
}, },
# Juniors will receive notification as soon # Juniors will receive notification as soon
# as their task is rejected by custodians # as their task is rejected by custodians
TASK_REJECTED: { TASK_REJECTED: {
"notification_type": 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 # Juniors will receive notification as soon as their task is approved by custodians
# and for every Points earned by Task completion # and for every Points earned by Task completion
TASK_APPROVED: { TASK_APPROVED: {
"notification_type": 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." "Also you earned 5 points for successful completion."
}, },
# Juniors will receive notification when their task end date about to end # Juniors will receive notification when their task end date about to end
PENDING_TASK_EXPIRING: { PENDING_TASK_EXPIRING: {
"notification_type": PENDING_TASK_EXPIRING,
"title": "Task expiring soon!", "title": "Task expiring soon!",
"body": "Your task {task_name} is expiring soon. Please complete it." "body": "Your task {task_name} is expiring soon. Please complete it."
}, },
# User will receive notification when their assigned task is about to end # User will receive notification when their assigned task is about to end
# and juniors have not performed any action # and juniors have not performed any action
IN_PROGRESS_TASK_EXPIRING: { IN_PROGRESS_TASK_EXPIRING: {
"notification_type": IN_PROGRESS_TASK_EXPIRING,
"title": "Task expiring soon!", "title": "Task expiring soon!",
"body": "{from_user} didn't take any action on assigned task {task_name} and it's expiring soon. " "body": "{from_user} didn't take any action on assigned task {task_name} and it's expiring soon. "
"Please assist to complete it." "Please assist to complete it."
@@ -102,27 +116,32 @@ NOTIFICATION_DICT = {
# Juniors will receive Notification # Juniors will receive Notification
# related to Leaderboard progress # related to Leaderboard progress
TOP_JUNIOR: { TOP_JUNIOR: {
"notification_type": TOP_JUNIOR,
"title": "Leaderboard topper!", "title": "Leaderboard topper!",
"body": "{from_user} is on top in leaderboard with {points} points." "body": "{from_user} is on top in leaderboard with {points} points."
}, },
# Juniors will receive notification # Juniors will receive notification
# when admin add any new financial learnings # when admin add any new financial learnings
NEW_ARTICLE_PUBLISHED: { NEW_ARTICLE_PUBLISHED: {
"notification_type": NEW_ARTICLE_PUBLISHED,
"title": "Time to read!", "title": "Time to read!",
"body": "A new article has been published." "body": "A new article has been published."
}, },
# Juniors will receive notification when they earn points by reading financial Learning # Juniors will receive notification when they earn points by reading financial Learning
ARTICLE_REWARD_POINTS: { ARTICLE_REWARD_POINTS: {
"notification_type": ARTICLE_REWARD_POINTS,
"title": "Article reward points!", "title": "Article reward points!",
"body": "You are rewarded with {points} points for reading article and answering questions. " "body": "You are rewarded with {points} points for reading article and answering questions. "
}, },
# Juniors will receive notification as soon as their custodians remove them from account # Juniors will receive notification as soon as their custodians remove them from account
REMOVE_JUNIOR: { REMOVE_JUNIOR: {
"notification_type": REMOVE_JUNIOR,
"title": "Disassociate by guardian!", "title": "Disassociate by guardian!",
"body": "Your guardian has disassociated you." "body": "Your guardian has disassociated you."
}, },
# Test notification # Test notification
TEST_NOTIFICATION: { TEST_NOTIFICATION: {
"notification_type": TEST_NOTIFICATION,
"title": "Test Notification", "title": "Test Notification",
"body": "This notification is for testing purpose from {from_user}." "body": "This notification is for testing purpose from {from_user}."
} }
@@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2023-09-29 07:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('notifications', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='notification',
name='updated_at',
field=models.DateTimeField(auto_now=True),
),
]
+1
View File
@@ -18,6 +18,7 @@ class Notification(models.Model):
data = models.JSONField(default=dict, blank=True, null=True) data = models.JSONField(default=dict, blank=True, null=True)
is_read = models.BooleanField(default=False) is_read = models.BooleanField(default=False)
created_at = models.DateTimeField(default=timezone.now) created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self): def __str__(self):
""" string representation """ """ string representation """
+1 -1
View File
@@ -36,7 +36,7 @@ class NotificationListSerializer(serializers.ModelSerializer):
class Meta(object): class Meta(object):
"""meta info""" """meta info"""
model = Notification model = Notification
fields = ['id', 'data', 'badge', 'is_read', 'created_at'] fields = ['id', 'notification_type', 'data', 'badge', 'is_read', 'updated_at']
@staticmethod @staticmethod
def get_badge(obj): def get_badge(obj):
+20 -2
View File
@@ -24,6 +24,7 @@ User = get_user_model()
def register_fcm_token(user_id, registration_id, device_id, device_type): def register_fcm_token(user_id, registration_id, device_id, device_type):
""" used to register the fcm device token""" """ used to register the fcm device token"""
FCMDevice.objects.filter(registration_id=registration_id).delete()
device, _ = FCMDevice.objects.update_or_create(user_id=user_id, device, _ = FCMDevice.objects.update_or_create(user_id=user_id,
defaults={'device_id': device_id, 'type': device_type, defaults={'device_id': device_id, 'type': device_type,
'active': True, 'active': True,
@@ -88,9 +89,14 @@ def get_notification_data(notification_type, from_user_id, from_user_type, to_us
push_data['body'] = push_data['body'].format(from_user=from_user_name, task_name=task_name, points=points) push_data['body'] = push_data['body'].format(from_user=from_user_name, task_name=task_name, points=points)
notification_data['body'] = notification_data['body'].format(from_user=from_user_name, notification_data['body'] = notification_data['body'].format(from_user=from_user_name,
task_name=task_name, points=points) task_name=task_name, points=points)
push_data['to_user_type'] = GUARDIAN if from_user_type == JUNIOR else JUNIOR
notification_data['to_user_type'] = GUARDIAN if from_user_type == JUNIOR else JUNIOR
notification_data['from_user'] = from_user_name notification_data['from_user'] = from_user_name
notification_data['from_user_image'] = from_user_image notification_data['from_user_image'] = from_user_image
notification_data.update(extra_data) notification_data.update(extra_data)
to_user = User.objects.filter(id=to_user_id).first() to_user = User.objects.filter(id=to_user_id).first()
return notification_data, push_data, from_user, to_user return notification_data, push_data, from_user, to_user
@@ -104,14 +110,25 @@ def send_notification(notification_type, from_user_id, from_user_type, to_user_i
notification_data, push_data, from_user, to_user = get_notification_data(notification_type, from_user_id, notification_data, push_data, from_user, to_user = get_notification_data(notification_type, from_user_id,
from_user_type, to_user_id, extra_data) from_user_type, to_user_id, extra_data)
user_notification_type = UserNotification.objects.filter(user=to_user).first() user_notification_type = UserNotification.objects.filter(user=to_user).first()
Notification.objects.create(notification_type=notification_type, notification_from=from_user,
notification_to=to_user, data=notification_data) # notification create method changed on 28sep as per changes required
task_id = extra_data['task_id'] if 'task_id' in extra_data else None
Notification.objects.update_or_create(data__has_key='task_id', data__task_id=task_id,
notification_from=from_user, notification_to=to_user,
defaults={
'notification_type': notification_type,
'notification_from': from_user,
'notification_to': to_user,
'data': notification_data
})
if user_notification_type and user_notification_type.push_notification: if user_notification_type and user_notification_type.push_notification:
send_push(to_user, push_data) send_push(to_user, push_data)
def send_push(user, data): def send_push(user, data):
""" used to send push notification to specific user """ """ used to send push notification to specific user """
data['notification_type'] = str(data['notification_type'])
user.fcmdevice_set.filter(active=True).send_message( user.fcmdevice_set.filter(active=True).send_message(
Message(notification=FirebaseNotification(data['title'], data['body']), data=data) Message(notification=FirebaseNotification(data['title'], data['body']), data=data)
) )
@@ -119,6 +136,7 @@ def send_push(user, data):
def send_multiple_push(queryset, data): def send_multiple_push(queryset, data):
""" used to send same notification to multiple users """ """ used to send same notification to multiple users """
data['notification_type'] = str(data['notification_type'])
FCMDevice.objects.filter(user__in=queryset, active=True).send_message( FCMDevice.objects.filter(user__in=queryset, active=True).send_message(
Message(notification=FirebaseNotification(data['title'], data['body']), data=data) Message(notification=FirebaseNotification(data['title'], data['body']), data=data)
) )
+16 -3
View File
@@ -33,7 +33,7 @@ class NotificationViewSet(viewsets.GenericViewSet):
:return: :return:
""" """
queryset = Notification.objects.filter(notification_to_id=request.auth.payload['user_id'] queryset = Notification.objects.filter(notification_to_id=request.auth.payload['user_id']
).select_related('notification_to').order_by('-id') ).select_related('notification_to').order_by('-updated_at', '-id')
paginator = CustomPageNumberPagination() paginator = CustomPageNumberPagination()
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)
@@ -58,8 +58,12 @@ class NotificationViewSet(viewsets.GenericViewSet):
""" """
notify_task_expiry() notify_task_expiry()
notify_top_junior() notify_top_junior()
send_notification(TEST_NOTIFICATION, None, None, request.auth.payload['user_id'], notification_type = request.query_params.get('type', TEST_NOTIFICATION)
from_user_type = request.query_params.get('from_user_type')
send_notification(int(notification_type), None, from_user_type, request.auth.payload['user_id'],
{}) {})
if notification_type and request.query_params.get('clear_all'):
Notification.objects.filter(notification_type=notification_type).delete()
return custom_response(SUCCESS_CODE["3000"]) return custom_response(SUCCESS_CODE["3000"])
@action(methods=['patch'], url_path='mark-as-read', url_name='mark-as-read', detail=False, @action(methods=['patch'], url_path='mark-as-read', url_name='mark-as-read', detail=False,
@@ -68,5 +72,14 @@ class NotificationViewSet(viewsets.GenericViewSet):
""" """
notification list notification list
""" """
Notification.objects.filter(id__in=request.data.get('id')).update(is_read=True)
if request.data.get('id'):
Notification.objects.filter(id__in=request.data.get('id')).update(is_read=True)
elif request.query_params.get('mark_all'):
Notification.objects.filter(notification_to_id=request.auth.payload['user_id']).update(is_read=True)
elif request.query_params.get('clear_all'):
Notification.objects.filter(notification_to_id=request.auth.payload['user_id']).delete()
return custom_response(SUCCESS_CODE['3039'], response_status=status.HTTP_200_OK) return custom_response(SUCCESS_CODE['3039'], response_status=status.HTTP_200_OK)
@@ -115,8 +115,6 @@ class UserCSVReportSerializer(serializers.ModelSerializer):
if profile := (obj.guardian_profile.all().first() or obj.junior_profile.all().first()): if profile := (obj.guardian_profile.all().first() or obj.junior_profile.all().first()):
return f"+{profile.country_code}{profile.phone}" \ return f"+{profile.country_code}{profile.phone}" \
if profile.country_code and profile.phone else profile.phone if profile.country_code and profile.phone else profile.phone
else:
return None
@staticmethod @staticmethod
def get_user_type(obj): def get_user_type(obj):
+2 -1
View File
@@ -357,8 +357,9 @@ class ArticleCardlistSerializer(serializers.ModelSerializer):
"""current page""" """current page"""
context_data = self.context.get('user') context_data = self.context.get('user')
data = JuniorArticle.objects.filter(junior__auth=context_data, article=obj.article).last() data = JuniorArticle.objects.filter(junior__auth=context_data, article=obj.article).last()
total_count = self.context.get('card_count')
if data: if data:
return data.current_card_page return data.current_card_page if data.current_card_page < total_count else data.current_card_page - 1
return NUMBER['zero'] return NUMBER['zero']
class Meta(object): class Meta(object):
@@ -50,8 +50,6 @@ class UserManagementListSerializer(serializers.ModelSerializer):
return profile.country_code if profile.country_code else None return profile.country_code if profile.country_code else None
elif profile := obj.junior_profile.all().first(): elif profile := obj.junior_profile.all().first():
return profile.country_code if profile.country_code else None return profile.country_code if profile.country_code else None
else:
return None
@staticmethod @staticmethod
def get_phone(obj): def get_phone(obj):
@@ -63,8 +61,6 @@ class UserManagementListSerializer(serializers.ModelSerializer):
return profile.phone if profile.phone else None return profile.phone if profile.phone else None
elif profile := obj.junior_profile.all().first(): elif profile := obj.junior_profile.all().first():
return profile.phone if profile.phone else None return profile.phone if profile.phone else None
else:
return None
@staticmethod @staticmethod
def get_user_type(obj): def get_user_type(obj):
@@ -76,8 +72,6 @@ class UserManagementListSerializer(serializers.ModelSerializer):
return dict(USER_TYPE).get('2') return dict(USER_TYPE).get('2')
elif obj.junior_profile.all().first(): elif obj.junior_profile.all().first():
return dict(USER_TYPE).get('1') return dict(USER_TYPE).get('1')
else:
return None
@staticmethod @staticmethod
def get_is_active(obj): def get_is_active(obj):
@@ -89,8 +83,6 @@ class UserManagementListSerializer(serializers.ModelSerializer):
return profile.is_active return profile.is_active
elif profile := obj.junior_profile.all().first(): elif profile := obj.junior_profile.all().first():
return profile.is_active return profile.is_active
else:
return obj.is_active
class GuardianSerializer(serializers.ModelSerializer): class GuardianSerializer(serializers.ModelSerializer):
@@ -292,5 +284,3 @@ class UserManagementDetailSerializer(serializers.ModelSerializer):
is_verified=True).select_related('user') is_verified=True).select_related('user')
serializer = GuardianSerializer(guardian, many=True) serializer = GuardianSerializer(guardian, many=True)
return serializer.data return serializer.data
else:
return None
+2 -1
View File
@@ -279,7 +279,8 @@ class ArticleCardListViewSet(viewsets.ModelViewSet):
try: try:
queryset = self.get_queryset() queryset = self.get_queryset()
# article card list # article card list
serializer = ArticleCardlistSerializer(queryset, context={"user": self.request.user}, many=True) serializer = ArticleCardlistSerializer(queryset, context={"user": self.request.user,
"card_count": queryset.count()}, 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)
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)
+9 -3
View File
@@ -120,17 +120,23 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin,
if user_type not in [GUARDIAN, JUNIOR]: if user_type not in [GUARDIAN, JUNIOR]:
return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST)
email_template = 'user_deactivate.email'
if user_type == GUARDIAN: if user_type == GUARDIAN:
obj = Guardian.objects.filter(user_id=kwargs['pk'], is_verified=True).select_related('user').first() obj = Guardian.objects.filter(user_id=kwargs['pk'], is_verified=True).select_related('user').first()
elif user_type == JUNIOR: elif user_type == JUNIOR:
obj = Junior.objects.filter(auth_id=kwargs['pk'], is_verified=True).select_related('auth').first() obj = Junior.objects.filter(auth_id=kwargs['pk'], is_verified=True).select_related('auth').first()
if not obj:
return custom_error_response(ERROR_CODE['2004'], status.HTTP_400_BAD_REQUEST)
if obj.is_active: if obj.is_active:
deactivate_email_template = 'user_deactivate.email'
obj.is_active = False obj.is_active = False
send_email([obj.user.email if user_type == GUARDIAN else obj.auth.email], email_template) send_email([obj.user.email if user_type == GUARDIAN else obj.auth.email],
deactivate_email_template)
else: else:
activate_email_template = 'user_activate.email'
obj.is_active = True obj.is_active = True
send_email([obj.user.email if user_type == GUARDIAN else obj.auth.email],
activate_email_template)
obj.save() obj.save()
return custom_response(SUCCESS_CODE['3038']) return custom_response(SUCCESS_CODE['3038'])