Merge pull request #5 from KiwiTechLLC/26june_sprint1

26june sprint1
This commit is contained in:
dilipshrivastwa-kiwi
2023-06-27 15:07:19 +05:30
committed by GitHub
24 changed files with 251 additions and 102 deletions

11
zod_bank/Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM python:3.9
ENV PYTHONUNBUFFERED 1
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
COPY . .
RUN apt-get update
RUN apt-get install wkhtmltopdf -y
RUN apt install -y gdal-bin python3-gdal
RUN pip install -r requirements.txt
WORKDIR /usr/src/app

View File

@ -1,10 +1,12 @@
"""Account admin"""
from django.contrib import admin from django.contrib import admin
# Register your models here. """Import django app"""
from .models import UserProfile, UserEmailOtp, UserPhoneOtp from .models import UserProfile, UserEmailOtp, UserPhoneOtp
# Register your models here. # Register your models here.
@admin.register(UserProfile) @admin.register(UserProfile)
class UserProfileAdmin(admin.ModelAdmin): class UserProfileAdmin(admin.ModelAdmin):
"""User profile admin"""
list_display = ['user'] list_display = ['user']
def __str__(self): def __str__(self):
@ -12,14 +14,18 @@ class UserProfileAdmin(admin.ModelAdmin):
@admin.register(UserEmailOtp) @admin.register(UserEmailOtp)
class UserEmailOtpAdmin(admin.ModelAdmin): class UserEmailOtpAdmin(admin.ModelAdmin):
"""User Email otp admin"""
list_display = ['email'] list_display = ['email']
def __str__(self): def __str__(self):
"""Return object in email and otp format"""
return self.email + '-' + self.otp return self.email + '-' + self.otp
@admin.register(UserPhoneOtp) @admin.register(UserPhoneOtp)
class UserPhoneOtpAdmin(admin.ModelAdmin): class UserPhoneOtpAdmin(admin.ModelAdmin):
"""User Phone otp admin"""
list_display = ['phone'] list_display = ['phone']
def __str__(self): def __str__(self):
"""Return object in phone number and otp format"""
return self.phone + '-' + self.otp return self.phone + '-' + self.otp

View File

@ -1,6 +1,6 @@
from django.core.mail import send_mail """Account utils"""
"""Third party Django app"""
from django.conf import settings from django.conf import settings
import random
from rest_framework import viewsets, status from rest_framework import viewsets, status
from rest_framework.response import Response from rest_framework.response import Response

View File

