Added updated at for applications

This commit is contained in:
gowtham 2022-05-24 15:05:53 +05:30
parent 74571cf802
commit a98c359d9b
7 changed files with 92 additions and 62 deletions

View File

@ -59,8 +59,8 @@ def markStatus(request, id, email, user_type):
def getDashboard(request, id, email, user_type): def getDashboard(request, id, email, user_type):
try: try:
placements = Placement.objects.all().order_by('-created_at') placements = Placement.objects.all().order_by('-created_at')
ongoing = placements.filter(deadline_datetime__gt=datetime.datetime.now(), offer_accepted=True, email_verified=True) ongoing = placements.filter(deadline_datetime__gt=timezone.now(), offer_accepted=True, email_verified=True)
previous = placements.exclude(deadline_datetime__gt=datetime.datetime.now()).filter( previous = placements.exclude(deadline_datetime__gt=timezone.now()).filter(
offer_accepted=True, email_verified=True) offer_accepted=True, email_verified=True)
new = placements.filter(offer_accepted__isnull=True, email_verified=True) new = placements.filter(offer_accepted__isnull=True, email_verified=True)
ongoing = PlacementSerializerForAdmin(ongoing, many=True).data ongoing = PlacementSerializerForAdmin(ongoing, many=True).data
@ -193,7 +193,7 @@ def getApplications(request, id, email, user_type):
@api_view(['POST']) @api_view(['POST'])
@isAuthorized(allowed_users=[ADMIN]) @isAuthorized(allowed_users=[ADMIN])
@precheck(required_data=[APPLICATION_ID,STUDENT_ID,OPENING_ID,ADDITIONAL_INFO,RESUME_FILE_NAME]) @precheck(required_data=[APPLICATION_ID, STUDENT_ID, OPENING_ID, ADDITIONAL_INFO, RESUME_FILE_NAME])
def submitApplication(request, id, email, user_type): def submitApplication(request, id, email, user_type):
try: try:
data = request.data data = request.data
@ -301,7 +301,7 @@ def generateCSV(request, id, email, user_type):
except: except:
logger.warning("Create csv: " + str(sys.exc_info())) logger.warning("Create csv: " + str(sys.exc_info()))
print(sys.exc_info()) print(sys.exc_info())
return Response({'action': "Create csv", 'message': "Error Occurred"}, return Response({'action': "Create csv", 'message': "Something Went Wrong"},
status=status.HTTP_400_BAD_REQUEST) status=status.HTTP_400_BAD_REQUEST)
@ -331,7 +331,7 @@ def addPPO(request, id, email, user_type):
except: except:
logger.warning("Add PPO: " + str(sys.exc_info())) logger.warning("Add PPO: " + str(sys.exc_info()))
print(sys.exc_info()) print(sys.exc_info())
return Response({'action': "Add PPO", 'message': "Error Occurred"}, return Response({'action': "Add PPO", 'message': "Something Went Wrong"},
status=status.HTTP_400_BAD_REQUEST) status=status.HTTP_400_BAD_REQUEST)
@ -350,7 +350,8 @@ def getStudentApplication(request, id, email, user_type):
"resume_list": student_serializer.data['resume_list'], "resume_list": student_serializer.data['resume_list'],
} }
# search for the application if there or not # search for the application if there or not
application = PlacementApplication.objects.filter(student=student, placement=get_object_or_404(Placement, id=data[OPENING_ID])) application = PlacementApplication.objects.filter(student=student,
placement=get_object_or_404(Placement, id=data[OPENING_ID]))
logger.info("Get Student Application: " + str(application)) logger.info("Get Student Application: " + str(application))
if application: if application:
serializer = PlacementApplicationSerializer(application[0]) serializer = PlacementApplicationSerializer(application[0])
@ -359,16 +360,17 @@ def getStudentApplication(request, id, email, user_type):
"additional_info": serializer.data['additional_info'], "additional_info": serializer.data['additional_info'],
"resume": serializer.data['resume_link'], "resume": serializer.data['resume_link'],
} }
return Response({'action': "Get Student Application", 'application_found': "true", "application_info": application_info, return Response(
"student_details":student_details }, status=status.HTTP_200_OK) {'action': "Get Student Application", 'application_found': "true", "application_info": application_info,
"student_details": student_details}, status=status.HTTP_200_OK)
else: else:
return Response({'action': "Get Student Application", 'application_found': "false", "student_details": student_details}, return Response(
{'action': "Get Student Application", 'application_found': "false", "student_details": student_details},
status=status.HTTP_404_NOT_FOUND) status=status.HTTP_404_NOT_FOUND)
except Http404: except Http404:
logger.warning("Get Student Application: " + str(sys.exc_info())) return Response({'action': "Get Student Application", 'message': "Student not found."},
print(sys.exc_info()) status.HTTP_404_NOT_FOUND)
return Response({'action': "Get Student Application", 'message': "Student with given roll number not found."}, status.HTTP_400_BAD_REQUEST)
except: except:
logger.warning("Get Student Application: " + str(sys.exc_info())) logger.warning("Get Student Application: " + str(sys.exc_info()))
print(sys.exc_info()) return Response({'action': "Get Student Application", 'message': "Something Went Wrong"},
return Response({'action': "Get Student Application", 'message': "Some error Occurred"}, status.HTTP_500_INTERNAL_SERVER_ERROR) status.HTTP_400_BAD_REQUEST)

