Merge branch 'dev' into ZBKADM-72-minor-changes

This commit is contained in:
abutalib-kiwi
2023-08-21 14:31:11 +05:30
9 changed files with 146 additions and 64 deletions

View File

@ -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"""

View File

@ -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):
""" """

View File

@ -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"],

View File

@ -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"

View File

@ -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 = {

View File

@ -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))

View File

@ -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)

View File

@ -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,

View File

@ -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)