@ -1,6 +1,7 @@
from rest_framework import viewsets, status, views from rest_framework import viewsets, status, views
from rest_framework.decorators import action from rest_framework.decorators import action
import random import random
import logging
from django.contrib.auth import authenticate, login from django.contrib.auth import authenticate, login
from guardian.models import Guardian from guardian.models import Guardian
from junior.models import Junior from junior.models import Junior
@ -8,11 +9,11 @@ from account.models import UserProfile, UserPhoneOtp, UserEmailOtp
from django.contrib.auth.models import User from django.contrib.auth.models import User
from .serializers import (SuperUserSerializer, GuardianSerializer, JuniorSerializer, EmailVerificationSerializer, from .serializers import (SuperUserSerializer, GuardianSerializer, JuniorSerializer, EmailVerificationSerializer,
ForgotPasswordSerializer, ResetPasswordSerializer, ChangePasswordSerializer) ForgotPasswordSerializer, ResetPasswordSerializer, ChangePasswordSerializer)
from django.views.decorators.csrf import csrf_exempt
from rest_framework_simplejwt.tokens import RefreshToken from rest_framework_simplejwt.tokens import RefreshToken
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
from guardian.tasks import generate_otp from guardian.tasks import generate_otp
from django.conf import settings from django.conf import settings
from account.utils import send_otp_email
from account.utils import custom_response, custom_error_response from account.utils import custom_response, custom_error_response
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
from django.core.mail import send_mail from django.core.mail import send_mail
@ -27,7 +28,7 @@ class ChangePasswordAPIView(views.APIView):
serializer = ChangePasswordSerializer(context=request.user, data=request.data) 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['3006'], response_status=status.HTTP_200_OK) return custom_response(SUCCESS_CODE['3007'], 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)
class ResetPasswordAPIView(views.APIView): class ResetPasswordAPIView(views.APIView):
@ -59,11 +60,11 @@ class ForgotPasswordAPIView(views.APIView):
'verification_code': verification_code 'verification_code': verification_code
} }
) )
user_data = UserEmailOtp.objects.get_or_create(email=email) user_data, created = UserEmailOtp.objects.get_or_create(email=email)
if user_data: if user_data:
user_data.otp = verification_code user_data.otp = verification_code
user_data.save() user_data.save()
return custom_response(SUCCESS_CODE['3015'], {'verification_code': verification_code}, return custom_response(SUCCESS_CODE['3015'],
response_status=status.HTTP_200_OK) 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)
@ -86,15 +87,15 @@ class UserPhoneVerification(viewsets.ModelViewSet):
"""Send otp on phone""" """Send otp on phone"""
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
try: try:
phone_data = UserPhoneOtp.objects.filter(phone=request.data['phone'], phone_data = UserPhoneOtp.objects.filter(phone=self.request.GET.get('phone'),
otp=request.data['otp']).last() otp=self.request.GET.get('otp')).last()
if phone_data: if phone_data:
phone_data.is_verified = True phone_data.is_verified = True
phone_data.save() phone_data.save()
return custom_response(SUCCESS_CODE['3012'], response_status=status.HTTP_200_OK) return custom_response(SUCCESS_CODE['3012'], response_status=status.HTTP_200_OK)
else: else:
return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST)
except Exception as e: except Exception:
return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST)
@ -114,12 +115,11 @@ class UserLogin(viewsets.ViewSet):
junior_data = Junior.objects.filter(auth__username=username, is_complete_profile=True).last() junior_data = Junior.objects.filter(auth__username=username, is_complete_profile=True).last()
if junior_data: if junior_data:
serializer = JuniorSerializer(junior_data) serializer = JuniorSerializer(junior_data)
if user.is_superuser:
serializer = SuperUserSerializer(user)
return custom_response(SUCCESS_CODE['3003'], serializer.data, response_status=status.HTTP_200_OK) return custom_response(SUCCESS_CODE['3003'], serializer.data, response_status=status.HTTP_200_OK)
else: else:
return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_401_UNAUTHORIZED) return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_401_UNAUTHORIZED)
except Exception as e: except Exception as e:
logging.error(e)
user_profile_data = UserProfile.objects.filter(user__username=username).last() user_profile_data = UserProfile.objects.filter(user__username=username).last()
email_verified = UserEmailOtp.objects.filter(email=username).last() email_verified = UserEmailOtp.objects.filter(email=username).last()
refresh = RefreshToken.for_user(user) refresh = RefreshToken.for_user(user)
@ -140,14 +140,34 @@ class UserLogin(viewsets.ViewSet):
data.update({"is_email_verified": is_verified}) data.update({"is_email_verified": is_verified})
return custom_response(None, data, response_status=status.HTTP_200_OK) return custom_response(None, data, response_status=status.HTTP_200_OK)
@action(methods=['post'], detail=False)
def admin_login(self, request):
username = request.data.get('username')
password = request.data.get('password')
user = authenticate(request, username=username, password=password)
try:
if user is not None:
login(request, user)
if user.is_superuser:
serializer = SuperUserSerializer(user)
return custom_response(SUCCESS_CODE['3003'], serializer.data, response_status=status.HTTP_200_OK)
else:
return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_401_UNAUTHORIZED)
except Exception as e:
logging.error(e)
refresh = RefreshToken.for_user(user)
access_token = str(refresh.access_token)
data = {"auth_token": access_token, "user_role": '3'}
return custom_response(None, data, response_status=status.HTTP_200_OK)
class UserEmailVerification(viewsets.ModelViewSet): class UserEmailVerification(viewsets.ModelViewSet):
"""User Email verification""" """User Email verification"""
serializer_class = EmailVerificationSerializer serializer_class = EmailVerificationSerializer
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
try: try:
email_data = UserEmailOtp.objects.filter(email=request.data['email'], email_data = UserEmailOtp.objects.filter(email=self.request.GET.get('email'),
otp=request.data['otp']).last() otp=self.request.GET.get('otp')).last()
if email_data: if email_data:
email_data.is_verified = True email_data.is_verified = True
email_data.save() email_data.save()
@ -155,6 +175,7 @@ class UserEmailVerification(viewsets.ModelViewSet):
else: else:
return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST)
except Exception as e: except Exception as e:
logging.error(e)
return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST)
class ReSendEmailOtp(viewsets.ModelViewSet): class ReSendEmailOtp(viewsets.ModelViewSet):
@ -162,11 +183,12 @@ class ReSendEmailOtp(viewsets.ModelViewSet):
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
otp = generate_otp() otp = generate_otp()
if User.objects.filter(email=request.data['email']): if User.objects.filter(email=request.data['email']):
email_data = UserEmailOtp.objects.get_or_create(email=request.data['email']) email_data, created = UserEmailOtp.objects.get_or_create(email=request.data['email'])
if email_data: if email_data:
email_data.otp = otp email_data.otp = otp
email_data.save() email_data.save()
return custom_response(None, {'email_otp': otp}, response_status=status.HTTP_200_OK) send_otp_email(request.data['email'], otp)
return custom_response(SUCCESS_CODE['3016'], response_status=status.HTTP_200_OK)
else: else:
return custom_error_response(ERROR_CODE["2023"], response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE["2023"], response_status=status.HTTP_400_BAD_REQUEST)

View File