View File

@ -6,14 +6,14 @@ logger = logging.getLogger('db')
@api_view(['POST']) @api_view(['POST'])
@precheck([COMPANY_NAME, ADDRESS, COMPANY_TYPE, NATURE_OF_BUSINESS, WEBSITE, COMPANY_DETAILS, IS_COMPANY_DETAILS_PDF, @precheck([COMPANY_NAME, ADDRESS, COMPANY_TYPE, NATURE_OF_BUSINESS, TYPE_OF_ORGANISATION, WEBSITE, COMPANY_DETAILS,
CONTACT_PERSON_NAME, PHONE_NUMBER, EMAIL, CITY, STATE, COUNTRY, PINCODE, DESIGNATION, DESCRIPTION, IS_COMPANY_DETAILS_PDF, CONTACT_PERSON_NAME, PHONE_NUMBER, EMAIL, CITY, STATE, COUNTRY, PINCODE, DESIGNATION,
IS_DESCRIPTION_PDF, DESCRIPTION,
COMPENSATION_CTC, COMPENSATION_GROSS, COMPENSATION_TAKE_HOME, COMPENSATION_BONUS, IS_DESCRIPTION_PDF, COMPENSATION_CTC, COMPENSATION_GROSS, COMPENSATION_TAKE_HOME, COMPENSATION_BONUS,
IS_COMPENSATION_DETAILS_PDF, IS_COMPENSATION_DETAILS_PDF, ALLOWED_BRANCH, RS_ELIGIBLE, SELECTION_PROCEDURE_ROUNDS,
ALLOWED_BRANCH, RS_ELIGIBLE, SELECTION_PROCEDURE_ROUNDS, SELECTION_PROCEDURE_DETAILS, IS_SELECTION_PROCEDURE_DETAILS_PDF, SELECTION_PROCEDURE_DETAILS,
TENTATIVE_DATE_OF_JOINING, IS_SELECTION_PROCEDURE_DETAILS_PDF, TENTATIVE_DATE_OF_JOINING, TENTATIVE_NO_OF_OFFERS, OTHER_REQUIREMENTS,
TENTATIVE_NO_OF_OFFERS, OTHER_REQUIREMENTS, RECAPTCHA_VALUE RECAPTCHA_VALUE, JOB_LOCATION
]) ])
def addPlacement(request): def addPlacement(request):
try: try:
@ -29,6 +29,7 @@ def addPlacement(request):
opening.address = data[ADDRESS] opening.address = data[ADDRESS]
opening.company_type = data[COMPANY_TYPE] opening.company_type = data[COMPANY_TYPE]
opening.nature_of_business = data[NATURE_OF_BUSINESS] opening.nature_of_business = data[NATURE_OF_BUSINESS]
opening.type_of_organisation = data[TYPE_OF_ORGANISATION]
opening.website = data[WEBSITE] opening.website = data[WEBSITE]
opening.company_details = data[COMPANY_DETAILS] opening.company_details = data[COMPANY_DETAILS]
opening.is_company_details_pdf = data[IS_COMPANY_DETAILS_PDF] opening.is_company_details_pdf = data[IS_COMPANY_DETAILS_PDF]
@ -36,7 +37,6 @@ def addPlacement(request):
opening.rs_eligible = True opening.rs_eligible = True
else: else:
opening.rs_eligible = False opening.rs_eligible = False
opening.job_locations = data[JOB_LOCATIONS]
if opening.is_company_details_pdf: if opening.is_company_details_pdf:
company_details_pdf = [] company_details_pdf = []
@ -83,6 +83,7 @@ def addPlacement(request):
# Add a designation details in the opening # Add a designation details in the opening
opening.designation = data[DESIGNATION] opening.designation = data[DESIGNATION]
opening.description = data[DESCRIPTION] opening.description = data[DESCRIPTION]
opening.job_location = data[JOB_LOCATION]
opening.is_description_pdf = data[IS_DESCRIPTION_PDF] opening.is_description_pdf = data[IS_DESCRIPTION_PDF]
if opening.is_description_pdf: if opening.is_description_pdf:

