Updated Backend To Accomodate Internships

This commit is contained in:
uttamthummala 2023-10-03 01:47:26 +05:30
parent 7fc18bb2fb
commit 1378898d37
10 changed files with 562 additions and 96 deletions

View File

@ -138,6 +138,13 @@ class PlacementApplicationResources(resources.ModelResource):
class PlacementAdmin(ExportMixin, SimpleHistoryAdmin):
resource_class = PlacementApplicationResources
class InternshipApplicationResources(resources.ModelResource):
class Meta:
model = InternshipApplication
exclude = ('id', 'changed_by')
class InternshipApplicationAdmin(ExportMixin, SimpleHistoryAdmin):
resource_class = InternshipApplicationResources
@admin.register(PlacementApplication)
class PlacementApplication(PlacementAdmin):
@ -151,7 +158,18 @@ class PlacementApplication(PlacementAdmin):
def Student(self, obj):
return model_admin_url(obj.student)
@admin.register(InternshipApplication)
class InternshipApplication(InternshipApplicationAdmin):
list_display = ('id', 'Internship', 'Student', 'selected')
search_fields = ('id',)
ordering = ('id',)
list_filter = ('selected',)
def Internship(self, obj):
return model_admin_url(obj.internship)
def Student(self, obj):
return model_admin_url(obj.student)
class PrePlacementResources(resources.ModelResource):
class Meta:
@ -178,7 +196,7 @@ class InternshipResources(resources.ModelResource):
class Meta:
model = Internship
exclude = ('id', 'changed_by', 'is_company_details_pdf', 'is_description_pdf',
'is_compensation_details_pdf', 'is_selection_procedure_details_pdf')
'is_stipend_details_pdf', 'is_selection_procedure_details_pdf')
class InternAdmin(ExportMixin, SimpleHistoryAdmin):

View File