@ -63,7 +63,7 @@ SUCCESS_CODE = {
# Success code for password reset # Success code for password reset
"3006": "Your password has been reset successfully.", "3006": "Your password has been reset successfully.",
# Success code for password update # Success code for password update
"3007": "Your password has been updated successfully.", "3007": "Your password has been changed successfully.",
# Success code for valid link # Success code for valid link
"3008": "You have a valid link.", "3008": "You have a valid link.",
# Success code for logged out # Success code for logged out
@ -74,7 +74,8 @@ SUCCESS_CODE = {
"3012": "Phone OTP Verified successfully", "3012": "Phone OTP Verified successfully",
"3013": "Valid Guardian code", "3013": "Valid Guardian code",
"3014": "Password has been updated successfully.", "3014": "Password has been updated successfully.",
"3015": "Verification code sent on your email." "3015": "Verification code sent on your email.",
"3016": "Send otp on your Email successfully"
} }
STATUS_CODE_ERROR = { STATUS_CODE_ERROR = {

View File

@ -0,0 +1,18 @@
version: '3'
services:
nginx:
image: nginx:latest
container_name: nginx
ports:
- "8000:8000"
volumes:
- ./nginx:/etc/nginx/conf.d
- .:/usr/src/app
depends_on:
- web
web:
build: .
container_name: django
command: bash -c "pip install -r requirements.txt && python manage.py collectstatic --noinput && python manage.py migrate && gunicorn zod_bank.wsgi -b 0.0.0.0:8000 -t 300 --log-level=info"
volumes:
- .:/usr/src/app

View File

@ -1,9 +1,14 @@
"""Guardian admin"""
"""Third party Django app"""
from django.contrib import admin from django.contrib import admin
"""Import Django app"""
from .models import Guardian from .models import Guardian
# Register your models here. # Register your models here.
@admin.register(Guardian) @admin.register(Guardian)
class GuardianAdmin(admin.ModelAdmin): class GuardianAdmin(admin.ModelAdmin):
"""Junior Admin"""
list_display = ['user', 'family_name'] list_display = ['user', 'family_name']
def __str__(self): def __str__(self):
"""Return email id"""
return self.user__email return self.user__email

View File

@ -1,6 +1,9 @@
"""Guardian app file"""
"""Third party Django app"""
from django.apps import AppConfig from django.apps import AppConfig
class CustodianConfig(AppConfig): class CustodianConfig(AppConfig):
"""Guardian config"""
default_auto_field = 'django.db.models.BigAutoField' default_auto_field = 'django.db.models.BigAutoField'
name = 'guardian' name = 'guardian'

View File

@ -0,0 +1,17 @@
# Generated by Django 4.2.2 on 2023-06-27 06:15
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('guardian', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='guardian',
name='junior_code',
),
]

View File

@ -1,23 +1,31 @@
"""Guardian model file"""
"""Third party Django app"""
from django.db import models from django.db import models
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
"""Import Django app"""
from base.constants import GENDERS from base.constants import GENDERS
from django.contrib.postgres.fields import ArrayField
User = get_user_model() User = get_user_model()
# Create your models here. # Create your models here.
class Guardian(models.Model): class Guardian(models.Model):
"""Guardian model"""
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='guardian_profile', verbose_name='Email') user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='guardian_profile', verbose_name='Email')
"""Contact details"""
country_code = models.IntegerField(blank=True, null=True) country_code = models.IntegerField(blank=True, null=True)
phone = models.CharField(max_length=31, null=True, blank=True, default=None) phone = models.CharField(max_length=31, null=True, blank=True, default=None)
"""Personal info"""
family_name = models.CharField(max_length=50, null=True, blank=True, default=None) family_name = models.CharField(max_length=50, null=True, blank=True, default=None)
gender = models.CharField(choices=GENDERS, max_length=15, null=True, blank=True, default=None) gender = models.CharField(choices=GENDERS, max_length=15, null=True, blank=True, default=None)
dob = models.DateField(max_length=15, null=True, blank=True, default=None) dob = models.DateField(max_length=15, null=True, blank=True, default=None)
"""Codes"""
guardian_code = models.CharField(max_length=10, null=True, blank=True, default=None) guardian_code = models.CharField(max_length=10, null=True, blank=True, default=None)
referral_code = models.CharField(max_length=10, null=True, blank=True, default=None) referral_code = models.CharField(max_length=10, null=True, blank=True, default=None)
referral_code_used = models.CharField(max_length=10, null=True, blank=True, default=None) referral_code_used = models.CharField(max_length=10, null=True, blank=True, default=None)
"""Profile activity"""
is_active = models.BooleanField(default=True) is_active = models.BooleanField(default=True)
is_complete_profile = models.BooleanField(default=False) is_complete_profile = models.BooleanField(default=False)
passcode = models.IntegerField(null=True, blank=True, default=None) passcode = models.IntegerField(null=True, blank=True, default=None)
"""Profile created and updated time"""
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
@ -27,4 +35,5 @@ class Guardian(models.Model):
verbose_name = 'Guardian' verbose_name = 'Guardian'
def __str__(self): def __str__(self):
"""Return email id"""
return f'{self.user}' return f'{self.user}'

View File