View File

@ -79,6 +79,7 @@ COMPANY_NAME = "company_name"
ADDRESS = "address" ADDRESS = "address"
COMPANY_TYPE = "company_type" COMPANY_TYPE = "company_type"
NATURE_OF_BUSINESS = "nature_of_business" NATURE_OF_BUSINESS = "nature_of_business"
TYPE_OF_ORGANISATION = "type_of_organisation"
WEBSITE = 'website' WEBSITE = 'website'
COMPANY_DETAILS = "company_details" COMPANY_DETAILS = "company_details"
COMPANY_DETAILS_PDF = "company_details_pdf" COMPANY_DETAILS_PDF = "company_details_pdf"
@ -97,7 +98,7 @@ DESCRIPTION_PDF = 'description_pdf'
DESCRIPTION_PDF_NAMES = 'description_pdf_names' DESCRIPTION_PDF_NAMES = 'description_pdf_names'
IS_DESCRIPTION_PDF = 'is_description_pdf' IS_DESCRIPTION_PDF = 'is_description_pdf'
OPENING_TYPE = 'opening_type' OPENING_TYPE = 'opening_type'
JOB_LOCATIONS = 'job_locations' JOB_LOCATION = 'job_location'
COMPENSATION_CTC = 'compensation_ctc' COMPENSATION_CTC = 'compensation_ctc'
COMPENSATION_GROSS = 'compensation_gross' COMPENSATION_GROSS = 'compensation_gross'
COMPENSATION_TAKE_HOME = 'compensation_take_home' COMPENSATION_TAKE_HOME = 'compensation_take_home'

View File

