jira-17 add junior and send invite mail

This commit is contained in:
jain
2023-07-12 16:24:30 +05:30
parent 33101811ff
commit a041028840
13 changed files with 235 additions and 8 deletions

View File

@ -0,0 +1,23 @@
{% extends "templated_email/email_base.email" %}
{% block subject %}
Approval Email
{% 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 {{full_name}},
</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;">
Please approve {{full_name}} for accessing the Zod bank platform as a junior.
</p>
</td>
</tr>
{% endblock %}

View File

@ -0,0 +1,24 @@
{% extends "templated_email/email_base.email" %}
{% block subject %}
Invitation Email
{% 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 {{full_name}},
</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;">
You are receiving this email for join the ZOD bank platform. Please use <b>{{ url }} </b> link to join the platform.
<br> Your credentials are:- username = <b>{{email}}</b> and password <b>{{password}}</b><br> <br>Below are the steps to complete the account and how to use this platform.
</p>
</td>
</tr>
{% endblock %}

View File

@ -6,6 +6,7 @@ from rest_framework.response import Response
"""Third party Django app""" """Third party Django app"""
from templated_email import send_templated_mail from templated_email import send_templated_mail
import jwt import jwt
import string
from datetime import datetime from datetime import datetime
from calendar import timegm from calendar import timegm
from uuid import uuid4 from uuid import uuid4
@ -179,3 +180,10 @@ def get_token(data: dict = dict):
'access': access, 'access': access,
'refresh': refresh 'refresh': refresh
} }
def generate_alphanumeric_code(length):
alphabet = string.ascii_letters + string.digits
code = ''.join(secrets.choice(alphabet) for _ in range(length))
return code

View File

@ -297,6 +297,7 @@ class UserLogin(viewsets.ViewSet):
email_verified.otp = otp email_verified.otp = otp
email_verified.save() email_verified.save()
data.update({"email_otp":otp}) data.update({"email_otp":otp})
send_otp_email(username, otp)
return custom_response(ERROR_CODE['2024'], {"email_otp": otp, "is_email_verified": is_verified}, return custom_response(ERROR_CODE['2024'], {"email_otp": otp, "is_email_verified": is_verified},
response_status=status.HTTP_200_OK) response_status=status.HTTP_200_OK)
data.update({"is_email_verified": is_verified}) data.update({"is_email_verified": is_verified})

View File

@ -51,6 +51,11 @@ SIGNUP_METHODS = (
('2', 'google'), ('2', 'google'),
('3', 'apple') ('3', 'apple')
) )
"""relationship"""
RELATIONSHIP = (
('1', 'parent'),
('2', 'legal_guardian')
)
PENDING = 1 PENDING = 1
IN_PROGRESS = 2 IN_PROGRESS = 2
REJECTED = 3 REJECTED = 3
@ -69,5 +74,3 @@ BYTE_IMAGE_SIZE = 1024
# validate file size # validate file size
MAX_FILE_SIZE = 1024 * 1024 * 5 MAX_FILE_SIZE = 1024 * 1024 * 5

View File