@ -1,91 +1,116 @@
from rest_framework import serializers """Serializer of Guardian"""
from django.contrib.auth.models import User """Third party Django app"""
from .models import Guardian import logging
from django.db import transaction
import random import random
from account.models import UserProfile from rest_framework import serializers
from junior.models import Junior
from base.constants import GENDERS, GUARDIAN, JUNIOR, SUPERUSER
from rest_framework_simplejwt.tokens import RefreshToken from rest_framework_simplejwt.tokens import RefreshToken
from django.db import transaction
from django.contrib.auth.models import User
"""Import Django app"""
from .models import Guardian
from account.models import UserProfile
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
class UserSerializer(serializers.ModelSerializer): class UserSerializer(serializers.ModelSerializer):
"""User serializer"""
auth_token = serializers.SerializerMethodField('get_auth_token') auth_token = serializers.SerializerMethodField('get_auth_token')
class Meta(object): class Meta(object):
"""Meta info"""
model = User model = User
fields = ['email', 'password', 'auth_token'] fields = ['email', 'password', 'auth_token']
def get_auth_token(self, obj): def get_auth_token(self, obj):
"""generate auth token"""
refresh = RefreshToken.for_user(obj) refresh = RefreshToken.for_user(obj)
access_token = str(refresh.access_token) access_token = str(refresh.access_token)
return access_token return access_token
def create(self, validated_data): def create(self, validated_data):
"""fetch data"""
email = validated_data.get('email') email = validated_data.get('email')
user_type = self.context user_type = self.context
password = validated_data.get('password') password = validated_data.get('password')
try: try:
"""Create user profile"""
user = User.objects.create_user(username=email, email=email, password=password) user = User.objects.create_user(username=email, email=email, password=password)
UserProfile.objects.create(user=user, user_type=user_type) UserProfile.objects.create(user=user, user_type=user_type)
return user return user
except: except Exception as e:
"""Error handling"""
logging.error(e)
raise serializers.ValidationError({"details":ERROR_CODE['2021']}) raise serializers.ValidationError({"details":ERROR_CODE['2021']})
def save(self, **kwargs): def save(self, **kwargs):
"""save the data"""
with transaction.atomic(): with transaction.atomic():
instance = super().save(**kwargs) instance = super().save(**kwargs)
return instance return instance
class CreateGuardianSerializer(serializers.ModelSerializer): class CreateGuardianSerializer(serializers.ModelSerializer):
"""Create guardian serializer"""
"""Basic info"""
first_name = serializers.SerializerMethodField('get_first_name') first_name = serializers.SerializerMethodField('get_first_name')
last_name = serializers.SerializerMethodField('get_last_name') last_name = serializers.SerializerMethodField('get_last_name')
email = serializers.SerializerMethodField('get_email') email = serializers.SerializerMethodField('get_email')
"""Contact details"""
phone = serializers.CharField(max_length=20, required=False) phone = serializers.CharField(max_length=20, required=False)
family_name = serializers.CharField(max_length=100, required=False)
country_code = serializers.IntegerField(required=False) country_code = serializers.IntegerField(required=False)
family_name = serializers.CharField(max_length=100, required=False)
dob = serializers.DateField(required=False) dob = serializers.DateField(required=False)
referral_code = serializers.CharField(max_length=100, required=False) referral_code = serializers.CharField(max_length=100, required=False)
class Meta(object): class Meta(object):
"""Meta info"""
model = Guardian model = Guardian
fields = ['first_name', 'last_name', 'email', 'phone', 'family_name', 'gender', 'country_code', 'dob', 'referral_code', 'passcode', fields = ['first_name', 'last_name', 'email', 'phone', 'family_name', 'gender', 'country_code',
'is_complete_profile'] 'dob', 'referral_code', 'passcode', 'is_complete_profile']
def get_first_name(self,obj): def get_first_name(self,obj):
"""first name of guardian"""
return obj.user.first_name return obj.user.first_name
def get_last_name(self,obj): def get_last_name(self,obj):
"""last name of guardian"""
return obj.user.last_name return obj.user.last_name
def get_email(self,obj): def get_email(self,obj):
"""emailof guardian"""
return obj.user.email return obj.user.email
def create(self, validated_data): def create(self, validated_data):
"""Create guardian profile"""
user = User.objects.filter(username=self.context['user']).last() user = User.objects.filter(username=self.context['user']).last()
if user: if user:
"""Save first and last name of guardian"""
user.first_name = self.context.get('first_name', user.first_name) user.first_name = self.context.get('first_name', user.first_name)
user.last_name = self.context.get('last_name', user.last_name) user.last_name = self.context.get('last_name', user.last_name)
user.save() user.save()
"""Create guardian data"""
guardian, created = Guardian.objects.get_or_create(user=self.context['user']) guardian, created = Guardian.objects.get_or_create(user=self.context['user'])
if created: if created:
"""Create referral code and guardian code"""
guardian.referral_code = ''.join([str(random.randrange(9)) for _ in range(4)]) guardian.referral_code = ''.join([str(random.randrange(9)) for _ in range(4)])
guardian.guardian_code = ''.join([str(random.randrange(9)) for _ in range(4)]) guardian.guardian_code = ''.join([str(random.randrange(9)) for _ in range(4)])
if guardian: if guardian:
guardian.phone = validated_data.get('phone', guardian.phone) """update details according to the data get from request"""
guardian.gender = validated_data.get('gender',guardian.gender) guardian.gender = validated_data.get('gender',guardian.gender)
guardian.family_name = validated_data.get('family_name', guardian.family_name) guardian.family_name = validated_data.get('family_name', guardian.family_name)
guardian.dob = validated_data.get('dob',guardian.dob) guardian.dob = validated_data.get('dob',guardian.dob)
"""Update country code and phone number"""
guardian.phone = validated_data.get('phone', guardian.phone)
guardian.country_code = validated_data.get('country_code', guardian.country_code)
guardian.passcode = validated_data.get('passcode', guardian.passcode) guardian.passcode = validated_data.get('passcode', guardian.passcode)
guardian.referral_code_used = validated_data.get('referral_code_used', guardian.referral_code_used)
"""Complete profile of the junior if below all data are filled"""
complete_profile_field = all([guardian.phone, guardian.gender, guardian.family_name, complete_profile_field = all([guardian.phone, guardian.gender, guardian.family_name,
guardian.dob, guardian.country_code, user.first_name, user.last_name]) guardian.dob, guardian.country_code, user.first_name, user.last_name])
guardian.is_complete_profile = False guardian.is_complete_profile = False
if complete_profile_field: if complete_profile_field:
guardian.is_complete_profile = True guardian.is_complete_profile = True
guardian.country_code = validated_data.get('country_code', guardian.country_code)
guardian.save() guardian.save()
return guardian return guardian
def save(self, **kwargs): def save(self, **kwargs):
"""Save the data into junior table"""
with transaction.atomic(): with transaction.atomic():
instance = super().save(**kwargs) instance = super().save(**kwargs)
return instance return instance

