From a98c359d9bf90e932089e55cb9d2fa9631a3c1d0 Mon Sep 17 00:00:00 2001 From: gowtham Date: Tue, 24 May 2022 15:05:53 +0530 Subject: [PATCH] Added updated at for applications --- CDC_Backend/APIs/adminViews.py | 40 ++++++------ CDC_Backend/APIs/companyViews.py | 19 +++--- CDC_Backend/APIs/constants.py | 3 +- CDC_Backend/APIs/models.py | 65 ++++++++++++++----- CDC_Backend/APIs/serializers.py | 8 +-- CDC_Backend/APIs/utils.py | 17 ++--- .../templates/company_email_verification.html | 2 +- 7 files changed, 92 insertions(+), 62 deletions(-) diff --git a/CDC_Backend/APIs/adminViews.py b/CDC_Backend/APIs/adminViews.py index 5ed0432..f588c19 100644 --- a/CDC_Backend/APIs/adminViews.py +++ b/CDC_Backend/APIs/adminViews.py @@ -59,8 +59,8 @@ def markStatus(request, id, email, user_type): def getDashboard(request, id, email, user_type): try: placements = Placement.objects.all().order_by('-created_at') - ongoing = placements.filter(deadline_datetime__gt=datetime.datetime.now(), offer_accepted=True, email_verified=True) - previous = placements.exclude(deadline_datetime__gt=datetime.datetime.now()).filter( + ongoing = placements.filter(deadline_datetime__gt=timezone.now(), offer_accepted=True, email_verified=True) + previous = placements.exclude(deadline_datetime__gt=timezone.now()).filter( offer_accepted=True, email_verified=True) new = placements.filter(offer_accepted__isnull=True, email_verified=True) ongoing = PlacementSerializerForAdmin(ongoing, many=True).data @@ -193,13 +193,13 @@ def getApplications(request, id, email, user_type): @api_view(['POST']) @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): try: data = request.data student = get_object_or_404(Student, pk=data[STUDENT_ID]) opening = get_object_or_404(Placement, pk=data[OPENING_ID]) - + if data[APPLICATION_ID] == "": application = PlacementApplication() application.id = generateRandomString() @@ -223,7 +223,7 @@ def submitApplication(request, id, email, user_type): application = get_object_or_404(PlacementApplication, id=data[APPLICATION_ID]) if application: if data[RESUME_FILE_NAME] in student.resumes: - application.resume = data[RESUME_FILE_NAME] + application.resume = data[RESUME_FILE_NAME] else: raise FileNotFoundError(RESUME_FILE_NAME + " Not Found") application.resume = data[RESUME_FILE_NAME] @@ -237,10 +237,10 @@ def submitApplication(request, id, email, user_type): application.additional_info = json.dumps(additional_info) application.save() return Response({'action': "Add Student Application", 'message': "Application updated"}, - status=status.HTTP_200_OK) + status=status.HTTP_200_OK) else: return Response({'action': "Edit Student Application", 'message': "No Application Found"}, - status=status.HTTP_400_BAD_REQUEST) + status=status.HTTP_400_BAD_REQUEST) except Http404 as e: return Response({'action': "Submit Application", 'message': str(e)}, @@ -301,7 +301,7 @@ def generateCSV(request, id, email, user_type): except: logger.warning("Create csv: " + str(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) @@ -331,7 +331,7 @@ def addPPO(request, id, email, user_type): except: logger.warning("Add PPO: " + str(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) @@ -350,7 +350,8 @@ def getStudentApplication(request, id, email, user_type): "resume_list": student_serializer.data['resume_list'], } # 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)) if application: serializer = PlacementApplicationSerializer(application[0]) @@ -359,16 +360,17 @@ def getStudentApplication(request, id, email, user_type): "additional_info": serializer.data['additional_info'], "resume": serializer.data['resume_link'], } - return Response({'action': "Get Student Application", 'application_found': "true", "application_info": application_info, - "student_details":student_details }, status=status.HTTP_200_OK) + return Response( + {'action': "Get Student Application", 'application_found': "true", "application_info": application_info, + "student_details": student_details}, status=status.HTTP_200_OK) else: - return Response({'action': "Get Student Application", 'application_found': "false", "student_details": student_details}, - status=status.HTTP_404_NOT_FOUND) + return Response( + {'action': "Get Student Application", 'application_found': "false", "student_details": student_details}, + status=status.HTTP_404_NOT_FOUND) except Http404: - logger.warning("Get Student Application: " + str(sys.exc_info())) - print(sys.exc_info()) - return Response({'action': "Get Student Application", 'message': "Student with given roll number not found."}, status.HTTP_400_BAD_REQUEST) + return Response({'action': "Get Student Application", 'message': "Student not found."}, + status.HTTP_404_NOT_FOUND) except: logger.warning("Get Student Application: " + str(sys.exc_info())) - print(sys.exc_info()) - return Response({'action': "Get Student Application", 'message': "Some error Occurred"}, status.HTTP_500_INTERNAL_SERVER_ERROR) + return Response({'action': "Get Student Application", 'message': "Something Went Wrong"}, + status.HTTP_400_BAD_REQUEST) diff --git a/CDC_Backend/APIs/companyViews.py b/CDC_Backend/APIs/companyViews.py index a1ec4b8..2593513 100644 --- a/CDC_Backend/APIs/companyViews.py +++ b/CDC_Backend/APIs/companyViews.py @@ -6,14 +6,14 @@ logger = logging.getLogger('db') @api_view(['POST']) -@precheck([COMPANY_NAME, ADDRESS, COMPANY_TYPE, NATURE_OF_BUSINESS, WEBSITE, COMPANY_DETAILS, IS_COMPANY_DETAILS_PDF, - CONTACT_PERSON_NAME, PHONE_NUMBER, EMAIL, CITY, STATE, COUNTRY, PINCODE, DESIGNATION, DESCRIPTION, - IS_DESCRIPTION_PDF, - COMPENSATION_CTC, COMPENSATION_GROSS, COMPENSATION_TAKE_HOME, COMPENSATION_BONUS, - IS_COMPENSATION_DETAILS_PDF, - ALLOWED_BRANCH, RS_ELIGIBLE, SELECTION_PROCEDURE_ROUNDS, SELECTION_PROCEDURE_DETAILS, IS_SELECTION_PROCEDURE_DETAILS_PDF, - TENTATIVE_DATE_OF_JOINING, - TENTATIVE_NO_OF_OFFERS, OTHER_REQUIREMENTS, RECAPTCHA_VALUE +@precheck([COMPANY_NAME, ADDRESS, COMPANY_TYPE, NATURE_OF_BUSINESS, TYPE_OF_ORGANISATION, WEBSITE, COMPANY_DETAILS, + IS_COMPANY_DETAILS_PDF, CONTACT_PERSON_NAME, PHONE_NUMBER, EMAIL, CITY, STATE, COUNTRY, PINCODE, DESIGNATION, + DESCRIPTION, + IS_DESCRIPTION_PDF, COMPENSATION_CTC, COMPENSATION_GROSS, COMPENSATION_TAKE_HOME, COMPENSATION_BONUS, + IS_COMPENSATION_DETAILS_PDF, ALLOWED_BRANCH, RS_ELIGIBLE, SELECTION_PROCEDURE_ROUNDS, + SELECTION_PROCEDURE_DETAILS, + IS_SELECTION_PROCEDURE_DETAILS_PDF, TENTATIVE_DATE_OF_JOINING, TENTATIVE_NO_OF_OFFERS, OTHER_REQUIREMENTS, + RECAPTCHA_VALUE, JOB_LOCATION ]) def addPlacement(request): try: @@ -29,6 +29,7 @@ def addPlacement(request): opening.address = data[ADDRESS] opening.company_type = data[COMPANY_TYPE] opening.nature_of_business = data[NATURE_OF_BUSINESS] + opening.type_of_organisation = data[TYPE_OF_ORGANISATION] opening.website = data[WEBSITE] opening.company_details = data[COMPANY_DETAILS] opening.is_company_details_pdf = data[IS_COMPANY_DETAILS_PDF] @@ -36,7 +37,6 @@ def addPlacement(request): opening.rs_eligible = True else: opening.rs_eligible = False - opening.job_locations = data[JOB_LOCATIONS] if opening.is_company_details_pdf: company_details_pdf = [] @@ -83,6 +83,7 @@ def addPlacement(request): # Add a designation details in the opening opening.designation = data[DESIGNATION] opening.description = data[DESCRIPTION] + opening.job_location = data[JOB_LOCATION] opening.is_description_pdf = data[IS_DESCRIPTION_PDF] if opening.is_description_pdf: diff --git a/CDC_Backend/APIs/constants.py b/CDC_Backend/APIs/constants.py index cc401de..5981cba 100644 --- a/CDC_Backend/APIs/constants.py +++ b/CDC_Backend/APIs/constants.py @@ -79,6 +79,7 @@ COMPANY_NAME = "company_name" ADDRESS = "address" COMPANY_TYPE = "company_type" NATURE_OF_BUSINESS = "nature_of_business" +TYPE_OF_ORGANISATION = "type_of_organisation" WEBSITE = 'website' COMPANY_DETAILS = "company_details" COMPANY_DETAILS_PDF = "company_details_pdf" @@ -97,7 +98,7 @@ DESCRIPTION_PDF = 'description_pdf' DESCRIPTION_PDF_NAMES = 'description_pdf_names' IS_DESCRIPTION_PDF = 'is_description_pdf' OPENING_TYPE = 'opening_type' -JOB_LOCATIONS = 'job_locations' +JOB_LOCATION = 'job_location' COMPENSATION_CTC = 'compensation_ctc' COMPENSATION_GROSS = 'compensation_gross' COMPENSATION_TAKE_HOME = 'compensation_take_home' diff --git a/CDC_Backend/APIs/models.py b/CDC_Backend/APIs/models.py index db25854..b986089 100644 --- a/CDC_Backend/APIs/models.py +++ b/CDC_Backend/APIs/models.py @@ -51,6 +51,7 @@ class Placement(models.Model): 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) 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) company_details = models.CharField(max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) company_details_pdf_names = ArrayField( @@ -68,6 +69,7 @@ class Placement(models.Model): # Job Details 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) + job_location = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") description_pdf_names = ArrayField( models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=5, default=list, blank=True) @@ -105,38 +107,63 @@ class Placement(models.Model): tentative_no_of_offers = models.IntegerField(blank=False, default=None, null=True) rs_eligible = models.BooleanField(blank=False, default=False) 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, default=list, blank=True) email_verified = models.BooleanField(blank=False, default=False) 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) created_at = models.DateTimeField(blank=False, default=None, null=True) + updated_at = models.DateTimeField(blank=False, default=None, null=True) def format(self): - self.company_name = self.company_name.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] - self.website = self.website.strip()[:JNF_TEXT_MAX_CHARACTER_COUNT] - self.company_details = self.company_details.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] - self.contact_person_name = self.contact_person_name.strip()[:JNF_TEXT_MAX_CHARACTER_COUNT] - self.email = self.email.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] - self.city = self.city.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] - self.state = self.state.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] - self.country = self.country.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] - self.city_type = self.city_type.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] - self.designation = self.designation.strip()[:JNF_TEXT_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] - self.bond_details = self.bond_details.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.company_name is not None: + 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] + if self.company_details is not None: + 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] + if self.email is not None: + 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] + if self.state is not None: + 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] + if self.city_type is not None: + 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] + if self.description is not None: + self.description = self.description.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] + if self.other_requirements is not None: + self.other_requirements = self.other_requirements.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + 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): ''' On save, add timestamps ''' if not self.created_at: self.created_at = timezone.now() self.format() + self.updated_at = timezone.now() return super(Placement, self).save(*args, **kwargs) def __str__(self): @@ -151,11 +178,13 @@ class PlacementApplication(models.Model): additional_info = models.JSONField(blank=True, null=True, default=None) selected = models.BooleanField(null=True, default=None, blank=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): ''' On save, add timestamps ''' if not self.applied_at: self.applied_at = timezone.now() + self.updated_at = timezone.now() return super(PlacementApplication, self).save(*args, **kwargs) diff --git a/CDC_Backend/APIs/serializers.py b/CDC_Backend/APIs/serializers.py index d3cd655..f7cc868 100644 --- a/CDC_Backend/APIs/serializers.py +++ b/CDC_Backend/APIs/serializers.py @@ -162,9 +162,7 @@ class PlacementApplicationSerializer(serializers.ModelSerializer): return data def get_resume_link(self, obj): - ele = {} - ele['link'] = LINK_TO_STORAGE_RESUME + urllib.parse.quote(obj.id + "/" + obj.resume) - ele['name'] = obj.resume + ele = {'link': LINK_TO_STORAGE_RESUME + urllib.parse.quote(obj.id + "/" + obj.resume), 'name': obj.resume} return ele class Meta: @@ -181,9 +179,7 @@ class PlacementApplicationSerializerForAdmin(serializers.ModelSerializer): return data def get_resume_link(self, obj): - ele = {} - ele['link'] = LINK_TO_STORAGE_RESUME + urllib.parse.quote(obj.id + "/" + obj.resume) - ele['name'] = obj.resume + ele = {'link': LINK_TO_STORAGE_RESUME + urllib.parse.quote(obj.id + "/" + obj.resume), 'name': obj.resume} return ele class Meta: diff --git a/CDC_Backend/APIs/utils.py b/CDC_Backend/APIs/utils.py index 827742a..83c2a93 100644 --- a/CDC_Backend/APIs/utils.py +++ b/CDC_Backend/APIs/utils.py @@ -20,6 +20,7 @@ from django.http import Http404 from django.shortcuts import get_object_or_404 from django.template.loader import render_to_string from django.utils.html import strip_tags +from django.utils import timezone from google.auth.transport import requests from google.oauth2 import id_token from rest_framework import status @@ -79,7 +80,7 @@ def isAuthorized(allowed_users=None): print(email) user = get_object_or_404(User, email=email) if user: - user.last_login_time = datetime.datetime.now() + user.last_login_time = timezone.now() user.save() 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) @@ -120,7 +121,7 @@ def generateRandomString(): def saveFile(file, location): prefix = generateRandomString() - file_name = prefix + "_" + file.name + file_name = prefix + "_" + file.name.strip() file_name = re.sub(r'[\\/:*?"<>|]', '_', file_name) @@ -137,8 +138,8 @@ def saveFile(file, location): return file_name -@background_task.background(schedule=10) -def sendEmail(email_to, subject, data, template, attachment_jnf_respone=None): +@background_task.background(schedule=5) +def sendEmail(email_to, subject, data, template, attachment_jnf_response=None): try: if not isinstance(data, dict): 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.attach_alternative(html_content, "text/html") - if attachment_jnf_respone: - logger.info(attachment_jnf_respone) - pdf = pdfkit.from_string(attachment_jnf_respone['html'], False, + if attachment_jnf_response: + logger.info(attachment_jnf_response) + pdf = pdfkit.from_string(attachment_jnf_response['html'], False, 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() return True except: diff --git a/CDC_Backend/templates/company_email_verification.html b/CDC_Backend/templates/company_email_verification.html index e4b6b19..16f39d4 100644 --- a/CDC_Backend/templates/company_email_verification.html +++ b/CDC_Backend/templates/company_email_verification.html @@ -44,7 +44,7 @@

- We have received your Job Notification. Kindly verify your email by clicking here.