mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-07-16 02:16:16 +00:00
Merge branch 'dev' into ZBKADM-72-minor-changes
This commit is contained in:
@ -104,10 +104,12 @@ class ResetPasswordSerializer(serializers.Serializer):
|
|||||||
return user_opt_details
|
return user_opt_details
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
class ChangePasswordSerializer(serializers.Serializer):
|
class ChangePasswordSerializer(serializers.Serializer):
|
||||||
"""Update Password after verification"""
|
"""Update Password after verification"""
|
||||||
current_password = serializers.CharField(max_length=100)
|
current_password = serializers.CharField(max_length=100, required=True)
|
||||||
new_password = serializers.CharField(required=True)
|
new_password = serializers.CharField(required=True)
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
"""Meta info"""
|
"""Meta info"""
|
||||||
model = User
|
model = User
|
||||||
@ -118,25 +120,36 @@ class ChangePasswordSerializer(serializers.Serializer):
|
|||||||
if self.context.password not in ('', None) and user.check_password(value):
|
if self.context.password not in ('', None) and user.check_password(value):
|
||||||
return value
|
return value
|
||||||
raise serializers.ValidationError(ERROR_CODE['2015'])
|
raise serializers.ValidationError(ERROR_CODE['2015'])
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
new_password = validated_data.pop('new_password')
|
new_password = validated_data.pop('new_password')
|
||||||
current_password = validated_data.pop('current_password')
|
current_password = validated_data.pop('current_password')
|
||||||
"""Check new password is different from current password"""
|
# Check new password is different from current password
|
||||||
if new_password == current_password:
|
if new_password == current_password:
|
||||||
raise serializers.ValidationError({"details": ERROR_CODE['2026']})
|
raise serializers.ValidationError({"details": ERROR_CODE['2026']})
|
||||||
user_details = User.objects.filter(email=self.context).last()
|
|
||||||
if user_details:
|
|
||||||
user_details.set_password(new_password)
|
|
||||||
user_details.save()
|
|
||||||
return {'password':new_password}
|
|
||||||
return ''
|
|
||||||
|
|
||||||
|
user_details = self.context
|
||||||
|
user_details.set_password(new_password)
|
||||||
|
user_details.save()
|
||||||
|
return {'password':new_password}
|
||||||
|
|
||||||
|
|
||||||
class ForgotPasswordSerializer(serializers.Serializer):
|
class ForgotPasswordSerializer(serializers.Serializer):
|
||||||
"""Forget password serializer"""
|
"""Forget password serializer"""
|
||||||
email = serializers.EmailField()
|
email = serializers.EmailField(required=True)
|
||||||
|
|
||||||
|
def validate_email(self, value):
|
||||||
|
"""
|
||||||
|
validate email exist ot not
|
||||||
|
value: string
|
||||||
|
return none
|
||||||
|
"""
|
||||||
|
if not User.objects.get(email=value):
|
||||||
|
raise serializers.ValidationError({'details': ERROR_CODE['2004']})
|
||||||
|
return value
|
||||||
|
|
||||||
class AdminLoginSerializer(serializers.ModelSerializer):
|
class AdminLoginSerializer(serializers.ModelSerializer):
|
||||||
"""admin login serializer"""
|
"""admin login serializer"""
|
||||||
|
@ -129,6 +129,28 @@ def send_otp_email(recipient_email, otp):
|
|||||||
)
|
)
|
||||||
return otp
|
return otp
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task()
|
||||||
|
def send_all_email(template_name, email, otp):
|
||||||
|
"""
|
||||||
|
Send all type of email by passing template name
|
||||||
|
template_name: string
|
||||||
|
email: string
|
||||||
|
otp: string
|
||||||
|
"""
|
||||||
|
from_email = settings.EMAIL_FROM_ADDRESS
|
||||||
|
recipient_list = [email]
|
||||||
|
send_templated_mail(
|
||||||
|
template_name=template_name,
|
||||||
|
from_email=from_email,
|
||||||
|
recipient_list=recipient_list,
|
||||||
|
context={
|
||||||
|
'verification_code': otp
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return otp
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def user_device_details(user, device_id):
|
def user_device_details(user, device_id):
|
||||||
"""
|
"""
|
||||||
|
107
account/views.py
107
account/views.py
@ -39,7 +39,7 @@ from base.messages import ERROR_CODE, SUCCESS_CODE
|
|||||||
from base.constants import NUMBER, ZOD, JUN, GRD, USER_TYPE_FLAG
|
from base.constants import NUMBER, ZOD, JUN, GRD, USER_TYPE_FLAG
|
||||||
from guardian.tasks import generate_otp
|
from guardian.tasks import generate_otp
|
||||||
from account.utils import (send_otp_email, send_support_email, custom_response, custom_error_response,
|
from account.utils import (send_otp_email, send_support_email, custom_response, custom_error_response,
|
||||||
generate_code, OTP_EXPIRY, user_device_details)
|
generate_code, OTP_EXPIRY, user_device_details, send_all_email)
|
||||||
from junior.serializers import JuniorProfileSerializer
|
from junior.serializers import JuniorProfileSerializer
|
||||||
from guardian.serializers import GuardianProfileSerializer
|
from guardian.serializers import GuardianProfileSerializer
|
||||||
|
|
||||||
@ -193,15 +193,30 @@ class UpdateProfileImage(views.APIView):
|
|||||||
return custom_error_response(ERROR_CODE['2036'],response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(ERROR_CODE['2036'],response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
class ChangePasswordAPIView(views.APIView):
|
class ChangePasswordAPIView(views.APIView):
|
||||||
"""change password"""
|
"""
|
||||||
|
change password"
|
||||||
|
"""
|
||||||
serializer_class = ChangePasswordSerializer
|
serializer_class = ChangePasswordSerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
serializer = ChangePasswordSerializer(context=request.user, data=request.data)
|
"""
|
||||||
|
POST request to change current login user password
|
||||||
|
"""
|
||||||
|
serializer = ChangePasswordSerializer(
|
||||||
|
context=request.user,
|
||||||
|
data=request.data
|
||||||
|
)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return custom_response(SUCCESS_CODE['3007'], response_status=status.HTTP_200_OK)
|
return custom_response(
|
||||||
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
SUCCESS_CODE['3007'],
|
||||||
|
response_status=status.HTTP_200_OK
|
||||||
|
)
|
||||||
|
return custom_error_response(
|
||||||
|
serializer.errors,
|
||||||
|
response_status=status.HTTP_400_BAD_REQUEST
|
||||||
|
)
|
||||||
|
|
||||||
class ResetPasswordAPIView(views.APIView):
|
class ResetPasswordAPIView(views.APIView):
|
||||||
"""Reset password"""
|
"""Reset password"""
|
||||||
@ -213,40 +228,40 @@ class ResetPasswordAPIView(views.APIView):
|
|||||||
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)
|
||||||
|
|
||||||
class ForgotPasswordAPIView(views.APIView):
|
class ForgotPasswordAPIView(views.APIView):
|
||||||
"""Forgot password"""
|
"""
|
||||||
|
Forgot password
|
||||||
|
"""
|
||||||
|
serializer_class = ForgotPasswordSerializer
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
serializer = ForgotPasswordSerializer(data=request.data)
|
|
||||||
if serializer.is_valid():
|
"""
|
||||||
email = serializer.validated_data['email']
|
Post method to validate serializer
|
||||||
try:
|
"""
|
||||||
User.objects.get(email=email)
|
serializer = self.serializer_class(data=request.data)
|
||||||
except User.DoesNotExist:
|
serializer.is_valid(raise_exception=True)
|
||||||
return custom_error_response(ERROR_CODE['2004'], response_status=status.HTTP_404_NOT_FOUND)
|
email = serializer.validated_data['email']
|
||||||
verification_code = generate_otp()
|
# generate otp
|
||||||
# Send the verification code to the user's email
|
verification_code = generate_otp()
|
||||||
from_email = settings.EMAIL_FROM_ADDRESS
|
# Send the verification code to the user's email
|
||||||
recipient_list = [email]
|
send_all_email.delay(
|
||||||
send_templated_mail(
|
'email_reset_verification.email', email, verification_code
|
||||||
template_name='email_reset_verification.email',
|
)
|
||||||
from_email=from_email,
|
expiry = OTP_EXPIRY
|
||||||
recipient_list=recipient_list,
|
user_data, created = UserEmailOtp.objects.get_or_create(
|
||||||
context={
|
email=email
|
||||||
'verification_code': verification_code
|
)
|
||||||
}
|
if created:
|
||||||
)
|
user_data.expired_at = expiry
|
||||||
expiry = timezone.now() + timezone.timedelta(days=1)
|
user_data.save()
|
||||||
user_data, created = UserEmailOtp.objects.get_or_create(email=email)
|
if user_data:
|
||||||
if created:
|
user_data.otp = verification_code
|
||||||
user_data.expired_at = expiry
|
user_data.expired_at = expiry
|
||||||
user_data.save()
|
user_data.save()
|
||||||
if user_data:
|
return custom_response(
|
||||||
user_data.otp = verification_code
|
SUCCESS_CODE['3015'],
|
||||||
user_data.expired_at = expiry
|
response_status=status.HTTP_200_OK
|
||||||
user_data.save()
|
)
|
||||||
return custom_response(SUCCESS_CODE['3015'],
|
|
||||||
response_status=status.HTTP_200_OK)
|
|
||||||
return custom_error_response(serializer.errors, response_status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
class SendPhoneOtp(viewsets.ModelViewSet):
|
class SendPhoneOtp(viewsets.ModelViewSet):
|
||||||
"""Send otp on phone"""
|
"""Send otp on phone"""
|
||||||
@ -295,22 +310,24 @@ class UserLogin(viewsets.ViewSet):
|
|||||||
if user is not None:
|
if user is not None:
|
||||||
login(request, user)
|
login(request, user)
|
||||||
if str(user_type) == USER_TYPE_FLAG["TWO"]:
|
if str(user_type) == USER_TYPE_FLAG["TWO"]:
|
||||||
guardian_data = Guardian.objects.filter(user__username=username, is_verified=True).last()
|
guardian_data = Guardian.objects.filter(user__username=username).last()
|
||||||
if guardian_data:
|
if guardian_data:
|
||||||
serializer = GuardianSerializer(
|
if guardian_data.is_verified:
|
||||||
guardian_data, context={'user_type': user_type}
|
serializer = GuardianSerializer(
|
||||||
).data
|
guardian_data, context={'user_type': user_type}
|
||||||
|
).data
|
||||||
else:
|
else:
|
||||||
return custom_error_response(
|
return custom_error_response(
|
||||||
ERROR_CODE["2070"],
|
ERROR_CODE["2070"],
|
||||||
response_status=status.HTTP_401_UNAUTHORIZED
|
response_status=status.HTTP_401_UNAUTHORIZED
|
||||||
)
|
)
|
||||||
elif str(user_type) == USER_TYPE_FLAG["FIRST"]:
|
elif str(user_type) == USER_TYPE_FLAG["FIRST"]:
|
||||||
junior_data = Junior.objects.filter(auth__username=username, is_verified=True).last()
|
junior_data = Junior.objects.filter(auth__username=username).last()
|
||||||
if junior_data:
|
if junior_data:
|
||||||
serializer = JuniorSerializer(
|
if junior_data.is_verified:
|
||||||
junior_data, context={'user_type': user_type}
|
serializer = JuniorSerializer(
|
||||||
).data
|
junior_data, context={'user_type': user_type}
|
||||||
|
).data
|
||||||
else:
|
else:
|
||||||
return custom_error_response(
|
return custom_error_response(
|
||||||
ERROR_CODE["2071"],
|
ERROR_CODE["2071"],
|
||||||
|
@ -27,7 +27,7 @@ NUMBER = {
|
|||||||
'ninety_nine': 99, 'hundred': 100, 'thirty_six_hundred': 3600
|
'ninety_nine': 99, 'hundred': 100, 'thirty_six_hundred': 3600
|
||||||
}
|
}
|
||||||
|
|
||||||
|
none = "none"
|
||||||
|
|
||||||
# Super Admin string constant for 'role'
|
# Super Admin string constant for 'role'
|
||||||
SUPER_ADMIN = "Super Admin"
|
SUPER_ADMIN = "Super Admin"
|
||||||
|
@ -101,7 +101,11 @@ ERROR_CODE = {
|
|||||||
"2072": "You can not approve or reject this task because junior does not exist in the system",
|
"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",
|
"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",
|
"2074": "You can not complete this task because you does not exist in the system",
|
||||||
"2075": "Your account is deactivated. Please contact with admin"
|
"2075": "Your account is deactivated. Please contact with admin",
|
||||||
|
"2076": "This junior already associate with you",
|
||||||
|
"2077": "You can not add guardian",
|
||||||
|
"2078": "This junior is not associate with you",
|
||||||
|
|
||||||
}
|
}
|
||||||
"""Success message code"""
|
"""Success message code"""
|
||||||
SUCCESS_CODE = {
|
SUCCESS_CODE = {
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
"""task files"""
|
"""task files"""
|
||||||
"""Django import"""
|
|
||||||
|
# Django import
|
||||||
import secrets
|
import secrets
|
||||||
|
|
||||||
|
|
||||||
def generate_otp():
|
def generate_otp():
|
||||||
"""generate random otp"""
|
"""
|
||||||
|
generate random otp
|
||||||
|
"""
|
||||||
digits = "0123456789"
|
digits = "0123456789"
|
||||||
return "".join(secrets.choice(digits) for _ in range(6))
|
return "".join(secrets.choice(digits) for _ in range(6))
|
||||||
|
@ -166,6 +166,10 @@ class CreateTaskAPIView(viewsets.ModelViewSet):
|
|||||||
try:
|
try:
|
||||||
image = request.data['default_image']
|
image = request.data['default_image']
|
||||||
junior = request.data['junior']
|
junior = request.data['junior']
|
||||||
|
junior_id = Junior.objects.filter(id=junior).last()
|
||||||
|
guardian_data = Guardian.objects.filter(user=request.user).last()
|
||||||
|
if guardian_data.guardian_code in junior_id.guardian_code:
|
||||||
|
return custom_error_response(ERROR_CODE['2078'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
allowed_extensions = ['.jpg', '.jpeg', '.png']
|
allowed_extensions = ['.jpg', '.jpeg', '.png']
|
||||||
if not any(extension in str(image) for extension in allowed_extensions):
|
if not any(extension in str(image) for extension in allowed_extensions):
|
||||||
return custom_error_response(ERROR_CODE['2048'], response_status=status.HTTP_400_BAD_REQUEST)
|
return custom_error_response(ERROR_CODE['2048'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
@ -187,7 +191,7 @@ class CreateTaskAPIView(viewsets.ModelViewSet):
|
|||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
# save serializer
|
# save serializer
|
||||||
task = serializer.save()
|
task = serializer.save()
|
||||||
junior_id = Junior.objects.filter(id=junior).last()
|
|
||||||
send_notification_to_junior.delay(TASK_ASSIGNED, request.auth.payload['user_id'],
|
send_notification_to_junior.delay(TASK_ASSIGNED, request.auth.payload['user_id'],
|
||||||
junior_id.auth.id, {'task_id': task.id})
|
junior_id.auth.id, {'task_id': task.id})
|
||||||
return custom_response(SUCCESS_CODE['3018'], serializer.data, response_status=status.HTTP_200_OK)
|
return custom_response(SUCCESS_CODE['3018'], serializer.data, response_status=status.HTTP_200_OK)
|
||||||
@ -242,7 +246,7 @@ class TopJuniorListAPIView(viewsets.ModelViewSet):
|
|||||||
# Update the position field for each JuniorPoints object
|
# Update the position field for each JuniorPoints object
|
||||||
for index, junior in enumerate(junior_total_points):
|
for index, junior in enumerate(junior_total_points):
|
||||||
junior.position = index + 1
|
junior.position = index + 1
|
||||||
send_notification_to_junior.delay(LEADERBOARD_RANKING, None, junior.junior.auth.id, {})
|
# send_notification_to_junior.delay(LEADERBOARD_RANKING, None, junior.junior.auth.id, {})
|
||||||
junior.save()
|
junior.save()
|
||||||
serializer = self.get_serializer(junior_total_points[:NUMBER['fifteen']], many=True)
|
serializer = self.get_serializer(junior_total_points[:NUMBER['fifteen']], many=True)
|
||||||
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
|
||||||
|
@ -40,7 +40,7 @@ from .serializers import (CreateJuniorSerializer, JuniorDetailListSerializer, Ad
|
|||||||
from guardian.models import Guardian, JuniorTask
|
from guardian.models import Guardian, JuniorTask
|
||||||
from guardian.serializers import TaskDetailsSerializer, TaskDetailsjuniorSerializer
|
from guardian.serializers import TaskDetailsSerializer, TaskDetailsjuniorSerializer
|
||||||
from base.messages import ERROR_CODE, SUCCESS_CODE
|
from base.messages import ERROR_CODE, SUCCESS_CODE
|
||||||
from base.constants import NUMBER, ARTICLE_STATUS
|
from base.constants import NUMBER, ARTICLE_STATUS, none
|
||||||
from account.utils import custom_response, custom_error_response
|
from account.utils import custom_response, custom_error_response
|
||||||
from guardian.utils import upload_image_to_alibaba
|
from guardian.utils import upload_image_to_alibaba
|
||||||
from .utils import update_positions_based_on_points
|
from .utils import update_positions_based_on_points
|
||||||
@ -171,7 +171,11 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
|
|||||||
image_url = upload_image_to_alibaba(profile_image, filename)
|
image_url = upload_image_to_alibaba(profile_image, filename)
|
||||||
info_data.update({"image": image_url})
|
info_data.update({"image": image_url})
|
||||||
if user := User.objects.filter(username=request.data['email']).first():
|
if user := User.objects.filter(username=request.data['email']).first():
|
||||||
self.associate_guardian(user)
|
data = self.associate_guardian(user)
|
||||||
|
if data == none:
|
||||||
|
return custom_error_response(ERROR_CODE['2077'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
elif not data:
|
||||||
|
return custom_error_response(ERROR_CODE['2076'], response_status=status.HTTP_400_BAD_REQUEST)
|
||||||
return custom_response(SUCCESS_CODE['3021'], response_status=status.HTTP_200_OK)
|
return custom_response(SUCCESS_CODE['3021'], response_status=status.HTTP_200_OK)
|
||||||
# use AddJuniorSerializer serializer
|
# use AddJuniorSerializer serializer
|
||||||
serializer = AddJuniorSerializer(data=request.data, context=info_data)
|
serializer = AddJuniorSerializer(data=request.data, context=info_data)
|
||||||
@ -184,9 +188,16 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
|
|||||||
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)
|
||||||
|
|
||||||
def associate_guardian(self, user):
|
def associate_guardian(self, user):
|
||||||
junior = Junior.objects.filter(auth=user).first()
|
junior = Junior.objects.filter(auth__email=self.request.data['email']).first()
|
||||||
guardian = Guardian.objects.filter(user=self.request.user).first()
|
guardian = Guardian.objects.filter(user=self.request.user).first()
|
||||||
junior.guardian_code = [guardian.guardian_code]
|
if not junior:
|
||||||
|
return none
|
||||||
|
if guardian.guardian_code in junior.guardian_code:
|
||||||
|
return False
|
||||||
|
if type(junior.guardian_code) is list:
|
||||||
|
junior.guardian_code.append(guardian.guardian_code)
|
||||||
|
else:
|
||||||
|
junior.guardian_code = [guardian.guardian_code]
|
||||||
junior.guardian_code_status = str(NUMBER['two'])
|
junior.guardian_code_status = str(NUMBER['two'])
|
||||||
junior.save()
|
junior.save()
|
||||||
JuniorGuardianRelationship.objects.get_or_create(guardian=guardian, junior=junior,
|
JuniorGuardianRelationship.objects.get_or_create(guardian=guardian, junior=junior,
|
||||||
|
@ -222,6 +222,12 @@ class AnalyticsViewSet(GenericViewSet):
|
|||||||
|
|
||||||
|
|
||||||
def write_excel_worksheet(worksheet, dataframe):
|
def write_excel_worksheet(worksheet, dataframe):
|
||||||
|
"""
|
||||||
|
to perform write action on worksheets
|
||||||
|
:param worksheet:
|
||||||
|
:param dataframe:
|
||||||
|
:return: worksheet
|
||||||
|
"""
|
||||||
for idx, col in enumerate(dataframe.columns):
|
for idx, col in enumerate(dataframe.columns):
|
||||||
# Write header
|
# Write header
|
||||||
worksheet.write(0, idx, col)
|
worksheet.write(0, idx, col)
|
||||||
|
Reference in New Issue
Block a user