@ -51,6 +51,7 @@ class Placement(models.Model):
address = models.CharField(blank=False, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT) address = models.CharField(blank=False, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT)
company_type = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT) company_type = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT)
nature_of_business = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") nature_of_business = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="")
type_of_organisation = models.CharField(max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="", blank=False)
website = models.CharField(blank=True, max_length=JNF_TEXT_MAX_CHARACTER_COUNT) website = models.CharField(blank=True, max_length=JNF_TEXT_MAX_CHARACTER_COUNT)
company_details = models.CharField(max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) company_details = models.CharField(max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True)
company_details_pdf_names = ArrayField( company_details_pdf_names = ArrayField(
@ -68,6 +69,7 @@ class Placement(models.Model):
# Job Details # Job Details
designation = models.CharField(blank=False, max_length=JNF_TEXT_MAX_CHARACTER_COUNT, default=None, null=True) designation = models.CharField(blank=False, max_length=JNF_TEXT_MAX_CHARACTER_COUNT, default=None, null=True)
description = models.CharField(blank=False, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) description = models.CharField(blank=False, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True)
job_location = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="")
description_pdf_names = ArrayField( description_pdf_names = ArrayField(
models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=5, default=list, models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=5, default=list,
blank=True) blank=True)
@ -105,38 +107,63 @@ class Placement(models.Model):
tentative_no_of_offers = models.IntegerField(blank=False, default=None, null=True) tentative_no_of_offers = models.IntegerField(blank=False, default=None, null=True)
rs_eligible = models.BooleanField(blank=False, default=False) rs_eligible = models.BooleanField(blank=False, default=False)
other_requirements = models.CharField(blank=True, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default="") other_requirements = models.CharField(blank=True, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default="")
job_locations = models.CharField(blank=True, max_length=JNF_TEXT_MAX_CHARACTER_COUNT, default="")
additional_info = ArrayField(models.CharField(blank=True, max_length=JNF_TEXTMEDIUM_MAX_CHARACTER_COUNT), size=15, additional_info = ArrayField(models.CharField(blank=True, max_length=JNF_TEXTMEDIUM_MAX_CHARACTER_COUNT), size=15,
default=list, blank=True) default=list, blank=True)
email_verified = models.BooleanField(blank=False, default=False) email_verified = models.BooleanField(blank=False, default=False)
offer_accepted = models.BooleanField(blank=False, default=None, null=True) offer_accepted = models.BooleanField(blank=False, default=None, null=True)
deadline_datetime = models.DateTimeField(blank=False, verbose_name="Deadline Date", default=two_day_after_today) deadline_datetime = models.DateTimeField(blank=False, verbose_name="Deadline Date", default=two_day_after_today)
created_at = models.DateTimeField(blank=False, default=None, null=True) created_at = models.DateTimeField(blank=False, default=None, null=True)
updated_at = models.DateTimeField(blank=False, default=None, null=True)
def format(self): def format(self):
if self.company_name is not None:
self.company_name = self.company_name.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] self.company_name = self.company_name.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT]
if self.company_type is not None:
self.company_type = self.company_type.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] self.company_type = self.company_type.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT]
self.nature_of_business = self.nature_of_business.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] if self.company_details is not None:
self.website = self.website.strip()[:JNF_TEXT_MAX_CHARACTER_COUNT]
self.company_details = self.company_details.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] self.company_details = self.company_details.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT]
if self.address is not None:
self.address = self.address.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT]
if self.nature_of_business is not None:
self.nature_of_business = self.nature_of_business.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT]
if self.type_of_organisation is not None:
self.type_of_organisation = self.type_of_organisation.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT]
if self.website is not None:
self.website = self.website.strip()[:JNF_TEXT_MAX_CHARACTER_COUNT]
if self.contact_person_name is not None:
self.contact_person_name = self.contact_person_name.strip()[:JNF_TEXT_MAX_CHARACTER_COUNT] self.contact_person_name = self.contact_person_name.strip()[:JNF_TEXT_MAX_CHARACTER_COUNT]
if self.email is not None:
self.email = self.email.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] self.email = self.email.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT]
if self.city is not None:
self.city = self.city.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] self.city = self.city.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT]
if self.state is not None:
self.state = self.state.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] self.state = self.state.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT]
if self.country is not None:
self.country = self.country.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] self.country = self.country.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT]
if self.city_type is not None:
self.city_type = self.city_type.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] self.city_type = self.city_type.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT]
if self.designation is not None:
self.designation = self.designation.strip()[:JNF_TEXT_MAX_CHARACTER_COUNT] self.designation = self.designation.strip()[:JNF_TEXT_MAX_CHARACTER_COUNT]
if self.description is not None:
self.description = self.description.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] self.description = self.description.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT]
self.selection_procedure_details = self.selection_procedure_details.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] if self.job_location is not None:
self.job_location = self.job_location.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT]
if self.selection_procedure_details is not None:
self.selection_procedure_details = self.selection_procedure_details.strip()[
:JNF_TEXTAREA_MAX_CHARACTER_COUNT]
if self.bond_details is not None:
self.bond_details = self.bond_details.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] self.bond_details = self.bond_details.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT]
if self.other_requirements is not None:
self.other_requirements = self.other_requirements.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] self.other_requirements = self.other_requirements.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT]
self.additional_info = [info.strip()[:JNF_TEXTMEDIUM_MAX_CHARACTER_COUNT] for info in self.additional_info] if self.additional_info is not None:
self.additional_info = [info.strip()[:JNF_TEXTMEDIUM_MAX_CHARACTER_COUNT] for info in list(self.additional_info)]
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
''' On save, add timestamps ''' ''' On save, add timestamps '''
if not self.created_at: if not self.created_at:
self.created_at = timezone.now() self.created_at = timezone.now()
self.format() self.format()
self.updated_at = timezone.now()
return super(Placement, self).save(*args, **kwargs) return super(Placement, self).save(*args, **kwargs)
def __str__(self): def __str__(self):
@ -151,11 +178,13 @@ class PlacementApplication(models.Model):
additional_info = models.JSONField(blank=True, null=True, default=None) additional_info = models.JSONField(blank=True, null=True, default=None)
selected = models.BooleanField(null=True, default=None, blank=True) selected = models.BooleanField(null=True, default=None, blank=True)
applied_at = models.DateTimeField(blank=False, default=None, null=True) applied_at = models.DateTimeField(blank=False, default=None, null=True)
updated_at = models.DateTimeField(blank=False, default=None, null=True)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
''' On save, add timestamps ''' ''' On save, add timestamps '''
if not self.applied_at: if not self.applied_at:
self.applied_at = timezone.now() self.applied_at = timezone.now()
self.updated_at = timezone.now()
return super(PlacementApplication, self).save(*args, **kwargs) return super(PlacementApplication, self).save(*args, **kwargs)

View File