@ -12,9 +12,18 @@ from .utils import *
def markStatus(request, id, email, user_type):
try:
data = request.data
if OPENING_TYPE in data:
opening_type= data[OPENING_TYPE] #not to break the code
else:
opening_type= "Placement"
if opening_type == "Internship":
applications = InternshipApplication.objects.filter(internship_id=data[OPENING_ID])
else:
applications = PlacementApplication.objects.filter(placement_id=data[OPENING_ID])
# Getting all application from db for this opening
applications = PlacementApplication.objects.filter(placement_id=data[OPENING_ID])
# applications = PlacementApplication.objects.filter(placement_id=data[OPENING_ID])
for i in data[STUDENT_LIST]:
# print(i[STUDENT_ID]) issue is using student id instead of roll no both may not be same
application = applications.filter(student__roll_no=i[STUDENT_ID]) # Filtering student's application
if len(application) > 0:
application = application[0]
@ -27,14 +36,23 @@ def markStatus(request, id, email, user_type):
raise ValueError("Student already selected")
email = str(application.student.roll_no) + "@iitdh.ac.in" # Only allowing for IITDh emails
subject = STUDENT_APPLICATION_STATUS_TEMPLATE_SUBJECT.format(
company_name=application.placement.company_name,
id=application.id)
data = {
"company_name": application.placement.company_name,
"designation": application.placement.designation,
"student_name": application.student.name
}
if opening_type == "Internship":
subject = STUDENT_APPLICATION_STATUS_TEMPLATE_SUBJECT.format(
company_name=application.internship.company_name,id=application.id)
data = {
"company_name": application.internship.company_name,
"designation": application.internship.designation,
"student_name": application.student.name
}
else:
subject = STUDENT_APPLICATION_STATUS_TEMPLATE_SUBJECT.format(
company_name=application.placement.company_name,
id=application.id)
data = {
"company_name": application.placement.company_name,
"designation": application.placement.designation,
"student_name": application.student.name
}
if application.selected: # Sending corresponding email to students
sendEmail(email, subject, data, STUDENT_APPLICATION_STATUS_SELECTED_TEMPLATE)
else:
@ -64,13 +82,22 @@ def getDashboard(request, id, email, user_type):
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)
internships=Internship.objects.all().order_by('-created_at')
ongoing_internships = internships.filter(deadline_datetime__gt=timezone.now(), offer_accepted=True, email_verified=True)
previous_internships = internships.exclude(deadline_datetime__gt=timezone.now()).filter(
offer_accepted=True, email_verified=True)
new_internships = internships.filter(offer_accepted__isnull=True, email_verified=True)
ongoing = PlacementSerializerForAdmin(ongoing, many=True).data
previous = PlacementSerializerForAdmin(previous, many=True).data
new = PlacementSerializerForAdmin(new, many=True).data
ongoing_internships = InternshipSerializerForAdmin(ongoing_internships, many=True).data
previous_internships = InternshipSerializerForAdmin(previous_internships, many=True).data
new_internships = InternshipSerializerForAdmin(new_internships, many=True).data
return Response(
{'action': "Get Dashboard - Admin", 'message': "Data Found", "ongoing": ongoing, "previous": previous,
"new": new},
"new": new, "ongoing_internships": ongoing_internships, "previous_internships": previous_internships,
"new_internships": new_internships},
status=status.HTTP_200_OK)
except Http404:
return Response({'action': "Get Dashboard - Admin", 'message': 'Student Not Found'},
@ -87,7 +114,15 @@ def getDashboard(request, id, email, user_type):
def updateDeadline(request, id, email, user_type):
try:
data = request.data
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
if OPENING_TYPE in data:
opening_type= data[OPENING_TYPE]
else:
opening_type= "Placement"
if opening_type == "Internship":
opening = get_object_or_404(Internship, pk=data[OPENING_ID])
else:
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
# Updating deadline date with correct format in datetime field
opening.deadline_datetime = datetime.datetime.strptime(data[DEADLINE_DATETIME], '%Y-%m-%d %H:%M:%S %z')
opening.changed_by = get_object_or_404(User, id=id)
@ -110,7 +145,14 @@ def updateOfferAccepted(request, id, email, user_type):
try:
data = request.data
offer_accepted = data[OFFER_ACCEPTED]
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
if OPENING_TYPE in data:
opening_type= data[OPENING_TYPE]
else:
opening_type= "Placement"
if opening_type == "Internship":
opening = get_object_or_404(Internship, pk=data[OPENING_ID])
else:
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
if opening.offer_accepted is None:
opening.offer_accepted = offer_accepted == "true"
opening.changed_by = get_object_or_404(User, id=id)
@ -140,7 +182,14 @@ def updateOfferAccepted(request, id, email, user_type):
def updateEmailVerified(request, id, email, user_type):
try:
data = request.data
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
if OPENING_TYPE in data:
opening_type= data[OPENING_TYPE]
else:
opening_type= "Placement"
if opening_type == "Internship":
opening = get_object_or_404(Internship, pk=data[OPENING_ID])
else:
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
opening.email_verified = True if data[EMAIL_VERIFIED] == "true" else False
opening.changed_by = get_object_or_404(User, id=id)
opening.save()
@ -161,7 +210,14 @@ def updateEmailVerified(request, id, email, user_type):
def deleteAdditionalInfo(request, id, email, user_type):
try:
data = request.data
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
if OPENING_TYPE in data:
opening_type= data[OPENING_TYPE]
else:
opening_type= "Placement"
if opening_type == "Internship":
opening = get_object_or_404(Internship, pk=data[OPENING_ID])
else:
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
if data[FIELD] in opening.additional_info:
opening.additional_info.remove(data[FIELD])
opening.changed_by = get_object_or_404(User, id=id)
@ -188,7 +244,14 @@ def deleteAdditionalInfo(request, id, email, user_type):
def addAdditionalInfo(request, id, email, user_type):
try:
data = request.data
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
if OPENING_TYPE in data:
opening_type= data[OPENING_TYPE]
else:
opening_type= "Placement"
if opening_type == "Internship":
opening = get_object_or_404(Internship, pk=data[OPENING_ID])
else:
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
if data[FIELD] not in opening.additional_info:
opening.additional_info.append(data[FIELD])
opening.save()
@ -215,11 +278,20 @@ def addAdditionalInfo(request, id, email, user_type):
def getApplications(request, id, email, user_type):
try:
data = request.GET
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
applications = PlacementApplication.objects.filter(placement=opening)
serializer = PlacementApplicationSerializerForAdmin(applications, many=True)
if OPENING_TYPE in data:
opening_type= data[OPENING_TYPE]
else:
opening_type= "Placement"
if opening_type == "Internship":
opening = get_object_or_404(Internship, pk=data[OPENING_ID])
applications = InternshipApplication.objects.filter(internship=opening)
serializer = InternshipApplicationSerializerForAdmin(applications, many=True)
else:
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
applications = PlacementApplication.objects.filter(placement=opening)
serializer = PlacementApplicationSerializerForAdmin(applications, many=True)
return Response({'action': "Get Applications", 'message': 'Data Found', 'applications': serializer.data},
status=status.HTTP_200_OK)
status=status.HTTP_200_OK)
except Http404:
return Response({'action': "Get Applications", 'message': 'Opening Not Found'},
status=status.HTTP_404_NOT_FOUND)
@ -235,68 +307,136 @@ def getApplications(request, id, email, user_type):
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])
student_user = get_object_or_404(User, id=student.id)
if data[APPLICATION_ID] == "":
application = PlacementApplication()
application.id = generateRandomString()
application.placement = opening
application.student = student
if data[RESUME_FILE_NAME] in student.resumes:
application.resume = data[RESUME_FILE_NAME]
else:
raise FileNotFoundError(RESUME_FILE_NAME + " Not Found")
additional_info = {}
for i in opening.additional_info:
if i not in data[ADDITIONAL_INFO]:
raise AttributeError(i + " not found in Additional Info")
else:
additional_info[i] = data[ADDITIONAL_INFO][i]
application.additional_info = json.dumps(additional_info)
data = {
"name": student.name,
"company_name": opening.company_name,
"application_type": "Placement",
"additional_info": dict(json.loads(application.additional_info)),
}
subject = STUDENT_APPLICATION_SUBMITTED_TEMPLATE_SUBJECT.format(company_name=opening.company_name)
application.changed_by = get_object_or_404(User, id=id)
application.save()
sendEmail(student_user.email, subject, data, STUDENT_APPLICATION_SUBMITTED_TEMPLATE)
return Response({'action': "Add Student Application", 'message': "Application added"},
status=status.HTTP_200_OK)
if OPENING_TYPE in data:
opening_type= data[OPENING_TYPE]
else:
application = get_object_or_404(PlacementApplication, id=data[APPLICATION_ID])
if application:
opening_type= "Placement"
student = get_object_or_404(Student, pk=data[STUDENT_ID])
if opening_type == "Internship":
opening = get_object_or_404(Internship, pk=data[OPENING_ID])
student_user = get_object_or_404(User, id=student.id)
if data[APPLICATION_ID] == "":
application = InternshipApplication()
application.id = generateRandomString()
application.internship = opening
application.student = student
if data[RESUME_FILE_NAME] in student.resumes:
application.resume = data[RESUME_FILE_NAME]
else:
raise FileNotFoundError(RESUME_FILE_NAME + " Not Found")
application.resume = data[RESUME_FILE_NAME]
additional_info = {}
for i in opening.additional_info:
if i not in data[ADDITIONAL_INFO]:
raise AttributeError(i + " not found in Additional Info")
else:
additional_info[i] = data[ADDITIONAL_INFO][i]
application.additional_info = json.dumps(additional_info)
data = {
"name": student.name,
"company_name": opening.company_name,
"application_type": "Internship",
"additional_info": dict(json.loads(application.additional_info)),
}
subject = STUDENT_APPLICATION_SUBMITTED_TEMPLATE_SUBJECT.format(company_name=opening.company_name)
application.changed_by = get_object_or_404(User, id=id)
application.save()
sendEmail(student_user.email, subject, data, STUDENT_APPLICATION_SUBMITTED_TEMPLATE)
return Response({'action': "Add Student Application", 'message': "Application added For Internship"},
status=status.HTTP_200_OK)
else:
application = get_object_or_404(InternshipApplication, id=data[APPLICATION_ID])
if application:
if data[RESUME_FILE_NAME] in student.resumes:
application.resume = data[RESUME_FILE_NAME]
else:
raise FileNotFoundError(RESUME_FILE_NAME + " Not Found")
application.resume = data[RESUME_FILE_NAME]
additional_info = {}
for i in opening.additional_info:
if i not in data[ADDITIONAL_INFO]:
raise AttributeError(i + " not found in Additional Info")
else:
additional_info[i] = data[ADDITIONAL_INFO][i]
application.additional_info = json.dumps(additional_info)
data = {
"name": student.name,
"company_name": opening.company_name,
"application_type": "Internship",
"resume": application.resume[16:],
"additional_info_items": dict(json.loads(application.additional_info)),
}
subject = STUDENT_APPLICATION_UPDATED_TEMPLATE_SUBJECT.format(company_name=opening.company_name)
application.changed_by = get_object_or_404(User, id=id)
application.save()
sendEmail(student_user.email, subject, data, STUDENT_APPLICATION_UPDATED_TEMPLATE)
return Response({'action': "Add Student Application", 'message': "Application updated For Internship"},
status=status.HTTP_200_OK)
else:
return Response({'action': "Edit Student Application", 'message': "No Application Found For Internship"},
status=status.HTTP_400_BAD_REQUEST)
else:
opening = get_object_or_404(Placement, pk=data[OPENING_ID])
student_user = get_object_or_404(User, id=student.id)
if data[APPLICATION_ID] == "":
application = PlacementApplication()
application.id = generateRandomString()
application.placement = opening
application.student = student
if data[RESUME_FILE_NAME] in student.resumes:
application.resume = data[RESUME_FILE_NAME]
else:
raise FileNotFoundError(RESUME_FILE_NAME + " Not Found")
additional_info = {}
for i in opening.additional_info:
if i not in data[ADDITIONAL_INFO]:
raise AttributeError(i + " not found in Additional Info")
else:
additional_info[i] = data[ADDITIONAL_INFO][i]
application.additional_info = json.dumps(additional_info)
data = {
"name": student.name,
"company_name": opening.company_name,
"application_type": "Placement",
"resume": application.resume[16:],
"additional_info_items": dict(json.loads(application.additional_info)),
"additional_info": dict(json.loads(application.additional_info)),
}
subject = STUDENT_APPLICATION_UPDATED_TEMPLATE_SUBJECT.format(company_name=opening.company_name)
subject = STUDENT_APPLICATION_SUBMITTED_TEMPLATE_SUBJECT.format(company_name=opening.company_name)
application.changed_by = get_object_or_404(User, id=id)
application.save()
sendEmail(student_user.email, subject, data, STUDENT_APPLICATION_UPDATED_TEMPLATE)
return Response({'action': "Add Student Application", 'message': "Application updated"},
status=status.HTTP_200_OK)
sendEmail(student_user.email, subject, data, STUDENT_APPLICATION_SUBMITTED_TEMPLATE)
return Response({'action': "Add Student Application", 'message': "Application added"},
status=status.HTTP_200_OK)
else:
return Response({'action': "Edit Student Application", 'message': "No Application Found"},
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]
else:
raise FileNotFoundError(RESUME_FILE_NAME + " Not Found")
application.resume = data[RESUME_FILE_NAME]
additional_info = {}
for i in opening.additional_info:
if i not in data[ADDITIONAL_INFO]:
raise AttributeError(i + " not found in Additional Info")
else:
additional_info[i] = data[ADDITIONAL_INFO][i]
application.additional_info = json.dumps(additional_info)
data = {
"name": student.name,
"company_name": opening.company_name,
"application_type": "Placement",
"resume": application.resume[16:],
"additional_info_items": dict(json.loads(application.additional_info)),
}
subject = STUDENT_APPLICATION_UPDATED_TEMPLATE_SUBJECT.format(company_name=opening.company_name)
application.changed_by = get_object_or_404(User, id=id)
application.save()
sendEmail(student_user.email, subject, data, STUDENT_APPLICATION_UPDATED_TEMPLATE)
return Response({'action': "Add Student Application", 'message': "Application updated"},
status=status.HTTP_200_OK)
else:
return Response({'action': "Edit Student Application", 'message': "No Application Found"},
status=status.HTTP_400_BAD_REQUEST)
except Http404 as e:
@ -320,8 +460,16 @@ def submitApplication(request, id, email, user_type):
def generateCSV(request, id, email, user_type):
try:
data = request.data
placement = get_object_or_404(Placement, id=data[OPENING_ID])
applications = PlacementApplication.objects.filter(placement=placement)
if OPENING_TYPE in data:
opening_type= data[OPENING_TYPE]
else:
opening_type= "Placement"
if opening_type == "Internship":
opening = get_object_or_404(Internship, id=data[OPENING_ID])
applications = InternshipApplication.objects.filter(internship=opening)
else:
opening = get_object_or_404(Placement, id=data[OPENING_ID])
applications = PlacementApplication.objects.filter(placement=opening)
filename = generateRandomString()
if not os.path.isdir(STORAGE_DESTINATION_APPLICATION_CSV):
os.mkdir(STORAGE_DESTINATION_APPLICATION_CSV)
@ -330,7 +478,7 @@ def generateCSV(request, id, email, user_type):
writer = csv.writer(f)
header_row = APPLICATION_CSV_COL_NAMES.copy()
header_row.extend(placement.additional_info)
header_row.extend(opening.additional_info)
writer.writerow(header_row)
for apl in applications:
row_details = []
@ -347,7 +495,7 @@ def generateCSV(request, id, email, user_type):
row_details.append(link)
row_details.append(apl.selected)
for i in placement.additional_info:
for i in opening.additional_info:
row_details.append(json.loads(apl.additional_info)[i])
writer.writerow(row_details)
@ -397,6 +545,10 @@ def addPPO(request, id, email, user_type):
def getStudentApplication(request, id, email, user_type):
try:
data = request.data
if OPENING_TYPE in data:
opening_type= data[OPENING_TYPE]
else:
opening_type= "Placement"
student = get_object_or_404(Student, id=data[STUDENT_ID])
student_serializer = StudentSerializer(student)
student_details = {
@ -406,15 +558,29 @@ 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,
if opening_type == "Internship":
application = InternshipApplication.objects.filter(student=student,
internship=get_object_or_404(Internship,
id=data[OPENING_ID]))
else:
application = PlacementApplication.objects.filter(student=student,
placement=get_object_or_404(Placement, id=data[OPENING_ID]))
if application:
serializer = PlacementApplicationSerializer(application[0])
application_info = {
"id": serializer.data['id'],
"additional_info": serializer.data['additional_info'],
"resume": serializer.data['resume_link'],
}
if opening_type == "Internship":
serializer = InternshipApplicationSerializer(application[0])
application_info = {
"id": serializer.data['id'],
"additional_info": serializer.data['additional_info'],
"resume": serializer.data['resume_link'],
}
else:
serializer = PlacementApplicationSerializer(application[0])
application_info = {
"id": serializer.data['id'],
"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)

View File

@ -321,6 +321,24 @@ def autoFillJnf(request):
return Response({'action': "Get AutoFill", 'message': "Something went wrong"},
status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET'])
@precheck([PLACEMENT_ID])
def autoFillInf(request):
try:
data = request.GET
internship_id = data.get(INTERNSHIP_ID)
opening = get_object_or_404(Internship, id=internship_id)
serializer = AutofillSerializersInternship(opening)
return Response({'action': "Get AutoFill ", 'message': 'Data Found', 'internship_data': serializer.data},
status=status.HTTP_200_OK)
except Http404:
return Response({'action': "Get AutoFill", 'message': 'Internship Not Found'},
status=status.HTTP_404_NOT_FOUND)
except Exception as e:
traceback_str = traceback.format_exc()
logger.warning("Get AutoFill: " + traceback_str)
return Response({'action': "Get AutoFill", 'message': "Something went wrong"},
status=status.HTTP_400_BAD_REQUEST)
## Internships ##
@ -397,6 +415,14 @@ def addInternship(request):
internship.is_work_from_home = True
else:
internship.is_work_from_home = False
if data[ALLOWED_BATCH] is None or json.loads(data[ALLOWED_BATCH]) == "":
raise ValueError('Allowed Branch cannot be empty')
elif set(json.loads(data[ALLOWED_BATCH])).issubset(BATCHES):
internship.allowed_batch = json.loads(data[ALLOWED_BATCH])
else:
raise ValueError('Allowed Batch must be a subset of ' + str(BATCHES))
if data[ALLOWED_BRANCH] is None or json.loads(data[ALLOWED_BRANCH]) == "":
raise ValueError('Allowed Branch cannot be empty')
elif set(json.loads(data[ALLOWED_BRANCH])).issubset(BRANCHES):
@ -468,6 +494,11 @@ def addInternship(request):
internship.selection_procedure_details_pdf_names = selection_procedure_details_pdf
internship.additional_facilities = data[OTHER_FACILITIES]
#add additional info
# Only Allowing Fourth Year for Placement
internship.academic_requirements = data[OTHER_REQUIREMENTS]

View File

@ -21,6 +21,12 @@ BRANCHES = [
"CHEMICAL",
"BSMS",
]
BATCHES = [ #change it accordingly
"2023",
"2022",
"2021",
"2020",
]
BATCH_CHOICES = [
["2022", "2022"],
["2021", "2021"],
@ -218,6 +224,7 @@ STIPEND = 'stipend'
FACILITIES = 'facilities'
OTHER_FACILITIES = 'other_facilities'
STIPEND_DETAILS_PDF = 'compensation_details_pdf'
STIPEND_DETAILS_PDF_NAMES = 'stipend_description_pdf_names'
SEASONS = (
'Summer',

View File

@ -32,6 +32,7 @@ class Student(models.Model):
default=list, blank=True)
cpi = models.DecimalField(decimal_places=2, max_digits=4)
can_apply = models.BooleanField(default=True, verbose_name='Registered')
can_apply_internship = models.BooleanField(default=True, verbose_name='Internship Registered') #added for internship
changed_by = models.ForeignKey(User, blank=True, on_delete=models.RESTRICT, default=None, null=True)
degree = models.CharField(choices=DEGREE_CHOICES, blank=False, max_length=10, default=DEGREE_CHOICES[0][0])
history = HistoricalRecords(user_model=User)
@ -318,6 +319,11 @@ class Internship(models.Model):
size=TOTAL_BRANCHES,
default=list
)
allowed_batch = ArrayField(
models.CharField(max_length=10, choices=BATCH_CHOICES),
size=TOTAL_BATCHES,
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)
@ -332,6 +338,11 @@ class Internship(models.Model):
default=list,
blank=True
)
additional_info = ArrayField(models.CharField(blank=True, max_length=JNF_TEXTMEDIUM_MAX_CHARACTER_COUNT), size=15,
default=list, blank=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)
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
@ -388,6 +399,9 @@ class Internship(models.Model):
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.additional_info is not None:
self.additional_info = [info.strip()[:JNF_TEXTMEDIUM_MAX_CHARACTER_COUNT] for info in
list(self.additional_info)]
# if self.contact_person_designation is not None:
# self.contact_person_designation = self.contact_person_designation.strip()[:JNF_SMALLTEXT_MAX_CHARACTER_COUNT]

View File

@ -99,6 +99,59 @@ class PlacementSerializerForStudent(serializers.ModelSerializer):
]
depth = 1
class InternshipSerializerForStudent(serializers.ModelSerializer):
company_details_pdf_links = serializers.SerializerMethodField()
description_pdf_links = serializers.SerializerMethodField()
compensation_pdf_links = serializers.SerializerMethodField()
selection_procedure_details_pdf_links = serializers.SerializerMethodField()
def get_company_details_pdf_links(self, obj):
links = []
for pdf_name in obj.company_details_pdf_names:
ele = {}
link = LINK_TO_STORAGE_COMPANY_ATTACHMENT + urllib.parse.quote(obj.id + "/" + pdf_name)
ele['link'] = link
ele['name'] = pdf_name
links.append(ele)
return links
def get_description_pdf_links(self, obj):
links = []
for pdf_name in obj.description_pdf_names:
ele = {}
link = LINK_TO_STORAGE_COMPANY_ATTACHMENT + urllib.parse.quote(obj.id + "/" + pdf_name)
ele['link'] = link
ele['name'] = pdf_name
links.append(ele)
return links
def get_compensation_pdf_links(self, obj):
links = []
for pdf_name in obj.stipend_description_pdf_names:
ele = {}
link = LINK_TO_STORAGE_COMPANY_ATTACHMENT + urllib.parse.quote(obj.id + "/" + pdf_name)
ele['link'] = link
ele['name'] = pdf_name
links.append(ele)
return links
def get_selection_procedure_details_pdf_links(self, obj):
links = []
for pdf_name in obj.selection_procedure_details_pdf_names:
ele = {}
link = LINK_TO_STORAGE_COMPANY_ATTACHMENT + urllib.parse.quote(obj.id + "/" + pdf_name)
ele['link'] = link
ele['name'] = pdf_name
links.append(ele)
return links
class Meta:
model = Internship
exclude = [CONTACT_PERSON_NAME, PHONE_NUMBER, EMAIL, COMPANY_DETAILS_PDF_NAMES, DESCRIPTION_PDF_NAMES,
STIPEND_DETAILS_PDF_NAMES, SELECTION_PROCEDURE_DETAILS_PDF_NAMES, OFFER_ACCEPTED,
EMAIL_VERIFIED,
]
depth = 1
class PlacementSerializerForAdmin(serializers.ModelSerializer):
company_details_pdf_links = serializers.SerializerMethodField()
@ -152,6 +205,58 @@ class PlacementSerializerForAdmin(serializers.ModelSerializer):
COMPENSATION_DETAILS_PDF_NAMES, SELECTION_PROCEDURE_DETAILS_PDF_NAMES]
depth = 1
class InternshipSerializerForAdmin(serializers.ModelSerializer):
company_details_pdf_links = serializers.SerializerMethodField()
description_pdf_links = serializers.SerializerMethodField()
compensation_pdf_links = serializers.SerializerMethodField()
selection_procedure_details_pdf_links = serializers.SerializerMethodField()
def get_company_details_pdf_links(self, obj):
links = []
for pdf_name in obj.company_details_pdf_names:
ele = {}
link = LINK_TO_STORAGE_COMPANY_ATTACHMENT + urllib.parse.quote(obj.id + "/" + pdf_name)
ele['link'] = link
ele['name'] = pdf_name
links.append(ele)
return links
def get_description_pdf_links(self, obj):
links = []
for pdf_name in obj.description_pdf_names:
ele = {}
link = LINK_TO_STORAGE_COMPANY_ATTACHMENT + urllib.parse.quote(obj.id + "/" + pdf_name)
ele['link'] = link
ele['name'] = pdf_name
links.append(ele)
return links
def get_compensation_pdf_links(self, obj):
links = []
for pdf_name in obj.stipend_description_pdf_names:
ele = {}
link = LINK_TO_STORAGE_COMPANY_ATTACHMENT + urllib.parse.quote(obj.id + "/" + pdf_name)
ele['link'] = link
ele['name'] = pdf_name
links.append(ele)
return links
def get_selection_procedure_details_pdf_links(self, obj):
links = []
for pdf_name in obj.selection_procedure_details_pdf_names:
ele = {}
link = LINK_TO_STORAGE_COMPANY_ATTACHMENT + urllib.parse.quote(obj.id + "/" + pdf_name)
ele['link'] = link
ele['name'] = pdf_name
links.append(ele)
return links
class Meta:
model = Internship
exclude = [COMPANY_DETAILS_PDF_NAMES, DESCRIPTION_PDF_NAMES, SELECTION_PROCEDURE_DETAILS_PDF_NAMES,
STIPEND_DETAILS_PDF_NAMES]
depth = 1
class PlacementApplicationSerializer(serializers.ModelSerializer):
placement = serializers.SerializerMethodField()
@ -168,6 +273,21 @@ class PlacementApplicationSerializer(serializers.ModelSerializer):
class Meta:
model = PlacementApplication
exclude = [STUDENT, 'resume']
class InternshipApplicationSerializer(serializers.ModelSerializer):
internship = serializers.SerializerMethodField()
resume_link = serializers.SerializerMethodField()
def get_internship(self, obj):
data = InternshipSerializerForStudent(obj.internship).data
return data
def get_resume_link(self, obj):
ele = {'link': LINK_TO_STORAGE_RESUME + urllib.parse.quote(str(obj.student.roll_no) + "/" + obj.resume), 'name': obj.resume}
return ele
class Meta:
model = InternshipApplication
exclude = [STUDENT, 'resume']
class PlacementApplicationSerializerForAdmin(serializers.ModelSerializer):
@ -186,6 +306,22 @@ class PlacementApplicationSerializerForAdmin(serializers.ModelSerializer):
model = PlacementApplication
exclude = ['placement', 'resume']
class InternshipApplicationSerializerForAdmin(serializers.ModelSerializer):
student_details = serializers.SerializerMethodField()
resume_link = serializers.SerializerMethodField()
def get_student_details(self, obj):
data = StudentSerializer(obj.student).data
return data
def get_resume_link(self, obj):
ele = {'link': LINK_TO_STORAGE_RESUME + urllib.parse.quote(obj.id + "/" + obj.resume), 'name': obj.resume}
return ele
class Meta:
model = InternshipApplication
exclude = ['internship', 'resume']
class ContributorSerializer(serializers.ModelSerializer):
class Meta:
model = Contributor
@ -195,4 +331,9 @@ class ContributorSerializer(serializers.ModelSerializer):
class AutofillSerializers(serializers.ModelSerializer):
class Meta:
model = Placement
fields = '__all__'
class AutofillSerializersInternship(serializers.ModelSerializer):
class Meta:
model = Internship
fields = '__all__'