View File

@ -1,3 +1,5 @@
"""Test file of Guardian"""
"""Third party Django app"""
from django.test import TestCase from django.test import TestCase
# Create your tests here. # Create your tests here.

View File

@ -1,17 +1,19 @@
""" Urls files""" """ Urls files"""
"""Django import""" """Django import"""
from django.urls import path, include from django.urls import path, include
from rest_framework.decorators import api_view
from .views import SignupViewset, UpdateGuardianProfile from .views import SignupViewset, UpdateGuardianProfile
"""Third party import""" """Third party import"""
from rest_framework import routers from rest_framework import routers
"""Router""" """Define Router"""
router = routers.SimpleRouter() router = routers.SimpleRouter()
"""API End points with router""" """API End points with router"""
"""Sign up API"""
router.register('sign-up', SignupViewset, basename='sign-up') router.register('sign-up', SignupViewset, basename='sign-up')
"""Create guardian profile API"""
router.register('create-guardian-profile', UpdateGuardianProfile, basename='update-guardian-profile') router.register('create-guardian-profile', UpdateGuardianProfile, basename='update-guardian-profile')
"""Define Url pattern"""
urlpatterns = [ urlpatterns = [
path('api/v1/', include(router.urls)), path('api/v1/', include(router.urls)),
] ]

View File