@ -88,7 +88,8 @@ SUCCESS_CODE = {
"3017": "Profile image update successfully", "3017": "Profile image update successfully",
"3018": "Task created successfully", "3018": "Task created successfully",
"3019": "Support Email sent successfully", "3019": "Support Email sent successfully",
"3020": "Logged out successfully." "3020": "Logged out successfully.",
"3021": "Add junior successfully"
} }
STATUS_CODE_ERROR = { STATUS_CODE_ERROR = {

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2023-07-12 06:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('junior', '0010_junior_signup_method'),
]
operations = [
migrations.AddField(
model_name='junior',
name='relationship',
field=models.CharField(blank=True, choices=[('1', 'parent'), ('2', 'legal_guardian')], default='1', max_length=31, null=True),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2023-07-12 10:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('junior', '0011_junior_relationship'),
]
operations = [
migrations.AddField(
model_name='junior',
name='is_invited',
field=models.BooleanField(default=False),
),
]

View File

@ -4,7 +4,7 @@ from django.db import models
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
"""Import django app""" """Import django app"""
from base.constants import GENDERS, SIGNUP_METHODS from base.constants import GENDERS, SIGNUP_METHODS, RELATIONSHIP
User = get_user_model() User = get_user_model()
# Create your models here. # Create your models here.
@ -19,6 +19,9 @@ class Junior(models.Model):
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.URLField(null=True, blank=True, default=None) image = models.URLField(null=True, blank=True, default=None)
"""relationship"""
relationship = models.CharField(max_length=31, choices=RELATIONSHIP, null=True, blank=True,
default='1')
"""Sign up method""" """Sign up method"""
signup_method = models.CharField(max_length=31, choices=SIGNUP_METHODS, default='1') signup_method = models.CharField(max_length=31, choices=SIGNUP_METHODS, default='1')
"""Codes""" """Codes"""
@ -26,6 +29,8 @@ class Junior(models.Model):
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)
"""invited junior"""
is_invited = models.BooleanField(default=False)
"""Profile activity""" """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)

View File

@ -4,12 +4,19 @@ from rest_framework import serializers
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db import transaction from django.db import transaction
import random import random
from django.utils import timezone
from rest_framework_simplejwt.tokens import RefreshToken
"""Import django app""" """Import django app"""
from account.utils import send_otp_email
from junior.models import Junior, JuniorPoints from junior.models import Junior, JuniorPoints
from guardian.utils import upload_image_to_alibaba from guardian.tasks import generate_otp
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
from guardian.models import Guardian, JuniorTask
from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED from base.constants import PENDING, IN_PROGRESS, REJECTED, REQUESTED, COMPLETED
from guardian.models import Guardian, JuniorTask
from account.models import UserEmailOtp
from junior.utils import junior_notification_email, junior_approval_mail
class ListCharField(serializers.ListField): class ListCharField(serializers.ListField):
"""Serializer for Array field""" """Serializer for Array field"""
@ -238,3 +245,54 @@ class JuniorProfileSerializer(serializers.ModelSerializer):
fields = ['id', 'email', 'first_name', 'last_name', 'country_name', 'country_code', 'phone', 'gender', 'dob', fields = ['id', 'email', 'first_name', 'last_name', 'country_name', 'country_code', 'phone', 'gender', 'dob',
'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image', 'guardian_code', 'referral_code','is_active', 'is_complete_profile', 'created_at', 'image',
'updated_at', 'notification_count', 'total_count', 'complete_field_count', 'signup_method'] 'updated_at', 'notification_count', 'total_count', 'complete_field_count', 'signup_method']
class AddJuniorSerializer(serializers.ModelSerializer):
"""Add junior serializer"""
auth_token = serializers.SerializerMethodField('get_auth_token')
def get_auth_token(self, obj):
"""auth token"""
refresh = RefreshToken.for_user(obj)
access_token = str(refresh.access_token)
return access_token
class Meta(object):
"""Meta info"""
model = Junior
fields = ['gender','dob', 'relationship', 'auth_token']
def create(self, validated_data):
""" create junior"""
with transaction.atomic():
email = self.context['email']
guardian = self.context['user']
full_name = self.context['first_name'] + ' ' + self.context['last_name']
guardian_data = Guardian.objects.filter(user__username=guardian).last()
user_data = User.objects.create(username=email, email=email,
first_name=self.context['first_name'],
last_name=self.context['last_name'])
password = User.objects.make_random_password()
user_data.set_password(password)
user_data.save()
junior_data = Junior.objects.create(auth=user_data, gender=validated_data.get('gender'),
dob=validated_data.get('dob'), is_invited=True,
relationship=validated_data.get('relationship'),
junior_code=''.join([str(random.randrange(9)) for _ in range(4)]),
referral_code=''.join([str(random.randrange(9)) for _ in range(4)]),
referral_code_used=guardian_data.referral_code)
"""Generate otp"""
otp_value = generate_otp()
expiry_time = timezone.now() + timezone.timedelta(days=1)
UserEmailOtp.objects.create(email=email, otp=otp_value,
user_type='1', expired_at=expiry_time)
"""Send email to the register user"""
send_otp_email(email, otp_value)
"""Notification email"""
junior_notification_email(email, full_name, email, password)
junior_approval_mail(guardian, full_name)
return junior_data

View File

@ -1,7 +1,7 @@
""" Urls files""" """ Urls files"""
"""Django import""" """Django import"""
from django.urls import path, include from django.urls import path, include
from .views import UpdateJuniorProfile, ValidateGuardianCode, JuniorListAPIView from .views import UpdateJuniorProfile, ValidateGuardianCode, JuniorListAPIView, AddJuniorAPIView
"""Third party import""" """Third party import"""
from rest_framework import routers from rest_framework import routers
@ -15,6 +15,8 @@ router.register('create-junior-profile', UpdateJuniorProfile, basename='profile-
router.register('validate-guardian-code', ValidateGuardianCode, basename='validate-guardian-code') router.register('validate-guardian-code', ValidateGuardianCode, basename='validate-guardian-code')
"""junior list API""" """junior list API"""
router.register('junior-list', JuniorListAPIView, basename='junior-list') router.register('junior-list', JuniorListAPIView, basename='junior-list')
"""Add junior list API"""
router.register('add-junior', AddJuniorAPIView, basename='add-junior')
"""Define url pattern""" """Define url pattern"""
urlpatterns = [ urlpatterns = [
path('api/v1/', include(router.urls)), path('api/v1/', include(router.urls)),

51
junior/utils.py Normal file
View File

@ -0,0 +1,51 @@
"""Account utils"""
"""Import django"""
from django.conf import settings
from rest_framework import viewsets, status
from rest_framework.response import Response
"""Third party Django app"""
from templated_email import send_templated_mail
import jwt
import string
from datetime import datetime
from calendar import timegm
from uuid import uuid4
import secrets
from rest_framework import serializers
from junior.models import Junior
from guardian.models import Guardian
from account.models import UserDelete
from base.messages import ERROR_CODE
def junior_notification_email(recipient_email, full_name, email, password):
"""Notification email"""
from_email = settings.EMAIL_FROM_ADDRESS
recipient_list = [recipient_email]
send_templated_mail(
template_name='junior_notification_email.email',
from_email=from_email,
recipient_list=recipient_list,
context={
'full_name': full_name,
'url':'link',
'email': email,
'password': password
}
)
return full_name
def junior_approval_mail(guardian, full_name):
"""junior approval mail"""
from_email = settings.EMAIL_FROM_ADDRESS
recipient_list = [guardian]
send_templated_mail(
template_name='junior_approval_mail.email',
from_email=from_email,
recipient_list=recipient_list,
context={
'full_name': full_name
}
)
return full_name

View File

@ -3,7 +3,7 @@ from rest_framework import viewsets, status
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
"""Django app import""" """Django app import"""
from junior.models import Junior from junior.models import Junior
from .serializers import CreateJuniorSerializer, JuniorDetailListSerializer from .serializers import CreateJuniorSerializer, JuniorDetailListSerializer, AddJuniorSerializer
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
@ -61,3 +61,18 @@ class JuniorListAPIView(viewsets.ModelViewSet):
queryset = Junior.objects.filter(guardian_code__icontains=str(guardian_data.guardian_code)) queryset = Junior.objects.filter(guardian_code__icontains=str(guardian_data.guardian_code))
serializer = JuniorDetailListSerializer(queryset, many=True) serializer = JuniorDetailListSerializer(queryset, 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)
class AddJuniorAPIView(viewsets.ModelViewSet):
"""Add Junior by guardian"""
queryset = Junior.objects.all()
serializer_class = AddJuniorSerializer
permission_classes = [IsAuthenticated]
def create(self, request, *args, **kwargs):
""" junior list"""
info = {'user': request.user, 'email': request.data['email'], 'first_name': request.data['first_name'],
'last_name': request.data['last_name']}
serializer = AddJuniorSerializer(data=request.data, context=info)
if serializer.is_valid():
serializer.save()
return custom_response(SUCCESS_CODE['3021'], serializer.data, response_status=status.HTTP_200_OK)
return custom_error_response(serializer.error, response_status=status.HTTP_400_BAD_REQUEST)