View File

@ -3,13 +3,14 @@ from django.urls import path
from . import studentViews
urlpatterns = [
path('login/', studentViews.login, name="Login"),
path('profile/', studentViews.studentProfile, name="Student Profile"),
path('getDashboard/', studentViews.getDashboard, name="Dashboard"),
path("addResume/", studentViews.addResume, name="Upload Resume"),
path("deleteResume/", studentViews.deleteResume, name="Upload Resume"),
path("submitApplication/", studentViews.submitApplication, name="Submit Application"),
path("deleteApplication/", studentViews.deleteApplication, name="Delete Application"),
path('login/', studentViews.login, name="Login"), #done for intern
path('profile/', studentViews.studentProfile, name="Student Profile"), #done for intern
path('getDashboard/', studentViews.getDashboard, name="Dashboard"), # customised dashboard.. check are we checking registedred check allowed branch/batches filter in
path("addResume/", studentViews.addResume, name="Upload Resume"), #done for intern
path("deleteResume/", studentViews.deleteResume, name="Upload Resume"),#done for intern
path("submitApplication/", studentViews.submitApplication, name="Submit Application"), #done for intern
path("deleteApplication/", studentViews.deleteApplication, name="Delete Application"), #done for intern check for opening type data in headers
path("getContributorStats/", studentViews.getContributorStats, name="Get Contributor Stats"),
path("studentAcceptOffer/", studentViews.studentAcceptOffer, name="Student Accept Offer"),
path("studentAcceptOffer/", studentViews.studentAcceptOffer, name="Student Accept Offer"), #same as above check header
]
#store all files..