@ -1,45 +1,47 @@
from django.shortcuts import render """Views of Guardian"""
from rest_framework import (pagination, viewsets, status, generics, mixins) """Third party Django app"""
from .serializers import CreateGuardianSerializer
from rest_framework.decorators import action
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt
# Create your views here.
from rest_framework import viewsets, status
from rest_framework.response import Response
from .serializers import UserSerializer
from django.contrib.auth.models import User
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from base.constants import GUARDIAN, JUNIOR, SUPERUSER from rest_framework import viewsets, status
from junior.models import Junior """Import Django app"""
from .serializers import UserSerializer
from .serializers import CreateGuardianSerializer
from account.models import UserEmailOtp from account.models import UserEmailOtp
from .tasks import generate_otp from .tasks import generate_otp
from account.utils import send_otp_email from account.utils import send_otp_email
from account.utils import custom_response, custom_error_response from account.utils import custom_response, custom_error_response
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
# Create your views here.
class SignupViewset(viewsets.ModelViewSet): class SignupViewset(viewsets.ModelViewSet):
"""Signup view set"""
serializer_class = UserSerializer serializer_class = UserSerializer
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
"""Create user profile"""
serializer = UserSerializer(context=request.data['user_type'], data=request.data) serializer = UserSerializer(context=request.data['user_type'], data=request.data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save() serializer.save()
"""Generate otp"""
otp = generate_otp() otp = generate_otp()
UserEmailOtp.objects.create(email=request.data['email'], otp=otp) UserEmailOtp.objects.create(email=request.data['email'], otp=otp)
"""Send email to the register user"""
send_otp_email(request.data['email'], otp) send_otp_email(request.data['email'], otp)
return custom_response(SUCCESS_CODE['3001'], {"email_otp": otp}, return custom_response(SUCCESS_CODE['3001'], {"email_otp": otp},
response_status=status.HTTP_200_OK) 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)
class UpdateGuardianProfile(viewsets.ViewSet): class UpdateGuardianProfile(viewsets.ViewSet):
"""Update guardian profile"""
serializer_class = CreateGuardianSerializer serializer_class = CreateGuardianSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
serializer = CreateGuardianSerializer(context={"user":request.user,"first_name":request.data.get('first_name', ''), """Create guardian profile"""
"last_name": request.data.get('last_name',' ')}, data=request.data) serializer = CreateGuardianSerializer(context={"user":request.user,
"first_name":request.data.get('first_name', ''),
"last_name": request.data.get('last_name',' ')},
data=request.data)
if serializer.is_valid(): if serializer.is_valid():
"""save serializer"""
serializer.save() serializer.save()
return custom_response(None, serializer.data,response_status=status.HTTP_200_OK) return custom_response(None, 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)

View File

@ -1,9 +1,14 @@
"""Junior admin"""
"""Third party Django app"""
from django.contrib import admin from django.contrib import admin
"""Import Django app"""
from .models import Junior from .models import Junior
# Register your models here. # Register your models here.
@admin.register(Junior) @admin.register(Junior)
class JuniorAdmin(admin.ModelAdmin): class JuniorAdmin(admin.ModelAdmin):
"""Junior Admin"""
list_display = ['auth'] list_display = ['auth']
def __str__(self): def __str__(self):
"""Return email id"""
return self.auth__email return self.auth__email

View File

@ -1,6 +1,8 @@
"""App file"""
"""Import AppConfig"""
from django.apps import AppConfig from django.apps import AppConfig
class JuniorConfig(AppConfig): class JuniorConfig(AppConfig):
"""Junior config"""
default_auto_field = 'django.db.models.BigAutoField' default_auto_field = 'django.db.models.BigAutoField'
name = 'junior' name = 'junior'

View File

@ -1,25 +1,33 @@
"""Junior model """
"""Import django"""
from django.db import models from django.db import models
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from base.constants import GENDERS
from guardian.models import Guardian
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
"""Import django app"""
from base.constants import GENDERS
User = get_user_model() User = get_user_model()
# Create your models here. # Create your models here.
class Junior(models.Model): class Junior(models.Model):
"""Junior model"""
auth = models.ForeignKey(User, on_delete=models.CASCADE, related_name='junior_profile', verbose_name='Email') auth = models.ForeignKey(User, on_delete=models.CASCADE, related_name='junior_profile', verbose_name='Email')
"""Contact details"""
phone = models.CharField(max_length=31, null=True, blank=True, default=None) phone = models.CharField(max_length=31, null=True, blank=True, default=None)
country_code = models.IntegerField(blank=True, null=True) country_code = models.IntegerField(blank=True, null=True)
"""Personal info"""
gender = models.CharField(max_length=10, choices=GENDERS, null=True, blank=True, default=None) gender = models.CharField(max_length=10, choices=GENDERS, null=True, blank=True, default=None)
dob = models.DateField(max_length=15, null=True, blank=True, default=None) dob = models.DateField(max_length=15, null=True, blank=True, default=None)
# image = models.ImageField(upload_to='images/') # image = models.ImageField(upload_to='images/')
"""Codes"""
junior_code = models.CharField(max_length=10, null=True, blank=True, default=None) junior_code = models.CharField(max_length=10, null=True, blank=True, default=None)
guardian_code = ArrayField(models.CharField(max_length=10, null=True, blank=True, default=None),null=True) guardian_code = ArrayField(models.CharField(max_length=10, null=True, blank=True, default=None),null=True)
referral_code = models.CharField(max_length=10, null=True, blank=True, default=None) referral_code = models.CharField(max_length=10, null=True, blank=True, default=None)
referral_code_used = models.CharField(max_length=10, null=True, blank=True, default=None) referral_code_used = models.CharField(max_length=10, null=True, blank=True, default=None)
"""Profile activity"""
is_active = models.BooleanField(default=True) is_active = models.BooleanField(default=True)
is_complete_profile = models.BooleanField(default=False) is_complete_profile = models.BooleanField(default=False)
passcode = models.IntegerField(null=True, blank=True, default=None) passcode = models.IntegerField(null=True, blank=True, default=None)
"""Profile created and updated time"""
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
@ -29,4 +37,5 @@ class Junior(models.Model):
verbose_name = 'Junior' verbose_name = 'Junior'
def __str__(self): def __str__(self):
"""Return email id"""
return f'{self.auth}' return f'{self.auth}'

View File

@ -1,28 +1,29 @@
"""Serializer file for junior"""
"""Import Django 3rd party app"""
from rest_framework import serializers from rest_framework import serializers
from django.contrib.auth.models import User from django.contrib.auth.models import User
from .models import Guardian
from django.db import transaction from django.db import transaction
import random import random
from account.models import UserProfile """Import django app"""
from junior.models import Junior from junior.models import Junior
from base.constants import GENDERS, GUARDIAN, JUNIOR, SUPERUSER
from rest_framework_simplejwt.tokens import RefreshToken
from base.messages import ERROR_CODE, SUCCESS_CODE
from django.contrib.postgres.fields import ArrayField
class ListCharField(serializers.ListField): class ListCharField(serializers.ListField):
"""Serializer for Array field"""
child = serializers.CharField() child = serializers.CharField()
def to_representation(self, data): def to_representation(self, data):
"""to represent the data"""
return data return data
def to_internal_value(self, data): def to_internal_value(self, data):
"""internal value"""
if isinstance(data, list): if isinstance(data, list):
return data return data
raise serializers.ValidationError({"details":"Invalid input. Expected a list of strings."}) raise serializers.ValidationError({"details":"Invalid input. Expected a list of strings."})
class CreateJuniorSerializer(serializers.ModelSerializer): class CreateJuniorSerializer(serializers.ModelSerializer):
"""Create junior serializer"""
first_name = serializers.SerializerMethodField('get_first_name') first_name = serializers.SerializerMethodField('get_first_name')
last_name = serializers.SerializerMethodField('get_last_name') last_name = serializers.SerializerMethodField('get_last_name')
email = serializers.SerializerMethodField('get_email') email = serializers.SerializerMethodField('get_email')
@ -33,41 +34,59 @@ class CreateJuniorSerializer(serializers.ModelSerializer):
guardian_code = ListCharField(required=False) guardian_code = ListCharField(required=False)
class Meta(object): class Meta(object):
"""Meta info"""
model = Junior model = Junior
fields = ['first_name', 'last_name', 'email', 'phone', 'gender', 'country_code', 'dob', 'referral_code', fields = ['first_name', 'last_name', 'email', 'phone', 'gender', 'country_code', 'dob', 'referral_code',
'passcode', 'is_complete_profile', 'guardian_code'] 'passcode', 'is_complete_profile', 'guardian_code']
def get_first_name(self,obj): def get_first_name(self,obj):
"""first name of junior"""
return obj.auth.first_name return obj.auth.first_name
def get_last_name(self,obj): def get_last_name(self,obj):
"""last name of junior"""
return obj.auth.last_name return obj.auth.last_name
def get_email(self,obj): def get_email(self,obj):
"""email of junior"""
return obj.auth.email return obj.auth.email
def create(self, validated_data): def create(self, validated_data):
"""Create junior profile"""
user = User.objects.filter(username=self.context['user']).last() user = User.objects.filter(username=self.context['user']).last()
if user: if user:
"""Save first and last name of junior"""
user.first_name = self.context.get('first_name', user.first_name) user.first_name = self.context.get('first_name', user.first_name)
user.last_name = self.context.get('last_name', user.last_name) user.last_name = self.context.get('last_name', user.last_name)
user.save() user.save()
"""Create junior data"""
junior, created = Junior.objects.get_or_create(auth=self.context['user']) junior, created = Junior.objects.get_or_create(auth=self.context['user'])
if created: if created:
"""Create referral code and junior code"""
junior.referral_code = ''.join([str(random.randrange(9)) for _ in range(4)]) junior.referral_code = ''.join([str(random.randrange(9)) for _ in range(4)])
junior.junior_code = ''.join([str(random.randrange(9)) for _ in range(4)]) junior.junior_code = ''.join([str(random.randrange(9)) for _ in range(4)])
if junior: if junior:
junior.phone = validated_data.get('phone', junior.phone) """update details according to the data get from request"""
junior.gender = validated_data.get('gender',junior.gender) junior.gender = validated_data.get('gender',junior.gender)
"""Update guardian code"""
junior.guardian_code = validated_data.get('guardian_code', junior.guardian_code) junior.guardian_code = validated_data.get('guardian_code', junior.guardian_code)
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.is_complete_profile = validated_data.get('is_complete_profile', junior.is_complete_profile) """Update country code and phone number"""
junior.phone = validated_data.get('phone', junior.phone)
junior.country_code = validated_data.get('country_code', junior.country_code) junior.country_code = validated_data.get('country_code', junior.country_code)
junior.referral_code_used = validated_data.get('referral_code_used', junior.referral_code_used)
"""Complete profile of the junior if below all data are filled"""
complete_profile_field = all([junior.phone, junior.gender, junior.family_name,
junior.dob, junior.country_code, user.first_name, user.last_name])
junior.is_complete_profile = False
if complete_profile_field:
junior.is_complete_profile = True
junior.save() junior.save()
return junior return junior
def save(self, **kwargs): def save(self, **kwargs):
"""Save the data into junior table"""
with transaction.atomic(): with transaction.atomic():
instance = super().save(**kwargs) instance = super().save(**kwargs)
return instance return instance

View File

@ -1,3 +1,5 @@
"""Junior test file"""
"""Import TestCase"""
from django.test import TestCase from django.test import TestCase
# Create your tests here. # Create your tests here.

View File

@ -1,7 +1,6 @@
""" Urls files""" """ Urls files"""
"""Django import""" """Django import"""
from django.urls import path, include from django.urls import path, include
from rest_framework.decorators import api_view
from .views import UpdateJuniorProfile, ValidateGuardianCode from .views import UpdateJuniorProfile, ValidateGuardianCode
"""Third party import""" """Third party import"""
from rest_framework import routers from rest_framework import routers
@ -10,8 +9,11 @@ from rest_framework import routers
router = routers.SimpleRouter() router = routers.SimpleRouter()
"""API End points with router""" """API End points with router"""
"""Create junior profile API"""
router.register('create-junior-profile', UpdateJuniorProfile, basename='profile-update') router.register('create-junior-profile', UpdateJuniorProfile, basename='profile-update')
"""validate guardian code API"""
router.register('validate-guardian-code', ValidateGuardianCode, basename='validate-guardian-code') router.register('validate-guardian-code', ValidateGuardianCode, basename='validate-guardian-code')
"""Define url pattern"""
urlpatterns = [ urlpatterns = [
path('api/v1/', include(router.urls)), path('api/v1/', include(router.urls)),
] ]

View File

@ -1,40 +1,40 @@
from django.shortcuts import render """Junior view file"""
from rest_framework import (pagination, viewsets, status, generics, mixins)
from rest_framework.decorators import action
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt
# Create your views here.
from rest_framework import viewsets, status from rest_framework import viewsets, status
from rest_framework.response import Response
from .serializers import CreateJuniorSerializer
from django.contrib.auth.models import User
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from base.constants import GUARDIAN, JUNIOR, SUPERUSER """Django app import"""
from junior.models import Junior from junior.models import Junior
from .serializers import CreateJuniorSerializer
from guardian.models import Guardian from guardian.models import Guardian
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
from account.utils import custom_response, custom_error_response from account.utils import custom_response, custom_error_response
# Create your views here.
class UpdateJuniorProfile(viewsets.ViewSet): class UpdateJuniorProfile(viewsets.ViewSet):
"""Update junior profile"""
serializer_class = CreateJuniorSerializer serializer_class = CreateJuniorSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
serializer = CreateJuniorSerializer(context={"user":request.user,"first_name":request.data.get('first_name', ''), """Use CreateJuniorSerializer"""
"last_name": request.data.get('last_name',' ')}, data=request.data) serializer = CreateJuniorSerializer(context={"user":request.user,
"first_name":request.data.get('first_name', ''),
"last_name": request.data.get('last_name',' ')},
data=request.data)
if serializer.is_valid(): if serializer.is_valid():
"""save serializer"""
serializer.save() serializer.save()
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK) return custom_response(None, 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)
class ValidateGuardianCode(viewsets.ViewSet): class ValidateGuardianCode(viewsets.ViewSet):
"""Check guardian code exist or not"""
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
guardian_code = request.data.get('guardian_code') """check guardian code"""
guardian_code = self.request.GET.get('guardian_code').split(',')
for code in guardian_code: for code in guardian_code:
guardian_data = Guardian.objects.filter(guardian_code=code).exists() guardian_data = Guardian.objects.filter(guardian_code=code).exists()
if guardian_data: if guardian_data:
return custom_response(SUCCESS_CODE['3028'], response_status=status.HTTP_200_OK) return custom_response(SUCCESS_CODE['3013'], response_status=status.HTTP_200_OK)
else: else:
return custom_error_response(ERROR_CODE["2022"], response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE["2022"], response_status=status.HTTP_400_BAD_REQUEST)

