From fecb2f3593bd048259994560e3025d556335c502 Mon Sep 17 00:00:00 2001 From: karthik-k-18 <200010024@iitdh.ac.in> Date: Sun, 11 Jun 2023 00:06:36 +0530 Subject: [PATCH 1/8] added field for offer acceptance --- .gitignore | 3 +++ CDC_Backend/APIs/companyViews.py | 2 +- CDC_Backend/APIs/constants.py | 2 +- CDC_Backend/APIs/models.py | 1 + CDC_Backend/APIs/studentUrls.py | 1 + CDC_Backend/APIs/studentViews.py | 8 +++++++- 6 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 445be84..64c7e13 100644 --- a/.gitignore +++ b/.gitignore @@ -140,3 +140,6 @@ dmypy.json .idea *.pyc dev.env + +#vscode settings +.vscode/ diff --git a/CDC_Backend/APIs/companyViews.py b/CDC_Backend/APIs/companyViews.py index 77d228e..590673e 100644 --- a/CDC_Backend/APIs/companyViews.py +++ b/CDC_Backend/APIs/companyViews.py @@ -194,7 +194,7 @@ def addPlacement(request): '%d-%m-%Y').date() # Only Allowing Fourth Year for Placement - opening.allowed_batch = [2017, 2018, 2019, 2020, 2021] + opening.allowed_batch = [FOURTH_YEAR,] # Check if allowed_branch are valid if data[ALLOWED_BRANCH] is None: raise ValueError('Allowed Branch cannot be empty') diff --git a/CDC_Backend/APIs/constants.py b/CDC_Backend/APIs/constants.py index 5696feb..526eb9e 100644 --- a/CDC_Backend/APIs/constants.py +++ b/CDC_Backend/APIs/constants.py @@ -66,7 +66,7 @@ SUPER_ADMIN = 's_admin' COMPANY = 'company' TIER = 'tier' # To be Configured Properly -FOURTH_YEAR = '2019' +FOURTH_YEAR = '2020' MAX_OFFERS_PER_STUDENT = 2 MAX_RESUMES_PER_STUDENT = 3 EMAIL_VERIFICATION_TOKEN_TTL = 48 # in hours diff --git a/CDC_Backend/APIs/models.py b/CDC_Backend/APIs/models.py index 77d8c6a..8f9360b 100644 --- a/CDC_Backend/APIs/models.py +++ b/CDC_Backend/APIs/models.py @@ -221,6 +221,7 @@ class PlacementApplication(models.Model): resume = models.CharField(max_length=JNF_TEXT_MAX_CHARACTER_COUNT, blank=False, null=True, default=None) additional_info = models.JSONField(blank=True, null=True, default=None) selected = models.BooleanField(null=True, default=None, blank=True) + offer_accepted = models.BooleanField(null=True, default=None, blank=True) # True if offer accepted, False if rejected, None if not yet decided applied_at = models.DateTimeField(blank=False, default=None, null=True) updated_at = models.DateTimeField(blank=False, default=None, null=True) changed_by = models.ForeignKey(User, blank=False, on_delete=models.RESTRICT, default=None, null=True) diff --git a/CDC_Backend/APIs/studentUrls.py b/CDC_Backend/APIs/studentUrls.py index 8a1acce..f9dee52 100644 --- a/CDC_Backend/APIs/studentUrls.py +++ b/CDC_Backend/APIs/studentUrls.py @@ -11,4 +11,5 @@ urlpatterns = [ path("submitApplication/", studentViews.submitApplication, name="Submit Application"), path("deleteApplication/", studentViews.deleteApplication, name="Delete Application"), path("getContributorStats/", studentViews.getContributorStats, name="Get Contributor Stats"), + path("studentAcceptOffer/", studentViews.studentAcceptOffer, name="Student Accept Offer"), ] diff --git a/CDC_Backend/APIs/studentViews.py b/CDC_Backend/APIs/studentViews.py index c68d846..50b4a6b 100644 --- a/CDC_Backend/APIs/studentViews.py +++ b/CDC_Backend/APIs/studentViews.py @@ -246,4 +246,10 @@ def getContributorStats(request, id, email, user_type): logger.warning("Get Contributor Stats: " + str(sys.exc_info())) return Response({'action': "Get Contributor Stats", 'message': "Something Went Wrong"}, - status=status.HTTP_400_BAD_REQUEST) \ No newline at end of file + status=status.HTTP_400_BAD_REQUEST) + +#view for sudentAcceptOffer +@api_view(['POST']) +@isAuthorized(allowed_users=[STUDENT]) +def studentAcceptOffer(request, id, email, user_type): + None \ No newline at end of file From c8398ee3dcd4e4bb335a96f767f0a912bcb37fc2 Mon Sep 17 00:00:00 2001 From: karthik-k-18 <200010024@iitdh.ac.in> Date: Wed, 14 Jun 2023 02:02:05 +0530 Subject: [PATCH 2/8] student_accepet view done --- CDC_Backend/APIs/studentViews.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/CDC_Backend/APIs/studentViews.py b/CDC_Backend/APIs/studentViews.py index 50b4a6b..e02e0f1 100644 --- a/CDC_Backend/APIs/studentViews.py +++ b/CDC_Backend/APIs/studentViews.py @@ -252,4 +252,17 @@ def getContributorStats(request, id, email, user_type): @api_view(['POST']) @isAuthorized(allowed_users=[STUDENT]) def studentAcceptOffer(request, id, email, user_type): - None \ No newline at end of file + try: + company_id = request.data['id'] + student_id=request.data['profileInfo']['id'] + offer_status = request.data['offerStatus'] + placement_application=PlacementApplication.objects.get(placement=company_id,student=student_id) + placement_application.offer_accepted=offer_status + placement_application.save() + return Response({'action': "Accept Offer", 'message': "Updated Offer Status"}, + status=status.HTTP_200_OK) + except: + logger.warning("Accept Offer: " + str(sys.exc_info())) + + return Response({'action': "Accept Offer", 'message': "Something Went Wrong"}, + status=status.HTTP_400_BAD_REQUEST) \ No newline at end of file From abc4c6f0bb357f38fca47ed2721bc67030228194 Mon Sep 17 00:00:00 2001 From: karthik-k-18 <200010024@iitdh.ac.in> Date: Thu, 29 Jun 2023 05:41:33 +0530 Subject: [PATCH 3/8] added all models --- CDC_Backend/CDC_Backend/settings.py | 1 + CDC_Backend/internAPIs/__init__.py | 0 CDC_Backend/internAPIs/admin.py | 10 ++ CDC_Backend/internAPIs/apps.py | 6 + CDC_Backend/internAPIs/constants.py | 189 ++++++++++++++++++++++++++++ CDC_Backend/internAPIs/models.py | 186 +++++++++++++++++++++++++++ CDC_Backend/internAPIs/tests.py | 3 + CDC_Backend/internAPIs/views.py | 3 + 8 files changed, 398 insertions(+) create mode 100644 CDC_Backend/internAPIs/__init__.py create mode 100644 CDC_Backend/internAPIs/admin.py create mode 100644 CDC_Backend/internAPIs/apps.py create mode 100644 CDC_Backend/internAPIs/constants.py create mode 100644 CDC_Backend/internAPIs/models.py create mode 100644 CDC_Backend/internAPIs/tests.py create mode 100644 CDC_Backend/internAPIs/views.py diff --git a/CDC_Backend/CDC_Backend/settings.py b/CDC_Backend/CDC_Backend/settings.py index 2447ee0..4f04556 100644 --- a/CDC_Backend/CDC_Backend/settings.py +++ b/CDC_Backend/CDC_Backend/settings.py @@ -41,6 +41,7 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'APIs', + 'internAPIs', 'rest_framework', 'corsheaders', 'django_db_logger', diff --git a/CDC_Backend/internAPIs/__init__.py b/CDC_Backend/internAPIs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/CDC_Backend/internAPIs/admin.py b/CDC_Backend/internAPIs/admin.py new file mode 100644 index 0000000..e0f38d1 --- /dev/null +++ b/CDC_Backend/internAPIs/admin.py @@ -0,0 +1,10 @@ +from django.contrib import admin + +# Register your models here. +from .models import * + +admin.site.register(Internship) + +admin.site.register(Season) + +admin.site.register(InternshipApplication) \ No newline at end of file diff --git a/CDC_Backend/internAPIs/apps.py b/CDC_Backend/internAPIs/apps.py new file mode 100644 index 0000000..d8cd54d --- /dev/null +++ b/CDC_Backend/internAPIs/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class InternapisConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'internAPIs' diff --git a/CDC_Backend/internAPIs/constants.py b/CDC_Backend/internAPIs/constants.py new file mode 100644 index 0000000..58e9431 --- /dev/null +++ b/CDC_Backend/internAPIs/constants.py @@ -0,0 +1,189 @@ +import os + +BRANCH_CHOICES = [ + ["CSE", "CSE"], + ["EE", "EE"], + ["ME", "ME"], + ['MMAE', 'MMAE'], + ['EP', 'EP'], +] +BRANCHES = [ + "CSE", + "EE", + "MMAE", + "EP" +] +BATCH_CHOICES = [ + ["2021", "2021"], + ["2020", "2020"], + ["2019", "2019"], + ["2018", "2018"], + ["2017", "2017"], +] + +OFFER_CITY_TYPE = [ + ['Domestic', 'Domestic'], + ['International', 'International'] +] + +FACILITIES_PROVIDED = [ + ['Accommodation', 'Accommodation'], + ['Food', 'Food'], + ['Transport', 'Transport'], + ['Medical', 'Medical'], +] + +TOTAL_FACILITIES = 4 + +TIERS = [ + ['psu', 'PSU'], + ['1', 'Tier 1'], + ['2', 'Tier 2'], + ['3', 'Tier 3'], + ['4', 'Tier 4'], + ['5', 'Tier 5'], + ['6', 'Tier 6'], + ['7', 'Tier 7'], +] + +SEASON_CHOICES = ( + ('summer', 'Summer'), + ('winter', 'Winter'), + ('monsoon', 'Monsoon'), + ('spring', 'Spring'), + ) + +DEGREE_CHOICES = [ + ['bTech', 'B.Tech'], + ['ms/phd', 'MS/ PhD'], +] + +TOTAL_BRANCHES = 4 # Total No of Branches +TOTAL_BATCHES = 5 # Total No of Batches + +CDC_MAIl_ADDRESS = 'cdc@iitdh.ac.in' + +# To be Configured Properly +CLIENT_ID = os.environ.get('GOOGLE_OAUTH_CLIENT_ID') # Google Login Client ID + +# To be Configured Properly +PLACEMENT_OPENING_URL = "https://cdc.iitdh.ac.in/portal/student/dashboard/placements/{id}" # On frontend, this is the URL to be opened +LINK_TO_STORAGE_COMPANY_ATTACHMENT = "https://cdc.iitdh.ac.in/storage/Company_Attachments/" +LINK_TO_STORAGE_RESUME = "https://cdc.iitdh.ac.in/storage/Resumes/" +LINK_TO_APPLICATIONS_CSV = "https://cdc.iitdh.ac.in/storage/Application_CSV/" +LINK_TO_EMAIl_VERIFICATION_API = "https://cdc.iitdh.ac.in/portal/company/verifyEmail?token={token}" +PDF_FILES_SERVING_ENDPOINT = 'https://cdc.iitdh.ac.in/storage/Company_Attachments/' # TODO: Change this to actual URL + +EMAIL = "email" + +STUDENT = 'student' +ADMIN = 'admin' +SUPER_ADMIN = 's_admin' +COMPANY = 'company' +TIER = 'tier' +# To be Configured Properly +FOURTH_YEAR = '2020' +MAX_OFFERS_PER_STUDENT = 2 +MAX_RESUMES_PER_STUDENT = 3 +EMAIL_VERIFICATION_TOKEN_TTL = 48 # in hours +JNF_TEXT_MAX_CHARACTER_COUNT = 100 +JNF_TEXTMEDIUM_MAX_CHARACTER_COUNT = 200 +JNF_TEXTAREA_MAX_CHARACTER_COUNT = 1000 +JNF_SMALLTEXT_MAX_CHARACTER_COUNT = 50 + +STORAGE_DESTINATION_RESUMES = "./Storage/Resumes/" +STORAGE_DESTINATION_COMPANY_ATTACHMENTS = './Storage/Company_Attachments/' +STORAGE_DESTINATION_APPLICATION_CSV = './Storage/Application_CSV/' + +TOKEN = 'token' +RESUME_FILE_NAME = 'resume_file_name' + +APPLICATION_ID = "application_id" +OPENING_ID = "opening_id" +ADDITIONAL_INFO = "additional_info" +FIELD = "field" + +STATUS_ACCEPTING_APPLICATIONS = "Accepting Applications" + +PLACEMENT = "Placement" + +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" +IS_COMPANY_DETAILS_PDF = "is_company_details_pdf" +COMPANY_DETAILS_PDF_NAMES = "company_details_pdf_names" +PHONE_NUMBER = 'phone_number' +CONTACT_PERSON_NAME = 'contact_person_name' +CITY = 'city' +STATE = 'state' +COUNTRY = 'country' +PINCODE = 'pincode' + +DESIGNATION = 'designation' +DESCRIPTION = 'description' +DESCRIPTION_PDF = 'description_pdf' +DESCRIPTION_PDF_NAMES = 'description_pdf_names' +IS_DESCRIPTION_PDF = 'is_description_pdf' +OPENING_TYPE = 'opening_type' +JOB_LOCATION = 'job_location' +COMPENSATION_CTC = 'compensation_ctc' +COMPENSATION_GROSS = 'compensation_gross' +COMPENSATION_TAKE_HOME = 'compensation_take_home' +COMPENSATION_BONUS = 'compensation_bonus' +COMPENSATION_DETAILS = 'compensation_details' +COMPENSATION_DETAILS_PDF = 'compensation_details_pdf' +COMPENSATION_DETAILS_PDF_NAMES = 'compensation_details_pdf_names' +IS_COMPENSATION_DETAILS_PDF = 'is_compensation_details_pdf' +ALLOWED_BATCH = 'allowed_batch' +ALLOWED_BRANCH = 'allowed_branch' +RS_ELIGIBLE = 'rs_eligible' +BOND_DETAILS = 'bond_details' +SELECTION_PROCEDURE_ROUNDS = 'selection_procedure_rounds' +SELECTION_PROCEDURE_DETAILS = 'selection_procedure_details' +SELECTION_PROCEDURE_DETAILS_PDF = 'selection_procedure_details_pdf' +SELECTION_PROCEDURE_DETAILS_PDF_NAMES = 'selection_procedure_details_pdf_names' +IS_SELECTION_PROCEDURE_DETAILS_PDF = 'is_selection_procedure_details_pdf' +TENTATIVE_DATE_OF_JOINING = 'tentative_date_of_joining' +TENTATIVE_NO_OF_OFFERS = 'tentative_no_of_offers' +OTHER_REQUIREMENTS = 'other_requirements' +DEADLINE_DATETIME = 'deadline_datetime' +OFFER_ACCEPTED = 'offer_accepted' +EMAIL_VERIFIED = 'email_verified' +RECAPTCHA_VALUE = 'recaptchakey' + +STUDENT_LIST = "student_list" +STUDENT_ID = "student_id" +STUDENT_SELECTED = "student_selected" + +EXCLUDE_IN_PDF = ['id', 'is_company_details_pdf', 'offer_accepted', 'is_description_pdf', + 'is_compensation_details_pdf', 'is_selection_procedure_details_pdf', + 'email_verified', 'created_at'] +SPECIAL_FORMAT_IN_PDF = ['website', 'company_details_pdf_names', 'description_pdf_names', + 'compensation_details_pdf_names', + 'selection_procedure_details_pdf_names'] + +COMPANY_OPENING_ERROR_TEMPLATE = "Alert! Error submitting opening for {company_name}." +COMPANY_OPENING_SUBMITTED_TEMPLATE_SUBJECT = "Notification Submitted - {id} - Career Development Cell, IIT Dharwad" +STUDENT_APPLICATION_STATUS_TEMPLATE_SUBJECT = 'Application Status - {company_name} - {id}' +STUDENT_APPLICATION_SUBMITTED_TEMPLATE_SUBJECT = 'CDC - Application Submitted - {company_name}' +STUDENT_APPLICATION_UPDATED_TEMPLATE_SUBJECT = 'CDC - Application Updated - {company_name}' +COMPANY_EMAIl_VERIFICATION_TEMPLATE_SUBJECT = 'Email Verification - Career Development Cell, IIT Dharwad' +NOTIFY_STUDENTS_OPENING_TEMPLATE_SUBJECT = 'Placement Opportunity at {company_name}' + +STUDENT_APPLICATION_SUBMITTED_TEMPLATE = 'student_application_submitted.html' +COMPANY_OPENING_SUBMITTED_TEMPLATE = 'company_opening_submitted.html' +STUDENT_APPLICATION_STATUS_SELECTED_TEMPLATE = 'student_application_status_selected.html' +STUDENT_APPLICATION_STATUS_NOT_SELECTED_TEMPLATE = 'student_application_status_not_selected.html' +STUDENT_APPLICATION_UPDATED_TEMPLATE = 'student_application_updated.html' +COMPANY_EMAIL_VERIFICATION_TEMPLATE = 'company_email_verification.html' +COMPANY_JNF_RESPONSE_TEMPLATE = 'company_jnf_response.html' +NOTIFY_STUDENTS_OPENING_TEMPLATE = 'notify_students_new_opening.html' + +APPLICATION_CSV_COL_NAMES = ['Applied At', 'Roll No.', 'Name', 'Email', 'Phone Number', 'Branch', 'Batch', 'CPI', + 'Resume', 'Selected', ] + diff --git a/CDC_Backend/internAPIs/models.py b/CDC_Backend/internAPIs/models.py new file mode 100644 index 0000000..a8da702 --- /dev/null +++ b/CDC_Backend/internAPIs/models.py @@ -0,0 +1,186 @@ +from django.db import models + +# Create your models here. +from django.contrib.postgres.fields import ArrayField +from django.db import models +from django.utils import timezone +from simple_history.models import HistoricalRecords + +from .constants import * + +#import models from other apps +from APIs.models import User,Student + +# Create your models here. +class Internship(models.Model): + id = models.CharField(blank=False, primary_key=True, max_length=15) #unique id for each internship + # Company Details + company_name = models.CharField(blank=False, max_length=JNF_SMALLTEXT_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) + 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, blank=True) + company_details_pdf_names = ArrayField( + models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=5, + default=list, blank=True) + is_company_details_pdf = models.BooleanField(blank=False, default=False) + #Company Address + city = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + state = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + country = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + pin_code = models.IntegerField(blank=False, default=None, null=True) + # selection process + selection_procedure_rounds = ArrayField( + models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=10, + default=list, blank=True) + selection_procedure_details = models.CharField(blank=True, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT) + selection_procedure_details_pdf_names = ArrayField( + models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), + size=5, default=list, blank=True) + is_selection_procedure_details_pdf = models.BooleanField(blank=False, default=False) + #Internship Details + description_pdf_names = ArrayField( + models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=5, default=list, + blank=True) + is_description_pdf = models.BooleanField(blank=False, default=False) + description = models.CharField(blank=False, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) + interning_period_from = models.DateField(blank=False, default=None, null=True) + interning_period_to = models.DateField(blank=False, default=None, null=True) + is_work_from_home = models.BooleanField(blank=False, default=False) + sophomore_eligible = models.BooleanField(blank=False, default=False) + tentative_no_of_offers = models.IntegerField(blank=False, default=None, null=True) + stipend_description_pdf_names=ArrayField( + models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=5, default=list, + blank=True) + is_stipend_description_pdf = models.BooleanField(blank=False, default=False) + stipend=models.IntegerField(blank=False, default=None, null=True) + facilities_provided=ArrayField( + models.CharField(choices=FACILITIES_PROVIDED, blank=False, max_length=20), + size=TOTAL_FACILITIES, + default=list + ) + additional_facilities = models.CharField(blank=True, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) + academic_requirements = models.CharField(blank=True, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) + #contact details of company person + contact_person_name = models.CharField(blank=False, max_length=JNF_TEXT_MAX_CHARACTER_COUNT) + phone_number = models.PositiveBigIntegerField(blank=False) + email = models.EmailField(blank=False) + contact_person_designation = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + telephone_number = models.PositiveBigIntegerField(blank=True, default=None, null=True) + email_verified = models.BooleanField(blank=False, default=False) + #history + created_at = models.DateTimeField(blank=False, default=None, null=True) + updated_at = models.DateTimeField(blank=False, default=None, null=True) + changed_by = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True) + history = HistoricalRecords(user_model=User) + + + def format(self): + 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.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.selection_procedure_details is not None: + self.selection_procedure_details = self.selection_procedure_details.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + if self.description is not None: + self.description = self.description.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + if self.additional_facilities is not None: + self.additional_facilities = self.additional_facilities.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + if self.academic_requirements is not None: + self.academic_requirements = self.academic_requirements.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + if self.contact_person_designation is not None: + self.contact_person_designation = self.contact_person_designation.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] + + @property + def _history_user(self): + return self.changed_by + + @_history_user.setter + def _history_user(self, value): + if isinstance(value, User): + self.changed_by = value + else: + self.changed_by = None + + 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(Internship, self).save(*args, **kwargs) + + def __str__(self): + return self.company_name + " - " + self.id + + + +class Season(models.Model): + + season = models.CharField(max_length=10, choices=SEASON_CHOICES, unique=True) + student = models.ForeignKey(Student, on_delete=models.CASCADE, default=None) + + def __str__(self): + return self.season + " Season - " + self.student.id + +class InternshipApplication(models.Model): + id = models.CharField(blank=False, primary_key=True, max_length=15) #unique id for each internship + internship=models.ForeignKey(Internship,blank=False, on_delete=models.CASCADE, default=None) + student=models.ForeignKey(Student,blank=False, on_delete=models.CASCADE, default=None) + resume = models.CharField(max_length=JNF_TEXT_MAX_CHARACTER_COUNT, blank=False, null=True, default=None) + additional_info = models.JSONField(blank=True, null=True, default=None) + selected = models.BooleanField(null=True, default=None, blank=True) + offer_accepted = models.BooleanField(null=True, default=None, blank=True) # True if offer accepted, False if rejected, None if not yet decided + applied_at = models.DateTimeField(blank=False, default=None, null=True) + updated_at = models.DateTimeField(blank=False, default=None, null=True) + changed_by = models.ForeignKey(User, blank=False, on_delete=models.RESTRICT, default=None, null=True) + history = HistoricalRecords(user_model=User) + + 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(InternshipApplication, self).save(*args, **kwargs) + + @property + def _history_user(self): + return self.changed_by + + @_history_user.setter + def _history_user(self, value): + if isinstance(value, User): + self.changed_by = value + else: + self.changed_by = None + + class Meta: + verbose_name_plural = "Internship Applications" + unique_together = ('internship', 'student') + + def __str__(self): + return self.internship.company_name + " - " + self.student.name + \ No newline at end of file diff --git a/CDC_Backend/internAPIs/tests.py b/CDC_Backend/internAPIs/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/CDC_Backend/internAPIs/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/CDC_Backend/internAPIs/views.py b/CDC_Backend/internAPIs/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/CDC_Backend/internAPIs/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. From e436d42ae96c4ed1f163273dd05289e8007d45f7 Mon Sep 17 00:00:00 2001 From: karthik-k-18 <200010024@iitdh.ac.in> Date: Thu, 29 Jun 2023 05:45:45 +0530 Subject: [PATCH 4/8] modified constants.py --- CDC_Backend/internAPIs/constants.py | 8 +-- CDC_Backend/internAPIs/models.py | 78 ++++++++++++++--------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/CDC_Backend/internAPIs/constants.py b/CDC_Backend/internAPIs/constants.py index 58e9431..4465ffa 100644 --- a/CDC_Backend/internAPIs/constants.py +++ b/CDC_Backend/internAPIs/constants.py @@ -86,10 +86,10 @@ FOURTH_YEAR = '2020' MAX_OFFERS_PER_STUDENT = 2 MAX_RESUMES_PER_STUDENT = 3 EMAIL_VERIFICATION_TOKEN_TTL = 48 # in hours -JNF_TEXT_MAX_CHARACTER_COUNT = 100 -JNF_TEXTMEDIUM_MAX_CHARACTER_COUNT = 200 -JNF_TEXTAREA_MAX_CHARACTER_COUNT = 1000 -JNF_SMALLTEXT_MAX_CHARACTER_COUNT = 50 +INF_TEXT_MAX_CHARACTER_COUNT = 100 +INF_TEXTMEDIUM_MAX_CHARACTER_COUNT = 200 +INF_TEXTAREA_MAX_CHARACTER_COUNT = 1000 +INF_SMALLTEXT_MAX_CHARACTER_COUNT = 50 STORAGE_DESTINATION_RESUMES = "./Storage/Resumes/" STORAGE_DESTINATION_COMPANY_ATTACHMENTS = './Storage/Company_Attachments/' diff --git a/CDC_Backend/internAPIs/models.py b/CDC_Backend/internAPIs/models.py index a8da702..93fbcad 100644 --- a/CDC_Backend/internAPIs/models.py +++ b/CDC_Backend/internAPIs/models.py @@ -15,44 +15,44 @@ from APIs.models import User,Student class Internship(models.Model): id = models.CharField(blank=False, primary_key=True, max_length=15) #unique id for each internship # Company Details - company_name = models.CharField(blank=False, max_length=JNF_SMALLTEXT_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) - 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, blank=True) + company_name = models.CharField(blank=False, max_length=INF_SMALLTEXT_MAX_CHARACTER_COUNT) + address = models.CharField(blank=False, max_length=INF_TEXTAREA_MAX_CHARACTER_COUNT) + company_type = models.CharField(blank=False, max_length=INF_SMALLTEXT_MAX_CHARACTER_COUNT) + nature_of_business = models.CharField(blank=False, max_length=INF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + type_of_organisation = models.CharField(max_length=INF_SMALLTEXT_MAX_CHARACTER_COUNT, default="", blank=False) + website = models.CharField(blank=True, max_length=INF_TEXT_MAX_CHARACTER_COUNT) + company_details = models.CharField(max_length=INF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True, blank=True) company_details_pdf_names = ArrayField( - models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=5, + models.CharField(null=True, default=None, max_length=INF_TEXT_MAX_CHARACTER_COUNT), size=5, default=list, blank=True) is_company_details_pdf = models.BooleanField(blank=False, default=False) #Company Address - city = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") - state = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") - country = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + city = models.CharField(blank=False, max_length=INF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + state = models.CharField(blank=False, max_length=INF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + country = models.CharField(blank=False, max_length=INF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") pin_code = models.IntegerField(blank=False, default=None, null=True) # selection process selection_procedure_rounds = ArrayField( - models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=10, + models.CharField(null=True, default=None, max_length=INF_TEXT_MAX_CHARACTER_COUNT), size=10, default=list, blank=True) - selection_procedure_details = models.CharField(blank=True, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT) + selection_procedure_details = models.CharField(blank=True, max_length=INF_TEXTAREA_MAX_CHARACTER_COUNT) selection_procedure_details_pdf_names = ArrayField( - models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), + models.CharField(null=True, default=None, max_length=INF_TEXT_MAX_CHARACTER_COUNT), size=5, default=list, blank=True) is_selection_procedure_details_pdf = models.BooleanField(blank=False, default=False) #Internship Details 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=INF_TEXT_MAX_CHARACTER_COUNT), size=5, default=list, blank=True) is_description_pdf = models.BooleanField(blank=False, default=False) - description = models.CharField(blank=False, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) + description = models.CharField(blank=False, max_length=INF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) interning_period_from = models.DateField(blank=False, default=None, null=True) interning_period_to = models.DateField(blank=False, default=None, null=True) is_work_from_home = models.BooleanField(blank=False, default=False) sophomore_eligible = models.BooleanField(blank=False, default=False) tentative_no_of_offers = models.IntegerField(blank=False, default=None, null=True) stipend_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=INF_TEXT_MAX_CHARACTER_COUNT), size=5, default=list, blank=True) is_stipend_description_pdf = models.BooleanField(blank=False, default=False) stipend=models.IntegerField(blank=False, default=None, null=True) @@ -61,13 +61,13 @@ class Internship(models.Model): size=TOTAL_FACILITIES, default=list ) - additional_facilities = models.CharField(blank=True, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) - academic_requirements = models.CharField(blank=True, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) + additional_facilities = models.CharField(blank=True, max_length=INF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) + academic_requirements = models.CharField(blank=True, max_length=INF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) #contact details of company person - contact_person_name = models.CharField(blank=False, max_length=JNF_TEXT_MAX_CHARACTER_COUNT) + contact_person_name = models.CharField(blank=False, max_length=INF_TEXT_MAX_CHARACTER_COUNT) phone_number = models.PositiveBigIntegerField(blank=False) email = models.EmailField(blank=False) - contact_person_designation = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + contact_person_designation = models.CharField(blank=False, max_length=INF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") telephone_number = models.PositiveBigIntegerField(blank=True, default=None, null=True) email_verified = models.BooleanField(blank=False, default=False) #history @@ -79,39 +79,39 @@ class Internship(models.Model): 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()[:INF_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()[:INF_SMALLTEXT_MAX_CHARACTER_COUNT] if self.company_details is not None: - self.company_details = self.company_details.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + self.company_details = self.company_details.strip()[:INF_TEXTAREA_MAX_CHARACTER_COUNT] if self.address is not None: - self.address = self.address.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + self.address = self.address.strip()[:INF_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] + self.nature_of_business = self.nature_of_business.strip()[:INF_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] + self.type_of_organisation = self.type_of_organisation.strip()[:INF_TEXTAREA_MAX_CHARACTER_COUNT] if self.website is not None: - self.website = self.website.strip()[:JNF_TEXT_MAX_CHARACTER_COUNT] + self.website = self.website.strip()[:INF_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()[:INF_TEXT_MAX_CHARACTER_COUNT] if self.city is not None: - self.city = self.city.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] + self.city = self.city.strip()[:INF_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()[:INF_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()[:INF_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()[:INF_SMALLTEXT_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] + self.selection_procedure_details = self.selection_procedure_details.strip()[:INF_TEXTAREA_MAX_CHARACTER_COUNT] if self.description is not None: - self.description = self.description.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + self.description = self.description.strip()[:INF_TEXTAREA_MAX_CHARACTER_COUNT] if self.additional_facilities is not None: - self.additional_facilities = self.additional_facilities.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + self.additional_facilities = self.additional_facilities.strip()[:INF_TEXTAREA_MAX_CHARACTER_COUNT] if self.academic_requirements is not None: - self.academic_requirements = self.academic_requirements.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + self.academic_requirements = self.academic_requirements.strip()[:INF_TEXTAREA_MAX_CHARACTER_COUNT] if self.contact_person_designation is not None: - self.contact_person_designation = self.contact_person_designation.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] + self.contact_person_designation = self.contact_person_designation.strip()[:INF_SMALLTEXT_MAX_CHARACTER_COUNT] @property def _history_user(self): @@ -149,7 +149,7 @@ class InternshipApplication(models.Model): id = models.CharField(blank=False, primary_key=True, max_length=15) #unique id for each internship internship=models.ForeignKey(Internship,blank=False, on_delete=models.CASCADE, default=None) student=models.ForeignKey(Student,blank=False, on_delete=models.CASCADE, default=None) - resume = models.CharField(max_length=JNF_TEXT_MAX_CHARACTER_COUNT, blank=False, null=True, default=None) + resume = models.CharField(max_length=INF_TEXT_MAX_CHARACTER_COUNT, blank=False, null=True, default=None) additional_info = models.JSONField(blank=True, null=True, default=None) selected = models.BooleanField(null=True, default=None, blank=True) offer_accepted = models.BooleanField(null=True, default=None, blank=True) # True if offer accepted, False if rejected, None if not yet decided From 2d18135a4a13b23205437e6c3a80a8c465987901 Mon Sep 17 00:00:00 2001 From: karthikmurakonda Date: Tue, 11 Jul 2023 19:54:04 +0530 Subject: [PATCH 5/8] updated .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 43f423c..1c22318 100644 --- a/.gitignore +++ b/.gitignore @@ -135,6 +135,8 @@ dmypy.json /CDC_Backend/CDC_Backend/__pycache__/ /CDC_Backend/APIs/__pycache__/ /CDC_Backend/APIs/migrations/ +/CDC_Backend/internAPIs/__pycache__/ +/CDC_Backend/internAPIs/migrations/ /CDC_Backend/static/ /CDC_Backend/Storage/ .idea From 4e8577255755935c0c1b978b0907b8b407b1e6b1 Mon Sep 17 00:00:00 2001 From: karthikmurakonda Date: Thu, 13 Jul 2023 00:03:48 +0530 Subject: [PATCH 6/8] init views and add season attribute to internship --- CDC_Backend/CDC_Backend/urls.py | 3 ++- CDC_Backend/internAPIs/companyUrls.py | 7 +++++++ CDC_Backend/internAPIs/companyViews.py | 4 ++++ CDC_Backend/internAPIs/constants.py | 8 ++++---- CDC_Backend/internAPIs/models.py | 1 + CDC_Backend/internAPIs/urls.py | 7 +++++++ 6 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 CDC_Backend/internAPIs/companyUrls.py create mode 100644 CDC_Backend/internAPIs/companyViews.py create mode 100644 CDC_Backend/internAPIs/urls.py diff --git a/CDC_Backend/CDC_Backend/urls.py b/CDC_Backend/CDC_Backend/urls.py index 6a3f873..69ba9ea 100644 --- a/CDC_Backend/CDC_Backend/urls.py +++ b/CDC_Backend/CDC_Backend/urls.py @@ -3,5 +3,6 @@ from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), - path('api/', include('APIs.urls')) + path('api/', include('APIs.urls')), + path('internapi/', include('internAPIs.urls')) ] diff --git a/CDC_Backend/internAPIs/companyUrls.py b/CDC_Backend/internAPIs/companyUrls.py new file mode 100644 index 0000000..7fd2773 --- /dev/null +++ b/CDC_Backend/internAPIs/companyUrls.py @@ -0,0 +1,7 @@ +from django.urls import path + +from . import companyViews + +urlpatterns = [ + path('addInternship/', companyViews.addInternship, name="Add Internship"), +] diff --git a/CDC_Backend/internAPIs/companyViews.py b/CDC_Backend/internAPIs/companyViews.py new file mode 100644 index 0000000..1d55cf1 --- /dev/null +++ b/CDC_Backend/internAPIs/companyViews.py @@ -0,0 +1,4 @@ + + +def addInternship(request): + pass diff --git a/CDC_Backend/internAPIs/constants.py b/CDC_Backend/internAPIs/constants.py index 4465ffa..20081d1 100644 --- a/CDC_Backend/internAPIs/constants.py +++ b/CDC_Backend/internAPIs/constants.py @@ -47,10 +47,10 @@ TIERS = [ ] SEASON_CHOICES = ( - ('summer', 'Summer'), - ('winter', 'Winter'), - ('monsoon', 'Monsoon'), - ('spring', 'Spring'), + ['summer', 'Summer'], + ['winter', 'Winter'], + ['autumn', 'Autumn'], + ['spring', 'Spring'], ) DEGREE_CHOICES = [ diff --git a/CDC_Backend/internAPIs/models.py b/CDC_Backend/internAPIs/models.py index 93fbcad..cfb896c 100644 --- a/CDC_Backend/internAPIs/models.py +++ b/CDC_Backend/internAPIs/models.py @@ -48,6 +48,7 @@ class Internship(models.Model): description = models.CharField(blank=False, max_length=INF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) interning_period_from = models.DateField(blank=False, default=None, null=True) interning_period_to = models.DateField(blank=False, default=None, null=True) + season = models.CharField(blank=False, max_length=10, choices=SEASON_CHOICES, default=None) is_work_from_home = models.BooleanField(blank=False, default=False) sophomore_eligible = models.BooleanField(blank=False, default=False) tentative_no_of_offers = models.IntegerField(blank=False, default=None, null=True) diff --git a/CDC_Backend/internAPIs/urls.py b/CDC_Backend/internAPIs/urls.py new file mode 100644 index 0000000..411db7d --- /dev/null +++ b/CDC_Backend/internAPIs/urls.py @@ -0,0 +1,7 @@ +from django.urls import path, include + +from . import companyUrls + +urlpatterns = [ + path('company/', include(companyUrls)), +] From 47be3b81904838846bf8af43a01eb0bf14380302 Mon Sep 17 00:00:00 2001 From: karthikmurakonda Date: Mon, 24 Jul 2023 19:00:52 +0530 Subject: [PATCH 7/8] init interns support --- CDC_Backend/APIs/admin.py | 2 + CDC_Backend/APIs/companyViews.py | 10 +++ CDC_Backend/APIs/constants.py | 20 +++++ CDC_Backend/APIs/models.py | 133 +++++++++++++++++++++++++++- CDC_Backend/CDC_Backend/settings.py | 1 - 5 files changed, 164 insertions(+), 2 deletions(-) diff --git a/CDC_Backend/APIs/admin.py b/CDC_Backend/APIs/admin.py index 08ac51b..6b80e78 100644 --- a/CDC_Backend/APIs/admin.py +++ b/CDC_Backend/APIs/admin.py @@ -161,3 +161,5 @@ class PrePlacementOffer(PrePlacementOfferAdmin): def Student(self, obj): return model_admin_url(obj.student) + +admin.site.register(Internship) \ No newline at end of file diff --git a/CDC_Backend/APIs/companyViews.py b/CDC_Backend/APIs/companyViews.py index 60e144c..467f6df 100644 --- a/CDC_Backend/APIs/companyViews.py +++ b/CDC_Backend/APIs/companyViews.py @@ -320,3 +320,13 @@ def autoFillJnf(request): logger.warning("Get AutoFill: " + traceback_str) return Response({'action': "Get AutoFill", 'message': "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST) + + +## Internships ## + + +@api_view(['POST']) +def addInternship(request): + logger.info(request.data) + return Response({'action': "Add Internship", 'message': "Internship Added Successfully"}, + status=status.HTTP_200_OK) diff --git a/CDC_Backend/APIs/constants.py b/CDC_Backend/APIs/constants.py index d2daf91..f792f6b 100644 --- a/CDC_Backend/APIs/constants.py +++ b/CDC_Backend/APIs/constants.py @@ -178,3 +178,23 @@ REMINDER_STUDENTS_OPENING_TEMPLATE = 'students_opening_reminder.html' APPLICATION_CSV_COL_NAMES = ['Applied At', 'Roll No.', 'Name', 'Email', 'Phone Number', 'Branch', 'Batch', 'CPI', 'Resume', 'Selected', ] + + +# Internships +SEASON_CHOICES = ( + ['summer', 'Summer'], + ['winter', 'Winter'], + ['autumn', 'Autumn'], + ['spring', 'Spring'], + ) + +INF_FACILITIES_PROVIDED = [ + ['Accommodation', 'Accommodation'], + ['Food', 'Food'], + ['Transport', 'Transport'], + ['Medical', 'Medical'], +] + +INF_TOTAL_SEASONS = 4 + +INF_TOTAL_FACILITIES = 4 diff --git a/CDC_Backend/APIs/models.py b/CDC_Backend/APIs/models.py index 8f9360b..1bc05ff 100644 --- a/CDC_Backend/APIs/models.py +++ b/CDC_Backend/APIs/models.py @@ -144,7 +144,7 @@ class Placement(models.Model): 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) - changed_by = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True) + changed_by = models.ForeignKey(User, on_delete=models.RESTRICT, blank=True, null=True) history = HistoricalRecords(user_model=User) def format(self): @@ -278,6 +278,137 @@ class PrePlacementOffer(models.Model): else: self.changed_by = None +class Internship(models.Model): + id = models.CharField(blank=False, primary_key=True, max_length=15) #unique id for each internship + # Company Details + company_name = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT) + website = models.CharField(blank=True, max_length=JNF_TEXT_MAX_CHARACTER_COUNT) + is_company_details_pdf = models.BooleanField(blank=False, default=False) + company_details_pdf_names = ArrayField( + models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=5, + default=list, blank=True) + company_details = models.CharField(max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True, blank=True) + #Company Address + address = models.CharField(blank=False, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT) + city = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + state = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + country = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + pin_code = models.IntegerField(blank=False, default=None, null=True) + 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) + #Internship Details + is_description_pdf = models.BooleanField(blank=False, default=False) + description_pdf_names = ArrayField( + models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=5, default=list, + blank=True) + designation = models.CharField(blank=False, max_length=JNF_TEXT_MAX_CHARACTER_COUNT, default="") + description = models.CharField(blank=False, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) + location = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + season = ArrayField( + models.CharField(choices=SEASON_CHOICES, max_length=10, blank=False), + size=INF_TOTAL_SEASONS, + default=list + ) + interning_period_from = models.DateField(blank=False, default=None, null=True) + interning_period_to = models.DateField(blank=False, default=None, null=True) + is_work_from_home = models.BooleanField(blank=False, default=False) + sophomore_eligible = models.BooleanField(blank=False, default=False) + rs_eligible = models.BooleanField(blank=False, default=False) + tentative_no_of_offers = models.IntegerField(blank=False, default=None, null=True) + is_stipend_description_pdf = models.BooleanField(blank=False, default=False) + stipend_description_pdf_names=ArrayField( + models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=5, default=list, + blank=True) + stipend=models.IntegerField(blank=False, default=None, null=True) + facilities_provided=ArrayField( + models.CharField(choices=INF_FACILITIES_PROVIDED, blank=False, max_length=20), + size=INF_TOTAL_FACILITIES, + default=list + ) + additional_facilities = models.CharField(blank=True, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) + academic_requirements = models.CharField(blank=True, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT, default=None, null=True) + # selection process + selection_procedure_rounds = ArrayField( + models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), size=10, + default=list, blank=True) + selection_procedure_details = models.CharField(blank=True, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT) + selection_procedure_details_pdf_names = ArrayField( + models.CharField(null=True, default=None, max_length=JNF_TEXT_MAX_CHARACTER_COUNT), + size=5, default=list, blank=True) + is_selection_procedure_details_pdf = models.BooleanField(blank=False, default=False) + #contact details of company person + contact_person_name = models.CharField(blank=False, max_length=JNF_TEXT_MAX_CHARACTER_COUNT) + phone_number = models.PositiveBigIntegerField(blank=False) + email = models.EmailField(blank=False) + contact_person_designation = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + telephone_number = models.PositiveBigIntegerField(blank=True, default=None, null=True) + email_verified = models.BooleanField(blank=False, default=False) + #history + created_at = models.DateTimeField(blank=False, default=None, null=True) + updated_at = models.DateTimeField(blank=False, default=None, null=True) + changed_by = models.ForeignKey(User, on_delete=models.RESTRICT, blank=True, null=True) + history = HistoricalRecords(user_model=User) + + + def format(self): + 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.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.selection_procedure_details is not None: + self.selection_procedure_details = self.selection_procedure_details.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + if self.description is not None: + self.description = self.description.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + if self.additional_facilities is not None: + self.additional_facilities = self.additional_facilities.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + if self.academic_requirements is not None: + self.academic_requirements = self.academic_requirements.strip()[:JNF_TEXTAREA_MAX_CHARACTER_COUNT] + if self.contact_person_designation is not None: + self.contact_person_designation = self.contact_person_designation.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT] + + @property + def _history_user(self): + return self.changed_by + + @_history_user.setter + def _history_user(self, value): + if isinstance(value, User): + self.changed_by = value + else: + self.changed_by = None + + 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(Internship, self).save(*args, **kwargs) + + def __str__(self): + return self.company_name + " - " + self.id + class Contributor(models.Model): id = models.AutoField(primary_key=True) diff --git a/CDC_Backend/CDC_Backend/settings.py b/CDC_Backend/CDC_Backend/settings.py index 786e67b..7df7fc3 100644 --- a/CDC_Backend/CDC_Backend/settings.py +++ b/CDC_Backend/CDC_Backend/settings.py @@ -41,7 +41,6 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'APIs', - 'internAPIs', 'rest_framework', 'corsheaders', 'django_db_logger', From e3d111e8d5fc0ad18af194ff0dbedc65920dbb22 Mon Sep 17 00:00:00 2001 From: karthikmurakonda Date: Tue, 25 Jul 2023 00:34:39 +0530 Subject: [PATCH 8/8] added internship view --- CDC_Backend/APIs/companyUrls.py | 1 + CDC_Backend/APIs/companyViews.py | 196 +++++++++++++++++++++++++++- CDC_Backend/APIs/constants.py | 34 ++++- CDC_Backend/APIs/models.py | 9 +- CDC_Backend/APIs/utils.py | 10 +- CDC_Backend/internAPIs/constants.py | 2 +- CDC_Backend/run_prod.sh | 2 +- 7 files changed, 240 insertions(+), 14 deletions(-) diff --git a/CDC_Backend/APIs/companyUrls.py b/CDC_Backend/APIs/companyUrls.py index e09de52..3dcaa27 100644 --- a/CDC_Backend/APIs/companyUrls.py +++ b/CDC_Backend/APIs/companyUrls.py @@ -6,4 +6,5 @@ urlpatterns = [ path('addPlacement/', companyViews.addPlacement, name="Add Placement"), path('verifyEmail/', companyViews.verifyEmail, name="Verify Email"), path('getAutoFillJnf/', companyViews.autoFillJnf, name="Auto FIll JNF"), + path('addInternship/',companyViews.addInternship,name="Add Internship"), ] diff --git a/CDC_Backend/APIs/companyViews.py b/CDC_Backend/APIs/companyViews.py index 467f6df..cb0cf7f 100644 --- a/CDC_Backend/APIs/companyViews.py +++ b/CDC_Backend/APIs/companyViews.py @@ -167,7 +167,7 @@ def addPlacement(request): opening.selection_procedure_details = data[SELECTION_PROCEDURE_DETAILS] opening.is_selection_procedure_details_pdf = data[IS_SELECTION_PROCEDURE_DETAILS_PDF] - if opening.is_selection_procedure_details_pdf: + if opening.is_selection_procedure_details_pdf == "true": selection_procedure_details_pdf = [] for file in files.getlist(SELECTION_PROCEDURE_DETAILS_PDF): file_location = STORAGE_DESTINATION_COMPANY_ATTACHMENTS + opening.id + '/' @@ -268,6 +268,16 @@ def verifyEmail(request): else: send_email_to_company = False opening.save() + elif opening_type == INTERNSHIP: + opening = get_object_or_404(Internship, id=opening_id) + if email != opening.email: + raise ValueError("Invalid Email") + if not opening.email_verified: + opening.email_verified = True + send_email_to_company = True + else: + send_email_to_company = False + opening.save() else: raise ValueError('Invalid opening type') @@ -281,7 +291,7 @@ def verifyEmail(request): } data = { "designation": opening.designation, - "opening_type": PLACEMENT, + "opening_type": opening_type, "company_name": opening.company_name, } sendEmail([opening.email, CDC_MAIl_ADDRESS], @@ -294,9 +304,11 @@ def verifyEmail(request): return Response({'action': "Verify Email", 'message': "Opening Not Found"}, status=status.HTTP_404_NOT_FOUND) except ValueError as e: + print(traceback.format_exc()) return Response({'action': "Verify Email", 'message': str(e)}, status=status.HTTP_400_BAD_REQUEST) except: + print(traceback.format_exc()) logger.warning("Verify Email: " + str(sys.exc_info())) return Response({'action': "Verify Email", 'message': "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST) @@ -326,7 +338,181 @@ def autoFillJnf(request): @api_view(['POST']) +@precheck([COMPANY_NAME, WEBSITE, IS_COMPANY_DETAILS_PDF, COMPANY_DETAILS, ADDRESS, + CITY, STATE, COUNTRY, PINCODE, COMPANY_TYPE, NATURE_OF_BUSINESS, IS_DESCRIPTION_PDF, + DESIGNATION, INTERNSHIP_LOCATION, DESCRIPTION, SEASON, START_DATE, END_DATE, WORK_TYPE, + ALLOWED_BRANCH, SOPHOMORES_ELIIGIBLE, RS_ELIGIBLE, NUM_OFFERS, IS_STIPEND_DETAILS_PDF, STIPEND, + FACILITIES, OTHER_FACILITIES, SELECTION_PROCEDURE_ROUNDS, SELECTION_PROCEDURE_DETAILS, IS_SELECTION_PROCEDURE_DETAILS_PDF, + SELECTION_PROCEDURE_DETAILS, OTHER_REQUIREMENTS, + CONTACT_PERSON_NAME, PHONE_NUMBER, EMAIL, RECAPTCHA_VALUE]) def addInternship(request): - logger.info(request.data) - return Response({'action': "Add Internship", 'message': "Internship Added Successfully"}, - status=status.HTTP_200_OK) + logger.info("INF filled by " + str(request.data['email'])) + try: + data = request.data + files = request.FILES + internship = Internship() + if not verify_recaptcha(data[RECAPTCHA_VALUE]): + raise Exception("Recaptcha Failed") + + print(internship) + internship.id = generateRandomString() + # Add a company details in the internship + internship.company_name = data[COMPANY_NAME] + internship.website = data[WEBSITE] + if data[IS_COMPANY_DETAILS_PDF] == "true": + internship.is_company_details_pdf = True + else: + internship.is_company_details_pdf = False + if internship.is_company_details_pdf: + company_details_pdf = [] + for file in files.getlist(COMPANY_DETAILS_PDF): + file_location = STORAGE_DESTINATION_COMPANY_ATTACHMENTS + internship.id + '/' + company_details_pdf.append(saveFile(file, file_location)) + internship.company_details_pdf_names = company_details_pdf + + internship.company_details = data[COMPANY_DETAILS] + internship.address = data[ADDRESS] + internship.city = data[CITY] + internship.state = data[STATE] + internship.country = data[COUNTRY] + if internship.country.upper() == 'INDIA': + internship.city_type = 'Domestic' + else: + internship.city_type = 'International' + internship.pin_code = data[PINCODE] + internship.company_type = data[COMPANY_TYPE] + internship.nature_of_business = data[NATURE_OF_BUSINESS] + + if data[IS_DESCRIPTION_PDF] == "true": + internship.is_description_pdf = True + else: + internship.is_description_pdf = False + + if internship.is_description_pdf: + description_pdf = [] + for file in files.getlist(DESCRIPTION_PDF): + file_location = STORAGE_DESTINATION_COMPANY_ATTACHMENTS + internship.id + '/' + description_pdf.append(saveFile(file, file_location)) + internship.description_pdf_names = description_pdf + internship.designation = data[DESIGNATION] + internship.location = data[INTERNSHIP_LOCATION] + internship.description = data[DESCRIPTION] + if data[SEASON] == "": + raise ValueError('Season cannot be empty') + elif set(json.loads(data[SEASON])).issubset(SEASONS): + internship.season = json.loads(data[SEASON]) + else: + raise ValueError('Season must be a subset of ' + str(SEASONS)) + internship.interning_period_from = datetime.datetime.strptime(data[START_DATE], '%d-%m-%Y').date() + internship.interning_period_to = datetime.datetime.strptime(data[END_DATE], '%d-%m-%Y').date() + + if data[WORK_TYPE] == 'Work from home': + internship.work_from_home = True + else: + internship.work_from_home = False + if data[ALLOWED_BRANCH] is None: + raise ValueError('Allowed Branch cannot be empty') + elif set(json.loads(data[ALLOWED_BRANCH])).issubset(BRANCHES): + internship.allowed_branch = json.loads(data[ALLOWED_BRANCH]) + else: + raise ValueError('Allowed Branch must be a subset of ' + str(BRANCHES)) + + if data[SOPHOMORES_ELIIGIBLE] == 'Yes': + internship.sophomores_eligible = True + else: + internship.sophomores_eligible = False + if data[RS_ELIGIBLE] == 'Yes': + internship.rs_eligible = True + else: + internship.rs_eligible = False + if data[NUM_OFFERS].isdigit(): + internship.num_offers = int(data[NUM_OFFERS]) + else: + raise ValueError('Number of offers must be an integer') + + if data[IS_STIPEND_DETAILS_PDF] == "true": + internship.is_stipend_details_pdf = True + else: + internship.is_stipend_details_pdf = False + + if internship.is_stipend_details_pdf: + stipend_details_pdf = [] + for file in files.getlist(STIPEND_DETAILS_PDF): + file_location = STORAGE_DESTINATION_COMPANY_ATTACHMENTS + internship.id + '/' + stipend_details_pdf.append(saveFile(file, file_location)) + internship.stipend_description_pdf_names = stipend_details_pdf + + if data[STIPEND].isdigit(): + internship.stipend = int(data[STIPEND]) + else: + raise ValueError('Stipend must be an integer') + + if data[FACILITIES] != "": + if set(json.loads(data[FACILITIES])).issubset(FACILITIES_CHOICES): + internship.facilities = json.loads(data[FACILITIES]) + else: + raise ValueError('Facilities must be a subset of ' + str(FACILITIES_CHOICES)) + else: + internship.facilities = [] + internship.other_facilities = data[OTHER_FACILITIES] + + if data[SELECTION_PROCEDURE_ROUNDS] is None: + raise ValueError('Selection Procedure Rounds cannot be empty') + else: + try: + internship.selection_procedure_rounds = json.loads(data[SELECTION_PROCEDURE_ROUNDS]) + except: + raise ValueError('Selection Procedure Rounds must be a list') + + internship.selection_procedure_details = data[SELECTION_PROCEDURE_DETAILS] + if data[IS_SELECTION_PROCEDURE_DETAILS_PDF] == "true": + internship.is_selection_procedure_details_pdf = True + else: + internship.is_selection_procedure_details_pdf = False + + if internship.is_selection_procedure_details_pdf: + selection_procedure_details_pdf = [] + for file in files.getlist(SELECTION_PROCEDURE_DETAILS_PDF): + file_location = STORAGE_DESTINATION_COMPANY_ATTACHMENTS + internship.id + '/' + selection_procedure_details_pdf.append(saveFile(file, file_location)) + internship.selection_procedure_details_pdf_names = selection_procedure_details_pdf + internship.other_requirements = data[OTHER_REQUIREMENTS] + + + internship.contact_person_name = data[CONTACT_PERSON_NAME] + internship.phone_number = data[PHONE_NUMBER] + internship.email = data[EMAIL] + internship.save() + + stat, link = generateOneTimeVerificationLink(internship.email, internship.id, "Internship") + if not stat: + raise RuntimeError("Error in generating one time verification link for internship") + data = { + "designation": internship.designation, + "one_time_link": link + } + + sendEmail(internship.email, COMPANY_EMAIl_VERIFICATION_TEMPLATE_SUBJECT, data, + COMPANY_EMAIL_VERIFICATION_TEMPLATE) + + return Response({'action': "Add Internship", 'message': "Internship Added Successfully"}, + status=status.HTTP_200_OK) + except ValueError as e: + store_all_files(request) + # exception_email(data) + logger.info("ValueError in addInternship: " + str(e)) + return Response({'action': "Add Internship", 'message': str(e)}, + status=status.HTTP_400_BAD_REQUEST) + except: + store_all_files(request) + print(traceback.format_exc()) + # exception_email(data) + logger.warning("Add New Internship: " + str(sys.exc_info())) + return Response({'action': "Add Internship", 'message': "Something went wrong"}, + status=status.HTTP_400_BAD_REQUEST) + + + + + + diff --git a/CDC_Backend/APIs/constants.py b/CDC_Backend/APIs/constants.py index f792f6b..9dea2f4 100644 --- a/CDC_Backend/APIs/constants.py +++ b/CDC_Backend/APIs/constants.py @@ -45,7 +45,7 @@ DEGREE_CHOICES = [ TOTAL_BRANCHES = 4 # Total No of Branches TOTAL_BATCHES = 5 # Total No of Batches -CDC_MAIl_ADDRESS = 'cdc@iitdh.ac.in' +CDC_MAIl_ADDRESS = '200010030@iitdh.ac.in' # To be Configured Properly CLIENT_ID = os.environ.get('GOOGLE_OAUTH_CLIENT_ID') # Google Login Client ID @@ -99,7 +99,6 @@ PLACEMENT = "Placement" PLACEMENT_ID = "placement_id" COMPANY_NAME = "company_name" -ADDRESS = "address" COMPANY_TYPE = "company_type" NATURE_OF_BUSINESS = "nature_of_business" TYPE_OF_ORGANISATION = "type_of_organisation" @@ -110,6 +109,7 @@ IS_COMPANY_DETAILS_PDF = "is_company_details_pdf" COMPANY_DETAILS_PDF_NAMES = "company_details_pdf_names" PHONE_NUMBER = 'phone_number' CONTACT_PERSON_NAME = 'contact_person_name' +ADDRESS = "address" CITY = 'city' STATE = 'state' COUNTRY = 'country' @@ -181,6 +181,29 @@ APPLICATION_CSV_COL_NAMES = ['Applied At', 'Roll No.', 'Name', 'Email', 'Phone N # Internships +INTERNSHIP = 'Internship' +INTERNSHIP_ID = 'internship_id' +INF_COMPANY_NAME = 'companyname' +INTERNSHIP_LOCATION = 'internship_location' +SEASON = 'season' +START_DATE = 'start_date' +END_DATE = 'end_date' +WORK_TYPE = 'work_type' +SOPHOMORES_ELIIGIBLE = 'sophomores_allowed' +NUM_OFFERS = 'num_offers' +IS_STIPEND_DETAILS_PDF = 'is_stipend_details_pdf' +STIPEND = 'stipend' +FACILITIES = 'facilities' +OTHER_FACILITIES = 'other_facilities' +STIPEND_DETAILS_PDF = 'stipend_details_pdf' + +SEASONS = ( + 'Summer', + 'Winter', + 'Autumn', + 'Spring', +) + SEASON_CHOICES = ( ['summer', 'Summer'], ['winter', 'Winter'], @@ -188,6 +211,13 @@ SEASON_CHOICES = ( ['spring', 'Spring'], ) +FACILITIES_CHOICES = [ + 'Accommodation', + 'Food', + 'Transport', + 'Medical', +] + INF_FACILITIES_PROVIDED = [ ['Accommodation', 'Accommodation'], ['Food', 'Food'], diff --git a/CDC_Backend/APIs/models.py b/CDC_Backend/APIs/models.py index 1bc05ff..5f1083d 100644 --- a/CDC_Backend/APIs/models.py +++ b/CDC_Backend/APIs/models.py @@ -291,12 +291,12 @@ class Internship(models.Model): #Company Address address = models.CharField(blank=False, max_length=JNF_TEXTAREA_MAX_CHARACTER_COUNT) city = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") + city_type = models.CharField(blank=True, max_length=15, choices=OFFER_CITY_TYPE) state = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") country = models.CharField(blank=False, max_length=JNF_SMALLTEXT_MAX_CHARACTER_COUNT, default="") pin_code = models.IntegerField(blank=False, default=None, null=True) 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) #Internship Details is_description_pdf = models.BooleanField(blank=False, default=False) description_pdf_names = ArrayField( @@ -313,6 +313,11 @@ class Internship(models.Model): interning_period_from = models.DateField(blank=False, default=None, null=True) interning_period_to = models.DateField(blank=False, default=None, null=True) is_work_from_home = models.BooleanField(blank=False, default=False) + allowed_branch = ArrayField( + models.CharField(choices=BRANCH_CHOICES, blank=False, max_length=10), + size=TOTAL_BRANCHES, + default=list + ) sophomore_eligible = models.BooleanField(blank=False, default=False) rs_eligible = models.BooleanField(blank=False, default=False) tentative_no_of_offers = models.IntegerField(blank=False, default=None, null=True) @@ -362,8 +367,6 @@ class Internship(models.Model): 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: diff --git a/CDC_Backend/APIs/utils.py b/CDC_Backend/APIs/utils.py index 63f2729..deaafd0 100644 --- a/CDC_Backend/APIs/utils.py +++ b/CDC_Backend/APIs/utils.py @@ -28,7 +28,7 @@ from rest_framework import status from rest_framework.response import Response from .constants import * -from .models import User, PrePlacementOffer, PlacementApplication, Placement, Student +from .models import User, PrePlacementOffer, PlacementApplication, Placement, Student, Internship logger = logging.getLogger('db') @@ -81,15 +81,18 @@ def precheck(required_data=None): request_data = request.POST if len(request_data): for i in required_data: + # print(i) if i not in request_data: return Response({'action': "Pre check", 'message': str(i) + " Not Found"}, status=status.HTTP_400_BAD_REQUEST) else: return Response({'action': "Pre check", 'message': "Message Data not Found"}, status=status.HTTP_400_BAD_REQUEST) - + # print("Pre check: " + str(request_data)) return view_func(request, *args, **kwargs) except: + # print what exception is + print(traceback.format_exc()) logger.warning("Pre check: " + str(sys.exc_info())) return Response({'action': "Pre check", 'message': "Something went wrong"}, status=status.HTTP_400_BAD_REQUEST) @@ -316,6 +319,9 @@ def opening_description_table_html(opening): if isinstance(opening, Placement): details = model_to_dict(opening, fields=[field.name for field in Placement._meta.fields], exclude=EXCLUDE_IN_PDF) + elif isinstance(opening, Internship): + details = model_to_dict(opening, fields=[field.name for field in Internship._meta.fields], + exclude=EXCLUDE_IN_PDF) # check typing of opening is query dict else: # if isinstance(opening, QueryDict): details = opening diff --git a/CDC_Backend/internAPIs/constants.py b/CDC_Backend/internAPIs/constants.py index 20081d1..9230fa5 100644 --- a/CDC_Backend/internAPIs/constants.py +++ b/CDC_Backend/internAPIs/constants.py @@ -61,7 +61,7 @@ DEGREE_CHOICES = [ TOTAL_BRANCHES = 4 # Total No of Branches TOTAL_BATCHES = 5 # Total No of Batches -CDC_MAIl_ADDRESS = 'cdc@iitdh.ac.in' +CDC_MAIl_ADDRESS = '2000' # To be Configured Properly CLIENT_ID = os.environ.get('GOOGLE_OAUTH_CLIENT_ID') # Google Login Client ID diff --git a/CDC_Backend/run_prod.sh b/CDC_Backend/run_prod.sh index 3ad9b30..6476aab 100644 --- a/CDC_Backend/run_prod.sh +++ b/CDC_Backend/run_prod.sh @@ -1 +1 @@ -gunicorn --certfile=/home/cdc/Desktop/1f9476e3959ebe60.crt --keyfile=/home/cdc/Desktop/star_iitdh_key.key --bind localhost:8000 CDC_Backend.wsgi --access-logfile access.log --error-logfile error.log & +gunicorn --certfile=/home/cdc/Desktop/1f9476e3959ebe60.crt --keyfile=/home/cdc/Desktop/star_iitdh_key.key --bind localhost:8000 CDC_Backend.wsgi --access-logfile access.log --error-logfile error.log --forwarded-allow-ips="cdc.iitdh.ac.in" &