mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-25 13:49:40 +00:00
Compare commits
67 Commits
ZBKADM-73-
...
8fb627ec03
Author | SHA1 | Date | |
---|---|---|---|
8fb627ec03 | |||
c3aa31788f | |||
09aecc36b3 | |||
348c5946dd | |||
5603853896 | |||
82b7fe7000 | |||
92679061e2 | |||
67e4e96d85 | |||
df32e5ed37 | |||
e3796f2204 | |||
03f0a4c363 | |||
a3a4a8d091 | |||
772c0c89b5 | |||
d614d13136 | |||
93ce63b1d4 | |||
4f2b42dc08 | |||
5c05a988a5 | |||
2aff4e52f0 | |||
bdc92163c3 | |||
9abf549ed4 | |||
057c58b709 | |||
b1d8949b08 | |||
801bc45bc5 | |||
d1927b24ee | |||
012d93f70f | |||
a1f9f93654 | |||
652fe9e680 | |||
13665f4c9a | |||
bf5453c7b7 | |||
6e3166967e | |||
47a00f313a | |||
ad4d782e72 | |||
8050e70cf7 | |||
18a53e1c48 | |||
f1333491e0 | |||
bd7eddb275 | |||
4c34c2496b | |||
e121c92fb4 | |||
18143e0219 | |||
251a912948 | |||
f7bb83cebb | |||
994e9a270e | |||
32c35f8649 | |||
ea02d7f5bb | |||
648628d3ea | |||
6ba3d7d8db | |||
651405ddef | |||
3afd7fecf3 | |||
c484669a2d | |||
d1a4b86b09 | |||
a3c2b68a0d | |||
e157e98a17 | |||
a653518cfd | |||
af25dc4e82 | |||
eaf67b682f | |||
71bbef84aa | |||
085607128b | |||
fbdef7c0c4 | |||
535e2e7f56 | |||
de710c8a7b | |||
0a9dde2038 | |||
f11959d6bc | |||
1dec5ace3f | |||
3ecbc1d303 | |||
ca0041caa6 | |||
c800853e9b | |||
3a84b1ea75 |
@ -216,6 +216,7 @@ class GuardianSerializer(serializers.ModelSerializer):
|
||||
last_name = serializers.SerializerMethodField('get_last_name')
|
||||
auth_token = serializers.SerializerMethodField('get_auth_token')
|
||||
refresh_token = serializers.SerializerMethodField('get_refresh_token')
|
||||
sign_up = serializers.SerializerMethodField()
|
||||
|
||||
def get_auth_token(self, obj):
|
||||
refresh = RefreshToken.for_user(obj.user)
|
||||
@ -253,12 +254,16 @@ class GuardianSerializer(serializers.ModelSerializer):
|
||||
"""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):
|
||||
"""Meta info"""
|
||||
model = Guardian
|
||||
fields = ['id', 'auth_token', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code',
|
||||
'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):
|
||||
@ -269,6 +274,7 @@ class JuniorSerializer(serializers.ModelSerializer):
|
||||
last_name = serializers.SerializerMethodField('get_last_name')
|
||||
auth_token = serializers.SerializerMethodField('get_auth_token')
|
||||
refresh_token = serializers.SerializerMethodField('get_refresh_token')
|
||||
sign_up = serializers.SerializerMethodField()
|
||||
|
||||
def get_auth_token(self, obj):
|
||||
refresh = RefreshToken.for_user(obj.auth)
|
||||
@ -295,13 +301,16 @@ class JuniorSerializer(serializers.ModelSerializer):
|
||||
def get_last_name(self, obj):
|
||||
return obj.auth.last_name
|
||||
|
||||
def get_sign_up(self, obj):
|
||||
return True if self.context.get('sign_up', '') else False
|
||||
|
||||
class Meta(object):
|
||||
"""Meta info"""
|
||||
model = Junior
|
||||
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',
|
||||
'is_complete_profile', 'created_at', 'image', 'updated_at', 'user_type', 'country_name','is_invited',
|
||||
'is_deleted']
|
||||
'is_deleted', 'sign_up']
|
||||
|
||||
class EmailVerificationSerializer(serializers.ModelSerializer):
|
||||
"""Email verification serializer"""
|
||||
@ -373,17 +382,16 @@ class UpdateUserNotificationSerializer(serializers.ModelSerializer):
|
||||
fields = ['push_notification', 'email_notification', 'sms_notification']
|
||||
|
||||
def create(self, validated_data):
|
||||
instance = UserNotification.objects.filter(user=self.context).last()
|
||||
if instance:
|
||||
# change notification status
|
||||
instance.push_notification = validated_data.get('push_notification',instance.push_notification)
|
||||
instance.email_notification = validated_data.get('email_notification', instance.email_notification)
|
||||
instance.sms_notification = validated_data.get('sms_notification', instance.sms_notification)
|
||||
instance.save()
|
||||
else:
|
||||
instance = UserNotification.objects.create(user=self.context)
|
||||
instance, _ = UserNotification.objects.update_or_create(
|
||||
user=self.context,
|
||||
defaults={
|
||||
'push_notification': validated_data.get('push_notification'),
|
||||
'email_notification': validated_data.get('email_notification'),
|
||||
'sms_notification': validated_data.get('sms_notification', False),
|
||||
})
|
||||
return instance
|
||||
|
||||
|
||||
class UserPhoneOtpSerializer(serializers.ModelSerializer):
|
||||
"""User Phone serializers"""
|
||||
class Meta(object):
|
||||
|
22
account/templates/templated_email/user_activate.email
Normal file
22
account/templates/templated_email/user_activate.email
Normal file
@ -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 %}
|
@ -74,7 +74,7 @@ class GoogleLoginMixin(object):
|
||||
user_info = response.json()
|
||||
email = user_info['email']
|
||||
first_name = user_info['given_name']
|
||||
last_name = user_info['family_name']
|
||||
last_name = user_info['family_name'] if 'family_name' in user_info and user_info['family_name'] else user_info['given_name']
|
||||
profile_picture = user_info['picture']
|
||||
except Exception as e:
|
||||
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
||||
@ -90,6 +90,11 @@ class GoogleLoginMixin(object):
|
||||
ERROR_CODE["2071"],
|
||||
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)
|
||||
elif str(user_type) == '2':
|
||||
guardian_query = Guardian.objects.filter(user=user_data.last()).last()
|
||||
@ -98,12 +103,21 @@ class GoogleLoginMixin(object):
|
||||
ERROR_CODE["2070"],
|
||||
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)
|
||||
else:
|
||||
return custom_error_response(
|
||||
ERROR_CODE["2069"],
|
||||
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,
|
||||
response_status=status.HTTP_200_OK)
|
||||
|
||||
@ -115,7 +129,7 @@ class GoogleLoginMixin(object):
|
||||
junior_code=generate_code(JUN, 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()
|
||||
JuniorPoints.objects.create(junior=junior_query, position=position)
|
||||
elif str(user_type) == '2':
|
||||
@ -124,7 +138,7 @@ class GoogleLoginMixin(object):
|
||||
guardian_code=generate_code(GRD, user_obj.id),
|
||||
referral_code=generate_code(ZOD, user_obj.id)
|
||||
)
|
||||
serializer = GuardianSerializer(guardian_query)
|
||||
serializer = GuardianSerializer(guardian_query, context={'sign_up': True})
|
||||
else:
|
||||
user_obj.delete()
|
||||
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}
|
||||
if decoded_data.get("email"):
|
||||
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':
|
||||
junior_data = Junior.objects.filter(auth=user).last()
|
||||
if not junior_data:
|
||||
@ -192,6 +206,10 @@ class SigninWithApple(views.APIView):
|
||||
ERROR_CODE["2069"],
|
||||
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,
|
||||
response_status=status.HTTP_200_OK)
|
||||
|
||||
@ -202,7 +220,7 @@ class SigninWithApple(views.APIView):
|
||||
signup_method='3',
|
||||
junior_code=generate_code(JUN, 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()
|
||||
JuniorPoints.objects.create(junior=junior_query, position=position)
|
||||
elif str(user_type) == '2':
|
||||
@ -210,7 +228,7 @@ class SigninWithApple(views.APIView):
|
||||
signup_method='3',
|
||||
guardian_code=generate_code(GRD, user.id),
|
||||
referral_code=generate_code(ZOD, user.id))
|
||||
serializer = GuardianSerializer(guardian_query)
|
||||
serializer = GuardianSerializer(guardian_query, context={'sign_up': True})
|
||||
else:
|
||||
user.delete()
|
||||
return custom_error_response(
|
||||
@ -742,7 +760,7 @@ class ForceUpdateViewSet(GenericViewSet, mixins.CreateModelMixin):
|
||||
:param kwargs:
|
||||
:return: success message
|
||||
"""
|
||||
if ForceUpdate.objects.all().count() >= 2:
|
||||
if ForceUpdate.objects.all().count() >= 4:
|
||||
return custom_error_response(ERROR_CODE['2080'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||
obj_data = [ForceUpdate(**item) for item in request.data]
|
||||
try:
|
||||
|
@ -44,7 +44,7 @@ ERROR_CODE = {
|
||||
"2018": "Attached File not found",
|
||||
"2019": "Invalid Referral code",
|
||||
"2020": "Enter valid mobile number",
|
||||
"2021": "Already register",
|
||||
"2021": "User registered",
|
||||
"2022": "Invalid Guardian code",
|
||||
"2023": "Invalid user",
|
||||
# email not verified
|
||||
@ -96,8 +96,8 @@ ERROR_CODE = {
|
||||
"2067": "Action not allowed. User type missing.",
|
||||
"2068": "No guardian associated with this junior",
|
||||
"2069": "Invalid user type",
|
||||
"2070": "You do not find as a guardian",
|
||||
"2071": "You do not find as a junior",
|
||||
"2070": "You are not registered as a guardian in our system. Please try again as junior.",
|
||||
"2071": "You are not registered as a junior in our system. Please try again as guardian.",
|
||||
"2072": "You can not approve or reject this task because junior does not exist in the system",
|
||||
"2073": "You can not approve or reject this junior because junior does not exist in the system",
|
||||
"2074": "You can not complete this task because you does not exist in the system",
|
||||
|
@ -13,7 +13,7 @@ from django.db.models import F, Window
|
||||
from django.db.models.functions.window import Rank
|
||||
|
||||
# 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 junior.models import JuniorPoints
|
||||
from notifications.constants import PENDING_TASK_EXPIRING, IN_PROGRESS_TASK_EXPIRING, NOTIFICATION_DICT, TOP_JUNIOR
|
||||
@ -48,16 +48,17 @@ def notify_task_expiry():
|
||||
:return:
|
||||
"""
|
||||
all_pending_tasks = JuniorTask.objects.filter(
|
||||
junior__is_verified=True,
|
||||
task_status__in=[PENDING, IN_PROGRESS],
|
||||
due_date__range=[datetime.datetime.now().date(),
|
||||
(datetime.datetime.now().date() + datetime.timedelta(days=1))])
|
||||
if pending_tasks := all_pending_tasks.filter(task_status=PENDING):
|
||||
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})
|
||||
if in_progress_tasks := all_pending_tasks.filter(task_status=IN_PROGRESS):
|
||||
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})
|
||||
return True
|
||||
|
||||
@ -80,7 +81,7 @@ def notify_top_junior():
|
||||
prev_top_position = junior_points_qs.filter(position=1).first()
|
||||
new_top_position = junior_points_qs.filter(rank=1).first()
|
||||
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})
|
||||
for junior_point in junior_points_qs:
|
||||
junior_point.position = junior_point.rank
|
||||
|
Binary file not shown.
112
fixtures/faq.json
Normal file
112
fixtures/faq.json
Normal file
@ -0,0 +1,112 @@
|
||||
[
|
||||
{
|
||||
"model": "junior.faq",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"question": "What is ZOD ?",
|
||||
"description": "We are a future neobank for under 18. We aim to provide children with the ability to use debit cards under the watchfull eye of their parents.",
|
||||
"status": 1,
|
||||
"created_at": "2023-11-08T12:32:55.291Z",
|
||||
"updated_at": "2023-11-08T12:32:55.291Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "junior.faq",
|
||||
"pk": 2,
|
||||
"fields": {
|
||||
"question": "What is financial literacy ?",
|
||||
"description": "",
|
||||
"status": 2,
|
||||
"created_at": "2023-11-08T12:32:55.291Z",
|
||||
"updated_at": "2023-11-08T12:32:55.291Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "junior.faq",
|
||||
"pk": 3,
|
||||
"fields": {
|
||||
"question": "How can we win with Zod ?",
|
||||
"description": "",
|
||||
"status": 2,
|
||||
"created_at": "2023-11-08T12:32:55.291Z",
|
||||
"updated_at": "2023-11-08T12:32:55.291Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "junior.faq",
|
||||
"pk": 4,
|
||||
"fields": {
|
||||
"question": "What is a budget ?",
|
||||
"description": "",
|
||||
"status": 2,
|
||||
"created_at": "2023-11-08T12:32:55.291Z",
|
||||
"updated_at": "2023-11-08T12:32:55.291Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "junior.faq",
|
||||
"pk": 5,
|
||||
"fields": {
|
||||
"question": "What is the difference between stocks and bonds ?",
|
||||
"description": "",
|
||||
"status": 2,
|
||||
"created_at": "2023-11-08T12:32:55.291Z",
|
||||
"updated_at": "2023-11-08T12:32:55.291Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "junior.faq",
|
||||
"pk": 6,
|
||||
"fields": {
|
||||
"question": "What is compound interest ?",
|
||||
"description": "",
|
||||
"status": 2,
|
||||
"created_at": "2023-11-08T12:32:55.291Z",
|
||||
"updated_at": "2023-11-08T12:32:55.291Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "junior.faq",
|
||||
"pk": 7,
|
||||
"fields": {
|
||||
"question": "What is diversification ?",
|
||||
"description": "",
|
||||
"status": 2,
|
||||
"created_at": "2023-11-08T12:32:55.291Z",
|
||||
"updated_at": "2023-11-08T12:32:55.291Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "junior.faq",
|
||||
"pk": 8,
|
||||
"fields": {
|
||||
"question": "What is a 401(k) ?",
|
||||
"description": "",
|
||||
"status": 2,
|
||||
"created_at": "2023-11-08T12:32:55.291Z",
|
||||
"updated_at": "2023-11-08T12:32:55.291Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "junior.faq",
|
||||
"pk": 9,
|
||||
"fields": {
|
||||
"question": "What is an emergency fund ?",
|
||||
"description": "",
|
||||
"status": 2,
|
||||
"created_at": "2023-11-08T12:32:55.291Z",
|
||||
"updated_at": "2023-11-08T12:32:55.291Z"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "junior.faq",
|
||||
"pk": 10,
|
||||
"fields": {
|
||||
"question": "What is a mortgage ?",
|
||||
"description": "",
|
||||
"status": 2,
|
||||
"created_at": "2023-11-08T12:32:55.291Z",
|
||||
"updated_at": "2023-11-08T12:32:55.291Z"
|
||||
}
|
||||
}
|
||||
]
|
@ -243,8 +243,8 @@ class TaskSerializer(serializers.ModelSerializer):
|
||||
task_data['junior'] = junior
|
||||
instance = JuniorTask.objects.create(**task_data)
|
||||
tasks_created.append(instance)
|
||||
send_notification.delay(TASK_ASSIGNED, guardian.user.id, GUARDIAN,
|
||||
junior.auth.id, {'task_id': instance.id})
|
||||
send_notification.delay(TASK_ASSIGNED, guardian.user_id, GUARDIAN,
|
||||
junior.auth_id, {'task_id': instance.id})
|
||||
return instance
|
||||
|
||||
class GuardianDetailSerializer(serializers.ModelSerializer):
|
||||
@ -443,8 +443,8 @@ class ApproveTaskSerializer(serializers.ModelSerializer):
|
||||
# update complete time of task
|
||||
# instance.completed_on = real_time()
|
||||
instance.completed_on = timezone.now().astimezone(pytz.utc)
|
||||
send_notification.delay(TASK_APPROVED, instance.guardian.user.id, GUARDIAN,
|
||||
junior_details.auth.id, {'task_id': instance.id})
|
||||
send_notification.delay(TASK_APPROVED, instance.guardian.user_id, GUARDIAN,
|
||||
junior_details.auth_id, {'task_id': instance.id})
|
||||
else:
|
||||
# reject the task
|
||||
instance.task_status = str(NUMBER['three'])
|
||||
@ -452,8 +452,8 @@ class ApproveTaskSerializer(serializers.ModelSerializer):
|
||||
# update reject time of task
|
||||
# instance.rejected_on = real_time()
|
||||
instance.rejected_on = timezone.now().astimezone(pytz.utc)
|
||||
send_notification.delay(TASK_REJECTED, instance.guardian.user.id, GUARDIAN,
|
||||
junior_details.auth.id, {'task_id': instance.id})
|
||||
send_notification.delay(TASK_REJECTED, instance.guardian.user_id, GUARDIAN,
|
||||
junior_details.auth_id, {'task_id': instance.id})
|
||||
instance.save()
|
||||
junior_data.save()
|
||||
return junior_details
|
||||
|
@ -11,7 +11,7 @@ import tempfile
|
||||
# Import date time module's function
|
||||
from datetime import datetime, time
|
||||
# import Number constant
|
||||
from base.constants import NUMBER
|
||||
from base.constants import NUMBER, GUARDIAN
|
||||
# Import Junior's model
|
||||
from junior.models import Junior, JuniorPoints
|
||||
# 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.referral_points = junior_query.referral_points + NUMBER['five']
|
||||
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, {})
|
||||
|
||||
|
||||
|
||||
|
@ -149,7 +149,7 @@ class TaskListAPIView(viewsets.ModelViewSet):
|
||||
def get_queryset(self):
|
||||
queryset = JuniorTask.objects.filter(guardian__user=self.request.user
|
||||
).select_related('junior', 'junior__auth'
|
||||
).order_by('due_date', 'created_at')
|
||||
).order_by('-created_at')
|
||||
|
||||
queryset = self.filter_queryset(queryset)
|
||||
return queryset
|
||||
@ -304,9 +304,13 @@ class ApproveJuniorAPIView(viewsets.ModelViewSet):
|
||||
"action":"1"}
|
||||
"""
|
||||
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
|
||||
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):
|
||||
return custom_error_response(ERROR_CODE['2073'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||
# action 1 is use for approve and 2 for reject
|
||||
@ -319,8 +323,8 @@ class ApproveJuniorAPIView(viewsets.ModelViewSet):
|
||||
if serializer.is_valid():
|
||||
# save serializer
|
||||
serializer.save()
|
||||
send_notification.delay(ASSOCIATE_APPROVED, guardian.user.id, GUARDIAN,
|
||||
junior_queryset.auth.id, {})
|
||||
send_notification.delay(ASSOCIATE_APPROVED, guardian.user_id, GUARDIAN,
|
||||
junior_queryset.auth_id, {})
|
||||
return custom_response(SUCCESS_CODE['3023'], serializer.data, response_status=status.HTTP_200_OK)
|
||||
else:
|
||||
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_status.pop(index)
|
||||
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)
|
||||
except Exception as e:
|
||||
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
||||
|
@ -16,7 +16,7 @@ from junior.models import Junior, JuniorPoints, JuniorGuardianRelationship, Juni
|
||||
from guardian.tasks import generate_otp
|
||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||
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 account.models import UserEmailOtp, UserNotification
|
||||
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()
|
||||
if guardian_data:
|
||||
JuniorGuardianRelationship.objects.get_or_create(guardian=guardian_data, junior=junior)
|
||||
send_notification.delay(ASSOCIATE_REQUEST, junior.auth.id, JUNIOR, guardian_data.user.id, {})
|
||||
junior_approval_mail.delay(user.email, user.first_name)
|
||||
send_notification.delay(ASSOCIATE_REQUEST, junior.auth_id, JUNIOR, guardian_data.user_id, {})
|
||||
# junior_approval_mail.delay(user.email, user.first_name) removed as per changes
|
||||
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)
|
||||
@ -323,7 +323,7 @@ class AddJuniorSerializer(serializers.ModelSerializer):
|
||||
"""Notification email"""
|
||||
junior_notification_email.delay(email, full_name, email, special_password)
|
||||
# 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
|
||||
|
||||
|
||||
@ -359,8 +359,8 @@ class CompleteTaskSerializer(serializers.ModelSerializer):
|
||||
instance.task_status = str(NUMBER['four'])
|
||||
instance.is_approved = False
|
||||
instance.save()
|
||||
send_notification.delay(TASK_ACTION, instance.junior.auth.id, JUNIOR,
|
||||
instance.guardian.user.id, {'task_id': instance.id})
|
||||
send_notification.delay(TASK_ACTION, instance.junior.auth_id, JUNIOR,
|
||||
instance.guardian.user_id, {'task_id': instance.id})
|
||||
return instance
|
||||
|
||||
class JuniorPointsSerializer(serializers.ModelSerializer):
|
||||
@ -466,8 +466,8 @@ class AddGuardianSerializer(serializers.ModelSerializer):
|
||||
|
||||
"""Notification email"""
|
||||
junior_notification_email(email, full_name, email, password)
|
||||
junior_approval_mail.delay(email, full_name)
|
||||
send_notification.delay(ASSOCIATE_REQUEST, junior_data.auth.id, JUNIOR, guardian_data.user.id, {})
|
||||
# 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, {})
|
||||
return guardian_data
|
||||
|
||||
class StartTaskSerializer(serializers.ModelSerializer):
|
||||
|
@ -19,6 +19,7 @@ from base.pagination import CustomPageNumberPagination
|
||||
"""Django app import"""
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
from drf_yasg import openapi
|
||||
from django.core.management import call_command
|
||||
from drf_yasg.views import get_schema_view
|
||||
# Import guardian's model,
|
||||
# Import junior's model,
|
||||
@ -263,7 +264,7 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
|
||||
if jun_data:
|
||||
jun_data.relationship = str(self.request.data['relationship'])
|
||||
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
|
||||
|
||||
|
||||
@ -362,7 +363,7 @@ class RemoveJuniorAPIView(views.APIView):
|
||||
# save serializer
|
||||
serializer.save()
|
||||
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_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
||||
else:
|
||||
@ -383,7 +384,7 @@ class JuniorTaskListAPIView(viewsets.ModelViewSet):
|
||||
def get_queryset(self):
|
||||
queryset = JuniorTask.objects.filter(junior__auth=self.request.user
|
||||
).select_related('junior', 'junior__auth'
|
||||
).order_by('due_date', 'created_at')
|
||||
).order_by('-created_at')
|
||||
|
||||
queryset = self.filter_queryset(queryset)
|
||||
return queryset
|
||||
@ -711,8 +712,9 @@ class CompleteArticleAPIView(views.APIView):
|
||||
is_answer_correct=True).aggregate(
|
||||
total_earn_points=Sum('earn_points'))['total_earn_points']
|
||||
data = {"total_earn_points":total_earn_points}
|
||||
send_notification.delay(ARTICLE_REWARD_POINTS, None, None,
|
||||
request.user.id, {'points': total_earn_points})
|
||||
if 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)
|
||||
except Exception as e:
|
||||
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
||||
@ -812,7 +814,7 @@ class FAQViewSet(GenericViewSet, mixins.CreateModelMixin,
|
||||
http_method_names = ['get', 'post']
|
||||
|
||||
def get_queryset(self):
|
||||
return FAQ.objects.all()
|
||||
return FAQ.objects.filter(status=1).order_by('id')
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
"""
|
||||
@ -822,6 +824,10 @@ class FAQViewSet(GenericViewSet, mixins.CreateModelMixin,
|
||||
:param kwargs:
|
||||
:return: success message
|
||||
"""
|
||||
load_fixture = request.query_params.get('load_fixture')
|
||||
if load_fixture:
|
||||
call_command('loaddata', 'fixtures/faq.json')
|
||||
return custom_response(SUCCESS_CODE["3045"], response_status=status.HTTP_200_OK)
|
||||
obj_data = [FAQ(**item) for item in request.data]
|
||||
try:
|
||||
FAQ.objects.bulk_create(obj_data)
|
||||
|
@ -11,3 +11,4 @@ class NotificationAdmin(admin.ModelAdmin):
|
||||
"""Notification Admin"""
|
||||
list_display = ['id', 'notification_type', 'notification_to', 'data', 'is_read']
|
||||
list_filter = ['notification_type']
|
||||
search_fields = ['notification_to']
|
||||
|
@ -22,79 +22,93 @@ ARTICLE_REWARD_POINTS = 17
|
||||
REMOVE_JUNIOR = 18
|
||||
|
||||
TEST_NOTIFICATION = 99
|
||||
|
||||
# notification dictionary
|
||||
NOTIFICATION_DICT = {
|
||||
REGISTRATION: {
|
||||
"notification_type": REGISTRATION,
|
||||
"title": "Successfully registered!",
|
||||
"body": "You have registered successfully. Now login and complete your profile."
|
||||
},
|
||||
# user will receive notification as soon junior
|
||||
# sign up application using their guardian code for association
|
||||
ASSOCIATE_REQUEST: {
|
||||
"notification_type": ASSOCIATE_REQUEST,
|
||||
"title": "Associate request!",
|
||||
"body": "You have request from {from_user} to associate with you."
|
||||
},
|
||||
# Juniors will receive notification when
|
||||
# custodians reject their request for associate
|
||||
ASSOCIATE_REJECTED: {
|
||||
"notification_type": ASSOCIATE_REJECTED,
|
||||
"title": "Associate request rejected!",
|
||||
"body": "Your request to associate has been rejected by {from_user}."
|
||||
},
|
||||
# Juniors will receive notification when
|
||||
# custodians approve their request for associate
|
||||
ASSOCIATE_APPROVED: {
|
||||
"notification_type": 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: {
|
||||
"notification_type": 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
|
||||
ASSOCIATE_JUNIOR: {
|
||||
"notification_type": ASSOCIATE_JUNIOR,
|
||||
"title": "Profile already setup!",
|
||||
"body": "Your guardian has already setup your profile."
|
||||
},
|
||||
ASSOCIATE_EXISTING_JUNIOR: {
|
||||
"notification_type": ASSOCIATE_EXISTING_JUNIOR,
|
||||
"title": "Associated to guardian",
|
||||
"body": "Your are associated to your guardian {from_user}."
|
||||
},
|
||||
# Juniors will receive Notification
|
||||
# for every Task Assign by Custodians
|
||||
TASK_ASSIGNED: {
|
||||
"notification_type": TASK_ASSIGNED,
|
||||
"title": "New task assigned!",
|
||||
"body": "{from_user} has assigned you a new task."
|
||||
},
|
||||
# Guardian will receive notification as soon
|
||||
# as junior send task for approval
|
||||
TASK_ACTION: {
|
||||
"notification_type": TASK_ACTION,
|
||||
"title": "Task completion approval!",
|
||||
"body": "{from_user} completed their task {task_name}."
|
||||
},
|
||||
# Juniors will receive notification as soon
|
||||
# as their task is rejected by custodians
|
||||
TASK_REJECTED: {
|
||||
"notification_type": 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: {
|
||||
"notification_type": TASK_APPROVED,
|
||||
"title": "Task completion approved!",
|
||||
"body": "Your task completion request has been approved by {from_user}. "
|
||||
"Also you earned 5 points for successful completion."
|
||||
},
|
||||
# Juniors will receive notification when their task end date about to end
|
||||
PENDING_TASK_EXPIRING: {
|
||||
"notification_type": PENDING_TASK_EXPIRING,
|
||||
"title": "Task expiring soon!",
|
||||
"body": "Your task {task_name} is expiring soon. Please complete it."
|
||||
},
|
||||
# User will receive notification when their assigned task is about to end
|
||||
# and juniors have not performed any action
|
||||
IN_PROGRESS_TASK_EXPIRING: {
|
||||
"notification_type": IN_PROGRESS_TASK_EXPIRING,
|
||||
"title": "Task 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."
|
||||
@ -102,27 +116,32 @@ NOTIFICATION_DICT = {
|
||||
# Juniors will receive Notification
|
||||
# related to Leaderboard progress
|
||||
TOP_JUNIOR: {
|
||||
"notification_type": TOP_JUNIOR,
|
||||
"title": "Leaderboard topper!",
|
||||
"body": "{from_user} is on top in leaderboard with {points} points."
|
||||
},
|
||||
# Juniors will receive notification
|
||||
# when admin add any new financial learnings
|
||||
NEW_ARTICLE_PUBLISHED: {
|
||||
"notification_type": NEW_ARTICLE_PUBLISHED,
|
||||
"title": "Time to read!",
|
||||
"body": "A new article has been published."
|
||||
},
|
||||
# Juniors will receive notification when they earn points by reading financial Learning
|
||||
ARTICLE_REWARD_POINTS: {
|
||||
"notification_type": ARTICLE_REWARD_POINTS,
|
||||
"title": "Article reward points!",
|
||||
"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
|
||||
REMOVE_JUNIOR: {
|
||||
"notification_type": REMOVE_JUNIOR,
|
||||
"title": "Disassociate by guardian!",
|
||||
"body": "Your guardian has disassociated you."
|
||||
},
|
||||
# Test notification
|
||||
TEST_NOTIFICATION: {
|
||||
"notification_type": TEST_NOTIFICATION,
|
||||
"title": "Test Notification",
|
||||
"body": "This notification is for testing purpose from {from_user}."
|
||||
}
|
||||
|
18
notifications/migrations/0002_notification_updated_at.py
Normal file
18
notifications/migrations/0002_notification_updated_at.py
Normal file
@ -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),
|
||||
),
|
||||
]
|
@ -18,6 +18,7 @@ class Notification(models.Model):
|
||||
data = models.JSONField(default=dict, blank=True, null=True)
|
||||
is_read = models.BooleanField(default=False)
|
||||
created_at = models.DateTimeField(default=timezone.now)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
def __str__(self):
|
||||
""" string representation """
|
||||
|
@ -36,7 +36,7 @@ class NotificationListSerializer(serializers.ModelSerializer):
|
||||
class Meta(object):
|
||||
"""meta info"""
|
||||
model = Notification
|
||||
fields = ['id', 'data', 'badge', 'is_read', 'created_at']
|
||||
fields = ['id', 'notification_type', 'data', 'badge', 'is_read', 'updated_at']
|
||||
|
||||
@staticmethod
|
||||
def get_badge(obj):
|
||||
|
@ -24,6 +24,7 @@ User = get_user_model()
|
||||
|
||||
def register_fcm_token(user_id, registration_id, device_id, device_type):
|
||||
""" 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,
|
||||
defaults={'device_id': device_id, 'type': device_type,
|
||||
'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)
|
||||
notification_data['body'] = notification_data['body'].format(from_user=from_user_name,
|
||||
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_image'] = from_user_image
|
||||
|
||||
|
||||
notification_data.update(extra_data)
|
||||
to_user = User.objects.filter(id=to_user_id).first()
|
||||
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,
|
||||
from_user_type, to_user_id, extra_data)
|
||||
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:
|
||||
send_push(to_user, push_data)
|
||||
|
||||
|
||||
def send_push(user, data):
|
||||
""" used to send push notification to specific user """
|
||||
data['notification_type'] = str(data['notification_type'])
|
||||
user.fcmdevice_set.filter(active=True).send_message(
|
||||
Message(notification=FirebaseNotification(data['title'], data['body']), data=data)
|
||||
)
|
||||
@ -119,6 +136,7 @@ def send_push(user, data):
|
||||
|
||||
def send_multiple_push(queryset, data):
|
||||
""" 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(
|
||||
Message(notification=FirebaseNotification(data['title'], data['body']), data=data)
|
||||
)
|
||||
|
@ -33,7 +33,7 @@ class NotificationViewSet(viewsets.GenericViewSet):
|
||||
:return:
|
||||
"""
|
||||
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()
|
||||
paginated_queryset = paginator.paginate_queryset(queryset, request)
|
||||
serializer = self.serializer_class(paginated_queryset, many=True)
|
||||
@ -58,8 +58,12 @@ class NotificationViewSet(viewsets.GenericViewSet):
|
||||
"""
|
||||
notify_task_expiry()
|
||||
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"])
|
||||
|
||||
@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.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)
|
||||
|
@ -115,8 +115,6 @@ class UserCSVReportSerializer(serializers.ModelSerializer):
|
||||
if profile := (obj.guardian_profile.all().first() or obj.junior_profile.all().first()):
|
||||
return f"+{profile.country_code}{profile.phone}" \
|
||||
if profile.country_code and profile.phone else profile.phone
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_user_type(obj):
|
||||
|
@ -357,8 +357,9 @@ class ArticleCardlistSerializer(serializers.ModelSerializer):
|
||||
"""current page"""
|
||||
context_data = self.context.get('user')
|
||||
data = JuniorArticle.objects.filter(junior__auth=context_data, article=obj.article).last()
|
||||
total_count = self.context.get('card_count')
|
||||
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']
|
||||
|
||||
class Meta(object):
|
||||
|
@ -50,8 +50,6 @@ class UserManagementListSerializer(serializers.ModelSerializer):
|
||||
return profile.country_code if profile.country_code else None
|
||||
elif profile := obj.junior_profile.all().first():
|
||||
return profile.country_code if profile.country_code else None
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_phone(obj):
|
||||
@ -63,8 +61,6 @@ class UserManagementListSerializer(serializers.ModelSerializer):
|
||||
return profile.phone if profile.phone else None
|
||||
elif profile := obj.junior_profile.all().first():
|
||||
return profile.phone if profile.phone else None
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_user_type(obj):
|
||||
@ -76,8 +72,6 @@ class UserManagementListSerializer(serializers.ModelSerializer):
|
||||
return dict(USER_TYPE).get('2')
|
||||
elif obj.junior_profile.all().first():
|
||||
return dict(USER_TYPE).get('1')
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_is_active(obj):
|
||||
@ -89,8 +83,6 @@ class UserManagementListSerializer(serializers.ModelSerializer):
|
||||
return profile.is_active
|
||||
elif profile := obj.junior_profile.all().first():
|
||||
return profile.is_active
|
||||
else:
|
||||
return obj.is_active
|
||||
|
||||
|
||||
class GuardianSerializer(serializers.ModelSerializer):
|
||||
@ -292,5 +284,3 @@ class UserManagementDetailSerializer(serializers.ModelSerializer):
|
||||
is_verified=True).select_related('user')
|
||||
serializer = GuardianSerializer(guardian, many=True)
|
||||
return serializer.data
|
||||
else:
|
||||
return None
|
||||
|
@ -279,7 +279,8 @@ class ArticleCardListViewSet(viewsets.ModelViewSet):
|
||||
try:
|
||||
queryset = self.get_queryset()
|
||||
# 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)
|
||||
except Exception as e:
|
||||
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
|
||||
|
@ -120,17 +120,23 @@ class UserManagementViewSet(GenericViewSet, mixins.ListModelMixin,
|
||||
if user_type not in [GUARDIAN, JUNIOR]:
|
||||
return custom_error_response(ERROR_CODE['2067'], status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
email_template = 'user_deactivate.email'
|
||||
|
||||
if user_type == GUARDIAN:
|
||||
obj = Guardian.objects.filter(user_id=kwargs['pk'], is_verified=True).select_related('user').first()
|
||||
elif user_type == JUNIOR:
|
||||
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:
|
||||
deactivate_email_template = 'user_deactivate.email'
|
||||
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:
|
||||
activate_email_template = 'user_activate.email'
|
||||
obj.is_active = True
|
||||
send_email([obj.user.email if user_type == GUARDIAN else obj.auth.email],
|
||||
activate_email_template)
|
||||
obj.save()
|
||||
return custom_response(SUCCESS_CODE['3038'])
|
||||
|
@ -56,7 +56,14 @@ if ENV in ['dev', 'qa', 'stage']:
|
||||
# Add more trusted origins as needed
|
||||
]
|
||||
if ENV == "prod":
|
||||
CORS_ALLOWED_ORIGINS = []
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
# backend base url
|
||||
"https://prod-api.zodbank.com",
|
||||
|
||||
# frontend url
|
||||
"https://web.zodbank.com",
|
||||
# Add more trusted origins as needed
|
||||
]
|
||||
|
||||
# allow all host
|
||||
ALLOWED_HOSTS = ['*']
|
||||
@ -138,9 +145,10 @@ REST_FRAMEWORK = {
|
||||
# define jwt token
|
||||
SIMPLE_JWT = {
|
||||
'ACCESS_TOKEN_LIFETIME': timedelta(hours=2, minutes=59, seconds=59, microseconds=999999),
|
||||
'REFRESH_TOKEN_LIFETIME': timedelta(hours=71, minutes=59, seconds=59, microseconds=999999),
|
||||
'REFRESH_TOKEN_LIFETIME': timedelta(days=364, hours=23, minutes=59, seconds=59, microseconds=999999),
|
||||
|
||||
}
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
||||
DATABASES = {
|
||||
@ -200,7 +208,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
# database query logs settings
|
||||
# Allows us to check db hits
|
||||
# useful to optimize db query and hit
|
||||
LOGGING = {
|
||||
LOGGING1 = {
|
||||
"version": 1,
|
||||
"filters": {
|
||||
"require_debug_true": {
|
||||
|
Reference in New Issue
Block a user