View File

@ -48,6 +48,7 @@ def refresh(request):
@isAuthorized(allowed_users=[STUDENT])
def studentProfile(request, id, email, user_type):
try:
print(id)
studentDetails = get_object_or_404(Student, id=id)
data = StudentSerializer(studentDetails).data
@ -110,9 +111,20 @@ def getDashboard(request, id, email, user_type):
placementApplications = PlacementApplication.objects.filter(student_id=id)
placementApplications = PlacementApplicationSerializer(placementApplications, many=True).data
internships = Internship.objects.filter(allowed_batch__contains=[studentDetails.batch],
allowed_branch__contains=[studentDetails.branch],
deadline_datetime__gte=datetime.datetime.now(),
offer_accepted=True, email_verified=True).order_by('deadline_datetime')
filtered_internships = internship_eligibility_filters(studentDetails, internships)
print(len(filtered_internships))
internshipsdata = InternshipSerializerForStudent(filtered_internships, many=True).data
internshipApplications = InternshipApplication.objects.filter(student_id=id)
internshipApplications = InternshipApplicationSerializer(internshipApplications, many=True).data
return Response(
{'action': "Get Dashboard - Student", 'message': "Data Found", "placements": placementsdata,
'placementApplication': placementApplications},
'placementApplication': placementApplications, 'internships':internshipsdata,'internshipApplication':internshipApplications},
status=status.HTTP_200_OK)
except Http404:
return Response({'action': "Get Dashboard - Student", 'message': 'Student Not Found'},
@ -163,13 +175,14 @@ def deleteResume(request, id, email, user_type):
])
def submitApplication(request, id, email, user_type):
try:
data = request.data
data = request.data
student = get_object_or_404(Student, id=id)
if not student.can_apply:
return Response({'action': "Submit Application", 'message': "Student Can't Apply"},
status=status.HTTP_400_BAD_REQUEST)
# Only Allowing Applications for Placements
if data[OPENING_TYPE] == PLACEMENT:
if not student.can_apply: #why not checking in admin
return Response({'action': "Submit Application", 'message': "Student Can't Apply"},
status=status.HTTP_400_BAD_REQUEST)
if not len(PlacementApplication.objects.filter(
student_id=id, placement_id=data[OPENING_ID])):
application = PlacementApplication()
@ -187,6 +200,27 @@ def submitApplication(request, id, email, user_type):
application.placement = opening
else:
raise PermissionError("Application is already Submitted")
elif data[OPENING_TYPE] == INTERNSHIP:
if not student.can_apply_internship:
return Response({'action': "Submit Application", 'message': "Student Can't Apply Internship"},
status=status.HTTP_400_BAD_REQUEST)
if not len(InternshipApplication.objects.filter(
student_id=id, internship_id=data[OPENING_ID])):
application = InternshipApplication()
opening = get_object_or_404(Internship, id=data[OPENING_ID],
allowed_batch__contains=[student.batch],
allowed_branch__contains=[student.branch],
deadline_datetime__gte=datetime.datetime.now().date()
)
if not opening.offer_accepted or not opening.email_verified:
raise PermissionError("Internship Not Approved")
cond_stat, cond_msg = InternshipApplicationConditions(student, opening)
if not cond_stat:
raise PermissionError(cond_msg)
application.internship = opening
else:
raise PermissionError("Application is already Submitted")
else:
raise ValueError(OPENING_TYPE + " is Invalid")
@ -239,10 +273,22 @@ def submitApplication(request, id, email, user_type):
def deleteApplication(request, id, email, user_type):
try:
data = request.data
application = get_object_or_404(PlacementApplication, id=data[APPLICATION_ID],
if OPENING_TYPE in request.data:
opening_type = request.data[OPENING_TYPE]
else:
opening_type = PLACEMENT
if opening_type==INTERNSHIP: #check whether it has header or not
application = get_object_or_404(InternshipApplication, id=data[APPLICATION_ID],
student_id=id)
if application.placement.deadline_datetime < timezone.now():
raise PermissionError("Deadline Passed")
if application.internship.deadline_datetime < timezone.now():
raise PermissionError("Deadline Passed")
else:
application = get_object_or_404(PlacementApplication, id=data[APPLICATION_ID],
student_id=id)
if application.placement.deadline_datetime < timezone.now():
raise PermissionError("Deadline Passed")
application.delete()
return Response({'action': "Delete Application", 'message': "Application Deleted"},
@ -283,9 +329,17 @@ def studentAcceptOffer(request, id, email, user_type):
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()
if OPENING_TYPE in request.data:
opening_type = request.data[OPENING_TYPE]
else:
opening_type = PLACEMENT
if opening_type==INTERNSHIP:
application=InternshipApplication.objects.get(internship=company_id,student=student_id) #check syntax
else:
application=PlacementApplication.objects.get(placement=company_id,student=student_id)
application.offer_accepted=offer_status
application.save()
return Response({'action': "Accept Offer", 'message': "Updated Offer Status"},
status=status.HTTP_200_OK)
except:

View File

@ -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, Internship
from .models import User, PrePlacementOffer, PlacementApplication, Placement, Student, Internship,InternshipApplication
logger = logging.getLogger('db')
@ -112,10 +112,12 @@ def isAuthorized(allowed_users=None):
def wrapper_func(request, *args, **kwargs):
try:
headers = request.META
#print(headers)
if 'HTTP_AUTHORIZATION' in headers:
token_id = headers['HTTP_AUTHORIZATION'][7:]
idinfo = id_token.verify_oauth2_token(token_id, requests.Request(), CLIENT_ID)
email = idinfo[EMAIL]
# print(idinfo)
user = get_object_or_404(User, email=email)
if user:
user.last_login_time = timezone.now()
@ -167,6 +169,8 @@ def saveFile(file, location):
file_name = re.sub(r'[\\/:*?"<>|]', '_', file_name)
# print("Inside saveFile: " + str(file_name))
if not path.isdir(location):
os.makedirs(location)
@ -194,7 +198,7 @@ def sendEmail(email_to, subject, data, template, attachment_jnf_response=None):
else:
recipient_list = [str(email_to), ]
msg = EmailMultiAlternatives(subject, text_content, email_from, recipient_list)
msg = EmailMultiAlternatives(subject, text_content, email_from,"uttamthummala@gmail.com",bcc=recipient_list)
msg.attach_alternative(html_content, "text/html")
if attachment_jnf_response:
# logger.info(attachment_jnf_response)
@ -246,6 +250,20 @@ def PlacementApplicationConditions(student, placement):
logger.warning("Utils - PlacementApplicationConditions: " + str(sys.exc_info()))
return False, "_"
def InternshipApplicationConditions(student, internship):
try:
selected_companies = InternshipApplication.objects.filter(student=student, selected=True)
if len(selected_companies)>=1:
print("selected companies > 1")
return False, "You have already secured a Internship"
return True, "Conditions Satisfied"
except PermissionError as e:
return False, e
except:
logger.warning("Utils - InternshipApplicationConditions: " + str(sys.exc_info()))
return False, "_"
def getTier(compensation_gross, is_psu=False):
try:
@ -370,12 +388,27 @@ def placement_eligibility_filters(student, placements):
except:
logger.warning("Utils - placement_eligibility_filters: " + str(sys.exc_info()))
return placements
def internship_eligibility_filters(student, internships):
try:
filtered_internships = []
for internship in internships.iterator():
if InternshipApplicationConditions(student, internship)[0]:
filtered_internships.append(internship)
else:
print("Not applicable")
return filtered_internships
except:
logger.warning("Utils - internship_eligibility_filters: " + str(sys.exc_info()))
return internships
@background_task.background(schedule=2)
def send_opening_notifications(placement_id):
try:
placement = get_object_or_404(Placement, id=placement_id)
emails=[]
students = Student.objects.all()
for student in students.iterator():
if student.branch in placement.allowed_branch:
@ -393,12 +426,13 @@ def send_opening_notifications(placement_id):
"deadline": deadline_datetime.strftime("%A, %-d %B %Y, %-I:%M %p"),
"link": PLACEMENT_OPENING_URL.format(id=placement.designation)
}
sendEmail(student_user.email, subject, data, NOTIFY_STUDENTS_OPENING_TEMPLATE)
emails.append(student_user.email)
#sendEmail(student_user.email, subject, data, NOTIFY_STUDENTS_OPENING_TEMPLATE)
except Http404:
logger.warning('Utils - send_opening_notifications: user not found : ' + student.id)
except Exception as e:
logger.warning('Utils - send_opening_notifications: For Loop' + str(e))
sendEmail(emails, subject, data, NOTIFY_STUDENTS_OPENING_TEMPLATE) #handled multiple mailings
except:
logger.warning('Utils - send_opening_notifications: ' + str(sys.exc_info()))
return False

2
setup.sh Normal file → Executable file
View File

@ -3,7 +3,7 @@ echo "Environment setup complete"
cd CDC_Backend
python3 manage.py flush --no-input
python3 manage.py makemigrations
python3 manage.py makemigrations APIs
python3 manage.py migrate
echo "Migrations complete"