View File

@ -1,14 +1,18 @@
#!/usr/bin/env python #!/usr/bin/env python
"""Django's command-line utility for administrative tasks.""" """Django's command-line utility for administrative tasks."""
"""Django import"""
import os import os
import sys import sys
def main(): def main():
"""Main function"""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'zod_bank.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'zod_bank.settings')
try: try:
"""Import execute from command line function"""
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line
except ImportError as exc: except ImportError as exc:
"""Show Exception error"""
raise ImportError( raise ImportError(
"Couldn't import Django. Are you sure it's installed and " "Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you " "available on your PYTHONPATH environment variable? Did you "

View File

@ -33,6 +33,7 @@ django-timezone-field==5.1
djangorestframework==3.14.0 djangorestframework==3.14.0
djangorestframework-simplejwt==5.2.2 djangorestframework-simplejwt==5.2.2
drf-yasg==1.21.6 drf-yasg==1.21.6
gunicorn==20.1.0
inflection==0.5.1 inflection==0.5.1
jmespath==0.10.0 jmespath==0.10.0
kombu==5.3.1 kombu==5.3.1

View File

@ -57,7 +57,7 @@ INSTALLED_APPS = [
'junior', 'junior',
'guardian', 'guardian',
] ]
# CSRF_COOKIE_SECURE = False
MIDDLEWARE = [ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
@ -168,27 +168,9 @@ CORS_ALLOW_HEADERS = (
'x-requested-with', 'x-requested-with',
) )
# Static files (CSS, JavaScript, Images) """Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/ https://docs.djangoproject.com/en/3.0/howto/static-files/"""
#
# MAIL_MAILER='smtp'
# MAIL_HOST='smtp.gmail.com'
# MAIL_PORT=587
# mail_username='infozodbank@gmail.com'
# MAIL_PASSWORD='ghwdmznwwslvchga'
# MAIL_ENCRYPTION='tls'
# mail_from_address='infozodbank@gmail.com'
# MAIL_FROM_NAME="${APP_NAME}"
# MAIL_MAILER='smtp'
# MAIL_HOST='smtp.gmail.com'
# MAIL_PORT=587
# mail_username='ankita.jain@kiwitech.com'
# MAIL_PASSWORD='jaijain0912@'
# MAIL_ENCRYPTION='tls'
# mail_from_address='infozodbank@gmail.com'
# MAIL_FROM_NAME="${APP_NAME}"
# Email settings # Email settings
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
@ -196,7 +178,7 @@ EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587 EMAIL_PORT = 587
EMAIL_USE_TLS = True EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'infozodbank@gmail.com' EMAIL_HOST_USER = 'infozodbank@gmail.com'
EMAIL_HOST_PASSWORD = 'ghwdmznwwslvchga' # Replace with your Gmail email password or App password # Replace with your Gmail email password or App password
EMAIL_HOST_PASSWORD = 'ghwdmznwwslvchga'
STATIC_URL = '/static/' STATIC_URL = '/static/'