@ -162,9 +162,7 @@ class PlacementApplicationSerializer(serializers.ModelSerializer):
return data return data
def get_resume_link(self, obj): def get_resume_link(self, obj):
ele = {} ele = {'link': LINK_TO_STORAGE_RESUME + urllib.parse.quote(obj.id + "/" + obj.resume), 'name': obj.resume}
ele['link'] = LINK_TO_STORAGE_RESUME + urllib.parse.quote(obj.id + "/" + obj.resume)
ele['name'] = obj.resume
return ele return ele
class Meta: class Meta:
@ -181,9 +179,7 @@ class PlacementApplicationSerializerForAdmin(serializers.ModelSerializer):
return data return data
def get_resume_link(self, obj): def get_resume_link(self, obj):
ele = {} ele = {'link': LINK_TO_STORAGE_RESUME + urllib.parse.quote(obj.id + "/" + obj.resume), 'name': obj.resume}
ele['link'] = LINK_TO_STORAGE_RESUME + urllib.parse.quote(obj.id + "/" + obj.resume)
ele['name'] = obj.resume
return ele return ele
class Meta: class Meta:

View File

@ -20,6 +20,7 @@ from django.http import Http404
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.utils.html import strip_tags from django.utils.html import strip_tags
from django.utils import timezone
from google.auth.transport import requests from google.auth.transport import requests
from google.oauth2 import id_token from google.oauth2 import id_token
from rest_framework import status from rest_framework import status
@ -79,7 +80,7 @@ def isAuthorized(allowed_users=None):
print(email) print(email)
user = get_object_or_404(User, email=email) user = get_object_or_404(User, email=email)
if user: if user:
user.last_login_time = datetime.datetime.now() user.last_login_time = timezone.now()
user.save() user.save()
if len(set(user.user_type).intersection(set(allowed_users))) or allowed_users == '*': if len(set(user.user_type).intersection(set(allowed_users))) or allowed_users == '*':
return view_func(request, user.id, user.email, user.user_type, *args, **kwargs) return view_func(request, user.id, user.email, user.user_type, *args, **kwargs)
@ -120,7 +121,7 @@ def generateRandomString():
def saveFile(file, location): def saveFile(file, location):
prefix = generateRandomString() prefix = generateRandomString()
file_name = prefix + "_" + file.name file_name = prefix + "_" + file.name.strip()
file_name = re.sub(r'[\\/:*?"<>|]', '_', file_name) file_name = re.sub(r'[\\/:*?"<>|]', '_', file_name)
@ -137,8 +138,8 @@ def saveFile(file, location):
return file_name return file_name
@background_task.background(schedule=10) @background_task.background(schedule=5)
def sendEmail(email_to, subject, data, template, attachment_jnf_respone=None): def sendEmail(email_to, subject, data, template, attachment_jnf_response=None):
try: try:
if not isinstance(data, dict): if not isinstance(data, dict):
data = json.loads(data) data = json.loads(data)
@ -150,11 +151,11 @@ def sendEmail(email_to, subject, data, template, attachment_jnf_respone=None):
msg = EmailMultiAlternatives(subject, text_content, email_from, recipient_list) msg = EmailMultiAlternatives(subject, text_content, email_from, recipient_list)
msg.attach_alternative(html_content, "text/html") msg.attach_alternative(html_content, "text/html")
if attachment_jnf_respone: if attachment_jnf_response:
logger.info(attachment_jnf_respone) logger.info(attachment_jnf_response)
pdf = pdfkit.from_string(attachment_jnf_respone['html'], False, pdf = pdfkit.from_string(attachment_jnf_response['html'], False,
options={"--enable-local-file-access": "", '--dpi': '96'}) options={"--enable-local-file-access": "", '--dpi': '96'})
msg.attach(attachment_jnf_respone['name'], pdf, 'application/pdf') msg.attach(attachment_jnf_response['name'], pdf, 'application/pdf')
msg.send() msg.send()
return True return True
except: except:

View File

@ -44,7 +44,7 @@
<td style="padding:0 0 36px 0;color:#153643;"> <td style="padding:0 0 36px 0;color:#153643;">
<p style="margin:0 0 12px 0;font-size:16px;line-height:24px;font-family: 'Roboto', sans-serif;"> <p style="margin:0 0 12px 0;font-size:16px;line-height:24px;font-family: 'Roboto', sans-serif;">
We have received your Job Notification. Kindly verify your email by clicking <a We have received your Job Notification for {{ designation }}. Kindly verify your email by clicking <a
href="{{ one_time_link }}">here</a>. href="{{ one_time_link }}">here</a>.
</p> </p>
</td> </td>