diff --git a/.gitignore b/.gitignore index 13184f251..bc7a548db 100644 --- a/.gitignore +++ b/.gitignore @@ -74,3 +74,5 @@ FusionIIIT/static/ package-lock.json +.DS_Store + diff --git a/FusionIIIT/Fusion/settings/common.py b/FusionIIIT/Fusion/settings/common.py index 54494036e..d9017dd40 100644 --- a/FusionIIIT/Fusion/settings/common.py +++ b/FusionIIIT/Fusion/settings/common.py @@ -111,6 +111,7 @@ 'notification', 'notifications', 'applications.academic_procedures', + 'applications.examination', 'applications.academic_information', 'applications.leave', 'applications.library', @@ -127,6 +128,7 @@ 'applications.ps1', 'applications.programme_curriculum', 'applications.placement_cell', + 'applications.otheracademic', 'applications.recruitment', 'applications.scholarships', 'applications.visitor_hostel', @@ -281,4 +283,4 @@ CORS_ORIGIN_ALLOW_ALL = True -ALLOW_PASS_RESET = True \ No newline at end of file +ALLOW_PASS_RESET = True diff --git a/FusionIIIT/Fusion/settings/development.py b/FusionIIIT/Fusion/settings/development.py index 3f95a478c..63587a11f 100644 --- a/FusionIIIT/Fusion/settings/development.py +++ b/FusionIIIT/Fusion/settings/development.py @@ -63,3 +63,5 @@ #the below job which we need to add in production server, to update the mess bill of student everyday at 10 pm in night ('0 22 * * *', 'applications.central_mess.tasks.generate_bill'), ] + +CRONTAB_DJANGO_MANAGE_PATH = '/home/owlman/Desktop/Fuse/Fusion/FusionIIIT/manage.py' \ No newline at end of file diff --git a/FusionIIIT/Fusion/urls.py b/FusionIIIT/Fusion/urls.py index 837bf776a..b9c03eeb8 100755 --- a/FusionIIIT/Fusion/urls.py +++ b/FusionIIIT/Fusion/urls.py @@ -60,4 +60,6 @@ url(r'^income-expenditure/', include('applications.income_expenditure.urls')), url(r'^hr2/', include('applications.hr2.urls')), url(r'^recruitment/', include('applications.recruitment.urls')), + url(r'^examination/', include('applications.examination.urls')), + url(r'^otheracademic/', include('applications.otheracademic.urls')), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/FusionIIIT/applications/academic_information/admin.py b/FusionIIIT/applications/academic_information/admin.py index 94f60274d..522815707 100755 --- a/FusionIIIT/applications/academic_information/admin.py +++ b/FusionIIIT/applications/academic_information/admin.py @@ -32,4 +32,3 @@ class Curriculum_InstructorAdmin(admin.ModelAdmin): admin.site.register(Holiday) admin.site.register(Curriculum,CurriculumAdmin) -#Hello! diff --git a/FusionIIIT/applications/academic_information/api/serializers.py b/FusionIIIT/applications/academic_information/api/serializers.py index 06d6154c5..fd4fb59b7 100644 --- a/FusionIIIT/applications/academic_information/api/serializers.py +++ b/FusionIIIT/applications/academic_information/api/serializers.py @@ -18,7 +18,6 @@ class Meta: class CurriculumSerializer(serializers.ModelSerializer): course_id = CourseSerializer() - class Meta: model = Curriculum fields = ('curriculum_id','course_code','course_id','credits','course_type', diff --git a/FusionIIIT/applications/academic_information/api/urls.py b/FusionIIIT/applications/academic_information/api/urls.py index e7fe37be9..39a89fdb3 100644 --- a/FusionIIIT/applications/academic_information/api/urls.py +++ b/FusionIIIT/applications/academic_information/api/urls.py @@ -27,4 +27,4 @@ # url(r'^grades',views.grades_api,name='grades-get-api'), # url(r'^spi',views.spi_api,name='spi-get-api') -] \ No newline at end of file +] diff --git a/FusionIIIT/applications/academic_information/api/views.py b/FusionIIIT/applications/academic_information/api/views.py index 192785374..bbe6aebef 100644 --- a/FusionIIIT/applications/academic_information/api/views.py +++ b/FusionIIIT/applications/academic_information/api/views.py @@ -1,181 +1,182 @@ -# from django.contrib.auth import get_user_model -# from django.contrib.auth.decorators import login_required -# from applications.globals.models import (HoldsDesignation,Designation) -# from django.shortcuts import get_object_or_404 -# from django.forms.models import model_to_dict -# from rest_framework.permissions import IsAuthenticated -# from rest_framework.authentication import TokenAuthentication -# from rest_framework import status -# from rest_framework.decorators import api_view, permission_classes,authentication_classes -# from rest_framework.permissions import AllowAny -# from rest_framework.response import Response -# from applications.globals.models import User,ExtraInfo -# from applications.academic_information.models import Student, Course, Curriculum, Curriculum_Instructor, Student_attendance, Meeting, Calendar, Holiday, Grades, Spi, Timetable, Exam_timetable -# from . import serializers - -# @api_view(['GET']) +from django.contrib.auth import get_user_model +from django.contrib.auth.decorators import login_required +from applications.globals.models import (HoldsDesignation,Designation) +from django.shortcuts import get_object_or_404 +from django.forms.models import model_to_dict +from rest_framework.permissions import IsAuthenticated +from rest_framework.authentication import TokenAuthentication +from rest_framework import status +from rest_framework.decorators import api_view, permission_classes,authentication_classes +from rest_framework.permissions import AllowAny +from rest_framework.response import Response +from applications.globals.models import User,ExtraInfo +from applications.academic_information.models import Student, Course, Curriculum, Curriculum_Instructor, Student_attendance, Meeting, Calendar, Holiday, Grades, Spi, Timetable, Exam_timetable +from . import serializers + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def student_api(request): + + if request.method == 'GET': + student = Student.objects.all() + student_serialized = serializers.StudentSerializers(student,many=True).data + resp = { + 'students' : student_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) + + +@api_view(['GET']) # @permission_classes([IsAuthenticated]) # @authentication_classes([TokenAuthentication]) -# def student_api(request): - -# if request.method == 'GET': -# student = Student.objects.all() -# student_serialized = serializers.StudentSerializers(student,many=True).data -# resp = { -# 'students' : student_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) - - -# @api_view(['GET']) -# @permission_classes([IsAuthenticated]) -# @authentication_classes([TokenAuthentication]) -# def course_api(request): - -# if request.method == 'GET': -# course = Course.objects.all() -# course_serialized = serializers.CourseSerializer(course,many=True).data -# resp = { -# 'courses' : course_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) - - -# @api_view(['GET']) -# @permission_classes([IsAuthenticated]) -# @authentication_classes([TokenAuthentication]) -# def curriculum_api(request): - -# if request.method == 'GET': -# curriculum = Curriculum.objects.all() -# curriculum_serialized = serializers.CurriculumSerializer(curriculum,many=True).data -# resp = { -# 'curriculum' : curriculum_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) - - -# @api_view(['GET']) -# @permission_classes([IsAuthenticated]) -# @authentication_classes([TokenAuthentication]) -# def meeting_api(request): - -# if request.method == 'GET': -# meeting = Meeting.objects.all() -# meeting_serialized = serializers.MeetingSerializers(meeting,many=True).data -# resp = { -# 'meeting' : meeting_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) - - -# @api_view(['GET']) -# @permission_classes([IsAuthenticated]) -# @authentication_classes([TokenAuthentication]) -# def calendar_api(request): - -# if request.method == 'GET': -# calendar = Calendar.objects.all() -# calendar_serialized = serializers.CalendarSerializers(calendar,many=True).data -# resp = { -# 'calendar' :calendar_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) - - -# @api_view(['GET']) -# @permission_classes([IsAuthenticated]) -# @authentication_classes([TokenAuthentication]) -# def holiday_api(request): - -# if request.method == 'GET': -# holiday = Holiday.objects.all() -# holiday_serialized = serializers.HolidaySerializers(holiday,many=True).data -# resp = { -# 'holiday' : holiday_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) - - -# @api_view(['GET']) -# @permission_classes([IsAuthenticated]) -# @authentication_classes([TokenAuthentication]) -# def timetable_api(request): - -# if request.method == 'GET': -# timetable = Timetable.objects.all() -# timetable_serialized = serializers.TimetableSerializers(timetable,many=True).data -# resp = { -# 'timetable' : timetable_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) - - -# @api_view(['GET']) -# @permission_classes([IsAuthenticated]) -# @authentication_classes([TokenAuthentication]) -# def exam_timetable_api(request): - -# if request.method == 'GET': -# exam_timetable = Exam_timetable.objects.all() -# exam_timetable_serialized = serializers.Exam_timetableSerializers(exam_timetable,many=True).data -# resp = { -# 'exam_timetable' : exam_timetable_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) - - -# @api_view(['GET']) -# @permission_classes([IsAuthenticated]) -# @authentication_classes([TokenAuthentication]) -# def curriculum_instructor_api(request): - -# if request.method == 'GET': -# curriculum_instructor = Curriculum_Instructor.objects.all() -# curriculum_instructor_serialized = serializers.CurriculumInstructorSerializer(curriculum_instructor,many=True).data -# resp = { -# 'curriculum_instructor' : curriculum_instructor_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) - - -# @api_view(['GET']) -# @permission_classes([IsAuthenticated]) -# @authentication_classes([TokenAuthentication]) -# def student_attendance_api(request): - -# if request.method == 'GET': -# student_attendance = Student_attendance.objects.all() -# student_attendance_serialized = serializers.Student_attendanceSerializers(student_attendance,many=True).data -# resp = { -# 'student_attendance' : student_attendance_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) - - -# @api_view(['GET']) -# @permission_classes([IsAuthenticated]) -# @authentication_classes([TokenAuthentication]) -# def grades_api(request): - -# if request.method == 'GET': -# grades = Grades.objects.all() -# grades_serialized = serializers.GradesSerializers(grades,many=True).data -# resp = { -# 'grades' : grades_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) - - -# @api_view(['GET']) -# @permission_classes([IsAuthenticated]) -# @authentication_classes([TokenAuthentication]) -# def spi_api(request): - -# if request.method == 'GET': -# spi = Spi.objects.all() -# spi_serialized = serializers.SpiSerializers(spi,many=True).data -# resp = { -# 'spi' : spi_serialized, -# } -# return Response(data=resp,status=status.HTTP_200_OK) \ No newline at end of file +def course_api(request): + + if request.method == 'GET': + course = Course.objects.all() + course_serialized = serializers.CourseSerializer(course,many=True).data + resp = { + 'courses' : course_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) + + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def curriculum_api(request): + + if request.method == 'GET': + curriculum = Curriculum.objects.all() + curriculum_serialized = serializers.CurriculumSerializer(curriculum,many=True).data + resp = { + 'curriculum' : curriculum_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def meeting_api(request): + + if request.method == 'GET': + meeting = Meeting.objects.all() + meeting_serialized = serializers.MeetingSerializers(meeting,many=True).data + resp = { + 'meeting' : meeting_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def calendar_api(request): + + if request.method == 'GET': + calendar = Calendar.objects.all() + calendar_serialized = serializers.CalendarSerializers(calendar,many=True).data + resp = { + 'calendar' :calendar_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def holiday_api(request): + + if request.method == 'GET': + holiday = Holiday.objects.all() + holiday_serialized = serializers.HolidaySerializers(holiday,many=True).data + resp = { + 'holiday' : holiday_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def timetable_api(request): + + if request.method == 'GET': + timetable = Timetable.objects.all() + timetable_serialized = serializers.TimetableSerializers(timetable,many=True).data + resp = { + 'timetable' : timetable_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def exam_timetable_api(request): + + if request.method == 'GET': + exam_timetable = Exam_timetable.objects.all() + exam_timetable_serialized = serializers.Exam_timetableSerializers(exam_timetable,many=True).data + resp = { + 'exam_timetable' : exam_timetable_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def curriculum_instructor_api(request): + + if request.method == 'GET': + curriculum_instructor = Curriculum_Instructor.objects.all() + curriculum_instructor_serialized = serializers.CurriculumInstructorSerializer(curriculum_instructor,many=True).data + resp = { + 'curriculum_instructor' : curriculum_instructor_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def student_attendance_api(request): + + if request.method == 'GET': + student_attendance = Student_attendance.objects.all() + student_attendance_serialized = serializers.Student_attendanceSerializers(student_attendance,many=True).data + resp = { + 'student_attendance' : student_attendance_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def grades_api(request): + + if request.method == 'GET': + grades = Grades.objects.all() + grades_serialized = serializers.GradesSerializers(grades,many=True).data + resp = { + 'grades' : grades_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def spi_api(request): + + if request.method == 'GET': + spi = Spi.objects.all() + spi_serialized = serializers.SpiSerializers(spi,many=True).data + resp = { + 'spi' : spi_serialized, + } + return Response(data=resp,status=status.HTTP_200_OK) \ No newline at end of file diff --git a/FusionIIIT/applications/academic_information/models.py b/FusionIIIT/applications/academic_information/models.py index d5103fbd7..280e84b32 100755 --- a/FusionIIIT/applications/academic_information/models.py +++ b/FusionIIIT/applications/academic_information/models.py @@ -69,7 +69,7 @@ class Student(models.Model): ''' Current Purpose : To store information pertinent to a user who is also a student - + ATTRIBUTES : @@ -99,9 +99,6 @@ class Student(models.Model): room_no = models.CharField(max_length=10, blank=True, null=True) specialization = models.CharField(max_length=40,choices=Constants.MTechSpecialization, null=True, default='') curr_semester_no = models.IntegerField(default=1) -# pwd_status = models.BooleanField(null=True, blank=True,default=False) -# father_mobile_no = models.CharField(max_length=10, null=True, blank=True, default='9999999999') -# mother_mobile_no = models.CharField(max_length=10, null=True, blank=True, default='9999999999') def __str__(self): username = str(self.id.user.username) @@ -110,17 +107,7 @@ def __str__(self): class Course(models.Model): - ''' - Current Purpose : To store information of a course - - - - ATTRIBUTES : - - course_name(char) - to store the name of the course - course_details(TextField) - to store the course details - - ''' + course_name = models.CharField(max_length=600) course_details = models.TextField(max_length=500) @@ -132,25 +119,7 @@ def __str__(self): class Curriculum(models.Model): - ''' - Current Purpose : Currently this table stores mapping of a course to a particular semester and relevant details - - ! - the table does not follow the conventional definition of the term Curriculum - ATTRIBUTES : - - curriculum_id(AutoField) - to store the automatically generated course id which will be the primary key - course_code(CharField) - stores the course code (can be null) - course_id(academic_information.Course) - foreign key to the course - credits(integer) - stores credits assigned for the course - course_type(char) - to select the type of the course(eg : Professional Core/Project) - programme(char) - to store the programme for which the course is being offered - branch(char) - to store the branch/discipline for which the course is being offered(eg CSE) - batch(integer) - to store the batch for which the course is available(eg:2019) - sem(Integer) - the semester in which the course is offered for a batch - optional(Boolean) - denotes whether the course is optional or not - floated(Boolean) - denotes whether a course is floated for a particular semester or not - - ''' + curriculum_id = models.AutoField(primary_key=True) course_code = models.CharField(max_length = 20) course_id = models.ForeignKey(Course,on_delete= models.CASCADE) @@ -172,23 +141,7 @@ def __str__(self): class Curriculum_Instructor(models.Model): - ''' - Current Purpose : Currently this table stores mapping of a course in a semester to the faculty who will teach the course - - ! - the table does not follow the conventional definition of the term Curriculum - - - - - - ATTRIBUTES : - - curriculum_id(academic_information.Curriculum) - reference to the course details - instructor_id(globals.ExtraInfo) - reference to the faculty who will teach the course - chief_inst(Bool) - denotes whether the faculty is the chief instructor of the course or not - - - ''' + curriculum_id = models.ForeignKey(Curriculum, on_delete=models.CASCADE) instructor_id = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) chief_inst = models.BooleanField(default=False) @@ -205,27 +158,11 @@ def __str__(self): class Student_attendance(models.Model): - ''' - Current Purpose : Currently this table stores mapping of a student's attendance for a particular course in a semester - - - - - - - ATTRIBUTES : - - student_id(academic_information.Student) - referene to the student for whom the attendance is being recorded - instructor_id(academic_information.Curriculum_Instructor) - reference to the faculty and course - date(DateField) - the date for which the attendance will be recorded - present(Boolean) - to denote whether the student was present or not - - ''' + student_id = models.ForeignKey(Student,on_delete=models.CASCADE) -# course_id = models.ForeignKey(Course) -# attend = models.CharField(max_length=6, choices=Constants.ATTEND_CHOICES) + instructor_id = models.ForeignKey(Curriculum_Instructor, on_delete=models.CASCADE) -# curriculum_id = models.ForeignKey(Curriculum, on_delete=models.CASCADE) + date = models.DateField() present = models.BooleanField(default=False) @@ -237,18 +174,7 @@ def __self__(self): class Meeting(models.Model): - ''' - Current Purpose : stores the information regarding a meeting which was conducted by the academic department - - ATTRIBUTES: - - venue(char) - venue where the meeting will be held(eg:L-103) - date(DateField) - the date on which the meeting was held - time(char) - time at the meeting was held - agenga(text) - the points of discussion for the meeting - minutes_file(char) - the summary of the meeting - - ''' + venue = models.CharField(max_length=50) date = models.DateField() time = models.CharField(max_length=20) @@ -263,15 +189,7 @@ def __str__(self): class Calendar(models.Model): - ''' - Current Purpose : stores the information regarding an academic event(eg : course registrations etc) - - ATTRIBUTES: - - from_date(DateField) - start date of the event - to_date(DateField) - end date of the event - description(Char) - description about the event - ''' + from_date = models.DateField() to_date = models.DateField() description = models.CharField(max_length=40) @@ -284,14 +202,7 @@ def __str__(self): class Holiday(models.Model): - ''' - Current Purpose : stores the information regarding a holiday - - ATTRIBUTES - holiday_date(DateField) - the date of the holidar - holiday_name(char) - to denote the name of the holiday(eg : Republic Day) - holiday_type - to store whether the holiday is restricted or closed - ''' + holiday_date = models.DateField() holiday_name = models.CharField(max_length=40) holiday_type = models.CharField(default='restricted', max_length=30, @@ -305,14 +216,7 @@ def __str__(self): class Grades(models.Model): - ''' - Current Purpose : stores the information regarding the gradees of a student for a course in a semester - - ATTRIBUTES - student_id(academic_information.Student) - Reference to the student for whom the grades is about to be stores - curriculum_id(academic_information.Curriculum) - Reference to the course for which the graded are to be given - grade(Char) - denotes whether the grade given to the student is verified or not - ''' + student_id = models.ForeignKey(Student,on_delete=models.CASCADE) curriculum_id = models.ForeignKey(Curriculum,on_delete=models.CASCADE) grade = models.CharField(max_length=4) @@ -323,14 +227,7 @@ class Meta: class Spi(models.Model): - ''' - Current Purpose : stores the information regarding the SPI of a student for a semester - - ATTRIBUTES - sem(Integer) - the semester to which the spi refers to - student_id(academic_information.Student) - the student for whom the spi is stored - spi(float) - the spi value achieved - ''' + sem = models.IntegerField() student_id = models.ForeignKey(Student, on_delete=models.CASCADE) spi = models.FloatField(default=0) @@ -344,18 +241,7 @@ def __self__(self): class Timetable(models.Model): - ''' - Current Purpose : stores the class-schedule timetable for a batch (eg CSE -2019-Btech) - - ATTRIBUTES - - upload_date(DateTime) - stores the upload date and time - time_table(File) - the file which contains the timetable - batch(Integer) - stores the batch for which the timetable is valid - programme(Char) - stores the programme for which the time table is valid - branch(char) - the branch for which the time table is valid - ''' - + upload_date = models.DateTimeField(auto_now_add=True) time_table = models.FileField(upload_to='Administrator/academic_information/') batch = models.IntegerField(default="2016") @@ -366,17 +252,7 @@ class Meta: class Exam_timetable(models.Model): - ''' - Current Purpose : stores the exam-schedule timetable for a batch (2019-Btech) - - ATTRIBUTES - - upload_date(DateTime) - stores the upload date and time - exam_time_table(File) - the file which contains the timetable - batch(Integer) - stores the batch for which the timetable is valid - programme(Char) - stores the programme for which the time table is valid - - ''' + upload_date = models.DateField(auto_now_add=True) exam_time_table = models.FileField(upload_to='Administrator/academic_information/') batch = models.IntegerField(default="2016") diff --git a/FusionIIIT/applications/academic_information/views.py b/FusionIIIT/applications/academic_information/views.py index 22210a52e..b3702b3ef 100755 --- a/FusionIIIT/applications/academic_information/views.py +++ b/FusionIIIT/applications/academic_information/views.py @@ -28,7 +28,7 @@ -from applications.academic_procedures.views import acad_proced_global_context +from applications.academic_procedures.views import acad_proced_global_context , get_sem_courses from applications.programme_curriculum.models import Batch @@ -107,9 +107,8 @@ def get_context(request): # course_type = Constants.COURSE_TYPE # timetable = Timetable.objects.all() # exam_t = Exam_timetable.objects.all() - procedures_context = acad_proced_global_context() - + notifs = request.user.notifications.all() try: examTtForm = ExamTimetableForm() acadTtForm = AcademicTimetableForm() @@ -176,7 +175,8 @@ def get_context(request): 'batch_branch_data' : procedures_context['batch_branch_data'], 'assistant_flag' : assistant_flag, 'hod_flag' : hod_flag, - 'account_flag' : account_flag + 'account_flag' : account_flag, + 'notifications': notifs, } return context @@ -842,12 +842,16 @@ def generatexlsheet(request): """ if user_check(request): return HttpResponseRedirect('/academic-procedures/') - + # print(request.POST) try: - batch = request.POST['batch'] - course = Courses.objects.get(id = request.POST['course']) + batch = request.POST['batch']#batch hai year wala (2020 , 21) + course_id = int(request.POST['course']) # id of course in integer + course = course = Courses.objects.get(id=course_id) + + # print(course.name) obj = course_registration.objects.all().filter(course_id = course) except Exception as e: + print(str(e)) batch="" course="" curr_key="" @@ -1029,9 +1033,14 @@ def generate_preregistration_report(request): max_width = max(max_width,len(choices_of_current_student)) for choice in range(1,len(choices_of_current_student)+1): - current_choice = InitialRegistration.objects.get(student_id=student, semester_id__semester_no=sem,course_slot_id = slot,priority = choice) - # #print("current choice is ",current_choice) - z.append(str(current_choice.course_id.code)+"-"+str(current_choice.course_id.name)) + try: + current_choice = InitialRegistration.objects.get(student_id=student, semester_id__semester_no=sem, course_slot_id=slot, priority=choice) + z.append(str(current_choice.course_id.code) + "-" + str(current_choice.course_id.name)) + except : + z.append("No registration found") + # current_choice = InitialRegistration.objects.get(student_id=student, semester_id__semester_no=sem,course_slot_id = slot,priority = choice) + # # #print("current choice is ",current_choice) + # z.append(str(current_choice.course_id.code)+"-"+str(current_choice.course_id.name)) data.append(z) m+=1 @@ -1169,9 +1178,9 @@ def add_new_profile (request): } if request.method == 'POST' and request.FILES: profiles=request.FILES['profiles'] - excel = xlrd.open_workbook(file_contents=profiles.read()) + excel = xlrd.open_workbook(profiles.name,file_contents=profiles.read()) sheet=excel.sheet_by_index(0) - for i in range(sheet.nrows): + for i in range(1,sheet.nrows): roll_no=sheet.cell(i,0).value first_name=str(sheet.cell(i,1).value) last_name=str(sheet.cell(i,2).value) @@ -1191,7 +1200,7 @@ def add_new_profile (request): category="" phone_no=0 address="" - dept=str(sheet.cell(i,12).value) + dept=str(sheet.cell(i,11).value) specialization=str(sheet.cell(i,12).value) hall_no=None @@ -1209,7 +1218,6 @@ def add_new_profile (request): batch_year=request.POST['Batch'] batch = Batch.objects.all().filter(name = programme_name, discipline__acronym = dept, year = batch_year).first() - user = User.objects.create_user( username=roll_no, password='hello123', @@ -1217,6 +1225,7 @@ def add_new_profile (request): last_name=last_name, email=email, ) + einfo = ExtraInfo.objects.create( id=roll_no, @@ -1253,6 +1262,11 @@ def add_new_profile (request): working=user, designation=desig, ) + + user.save() + einfo.save() + stud_data.save() + hold_des.save() sem_id = Semester.objects.get(curriculum = batch.curriculum, semester_no = sem) course_slots = CourseSlot.objects.all().filter(semester = sem_id) @@ -2063,14 +2077,15 @@ def view_all_student_data(request): "specailization": student.specialization, "gender" : student.id.sex, "category": student.category, - "pwd_status": student.pwd_status, + # "pwd_status": student.pwd_status, + "pwd_status": False, "Mobile": student.id.phone_no, "dob" : student.id.date_of_birth, "emailid" : student.id.user.email, "father_name": student.father_name, - "father_mobile_no": student.father_mobile_no, + # "father_mobile_no": student.father_mobile_no, "mother_name": student.mother_name, - "mother_mobile_no": student.mother_mobile_no, + # "mother_mobile_no": student.mother_mobile_no, "address": student.id.address } data.append(obj) @@ -2140,9 +2155,9 @@ def generatestudentxlsheet(request): data = None else: if(request_rollno != ""): - students = Student.objects.select_related('batch_id', 'id__user', 'batch_id__discipline', 'id').filter(id = request_rollno).only('batch', 'id__id', 'id__user', 'programme','pwd_status', 'father_mobile_no', 'mother_mobile_no', 'batch_id__discipline__acronym', 'specialization', 'id__sex', 'category', 'id__phone_no', 'id__date_of_birth', 'id__user__first_name', 'id__user__last_name', 'id__user__email', 'father_name', 'mother_name', 'id__address') + students = Student.objects.select_related('batch_id', 'id__user', 'batch_id__discipline', 'id').filter(id = request_rollno).only('batch', 'id__id', 'id__user', 'programme', 'batch_id__discipline__acronym', 'specialization', 'id__sex', 'category', 'id__phone_no', 'id__date_of_birth', 'id__user__first_name', 'id__user__last_name', 'id__user__email', 'father_name', 'mother_name', 'id__address') else: - students = Student.objects.select_related('batch_id', 'id__user', 'batch_id__discipline', 'id').filter(**filter_names).order_by('id').all().only('batch', 'id__id', 'id__user', 'programme','pwd_status', 'father_mobile_no', 'mother_mobile_no', 'batch_id__discipline__acronym', 'specialization', 'id__sex', 'category', 'id__phone_no', 'id__date_of_birth', 'id__user__first_name', 'id__user__last_name', 'id__user__email', 'father_name', 'mother_name', 'id__address') + students = Student.objects.select_related('batch_id', 'id__user', 'batch_id__discipline', 'id').filter(**filter_names).order_by('id').all().only('batch', 'id__id', 'id__user', 'programme', 'batch_id__discipline__acronym', 'specialization', 'id__sex', 'category', 'id__phone_no', 'id__date_of_birth', 'id__user__first_name', 'id__user__last_name', 'id__user__email', 'father_name', 'mother_name', 'id__address') for i in students: obj = [] obj.append(i.batch) @@ -2153,14 +2168,17 @@ def generatestudentxlsheet(request): obj.append(i.specialization) obj.append(i.id.sex) obj.append(i.category) - obj.append(i.pwd_status) + #obj.append(i.pwd_status) + obj.append(None) obj.append(i.id.phone_no) obj.append(i.id.date_of_birth) obj.append(i.id.user.email) obj.append(i.father_name) - obj.append(i.father_mobile_no) + #obj.append(i.father_mobile_no) + obj.append(None) obj.append(i.mother_name) - obj.append(i.mother_mobile_no) + # obj.append(i.mother_mobile_no) + obj.append(None) obj.append(i.id.address) data.append(obj) data.sort() diff --git a/FusionIIIT/applications/academic_procedures/api/serializers.py b/FusionIIIT/applications/academic_procedures/api/serializers.py index e8020d0e0..ee3d46743 100644 --- a/FusionIIIT/applications/academic_procedures/api/serializers.py +++ b/FusionIIIT/applications/academic_procedures/api/serializers.py @@ -1,13 +1,13 @@ from rest_framework.authtoken.models import Token from rest_framework import serializers -from applications.academic_procedures.models import (ThesisTopicProcess, InitialRegistrations, - FinalRegistrations, SemesterMarks, - BranchChange) +from applications.academic_procedures.models import (ThesisTopicProcess, InitialRegistrations,InitialRegistration, + FinalRegistration, FinalRegistrations, SemesterMarks, + BranchChange , StudentRegistrationChecks, Semester, backlog_course , CourseSlot , FeePayments , Course, course_registration) from applications.academic_information.api.serializers import (CurriculumInstructorSerializer, - CurriculumSerializer) -from applications.globals.api.serializers import (UserSerializer, HoldsDesignationSerializer) + CurriculumSerializer , CourseSerializer , StudentSerializers ) +from applications.globals.api.serializers import (UserSerializer, HoldsDesignationSerializer , ExtraInfoSerializer) class ThesisTopicProcessSerializer(serializers.ModelSerializer): @@ -27,6 +27,24 @@ class Meta: model = FinalRegistrations fields = ('__all__') +class InitialRegistrationSerializer(serializers.ModelSerializer): + + class Meta: + model = InitialRegistration + fields = ('__all__') + +class FinalRegistrationSerializer(serializers.ModelSerializer): + + class Meta: + model = FinalRegistration + fields = ('__all__') + +class StudentRegistrationChecksSerializer(serializers.ModelSerializer): + class Meta: + model = StudentRegistrationChecks + fields = '__all__' + + class SemesterMarksSerializer(serializers.ModelSerializer): class Meta: @@ -38,3 +56,24 @@ class BranchChangeSerializer(serializers.ModelSerializer): class Meta: model = BranchChange fields = ('__all__') + +class SemesterSerializer(serializers.ModelSerializer): + + class Meta: + model = Semester + fields = ('__all__') + +class CourseRegistrationSerializer(serializers.ModelSerializer): + class Meta: + model = course_registration + fields = ('__all__') + +class CourseSlotSerializer(serializers.ModelSerializer): + class Meta: + model = CourseSlot + fields = ('__all__') + +class CourseSerializer(serializers.ModelSerializer): + class Meta: + model = Course + fields = ('__all__') \ No newline at end of file diff --git a/FusionIIIT/applications/academic_procedures/api/urls.py b/FusionIIIT/applications/academic_procedures/api/urls.py index 3abeace02..1f46e8d4d 100644 --- a/FusionIIIT/applications/academic_procedures/api/urls.py +++ b/FusionIIIT/applications/academic_procedures/api/urls.py @@ -1,12 +1,45 @@ from django.conf.urls import url - from . import views + urlpatterns = [ + url(r'^stu/details', views.academic_procedures_student, name='student_procedures'), + url(r'^stu/pre_registration' , views.student_pre_registration , name = 'pre_registration'), + url(r'^stu/final_registration' , views.final_registration , name = 'final_registration'), + url(r'^stu/add_one_course/' , views.add_one_course , name = 'add_one_course'), + url(r'^stu/view_registration' , views.student_view_registration , name = 'view_registration'), + url(r'^stu/view_offered_courses' , views.view_offered_courses , name = 'student_view_offered_courses'), + url(r'^stu/backlog_courses', views.student_backlog_courses , name = 'student_backlog_courses'), + url(r'^stu/add_course' , views.add_course , name ='add_course') , + url(r'^stu/drop_course' , views.drop_course , name = 'drop_course'), + # url(r'^stu/replaceCourse' , views.replaceCourse , name = 'replaceCourse') + + + + url(r'^acad/view_registrations' , views.acad_view_reigstrations , name='acad_view_registrations'), + url(r'^acad/verify_registration' , views.verify_registration , name='verify_registration'), + url(r'^acad/get_course_list' , views.get_course_list , name = 'get_course_list' ), + url(r'^acad/get_all_courses' , views.get_all_courses , name = 'get_all_courses' ), + url(r'^acad/gen_roll_list' , views.gen_roll_list , name = 'gen_roll_list' ), + url(r'^acad/configure_pre_registration' , views.configure_pre_registration_date , name = 'configure_pre_registration'), + url(r'^acad/configure_final_registration' , views.configure_final_registration_date , name = 'configure_final_registration'), + url(r'^acad/add_course_to_slot' , views.add_course_to_slot , name = 'add_course_to_slot'), + url(r'^acad/remove_course_from_slot' , views.remove_course_from_slot , name = 'remove_course_from_slot'), + url(r'^get_next_sem_courses' , views.get_next_sem_courses , name= 'get_next_sem_courses'), + + + url(r'^fac/view_assigned_courses' , views.faculty_assigned_courses , name = 'faculty_assigned_courses'), + # url(r'^fac/get_roll_list' , views.fetch_roll_list , name = 'fetch_roll_list'), + + + + url(r'^get_user_info' , views.get_user_info , name = 'get_user_info'), + + # these urls were designed previously and are not working any more - url(r'^fac/', views.academic_procedures_faculty, name='faculty_procedures'), - url(r'^stu/', views.academic_procedures_student, name='student_procedures'), - url(r'^addThesis/', views.add_thesis, name='add_thesis'), - url(r'^approve_thesis/(?P[0-9]+)/', views.approve_thesis, name='approve_thesis'), + # url(r'^fac/', views.academic_procedures_faculty, name='faculty_procedures'), + # url(r'^stu', views.academic_procedures_student, name='student_procedures'), + # url(r'^addThesis/', views.add_thesis, name='add_thesis'), + # url(r'^approve_thesis/(?P[0-9]+)/', views.approve_thesis, name='approve_thesis') -] +] \ No newline at end of file diff --git a/FusionIIIT/applications/academic_procedures/api/views.py b/FusionIIIT/applications/academic_procedures/api/views.py index aab6deaa7..167ec6c84 100644 --- a/FusionIIIT/applications/academic_procedures/api/views.py +++ b/FusionIIIT/applications/academic_procedures/api/views.py @@ -1,8 +1,10 @@ import datetime - +from django.utils import timezone from django.contrib.auth import get_user_model from django.shortcuts import get_object_or_404, redirect +from django.db import transaction +from django.http import JsonResponse from rest_framework.permissions import IsAuthenticated from rest_framework.authentication import TokenAuthentication from rest_framework import status @@ -10,11 +12,15 @@ from rest_framework.permissions import AllowAny from rest_framework.response import Response -from applications.academic_information.models import Curriculum -from applications.academic_procedures.models import ThesisTopicProcess from applications.globals.models import HoldsDesignation, Designation, ExtraInfo -from applications.programme_curriculum.models import (CourseSlot, Course as Courses, Batch, Semester) +from applications.programme_curriculum.models import ( CourseSlot, Course as Courses, Batch, Semester) + +from applications.academic_procedures.models import (Course, Student, Curriculum , ThesisTopicProcess, InitialRegistrations, + FinalRegistration, SemesterMarks,backlog_course, + BranchChange , StudentRegistrationChecks, Semester , FeePayments , course_registration) + +from applications.academic_information.models import (Curriculum_Instructor , Calendar) from applications.academic_procedures.views import (get_user_semester, get_acad_year, get_currently_registered_courses, @@ -23,7 +29,11 @@ get_registration_courses, get_add_course_options, get_pre_registration_eligibility, get_final_registration_eligibility, - get_add_or_drop_course_date_eligibility) + get_add_or_drop_course_date_eligibility, + get_detailed_sem_courses, + InitialRegistration) + +from applications.academic_procedures.views import get_sem_courses, get_student_registrtion_check, get_cpi, academics_module_notif from . import serializers @@ -31,46 +41,13 @@ date_time = datetime.datetime.now() -@api_view(['GET']) -def academic_procedures_faculty(request): - current_user = request.user - user_details = current_user.extrainfo - des = current_user.holds_designations.all().first() - if str(des.designation) == 'student': - return Response({'error':'Not a faculty'}, status=status.HTTP_400_BAD_REQUEST) - elif str(current_user) == 'acadadmin': - return Response({'error':'User is acadadmin'}, status=status.HTTP_400_BAD_REQUEST) - - elif str(des.designation) == "Associate Professor" or str(des.designation) == "Professor" or str(des.designation) == "Assistant Professor": - faculty_object = user_details.faculty - month = int(date_time.month) - sem = [] - if month>=7 and month<=12: - sem = [1,3,5,7] - else: - sem = [2,4,6,8] - student_flag = False - fac_flag = True - thesis_supervision_request_list = faculty_object.thesistopicprocess_supervisor.all() - thesis_supervision_request_list_data = serializers.ThesisTopicProcessSerializer(thesis_supervision_request_list, many=True).data - approved_thesis_request_list = serializers.ThesisTopicProcessSerializer(thesis_supervision_request_list.filter(approval_supervisor = True), many=True).data - pending_thesis_request_list = serializers.ThesisTopicProcessSerializer(thesis_supervision_request_list.filter(pending_supervisor = True), many=True).data - courses_list = serializers.CurriculumInstructorSerializer(user_details.curriculum_instructor_set.all(), many=True).data - fac_details = serializers.UserSerializer(current_user).data +#--------------------------------------- APIs of student---------------------------------------------------------- - resp = { - 'student_flag' : student_flag, - 'fac_flag' : fac_flag, - 'thesis_supervision_request_list' : thesis_supervision_request_list_data, - 'pending_thesis_request_list' : pending_thesis_request_list, - 'approved_thesis_request_list' : approved_thesis_request_list, - 'courses_list': courses_list, - 'faculty': fac_details - } - return Response(data=resp, status=status.HTTP_200_OK) +demo_date = timezone.now() +# with this student can get all his details in one api call @api_view(['GET']) def academic_procedures_student(request): current_user = request.user @@ -128,6 +105,10 @@ def academic_procedures_student(request): else: return Response({'message':'Student has no record'}, status=status.HTTP_400_BAD_REQUEST) + + current_date = demo_date.date() + year = demo_date.year + current_date = date_time.date() current_year = date_time.year batch = obj.batch_id @@ -145,6 +126,7 @@ def academic_procedures_student(request): 'cpi' : cpi, 'spi' : cur_spi } + currently_registered_courses = get_currently_registered_courses(user_details.id, user_sem) currently_registered_courses_data = serializers.CurriculumSerializer(currently_registered_courses, many=True).data try: @@ -157,14 +139,47 @@ def academic_procedures_student(request): final_registered_courses = obj.finalregistrations_set.all().filter(semester = user_sem) except: final_registered_courses = None + + try: + pre_registered_courses = InitialRegistration.objects.all().filter(student_id = user_details.id,semester_id = next_sem_id) + pre_registered_course_show = {} + pre_registration_timestamp=None + for pre_registered_course in pre_registered_courses: + pre_registration_timestamp=pre_registered_course.timestamp + if(pre_registered_course.course_slot_id.name not in pre_registered_course_show): + pre_registered_course_show[pre_registered_course.course_slot_id.name] = [{"course_code":pre_registered_course.course_id.code,"course_name":pre_registered_course.course_id.name,"course_credit":pre_registered_course.course_id.credit,"priority":pre_registered_course.priority}] + else: + pre_registered_course_show[pre_registered_course.course_slot_id.name].append({"course_code":pre_registered_course.course_id.code,"course_name":pre_registered_course.course_id.name,"course_credit":pre_registered_course.course_id.credit,"priority":pre_registered_course.priority}) + pre_registration_timestamp=str(pre_registration_timestamp) + except Exception as e: + pre_registered_courses = None + pre_registered_course_show = None + + try: + final_registered_courses = FinalRegistration.objects.all().filter(student_id = user_details.id,semester_id = next_sem_id) + final_registered_course_show=[] + for final_registered_course in final_registered_courses: + final_registered_course_show.append({"course_code":final_registered_course.course_id.code,"course_name":final_registered_course.course_id.name,"course_credit":final_registered_course.course_id.credit}) + # add_courses_options = get_add_course_options(current_sem_branch_course, currently_registered_course, batch.year) + # drop_courses_options = get_drop_course_options(currently_registered_course) + # replace_courses_options = get_replace_course_options(currently_registered_course, batch.year) + except Exception as e: + final_registered_courses = None + final_registered_course_show = None + # drop_courses_options = None + add_courses_options = None + replace_courses_options = None - pre_registered_courses_data = serializers.InitialRegistrationsSerializer(pre_registered_courses, many=True).data - pre_registered_courses_show_data = serializers.InitialRegistrationsSerializer(pre_registered_courses_show, many=True).data + # pre_registered_courses_data = serializers.InitialRegistrationsSerializer(pre_registered_courses, many=True).data + # pre_registered_courses_show_data = serializers.InitialRegistrationsSerializer(pre_registered_courses_show, many=True).data final_registered_courses_data = serializers.FinalRegistrationsSerializer(final_registered_courses, many=True).data current_credits = get_current_credits(currently_registered_courses) - - next_sem_branch_courses = get_branch_courses(current_user, user_sem+1, user_branch) + print(current_user, user_sem+1, user_branch) + try: + next_sem_branch_courses = get_branch_courses(current_user, user_sem+1, user_branch) + except Exception as e: + return Response(data = str(e)) next_sem_branch_courses_data = serializers.CurriculumSerializer(next_sem_branch_courses, many=True).data fee_payment_mode_list = dict(Constants.PaymentMode) @@ -173,7 +188,8 @@ def academic_procedures_student(request): next_sem_branch_registration_courses_data = [] for choices in next_sem_branch_registration_courses: next_sem_branch_registration_courses_data.append(serializers.CurriculumSerializer(choices, many=True).data) - # next_sem_branch_registration_courses_data = serializers.CurriculumSerializer(next_sem_branch_registration_courses, many=True).data + # print(next_sem_branch_registration_courses_data) + # next_sem_branch_registration_courses_data = serializers.CurriculumSerializer(next_sem_branch_registration_courses_data, many=True).data final_registration_choices = get_registration_courses(get_branch_courses(request.user, user_sem, user_branch)) final_registration_choices_data = [] @@ -196,11 +212,47 @@ def academic_procedures_student(request): current_sem_branch_courses = get_branch_courses(current_user, user_sem, user_branch) - pre_registration_date_flag = get_pre_registration_eligibility(current_date) + pre_registration_date_flag = get_pre_registration_eligibility(current_date , user_sem , acad_year) final_registration_date_flag = get_final_registration_eligibility(current_date) add_or_drop_course_date_flag = get_add_or_drop_course_date_eligibility(current_date) + curr_id = batch.curriculum + curr_sem_id = Semester.objects.get(curriculum = curr_id, semester_no = obj.curr_semester_no) + + try: + semester_no = obj.curr_semester_no+1 + next_sem_id = Semester.objects.get(curriculum = curr_id, semester_no = semester_no) + user_sem = semester_no + + except Exception as e: + user_sem = get_user_semester(request.user, ug_flag, masters_flag, phd_flag) + next_sem_id = curr_sem_id + + student_registration_check_pre = get_student_registrtion_check(obj,next_sem_id) + student_registration_check_final = get_student_registrtion_check(obj,next_sem_id) + + cpi = get_cpi(user_details.id) + + next_sem_registration_courses = get_sem_courses(next_sem_id, batch) + print(next_sem_registration_courses) + + next_sem_courses = [] + + for course_slot in next_sem_registration_courses: + courses = course_slot.courses.all() + courselist = [] + for course in courses: + courselist.append({'course_id': course.id, 'name': course.name, 'credit': course.credit, 'course_code': course.code}); + next_sem_courses.append({'slot_id': course_slot.id,'slot_name':course_slot.name, 'slot_type': course_slot.type, 'semester': course_slot.semester.semester_no, 'slot_info': course_slot.course_slot_info, 'courses': courselist }) + + print(next_sem_courses) + + print(current_date, user_sem, year) + pre_registration_date_flag, prd_start_date= get_pre_registration_eligibility(current_date, user_sem, year) + final_registration_date_flag = get_final_registration_eligibility(current_date) + add_or_drop_course_date_flag = get_add_or_drop_course_date_eligibility(current_date) + student_registration_check_pre = obj.studentregistrationcheck_set.all().filter(semester=user_sem+1) student_registration_check_final = obj.studentregistrationcheck_set.all().filter(semester=user_sem) pre_registration_flag = False @@ -215,18 +267,6 @@ def academic_procedures_student(request): teaching_credit_registration_course = Curriculum.objects.all().filter(batch = 2016, sem =6) teaching_credit_registration_course_data = serializers.CurriculumSerializer(teaching_credit_registration_course, many=True).data - if student_flag: - try: - due = obj.dues_set.get() - lib_d = due.library_due - pc_d = due.placement_cell_due - hos_d = due.hostel_due - mess_d = due.mess_due - acad_d = due.academic_due - except: - lib_d, pc_d, hos_d, mess_d, acad_d = 0, 0, 0, 0, 0 - - tot_d = lib_d + acad_d + pc_d + hos_d + mess_d registers = obj.register_set.all() course_list = [] @@ -254,28 +294,36 @@ def academic_procedures_student(request): if user_sem == 2: branchchange_flag=True - # faculty_list = serializers.HoldsDesignationSerializer(get_faculty_list(), many=True).data + faculty_list = serializers.HoldsDesignationSerializer(get_faculty_list(), many=True).data resp = { 'details': details, 'currently_registered': currently_registered_courses_data, - 'pre_registered_courses' : pre_registered_courses_data, - 'pre_registered_courses_show' : pre_registered_courses_show_data, - 'final_registered_courses' : final_registered_courses_data, + 'pre_registered_courses' : pre_registered_courses, + 'pre_registered_courses_show' : pre_registered_course_show, + 'final_registered_course' : final_registered_courses, + 'final_registered_course_show' : final_registered_course_show, 'current_credits' : current_credits, 'courses_list': next_sem_branch_courses_data, 'fee_payment_mode_list' : fee_payment_mode_list, + 'next_sem_registration_courses': next_sem_courses, 'next_sem_branch_registration_courses' : next_sem_branch_registration_courses_data, 'final_registration_choices' : final_registration_choices_data, - 'performance_list' : performance_list_data, - 'thesis_request_list' : thesis_request_list, + 'final_registration_flag': final_registration_flag, + + 'student_flag' : student_flag, 'ug_flag' : ug_flag, 'masters_flag' : masters_flag, 'phd_flag' : phd_flag, 'fac_flag' : fac_flag, 'des_flag' : des_flag, - 'thesis_flag' : pre_existing_thesis_flag, + + 'prd': pre_registration_date_flag, + 'prd_start_date': prd_start_date, + 'frd': final_registration_date_flag, + 'adc_date_flag': add_or_drop_course_date_flag, + 'drop_courses_options' : currently_registered_courses_data, 'pre_registration_date_flag': pre_registration_date_flag, 'final_registration_date_flag': final_registration_date_flag, @@ -283,116 +331,1072 @@ def academic_procedures_student(request): 'pre_registration_flag' : pre_registration_flag, 'final_registration_flag': final_registration_flag, 'teaching_credit_registration_course' : teaching_credit_registration_course_data, - 'lib_d':lib_d, - 'acad_d':acad_d, - 'mess_d':mess_d, - 'pc_d':pc_d, - 'hos_d':hos_d, - 'tot_d':tot_d, + 'attendance': attendance_data, 'Branch_Change_Flag':branchchange_flag - # 'faculty_list' : faculty_list } - return Response(data=resp, status=status.HTTP_200_OK) + return Response(data=resp, status=status.HTTP_200_OK) + +@api_view(['GET']) +def get_all_courses(request): + try: + obj = Course.objects.all() + serializer = serializers.CourseSerializer(obj, many=True).data + return Response(serializer, status=status.HTTP_200_OK) + except Exception as e: + return Response(data = str(e) , status=status.HTTP_500_INTERNAL_SERVER_ERROR) @api_view(['POST']) -def add_thesis(request): - current_user = request.user - profile = current_user.extrainfo - if profile.user_type == 'student': - if not 'thesis_topic' in request.data: - return Response({'error':'Thesis topic is required'}, status=status.HTTP_400_BAD_REQUEST) - if not 'research_area' in request.data: - return Response({'error':'Research area is required'}, status=status.HTTP_400_BAD_REQUEST) - if 'supervisor_id' in request.data: - try: - supervisor_faculty = User.objects.get(username=request.data['supervisor_id']) - supervisor_faculty = supervisor_faculty.extrainfo - request.data['supervisor_id'] = supervisor_faculty - except: - return Response({'error':'Wrong supervisor id. User does not exist.'}, status=status.HTTP_400_BAD_REQUEST) - else: - return Response({'error':'supervisor id is required'}, status=status.HTTP_400_BAD_REQUEST) - if 'co_supervisor_id' in request.data: +def gen_roll_list(request): + try: + batch = request.data['batch'] + course_id = request.data['course'] + course = Courses.objects.get(id = course_id) + #obj = course_registration.objects.all().filter(course_id = course) + obj=course_registration.objects.filter(course_id__id=course_id, student_id__batch=batch).select_related( + 'student_id__id__user','student_id__id__department').only('student_id__batch', + 'student_id__id__user__first_name', 'student_id__id__user__last_name', + 'student_id__id__department__name','student_id__id__user__username') + except Exception as e: + batch="" + course="" + obj="" + students = [] + for i in obj: + students.append({"rollno":i.student_id.id.user.username, + "name":i.student_id.id.user.first_name+" "+i.student_id.id.user.last_name, + "department":i.student_id.id.department.name}) + # {'students': students, 'batch':batch, 'course':course_id} + return JsonResponse({'students': students, 'batch':batch, 'course':course_id}, status=200) + + +# api for student for adding courses +@api_view(['POST']) +def add_course(request): + try: + current_user = request.user + current_user = ExtraInfo.objects.all().filter(user=current_user).first() + current_user = Student.objects.all().filter(id=current_user.id).first() + + sem_id_instance = Semester.objects.get(id = request.data['semester']) + + count = request.data['ct'] + count = int(count) + reg_curr = [] + + for i in range(1, count+1): + choice = "choice["+str(i)+"]" + slot = "slot["+str(i)+"]" try: - co_supervisor_faculty = User.objects.get(username=request.data['co_supervisor_id']) - co_supervisor_faculty = co_supervisor_faculty.extrainfo - request.data['co_supervisor_id'] = co_supervisor_faculty - except: - return Response({'error':'Wrong co_supervisor id. User does not exist.'}, status=status.HTTP_400_BAD_REQUEST) - else: - co_supervisor_faculty = None - if 'curr_id' in request.data: - curr_id = None - student = profile.student - request.data['student_id'] = profile - request.data['submission_by_student'] = True - serializer = serializers.ThesisTopicProcessSerializer(data=request.data) - if serializer.is_valid(): - serializer.save() - return Response(serializer.data, status=status.HTTP_200_OK) - else: - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - else: - return Response({'error':'Cannot add thesis'}, status=status.HTTP_400_BAD_REQUEST) + course_id_instance = Courses.objects.get(id = request.data[choice]) + courseslot_id_instance = CourseSlot.objects.get(id = request.data[slot]) + + print(courseslot_id_instance.max_registration_limit) + if course_registration.objects.filter(working_year = current_user.batch_id.year, course_id = course_id_instance).count() < courseslot_id_instance.max_registration_limit and (course_registration.objects.filter(course_id=course_id_instance, student_id=current_user).count() == 0): + p = course_registration( + course_id=course_id_instance, + student_id=current_user, + course_slot_id=courseslot_id_instance, + semester_id=sem_id_instance + ) + print(serializers.course_registration(p)) + if p not in reg_curr: + reg_curr.append(p) + else: + print("already exist") + except Exception as e: + error_message = str(e) + resp = {'message': 'Course addition failed', 'error': error_message} + return Response(resp, status=status.HTTP_400_BAD_REQUEST) + print(reg_curr) + course_registration_data = course_registration.objects.bulk_create(reg_curr) + course_registration_data = serializers.CourseRegistrationSerializer(course_registration_data , many = True).data + res = {'message' : 'Courses successfully added' , "courses_added" : course_registration_data } + return Response(data = res , status = status.HTTP_200_OK) + except Exception as e: + return Response(data = str(e) , status= status.HTTP_500_INTERNAL_SERVER_ERROR) -@api_view(['PUT']) -def approve_thesis(request, id): + +@api_view(['POST']) +def drop_course(request): current_user = request.user - profile = current_user.extrainfo - if profile.user_type == 'faculty': + current_user = ExtraInfo.objects.all().filter(user=current_user).first() + current_user = Student.objects.all().filter(id = current_user.id).first() + + courses = request.data['courses'] + + for course in courses: try: - thesis = ThesisTopicProcess.objects.get(id=id) - except: - return Response({'error':'This thesis does not exist'}, status=status.HTTP_400_BAD_REQUEST) - if 'member1' in request.data: - try: - user1 = User.objects.get(username=request.data['member1']) - member1 = user1.extrainfo - request.data['member1'] = member1 - except: - return Response({'error':'Wrong username of member 1. User does not exist.'}, status=status.HTTP_400_BAD_REQUEST) - else: - return Response({'error':'Member 1 is required'}, status=status.HTTP_400_BAD_REQUEST) - if 'member2' in request.data: - try: - user2 = User.objects.get(username=request.data['member2']) - member2 = user2.extrainfo - request.data['member2'] = member2 - except: - return Response({'error':'Wrong username of member 2. User does not exist.'}, status=status.HTTP_400_BAD_REQUEST) - else: - return Response({'error':'Member 2 is required'}, status=status.HTTP_400_BAD_REQUEST) - if 'member3' in request.data: - try: - user3 = User.objects.get(username=request.data['member3']) - member3 = user3.extrainfo - request.data['member3'] = member3 - except: - return Response({'error':'Wrong username of member 3. User does not exist.'}, status=status.HTTP_400_BAD_REQUEST) - else: - member3 = None - if not 'approval' in request.data: - return Response({'error':'Approval value is required.'}, status=status.HTTP_400_BAD_REQUEST) - elif request.data['approval'] != 'yes' and request.data['approval'] != 'no': - return Response({'error':'Wrong approval value provided. Approval value should be yes or no'}, status=status.HTTP_400_BAD_REQUEST) - if request.data['approval'] == 'yes': - request.data.pop('approval', None) - request.data['pending_supervisor'] = False - request.data['approval_supervisor'] = True - request.data['forwarded_to_hod'] = True - request.data['pending_hod'] = True + course_id = Courses.objects.all().filter(id=course).first() + course_registration.objects.filter(course_id = course_id, student_id = current_user).delete() + except Exception as e: + resp = {"message" : "Course drop failed", "error" : str(e)} + return Response(data = resp, status = status.HTTP_400_BAD_REQUEST) + + resp = {"message" : "Course successfully dropped"} + return Response(data = resp , status = status.HTTP_200_OK) + + +# simple api for getting to know the details of user who have logined in the system +@api_view(['GET']) +def get_user_info(request): + current_user = request.user + details1 = serializers.UserSerializer(current_user).data + details2 = serializers.ExtraInfoSerializer(current_user.extrainfo).data + details = { + "user_serializer_Data" : details1, + "ExtraInfoSerializer_Data" : details2 + } + return Response(data = details , status= status.HTTP_200_OK) + + +# with this api student can see the list of courses offered to him in upcoming semester +@api_view(['POST']) +def view_offered_courses(request): + try : + obj = Curriculum.objects.filter( + programme = request.data['programme'], + branch = request.data['branch'], + batch = request.data["batch"], + sem = request.data["semester"] + ) + serializer = serializers.CurriculumSerializer(obj, many=True).data + return Response(serializer, status=status.HTTP_200_OK) + except Exception as e: + return Response(data = str(e) , status=status.HTTP_500_INTERNAL_SERVER_ERROR) + # try: + # ug_flag = True + # masters_flag = False + # phd_flag = False + # current_semester = get_user_semester(request.user, ug_flag, masters_flag, phd_flag) + # current_year = date_time.date().year + + # return Response(data= { } , status=status.HTTP_200_OK) + # except Exception as e: + # return Response(data = {"error" : str(e)} , status= status.HTTP_500_INTERNAL_SERVER_ERROR) + + +# with this student can know status of pre registration and final registration +@api_view(['GET']) +def student_view_registration(request): + try: + # getting the registration status of current user for the given semester + current_user = request.user + student_id = current_user.extrainfo.id + + sem_id = Semester.objects.get(id = request.data.get('semester')) + sem_id = serializers.SemesterSerializer(sem_id).data["id"] + + # filter based on the semester id and student id + obj = StudentRegistrationChecks.objects.filter(semester_id_id = sem_id, student_id = student_id) + + # serialize the data for displaying + serializer = serializers.StudentRegistrationChecksSerializer(obj, many=True).data + + return Response(serializer, status=status.HTTP_200_OK) + except Exception as e: + return Response(data = str(e) , status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + +# with this student can do his pre registration for the upcoming semester +@api_view(['POST']) +@transaction.atomic +def student_pre_registration(request): + try: + current_user = request.user + current_user_id = serializers.UserSerializer(current_user).data["id"] + s_id = current_user.extrainfo.id + + current_user = ExtraInfo.objects.all().select_related('user','department').filter(user=current_user_id).first() + current_user = serializers.ExtraInfoSerializer(current_user).data + + current_user_instance = Student.objects.all().filter(id=current_user["id"]).first() + current_user = serializers.StudentSerializers(current_user_instance).data + + sem_id_instance = Semester.objects.get(id = request.data.get('semester')) + sem_id = serializers.SemesterSerializer(sem_id_instance).data["id"] + + # filter based on the semester id and student id + obj = StudentRegistrationChecks.objects.filter(semester_id_id = sem_id, student_id = s_id) + # serialize the data for displaying + student_registration_check = serializers.StudentRegistrationChecksSerializer(obj, many=True).data + + try: + # check if user have already done pre registration + if(student_registration_check and student_registration_check[0]["pre_registration_flag"] ): + return Response(data = {"message" : "You have already registered for this semester" }, status=status.HTTP_400_BAD_REQUEST) + except Exception as e: + return Response(data = str(e) , status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + course_slots=request.data.get("course_slot") + reg_curr = [] + + + for course_slot in course_slots : + course_priorities = request.data.get("course_priority-"+course_slot) + if(course_priorities[0] == 'NULL'): + print("NULL FOUND") + continue + course_slot_id_for_model = CourseSlot.objects.get(id = int(course_slot)) + + # return Response(data = course_slots , status=status.HTTP_200_OK) + for course_priority in course_priorities: + priority_of_current_course,course_id = map(int,course_priority.split("-")) + # get course id for the model + course_id_for_model = Courses.objects.get(id = course_id) + print("check") + p = InitialRegistration( + course_id = course_id_for_model, + semester_id = sem_id_instance, + student_id = current_user_instance, + course_slot_id = course_slot_id_for_model, + priority = priority_of_current_course + ) + p.save() + reg_curr.append(p) + + + try: + serialized_reg_curr = serializers.InitialRegistrationSerializer(reg_curr, many=True).data + + registration_check = StudentRegistrationChecks( + student_id = current_user_instance, + pre_registration_flag = True, + final_registration_flag = False, + semester_id = sem_id_instance + ) + registration_check.save() + return Response(data={"message": "Successfully Registered for the courses.", "registrations": serialized_reg_curr}, status=status.HTTP_200_OK) + except Exception as e: + return Response(data = {"message" : "Error in Registration." , "error" : str(e)} , status=status.HTTP_500_INTERNAL_SERVER_ERROR) + except Exception as e: + return Response(data = {"message" : "Error in Registration." , "error" : str(e)} , status=status.HTTP_500_INTERNAL_SERVER_ERROR) + +@api_view(['POST']) +def final_registration(request): + try: + print(request.data) + current_user = get_object_or_404(User, username=request.data.get('user')) + current_user = ExtraInfo.objects.all().select_related('user','department').filter(user=current_user).first() + current_user = Student.objects.all().filter(id=current_user.id).first() + + sem_id = Semester.objects.get(id = request.data.get('semester')) + + mode = str(request.data.get('mode')) + transaction_id = str(request.data.get('transaction_id')) + deposit_date = request.data.get('deposit_date') + utr_number = str(request.data.get('utr_number')) + fee_paid = request.data.get('fee_paid') + actual_fee = request.data.get('actual_fee') + reason = str(request.data.get('reason')) + if reason=="": + reason=None + # fee_receipt = request.FILES['fee_receipt'] + + obj = FeePayments( + student_id = current_user, + semester_id = sem_id, + mode = mode, + transaction_id = transaction_id, + # fee_receipt = fee_receipt, + deposit_date = deposit_date, + utr_number = utr_number, + fee_paid = fee_paid, + actual_fee = actual_fee, + reason = reason + ) + obj.save() + + try: + semester = Semester.objects.get(id = request.data.get('semester')) + student = StudentRegistrationChecks.objects.filter(student_id = current_user, semester_id = semester).update(final_registration_flag = True) + return JsonResponse({'message': 'Final Registration Successfull'}) + except Exception as e: + return JsonResponse({'message': 'Final Registration Failed '}, status=500) + + except Exception as e: + return JsonResponse({'message': 'Final Registration Failed '}, status=500) + + +# with this student can do his final registration for the upcoming semester +@api_view(['POST']) +@transaction.atomic +def student_final_registration(request): + try: + current_user = request.user + current_user_id = serializers.UserSerializer(current_user).data["id"] + s_id = current_user.extrainfo.id + + current_user = ExtraInfo.objects.all().select_related('user','department').filter(user=current_user).first() + current_user = serializers.ExtraInfoSerializer(current_user).data + + current_user_instance = Student.objects.all().filter(id=current_user["id"]).first() + current_user = serializers.StudentSerializers(current_user_instance).data + + # these details we need from the body of the request fot doing final registration + sem_id_instance = Semester.objects.get(id = request.data.get('semester')) + sem_id = serializers.SemesterSerializer(sem_id_instance).data["id"] + registration_status = StudentRegistrationChecks.objects.filter(student_id = current_user["id"], semester_id = sem_id) + registration_status = serializers.StudentRegistrationChecksSerializer(registration_status , many = True ).data + + if(len(registration_status)>0 and registration_status[0]["pre_registration_flag"] == False): + return Response(data = {"message" : "Student haven't done pre registration yet."} , status= status.HTTP_400_BAD_REQUEST ) + mode = str(request.data.get('mode')) + transaction_id = str(request.data.get('transaction_id')) + deposit_date = request.data.get('deposit_date') + utr_number = str(request.data.get('utr_number')) + fee_paid = request.data.get('fee_paid') + actual_fee = request.data.get('actual_fee') + reason = str(request.data.get('reason')) + if reason=="": + reason=None + # fee_receipt = request.FILES['fee_receipt'] + + # print(fee_receipt) + obj = FeePayments( + student_id = current_user_instance, + semester_id = sem_id_instance, + mode = mode, + transaction_id = transaction_id, + # fee_receipt = fee_receipt, + deposit_date = deposit_date, + utr_number = utr_number, + fee_paid = fee_paid, + actual_fee = actual_fee, + reason = reason + ) + obj.save() + try: + registration_status = StudentRegistrationChecks.objects.filter(student_id = current_user["id"], semester_id = sem_id).update(final_registration_flag = True) + return Response(data = {"message" : "Final Registration Successfull" } , status= status.HTTP_200_OK) + except Exception as e: + return Response(data = {"message" : "Final Registration Failed " , "error" : str(e)} , status = status.HTTP_500_INTERNAL_SERVER_ERROR) + except Exception as e: + return Response(data = {"message" : "Final Registration Failed " , "error" : str(e)} , status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + +# with this api student can get his backlog courses list +@api_view(['GET']) +def student_backlog_courses(request): + try : + stu_id = Student.objects.select_related('id','id__user','id__department').get(id=request.user.username) + backlogCourseList = [] + backlogCourses = backlog_course.objects.select_related('course_id' , 'student_id' , 'semester_id' ).filter(student_id=stu_id) + for i in backlogCourses: + obj = { + "course_id" : i.course_id.id, + "course_name" : i.course_id.course_name, + "faculty" : i.course_id.course_details, + "semester" : i.semester_id.semester_no, + "is_summer_course" : i.is_summer_course + } + backlogCourseList.append(obj) + + return Response(backlogCourseList, status=status.HTTP_200_OK) + except Exception as e: + return Response(data = str(e) , status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + + +#--------------------------------------- APIs of acad person---------------------------------------------------------- + + +# with this acad admin can fetch the list of courses for any batch , semester and brach +@api_view(['POST']) +def get_course_list(request): + + programme = request.data['programme'] + branch = request.data['branch'] + batch = request.data['batch'] + + try : + print(programme , branch , batch) + obj = Curriculum.objects.filter( + programme = request.data['programme'], + branch = request.data['branch'], + batch = request.data["batch"] + ) + serializer = serializers.CurriculumSerializer(obj, many=True).data + return Response(serializer, status=status.HTTP_200_OK) + except Exception as e: + return Response(data = str(e) , status=status.HTTP_500_INTERNAL_SERVER_ERROR) + # obj = Curriculum.objects.filter(curriculum_id_=curriculum_id, course_type_ = course_type, programme_ = programme, batch_ = batch, branch_ = branch, sem_ = sem, optional_ = optional) + + +# with this api acad person can see the list of students who have completed their pre and final registrations for any semester +@api_view(['GET']) +def acad_view_reigstrations(request): + try: + semester = request.data["semester"] + sem_id_instance = Semester.objects.get(id = request.data.get('semester')) + sem_id = serializers.SemesterSerializer(sem_id_instance).data["id"] + obj = StudentRegistrationChecks.objects.filter(semester_id_id = sem_id, final_registration_flag =True) + student_registration_check = serializers.StudentRegistrationChecksSerializer(obj, many=True).data + + return Response(data= student_registration_check , status=status.HTTP_200_OK) + except Exception as e: + return Response(data = {"error" : str(e)} , status= status.HTTP_500_INTERNAL_SERVER_ERROR) + + +# with this api acad person set the date of pre registration date for any semester +@api_view(['POST']) +def configure_pre_registration_date(request): + try: + try: + from_date = request.data.get('from_date') + to_date = request.data.get('to_date') + semester = request.data.get('semester') + current_year = date_time.date().year + desc = "Pre Registration " + str(semester) +" " + str(current_year) + print(from_date , to_date , desc) + from_date = from_date.split('-') + from_date = [int(i) for i in from_date] + from_date = datetime.datetime(*from_date).date() + to_date = to_date.split('-') + to_date = [int(i) for i in to_date] + to_date = datetime.datetime(*to_date).date() + except Exception as e: + from_date="" + to_date="" + desc="" + pass + c = Calendar( + from_date=from_date, + to_date=to_date, + description=desc) + c.save() + return Response(data = {"message" : "Pre registration for semester " + str(semester) + " will be opened from " + str(from_date) + " to " + str(to_date) + ". " , } , status= status.HTTP_200_OK) + except Exception as e: + return Response(data = {"error " : str(e)} , status= status.HTTP_500_INTERNAL_SERVER_ERROR) + + +# with this api request acad person can set the date of final registration +@api_view(['POST']) +def configure_final_registration_date(request): + try: + try: + from_date = request.data.get('from_date') + to_date = request.data.get('to_date') + semester = request.data.get('semester') + current_year = date_time.date().year + desc = "Physical Reporting at the Institute" + print(from_date , to_date , desc) + from_date = from_date.split('-') + from_date = [int(i) for i in from_date] + from_date = datetime.datetime(*from_date).date() + to_date = to_date.split('-') + to_date = [int(i) for i in to_date] + to_date = datetime.datetime(*to_date).date() + except Exception as e: + from_date="" + to_date="" + desc="" + pass + c = Calendar( + from_date=from_date, + to_date=to_date, + description=desc) + c.save() + return Response(data = {"message" : "Physical Reporting at the Institute will be opened from " + str(from_date) + " to " + str(to_date) + ". " , } , status= status.HTTP_200_OK) + except Exception as e: + return Response(data = {"error " : str(e)} , status= status.HTTP_500_INTERNAL_SERVER_ERROR) + +# with this api request acad person can add any courses in a specific slot +@api_view(['POST']) +def add_course_to_slot(request): + course_code = request.data.get('course_code') + course_slot_name = request.data.get('course_slot_name') + try: + course_slot = CourseSlot.objects.get(name=course_slot_name) + course = Courses.objects.get(code=course_code) + course_slot.courses.add(course) + + return JsonResponse({'message': f'Course {course_code} added to slot {course_slot_name} successfully.'}, status=200) + except CourseSlot.DoesNotExist: + return JsonResponse({'error': 'Course slot does not exist.'}, status=400) + except Course.DoesNotExist: + return JsonResponse({'error': 'Course does not exist.'}, status=400) + +# with this api request acad person can remove any course from a specific slot +@api_view(['POST']) +def remove_course_from_slot(request): + course_code = request.data.get('course_code') + course_slot_name = request.data.get('course_slot_name') + try: + course_slot = CourseSlot.objects.get(name=course_slot_name) + course = Courses.objects.get(code=course_code) + course_slot.courses.remove(course) + return JsonResponse({'message': f'Course {course_code} removed from slot {course_slot_name} successfully.'}, status=200) + except CourseSlot.DoesNotExist: + return JsonResponse({'error': 'Course slot does not exist.'}, status=400) + except Course.DoesNotExist: + return JsonResponse({'error': 'Course does not exist.'}, status=400) + + + +#--------------------------------------- APIs of faculty---------------------------------------------------------- + +# with this api faculty can know what are the courses assigned to him +@api_view(['GET']) +def faculty_assigned_courses(request): + try: + current_user = request.user + curriculum_ids = Curriculum_Instructor.objects.filter(instructor_id=current_user.id).values_list('curriculum_id', flat=True) + course_infos = [] + print(current_user.id) + for curriculum_id in curriculum_ids: + course_info = Curriculum.objects.filter(curriculum_id=curriculum_id).values_list('course_code','course_type','programme','branch','sem','course_id_id').first() + # course_infos.append(course_info) + context = { + "course_code": course_info[0], + "course_type": course_info[1], + "programme": course_info[2], + "branch": course_info[3], + "sem": course_info[4], + "course_id": course_info[5] + } + course_infos.append(context) + + return Response(data= course_infos , status=status.HTTP_200_OK) + except Exception as e: + return Response(data = {"error" : str(e)} , status= status.HTTP_500_INTERNAL_SERVER_ERROR) + + +@api_view(['POST']) +def get_next_sem_courses(request): + try: + next_sem = request.data.get('next_sem') + branch = request.data.get('branch') + programme = request.data.get('programme') + batch = request.data.get('batch') + + # we go to student table and apply filters and get batch_id of the students with these filter + batch_id = Student.objects.filter(programme = programme , batch = batch , specialization = branch)[0].batch_id + + curr_id = batch_id.curriculum + next_sem_id = Semester.objects.get(curriculum = curr_id, semester_no = next_sem) + + if next_sem_id: + next_sem_registration_courses = get_detailed_sem_courses(next_sem_id ) + return JsonResponse(next_sem_registration_courses, safe=False) + except Exception as e: + return Response(data = {"error" : str(e)} , status= status.HTTP_500_INTERNAL_SERVER_ERROR) + +@api_view(['POST']) +def add_one_course(request): + try: + print(request.data) + current_user = get_object_or_404(User, username=request.data.get('user')) + current_user = ExtraInfo.objects.all().filter(user=current_user).first() + current_user = Student.objects.all().filter(id=current_user.id).first() + + sem_id = Semester.objects.get(id=request.data.get('semester')) + choice = request.data.get('choice') + slot = request.data.get('slot') + + try: + course_id = Courses.objects.get(id=choice) + courseslot_id = CourseSlot.objects.get(id=slot) + print(courseslot_id.id) + print(courseslot_id.type) + print(courseslot_id.max_registration_limit) + if course_registration.objects.filter(course_slot_id_id=courseslot_id, student_id=current_user).count() == 1 and courseslot_id.type != "Swayam": + already_registered_course_id = course_registration.objects.filter(course_slot_id_id=courseslot_id, student_id=current_user)[0].course_id + print(already_registered_course_id) + msg = 'Already Registered in the course : ' +already_registered_course_id.code + '-'+ already_registered_course_id.name + return JsonResponse({'message' : msg}) + if((course_registration.objects.filter(course_id=course_id, student_id=current_user).count() >= 1)): + return JsonResponse({'message': 'Already registered in this course!'}, status=200) + # Check if maximum course registration limit has not been reached + if course_registration.objects.filter(student_id__batch_id__year=current_user.batch_id.year, course_id=course_id).count() < courseslot_id.max_registration_limit and \ + (course_registration.objects.filter(course_id=course_id, student_id=current_user).count() == 0): + p = course_registration( + + course_id=course_id, + student_id=current_user, + course_slot_id=courseslot_id, + semester_id=sem_id + ) + p.save() + return JsonResponse({'message': 'Course added successfully'}, status=200) + else: + return JsonResponse({'message': 'Course not added because seats are full!'}, status=404) + except Exception as e: + print(e) + return JsonResponse({'message': 'Error adding course'}, status=500) + except Exception as e: + return JsonResponse({'message': 'Error adding course'}, status=500) + + +@transaction.atomic +@api_view(['POST']) +def verify_registration(request): + if request.data.get('status_req') == "accept" : + student_id = request.data.get('student_id') + student = Student.objects.get(id = student_id) + batch = student.batch_id + curr_id = batch.curriculum + + if(student.curr_semester_no+1 >= 9): + # print('----------------------------------------------------------------' , student.curr_semester_no) + sem_no = 8 else: - request.data.pop('approval', None) - request.data['pending_supervisor'] = False - request.data['approval_supervisor'] = False - request.data['forwarded_to_hod'] = False - request.data['pending_hod'] = False - serializer = serializers.ThesisTopicProcessSerializer(thesis, data=request.data, partial=True) - if serializer.is_valid(): - serializer.save() - return Response(serializer.data, status=status.HTTP_200_OK) + # print('----------------------------------------------------------------' , student.curr_semester_no) + sem_no = student.curr_semester_no+1 + sem_id = Semester.objects.get(curriculum = curr_id, semester_no = sem_no) + # print('----------------------------------------------------------------' , student.curr_semester_no) + + final_register_list = FinalRegistration.objects.all().filter(student_id = student, verified = False, semester_id = sem_id) + + # final_register_list = FinalRegistration.objects.all().filter(student_id = student, verified = False) + + with transaction.atomic(): + for obj in final_register_list: + o = FinalRegistration.objects.filter(id= obj.id).update(verified = True) + academics_module_notif(request.user, student.id.user, 'registration_approved') + + Student.objects.filter(id = student_id).update(curr_semester_no = sem_no) + return JsonResponse({'status': 'success', 'message': 'Successfully Accepted'}) + + elif request.data.get('status_req') == "reject" : + reject_reason = request.data.get('reason') + student_id = request.data.get('student_id') + student_id = Student.objects.get(id = student_id) + batch = student_id.batch_id + curr_id = batch.curriculum + if(student_id.curr_semester_no+1 >= 9): + sem_no = 8 else: - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - else: - return Response({'error':'Cannot approve thesis'}, status=status.HTTP_400_BAD_REQUEST) + sem_no = student_id.curr_semester_no+1 + sem_id = Semester.objects.get(curriculum = curr_id, semester_no = sem_no) + with transaction.atomic(): + academicadmin = get_object_or_404(User, username = "acadadmin") + # FinalRegistration.objects.filter(student_id = student_id, verified = False, semester_id = sem_id).delete() + StudentRegistrationChecks.objects.filter(student_id = student_id, semester_id = sem_id).update(final_registration_flag = False) + FeePayments.objects.filter(student_id = student_id, semester_id = sem_id).delete() + academics_module_notif(academicadmin, student_id.id.user, 'Registration Declined - '+reject_reason) + return JsonResponse({'status': 'success', 'message': 'Successfully Rejected'}) + + return JsonResponse({'status': 'error', 'message': 'Error in processing'}) + + + + +# These apis were implemented before but now don't use them they have some errors + + +# @api_view(['GET']) +# def academic_procedures_faculty(request): +# current_user = request.user +# user_details = current_user.extrainfo +# des = current_user.holds_designations.all().first() + +# if str(des.designation) == 'student': +# return Response({'error':'Not a faculty'}, status=status.HTTP_400_BAD_REQUEST) +# elif str(current_user) == 'acadadmin': +# return Response({'error':'User is acadadmin'}, status=status.HTTP_400_BAD_REQUEST) + +# elif str(des.designation) == "Associate Professor" or str(des.designation) == "Professor" or str(des.designation) == "Assistant Professor": +# faculty_object = user_details.faculty +# month = int(date_time.month) +# sem = [] +# if month>=7 and month<=12: +# sem = [1,3,5,7] +# else: +# sem = [2,4,6,8] +# student_flag = False +# fac_flag = True + +# thesis_supervision_request_list = faculty_object.thesistopicprocess_supervisor.all() +# thesis_supervision_request_list_data = serializers.ThesisTopicProcessSerializer(thesis_supervision_request_list, many=True).data +# approved_thesis_request_list = serializers.ThesisTopicProcessSerializer(thesis_supervision_request_list.filter(approval_supervisor = True), many=True).data +# pending_thesis_request_list = serializers.ThesisTopicProcessSerializer(thesis_supervision_request_list.filter(pending_supervisor = True), many=True).data +# courses_list = serializers.CurriculumInstructorSerializer(user_details.curriculum_instructor_set.all(), many=True).data +# fac_details = serializers.UserSerializer(current_user).data + +# resp = { +# 'student_flag' : student_flag, +# 'fac_flag' : fac_flag, +# 'thesis_supervision_request_list' : thesis_supervision_request_list_data, +# 'pending_thesis_request_list' : pending_thesis_request_list, +# 'approved_thesis_request_list' : approved_thesis_request_list, +# 'courses_list': courses_list, +# 'faculty': fac_details +# } +# return Response(data=resp, status=status.HTTP_200_OK) + + + + + + +# @api_view(['GET']) +# def academic_procedures_student(request): +# current_user = request.user +# current_user_data = { +# 'first_name': current_user.first_name, +# 'last_name': current_user.last_name, +# 'username': current_user.username, +# 'email': current_user.email +# } +# user_details = current_user.extrainfo +# des = current_user.holds_designations.all().first() +# if str(des.designation) == 'student': +# obj = user_details.student + +# if obj.programme.upper() == "PH.D": +# student_flag = True +# ug_flag = False +# masters_flag = False +# phd_flag = True +# fac_flag = False +# des_flag = False + +# elif obj.programme.upper() == "M.DES": +# student_flag = True +# ug_flag = False +# masters_flag = True +# phd_flag = False +# fac_flag = False +# des_flag = True + +# elif obj.programme.upper() == "B.DES": +# student_flag = True +# ug_flag = True +# masters_flag = False +# phd_flag = False +# fac_flag = False +# des_flag = True + +# elif obj.programme.upper() == "M.TECH": +# student_flag = True +# ug_flag = False +# masters_flag = True +# phd_flag = False +# fac_flag = False +# des_flag = False + +# elif obj.programme.upper() == "B.TECH": +# student_flag = True +# ug_flag = True +# masters_flag = False +# phd_flag = False +# fac_flag = False +# des_flag = False + +# else: +# return Response({'message':'Student has no record'}, status=status.HTTP_400_BAD_REQUEST) + +# current_date = date_time.date() +# current_year = date_time.year +# batch = obj.batch_id +# user_sem = get_user_semester(request.user, ug_flag, masters_flag, phd_flag) +# acad_year = get_acad_year(user_sem, current_year) +# user_branch = user_details.department.name +# cpi = obj.cpi +# cur_spi='Sem results not available' # To be fetched from db if result uploaded + +# details = { +# 'current_user': current_user_data, +# 'year': acad_year, +# 'user_sem': user_sem, +# 'user_branch' : str(user_branch), +# 'cpi' : cpi, +# 'spi' : cur_spi +# } + +# currently_registered_courses = get_currently_registered_courses(user_details.id, user_sem) +# currently_registered_courses_data = serializers.CurriculumSerializer(currently_registered_courses, many=True).data +# try: +# pre_registered_courses = obj.initialregistrations_set.all().filter(semester = user_sem) +# pre_registered_courses_show = obj.initialregistrations_set.all().filter(semester = user_sem+1) +# except: +# pre_registered_courses = None +# pre_registered_courses_show=None +# try: +# final_registered_courses = obj.finalregistrations_set.all().filter(semester = user_sem) +# except: +# final_registered_courses = None + +# pre_registered_courses_data = serializers.InitialRegistrationsSerializer(pre_registered_courses, many=True).data +# pre_registered_courses_show_data = serializers.InitialRegistrationsSerializer(pre_registered_courses_show, many=True).data +# final_registered_courses_data = serializers.FinalRegistrationsSerializer(final_registered_courses, many=True).data + +# current_credits = get_current_credits(currently_registered_courses) +# print(current_user, user_sem+1, user_branch) +# try: +# next_sem_branch_courses = get_branch_courses(current_user, user_sem+1, user_branch) +# except Exception as e: +# return Response(data = str(e)) +# next_sem_branch_courses_data = serializers.CurriculumSerializer(next_sem_branch_courses, many=True).data + +# fee_payment_mode_list = dict(Constants.PaymentMode) + +# next_sem_branch_registration_courses = get_registration_courses(next_sem_branch_courses) +# next_sem_branch_registration_courses_data = [] +# for choices in next_sem_branch_registration_courses: +# next_sem_branch_registration_courses_data.append(serializers.CurriculumSerializer(choices, many=True).data) +# # next_sem_branch_registration_courses_data = serializers.CurriculumSerializer(next_sem_branch_registration_courses, many=True).data + +# final_registration_choices = get_registration_courses(get_branch_courses(request.user, user_sem, user_branch)) +# final_registration_choices_data = [] +# for choices in final_registration_choices: +# final_registration_choices_data.append(serializers.CurriculumSerializer(choices, many=True).data) + +# performance_list = [] +# result_announced = False +# for i in currently_registered_courses: +# try: +# performance_obj = obj.semestermarks_set.all().filter(curr_id = i).first() +# except: +# performance_obj = None +# performance_list.append(performance_obj) +# performance_list_data = serializers.SemesterMarksSerializer(performance_list, many=True).data + +# thesis_request_list = serializers.ThesisTopicProcessSerializer(obj.thesistopicprocess_set.all(), many=True).data + +# pre_existing_thesis_flag = True if obj.thesistopicprocess_set.all() else False + +# current_sem_branch_courses = get_branch_courses(current_user, user_sem, user_branch) + +# # pre_registration_date_flag = get_pre_registration_eligibility(current_date) +# final_registration_date_flag = get_final_registration_eligibility(current_date) + +# add_or_drop_course_date_flag = get_add_or_drop_course_date_eligibility(current_date) + +# student_registration_check_pre = obj.studentregistrationcheck_set.all().filter(semester=user_sem+1) +# student_registration_check_final = obj.studentregistrationcheck_set.all().filter(semester=user_sem) +# pre_registration_flag = False +# final_registration_flag = False +# if(student_registration_check_pre): +# pre_registration_flag = student_registration_check_pre.pre_registration_flag +# if(student_registration_check_final): +# final_registration_flag = student_registration_check_final.final_registration_flag + +# teaching_credit_registration_course = None +# if phd_flag: +# teaching_credit_registration_course = Curriculum.objects.all().filter(batch = 2016, sem =6) +# teaching_credit_registration_course_data = serializers.CurriculumSerializer(teaching_credit_registration_course, many=True).data + +# if student_flag: +# try: +# due = obj.dues_set.get() +# lib_d = due.library_due +# pc_d = due.placement_cell_due +# hos_d = due.hostel_due +# mess_d = due.mess_due +# acad_d = due.academic_due +# except: +# lib_d, pc_d, hos_d, mess_d, acad_d = 0, 0, 0, 0, 0 + +# tot_d = lib_d + acad_d + pc_d + hos_d + mess_d + +# registers = obj.register_set.all() +# course_list = [] +# for i in registers: +# course_list.append(i.curr_id) +# attendence = [] +# for i in course_list: +# instructors = i.curriculum_instructor_set.all() +# pr,ab=0,0 +# for j in list(instructors): + +# presents = obj.student_attendance_set.all().filter(instructor_id=j, present=True) +# absents = obj.student_attendance_set.all().filter(instructor_id=j, present=False) +# pr += len(presents) +# ab += len(absents) +# attendence.append((i,pr,pr+ab)) +# attendance_data = {} +# for course in attendence: +# attendance_data[course[0].course_id.course_name] = { +# 'present' : course[1], +# 'total' : course[2] +# } + +# branchchange_flag = False +# if user_sem == 2: +# branchchange_flag=True + +# faculty_list = serializers.HoldsDesignationSerializer(get_faculty_list(), many=True).data + +# resp = { +# 'details': details, +# 'currently_registered': currently_registered_courses_data, +# # 'pre_registered_courses' : pre_registered_courses_data, +# # 'pre_registered_courses_show' : pre_registered_courses_show_data, +# 'final_registered_courses' : final_registered_courses_data, +# 'current_credits' : current_credits, +# 'courses_list': next_sem_branch_courses_data, +# 'fee_payment_mode_list' : fee_payment_mode_list, +# 'next_sem_branch_registration_courses' : next_sem_branch_registration_courses_data, +# 'final_registration_choices' : final_registration_choices_data, +# 'performance_list' : performance_list_data, +# 'thesis_request_list' : thesis_request_list, +# 'student_flag' : student_flag, +# 'ug_flag' : ug_flag, +# 'masters_flag' : masters_flag, +# 'phd_flag' : phd_flag, +# 'fac_flag' : fac_flag, +# 'des_flag' : des_flag, +# 'thesis_flag' : pre_existing_thesis_flag, +# 'drop_courses_options' : currently_registered_courses_data, +# # 'pre_registration_date_flag': pre_registration_date_flag, +# 'final_registration_date_flag': final_registration_date_flag, +# 'add_or_drop_course_date_flag': add_or_drop_course_date_flag, +# # 'pre_registration_flag' : pre_registration_flag, +# 'final_registration_flag': final_registration_flag, +# 'teaching_credit_registration_course' : teaching_credit_registration_course_data, +# 'lib_d':lib_d, +# 'acad_d':acad_d, +# 'mess_d':mess_d, +# 'pc_d':pc_d, +# 'hos_d':hos_d, +# 'tot_d':tot_d, +# 'attendance': attendance_data, +# 'Branch_Change_Flag':branchchange_flag +# # 'faculty_list' : faculty_list +# } +# return Response(data=resp, status=status.HTTP_200_OK) + + + + + + + + + + + + + + + + + + + + + + +# These apis are not needed in this module + + + +# @api_view(['POST']) +# def add_thesis(request): +# current_user = request.user +# profile = current_user.extrainfo +# if profile.user_type == 'student': +# if not 'thesis_topic' in request.data: +# return Response({'error':'Thesis topic is required'}, status=status.HTTP_400_BAD_REQUEST) +# if not 'research_area' in request.data: +# return Response({'error':'Research area is required'}, status=status.HTTP_400_BAD_REQUEST) +# if 'supervisor_id' in request.data: +# try: +# supervisor_faculty = User.objects.get(username=request.data['supervisor_id']) +# supervisor_faculty = supervisor_faculty.extrainfo +# request.data['supervisor_id'] = supervisor_faculty +# except: +# return Response({'error':'Wrong supervisor id. User does not exist.'}, status=status.HTTP_400_BAD_REQUEST) +# else: +# return Response({'error':'supervisor id is required'}, status=status.HTTP_400_BAD_REQUEST) +# if 'co_supervisor_id' in request.data: +# try: +# co_supervisor_faculty = User.objects.get(username=request.data['co_supervisor_id']) +# co_supervisor_faculty = co_supervisor_faculty.extrainfo +# request.data['co_supervisor_id'] = co_supervisor_faculty +# except: +# return Response({'error':'Wrong co_supervisor id. User does not exist.'}, status=status.HTTP_400_BAD_REQUEST) +# else: +# co_supervisor_faculty = None +# if 'curr_id' in request.data: +# curr_id = None +# student = profile.student +# request.data['student_id'] = profile +# request.data['submission_by_student'] = True +# serializer = serializers.ThesisTopicProcessSerializer(data=request.data) +# if serializer.is_valid(): +# serializer.save() +# return Response(serializer.data, status=status.HTTP_200_OK) +# else: +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# else: +# return Response({'error':'Cannot add thesis'}, status=status.HTTP_400_BAD_REQUEST) + + + + + + + + + + + + + + + + + +# @api_view(['PUT']) +# def approve_thesis(request, id): +# current_user = request.user +# profile = current_user.extrainfo +# if profile.user_type == 'faculty': +# try: +# thesis = ThesisTopicProcess.objects.get(id=id) +# except: +# return Response({'error':'This thesis does not exist'}, status=status.HTTP_400_BAD_REQUEST) +# if 'member1' in request.data: +# try: +# user1 = User.objects.get(username=request.data['member1']) +# member1 = user1.extrainfo +# request.data['member1'] = member1 +# except: +# return Response({'error':'Wrong username of member 1. User does not exist.'}, status=status.HTTP_400_BAD_REQUEST) +# else: +# return Response({'error':'Member 1 is required'}, status=status.HTTP_400_BAD_REQUEST) +# if 'member2' in request.data: +# try: +# user2 = User.objects.get(username=request.data['member2']) +# member2 = user2.extrainfo +# request.data['member2'] = member2 +# except: +# return Response({'error':'Wrong username of member 2. User does not exist.'}, status=status.HTTP_400_BAD_REQUEST) +# else: +# return Response({'error':'Member 2 is required'}, status=status.HTTP_400_BAD_REQUEST) +# if 'member3' in request.data: +# try: +# user3 = User.objects.get(username=request.data['member3']) +# member3 = user3.extrainfo +# request.data['member3'] = member3 +# except: +# return Response({'error':'Wrong username of member 3. User does not exist.'}, status=status.HTTP_400_BAD_REQUEST) +# else: +# member3 = None +# if not 'approval' in request.data: +# return Response({'error':'Approval value is required.'}, status=status.HTTP_400_BAD_REQUEST) +# elif request.data['approval'] != 'yes' and request.data['approval'] != 'no': +# return Response({'error':'Wrong approval value provided. Approval value should be yes or no'}, status=status.HTTP_400_BAD_REQUEST) +# if request.data['approval'] == 'yes': +# request.data.pop('approval', None) +# request.data['pending_supervisor'] = False +# request.data['approval_supervisor'] = True +# request.data['forwarded_to_hod'] = True +# request.data['pending_hod'] = True +# else: +# request.data.pop('approval', None) +# request.data['pending_supervisor'] = False +# request.data['approval_supervisor'] = False +# request.data['forwarded_to_hod'] = False +# request.data['pending_hod'] = False +# serializer = serializers.ThesisTopicProcessSerializer(thesis, data=request.data, partial=True) +# if serializer.is_valid(): +# serializer.save() +# return Response(serializer.data, status=status.HTTP_200_OK) +# else: +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# else: +# return Response({'error':'Cannot approve thesis'}, status=status.HTTP_400_BAD_REQUEST) \ No newline at end of file diff --git a/FusionIIIT/applications/academic_procedures/models.py b/FusionIIIT/applications/academic_procedures/models.py index 37b339378..6a3d5dcc7 100644 --- a/FusionIIIT/applications/academic_procedures/models.py +++ b/FusionIIIT/applications/academic_procedures/models.py @@ -283,6 +283,9 @@ class SemesterMarks(models.Model): # curr_id = models.ForeignKey(Curriculum, on_delete=models.CASCADE) curr_id = models.ForeignKey(Courses, on_delete=models.CASCADE) #course_id = models.ForeignKey(Courses, on_delete=models.CASCADE, null=True) + + # def __str__(self): + # return self.student_id class Meta: db_table = 'SemesterMarks' @@ -565,8 +568,6 @@ class StudentRegistrationChecks(models.Model): final_registration_flag(boolean) - to denote whether the final registration is complete semester_id(programme_curriculum.Semester) - reference to the semester for which the registration will be considered - - ''' @@ -618,9 +619,6 @@ class FinalRegistration(models.Model): verified(Boolean) - denotes whether the registration is verified by academic department and complete course_slot_id(programme_curriculum.CourseSlot) - details about under which course slot the course is offered(Optional/Core other details) - - - ''' @@ -671,18 +669,14 @@ class course_registration(models.Model): ''' Current Purpose : stores information regarding the process of registration of a student for a course - ATTRIBUTES course_id(programme_curriculum.Course) - reference to the course details for which the registration is being done semester_id(programme_curriculum.Semester) - reference to the semester for which the course registration is done student_id(academic_information.Student) - reference to the student course_slot_id(programme_curriculum.CourseSlot) - details about under which course slot the course is offered(Optional/Core other details) - - - ''' - + student_id = models.ForeignKey(Student, on_delete=models.CASCADE) working_year=models.IntegerField(null=True,blank=True,choices=Year_Choices) @@ -691,6 +685,23 @@ class course_registration(models.Model): course_slot_id = models.ForeignKey(CourseSlot, null=True, blank=True, on_delete=models.SET_NULL) # grade = models.CharField(max_length=10) #course_registration_year = models.IntegerField() - + def __str__(self): + return self.semester_id class Meta: db_table = 'course_registration' + + +class backlog_course(models.Model): + ''' + Current Purpose : stores information regarding the backlog courses of a student (purpose is unclear and is open to interpretations) + + ATTRIBUTES + course_id(programme_curriculum.Course) - reference to the course details for which the registration is being done + semester_id(programme_curriculum.Semester) - reference to the semester for which the course registration is done + student_id(academic_information.Student) - reference to the student + is_summer_course(Boolean) - details about whether this course is available as summer_course or not + ''' + student_id = models.ForeignKey(Student, on_delete=models.CASCADE) + semester_id = models.ForeignKey(Semester, on_delete=models.CASCADE) + course_id = models.ForeignKey(Course, on_delete=models.CASCADE) + is_summer_course = models.BooleanField(default= False) \ No newline at end of file diff --git a/FusionIIIT/applications/academic_procedures/tests.py b/FusionIIIT/applications/academic_procedures/tests.py index e9137c85e..2c9e754ad 100644 --- a/FusionIIIT/applications/academic_procedures/tests.py +++ b/FusionIIIT/applications/academic_procedures/tests.py @@ -1,3 +1,4 @@ # from django.test import TestCase # Create your tests here. + diff --git a/FusionIIIT/applications/academic_procedures/urls.py b/FusionIIIT/applications/academic_procedures/urls.py index 45f892b49..e11bdcd7d 100644 --- a/FusionIIIT/applications/academic_procedures/urls.py +++ b/FusionIIIT/applications/academic_procedures/urls.py @@ -1,5 +1,4 @@ from django.conf.urls import url, include - from . import views appname = 'procedures' urlpatterns = [ @@ -7,19 +6,23 @@ url(r'^main/', views.academic_procedures, name='procedures'), url(r'^register/', views.register, name='register'), url(r'^pre_registration/', views.pre_registration, name='pre_register'), + url(r'^auto_pre_registration/', views.auto_pre_registration, name='automatic_pre_register'), + url(r'^final_registration/', views.final_registration, name='final_register'), url(r'^addCourse/', views.add_courses, name='addCourse'), + url(r'^add_one_course/' , views.add_one_course , name = 'add_one_course'), url(r'^drop_course/', views.drop_course, name='drop_course'), + url(r'^replaceCourse/', views.replace_courses, name='replace_courses'), + url(r'^replace_one_course/', views.replace_one_course, name='replace_one_course'), url(r'^branch-change/', views.approve_branch_change, name='branch_change'), url(r'^brach-change-request/', views.branch_change_request, name='branch_change_request'), + url(r'^acad_person/verifyCourse/drop/$',views.dropcourseadmin, name='dropcourseadmin'), url(r'^acad_person/verifyCourse/', views.verify_course, name='verifyCourse'), url(r'^acad_person/addCourse/', views.acad_add_course, name="acad_add_course"), url(r'^acad_person/student_list$', views.student_list, name='studentlist'), url(r'^acad_person/course_list$', views.course_list, name='courseList'), url(r'^acad_person/$', views.acad_person, name='acad_person'), - url(r'^acad_person/verifyCourse/drop/$', - views.dropcourseadmin, name='dropcourseadmin'), url(r'^branch-validate', views.approve_branch_change, name='branch_validate'), url(r'^acad_person/branch_change/$', views.acad_branch_change, name='acad_branch_change'), @@ -28,8 +31,9 @@ url(r'^account/$', views.account), url(r'^addThesis/$', views.add_thesis, name='add_thesis'), url(r'^process_verification_request/$', views.process_verification_request), + url(r'^auto_process_verification_request/$', views.auto_process_verification_request), url(r'^teaching_credit/$', views.teaching_credit_register), - url(r'^course_marks_data/$', views.course_marks_data), # -- + url(r'^course_marks_data/$', views.course_marks_data), # -- url(r'^submit_marks/$', views.submit_marks), # -- url(r'^verify_course_marks_data/$', views.verify_course_marks_data), # -- url(r'^verify_marks/$', views.verify_marks), @@ -41,7 +45,10 @@ url(r'^test/$', views.test), url(r'^bonafide_pdf/$', views.Bonafide_form), url(r'^test_ret/$', views.test_ret), + url(r'^api/', include('applications.academic_procedures.api.urls')), + + url(r'^faculty_data/$', views.facultyData, name='faculty_data'), url(r'^ACF/$', views.ACF, name='ACF'), url(r'^MTSGF/$', views.MTSGF), @@ -51,12 +58,19 @@ url(r'^update_phdform/$', views.update_phdform), url(r'^update_dues/$', views.update_dues), url(r'^dues_pdf/$', views.dues_pdf), - url(r'^acad_person/gen_course_list$', - views.gen_course_list, name='gen_course_list'), + url(r'^acad_person/gen_course_list$', views.gen_course_list, name='gen_course_list'), url(r'^update_acad_assistantship/$', views.update_acad_assis), url(r'^update_account_assistantship/$', views.update_account_assistantship), url(r'^update_hod_assistantship/$', views.update_hod_assistantship), url(r'^mdue/$', views.mdue), url(r'^assis_stat/$', views.assis_stat), - url(r'^acad_person/allot_courses/' , views.allot_courses, name='allot_courses') + url(r'^acad_person/allot_courses/' , views.allot_courses, name='allot_courses'), + + url(r'^acad_person/get_next_sem_courses/' , views.get_next_sem_courses , name = 'get_next_sem_courses'), + + url(r'^acad_person/remove_course_from_slot/' , views.remove_course_from_slot , name = 'remove_course_from_slot'), + url(r'^acad_person/add_course_to_slot/' , views.add_course_to_slot , name = 'add_course_to_slot'), + url(r'^acad_person/replaceSwayam/', views.replaceSwayam, name='replaceSwayam'), + url(r'^acad_person/swayam_replace/', views.swayam_replace, name='swayam_replace'), + url(r'^register_backlog_course/' , views.register_backlog_course , name = 'register_backlog_course') ] diff --git a/FusionIIIT/applications/academic_procedures/views.py b/FusionIIIT/applications/academic_procedures/views.py index 7e55e3e45..0d6314873 100644 --- a/FusionIIIT/applications/academic_procedures/views.py +++ b/FusionIIIT/applications/academic_procedures/views.py @@ -11,6 +11,7 @@ import logging from django.db import transaction from django.contrib import messages +from django.db.models import Q from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from django.db.models import Max,Value,IntegerField,CharField,F,Sum @@ -29,16 +30,21 @@ from applications.programme_curriculum.models import (CourseSlot, Course as Courses, Batch, Semester , CourseInstructor) from applications.globals.models import (DepartmentInfo, Designation, ExtraInfo, Faculty, HoldsDesignation) - +from applications.programme_curriculum.models import Course as Courses from .models import (BranchChange, CoursesMtech, InitialRegistration, StudentRegistrationChecks, Register, Thesis, FinalRegistration, ThesisTopicProcess, Constants, FeePayments, TeachingCreditRegistration, SemesterMarks, MarkSubmissionCheck, Dues,AssistantshipClaim, MTechGraduateSeminarReport, - PhDProgressExamination,CourseRequested, course_registration, MessDue, Assistantship_status) + PhDProgressExamination,CourseRequested, course_registration, MessDue, Assistantship_status , backlog_course) from notification.views import academics_module_notif from .forms import BranchChangeForm from django.db.models.functions import Concat,ExtractYear,ExtractMonth,ExtractDay,Cast +from .api import serializers +from django.core.serializers import serialize +import datetime +"""every newfuncitons that have been created with name auto_ in start of their original name is to implement new logic of registraion .. +unlike the previous registration logic that was done with priority """ demo_date = timezone.now() @@ -53,12 +59,7 @@ available_ece_seats = 100 available_me_seats = 100 -# assistantship_status = Assistantship_status.objects.all() -# for obj in assistantship_status: -# student_status = obj.student_status -# hod_status = obj.hod_status -# account_status = obj.account_status @login_required(login_url='/accounts/login') @@ -75,21 +76,21 @@ def main(request): def academic_procedures(request): current_user = get_object_or_404(User, username=request.user.username) - + #extra info details , user id used as main id user_details = ExtraInfo.objects.select_related('user','department').get(user = request.user) - des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() + # des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() - if str(des.designation) == "student": + if request.session.get('currentDesignationSelected') == "student": obj = Student.objects.select_related('id','id__user','id__department').get(id = user_details.id) return HttpResponseRedirect('/academic-procedures/stu/') # return HttpResponseRedirect('/logout/') - elif str(des.designation) == "Associate Professor" or str(des.designation) == "Professor" or str(des.designation) == "Assistant Professor" : + elif request.session.get('currentDesignationSelected') == "faculty" or request.session.get('currentDesignationSelected') == "Associate Professor" or request.session.get('currentDesignationSelected') == "Professor" or request.session.get('currentDesignationSelected') == "Assistant Professor" : return HttpResponseRedirect('/academic-procedures/fac/') # return HttpResponseRedirect('/logout/') - elif str(request.user) == "acadadmin" : + elif request.session.get('currentDesignationSelected') == "acadadmin" : return HttpResponseRedirect('/aims/') elif str(request.user) == "rizwan": @@ -106,7 +107,7 @@ def academic_procedures(request): }) else: - return HttpResponse('person not found') + return HttpResponseRedirect('/dashboard/') # # # @@ -117,19 +118,20 @@ def academic_procedures(request): def academic_procedures_faculty(request): current_user = get_object_or_404(User, username=request.user.username) - + if request.user.extrainfo.user_type != 'faculty': + return HttpResponseRedirect('/dashboard/') #extra info details , user id used as main id user_details = ExtraInfo.objects.select_related('user','department').get(user = request.user) des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() fac_id = user_details fac_name = user_details.user.first_name + " " + user_details.user.last_name - if str(des.designation) == "student": - return HttpResponseRedirect('/academic-procedures/main/') - - elif str(request.user) == "acadadmin": - return HttpResponseRedirect('/academic-procedures/main/') + # if str(des.designation) == "student": + # return HttpResponseRedirect('/academic-procedures/main/') - elif str(des.designation) == "Associate Professor" or str(des.designation) == "Professor" or str(des.designation) == "Assistant Professor": + # elif str(request.user) == "acadadmin": + # return HttpResponseRedirect('/academic-procedures/main/') + notifs = request.user.notifications.all() + if request.session.get('currentDesignationSelected') == "faculty" or str(des.designation) == "Associate Professor" or str(des.designation) == "Professor" or str(des.designation) == "Assistant Professor": object_faculty = Faculty.objects.select_related('id','id__user','id__department').get(id = user_details.pk) @@ -158,6 +160,15 @@ def academic_procedures_faculty(request): mtechseminar_request_list = MTechGraduateSeminarReport.objects.all().filter(Overall_grade = '') phdprogress_request_list = PhDProgressExamination.objects.all().filter(Overall_grade = '') courses_list = list(CourseInstructor.objects.select_related('course_id', 'batch_id', 'batch_id__discipline').filter(instructor_id__id=fac_id.id).only('course_id__code', 'course_id__name', 'batch_id')) + + assigned_courses = CourseInstructor.objects.select_related('course_id', 'batch_id', 'batch_id__discipline').filter( + instructor_id__id=fac_id.id, # Filter by faculty ID + batch_id__running_batch=True, # Filter by currently running batches + course_id__working_course=True # Filter by currently active courses + ).only('course_id__code', 'course_id__name', 'batch_id') + assigned_courses = list(assigned_courses) + + # print('------------------------------------------------------------------------------------------------------------------' , list(assigned_courses)) r = range(4) return render( request, @@ -181,6 +192,8 @@ def academic_procedures_faculty(request): 'mtechseminar_request_list' : mtechseminar_request_list, 'phdprogress_request_list' : phdprogress_request_list, 'r' : r, + 'assigned_courses' : assigned_courses, + 'notifications': notifs, }) else: HttpResponse("user not found") @@ -205,11 +218,13 @@ def account(request): def academic_procedures_student(request): current_user = get_object_or_404(User, username=request.user.username) - + # if global_var != "student": + # return HttpResponse("Student has no record") user_details = ExtraInfo.objects.select_related('user','department').get(id = request.user) des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() if str(des.designation) == "student": + notifs = request.user.notifications.all() obj = Student.objects.select_related('id','id__user','id__department').get(id = user_details.id) if obj.programme.upper() == "PHD" : @@ -341,17 +356,23 @@ def academic_procedures_student(request): currently_registered_course = get_currently_registered_course(obj,obj.curr_semester_no) current_credits = get_current_credits(currently_registered_course) - + cur_cpi=0.0 details = { 'current_user': current_user, 'year': acad_year, - 'user_sem': user_sem, + 'user_sem': user_sem - 1, 'user_branch' : str(user_branch), 'cpi' : cpi, } cur_cpi=details['cpi'] + swayam_courses_count = 0 + next_sem_student = user_sem + 1 + if(next_sem_student > 2): + swayam_courses_count = 2 + if(next_sem_student == 6 or next_sem_student == 7 or next_sem_student == 8): + swayam_courses_count = 3 try: pre_registered_courses = InitialRegistration.objects.all().filter(student_id = user_details.id,semester_id = next_sem_id) @@ -374,13 +395,14 @@ def academic_procedures_student(request): for final_registered_course in final_registered_courses: final_registered_course_show.append({"course_code":final_registered_course.course_id.code,"course_name":final_registered_course.course_id.name,"course_credit":final_registered_course.course_id.credit}) add_courses_options = get_add_course_options(current_sem_branch_course, currently_registered_course, batch.year) - #drop_courses_options = get_drop_course_options(currently_registered_course) - + drop_courses_options = get_drop_course_options(currently_registered_course) + replace_courses_options = get_replace_course_options(currently_registered_course, batch.year) except Exception as e: final_registered_courses = None final_registered_course_show = None - #drop_courses_options = None + drop_courses_options = None add_courses_options = None + replace_courses_options = None fee_payment_mode_list = dict(Constants.PaymentMode) @@ -455,10 +477,24 @@ def academic_procedures_student(request): attendence.append((i,pr,pr+ab)) cur_spi='Sem results not available' # To be fetched from db if result uploaded - - Mess_bill = Monthly_bill.objects.filter(student_id = obj) - Mess_pay = Payments.objects.filter(student_id = obj) + backlogCourseList = [] + auto_backlog_courses = list(SemesterMarks.objects.filter(student_id = obj , grade = 'F')) + auto_backlog_courses_list = [] + for i in auto_backlog_courses: + if not i.curr_id.courseslots.filter(type__contains="Optional").exists(): + auto_backlog_courses_list.append([i.curr_id.name, i.curr_id.code, i.curr_id.version, i.curr_id.credit , i.grade]) + backlogCourses = backlog_course.objects.select_related('course_id' , 'student_id' , 'semester_id' ).filter(student_id=obj) + for i in backlogCourses: + summer_course = "Yes" if i.is_summer_course else "No" + course_details = i.course_id.course_details if i.course_id.course_details else "N/A" + + backlogCourseList.append([i.course_id.course_name, course_details , i.semester_id.semester_no , summer_course]) + + # Mess_bill = Monthly_bill.objects.filter(student_id = obj) + # Mess_pay = Payments.objects.filter(student_id = obj) + Mess_bill = [] + Mess_pay = [] # Branch Change Form save if request.method=='POST': if True: @@ -470,7 +506,7 @@ def academic_procedures_student(request): return render( request, '../templates/academic_procedures/academic.html', {'details': details, - # 'calendar': calendar, + # 'calendar': calendar, 'currently_registered': currently_registered_course, 'pre_registered_course' : pre_registered_courses, 'pre_registered_course_show' : pre_registered_course_show, @@ -503,7 +539,8 @@ def academic_procedures_student(request): # 'change_branch': change_branch, # 'add_course': add_course, 'add_courses_options': add_courses_options, - #'drop_courses_options' : drop_courses_options, + 'drop_courses_options' : drop_courses_options, + 'replace_courses_options' : replace_courses_options, # 'pre_register': pre_register, 'pre_registration_timestamp': pre_registration_timestamp, 'prd': pre_registration_date_flag, @@ -512,6 +549,7 @@ def academic_procedures_student(request): 'adc_date_flag': add_or_drop_course_date_flag, 'pre_registration_flag' : pre_registration_flag, 'final_registration_flag': final_registration_flag, + 'swayam_courses_count':swayam_courses_count, # 'final_r': final_register_1, 'teaching_credit_registration_course' : teaching_credit_registration_course, @@ -527,16 +565,19 @@ def academic_procedures_student(request): 'hos_d':hos_d, 'tot_d':tot_d, 'attendence':attendence, + 'backlogCourseList' : backlogCourseList, + 'auto_backlog_courses_list' : auto_backlog_courses_list, 'BranchChangeForm': BranchChangeForm(), 'BranchFlag':branchchange_flag, 'assistantship_flag' : student_status, + 'notifications': notifs, } ) - elif str(des.designation) == "Associate Professor" : + elif request.session.get('currentDesignationSelected') == "Associate Professor" : return HttpResponseRedirect('/academic-procedures/main/') - elif str(request.user) == "acadadmin" : + elif request.session.get('currentDesignationSelected') == "acadadmin" : return HttpResponseRedirect('/academic-procedures/main/') else: @@ -852,12 +893,16 @@ def dropcourseadmin(request): ''' data = request.GET.get('id') data = data.split(" - ") + student_id = data[0] course_code = data[1] + course = Courses.objects.get(code=course_code , version = 1.0) # need to add batch and programme - curriculum_object = Curriculum.objects.all().filter(course_code = course_code) + # curriculum_object = Curriculum.objects.all().filter(course_code = course_code) try: - Register.objects.filter(curr_id = curriculum_object.first(),student_id=int(data[0])).delete() - except: + # Register.objects.filter(curr_id = curriculum_object.first(),student_id=int(data[0])).delete() + course_registration.objects.filter(student_id = student_id , course_id = course.id).delete() + except Exception as e: + print(str(e)) pass # print("hello ") response_data = {} @@ -914,14 +959,13 @@ def verify_course(request): current_user = get_object_or_404(User, username=request.user.username) user_details = ExtraInfo.objects.all().select_related( 'user', 'department').filter(user=current_user).first() - desig_id = Designation.objects.all().filter(name='adminstrator').first() + desig_id = Designation.objects.all().filter(name='acadadmin').first() temp = HoldsDesignation.objects.all().select_related().filter( designation=desig_id).first() acadadmin = temp.working k = str(user_details).split() final_user = k[2] - - if (str(acadadmin) != str(final_user)): + if ('acadadmin' != request.session.get('currentDesignationSelected')): return HttpResponseRedirect('/academic-procedures/') roll_no = request.POST["rollNo"] obj = ExtraInfo.objects.all().select_related( @@ -932,9 +976,12 @@ def verify_course(request): 'firstname': firstname, 'lastname': lastname} obj2 = Student.objects.all().select_related( 'id', 'id__user', 'id__department').filter(id=roll_no).first() - obj = Register.objects.all().select_related('curr_id', 'student_id', 'curr_id__course_id', - 'student_id__id', 'student_id__id__user', 'student_id__id__department').filter(student_id=obj2) - curr_sem_id = obj2.curr_semester_no + # obj = Register.objects.all().select_related('curr_id', 'student_id', 'curr_id__course_id', + # 'student_id__id', 'student_id__id__user', 'student_id__id__department').filter(student_id=obj2) + batch = obj2.batch_id + curr_id = batch.curriculum + curr_sem_id = Semester.objects.get(curriculum = curr_id, semester_no = obj2.curr_semester_no) + # curr_sem_id = obj2.curr_semester_no details = [] current_sem_courses = get_currently_registered_course( @@ -943,7 +990,10 @@ def verify_course(request): idd = obj2 for z in current_sem_courses: z = z[1] - course_code, course_name = str(z).split(" - ") + print(z) + course_code = z.code + course_name = z.name + # course_code, course_name = str(z).split(" - ") k = {} # reg_ig has course registration id appended with the the roll number # so that when we have removed the registration we can be redirected to this view @@ -955,7 +1005,7 @@ def verify_course(request): for p in courseobj2: k['course_id'] = course_code k['course_name'] = course_name - k['sem'] = curr_sem_id + k['sem'] = curr_sem_id.semester_no k['credits'] = p.credit details.append(k) @@ -971,6 +1021,9 @@ def verify_course(request): date = {'year': yearr, 'semflag': semflag} course_list = Courses.objects.all() semester_list = Semester.objects.all() + semester_no_list=[] + for i in semester_list: + semester_no_list.append(int(i.semester_no)) html = render_to_string('academic_procedures/studentCourses.html', {'details': details, 'dict2': dict2, @@ -996,7 +1049,7 @@ def acad_add_course(request): sem_id = request.POST['semester_id'] semester = Semester.objects.get(id=sem_id) cr = course_registration( - course_id=course, student_id=student, semester_id=semester) + course_id=course, student_id=student, semester_id=semester , working_year = datetime.datetime.now().year,) cr.save() return HttpResponseRedirect('/academic-procedures/') @@ -1034,7 +1087,7 @@ def acad_branch_change(request): k = str(user_details).split() final_user = k[2] - if (str(acadadmin) != str(final_user)): + if ('acadadmin' != request.session.get('currentDesignationSelected')): return HttpResponseRedirect('/academic-procedures/') # year = datetime.datetime.now().year @@ -1368,7 +1421,77 @@ def pre_registration(request): else: return HttpResponseRedirect('/academic-procedures/main') +@login_required(login_url='/accounts/login') +@transaction.atomic +def auto_pre_registration(request): + if request.method == 'POST': + try: + current_user = get_object_or_404(User, username=request.POST.get('user')) + current_user = ExtraInfo.objects.all().select_related('user','department').filter(user=current_user).first() + current_user = Student.objects.all().filter(id=current_user.id).first() + sem_id = Semester.objects.get(id = request.POST.get('semester')) + + course_slots=request.POST.getlist("course_slot") + try: + student_registeration_check=get_student_registrtion_check(current_user,sem_id) + if(student_registeration_check and student_registeration_check.pre_registration_flag==True): + messages.error(request,"You have already registered for next semester") + return HttpResponseRedirect('/academic-procedures/main') + except Exception as e: + print(e) + + reg_curr = [] + final_reg_curr = [] + existing_entries = set() + for course_slot in course_slots : + course_priorities = request.POST.getlist("course_priority-"+course_slot) + if(course_priorities[0] == 'NULL'): + continue + course_slot_id_for_model = CourseSlot.objects.get(id = int(course_slot)) + print("=----> course_priorities ----- ",course_priorities) + print("------------>course slot id ",course_slot_id_for_model) + for course_priority in course_priorities: + if(course_priority == 'NULL'): + continue + priority_of_current_course,course_id = map(int,course_priority.split("-")) + + course_id_for_model = Courses.objects.get(id = course_id) + current_combination = (course_slot_id_for_model.id, course_id_for_model.id) + if current_combination not in existing_entries: + p = InitialRegistration( + course_id = course_id_for_model, + semester_id = sem_id, + student_id = current_user, + course_slot_id = course_slot_id_for_model, + priority = priority_of_current_course + ) + f =FinalRegistration(student_id=current_user ,course_slot_id=course_slot_id_for_model , course_id=course_id_for_model ,semester_id=sem_id) + final_reg_curr.append(f) + reg_curr.append(p) + existing_entries.add(current_combination) + try: + InitialRegistration.objects.bulk_create(reg_curr) + FinalRegistration.objects.bulk_create(final_reg_curr) + registration_check = StudentRegistrationChecks( + student_id = current_user, + pre_registration_flag = True, + final_registration_flag = False, + semester_id = sem_id + ) + registration_check.save() + messages.info(request, 'Successfully Registered.') + messages.success(request, "Successfully Registered.") + return HttpResponseRedirect('/academic-procedures/stu') + except Exception as e: + messages.error(request, "Error in Registration.") + return HttpResponseRedirect('/academic-procedures/stu') + except Exception as e: + messages.error(request, "Error in Registration.") + return HttpResponseRedirect('/academic-procedures/main') + else: + return HttpResponseRedirect('/academic-procedures/main') + def get_student_registrtion_check(obj, sem): return StudentRegistrationChecks.objects.all().filter(student_id = obj, semester_id = sem).first() @@ -1428,24 +1551,31 @@ def allot_courses(request): profiles=request.FILES['allotedCourses'] batch_id=request.POST['batch'] sem_no=int(request.POST['semester']) - + batch=Batch.objects.get(id=batch_id) sem_id=Semester.objects.get(curriculum=batch.curriculum,semester_no=sem_no) - + print(batch , sem_id) + # format of excel sheet being uploaded should be xls only , otherwise error excel = xlrd.open_workbook(file_contents=profiles.read()) sheet=excel.sheet_by_index(0) final_registrations=[] + # print('>>>>>>>>>>>>>>>>>>>' , sheet.nrows) for i in range(1,sheet.nrows): roll_no = str(sheet.cell(i,0).value).split(".")[0] + # print("Roll No from Excel:", roll_no) course_slot_name = sheet.cell_value(i,1) course_code = sheet.cell_value(i,2) course_name = sheet.cell_value(i,3) - user=User.objects.get(username=roll_no) - user_info = ExtraInfo.objects.get(user=user) - student = Student.objects.get(id=user_info) - course_slot=CourseSlot.objects.get(name=course_slot_name.strip(),semester=sem_id) - course = Courses.objects.get(code=course_code.strip(),name=course_name.strip()) - #print(">>>>>",roll_no,course_slot_name,course_code,course_name) + try: + user=User.objects.get(username=roll_no) + user_info = ExtraInfo.objects.get(user=user) + student = Student.objects.get(id=user_info) + course_slot=CourseSlot.objects.get(name=course_slot_name.strip(),semester=sem_id) + print(course_code.strip() , course_name.strip()) + course = Courses.objects.get(code=course_code.strip(),name=course_name.strip()) + # print(">>>>>",roll_no,course_slot_name,course_code,course_name) + except Exception as e: + print('----------------------' , e) final_registration=FinalRegistration(student_id=student,course_slot_id=course_slot, course_id=course,semester_id=sem_id) final_registrations.append(final_registration) @@ -1499,7 +1629,7 @@ def user_check(request): final_user="" pass - if (str(acadadmin) != str(final_user)): + if ('acadadmin' != request.session.get('currentDesignationSelected')): return True else: return False @@ -1587,7 +1717,8 @@ def add_courses(request): course_id = course_id, student_id=current_user, course_slot_id = courseslot_id, - semester_id=sem_id + semester_id=sem_id, + working_year = datetime.datetime.now().year, ) if p not in reg_curr: reg_curr.append(p) @@ -1627,6 +1758,52 @@ def drop_course(request): else: return HttpResponseRedirect('/academic-procedures/main') +def replace_courses(request): + """ + This function is used to replace elective courses which have been registered + @param: + request - contains metadata about the requested page + @variables: + current_user - contains current logged in user + sem_id - contains current semester id + count - no of courses to be replaced + course_id - contains course id for a particular course + course_slot_id - contains course slot id for a particular course + choice - contains choice of a particular course + slot - contains slot of a particular course + """ + + if request.method == 'POST' : + try: + current_user = get_object_or_404(User, username=request.POST.get('user')) + current_user = ExtraInfo.objects.all().filter(user=current_user).first() + current_user = Student.objects.all().filter(id=current_user.id).first() + + # sem_id = Semester.objects.get(id = request.POST.get('semester')) + count = request.POST.get('ct') + count = int(count) + + for i in range(1, count+1): + choice = "choice["+str(i)+"]" + slot = "slot["+str(i)+"]" + try : + + course_id = Courses.objects.get(id = request.POST.get(choice)) + courseslot_id = CourseSlot.objects.get(id = request.POST.get(slot)) + + registered_course = course_registration.objects.filter(student_id=current_user, course_slot_id = courseslot_id).first() + + if registered_course: + registered_course.course_id = course_id + registered_course.save() + except Exception as e: + continue + return HttpResponseRedirect('/academic-procedures/main') + except Exception as e: + return HttpResponseRedirect('/academic-procedures/main') + else : + return HttpResponseRedirect('/academic-procedures/main') + @@ -1726,7 +1903,7 @@ def get_final_registration_choices(branch_courses,batch): max_limit = courseslot.max_registration_limit lis = [] for course in courseslot.courses.all(): - if FinalRegistration .objects.filter(student_id__batch_id__year = batch, course_id = course).count() < max_limit: + if FinalRegistration.objects.filter(student_id__batch_id__year = batch, course_id = course).count() < max_limit: lis.append(course) else: unavailable_courses.append(course) @@ -1741,10 +1918,13 @@ def get_add_course_options(branch_courses, current_register, batch): for c in current_register: slots.append(c[0]) for courseslot in branch_courses: + if courseslot.type == "Swayam": + continue max_limit = courseslot.max_registration_limit if courseslot not in slots: lis = [] for course in courseslot.courses.all(): + print(course) if course_registration.objects.filter(student_id__batch_id__year = batch, course_id = course).count() < max_limit: lis.append(course) course_option.append((courseslot, lis)) @@ -1757,7 +1937,24 @@ def get_drop_course_options(current_register): courses.append(item[1]) return courses +def get_replace_course_options( current_register, batch): + replace_options = [] + for registered_course in current_register: + courseslot_id = registered_course[0] + course_id = registered_course[1] + + courseslot = courseslot_id + coursename = course_id.name + lis = [] + + if 'Elective' in courseslot.type: + for course in courseslot.courses.all(): + if course != course_id: + lis.append(course) + replace_options.append((courseslot, coursename, lis)) + + return replace_options @@ -1789,7 +1986,11 @@ def get_user_semester(roll_no, ug_flag, masters_flag, phd_flag): def get_branch_courses(roll_no, user_sem, branch): roll = str(roll_no) - year = int(roll[:4]) + try: + year = int(roll[:4]) + except: + year = int(roll[:2]) + year = 2000 + year courses = Curriculum.objects.all().select_related().filter(batch=(year)) courses = courses.filter(sem = user_sem) courses = courses.filter(floated = True) @@ -1864,13 +2065,13 @@ def acad_person(request): des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() - if str(des.designation) == "student": + if request.session.get('currentDesignationSelected') == "student": return HttpResponseRedirect('/academic-procedures/main/') - elif str(des.designation) == "Associate Professor" : + elif request.session.get('currentDesignationSelected') == "Associate Professor" : return HttpResponseRedirect('/academic-procedures/main/') - elif str(request.user) == "acadadmin" : + elif request.session.get('currentDesignationSelected')== "acadadmin" : # year = datetime.datetime.now().year @@ -2223,12 +2424,13 @@ def student_list(request): batch_id = Batch.objects.get(id = batch) student_obj = FeePayments.objects.all().select_related('student_id').filter(student_id__batch_id = batch_id) if (student_obj): - reg_table = student_obj.prefetch_related('student_id__studentregistrationchecks').filter(semester_id = student_obj[0].semester_id, student_id__studentregistrationchecks__final_registration_flag = True).select_related( + reg_table = student_obj.prefetch_related('student_id__studentregistrationchecks').filter(semester_id = student_obj[0].semester_id, student_id__studentregistrationchecks__final_registration_flag = True , student_id__finalregistration__verified=False , student_id__finalregistration__semester_id= student_obj[0].semester_id ).select_related( 'student_id','student_id__id','student_id__id__user','student_id__id__department').values( 'student_id__id','student_id__id__user__first_name','student_id__id__user__last_name','student_id__batch','student_id__id__department__name', 'student_id__programme','student_id__curr_semester_no','student_id__id__sex','student_id__id__phone_no','student_id__category', 'student_id__specialization','mode','transaction_id','deposit_date','fee_paid','utr_number','reason','fee_receipt','actual_fee', - 'student_id__id__user__username').order_by('student_id__id__user') + 'student_id__id__user__username').order_by('student_id__id__user').distinct() + # print('------------------------------------------------------------------------------------------------------------------------------------------',reg_table) else : reg_table = [] @@ -2288,7 +2490,7 @@ def student_list(request): 'specialization','gender','category', 'pwd_status','phone_no','actual_fee', 'fee_paid','reason','date_deposited', - 'mode','utr_number','fee_receipt')) + 'mode','utr_number','fee_receipt')).distinct() excel_response = BytesIO() @@ -2326,6 +2528,12 @@ def process_verification_request(request): return verify_registration(request) return JsonResponse({'status': 'Failed'}, status=400) + +def auto_process_verification_request(request): + if request.is_ajax(): + return auto_verify_registration(request) + return JsonResponse({'status': 'Failed'}, status=400) + @transaction.atomic def verify_registration(request): @@ -2335,12 +2543,17 @@ def verify_registration(request): batch = student.batch_id curr_id = batch.curriculum - sem_id = Semester.objects.get(curriculum = curr_id, semester_no = student.curr_semester_no+1) + + if(student.curr_semester_no+1 >= 9): + sem_no = 4 + else: + sem_no = student.curr_semester_no+1 - final_register_list = FinalRegistration.objects.all().filter(student_id = student, verified = False, semester_id = sem_id) + sem_id = Semester.objects.get(curriculum = curr_id, semester_no = sem_no) - sem_no = student.curr_semester_no + 1 + final_register_list = FinalRegistration.objects.all().filter(student_id = student, verified = False, semester_id = sem_id) + with transaction.atomic(): ver_reg = [] for obj in final_register_list: @@ -2348,11 +2561,13 @@ def verify_registration(request): course_id=obj.course_id, student_id=student, semester_id=obj.semester_id, - course_slot_id = obj.course_slot_id + course_slot_id = obj.course_slot_id, + working_year = datetime.datetime.now().year, ) ver_reg.append(p) o = FinalRegistration.objects.filter(id= obj.id).update(verified = True) course_registration.objects.bulk_create(ver_reg) + # StudentRegistrationChecks.objects.filter(student_id = student_id, semester_id = sem_id).update(final_registration_flag = True) academics_module_notif(request.user, student.id.user, 'registration_approved') Student.objects.filter(id = student_id).update(curr_semester_no = sem_no) return JsonResponse({'status': 'success', 'message': 'Successfully Accepted'}) @@ -2363,8 +2578,11 @@ def verify_registration(request): batch = student_id.batch_id curr_id = batch.curriculum - sem_id = Semester.objects.get(curriculum = curr_id, semester_no = student_id.curr_semester_no + 1) - + if(student.curr_semester_no+1 >= 9): + sem_no = 4 + else: + sem_no = student.curr_semester_no+1 + sem_id = Semester.objects.get(curriculum = curr_id, semester_no = sem_no) with transaction.atomic(): academicadmin = get_object_or_404(User, username = "acadadmin") FinalRegistration.objects.filter(student_id = student_id, verified = False, semester_id = sem_id).delete() @@ -2373,8 +2591,53 @@ def verify_registration(request): academics_module_notif(academicadmin, student_id.id.user, 'Registration Declined - '+reject_reason) return JsonResponse({'status': 'success', 'message': 'Successfully Rejected'}) - - +@transaction.atomic +def auto_verify_registration(request): + if request.POST.get('status_req') == "accept" : + student_id = request.POST.get('student_id') + student = Student.objects.get(id = student_id) + batch = student.batch_id + curr_id = batch.curriculum + + if(student.curr_semester_no+1 >= 9): + # print('----------------------------------------------------------------' , student.curr_semester_no) + sem_no = 8 + else: + # print('----------------------------------------------------------------' , student.curr_semester_no) + sem_no = student.curr_semester_no+1 + sem_id = Semester.objects.get(curriculum = curr_id, semester_no = sem_no) + # print('----------------------------------------------------------------' , student.curr_semester_no) + + final_register_list = FinalRegistration.objects.all().filter(student_id = student, verified = False, semester_id = sem_id) + + # final_register_list = FinalRegistration.objects.all().filter(student_id = student, verified = False) + + with transaction.atomic(): + for obj in final_register_list: + o = FinalRegistration.objects.filter(id= obj.id).update(verified = True) + academics_module_notif(request.user, student.id.user, 'registration_approved') + + Student.objects.filter(id = student_id).update(curr_semester_no = sem_no) + return JsonResponse({'status': 'success', 'message': 'Successfully Accepted'}) + + elif request.POST.get('status_req') == "reject" : + reject_reason = request.POST.get('reason') + student_id = request.POST.get('student_id') + student_id = Student.objects.get(id = student_id) + batch = student_id.batch_id + curr_id = batch.curriculum + if(student_id.curr_semester_no+1 >= 9): + sem_no = 8 + else: + sem_no = student_id.curr_semester_no+1 + sem_id = Semester.objects.get(curriculum = curr_id, semester_no = sem_no) + with transaction.atomic(): + academicadmin = get_object_or_404(User, username = "acadadmin") + # FinalRegistration.objects.filter(student_id = student_id, verified = False, semester_id = sem_id).delete() + StudentRegistrationChecks.objects.filter(student_id = student_id, semester_id = sem_id).update(final_registration_flag = False) + FeePayments.objects.filter(student_id = student_id, semester_id = sem_id).delete() + academics_module_notif(academicadmin, student_id.id.user, 'Registration Declined - '+reject_reason) + return JsonResponse({'status': 'success', 'message': 'Successfully Rejected'}) def get_registration_courses(courses): x = [[]] @@ -2439,8 +2702,8 @@ def course_marks_data(request): try: course_id = request.POST.get('course_id') course = Courses.objects.select_related().get(id = course_id) - print(course) - print(course_id) + # print(course) + # print(course_id) student_list = course_registration.objects.filter(course_id__id=course_id).select_related( 'student_id__id__user','student_id__id__department').only('student_id__batch', 'student_id__id__user__first_name', 'student_id__id__user__last_name', @@ -3462,7 +3725,380 @@ def mdue(request): content = json.dumps("success") return HttpResponse(content) + + + +def get_detailed_sem_courses(sem_id): + course_slots = CourseSlot.objects.filter(semester_id=sem_id) + # Serialize queryset of course slots into JSON + course_slots_json = serialize('json', course_slots) + # Convert JSON string into Python object + course_slots_data = json.loads(course_slots_json) + + # Iterate over each course slot data and include associated course data + for slot_data in course_slots_data: + # Retrieve associated courses for the current course slot + slot = CourseSlot.objects.get(id=slot_data['pk']) + courses = list(slot.courses.all().values()) + # Add courses data to the course slot data + slot_data['courses'] = courses + + return course_slots_data + + +def get_next_sem_courses(request): + if request.method == 'POST': + data = json.loads(request.body) + next_sem = data.get('next_sem') + branch = data.get('branch') + programme = data.get('programme') + batch = data.get('batch') + # we go to student table and apply filters and get batch_id of the students with these filter + batch_id = Student.objects.filter(programme = programme , batch = batch , specialization = branch)[0].batch_id + + curr_id = batch_id.curriculum + # print('-----------------------------------------------------------------------------------------', curr_id) + # curr_id = 1 + next_sem_id = Semester.objects.get(curriculum = curr_id, semester_no = next_sem) + + if next_sem_id: + next_sem_registration_courses = get_detailed_sem_courses(next_sem_id ) + # print(next_sem_registration_courses) + return JsonResponse(next_sem_registration_courses, safe=False) + return JsonResponse({'error': 'Invalid request'}) + + +def add_course_to_slot(request): + if request.method == 'POST': + data = json.loads(request.body) + course_slot_name = data.get('course_slot_name') + course_code = data.get('course_name') + # print('-----------------------------------------------------------------------------------------' , course_slot_name , course_code) + try: + course_slot = CourseSlot.objects.get(name=course_slot_name) + course = Courses.objects.get(code=course_code) + course_slot.courses.add(course) + + return JsonResponse({'message': f'Course {course_code} added to slot {course_slot_name} successfully.'}, status=200) + except CourseSlot.DoesNotExist: + return JsonResponse({'error': 'Course slot does not exist.'}, status=400) + except Course.DoesNotExist: + return JsonResponse({'error': 'Course does not exist.'}, status=400) + + return JsonResponse({'error': 'Invalid request method.'}, status=405) + + +def remove_course_from_slot(request): + if request.method == 'POST': + data = json.loads(request.body) + course_slot_name = data.get('course_slot_name') + course_code = data.get('course_name') + # print('-----------------------------------------------------------------------------------------' , course_slot_name , course_code) + try: + course_slot = CourseSlot.objects.get(name=course_slot_name) + course = Courses.objects.get(code=course_code) + course_slot.courses.remove(course) + return JsonResponse({'message': f'Course {course_code} removed from slot {course_slot_name} successfully.'}, status=200) + except CourseSlot.DoesNotExist: + return JsonResponse({'error': 'Course slot does not exist.'}, status=400) + except Course.DoesNotExist: + return JsonResponse({'error': 'Course does not exist.'}, status=400) + + return JsonResponse({'error': 'Invalid request method.'}, status=405) + + +def add_one_course(request): + if request.method == 'POST': + try: + # print(request.POST) + current_user = get_object_or_404(User, username=request.POST.get('user')) + current_user = ExtraInfo.objects.all().filter(user=current_user).first() + current_user = Student.objects.all().filter(id=current_user.id).first() + + sem_id = Semester.objects.get(id=request.POST.get('semester')) + choice = request.POST.get('choice') + slot = request.POST.get('slot') + + try: + course_id = Courses.objects.get(id=choice) + courseslot_id = CourseSlot.objects.get(id=slot) + print(courseslot_id) + print(courseslot_id.type) + if course_registration.objects.filter(course_slot_id_id=courseslot_id, student_id=current_user).count() == 1 and courseslot_id.type != "Swayam": + already_registered_course_id = course_registration.objects.filter(course_slot_id_id=courseslot_id, student_id=current_user)[0].course_id + # print(already_registered_course_id) + msg = 'Already Registered in the course : ' +already_registered_course_id.code + '-'+ already_registered_course_id.name + return JsonResponse({'message' : msg}) + if((course_registration.objects.filter(course_id=course_id, student_id=current_user).count() >= 1)): + return JsonResponse({'message': 'Already registered in this course!'}, status=200) + # Check if maximum course registration limit has not been reached + if course_registration.objects.filter(student_id__batch_id__year=current_user.batch_id.year, course_id=course_id).count() < courseslot_id.max_registration_limit and \ + (course_registration.objects.filter(course_id=course_id, student_id=current_user).count() == 0): + p = course_registration( + course_id=course_id, + student_id=current_user, + course_slot_id=courseslot_id, + semester_id=sem_id, + working_year = datetime.datetime.now().year, + ) + p.save() + return JsonResponse({'message': 'Course added successfully'}) + else: + return JsonResponse({'message': 'Course not added because seats are full!'}, status=200) + except Exception as e: + return JsonResponse({'message': 'Error adding course'}, status=500) + except Exception as e: + return JsonResponse({'message': 'Error adding course'}, status=500) + else: + return JsonResponse({'message': 'Invalid request method'}, status=405) + +def replace_one_course(request): + if request.method == 'POST' : + try: + current_user = get_object_or_404(User, username=request.POST.get('user')) + current_user = ExtraInfo.objects.all().filter(user=current_user).first() + current_user = Student.objects.all().filter(id=current_user.id).first() + + + course_id = Courses.objects.get(id = request.POST.get('choice')) + courseslot_id = CourseSlot.objects.get(id = request.POST.get('slot')) + if course_registration.objects.filter(student_id__batch_id__year=current_user.batch_id.year, course_id=course_id).count() < courseslot_id.max_registration_limit and \ + (course_registration.objects.filter(course_id=course_id, student_id=current_user).count() == 0): + # print('---------------------------------------------------------------------------------' , course_registration.objects.filter(student_id__batch_id__year=current_user.batch_id.year, course_id=course_id).count() , courseslot_id.max_registration_limit ) + registered_course = course_registration.objects.filter(student_id=current_user, course_slot_id = courseslot_id).first() + + if registered_course: + registered_course.course_id = course_id + registered_course.save() + else: + return JsonResponse({'message': 'Cannot Replace to this course seats are full!'}, status=200) + + return JsonResponse({'message': 'Course Replaced Successfully'}, status=200) + except Exception as e: + return JsonResponse({'message': 'Error Replacing course'}, status=500) + else : + return JsonResponse({'message': 'Invalid request method'}, status=405) + +def get_sem_swayam(sem_id, batch): + courses = [] + course_slots = CourseSlot.objects.all().filter(type='Swayam') + + for slot in course_slots: + courses.append(slot) + + return courses + +def replaceSwayam(request): + if(request.POST): + # print(f"++++++++++++++++++++++++++++++++++++++++++++++++{request.POST}") + + current_user = get_object_or_404(User, username=request.user.username) + user_details = ExtraInfo.objects.all().select_related( + 'user', 'department').filter(user=current_user).first() + desig_id = Designation.objects.all().filter(name='acadadmin').first() + temp = HoldsDesignation.objects.all().select_related().filter( + designation=desig_id).first() + acadadmin = temp.working + k = str(user_details).split() + final_user = k[2] + + if ('acadadmin' != request.session.get('currentDesignationSelected')): + return HttpResponseRedirect('/academic-procedures/') + roll_no = request.POST["rollNo"] + obj = ExtraInfo.objects.all().select_related( + 'user', 'department').filter(id=roll_no).first() + firstname = obj.user.first_name + lastname = obj.user.last_name + dict2 = {'roll_no': roll_no, + 'firstname': firstname, 'lastname': lastname} + + details = [] + obj2 = Student.objects.all().select_related( + 'id', 'id__user', 'id__department').filter(id=roll_no).first() + # obj = Register.objects.all().select_related('curr_id', 'student_id', 'curr_id__course_id', + # 'student_id__id', 'student_id__id__user', 'student_id__id__department').filter(student_id=obj2) + batch = obj2.batch_id + curr_id = batch.curriculum + curr_sem_id = Semester.objects.get(curriculum = curr_id, semester_no = obj2.curr_semester_no) + current_sem_courses = get_currently_registered_elective( + roll_no, curr_sem_id) + current_sem_swayam = get_sem_swayam(curr_sem_id,2025) + idd = obj2 + for z in current_sem_courses: + eletive_id=z[2] + z = z[1] + + course_code = z.code + course_name = z.name + + k = {} + # reg_ig has course registration id appended with the the roll number + # so that when we have removed the registration we can be redirected to this view + k['reg_id'] = roll_no+" - "+course_code + k['rid'] = roll_no+" - "+course_code + # Name ID Confusion here , be carefull + courseobj2 = Courses.objects.all().filter(code=course_code) + # if(str(z.student_id) == str(idd)): + for p in courseobj2: + k['course_id'] = course_code + k['course_name'] = course_name + k['sem'] = curr_sem_id.semester_no + k['credits'] = p.credit + k['eletive_id'] = eletive_id + details.append(k) + + year = demo_date.year + month = demo_date.month + yearr = str(year) + "-" + str(year+1) + semflag = 0 + if(month >= 7): + semflag = 1 + else: + semflag = 2 + # TO DO Bdes + date = {'year': yearr, 'semflag': semflag} + course_list = Courses.objects.all() + semester_list = Semester.objects.all() + html = render_to_string('academic_procedures/studentSwayam.html', + {'details': details, + 'dict2': dict2, + 'course_list': course_list, + 'current_sem_swayam':current_sem_swayam, + 'roll_no':roll_no, + 'semester_list': semester_list, + # 'csrf_token' : csrf_token, + 'date': date}, request) + + maindict = {'html': html} + obj = json.dumps(maindict) + return HttpResponse(obj, content_type='application/json') + +def get_currently_registered_elective(student_id, semester_id): + registrations = course_registration.objects.filter(student_id=student_id, semester_id=semester_id) + courses = [] + for registration in registrations: + if registration.course_slot_id.type == "Optional Elective": + courses.append((registration.course_slot_id, registration.course_id, registration.id)) + return courses + + + +def swayam_replace(request): + if request.method == 'POST': + csrf_token = request.POST.get('csrfmiddlewaretoken', None) + + # print(f"---------------------------------{csrf_token}") + try: + + # print(f"djfhajjfsjfhajfhjdsfsdfj{request.POST}") + csrf_token = request.POST.get('csrfmiddlewaretoken', None) + + # print(f"---------------------------------{csrf_token}") + # Accessing individual values by key + user_value = request.POST['user'] + course_id_value = request.POST['course_id'] + + # print(user_value) 20BCS074 + # print(course_id_value) 8955 + + elective_to_delete = course_registration.objects.get(id=course_id_value) + sem = elective_to_delete.semester_id + # print(elective_to_delete) + # print(sem) cse ug curri v1 + + + swayam_course_id_value = request.POST['swayam_course_id'] + swayam_course_id_value_array = [int(id_str) for id_str in swayam_course_id_value.split(',')[:-1]] + # print(swayam_course_id_value_array) + # print(swayam_course_id_value) + + + + swayam_course_slot_id_value = request.POST['swayam_course_slot_id'] + swayam_course_slot_id_value_array = [int(slot_str) for slot_str in swayam_course_slot_id_value.split(',')[:-1]] + # print(swayam_course_slot_id_value_array) + # print(swayam_course_slot_id_value) + + + swayam_semester_id_value = request.POST['swayam_semester_id'] + swayam_semester_id_value_array = [int(semester_str) for semester_str in swayam_semester_id_value.split(',')[:-1]] + + + + + n = len(swayam_course_id_value_array) + # print(n) + # new_row_data = [] + for i in range(n): + course_id_model = Courses.objects.get(id=swayam_course_id_value_array[i]) + # print(course_id_model) + semester_id_model = Semester.objects.get(id=swayam_semester_id_value_array[i]) + student_id_model = Student.objects.get(id=user_value) + course_slot_id_model = CourseSlot.objects.get(id=swayam_course_slot_id_value_array[i]) + obj = course_registration( + course_id = course_id_model, + semester_id = semester_id_model, + student_id = student_id_model, + course_slot_id = course_slot_id_model, + working_year = datetime.datetime.now().year, + ) + obj.save() + + # for j in range(n): + # SwayamCourses.objects.filter(course_id = swayam_course_id_value_array[j], student_id=user_value).update(course_used = True) + + elective_to_delete.delete() + + + messages.success(request, "Your Courses have been replaced.") + return HttpResponseRedirect('/academic-procedures/main') + + + + + except Exception as e: + error_message = str(e) + print("Error:", error_message) + messages.error(request, f"Error in Registration: {error_message}") + return HttpResponseRedirect('/academic-procedures/main') + else: + return HttpResponseRedirect('/academic-procedures/main') + +def register_backlog_course(request): + if request.method == 'POST': + try: + current_user = request.user + current_user = ExtraInfo.objects.all().filter(user=request.user).first() + current_user = Student.objects.all().filter(id=current_user.id).first() + sem_id = Semester.objects.filter(id = request.POST.get('semester')).first() + course_id = Courses.objects.get(code = request.POST.get('courseCode') , version = request.POST.get('Version')) + course_slots = course_id.courseslots.all() + course_slot_id = '' + if course_slots: + course_slot_id = CourseSlot.objects.filter(id = course_slots[0].id).first() + if (sem_id.semester_no - course_slot_id.semester.semester_no)%2 != 0 : + return JsonResponse({'message':'Wait for Next Semester !'}, status=200) + # print('_____________________________________________________________________________________________' , course_id ,current_user , course_slot_id , sem_id) + try: + if course_registration.objects.filter(course_id=course_id, student_id=current_user , semester_id = sem_id).count() == 0: + p = course_registration( + course_id=course_id, + student_id=current_user, + course_slot_id=course_slot_id, + semester_id=sem_id, + working_year = datetime.datetime.now().year, + ) + p.save() + return JsonResponse({'message': 'Successfully Registered Backlog course' }, status=200) + else: + return JsonResponse({'message': 'Already Registered Backlog course' }, status=200) + except Exception as e: + print(str(e)) + return JsonResponse({'message': 'Error Registering course ' + str(e)}, status=500) + except Exception as e: + print(str(e)) + return JsonResponse({'message': 'Adding Backlog Failed ' +str(e)}, status=500) \ No newline at end of file diff --git a/FusionIIIT/applications/central_mess/api/serializers.py b/FusionIIIT/applications/central_mess/api/serializers.py index b30ad2686..582f2725e 100644 --- a/FusionIIIT/applications/central_mess/api/serializers.py +++ b/FusionIIIT/applications/central_mess/api/serializers.py @@ -88,4 +88,14 @@ class Meta: class reg_recordSerialzer(serializers.ModelSerializer): class Meta: model = Reg_records - fields=('__all__') \ No newline at end of file + fields=('__all__') + +class RegistrationRequestSerializer(serializers.ModelSerializer): + class Meta: + model = Registration_Request + fields = ('__all__') + +class DeregistrationRequestSerializer(serializers.ModelSerializer): + class Meta: + model = Deregistration_Request + fields = ('__all__') \ No newline at end of file diff --git a/FusionIIIT/applications/central_mess/api/urls.py b/FusionIIIT/applications/central_mess/api/urls.py index 2bd15c746..7f4c03286 100644 --- a/FusionIIIT/applications/central_mess/api/urls.py +++ b/FusionIIIT/applications/central_mess/api/urls.py @@ -23,5 +23,7 @@ # url("billDashboard", views.Bill_dashboard.as_view(), name="billDashboard"), url("get_student_bill",views.Get_Student_bill.as_view(),name="student_bill_API"), url("get_student_payment",views.Get_Student_Payments.as_view(),name="student_payment_API"), - url("get_student_all_details",views.Get_Student_Details.as_view(),name="get_student_details_API") + url("get_student_all_details",views.Get_Student_Details.as_view(),name="get_student_details_API"), + url('registrationRequestApi', views.RegistrationRequestApi.as_view(), name='registrationRequestApi'), + url('deRegistrationRequestApi', views.DeregistrationRequestApi.as_view(), name='deRegistrationRequestApi'), ] \ No newline at end of file diff --git a/FusionIIIT/applications/central_mess/api/views.py b/FusionIIIT/applications/central_mess/api/views.py index 6d1b7d4ae..a6fbe4a97 100644 --- a/FusionIIIT/applications/central_mess/api/views.py +++ b/FusionIIIT/applications/central_mess/api/views.py @@ -1,4 +1,5 @@ #APIs +from django.db.models import F from rest_framework.views import APIView from rest_framework.response import Response from .serializers import * @@ -19,19 +20,47 @@ def post(self, request): data = request.data mess = data['mess'] - _type = data['type'] - desc = data['desc'] + feedback_type = data['feedback_type'] + description = data['description'] username = get_object_or_404(User,username=request.user.username) idd = ExtraInfo.objects.get(user=username) student = Student.objects.get(id=idd.id) obj = Feedback( student_id = student, mess =mess, - feedback_type=_type, - description=desc + feedback_type=feedback_type, + description=description ) obj.save() return Response({'status':200}) + + def put(self, request): + data = request.data + + print(data) + + student_id = data['student_id'] + mess = data['mess'] + feedback_type = data['feedback_type'] + description = data['description'] + fdate = data['fdate'] + new_remark = data['feedback_remark'] + + # username = get_object_or_404(User,username=request.user.username) + # idd = ExtraInfo.objects.get(user=username) + # student = Student.objects.get(id=idd.id) + + feedback_request = get_object_or_404(Feedback, + student_id = student_id, + mess = mess, + feedback_type = feedback_type, + description = description, + fdate = fdate, + ) + feedback_request.feedback_remark = new_remark + feedback_request.save() + + return Response({'status':200}) class MessinfoApi(APIView): @@ -104,30 +133,37 @@ def get(self, request): def post(self, request): data = request.data + student_id = data['student_id'] month = data['month'] year = data['year'] amount = data['amount'] rebate_count = data['rebate_count'] rebate_amount = data['rebate_amount'] - #nonveg_total_bill = data['nonveg_total_bill'] + total_bill = data['amount']-(data['rebate_count']*data['rebate_amount']) paid = data['paid'] - username = get_object_or_404(User,username=request.user.username) + username = get_object_or_404(User,username=student_id) idd = ExtraInfo.objects.get(user=username) student = Student.objects.get(id=idd.id) - - obj = Monthly_bill( - student_id = student, - month = month, - year = year, - amount = amount, - rebate_count = rebate_count, - rebate_amount = rebate_amount, - # nonveg_total_bill = nonveg_total_bill, - paid = paid - ) - obj.save() + try: + reg_main = Monthly_bill.objects.get(student_id=student, year = year, month = month) + reg_main.amount = amount + reg_main.rebate_count = rebate_count + reg_main.rebate_amount = rebate_amount + reg_main.total_bill = total_bill + except Monthly_bill.DoesNotExist: + reg_main = Monthly_bill.objects.create( + student_id=student, + month = month, + year = year, + amount = amount, + rebate_amount = rebate_amount, + rebate_count = rebate_count, + total_bill = total_bill, + paid = paid + ) + reg_main.save() return Response({'status':200}) class PaymentsApi(APIView): @@ -210,7 +246,33 @@ def post(self, request): start_date = start_date ) obj.save() - return Response({'status':200}) + return Response({'status':200}) + + def put(self, request): + data = request.data + + student_id = data['student_id'] + start_date = data['start_date'] + end_date = data['end_date'] + purpose = data['purpose'] + new_status = data['status'] + app_date = data['app_date'] + leave_type = data['leave_type'] + rebate_remark = data['rebate_remark'] + + # username = get_object_or_404(User,username=student_id) + # idd = ExtraInfo.objects.get(user=username) + # student = Student.objects.get(id=idd.id) + + rebate_request = get_object_or_404(Rebate, student_id=student_id, end_date=end_date, start_date=start_date, app_date=app_date, purpose=purpose, leave_type=leave_type) + + # Update the status + rebate_request.status = new_status + rebate_request.rebate_remark = rebate_remark + rebate_request.save() + + return Response({'status': 200}) + class Vacation_foodApi(APIView): def get(self, request): vacation_food_obj = Vacation_food.objects.all(); @@ -241,7 +303,45 @@ def post(self, request): start_date = start_date ) obj.save() - return Response({'status':200}) + return Response({'status':200}) + + def put(self, request): + print(request.data) + data = request.data + + student_id = data['student_id'] + start_date = data['start_date'] + end_date = data['end_date'] + purpose = data['purpose'] + new_status = data['status'] + app_date = data['app_date'] + + + # username = get_object_or_404(User,username=request.user.username) + # idd = ExtraInfo.objects.get(user=username) + # student = Student.objects.get(id=idd.id) + + try: + vacation_food_request = get_object_or_404(Vacation_food, + student_id = student_id, + app_date = app_date, + purpose = purpose, + end_date= end_date, + start_date = start_date + ) + vacation_food_request.status = new_status + vacation_food_request.save() + return Response({'status':200}) + except: + vacation_food_request = Vacation_food.objects.filter(student_id = student_id, + app_date = app_date, + purpose = purpose, + end_date= end_date, + start_date = start_date + ).latest('app_date') + vacation_food_request.status = new_status + vacation_food_request.save() + return Response({'status':200}) class Nonveg_menuApi(APIView): def get(self, request): @@ -331,7 +431,32 @@ def post(self, request): request = request_ ) obj.save() - return Response({'status':200}) + return Response({'status':200}) + + def put(self, request): + print(request.data) + data = request.data + student_id = data['student_id'] + start_date = data['start_date'] + end_date = data['end_date'] + app_date = data['app_date'] + request_= data['request'] + item1 = data['item1'] + item2 = data['item2'] + new_status = data['status'] + + # Fetch the Special_request object you want to update + # username = get_object_or_404(User, username=request.user.username) + # idd = ExtraInfo.objects.get(user=username) + # student = Student.objects.get(id=idd.id) + + special_request = get_object_or_404(Special_request, student_id=student_id, app_date=app_date, item1=item1, item2=item2, end_date=end_date, start_date=start_date, request=request_) + + # Update the status + special_request.status = new_status + special_request.save() + + return Response({'status': 200}) class Mess_meetingApi(APIView): def get(self, request): @@ -484,4 +609,114 @@ def post(self,request): reg_main = Reg_main.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').get(student_id=student) serialized_obj = GetFilteredSerialzer(reg_main) data={'payment':payment_serialized_obj.data,'bill':bill_serialized_obj.data,'reg_records':reg_record_serialized_obj.data,'student_details':serialized_obj.data} - return Response({'payload':data}) \ No newline at end of file + return Response({'payload':data}) + +class RegistrationRequestApi(APIView): + def get(self, request): + registration_requests = Registration_Request.objects.all() + serializer = RegistrationRequestSerializer(registration_requests, many=True) + return Response({'status': 200, 'payload': serializer.data}) + + def post(self, request): + serializer = RegistrationRequestSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return Response({'status': 200}) + return Response(serializer.errors, status=400) + + def put(self, request): + try: + data = request.data + print(data) + student_id = data['student_id'] + start_date = data['start_date'] + payment_date = data['payment_date'] + amount = data['amount'] + Txn_no = data['Txn_no'] + img = data['img'] + new_status = data['status'] + new_remark = data['registration_remark'] + mess_option = data['mess_option'] + + username = get_object_or_404(User, username=student_id) + idd = ExtraInfo.objects.get(user=username) + student = Student.objects.get(id=idd.id) + + registration_request = get_object_or_404(Registration_Request, student_id = student_id, start_date = start_date, payment_date = payment_date, amount = amount, Txn_no = Txn_no) + + registration_request.status = new_status + registration_request.registration_remark = new_remark + registration_request.save() + + if (new_status == 'accept'): + new_payment_record = Payments(student_id = student, amount_paid = amount, payment_date=payment_date, payment_month=current_month(), payment_year=current_year()) + new_payment_record.save() + + try: + reg_main = Reg_main.objects.get(student_id=student) + reg_main.current_mess_status = "Registered" + reg_main.balance = F('balance') + amount + except Reg_main.DoesNotExist: + reg_main = Reg_main.objects.create( + student_id=student, + program=student.programme, + current_mess_status="Registered", + balance=amount, + mess_option=mess_option + ) + reg_main.save() + + new_reg_record = Reg_records(student_id=student, start_date=start_date, end_date=None) + new_reg_record.save() + + + return Response({'status': 200}) + except Exception as e: + print({'error': str(e)}) + return Response({'error': str(e)}, status=400) + +class DeregistrationRequestApi(APIView): + def get(self, request): + deregistration_requests = Deregistration_Request.objects.all() + serializer = DeregistrationRequestSerializer(deregistration_requests, many=True) + return Response({'status': 200, 'payload': serializer.data}) + + def post(self, request): + serializer = DeregistrationRequestSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return Response({'status': 200}) + return Response(serializer.errors, status=400) + + def put(self, request): + try: + data = request.data + print(data) + student_id = data['student_id'] + end_date = data['end_date'] + new_status = data['status'] + new_remark = data['deregistration_remark'] + + username = get_object_or_404(User, username=student_id) + idd = ExtraInfo.objects.get(user=username) + student = Student.objects.get(id=idd.id) + + deregistration_request = get_object_or_404(Deregistration_Request, student_id = student_id, end_date = end_date) + + deregistration_request.status = new_status + deregistration_request.deregistration_remark = new_remark + deregistration_request.save() + + if (new_status == 'accept'): + + reg_main = Reg_main.objects.get(student_id=student) + reg_main.current_mess_status = "Deregistered" + reg_main.save() + + reg_record = Reg_records.objects.filter(student_id=student).latest('start_date') + reg_record.end_date = end_date + reg_record.save() + return Response({'status': 200}) + except Exception as e: + print({'error': str(e)}) + return Response({'error': str(e)}, status=400) \ No newline at end of file diff --git a/FusionIIIT/applications/central_mess/forms.py b/FusionIIIT/applications/central_mess/forms.py index ceecf4400..9325df23f 100644 --- a/FusionIIIT/applications/central_mess/forms.py +++ b/FusionIIIT/applications/central_mess/forms.py @@ -2,7 +2,7 @@ from .models import Mess_minutes from .models import Registration_Request -from .models import Semdates +from .models import Update_Payment class MinuteForm(forms.ModelForm): @@ -32,9 +32,22 @@ class Meta: 'img':forms.FileInput(attrs={'class':'ui big input'}), 'start_date':forms.widgets.DateInput(attrs={'type':'date'}), 'payment_date':forms.widgets.DateInput(attrs={'type':'date'}), - } - - + } + + +class UpdatePaymentRequest(forms.ModelForm): + + class Meta: + model = Update_Payment + fields = ('Txn_no','amount','img','payment_date') + + widgets={ + 'Txn_no':forms.TextInput(attrs={'class':'ui big input','style':'border-radius:4px', 'initial':'590'}), + 'amount':forms.TextInput(attrs={'class':'ui big input'}), + 'img':forms.FileInput(attrs={'class':'ui big input'}), + 'payment_date':forms.widgets.DateInput(attrs={'type':'date'}), + } + class UpdateBalanceRequest(forms.ModelForm): class Meta: diff --git a/FusionIIIT/applications/central_mess/handlers.py b/FusionIIIT/applications/central_mess/handlers.py index 47e840810..882cbe4e4 100644 --- a/FusionIIIT/applications/central_mess/handlers.py +++ b/FusionIIIT/applications/central_mess/handlers.py @@ -15,7 +15,7 @@ from applications.academic_information.models import Student from applications.globals.models import ExtraInfo, HoldsDesignation, Designation from .models import (Feedback, Menu, Menu_change_request, Mess_meeting, - Mess_minutes, Mess_reg, Messinfo, Monthly_bill, + Mess_minutes, Mess_reg, Messinfo, Monthly_bill, Update_Payment, Payments, Rebate,Special_request, Vacation_food, MessBillBase,Registration_Request, Reg_main, Reg_records ,Deregistration_Request, Semdates) from notification.views import central_mess_notif @@ -766,6 +766,40 @@ def handle_reg_response(request): return data +def handle_update_payment_response(request): + id = request.POST['id_reg'] + status = request.POST['status'] + remark = request.POST['remark'] + payment_req = Update_Payment.objects.get(pk=id) + payment_date = payment_req.payment_date + student = payment_req.student_id + payment_req.status = status + payment_req.update_remark=remark + + payment_req.save() + + if(status == 'accept'): + amount = payment_req.amount + reg_main_obj= Reg_main.objects.get(student_id=student) + new_balance = reg_main_obj.balance + amount + reg_main_obj.balance = new_balance + reg_main_obj.save() + new_payment_record = Payments(student_id=student, amount_paid = amount, payment_date=payment_date, payment_month=current_month(), payment_year= current_year()) + new_payment_record.save() + + message = 'Your update payment request has been accepted.' + + else: + message = 'Your update payment request has been rejected.' + + receiver = payment_req.student_id.id.user + central_mess_notif(request.user, receiver, 'leave_request', message) + data = { + 'message': 'success' + } + return data + + def handle_dreg_response(request): """ This function is to respond to de registeration requests @@ -816,14 +850,13 @@ def update_month_bill(request): """ student = str(request.POST.get("rollNo")).upper() studentHere = Student.objects.get(id = student) - rebate_count = int(request.POST.get("RebateCount")) - print(rebate_count) - rebate_amount = int(request.POST.get("RebateAmount")) - print(rebate_amount) new_amount = int(request.POST.get("new_amount")) month = request.POST.get("Month") year = int(request.POST.get("Year")) - bill_base_amount = int(MessBillBase.objects.latest('timestamp').bill_amount) + try: + bill_base_amount = int(MessBillBase.objects.latest('timestamp').bill_amount) + except: + bill_base_amount = 150 fixed_amount_per_month = int(bill_base_amount)*int(30) reg_main_obj = Reg_main.objects.get(student_id=student) @@ -838,7 +871,7 @@ def update_month_bill(request): reg_main_obj.save() existing_monthly_bill_object.save() except: - new_monthly_bill_obj = Monthly_bill(student_id = studentHere, rebate_amount=rebate_amount, rebate_count=rebate_count, month=month, year= year, total_bill = new_amount, amount=fixed_amount_per_month) + new_monthly_bill_obj = Monthly_bill(student_id = studentHere, month=month, year= year, total_bill = new_amount, amount=fixed_amount_per_month) curr_balance = curr_balance - new_amount reg_main_obj.balance = curr_balance reg_main_obj.save() diff --git a/FusionIIIT/applications/central_mess/models.py b/FusionIIIT/applications/central_mess/models.py index cd5427736..f92614ba1 100644 --- a/FusionIIIT/applications/central_mess/models.py +++ b/FusionIIIT/applications/central_mess/models.py @@ -321,3 +321,16 @@ class Semdates(models.Model): end_date = models.DateField(blank=False,default=datetime.date.today) class Meta: unique_together = (('start_date', 'end_date'),) + + +class Update_Payment(models.Model): + student_id = models.ForeignKey(Student, on_delete=models.CASCADE) + Txn_no =models.CharField(max_length=20) + img = models.ImageField(upload_to='images/',default=None) + amount=models.IntegerField(default=0) + status=models.CharField(max_length=10,default='pending') + update_remark=models.CharField(max_length=50,default='NA') + payment_date= models.DateField(default=None, null=True) + def __str__(self): + return str(self.student_id.id) + \ No newline at end of file diff --git a/FusionIIIT/applications/central_mess/urls.py b/FusionIIIT/applications/central_mess/urls.py index 031626819..78b65f22c 100644 --- a/FusionIIIT/applications/central_mess/urls.py +++ b/FusionIIIT/applications/central_mess/urls.py @@ -46,7 +46,8 @@ url(r'^registeredstudent', views.searchAddOrRemoveStudent, name='registeredstudent'), url(r'^registrationRequest', views.reg_request, name='reg_request'), - # url(r'^uploadpayment', views.uploadPaymentDue, name='uploadpayment') + url(r'^updatePaymentReq', views.update_payment, name='update_payment'), + url(r'^respond_to_updatePayment', views.respond_to_update_payment, name='response_to_update_payment'), url(r'^respond_to_reg_req',views.respond_to_reg, name='reg_response'), url(r'^deregistrationRequest', views.de_reg_request, name='deregistrationRequest'), url(r'^updatesemdates', views.update_semdates, name='updatesemdates'), diff --git a/FusionIIIT/applications/central_mess/views.py b/FusionIIIT/applications/central_mess/views.py index 4bc7238bd..255f34e40 100644 --- a/FusionIIIT/applications/central_mess/views.py +++ b/FusionIIIT/applications/central_mess/views.py @@ -14,16 +14,16 @@ from .utils import render_to_pdf from applications.academic_information.models import Student from applications.globals.models import ExtraInfo, HoldsDesignation, Designation -from .forms import MinuteForm, MessInfoForm,RegistrationRequest +from .forms import MinuteForm, MessInfoForm,RegistrationRequest,UpdatePaymentRequest from .tasks import * from .models import (Feedback, Menu, Menu_change_request, Mess_meeting, Mess_minutes, Mess_reg, Messinfo, Monthly_bill, Payments, Rebate, - Special_request, Vacation_food, MessBillBase,Registration_Request, Reg_records ,Reg_main,Deregistration_Request,Semdates) + Special_request, Vacation_food, MessBillBase,Registration_Request, Reg_records ,Reg_main,Deregistration_Request,Semdates,Update_Payment) from .handlers import (add_mess_feedback, add_sem_dates, add_vacation_food_request, add_menu_change_request, handle_menu_change_response, handle_vacation_food_request, add_mess_registration_time, add_leave_request, add_mess_meeting_invitation, - handle_rebate_response, add_special_food_request, + handle_rebate_response, add_special_food_request, handle_update_payment_response, handle_special_request, add_bill_base_amount, add_mess_committee, handle_reg_response, handle_dreg_response, update_month_bill,handle_add_reg) from notification.views import central_mess_notif @@ -59,7 +59,7 @@ def mess(request): holds_designations = HoldsDesignation.objects.select_related().filter(user=user) desig = holds_designations form = MinuteForm() - mess_reg = Mess_reg.objects.select_related().last() + # mess_reg = Mess_reg.objects.select_related().last() count1 = 0 count2 = 0 count3 = 0 @@ -82,12 +82,15 @@ def mess(request): splrequest = Special_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(student_id=student).order_by('-app_date') reg_form = RegistrationRequest() + update_form=UpdatePaymentRequest() reg_request = Registration_Request.objects.filter(student_id=student) - + update_payment_request = Update_Payment.objects.filter(student_id=student) de_reg_request = Deregistration_Request.objects.filter(student_id=student) + menu_data = Menu.objects.all() + try: mess_optn = Reg_main.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').get(student_id=student) y = Menu.objects.filter(mess_option=mess_optn.mess_option) @@ -127,21 +130,22 @@ def mess(request): # monthly_bill[i].due_amount=(-tot_am) # tot_am+=monthly_bill[i].total_bill # amount_due=-payments[0].amount_paid - amount_due = 0 + # amount_due = 0 ## adding the batch of student if btech or bdes then value of programme is 1 or else 0, holds value of phd and mtech. - if student.programme == 'B.Tech' or student.programme == 'B.Des': - programme = 1 - else: - programme = 0 - meeting = Mess_meeting.objects.all() - minutes = Mess_minutes.objects.all() - count = 0 + # if student.programme == 'B.Tech' or student.programme == 'B.Des': + # programme = 1 + # else: + # programme = 0 + # meeting = Mess_meeting.objects.all() + # minutes = Mess_minutes.objects.all() + # count = 0 # try: # mess_optn = Messinfo.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').get(student_id=student) # y = Menu.objects.filter(mess_option=mess_optn.mess_option) + # bill = Monthly_bill.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(Q(student_id=student) & Q(month=month_g_l) & Q(year=year_g)) # amount_c = MessBillBase.objects.latest('timestamp') @@ -182,169 +186,175 @@ def mess(request): # mess_optn={'mess_option':'no-mess'} # y = Menu.objects.filter(mess_option="mess1") - for d in desig: - if d.designation.name == 'mess_committee' or d.designation.name == 'mess_convener': - newmenu = Menu_change_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department','dish').filter(dish__mess_option='mess1').order_by('-app_date') - meeting = Mess_meeting.objects.all() - minutes = Mess_minutes.objects.select_related().all() - feed = Feedback.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(mess='mess1').order_by('-fdate') - feed2 = Feedback.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(mess='mess2').order_by('-fdate') - sprequest = Special_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(status='1').order_by('-app_date') - sprequest_past = Special_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(status='2').order_by('-app_date') - menuchangerequest= Menu_change_request.objects.select_related('student_id').filter().order_by('-app_date') - # menu_data = Menu.objects.all() - for f in feed: - if f.feedback_type == 'Maintenance' : - count1 += 1 - - elif f.feedback_type == 'Food' : - count2 += 1 - - elif f.feedback_type == 'Cleanliness' : - count3 += 1 - - elif f.feedback_type == 'Others' : - count4 += 1 - count5=0 - count6=0 - count7=0 - count8=0 - - context = { - 'menu': menu_data, - 'reg_menu': y, - 'messinfo': mess_optn, - 'newmenu': newmenu, - 'monthly_bill': monthly_bill, - 'total_due': amount_due, + # for d in desig: + # if d.designation.name == 'mess_committee' or d.designation.name == 'mess_convener': + # newmenu = Menu_change_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department','dish').filter(dish__mess_option='mess1').order_by('-app_date') + # meeting = Mess_meeting.objects.all() + # minutes = Mess_minutes.objects.select_related().all() + # feed = Feedback.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(mess='mess1').order_by('-fdate') + # feed2 = Feedback.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(mess='mess2').order_by('-fdate') + # sprequest = Special_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(status='1').order_by('-app_date') + # sprequest_past = Special_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(status='2').order_by('-app_date') + # menuchangerequest= Menu_change_request.objects.select_related('student_id').filter().order_by('-app_date') + + # # menu_data = Menu.objects.all() + + # for f in feed: + # if f.feedback_type == 'Maintenance' : + # count1 += 1 + + # elif f.feedback_type == 'Food' : + # count2 += 1 + + # elif f.feedback_type == 'Cleanliness' : + # count3 += 1 + + # elif f.feedback_type == 'Others' : + # count4 += 1 + # count5=0 + # count6=0 + # count7=0 + # count8=0 + + # context = { + # 'menu': menu_data, + # 'reg_menu': y, + # 'messinfo': mess_optn, + # 'newmenu': newmenu, + # 'monthly_bill': monthly_bill, + # 'total_due': amount_due, - 'vaca': vaca_obj, - 'info': extrainfo, - 'feedback': feedback_obj, - 'feed1': feed, - 'feed2':'', - 'student': student, - 'mess_reg': mess_reg, - 'current_date': current_date, - 'count': count, - 'rebates': rebates, - 'meeting': meeting, - 'minutes': minutes, - 'sprequest': sprequest, - 'splrequest': splrequest, - 'sprequest_past': sprequest_past, - 'menuchangerequest':menuchangerequest, - 'programme':programme, - 'count1': count1, - 'count2': count2, - 'count3': count3, - 'count4': count4, - 'count5': count5, - 'count6': count6, - 'count7': count7, - 'count8': count8, - 'form': form, - 'desig': desig, - 'reg_form':reg_form, - 'reg_request':reg_request, - 'reg_main':mess_optn, - 'reg_record':reg_record, - 'de_reg_request':de_reg_request, - - } - return render(request, "messModule/mess.html", context) - - if d.designation.name == 'mess_committee_mess2' or d.designation.name == 'mess_convener_mess2': - newmenu = Menu_change_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department','dish').filter(dish__mess_option='mess2').order_by('-app_date') - meeting = Mess_meeting.objects.all() - minutes = Mess_minutes.objects.select_related().all() - feed = Feedback.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(mess='mess2').order_by('-fdate') - feed2 = Feedback.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(mess='mess1').order_by('-fdate') - sprequest = Special_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(status='1').order_by('-app_date') - sprequest_past = Special_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(status='2').order_by('-app_date') - menuchangerequest= Menu_change_request.objects.select_related('student_id').filter().order_by('-app_date') - # menu_data = Menu.objects.all().order_by() - count5=0 - count6=0 - count7=0 - count8=0 - for f in feed: - if f.feedback_type == 'Maintenance' : - count1 += 1 - - elif f.feedback_type == 'Food' : - count2 += 1 - - elif f.feedback_type == 'Cleanliness' : - count3 += 1 - - elif f.feedback_type == 'Others' : - count4 += 1 - - context = { - 'menu': menu_data, - 'reg_menu': y, - 'messinfo': mess_optn, - 'newmenu': newmenu, - 'monthly_bill': monthly_bill, - 'total_due': amount_due, - 'vaca': vaca_obj, - 'info': extrainfo, - 'feedback': feedback_obj, - 'feed2': feed, - 'feed1':'', - 'student': student, - # 'data': data, - 'mess_reg': mess_reg, - 'current_date': current_date, - 'count': count, - 'rebates': rebates, - 'programme': programme, - 'meeting': meeting, - 'minutes': minutes, - 'splrequest': splrequest, - 'sprequest': sprequest, - 'sprequest_past': sprequest_past, - 'menuchangerequest':menuchangerequest, - 'count1': count1, - 'count2': count2, - 'count3': count3, - 'count4': count4, - 'count5': count5, - 'count6': count6, - 'count7': count7, - 'count8': count8, - 'form': form, - 'desig': desig, - 'reg_form':reg_form, - 'reg_request':reg_request, - 'reg_main':mess_optn, - 'reg_record':reg_record, - 'de_reg_request':de_reg_request, - } - return render(request, "messModule/mess.html", context) + # 'vaca': vaca_obj, + # 'info': extrainfo, + # 'feedback': feedback_obj, + # 'feed1': feed, + # 'feed2':'', + # 'student': student, + # 'mess_reg': mess_reg, + # 'current_date': current_date, + # 'count': count, + # 'rebates': rebates, + # 'meeting': meeting, + # 'minutes': minutes, + # 'sprequest': sprequest, + # 'splrequest': splrequest, + # 'sprequest_past': sprequest_past, + # 'menuchangerequest':menuchangerequest, + # 'programme':programme, + # 'count1': count1, + # 'count2': count2, + # 'count3': count3, + # 'count4': count4, + # 'count5': count5, + # 'count6': count6, + # 'count7': count7, + # 'count8': count8, + # 'form': form, + # 'desig': desig, + # 'reg_form':reg_form, + # 'reg_request':reg_request, + # 'reg_main':mess_optn, + # 'reg_record':reg_record, + # 'de_reg_request':de_reg_request, + + # } + # return render(request, "messModule/mess.html", context) + + # if d.designation.name == 'mess_committee_mess2' or d.designation.name == 'mess_convener_mess2': + # newmenu = Menu_change_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department','dish').filter(dish__mess_option='mess2').order_by('-app_date') + # meeting = Mess_meeting.objects.all() + # minutes = Mess_minutes.objects.select_related().all() + # feed = Feedback.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(mess='mess2').order_by('-fdate') + # feed2 = Feedback.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(mess='mess1').order_by('-fdate') + # sprequest = Special_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(status='1').order_by('-app_date') + # sprequest_past = Special_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(status='2').order_by('-app_date') + # menuchangerequest= Menu_change_request.objects.select_related('student_id').filter().order_by('-app_date') + + # # menu_data = Menu.objects.all().order_by() + + # count5=0 + # count6=0 + # count7=0 + # count8=0 + # for f in feed: + # if f.feedback_type == 'Maintenance' : + # count1 += 1 + + # elif f.feedback_type == 'Food' : + # count2 += 1 + + # elif f.feedback_type == 'Cleanliness' : + # count3 += 1 + + # elif f.feedback_type == 'Others' : + # count4 += 1 + + # context = { + # 'menu': menu_data, + # 'reg_menu': y, + # 'messinfo': mess_optn, + # 'newmenu': newmenu, + # 'monthly_bill': monthly_bill, + # 'total_due': amount_due, + # 'vaca': vaca_obj, + # 'info': extrainfo, + # 'feedback': feedback_obj, + # 'feed2': feed, + # 'feed1':'', + # 'student': student, + # # 'data': data, + # 'mess_reg': mess_reg, + # 'current_date': current_date, + # 'count': count, + # 'rebates': rebates, + # 'programme': programme, + # 'meeting': meeting, + # 'minutes': minutes, + # 'splrequest': splrequest, + # 'sprequest': sprequest, + # 'sprequest_past': sprequest_past, + # 'menuchangerequest':menuchangerequest, + # 'count1': count1, + # 'count2': count2, + # 'count3': count3, + # 'count4': count4, + # 'count5': count5, + # 'count6': count6, + # 'count7': count7, + # 'count8': count8, + # 'form': form, + # 'desig': desig, + # 'reg_form':reg_form, + # 'reg_request':reg_request, + # 'reg_main':mess_optn, + # 'reg_record':reg_record, + # 'de_reg_request':de_reg_request, + # } + # return render(request, "messModule/mess.html", context) context = { 'menu': menu_data, - 'reg_menu': y, - 'messinfo': mess_optn, + # 'reg_menu': y, + # 'messinfo': mess_optn, 'monthly_bill': monthly_bill, - 'total_due': amount_due, + # 'total_due': amount_due, 'vaca': vaca_obj, 'info': extrainfo, 'feedback': feedback_obj, 'student': student, - 'mess_reg': mess_reg, + # 'mess_reg': mess_reg, 'current_date': current_date, - 'count': count, + # 'count': count, 'rebates': rebates, 'splrequest': splrequest, 'form': form, - 'programme': programme, + # 'programme': programme, 'desig': desig, - 'minutes': minutes, - 'meeting': meeting, + # 'minutes': minutes, + # 'meeting': meeting, 'reg_form':reg_form, + 'update_form':update_form, + 'update_payment_request':update_payment_request, 'reg_main_stud':mess_optn, 'reg_request':reg_request, 'reg_record':reg_record, @@ -363,7 +373,12 @@ def mess(request): elif extrainfo.user_type == 'staff': for d in desig: if(d.designation.name == 'mess_manager'): - current_bill = MessBillBase.objects.latest('timestamp') + try: + current_bill = MessBillBase.objects.latest('timestamp') + except: + new_entry = MessBillBase(bill_amount=150) + new_entry.save() + current_bill = MessBillBase.objects.latest('timestamp') newmenu = Menu_change_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department','dish').all().order_by('-app_date') vaca_all = Vacation_food.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').all().order_by('-app_date') members_mess = HoldsDesignation.objects.select_related().filter(Q(designation__name__contains='mess_convener') @@ -371,8 +386,8 @@ def mess(request): y = Menu.objects.all() leave = Rebate.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(status='1').order_by('-app_date') leave_past = Rebate.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(status='2').order_by('-app_date') - meeting = Mess_meeting.objects.all() - minutes = Mess_minutes.objects.all() + # meeting = Mess_meeting.objects.all() + # minutes = Mess_minutes.objects.all() feed1 = Feedback.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(mess='mess1').order_by('-fdate') feed2 = Feedback.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(mess='mess2').order_by('-fdate') @@ -406,6 +421,7 @@ def mess(request): sprequest_past = Special_request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(status='2').order_by('-app_date') reg_request = Registration_Request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').all().filter(status='pending') + update_pay_request=Update_Payment.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').all().filter(status='pending') de_reg_request = Deregistration_Request.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').all().filter(status='pending') reg_main = Reg_main.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').filter(current_mess_status='Registered') reg_record = Reg_records.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').all() @@ -423,10 +439,10 @@ def mess(request): 'leave': leave, 'leave_past': leave_past, 'current_date': current_date, - 'mess_reg': mess_reg, + # 'mess_reg': mess_reg, 'desig': desig, - 'meeting': meeting, - 'minutes': minutes, + # 'meeting': meeting, + # 'minutes': minutes, 'sprequest': sprequest, 'sprequest_past': sprequest_past, 'count1': count1, @@ -436,7 +452,8 @@ def mess(request): 'reg_request':reg_request,'reg_record':reg_record,'reg_main':reg_main, 'de_reg_request':de_reg_request, 'bill': bills, - 'reg_form':reg_form + 'reg_form':reg_form, + 'update_pay_request':update_pay_request } return render(request, "messModule/mess.html", context) @@ -489,6 +506,7 @@ def mess(request): } return render(request, 'messModule/mess.html', context) + @login_required @transaction.atomic def mess_info(request): @@ -941,25 +959,13 @@ def post(self, request, *args, **kwargs): extra_info = ExtraInfo.objects.select_related().get(user=user) y = Menu.objects.all() - if extra_info.user_type=='student': - student = Student.objects.select_related('id','id__user','id__department').get(id=extra_info) - mess_info = Messinfo.objects.select_related('student_id','student_id__id','student_id__id__user','student_id__id__department').get(student_id=student) - mess_option = mess_info.mess_option - context = { - 'menu': y, - 'mess_option': mess_option - } - if mess_option=='mess2': - return render_to_pdf('messModule/menudownloadable2.html', context) - else: - return render_to_pdf('messModule/menudownloadable1.html', context) - else: - context = { - 'menu': y, - 'mess_option': 'mess2' - } - return render_to_pdf('messModule/menudownloadable2.html', context) - # return HttpResponse(pdf, content_type='application/pdf') + context = { + 'menu': y, + 'mess_option': 'mess2', + 'date':str(today_g.date()) + } + return render_to_pdf('messModule/menudownloadable2.html', context) + # return HttpResponse(pdf, content_type='application/pdf') class MenuPDF1(View): @@ -979,7 +985,8 @@ def post(self, request, *args, **kwargs): y = Menu.objects.all() context = { 'menu': y, - 'mess_option': 'mess1' + 'mess_option': 'mess1', + 'date':str(today_g.date()) } return render_to_pdf('messModule/menudownloadable1.html', context) @@ -1002,6 +1009,7 @@ def post(self, request, *args, **kwargs): return HttpResponseRedirect('/mess') + def menu_change_request(request): """ This function is to request a change in menu @@ -1553,6 +1561,21 @@ def respond_to_reg(request): data = handle_dreg_response(request) return JsonResponse(data) +@csrf_exempt +@login_required +def respond_to_update_payment(request): + data = { + 'status': 1 + } + user = request.user + designation = HoldsDesignation.objects.select_related().filter(user=user) + for d in designation: + if d.designation.name == 'mess_manager': + data = handle_update_payment_response(request) + + return JsonResponse(data) + + def reg_request(request): @@ -1583,6 +1606,18 @@ def reg_request(request): return HttpResponseRedirect("/mess") +def update_payment(request): + user = request.user + extra_info = ExtraInfo.objects.select_related().get(user=user) + student = Student.objects.select_related('id','id__user','id__department').get(id=extra_info) + if request.method == 'POST': + form = UpdatePaymentRequest(request.POST, request.FILES) + + if form.is_valid(): + temp=form.save(commit=False) + temp.student_id=student + temp.save() + return HttpResponseRedirect("/mess") @csrf_exempt def update_bill_excel(request): diff --git a/FusionIIIT/applications/department/models.py b/FusionIIIT/applications/department/models.py index 8f7dba039..f8e1392db 100644 --- a/FusionIIIT/applications/department/models.py +++ b/FusionIIIT/applications/department/models.py @@ -11,7 +11,7 @@ class SpecialRequest(models.Model): brief = models.CharField(max_length=20, default='--') request_details = models.CharField(max_length=200) upload_request = models.FileField(blank=True) - status = models.CharField(max_length=50,default='Pending') + status = models.CharField(max_length=50, default='Pending') remarks = models.CharField(max_length=300, default="--") request_receiver = models.CharField(max_length=30, default="--") @@ -23,9 +23,11 @@ class Announcements(models.Model): maker_id = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) ann_date = models.DateTimeField(default="04-04-2021") message = models.CharField(max_length=200) - batch = models.CharField(max_length=40,default="Year-1") - department = models.CharField(max_length=40,default="ALL") + batch = models.CharField(max_length=40, default="Year-1") + department = models.CharField(max_length=40, default="ALL") programme = models.CharField(max_length=10) - upload_announcement = models.FileField(upload_to='department/upload_announcement', null=True, default=" ") + upload_announcement = models.FileField( + upload_to='department/upload_announcement', null=True, default=" ") + def __str__(self): return str(self.maker_id.user.username) diff --git a/FusionIIIT/applications/department/serializers.py b/FusionIIIT/applications/department/serializers.py new file mode 100644 index 000000000..eb65119c9 --- /dev/null +++ b/FusionIIIT/applications/department/serializers.py @@ -0,0 +1,12 @@ +from rest_framework import serializers +from .models import * + +class AnnouncementSerializer(serializers.ModelSerializer): + class Meta: + model=Announcements + fields="__all__" + +class SpecialRequestSerializer(serializers.ModelSerializer): + class Meta: + model=SpecialRequest + fields="__all__" \ No newline at end of file diff --git a/FusionIIIT/applications/department/static/department/js/function.js b/FusionIIIT/applications/department/static/department/js/function.js index 732b50473..bdf859afd 100644 --- a/FusionIIIT/applications/department/static/department/js/function.js +++ b/FusionIIIT/applications/department/static/department/js/function.js @@ -52,6 +52,7 @@ function request(event) var request_to = $('input[name="request_to"]').val(); var request_details = $('input[name="request_details"]').val(); + if(request_type=="" || request_to=="" || request_details =="" ) { alert("Please fill all the details!"); @@ -59,7 +60,8 @@ function request(event) } else { - event.preventDefault(); + // event.preventDefault(); + alert("please wait we are processing your request."); $.ajax({ type : 'POST', url : '.', @@ -73,11 +75,11 @@ function request(event) alert("Request successfully made!!"); setTimeout(function() { window.location.reload(); - }, 1500); + }, 0); }, error : function (data,err){ - alert('Request successfully made ... '); + alert('Request not created'); } }); diff --git a/FusionIIIT/applications/department/urls.py b/FusionIIIT/applications/department/urls.py index b7338374a..30a4adfd4 100644 --- a/FusionIIIT/applications/department/urls.py +++ b/FusionIIIT/applications/department/urls.py @@ -11,5 +11,12 @@ url(r'^staffView/$', views.staff_view, name='staff_view'), url(r'^All_Students/(?P[0-9]+)/$', views.all_students,name='all_students'), url(r'^approved/$', views.approved, name='approved'), - url(r'^deny/$', views.deny, name='deny') + url(r'^deny/$', views.deny, name='deny'), + + #api routes + url(r'^fetchAnnouncements/$', views.AnnouncementAPI.as_view(http_method_names=['get']), name='fetchAnnouncements'), + url(r'^addNewAnnouncement/$', views.AnnouncementAPI.as_view(http_method_names=['post']), name='addNewAnnouncement'), + url(r'^fetchRequest/$', views.SpecialRequestAPI.as_view(http_method_names=['get']), name='fetchRequest'), + url(r'^addNewRequest/$', views.SpecialRequestAPI.as_view(http_method_names=['post']), name='addNewRequest'), ] + \ No newline at end of file diff --git a/FusionIIIT/applications/department/views.py b/FusionIIIT/applications/department/views.py index f138c77db..3bd39ea80 100644 --- a/FusionIIIT/applications/department/views.py +++ b/FusionIIIT/applications/department/views.py @@ -21,6 +21,125 @@ from jsonschema import validate from jsonschema.exceptions import ValidationError +# API +from rest_framework.views import APIView +from rest_framework.response import Response +from .serializers import AnnouncementSerializer, SpecialRequestSerializer + +# Announcement Api class to handle request related to announcements +class AnnouncementAPI(APIView): + """ + overriding the get method + if request body is empty then all the announcements will be fetched + else body should contain id of the Announcement that is to be fetched + """ + + def get(self , request): + data = request.data + if data: + id = data['id'] + announcemets_obj = Announcements.objects.get(id=id) + serializer_obj = AnnouncementSerializer(announcemets_obj , partial=True) + return Response({'status':HttpResponse.status_code , 'payload':serializer_obj.data}) + else: + announcemets_obj = Announcements.objects.all() + serializer_obj = AnnouncementSerializer(announcemets_obj , many=True) + return Response({'status':HttpResponse.status_code , 'payload':serializer_obj.data}) + + """ + body should contain following attributes + batch, programme, department, message and upload_announcement + """ + def post(self , request): + data = request.data + batch = data['batch'] + programme = data['programme'] + department = data['department'] + message = data['message'] + upload_announcement = data['upload_announcement'] + ann_date = date.today() + + usrnm = get_object_or_404(User, username=request.user.username) + user_info = ExtraInfo.objects.all().select_related('user','department').get(user=usrnm) + + announcement_obj = Announcements( + maker_id=user_info, + batch=batch, + programme=programme, + message=message, + upload_announcement=upload_announcement, + department = department, + ann_date=ann_date + ) + if announcement_obj: + announcement_obj.save() + return Response({'status':HttpResponse.status_code , 'payload':'Announcement added successfully'}) + else: + return Response({'status':HttpResponse.status_code , 'payload':'Unable to add announcement'}) + +# SpecialRequest Api class to handle request related to Request +class SpecialRequestAPI(APIView): + """ + overriding the get method + if api-request body is empty then all the requests will be fetched + else body should contain id of the requests that is to be fetched + """ + def get(self , request): + data = request.data + if data: + id = data['id'] + specialRequest_obj = SpecialRequest.objects.get(id=id) + serializer_obj = SpecialRequestSerializer(specialRequest_obj , partial=True) + return Response({'status':HttpResponse.status_code , 'payload':serializer_obj.data}) + else: + specialRequest_obj = SpecialRequest.objects.all() + serializer_obj = SpecialRequestSerializer(specialRequest_obj , many=True) + return Response({'status':HttpResponse.status_code , 'payload':serializer_obj.data}) + + """ + body should contain following attributes + request_type, request_to and request_details + """ + def post(self , request): + data = request.data + request_type = data['request_type'] + request_to = data['request_to'] + request_details = data['request_details'] + request_date = date.today() + + usrnm = get_object_or_404(User, username=request.user.username) + user_info = ExtraInfo.objects.all().select_related('user','department').get(user=usrnm) + + specialRequest_obj = SpecialRequest( + request_maker=user_info, + request_date=request_date, + brief=request_type, + request_details=request_details, + status="Pending", + remarks="--", + request_receiver=request_to + ) + if specialRequest_obj: + specialRequest_obj.save() + return Response({'status':HttpResponse.status_code , 'payload':'Request added successfully'}) + else: + return Response({'status':HttpResponse.status_code , 'payload':'Unable to add Request'}) + """ + body should contain following attributes + id, remark and status + """ + def put(self, request): + data = request.data + request_id = data['id'] + remark = data['remark'] + status = data['status'] + + SpecialRequest.objects.filter(id=request_id).update(status=status, remarks=remark) + + return Response({'status':HttpResponse.status_code , 'payload':status}) + + + # Create your views here. @@ -120,15 +239,16 @@ def dep_main(request): request_to = request.POST.get('request_to', '') request_details = request.POST.get('request_details', '') request_date = date.today() - - obj_sprequest, created_object = SpecialRequest.objects.get_or_create(request_maker=user_info, - request_date=request_date, - brief=request_type, - request_details=request_details, - status="Pending", - remarks="--", - request_receiver=request_to - ) + + if request_type and request_to and request_details: + obj_sprequest, created_object = SpecialRequest.objects.get_or_create(request_maker=user_info, + request_date=request_date, + brief=request_type, + request_details=request_details, + status="Pending", + remarks="--", + request_receiver=request_to + ) if user_designation == "student": return render(request,"department/index.html", {"announcements":context, @@ -586,4 +706,6 @@ def deny(request): remark = request.POST.get('remark') SpecialRequest.objects.filter(id=request_id).update(status="Denied", remarks=remark) request.method = '' - return redirect('/dep/facView/') \ No newline at end of file + return redirect('/dep/facView/') + + diff --git a/FusionIIIT/applications/estate_module/static/estate_module/sidebar.js b/FusionIIIT/applications/estate_module/static/estate_module/sidebar.js index 462ebb004..449a7f5c8 100644 --- a/FusionIIIT/applications/estate_module/static/estate_module/sidebar.js +++ b/FusionIIIT/applications/estate_module/static/estate_module/sidebar.js @@ -36,7 +36,7 @@ $(document).ready(function () { .sidebar('setting', 'transition', 'overlay'); }); function newNotification() { - console.log('A new Notification added!'); + // console.log('A new Notification added!'); var notifactionName = document.createTextNode('Kanishka Munshi'); var notificationEmail = document.createTextNode('gmail@zlatan.com'); diff --git a/FusionIIIT/applications/examination/admin.py b/FusionIIIT/applications/examination/admin.py new file mode 100644 index 000000000..c44d2718b --- /dev/null +++ b/FusionIIIT/applications/examination/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin +from .models import hidden_grades,authentication,grade + +# Register your models here. + +admin.site.register(hidden_grades) +admin.site.register(authentication) +admin.site.register(grade) \ No newline at end of file diff --git a/FusionIIIT/applications/examination/api/serializers.py b/FusionIIIT/applications/examination/api/serializers.py new file mode 100644 index 000000000..5f3ca03b4 --- /dev/null +++ b/FusionIIIT/applications/examination/api/serializers.py @@ -0,0 +1,22 @@ +from rest_framework.authtoken.models import Token +from rest_framework import serializers +from applications.department.models import(Announcements) + + +from applications.academic_procedures.models import (course_registration) + +class CourseRegistrationSerializer(serializers.ModelSerializer): + class Meta: + model = course_registration + fields = ('__all__') + + +class AnnouncementsSerializer(serializers.ModelSerializer): + class Meta: + model = Announcements + fields = ['maker_id', 'ann_date', 'message', 'batch', 'department', 'programme', 'upload_announcement'] + +class AuthenticationSerializer(serializers.ModelSerializer): + class Meta: + model = Announcements + fields = '__all__' \ No newline at end of file diff --git a/FusionIIIT/applications/examination/api/urls.py b/FusionIIIT/applications/examination/api/urls.py new file mode 100644 index 000000000..15e37a1ab --- /dev/null +++ b/FusionIIIT/applications/examination/api/urls.py @@ -0,0 +1,51 @@ + +from django.conf.urls import url +from django.urls import path, include +from . import views + + +urlpatterns = [ + url(r'^registered_student_details/', views.fetch_student_details, name='fetch_student_details'), + + + url(r'^update_hidden_grade/', views.update_hidden_grade, name='update_hidden_grade'), + + url(r'^add_courses/' , views.add_courses , name = 'add_courses'), + + url(r'^update_authenticator/', views.update_authenticator, name='update_authenticator'), + + url(r'^check_all_authenticators/', views.check_all_authenticators, name='check_all_authenticators'), + + + url(r'^publish_grade/' , views.publish_grade , name='publish_grade'), + + url(r'^generate_transcript_form/' , views.generate_transcript_form , name = 'generate_transcript_form'), + +# Here error + url(r'^generate_transcript/' , views.generate_transcript , name = 'generate_transcript'), + + url(r'^getGrades/' , views.get_grade_for_course , name='get_grade_for_course'), + + url(r'^get_course_names/' , views.get_course_names , name='get_course_names'), + + url(r'^update_grades/' , views.update_grades , name='update_grades'), + + url(r'^fetch_roll_of_courses/' , views.fetch_roll_of_courses , name='fetch_roll_of_courses/'), + + url(r'^get_registered_students_roll_no/' , views.get_registered_students_roll_no , name='get_registered_students_roll_no/'), + + url(r'^get_auth_status/' , views.get_auth_status , name='get_auth_status'), + + url(r'^get_curriculum_values/' , views.get_curriculum_values , name='get_curriculum_values/'), + + + url(r'^announce/' , views.announce , name='announce/'), + + url(r'^submit_grades/$' , views.submit_grades , name='submit_grades/'), + + + # Delete this + + url(r'^add_student_details/' , views.add_student_details , name='add_student_details/'), + +] \ No newline at end of file diff --git a/FusionIIIT/applications/examination/api/views.py b/FusionIIIT/applications/examination/api/views.py new file mode 100644 index 000000000..1eab764ef --- /dev/null +++ b/FusionIIIT/applications/examination/api/views.py @@ -0,0 +1,1122 @@ +from django.db.models.query_utils import Q +from django.http import request,HttpResponse +from django.shortcuts import get_object_or_404, render, HttpResponse,redirect +from django.http import HttpResponse, HttpResponseRedirect +import itertools +from django.contrib import messages +from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User +from django.http import JsonResponse + +# from applications.academic_information.models import Student +from applications.globals.models import (DepartmentInfo, Designation, + ExtraInfo, Faculty, HoldsDesignation) + +from applications.academic_procedures.models import(course_registration , Register) +# from applications.academic_information.models import Course , Curriculum +from applications.programme_curriculum.models import Course , Curriculum +from applications.examination.models import(hidden_grades , authentication , grade) +from applications.department.models import(Announcements , SpecialRequest) +from applications.academic_information.models import(Student) +from applications.online_cms.models import(Student_grades) +from applications.globals.models import(ExtraInfo) +from . import serializers +from datetime import date +from rest_framework import status +from rest_framework.decorators import api_view +from rest_framework.response import Response + +from django.core.serializers import serialize +from django.http import JsonResponse +import json +from datetime import datetime + + + +@api_view(['GET', 'POST']) +def fetch_roll_of_courses(request): + """ + This function is used to fetch roll numbers of students registered for a specific course. + + @variables: + course_id - ID of the course for which roll numbers are being fetched + working_year - Year for which roll numbers are being fetched + obj - Queryset containing student registrations filtered by course ID and working year + obj_serialized - Serialized data of student registrations + resp - Dictionary containing the response data + """ + if request.method == 'POST': + # Retrieve the course_id and working_year from the request data + course_id = request.data.get('course_id') + working_year = request.data.get('working_year') + + if course_id is None: + return Response({'error': 'Course ID is required in the request parameters'}, status=status.HTTP_400_BAD_REQUEST) + + # Filter students by the provided course ID and working year + obj = course_registration.objects.filter(course_id=course_id , working_year=working_year) + + # Serialize the queryset + obj_serialized = serializers.CourseRegistrationSerializer(obj, many=True).data + + # Prepare the response data + resp = { + 'objt': obj_serialized + } + + # Return the response + return Response(data=resp, status=status.HTTP_200_OK) + + # Return a default response for GET requests + return Response({'message': 'Students'}, status=status.HTTP_201_CREATED) + + + + + +# @api_view(['GET', 'POST']) +# def fetch_student_details(request): +# """ +# This function is used to fetch student details based on course, semester, and batch. + +# @variables: +# course_id - ID of the course for which student details are being fetched +# semester_id - ID of the semester for which student details are being fetched +# batch - Batch for which student details are being fetched +# course_present - Queryset containing student grades filtered by course, semester, and batch +# data - Dictionary containing the data to be returned in JSON format +# """ +# if request.method == 'GET': +# # Retrieve query parameters +# course_id = int(request.query_params.get('course')) +# semester_id = int(request.query_params.get('semester')) +# year = int(request.query_params.get('batch')) +# print(course_id,semester_id,year) +# if course_id is None or semester_id is None or year is None: +# return JsonResponse({'error': 'Incomplete parameters provided'}, status=400) + +# # Filter student grades based on provided parameters +# course_present = Student_grades.objects.filter(course_id=course_id, semester=semester_id, year=year) + +# # Prepare data to return in JSON format +# data = { +# 'registrations': list(course_present.values()) # Convert queryset to list of dictionaries +# } + +# # Return JSON response +# return JsonResponse(data) + + + +@api_view(['GET']) +def fetch_student_details(request): + """ + This function is used to fetch student details based on course, semester, and batch. + """ + if request.method == 'GET': + # Retrieve query parameters + course_id = request.query_params.get('course') + semester_id = request.query_params.get('semester') + year = request.query_params.get('year') + + if course_id is None or semester_id is None or year is None: + return JsonResponse({'error': 'Incomplete parameters provided'}, status=400) + + # Convert parameters to appropriate types + try: + course_id = int(course_id) + semester_id = (semester_id) + year = year + except ValueError: + return JsonResponse({'error': 'Invalid parameter types'}, status=400) + + # Filter student grades based on provided parameters + course_present = Student_grades.objects.filter(course_id=course_id, semester=semester_id, year=year) + # Prepare data to return in JSON format + data = { + 'registrations': list(course_present.values()) # Convert queryset to list of dictionaries + } + + # Return JSON response + return JsonResponse(data) + else: + return JsonResponse({'error': 'Only GET requests are allowed'}, status=405) + + + + + +@api_view(['GET', 'POST']) +def add_student_details(request): + """ + This function is used to add student details to the database. + + @variables: + course_id - ID of the course for which student details are being added + semester - Semester for which student details are being added + year - Year for which student details are being added + roll_no - Roll number of the student + total_marks - Total marks obtained by the student + grade - Grade obtained by the student + batch - Batch for which student details are being added + student_data_list - List of dictionaries containing student details + success_count - Counter to keep track of successfully added students + """ + if request.method == 'POST': + # Extract list of student details from the request + student_data_list = request.data.get('students', []) + + # Validate data + if not student_data_list: + return Response({'error': 'No student data provided'}, status=400) + + # Counter for successfully added students + success_count = 0 + + # Loop through each student data and add to database + for student_data in student_data_list: + # Extract data for each student + course_id = student_data.get('course_id') + semester = student_data.get('semester') + year = student_data.get('year') + roll_no = student_data.get('roll_no') + total_marks = student_data.get('total_marks') + grade = student_data.get('grade') + batch = student_data.get('batch') + + # Validate data for each student + if not all([course_id, semester, year, roll_no, total_marks, grade, batch]): + continue # Skip this student if data is incomplete + + try: + # Get the Course instance + course_instance = Course.objects.get(pk=course_id) + + # Create new Student_grades instance + Student_grades.objects.create( + course_id=course_instance, + semester=semester, + year=year, + roll_no=roll_no, + total_marks=total_marks, + grade=grade, + batch=batch + ) + + success_count += 1 # Increment success count + except Course.DoesNotExist: + continue # Skip this student if course does not exist + + # Return response with success count + return Response({'success': f'{success_count} student(s) added successfully'}, status=201) + + + + + +@api_view(['GET', 'POST']) +def update_hidden_grade(request): + """ + This function is used to retrieve or update hidden grades for a course. + + @variables: + course_id - ID of the course for which hidden grades are being retrieved or updated + students - Queryset containing students registered for the course + students_serialized - Serialized data of students registered for the course + resp - Dictionary containing the response data + data_list - List of data for multiple students provided in the request body + student_id - ID of the student for which hidden grade is being updated + grade - Grade for the hidden grade being updated + hidden_grade_obj - Hidden grade object corresponding to the course and student + """ + if request.method == 'GET': + # Retrieve the course_id from the request query parameters + course_id = request.query_params.get('course_id') + + if course_id is None: + return JsonResponse({'error': 'Course ID is required in the request parameters'}, status=status.HTTP_400_BAD_REQUEST) + + # Filter students by the provided course ID + students = course_registration.objects.filter(course_id=course_id) + + # Serialize the queryset + students_serialized = serializers.CourseRegistrationSerializer(students, many=True).data + + # Prepare the response data + resp = { + 'students': students_serialized + } + + # Return the response + return JsonResponse(data=resp, status=status.HTTP_200_OK) + + elif request.method == 'POST': + # Extract course_id from query parameters + course_id = request.query_params.get('course_id') + + # Extract data for multiple students + data_list = request.data + + # Check if course_id is provided + if not course_id: + return JsonResponse({'error': 'Course ID is required in the request parameters'}, status=status.HTTP_400_BAD_REQUEST) + + # Process each student in the list + for data in data_list: + student_id = data.get('student_id') + grade = data.get('grade') + + # Check if student_id and grade are provided + if not all([student_id, grade]): + return JsonResponse({'error': 'Incomplete data provided for one of the students'}, status=status.HTTP_400_BAD_REQUEST) + + # Check if the entry already exists + try: + hidden_grade_obj = hidden_grades.objects.get(course_id=course_id, student_id=student_id) + # If exists, update the grade + hidden_grade_obj.grade = grade + hidden_grade_obj.save() + except hidden_grades.DoesNotExist: + # If doesn't exist, create a new entry + hidden_grade_obj = hidden_grades.objects.create( + course_id=course_id, + student_id=student_id, + grade=grade + ) + + return JsonResponse({'message': 'Hidden grades updated successfully'}, status=status.HTTP_201_CREATED) + + else: + return JsonResponse({'error': 'Unsupported method'}, status=status.HTTP_405_METHOD_NOT_ALLOWED) + + + + + +@api_view(['GET']) +def check_all_authenticators(request): + """ + This function is used to check if all authenticators are verified for a specific course and year. + + @variables: + course_id - ID of the course for which all authenticators are being checked + year - Year for which all authenticators are being checked + auth_objects - Queryset containing authentication objects filtered by year + """ + if request.method == 'GET': + # Extract year and course ID from the request + course_id = int(request.query_params.get('course_id')) + year = request.query_params.get('year') + + # Validate year format + try: + datetime.strptime(year, '%Y') + except ValueError: + return Response({'error': 'Invalid year format. Please use YYYY format.'}, status=status.HTTP_400_BAD_REQUEST) + + # Retrieve all authentication objects for the given year and course ID + auth_objects = authentication.objects.filter(year__year=year ,course_id = course_id) + + if not auth_objects.exists(): + return Response({'error': 'No authentication entries found for the provided year.'}, status=status.HTTP_404_NOT_FOUND) + + # Check if all three authenticators are verified for all authentication objects + for auth_object in auth_objects: + if not (auth_object.authenticator_1 and auth_object.authenticator_2 and auth_object.authenticator_3): + return Response({'all_authenticated': False}, status=status.HTTP_200_OK) + + return Response({'all_authenticated': True}, status=status.HTTP_200_OK) + + + + + + +@api_view(['PATCH']) +def update_authenticator(request): + """ + This function is used to update the status of an authenticator for a specific course and year. + + @variables: + course_id - ID of the course for which authenticator status is being updated + year - Year for which authenticator status is being updated + authenticator_number - Number representing the authenticator whose status is being updated + auth_objects - Queryset containing authentication objects filtered by year and course_id + auth_object - Authentication object for the given year and course_id + """ + if request.method == 'PATCH': + # Extract course id, year, and authenticator number from the request + course_id = int(request.data.get('course_id')) + year = request.data.get('year')[:4] + authenticator_number = int(request.data.get('authenticator_number')) + + # Validate year format + print(course_id,year,authenticator_number) + try: + datetime.strptime(year, '%Y') + except ValueError: + return Response({'error': 'Invalid year format. Please use YYYY format.'}, status=status.HTTP_400_BAD_REQUEST) + + # Retrieve all authentication objects for the given year and course id + auth_objects = authentication.objects.filter(year__year=year ,course_id=course_id) + print(authentication.objects.all()[0]) + if not auth_objects.exists(): + return Response({'error': 'No authentication entries found for the provided year and course id.'}, status=status.HTTP_404_NOT_FOUND) + + # Toggle the specified authenticator for each authentication object + for auth_object in auth_objects: + if authenticator_number == 1: + auth_object.authenticator_1 = not auth_object.authenticator_1 + elif authenticator_number == 2: + auth_object.authenticator_2 = not auth_object.authenticator_2 + elif authenticator_number == 3: + auth_object.authenticator_3 = not auth_object.authenticator_3 + else: + return Response({'error': 'Invalid authenticator number'}, status=status.HTTP_400_BAD_REQUEST) + + auth_object.save() + + return Response({'message': f'Authenticator {authenticator_number} toggled successfully for the year {year} and course id {course_id}'}, status=status.HTTP_200_OK) + + + + + +@api_view(['GET','POST']) +def get_auth_status(request): + """ + This function is used to get the authentication status for a specific course and year. + + @variables: + course_id - ID of the course for which authentication status is being retrieved + year - Year for which authentication status is being retrieved + auth_objects - Queryset containing authentication objects filtered by year and course_id + auth_object - Authentication object for the given year and course_id + auth_status - Dictionary containing the authentication status for authenticators 1, 2, and 3 + """ + try: + course_id = int(request.data.get('course_id')) + year = request.data.get('year')[:4] + print(course_id, year) + + # Use filter instead of get to handle multiple objects + auth_objects = authentication.objects.filter(year__year=year, course_id=course_id) + + if auth_objects.exists(): + auth_object = auth_objects.first() # Use first() to get the first object + auth_status = { + 'authenticator1': auth_object.authenticator_1, + 'authenticator2': auth_object.authenticator_2, + 'authenticator3': auth_object.authenticator_3 + } + print(auth_status) + return JsonResponse(auth_status, status=status.HTTP_200_OK) + else: + return Response({'error': 'No authentication entries found for the provided year and course id.'}, status=status.HTTP_404_NOT_FOUND) + except Exception as e: + return JsonResponse({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + + + + + +@api_view(['GET']) +def publish_grade(request): + """ + This function is used to publish grades for a course. + + @variables: + course_id - ID of the course for which grades are being published + auth_obj - Authentication object corresponding to the course_id + hidden_grades_list - List of hidden grades for the given course + hidden_grade - Hidden grade object in the hidden_grades_list + existing_final_grade - Existing final grade object for the student and course + """ + course_id = request.GET.get('course_id') + auth_obj = authentication.objects.filter(course=course_id).first() + + if auth_obj: + if auth_obj.authenticator_1 and auth_obj.authenticator_2 and auth_obj.authenticator_3: + # Get hidden grades for the given course + hidden_grades_list = hidden_grades.objects.filter(course_id=course_id) + + # Update final grades table + for hidden_grade in hidden_grades_list: + # Check if final grade already exists + existing_final_grade = grade.objects.filter( + student_id=hidden_grade.student_id, + course_id=hidden_grade.course_id, + semester_id=hidden_grade.semester_id + ).first() + + if not existing_final_grade: + # Create final grade only if it doesn't already exist + grade.objects.create( + student_id=hidden_grade.student_id, + course_id=hidden_grade.course_id, + semester_id=hidden_grade.semester_id, + grade=hidden_grade.grade + ) + + return JsonResponse({'message': 'Grades are ready to publish'}, status=200) + else: + return JsonResponse({'error': 'Not all authenticators are True'}, status=400) + else: + return JsonResponse({'error': 'Authentication object not present'}, status=404) + + + + + +@api_view(['POST', 'GET']) +def generate_transcript_form(request): + """ + This function is used to generate a transcript form for students. + + @variables: + programme - Programme selected for filtering students + batch - Batch selected for filtering students + specialization - Specialization selected for filtering students + students - Queryset containing filtered students based on programme, batch, and specialization + serialized_students - Serialized JSON string representing the filtered students + students_data - Python object obtained by deserializing the JSON string + programmes - List of distinct programme values from Student objects + specializations - List of distinct specialization values from Student objects + batches - List of distinct batch values from Student objects + context - Dictionary containing programmes, batches, and specializations for rendering the form + """ + if request.method == 'POST': + programme = request.data.get('programme') + batch = request.data.get('batch') + specialization = request.data.get('specialization') + print(programme, batch, specialization) + + if specialization is None: + students = Student.objects.filter(programme=programme, batch=batch) + else: + students = Student.objects.filter(programme=programme, batch=batch, specialization=specialization) + + # Serialize QuerySet to JSON string + serialized_students = serialize('json', students) + print(serialized_students) + # Deserialize JSON string to Python object + students_data = json.loads(serialized_students) + + # Pass the deserialized data to JsonResponse + return JsonResponse({'students': students_data}) + else: + programmes = Student.objects.values_list('programme', flat=True).distinct() + specializations = Student.objects.exclude(specialization__isnull=True).values_list('specialization', flat=True).distinct() + batches = Student.objects.values_list('batch', flat=True).distinct() + context = { + 'programmes': list(programmes), + 'batches': list(batches), + 'specializations': list(specializations), + } + + return JsonResponse(context) + + + + + + + +# @api_view(['POST', 'GET']) +# def generate_transcript(request): +# """ +# This function is used to generate a transcript for a student. + +# @variables: +# student_id - ID of the student for whom the transcript is being generated +# semester - Semester for which the transcript is being generated +# student_grades - Queryset containing grades for the student in the specified semester +# transcript_data - List to hold transcript data for each course +# grade - Grade object for each course in the specified semester +# course_info - Dictionary containing course information to be included in the transcript +# student_info - Information about the student, such as CPI (Cumulative Performance Index) +# cpi - Cumulative Performance Index of the student +# course_detail - Details of the course obtained from Curriculum +# """ +# if request.method == 'POST': +# student_id = request.data.get('student_id') +# semester = request.data.get('semester') + +# # Fetch the courses and grades for the student in the specified semester +# student_grades = Student_grades.objects.filter(roll_no=student_id, semester=semester) +# print(student_id,semester) + +# total_course_registered = Student_grades.objects.filter( +# roll_no=student_id, semester__lte=semester) + +# # Prepare data to be returned +# transcript_data = [] +# for grade in student_grades: +# # Access fields of each object +# course_info = { +# 'course_id': grade.course_id.name, +# 'total_marks': grade.total_marks, +# 'grade': grade.grade, +# 'batch': grade.batch, +# } + +# student_info = Student.objects.filter(id=student_id).first() + +# ##### Student Grades fetch all courses before semester find spi and update cpi in student table +# print(student_info.cpi) +# if student_info: +# cpi = student_info.cpi +# course_info['cpi'] = cpi +# else: +# # Handle case where student info is not found +# print("cpi is not there") +# pass +# # Fetch course details from Curriculum +# course_detail = Course.objects.filter(id=grade.course_id.id).first() +# if course_detail: +# # Include additional attributes +# course_info['course_code'] = course_detail.code +# course_info['credits'] = course_detail.credit +# else: +# # If course details not found, assign default values +# course_info['course_code'] = "Unknown" +# course_info['credits'] = 0 + +# transcript_data.append(course_info) + +# return JsonResponse({'transcript': transcript_data}) +# else: +# return JsonResponse({'error': 'Invalid request method'}) + + + + +@api_view(['POST', 'GET']) +def generate_transcript(request): + """ + This function is used to generate a transcript for a student. + + @variables: + student_id - ID of the student for whom the transcript is being generated + semester - Semester for which the transcript is being generated + student_grades - Queryset containing grades for the student in the specified semester + transcript_data - List to hold transcript data for each course + grade - Grade object for each course in the specified semester + course_info - Dictionary containing course information to be included in the transcript + student_info - Information about the student, such as CPI (Cumulative Performance Index) + cpi - Cumulative Performance Index of the student + course_detail - Details of the course obtained from Curriculum + """ + if request.method == 'POST': + student_id = request.data.get('student_id') + semester = request.data.get('semester') + + # Fetch the courses and grades for the student in the specified semester + student_grades = Student_grades.objects.filter(roll_no=student_id, semester=semester) + print(student_id, semester) + + # Fetch all courses registered by the student up to the specified semester + total_courses_registered = Student_grades.objects.filter( + roll_no=student_id, semester__lte=semester + ).values_list('course_id', flat=True).distinct().count() + + # Prepare data to be returned + transcript_data = [] + for grade in student_grades: + # Access fields of each object + course_info = { + 'course_id': grade.course_id.name, + 'total_marks': grade.total_marks, + 'grade': grade.grade, + 'batch': grade.batch, + } + + student_info = Student.objects.filter(id=student_id).first() + + ##### Student Grades fetch all courses before semester find spi and update cpi in student table + print(student_info.cpi) + if student_info: + cpi = student_info.cpi + course_info['cpi'] = cpi + else: + # Handle case where student info is not found + print("cpi is not there") + pass + # Fetch course details from Curriculum + course_detail = Course.objects.filter(id=grade.course_id.id).first() + if course_detail: + # Include additional attributes + course_info['course_code'] = course_detail.code + course_info['credits'] = course_detail.credit + else: + # If course details not found, assign default values + course_info['course_code'] = "Unknown" + course_info['credits'] = 0 + + transcript_data.append(course_info) + + return JsonResponse({'transcript': transcript_data, 'total_courses_registered': total_courses_registered}) + else: + return JsonResponse({'error': 'Invalid request method'}) + + + + + + + + +# @api_view(['POST', 'GET']) +# def get_curriculum_values(request): +# """ +# This function is used to retrieve curriculum values for a given course. + +# @variables: +# course_id - ID of the course for which curriculum values are being retrieved +# curriculum_values - Curriculum object corresponding to the course_id +# """ +# try: +# course_id = request.data.get('course_id') + +# curriculum_values = Course.objects.get(id=course_id) +# print(Curriculum.objects.all()) +# return JsonResponse({ +# 'course_code': curriculum_values.course_code, +# 'credits': curriculum_values.credits, +# 'course_type': curriculum_values.course_type, +# 'programme': curriculum_values.programme, +# 'branch': curriculum_values.branch, +# 'sem': curriculum_values.sem, +# 'optional': curriculum_values.optional, +# 'floated': curriculum_values.floated +# }) +# except Curriculum.DoesNotExist: +# print(Curriculum.objects.all()) +# return JsonResponse({ +# 'course_code': 'Unknown', +# 'credits': 0, +# 'course_type': 'Unknown', +# 'programme': 'Unknown', +# 'branch': 'Unknown', +# 'sem': 0, +# 'optional': False, +# 'floated': False +# }) + + + + +@api_view(['POST', 'GET']) +def get_curriculum_values(request): + """ + This function is used to retrieve curriculum values for a given course. + + @variables: + course_id - ID of the course for which curriculum values are being retrieved + curriculum_values - Course object corresponding to the course_id + """ + try: + course_id = request.data.get('course_id') + + course_values = Course.objects.get(id=course_id) + + return JsonResponse({ + 'code': course_values.code, + 'name': course_values.name, + 'credit': course_values.credit, + 'lecture_hours': course_values.lecture_hours, + 'tutorial_hours': course_values.tutorial_hours, + 'pratical_hours': course_values.pratical_hours, + 'discussion_hours': course_values.discussion_hours, + 'project_hours': course_values.project_hours, + 'pre_requisits': course_values.pre_requisits, + # Add other fields as needed + }) + except Course.DoesNotExist: + return JsonResponse({ + 'error': 'Course not found for the given ID', + }) + + + + +@api_view(['POST', 'GET']) +def get_grade_for_course(course_id, batch, year, semester_id, selected_student_id): + """ + This function is used to retrieve the grade for a specific course, batch, year, semester, and student. + + @parameters: + course_id - ID of the course for which grade is being retrieved + batch - Batch for which grade is being retrieved + year - Year for which grade is being retrieved + semester_id - ID of the semester for which grade is being retrieved + selected_student_id - ID of the student for whom grade is being retrieved + + @variables: + grades - Queryset containing grades filtered by course_id, batch, year, semester_id, and selected_student_id + """ + # Filter Student_grades based on course_id, batch, year, semester_id, and selected_student_id + grades = Student_grades.objects.filter( + course_id=course_id, + batch=batch, + roll_no=selected_student_id, + year=year, + semester=semester_id, + ) + + # Assuming only one grade is expected for a given combination of parameters + if grades.exists(): + return grades.first().grade + else: + return None # Return None if no grade is found + + + + + +@api_view(['POST', 'GET']) +def get_course_names(request): + """ + This function is used to retrieve course names and IDs. + + @variables: + courses - Queryset containing all Course objects + course_data - List of dictionaries containing course IDs and names + """ + if request.method == 'GET': + # Retrieve all course names and IDs + courses = Course.objects.all() + course_data = [{'id': course.id, 'name': course.name} for course in courses] + + if not course_data: + return JsonResponse({'error': 'No courses found.'}, status=status.HTTP_404_NOT_FOUND) + + return JsonResponse({'courses': course_data}, status=status.HTTP_200_OK) + + + + + +@api_view(['POST']) +def add_courses(request): + """ + This function is used to add courses along with authentication objects. + + @variables: + courses - List of courses received from the request body + created_authentications - List to hold the created authentication objects + course_instance - Instance of the Course model corresponding to the course ID + authentication_object - Authentication object created for the course + serialized_data - Serialized data of the created authentication objects + """ + if request.method == 'POST': + # Get the list of courses from the request body + courses = request.data.get('courses', []) + + # Create a list to hold the created authentication objects + created_authentications = [] + + # Iterate over the list of courses and create an authentication object for each + for course in courses: + try: + # Get the Course instance corresponding to the course ID + course_instance = Course.objects.get(id=course['id']) + + # Create a new authentication object with the Course instance + authentication_object = authentication.objects.create(course_id=course_instance) + + # Append the created authentication object to the list + created_authentications.append(authentication_object) + except Exception as e: + # Handle any errors that occur during object creation + # You can choose to log the error or handle it based on your requirements + print(f"Error creating authentication object for course ID {course['id']}: {e}") + + # Convert the created authentication objects to dictionaries + serialized_data = [{'id': obj.id, 'authenticator_1': obj.authenticator_1, 'authenticator_2': obj.authenticator_2, 'authenticator_3': obj.authenticator_3, 'year': obj.year.year, 'course_id': obj.course_id_id} for obj in created_authentications] + + # Return a JSON response with the serialized data + return JsonResponse(serialized_data, status=201, safe=False) + + + + + +@api_view(['PATCH']) +def update_grades(request): + """ + This function is used to update grades for students. + + @variables: + updated_students_data - JSON data containing updated grades for students + roll_no - Roll number of the student + course_id - ID of the course for which grades are being updated + semester_id - ID of the semester for which grades are being updated + year - Year for which grades are being updated + grade - Updated grade received by the student + total_marks - Updated total marks obtained by the student + student_grade_obj - Student grades object to be updated or created + created - Flag indicating whether a new student grade object was created + """ + if request.method == 'PATCH': + try: + # Extract the updated student data from the request body + updated_students_data = json.loads(request.body) + print(updated_students_data) + # Iterate over each updated student data + for student_data in updated_students_data: + roll_no = student_data.get('roll_no') + course_id = int(student_data.get('course_id')) + semester_id = student_data.get('semester_id') + year = int(student_data.get('year')) + grade = student_data.get('grade') + total_marks = student_data.get('total_marks') + + # Check if all necessary data is provided + if not (roll_no and course_id and semester_id and year and grade and total_marks): + return JsonResponse({'error': 'Incomplete data provided'}, status=400) + + # Update the student grade + student_grade_obj, created = Student_grades.objects.update_or_create( + roll_no=roll_no, + course_id=course_id, + semester=semester_id, + year=year, + defaults={'grade': grade, 'total_marks': total_marks} + ) + + return JsonResponse({'message': 'Student grades updated successfully'}, status=200) + + except json.JSONDecodeError as e: + return JsonResponse({'error': 'Invalid JSON format'}, status=400) + + except KeyError as e: + return JsonResponse({'error': 'Missing required field: ' + str(e)}, status=400) + + except Exception as e: + return JsonResponse({'error': str(e)}, status=500) + + + + + +@api_view(['PATCH']) +def submit_grades(request): + """ + This function is used to submit grades for students. + + @variables: + updated_students_data - JSON data containing updated grades for students + roll_no - Roll number of the student + course_id - ID of the course for which grades are being submitted + semester_id - ID of the semester for which grades are being submitted + year - Year for which grades are being submitted + grade - Grade received by the student (defaulted to 'NA') + total_marks - Total marks obtained by the student (defaulted to 0) + course - Course object corresponding to course_id + student_grade_obj - Student grades object to be updated or created + created - Flag indicating whether a new student grade object was created + """ + if request.method == 'PATCH': + try: + updated_students_data = json.loads(request.body) + print(updated_students_data) + + for student_data in updated_students_data: + roll_no = student_data.get('roll_no') + course_id = int(student_data.get('course_id')) + semester_id = student_data.get('semester_id') + year = int(student_data.get('year')) + grade = student_data.get('grade','NA') + total_marks = student_data.get('total_marks','0') + + if not (roll_no and course_id and semester_id and year and grade and total_marks): + return JsonResponse({'error': 'Incomplete data provided'}, status=400) + + # Retrieve the Course object based on course_id + course = Course.objects.get(id=course_id) + + # Update or create the student grade object + student_grade_obj, created = Student_grades.objects.update_or_create( + roll_no=roll_no, + course_id=course, # Use the Course object instead of course_id + semester=semester_id, + year=year, + defaults={'grade': grade, 'total_marks': total_marks} + ) + + return JsonResponse({'message': 'Student grades updated successfully'}, status=200) + + except json.JSONDecodeError as e: + return JsonResponse({'error': 'Invalid JSON format'}, status=400) + + except KeyError as e: + return JsonResponse({'error': 'Missing required field: ' + str(e)}, status=400) + + except Exception as e: + return JsonResponse({'error': str(e)}, status=500) + + + + +@api_view(['POST', 'GET']) +def get_registered_students_roll_no(request): + """ + This function is used to retrieve registered students' information for a particular course and year. + + @variables: + course_id - ID of the course for which registrations are being retrieved + year - Year for which registrations are being retrieved + registrations - Queryset containing course registrations filtered by course_id and year + data - List to store serialized student data + student_data - Dictionary to store individual student information + student_grade - Grade and total marks of the student for the specified course + """ + # Retrieve the course_id and year from the request query parameters + course_id = request.data.get('course_id') + year = request.data.get('year') + + if not course_id or not year: + return JsonResponse({'error': 'Course ID and year are required'}, status=400) + + try: + # Filter course registrations by course_id and year + registrations = course_registration.objects.filter(course_id=course_id, working_year=year) + # registrations = Register.objects.filter(curr_id=course_id) + print(registrations) + # Serialize the queryset + data = [] + for registration in registrations: + # Access fields of the related Student instance + print(registration) + student_data = { + 'roll_no': registration.student_id.id.user.username, + 'name': registration.student_id.id.user.first_name, # Assuming first_name is a field of the User model + 'email': registration.student_id.id.user.email, # Assuming email is a field of the User model + # Include other relevant fields from the Student model + 'grade': None, + 'marks': None + } + + # Retrieve grades and total marks for the student + try: + print(registration.student_id.id , course_id) + student_grade = Student_grades.objects.get(roll_no=student_data['roll_no'],course_id=course_id) + student_data['grade'] = student_grade.grade + student_data['marks'] = student_grade.total_marks + + # print(student_grade) + except Student_grades.DoesNotExist: + print("Didn't find grades for roll_no:", registration.student_id.id, "and course_id:", course_id) + pass + # print(student_data) + data.append(student_data) + # Return the serialized data in the response + return JsonResponse({'registrations': data}, status=200) + except Exception as e: + return JsonResponse({'error': str(e)}, status=500) + + + + + +@api_view(['POST', 'GET']) +def get_to_request(username): + """ + This function is used to get requests for the receiver + + @variables: + req - Contains request queryset + + """ + req = SpecialRequest.objects.filter(request_receiver=username) + return req + + + + +@api_view(['POST', 'GET']) +def browse_announcements(): + """ + This function is used to browse Announcements Department-Wise + made by different faculties and admin. + + @variables: + cse_ann - Stores CSE Department Announcements + ece_ann - Stores ECE Department Announcements + me_ann - Stores ME Department Announcements + sm_ann - Stores SM Department Announcements + all_ann - Stores Announcements intended for all Departments + context - Dictionary for storing all above data + + """ + cse_ann = Announcements.objects.filter(department="CSE") + ece_ann = Announcements.objects.filter(department="ECE") + me_ann = Announcements.objects.filter(department="ME") + sm_ann = Announcements.objects.filter(department="SM") + all_ann = Announcements.objects.filter(department="ALL") + + context = { + "cse" : cse_ann, + "ece" : ece_ann, + "me" : me_ann, + "sm" : sm_ann, + "all" : all_ann + } + + return context + + + + +@api_view(['POST', 'GET']) +def announce(request): + """ + This function is used to make announcements by faculty or admin. + + @variables: + usrnm - Current user's username + user_info - Extra information of the current user + ann_maker_id - ID of the user making the announcement + batch - Batch for which the announcement is intended + programme - Programme for which the announcement is intended + message - Content of the announcement + upload_announcement - File uploaded with the announcement + department - Department for which the announcement is intended + ann_date - Date of the announcement + getstudents - All users with extra information + + """ + usrnm = get_object_or_404(User, username=request.user.username) + user_info = ExtraInfo.objects.all().select_related('user', 'department').filter(user=usrnm).first() + ann_maker_id = user_info.id + + if request.method == 'POST': + batch = request.data.get('batch', '') + programme = request.data.get('programme', '') + message = request.data.get('announcement', '') + upload_announcement = request.FILES.get('upload_announcement') + department = request.data.get('department', 'ALL') + ann_date = datetime.today() + user_info = ExtraInfo.objects.all().select_related('user', 'department').get(id=ann_maker_id) + getstudents = ExtraInfo.objects.select_related('user') + + obj1, created = Announcements.objects.get_or_create(maker_id=user_info, + batch=batch, + programme=programme, + message=message, + upload_announcement=upload_announcement, + department=department, + ann_date=ann_date) + + response_data = { + 'status': 'success', + 'message': 'Announcement successfully created' + } + return JsonResponse(response_data) + else: + response_data = { + 'error': 'Invalid request method' + } + return JsonResponse(response_data, status=405) diff --git a/FusionIIIT/applications/examination/apps.py b/FusionIIIT/applications/examination/apps.py new file mode 100644 index 000000000..4ea19472a --- /dev/null +++ b/FusionIIIT/applications/examination/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ExaminationConfig(AppConfig): + name = 'examination' diff --git a/FusionIIIT/applications/examination/forms.py b/FusionIIIT/applications/examination/forms.py new file mode 100644 index 000000000..30314d400 --- /dev/null +++ b/FusionIIIT/applications/examination/forms.py @@ -0,0 +1,4 @@ +from django import forms + +class StudentGradeForm(forms.Form): + grades = forms.CharField(widget=forms.MultipleHiddenInput) diff --git a/FusionIIIT/applications/examination/migrations/0001_initial.py b/FusionIIIT/applications/examination/migrations/0001_initial.py new file mode 100644 index 000000000..9cbd0f6ac --- /dev/null +++ b/FusionIIIT/applications/examination/migrations/0001_initial.py @@ -0,0 +1,48 @@ +# Generated by Django 3.1.5 on 2024-04-18 13:13 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('academic_information', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='grade', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('student', models.CharField(max_length=20)), + ('curriculum', models.CharField(max_length=50)), + ('semester_id', models.CharField(default='', max_length=10)), + ('grade', models.CharField(default='B', max_length=5)), + ], + ), + migrations.CreateModel( + name='hidden_grades', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('student_id', models.CharField(max_length=20)), + ('course_id', models.CharField(max_length=50)), + ('semester_id', models.CharField(max_length=10)), + ('grade', models.CharField(max_length=5)), + ], + ), + migrations.CreateModel( + name='authentication', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('authenticator_1', models.BooleanField(default=False)), + ('authenticator_2', models.BooleanField(default=False)), + ('authenticator_3', models.BooleanField(default=False)), + ('year', models.DateField(auto_now_add=True)), + ('course_year', models.IntegerField(default=2024)), + ('course_id', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='academic_information.course')), + ], + ), + ] diff --git a/FusionIIIT/media/New_Text_Document_2.txt b/FusionIIIT/applications/examination/migrations/__init__.py similarity index 100% rename from FusionIIIT/media/New_Text_Document_2.txt rename to FusionIIIT/applications/examination/migrations/__init__.py diff --git a/FusionIIIT/applications/examination/models.py b/FusionIIIT/applications/examination/models.py new file mode 100644 index 000000000..5cdced32c --- /dev/null +++ b/FusionIIIT/applications/examination/models.py @@ -0,0 +1,39 @@ +from django.db import models +from applications.academic_procedures.models import (course_registration) +from applications.online_cms.models import (Student_grades) +from applications.academic_information.models import Course +from applications.programme_curriculum.models import Course as Courses, CourseInstructor +# Create your models here. + + +class hidden_grades(models.Model): + student_id = models.CharField(max_length=20) + course_id = models.CharField(max_length=50) + semester_id = models.CharField(max_length=10) + grade = models.CharField(max_length=5) + + def __str__(self): + return f"{self.student_id}, {self.course_id}" + + +class authentication(models.Model): + authenticator_1 = models.BooleanField(default=False) + authenticator_2 = models.BooleanField(default=False) + authenticator_3 = models.BooleanField(default=False) + year = models.DateField(auto_now_add=True) + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE, default=1) + course_year = models.IntegerField(default=2024) + + @property + def working_year(self): + return self.year.year + + def __str__(self): + return f"{self.course_id} , {self.course_year}" + + +class grade(models.Model): + student = models.CharField(max_length=20) + curriculum = models.CharField(max_length=50) + semester_id = models.CharField(max_length=10, default='') + grade = models.CharField(max_length=5, default="B") diff --git a/FusionIIIT/applications/examination/tests.py b/FusionIIIT/applications/examination/tests.py new file mode 100644 index 000000000..7ce503c2d --- /dev/null +++ b/FusionIIIT/applications/examination/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/FusionIIIT/applications/examination/urls.py b/FusionIIIT/applications/examination/urls.py new file mode 100644 index 000000000..83789d49e --- /dev/null +++ b/FusionIIIT/applications/examination/urls.py @@ -0,0 +1,57 @@ + +from django.conf.urls import url +from django.urls import path, include +from . import views +from django.contrib import admin +from .views import update_authentication +from .views import DownloadExcelView, updateGrades + +app_name = 'examination' + +urlpatterns = [ + url(r'^api/', include('applications.examination.api.urls')), + url(r'^$', views.exam, name='exam'), + + + url(r'submit/', views.submit, name='submit'),#old + url(r'verify/', views.verify, name='verify'),#old + url(r'publish/', views.publish, name='publish'),#old + url(r'notReady_publish/', views.notReady_publish, name='notReady_publish'),#old + url(r'timetable/', views.timetable, name='timetable'),#old + # entering and updataing grade + path('entergrades/', views.entergrades, name='entergrades'),#old + path('update_hidden_grades_multiple/', views.Updatehidden_gradesMultipleView.as_view(), + name='update_hidden_grades_multiple'),#old + path('verifygrades/', views.verifygrades, name='verifygrades'),#old + path('update_hidden_grades_multiple/', views.Updatehidden_gradesMultipleView.as_view(), + name='update_hidden_grades_multiple'),#old + path('submit_hidden_grades_multiple/', views.Submithidden_gradesMultipleView.as_view(), + name='submit_hidden_grades_multiple'),#old + path('download_excel/', DownloadExcelView.as_view(), name='download_excel'),#old + + #new + url(r'submitGrades/', views.submitGrades, name='submitGrades'),#new + url(r'submitEntergrades/', views.submitEntergrades, name='submitEntergrades'),#new + path('submitEntergradesStoring/', views.submitEntergradesStoring.as_view(),#new + name='submitEntergradesStoring'), + #new + url(r'updateGrades/', views.updateGrades, name='updateGrades'),#new + path('updateEntergrades/', views.updateEntergrades, name='updateEntergrades'),#new + path('moderate_student_grades/', views.moderate_student_grades.as_view(),#new + name='moderate_student_grades'), + # authenticate new + path('authenticate/', views.authenticate, name='authenticate'), #new + path('authenticategrades/', views.authenticategrades, + name='authenticategrades'),#new + path('update_authentication/', update_authentication.as_view(), + name='update_authentication'),#new + # generate transcript new + path('generate_transcript/', views.generate_transcript, + name='generate_transcript'), #new + path('generate_transcript_form/', views.generate_transcript_form, + name='generate_transcript_form'),#new + # Announcement + url(r'announcement/', views.announcement, name='announcement'),#new + + +] diff --git a/FusionIIIT/applications/examination/views.py b/FusionIIIT/applications/examination/views.py new file mode 100644 index 000000000..6e7bb47a6 --- /dev/null +++ b/FusionIIIT/applications/examination/views.py @@ -0,0 +1,752 @@ +from notifications.signals import notify +from django.views import View +from django.views.generic import View +from django.http import HttpResponse +import csv +from django.db.models import IntegerField +from django.db.models.functions import Cast +from django.db.models.query_utils import Q +from django.http import request, HttpResponse +from django.shortcuts import get_object_or_404, render, HttpResponse, redirect +from django.http import HttpResponse, HttpResponseRedirect +import itertools +from django.contrib import messages +from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User +from datetime import date +import requests +from django.db.models import Q +from django.shortcuts import get_object_or_404, render, redirect +from django.contrib.auth.models import User +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger +from applications.academic_information.models import Spi, Student, Curriculum +from applications.globals.models import (Designation, ExtraInfo, + HoldsDesignation, Faculty) +from applications.eis.models import (faculty_about, emp_research_projects) +from applications.academic_information.models import Course +from applications.academic_procedures.models import course_registration, Register +from applications.programme_curriculum.filters import CourseFilter +from notification.views import examination_notif +from applications.department.models import SpecialRequest, Announcements +from applications.globals.models import (DepartmentInfo, Designation, + ExtraInfo, Faculty, HoldsDesignation) +from jsonschema import validate +from jsonschema.exceptions import ValidationError +from django.shortcuts import render, redirect, HttpResponse +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status +from .models import hidden_grades +from .forms import StudentGradeForm +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status +from .models import hidden_grades, authentication +from rest_framework.permissions import AllowAny +from applications.online_cms.models import (Student_grades) + +from applications.programme_curriculum.models import Course as Courses, CourseInstructor + + +@login_required(login_url='/accounts/login') +def exam(request): + """ + This function is used to Differenciate acadadmin and all other user. + + @param: + request - contains metadata about the requested page + + @variables: + user_details - Gets the information about the logged in user. + des - Gets the designation about the looged in user. + # """ + user_details = ExtraInfo.objects.get(user=request.user) + des = HoldsDesignation.objects.all().filter(user=request.user).first() + if str(des.designation) == "Associate Professor" or str(des.designation) == "Professor" or str(des.designation) == "Assistant Professor": + return HttpResponseRedirect('/examination/updateGrades/') + elif str(request.user) == "acadadmin": + return HttpResponseRedirect('/examination/updateGrades/') + + return HttpResponseRedirect('/dashboard/') + + +@login_required(login_url='/accounts/login') +def submit(request): + + unique_course_ids = course_registration.objects.values( + 'course_id').distinct() + + # Cast the course IDs to integers + unique_course_ids = unique_course_ids.annotate( + course_id_int=Cast('course_id', IntegerField())) + + # Retrieve course names and course codes based on unique course IDs + courses_info = Course.objects.filter( + id__in=unique_course_ids.values_list('course_id_int', flat=True)) + + return render(request, '../templates/examination/submit.html', {'courses_info': courses_info}) + + +@login_required(login_url='/accounts/login') +def verify(request): + unique_course_ids = hidden_grades.objects.values('course_id').distinct() + + unique_course_ids = unique_course_ids.annotate( + course_id_int=Cast('course_id', IntegerField())) + + courses_info = Course.objects.filter( + id__in=unique_course_ids.values_list('course_id_int', flat=True)) + + return render(request, '../templates/examination/verify.html', {'courses_info': courses_info}) + + +@login_required(login_url='/accounts/login') +def publish(request): + return render(request, '../templates/examination/publish.html', {}) + + +@login_required(login_url='/accounts/login') +def notReady_publish(request): + return render(request, '../templates/examination/notReady_publish.html', {}) + + +@login_required(login_url='/accounts/login') +def timetable(request): + return render(request, '../templates/examination/timetable.html', {}) + + +def browse_announcements(): + """ + This function is used to browse Announcements Department-Wise + made by different faculties and admin. + + @variables: + cse_ann - Stores CSE Department Announcements + ece_ann - Stores ECE Department Announcements + me_ann - Stores ME Department Announcements + sm_ann - Stores SM Department Announcements + all_ann - Stores Announcements intended for all Departments + context - Dictionary for storing all above data + + """ + cse_ann = Announcements.objects.filter(department="CSE") + ece_ann = Announcements.objects.filter(department="ECE") + me_ann = Announcements.objects.filter(department="ME") + sm_ann = Announcements.objects.filter(department="SM") + all_ann = Announcements.objects.filter(department="ALL") + + context = { + "cse": cse_ann, + "ece": ece_ann, + "me": me_ann, + "sm": sm_ann, + "all": all_ann + } + + return context + + +def get_to_request(username): + """ + This function is used to get requests for the receiver + + @variables: + req - Contains request queryset + + """ + req = SpecialRequest.objects.filter(request_receiver=username) + return req + + +def entergrades(request): + course_id = request.GET.get('course') + semester_id = request.GET.get('semester') + + course_present = hidden_grades.objects.filter( + course_id=course_id, semester_id=semester_id) + + if (course_present): + return render(request, 'examination/all_course_grade_filled.html', {}) + + registrations = course_registration.objects.filter( + course_id__id=course_id, semester_id=semester_id) + + context = { + 'registrations': registrations + } + + return render(request, 'examination/entergrades.html', context) + + +def verifygrades(request): + course_id = request.GET.get('course') + semester_id = request.GET.get('semester') + + registrations = hidden_grades.objects.filter( + course_id=course_id, semester_id=semester_id) + + context = { + 'registrations': registrations + } + + return render(request, 'examination/verifygrades.html', context) + + +def authenticate(request): # new + # Retrieve unique course IDs from hidden_grades + unique_course_ids = Student_grades.objects.values('course_id').distinct() + + # Cast the course IDs to integers + unique_course_ids = unique_course_ids.annotate( + course_id_int=Cast('course_id', IntegerField())) + + # Retrieve course names and course codes based on unique course IDs + courses_info = Courses.objects.filter( + id__in=unique_course_ids.values_list('course_id_int', flat=True)) + working_years = Student_grades.objects.values( + 'year').distinct() + context = { + 'courses_info': courses_info, + 'working_years':working_years + + } + print(working_years) + return render(request, '../templates/examination/authenticate.html', context) + + +@login_required(login_url='/accounts/login') +def authenticategrades(request): # new + course_id = request.GET.get('course') + year = request.GET.get('year') + + print(course_id) + print(year) + + course_instance = Courses.objects.get(id=course_id) + registrations = authentication.objects.filter( + course_id=course_instance, course_year=year) + + if registrations: + # Registrations exist, pass them to the template context + context = { + 'registrations': registrations, + 'year': year + } + else: + course_instance = Courses.objects.get(id=course_id) + course_present = Student_grades.objects.filter( + course_id=course_id, year=year) + if (course_present): + authentication_object = authentication.objects.create( + course_id=course_instance, course_year=year) + registrations = authentication.objects.filter( + course_id=course_instance, course_year=year) + + context = { + 'registrations': registrations, + 'course_year': year, + } + + context = { + 'registrations': registrations, + 'year': year + } + + return render(request, 'examination/authenticategrades.html', context) + + +# def examination_notif(sender, recipient, type): +# try: +# url = 'examination:examination' +# module = 'examination' +# verb = type +# flag = "examination" + +# notify.send(sender=sender, +# recipient=recipient, +# url=url, +# module=module, +# verb=verb, +# flag=flag) + +# except Exception as e: +# print("Error sending notification:", e) + + +@login_required(login_url='/accounts/login') +def announcement(request): + """ + This function is contains data for Requests and Announcement Related methods. + Data is added to Announcement Table using this function. + + @param: + request - contains metadata about the requested page + + @variables: + usrnm, user_info, ann_maker_id - Stores data needed for maker + batch, programme, message, upload_announcement, + department, ann_date, user_info - Gets and store data from FORM used for Announcements for Students. + + """ + try: + usrnm = get_object_or_404(User, username=request.user.username) + user_info = usrnm.extrainfo + ann_maker_id = user_info.id + requests_received = get_to_request(usrnm) + + if request.method == 'POST': + batch = request.POST.get('batch', '') + programme = request.POST.get('programme', '') + message = request.POST.get('announcement', '') + upload_announcement = request.FILES.get('upload_announcement') + department = request.POST.get('department') + ann_date = date.today() + + obj1, created = Announcements.objects.get_or_create( + maker_id=user_info, + batch=batch, + programme=programme, + message=message, + upload_announcement=upload_announcement, + department=department, + ann_date=ann_date + ) + + recipients = User.objects.all() # Modify this query as per your requirements + examination_notif(sender=usrnm, recipient=recipients, type=message) + + context = browse_announcements() + return render(request, 'examination/announcement_req.html', { + "user_designation": user_info.user_type, + "announcements": context, + "request_to": requests_received + }) + except Exception as e: + + return render(request, 'examination/announcement_req.html', {"error_message": "An error occurred. Please try again later."}) + + +class Updatehidden_gradesMultipleView(APIView): + permission_classes = [AllowAny] + + def post(self, request): + student_ids = request.POST.getlist('student_ids[]') + semester_ids = request.POST.getlist('semester_ids[]') + course_ids = request.POST.getlist('course_ids[]') + grades = request.POST.getlist('grades[]') + + if len(student_ids) != len(semester_ids) != len(course_ids) != len(grades): + return Response({'error': 'Invalid grade data provided'}, status=status.HTTP_400_BAD_REQUEST) + + for student_id, semester_id, course_id, grade in zip(student_ids, semester_ids, course_ids, grades): + # Create an instance of hidden_grades model and save the data + + try: + hidden_grade = hidden_grades.objects.get( + course_id=course_id, student_id=student_id, semester_id=semester_id) + hidden_grade.grade = grade + hidden_grade.save() + except hidden_grades.DoesNotExist: + # If the grade doesn't exist, create a new one + hidden_grade = hidden_grades.objects.create( + course_id=course_id, student_id=student_id, semester_id=semester_id, grade=grade) + hidden_grade.save() + + hidden_grade.save() + + response = HttpResponse(content_type='text/csv') + response['Content-Disposition'] = 'attachment; filename="grades.csv"' + + # Write data to CSV + writer = csv.writer(response) + writer.writerow(['Student ID', 'Semester ID', 'Course ID', 'Grade']) + for student_id, semester_id, course_id, grade in zip(student_ids, semester_ids, course_ids, grades): + writer.writerow([student_id, semester_id, course_id, grade]) + + return response + return render(request, '../templates/examination/grades_updated.html', {}) + + +class Submithidden_gradesMultipleView(APIView): + permission_classes = [AllowAny] + + def post(self, request): + student_ids = request.POST.getlist('student_ids[]') + semester_ids = request.POST.getlist('semester_ids[]') + course_ids = request.POST.getlist('course_ids[]') + grades = request.POST.getlist('grades[]') + + if len(student_ids) != len(semester_ids) != len(course_ids) != len(grades): + return Response({'error': 'Invalid grade data provided'}, status=status.HTTP_400_BAD_REQUEST) + + for student_id, semester_id, course_id, grade in zip(student_ids, semester_ids, course_ids, grades): + # Create an instance of hidden_grades model and save the data + + try: + hidden_grade = hidden_grades.objects.get( + course_id=course_id, student_id=student_id, semester_id=semester_id) + hidden_grade.grade = grade + hidden_grade.save() + except hidden_grades.DoesNotExist: + # If the grade doesn't exist, create a new one + hidden_grade = hidden_grades.objects.create( + course_id=course_id, student_id=student_id, semester_id=semester_id, grade=grade) + hidden_grade.save() + + hidden_grade.save() + + return render(request, '../templates/examination/grades_updated.html', {}) + + +class update_authentication(View): + def post(self, request, *args, **kwargs): + # Extract data from the POST request + course = request.POST.get('course') + course_year = request.POST.get('course_year') + authenticator1 = request.POST.get('authenticator1') + authenticator2 = request.POST.get('authenticator2') + authenticator3 = request.POST.get('authenticator3') + + # Retrieve the registration object + try: + + course_instance = Courses.objects.get(id=course) + registration = authentication.objects.get( + course_id=course_instance, course_year=course_year) + except authentication.DoesNotExist: + # Redirect if registration does not exist + return redirect('examination:submitGrades') + + # Update authenticators if the values have changed + if authenticator1 is not None: + registration.authenticator_1 = (authenticator1 == '1') + else: + registration.authenticator_1 = 0 + if authenticator2 is not None: + registration.authenticator_2 = (authenticator2 == '1') + else: + registration.authenticator_2 = 0 + if authenticator3 is not None: + registration.authenticator_3 = (authenticator3 == '1') + else: + registration.authenticator_3 = 0 + + # Save the changes + registration.save() + + # Redirect to the appropriate page + return redirect('examination:authenticate') + + +class DownloadExcelView(View): + def post(self, request, *args, **kwargs): + # Retrieve form data + student_ids = request.POST.getlist('student_ids[]') + semester_ids = request.POST.getlist('semester_ids[]') + course_ids = request.POST.getlist('course_ids[]') + grades = request.POST.getlist('grades[]') + + # Create a CSV response + response = HttpResponse(content_type='text/csv') + response['Content-Disposition'] = 'attachment; filename="grades.csv"' + + # Write data to CSV + writer = csv.writer(response) + writer.writerow(['Student ID', 'Semester ID', 'Course ID', 'Grade']) + for student_id, semester_id, course_id, grade in zip(student_ids, semester_ids, course_ids, grades): + writer.writerow([student_id, semester_id, course_id, grade]) + + return response + + +def generate_transcript(request): + + student_id = request.GET.get('student') + semester = request.GET.get('semester') + courses_registered = Student_grades.objects.filter( + roll_no=student_id, semester=semester) + + # Initialize a dictionary to store course grades + course_grades = {} + + total_course_registered = Student_grades.objects.filter( + roll_no=student_id, semester__lte=semester) + # for each_course in total_course_registered: + # course_name = Curriculum.objects.filter( + # curriculum_id=each_course.curr_id_id) + + + + for course in courses_registered: + try: + # Attempt to fetch the grade for the course from Student_grades + grade = Student_grades.objects.get( + roll_no=student_id, course_id=course.course_id) + + # course_detail = Curriculum.objects.get( + # course_id=course.course_id, batch=grade.batch) + course_instance = Courses.objects.get(id=course.course_id_id) + check_authentication_object = authentication.objects.filter( + course_id=course_instance, course_year=grade.year) + all_authenticators_true = True + + if check_authentication_object: + # Iterate over each authentication object + for auth_obj in check_authentication_object: + # Check if all authenticators are true + if not (auth_obj.authenticator_1 and auth_obj.authenticator_2 and auth_obj.authenticator_3): + all_authenticators_true = False + break # No need to check further if any authenticator is False + else: + # Create authentication object if it doesn't exist + authentication_object = authentication.objects.create( + course_id=course_instance, course_year=grade.year) + # Get all registrations for the course and year + registrations = authentication.objects.filter( + course_id=course_instance, course_year=grade.year) + all_authenticators_true = False + + course_grades[course_instance] = { + 'grade': grade, + 'all_authenticators_true': all_authenticators_true + } # Store the grade + except Student_grades.DoesNotExist: + # Grade not available + course_grades[course] = "Grading not done yet" + + context = { + 'courses_grades': course_grades, + 'total_course_registered':total_course_registered + } + # print(context) + + return render(request, 'examination/generate_transcript.html', context) + +# new + + +def generate_transcript_form(request): + if request.method == 'POST': + programme = request.POST.get('programme') + batch = request.POST.get('batch') + specialization = request.POST.get('specialization') + semester = request.POST.get('semester') + + if specialization == None: + students = Student.objects.filter( + programme=programme, batch=batch) + else: + students = Student.objects.filter( + programme=programme, batch=batch, specialization=specialization) + + # Pass the filtered students to the template + context = { + 'students': students, + 'semester': semester + } + return render(request, 'examination/generate_transcript_students.html', context) + else: + programmes = Student.objects.values_list( + 'programme', flat=True).distinct() + specializations = Student.objects.exclude( + specialization__isnull=True).values_list('specialization', flat=True).distinct() + batches = Student.objects.values_list('batch', flat=True).distinct() + context = { + 'programmes': programmes, + 'batches': batches, + 'specializations': specializations, + } + + return render(request, 'examination/generate_transcript_form.html', context) + + +@login_required(login_url='/accounts/login') +def updateGrades(request): + unique_course_ids = Student_grades.objects.values( + 'course_id').distinct() + + # Cast the course IDs to integers + unique_course_ids = unique_course_ids.annotate( + course_id_int=Cast('course_id', IntegerField())) + + # Retrieve course names and course codes based on unique course IDs + + print(unique_course_ids) + courses_info = Courses.objects.filter( + id__in=unique_course_ids.values_list('course_id_int', flat=True)) + + unique_batch_ids = Student_grades.objects.values( + 'batch').distinct() + + context = { + 'courses_info': courses_info, + 'unique_batch_ids': unique_batch_ids, + } + + return render(request, '../templates/examination/submitGrade.html', context) + + +def updateEntergrades(request): + course_id = request.GET.get('course') + semester_id = request.GET.get('semester') + batch = request.GET.get('batch') + + course_present = Student_grades.objects.filter( + course_id=course_id, semester=semester_id, batch=batch) + + context = { + 'registrations': course_present + } + + return render(request, '../templates/examination/updateEntergrades.html', context) + + +class moderate_student_grades(APIView): + permission_classes = [AllowAny] + + def post(self, request): + student_ids = request.POST.getlist('student_ids[]') + semester_ids = request.POST.getlist('semester_ids[]') + course_ids = request.POST.getlist('course_ids[]') + grades = request.POST.getlist('grades[]') + + if len(student_ids) != len(semester_ids) != len(course_ids) != len(grades): + return Response({'error': 'Invalid grade data provided'}, status=status.HTTP_400_BAD_REQUEST) + + for student_id, semester_id, course_id, grade in zip(student_ids, semester_ids, course_ids, grades): + + try: + grade_of_student = Student_grades.objects.get( + course_id=course_id, roll_no=student_id, semester=semester_id) + grade_of_student.grade = grade + grade_of_student.save() + except Student_grades.DoesNotExist: + # If the grade doesn't exist, create a new one + hidden_grade = hidden_grades.objects.create( + course_id=course_id, student_id=student_id, semester_id=semester_id, grade=grade) + hidden_grade.save() + + response = HttpResponse(content_type='text/csv') + response['Content-Disposition'] = 'attachment; filename="grades.csv"' + + # Write data to CSV + writer = csv.writer(response) + writer.writerow(['Student ID', 'Semester ID', 'Course ID', 'Grade']) + for student_id, semester_id, course_id, grade in zip(student_ids, semester_ids, course_ids, grades): + writer.writerow([student_id, semester_id, course_id, grade]) + + return response + return render(request, '../templates/examination/grades_updated.html', {}) + + +@login_required(login_url='/accounts/login') +def submitGrades(request): + + unique_course_ids = course_registration.objects.values( + 'course_id').distinct() + working_years = course_registration.objects.values( + 'working_year').distinct() + + + + # Cast the course IDs to integers + unique_course_ids = unique_course_ids.annotate( + course_id_int=Cast('course_id', IntegerField())) + + # Retrieve course names and course codes based on unique course IDs + + print(unique_course_ids) + courses_info = Courses.objects.filter( + id__in=unique_course_ids.values_list('course_id_int', flat=True)) + + context = { + 'courses_info': courses_info, + 'working_years': working_years + } + + print(working_years) + + return render(request, '../templates/examination/gradeSubmission.html', context) + + +def submitEntergrades(request): + course_id = request.GET.get('course') + year = request.GET.get('year') + if year is None or not year.isdigit(): + message = "YEAR SHOULD NOT BE NONE" + context = { + 'message': message + } + + return render(request, '../templates/examination/message.html', context) + return HttpResponse("Invalid year parameter") + # Handle invalid year parameter + # You can return an error response or redirect the user to an error page + courses_info = Courses.objects.get(id=course_id) + + courses = Student_grades.objects.filter( + course_id=courses_info.id, year=year) + + if courses: + message = "THIS Course was Already Submitted" + context = { + 'message': message + } + + return render(request, '../templates/examination/message.html', context) + + students = course_registration.objects.filter( + course_id_id=course_id, working_year=year) + + # print(students) + + context = { + 'registrations': students, + 'curr_id': course_id, + 'year': year + } + + return render(request, '../templates/examination/gradeSubmissionForm.html', context) + + +class submitEntergradesStoring(APIView): + permission_classes = [AllowAny] + + def post(self, request): + student_ids = request.POST.getlist('student_ids[]') + batch_ids = request.POST.getlist('batch_ids[]') + course_ids = request.POST.getlist('course_ids[]') + semester_ids = request.POST.getlist('semester_ids[]') + year_ids = request.POST.getlist('year_ids[]') + marks = request.POST.getlist('marks[]') + grades = request.POST.getlist('grades[]') + + if len(student_ids) != len(batch_ids) != len(course_ids) != len(semester_ids) != len(year_ids) != len(marks) != len(grades): + return Response({'error': 'Invalid grade data provided'}, status=status.HTTP_400_BAD_REQUEST) + + for student_id, batch_id, course_id, semester_id, year_id, mark, grade in zip(student_ids, batch_ids, course_ids, semester_ids, year_ids, marks, grades): + # Create an instance of hidden_grades model and save the data + + try: + grade_of_student = Student_grades.objects.get( + course_id=course_id, roll_no=student_id, semester=semester_id) + except Student_grades.DoesNotExist: + # If the grade doesn't exist, create a new one + course_instance = Courses.objects.get(id=course_id) + student_grade = Student_grades.objects.create( + course_id=course_instance, roll_no=student_id, semester=semester_id, grade=grade, batch=batch_id, year=year_id, total_marks=mark) + student_grade.save() + + response = HttpResponse(content_type='text/csv') + response['Content-Disposition'] = 'attachment; filename="grades.csv"' + + # Write data to CSV + writer = csv.writer(response) + writer.writerow(['student_id', 'batch_ids', 'course_id', + 'semester_id', 'year_ids', 'marks', 'grade']) + for student_id, batch_id, course_id, semester_id, year_id, mark, grade in zip(student_ids, batch_ids, course_ids, semester_ids, year_ids, marks, grades): + writer.writerow([student_id, batch_id, course_id, + semester_id, year_id, mark, grade]) + + return response + return render(request, '../templates/examination/grades_updated.html', {}) diff --git a/FusionIIIT/applications/filetracking/sdk/methods.py b/FusionIIIT/applications/filetracking/sdk/methods.py index 0ea167fc6..7bb56763e 100644 --- a/FusionIIIT/applications/filetracking/sdk/methods.py +++ b/FusionIIIT/applications/filetracking/sdk/methods.py @@ -108,7 +108,7 @@ def view_inbox(username: str, designation: str, src_module: str) -> list: receiver_id=recipient_object, receive_design=user_designation, file_id__src_module=src_module, - file_id__is_read=False).order_by('receive_date'); + file_id__is_read=False).order_by('-receive_date'); received_files = [tracking.file_id for tracking in received_files_tracking] # remove duplicate file ids (from sending back and forth) @@ -120,7 +120,6 @@ def view_inbox(username: str, designation: str, src_module: str) -> list: for file in received_files_serialized: file['sent_by_user'] = get_last_file_sender(file['id']).username file['sent_by_designation'] = get_last_file_sender_designation(file['id']).name - return received_files_serialized @@ -168,7 +167,7 @@ def view_archived(username: str, designation: str, src_module: str) -> dict: current_id=sender_ExtraInfo_object, current_design=user_HoldsDesignation_object, file_id__src_module=src_module, - file_id__is_read=True) + file_id__is_read=True).order_by('-receive_date') archived_tracking = received_archived_tracking | sent_archived_tracking archived_files = [tracking.file_id for tracking in archived_tracking] @@ -237,7 +236,7 @@ def view_drafts(username: str, designation: str, src_module: str) -> dict: user_designation = Designation.objects.get(name=designation) user_ExtraInfo_object = get_ExtraInfo_object_from_username(username) draft_files = File.objects.filter( - tracking__isnull=True, uploader=user_ExtraInfo_object, designation=user_designation, src_module=src_module) + tracking__isnull=True, uploader=user_ExtraInfo_object, designation=user_designation, src_module=src_module).order_by('-upload_date') draft_files_serialized = FileHeaderSerializer(draft_files, many=True) return draft_files_serialized.data diff --git a/FusionIIIT/applications/filetracking/urls.py b/FusionIIIT/applications/filetracking/urls.py index a451738de..70633ec3c 100644 --- a/FusionIIIT/applications/filetracking/urls.py +++ b/FusionIIIT/applications/filetracking/urls.py @@ -22,7 +22,6 @@ url(r'^forward/(?P\d+)/$', views.forward, name='forward'), url(r'^ajax/$', views.AjaxDropdown1, name='ajax_dropdown1'), url(r'^ajax_dropdown/$', views.AjaxDropdown, name='ajax_dropdown'), - url(r'^test/$', views.test, name='test'), url(r'^delete/(?P\d+)$', views.delete, name='delete'), url(r'^forward_inward/(?P\d+)/$', views.forward_inward, name='forward_inward'), @@ -39,9 +38,9 @@ views.unarchive_file, name='unarchive'), url(r'^getdesignations/(?P\w+)/$', views.get_designations_view, name="get_user_designations"), url(r'^editdraft/(?P\w+)/$', views.edit_draft_view, name="edit_draft"), + url(r'^download_file/(?P\w+)/$', views.download_file, name="download_file"), # REST api urls url(r'^api/', include(urls)) ] - diff --git a/FusionIIIT/applications/filetracking/views.py b/FusionIIIT/applications/filetracking/views.py index a01d71ac1..285192df4 100644 --- a/FusionIIIT/applications/filetracking/views.py +++ b/FusionIIIT/applications/filetracking/views.py @@ -1,21 +1,31 @@ -from django.contrib import messages -from django.shortcuts import render, get_object_or_404, redirect -from .models import File, Tracking -from applications.globals.models import ExtraInfo, HoldsDesignation, Designation -from django.template.defaulttags import csrf_token +from sqlite3 import IntegrityError from django.http import HttpResponse, HttpResponseRedirect, JsonResponse +from django.contrib import messages +from django.shortcuts import render, get_object_or_404, redirect, reverse from django.contrib.auth.decorators import login_required -from django.db import IntegrityError from django.core import serializers from django.contrib.auth.models import User -from django.http import JsonResponse -from timeit import default_timer as time -from notification.views import office_module_notif, file_tracking_notif -from .utils import * +from django.views.decorators.http import require_POST +from django.utils import timezone from django.utils.dateparse import parse_datetime + +from .models import File, Tracking +from applications.globals.models import ExtraInfo, HoldsDesignation, Designation +from .utils import * from .sdk.methods import * from .decorators import * + +from timeit import default_timer as time +from notification.views import office_module_notif, file_tracking_notif + +import io +from reportlab.lib.pagesizes import letter +from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image +from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle + import json +import zipfile +import os @login_required(login_url="/accounts/login/") @@ -43,7 +53,6 @@ def filetracking(request): context - Holds data needed to make necessary changes in the template. """ - if request.method == "POST": try: if 'save' in request.POST: @@ -59,8 +68,9 @@ def filetracking(request): request, "File should not be greater than 10MB") return redirect("/filetracking") + form_remarks = request.POST.get('remarks') extraJSON = { - 'remarks': request.POST.get('remarks'), + 'remarks': form_remarks if form_remarks is not None else '', } File.objects.create( @@ -111,7 +121,6 @@ def filetracking(request): return redirect('/filetracking/') receive = request.POST.get('receive') try: - print(receive) receive_design = Designation.objects.get(name=receive) except Exception as e: messages.error(request, 'Enter a valid Designation') @@ -128,7 +137,6 @@ def filetracking(request): remarks=remarks, upload_file=upload_file, ) - # office_module_notif(request.user, receiver_id) file_tracking_notif(request.user, receiver_id, subject) messages.success(request, 'File sent successfully') @@ -157,12 +165,15 @@ def filetracking(request): 'holdsdesignations': holdsdesignations, 'designation_name': designation_name, 'designation_id': designation_id, - 'notifications': request.user.notifications.all() + 'notifications': request.user.notifications.all(), + 'path_parent': 'compose' } return render(request, 'filetracking/composefile.html', context) @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def draft_design(request): """ This function redirects the user to the drafts page of designation selected in dropdown @@ -180,6 +191,8 @@ def draft_design(request): @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def drafts_view(request, id): """ This function is used to view all the drafts created by the user ordered by upload date.it collects all the created files from File object. @@ -192,9 +205,6 @@ def drafts_view(request, id): draft - file obeject containing all the files created by user context - holds data needed to render the template - - - """ user_HoldsDesignation_obj = HoldsDesignation.objects.select_related( 'user', 'working', 'designation').get(pk=id) @@ -216,12 +226,15 @@ def drafts_view(request, id): context = { 'draft_files': draft_files, 'designations': designation, - 'notifications': request.user.notifications.all() + 'notifications': request.user.notifications.all(), + 'path_parent': 'draft' } return render(request, 'filetracking/drafts.html', context) @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def outbox_view(request, id): """ The function is used to get all the files sent by user(employee) to other employees @@ -268,12 +281,15 @@ def outbox_view(request, id): context = { 'out_files': outward_files, 'viewer_designation': designation, - 'notifications': request.user.notifications.all() + 'notifications': request.user.notifications.all(), + 'path_parent': 'outbox' } return render(request, 'filetracking/outbox.html', context) @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def inbox_view(request, id): """ The function is used to fetch the files received by the user form other employees. @@ -314,12 +330,15 @@ def inbox_view(request, id): context = { 'in_file': inward_files, 'designations': designation, - 'notifications': request.user.notifications.all() + 'notifications': request.user.notifications.all(), + 'path_parent': 'inbox' } return render(request, 'filetracking/inbox.html', context) @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def outward(request): """ This function redirects the user to the outbox page of designation selected in dropdown @@ -339,6 +358,8 @@ def outward(request): @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def inward(request): """ This function redirects the user to the inbox page of designation selected in dropdown @@ -356,6 +377,8 @@ def inward(request): @login_required(login_url = "/accounts/login") +@user_is_student +@dropdown_designation_valid def confirmdelete(request,id): """ The function is used to confirm the deletion of a file. @@ -376,6 +399,8 @@ def confirmdelete(request,id): return render(request, 'filetracking/confirmdelete.html', context) @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def view_file(request, id): ''' This function is used to view a particular file received by an employee from another. @@ -417,24 +442,28 @@ def view_file(request, id): if current_owner == request.user and file_uploader == request.user and file.is_read is False: archive_enable = True + parent_of_prev_path = request.META.get('HTTP_REFERER').strip("/").split('/')[-2] context = { 'designations': designations, 'file': file, 'track': track, 'forward_enable': forward_enable, 'archive_enable': archive_enable, - 'notifications': request.user.notifications.all() + 'notifications': request.user.notifications.all(), + 'path_parent': parent_of_prev_path } return render(request, 'filetracking/viewfile.html', context) @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def archive_file(request, id): '''This function is used to archive a file. It returns unauthorized access if the user is not file uploader and the current owner of the file ''' if request.method == "POST": - file = get_object_or_404(File, id=id); + file = get_object_or_404(File, id=id) current_owner = get_current_file_owner(file.id) file_uploader = get_user_object_from_username(file.uploader.user.username) if current_owner == request.user and file_uploader == request.user: @@ -447,6 +476,8 @@ def archive_file(request, id): return render(request, 'filetracking/composefile.html') @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def forward(request, id): """ The function is used to forward files received by user(employee) from other @@ -477,6 +508,16 @@ def forward(request, id): track = Tracking.objects.select_related('file_id__uploader__user', 'file_id__uploader__department', 'file_id__designation', 'current_id__user', 'current_id__department', 'current_design__user', 'current_design__working', 'current_design__designation', 'receiver_id', 'receive_design').filter(file_id=file).order_by('receive_date') + designations = get_designation(request.user) + + designation_name = request.session.get('currentDesignationSelected', 'default_value') + all_available_designations = request.session.get( + 'allDesignations', 'default_value2') + + username = request.user + designation_id = get_HoldsDesignation_obj( + username, designation_name).id + if request.method == "POST": if 'finish' in request.POST: file.is_read = True @@ -499,11 +540,15 @@ def forward(request, id): 'user', 'working', 'designation').filter(user=request.user) context = { - 'designations': designations, 'file': file, 'track': track, + 'designation_name': designation_name, + 'designation_id': designation_id, + 'notifications': request.user.notifications.all(), + 'path_parent': 'inbox' } + return render(request, 'filetracking/forward.html', context) receive = request.POST.get('receive') try: @@ -513,11 +558,15 @@ def forward(request, id): designations = get_designation(request.user) context = { - 'designations': designations, 'file': file, 'track': track, + 'designation_name': designation_name, + 'designation_id': designation_id, + 'notifications': request.user.notifications.all(), + 'path_parent': 'inbox' } + return render(request, 'filetracking/forward.html', context) upload_file = request.FILES.get('myfile') @@ -531,18 +580,9 @@ def forward(request, id): remarks=remarks, upload_file=upload_file, ) + file_tracking_notif(request.user, receiver_id, file.subject) messages.success(request, 'File sent successfully') - - designations = get_designation(request.user) - - designation_name = request.session.get('currentDesignationSelected', 'default_value') - all_available_designations = request.session.get( - 'allDesignations', 'default_value2') - - username = request.user - designation_id = get_HoldsDesignation_obj( - username, designation_name).id - + return redirect(reverse('filetracking:filetracking')) context = { 'designations': designations, @@ -550,14 +590,16 @@ def forward(request, id): 'track': track, 'designation_name': designation_name, 'designation_id': designation_id, - - 'notifications': request.user.notifications.all() + 'notifications': request.user.notifications.all(), + 'path_parent': 'inbox' } return render(request, 'filetracking/forward.html', context) @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def archive_design(request): """ This function redirects the user to the archive page of designation selected in dropdown @@ -575,6 +617,8 @@ def archive_design(request): @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def archive_view(request, id): """ The function is used to fetch the files in the user's archive @@ -611,15 +655,17 @@ def archive_view(request, id): context = { 'archive_files': archive_files, 'designations': designation, - 'notifications': request.user.notifications.all() + 'notifications': request.user.notifications.all(), + 'path_parent': 'archive' } return render(request, 'filetracking/archive.html', context) @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def archive_finish(request, id): - # file = get_object_or_404(File, ref_id=id) file1 = get_object_or_404(File, id=id) track = Tracking.objects.filter(file_id=file1) @@ -627,6 +673,8 @@ def archive_finish(request, id): @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def finish_design(request): designation = HoldsDesignation.objects.select_related( @@ -640,6 +688,8 @@ def finish_design(request): @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def finish_fileview(request, id): out = Tracking.objects.select_related('file_id__uploader__user', 'file_id__uploader__department', 'file_id__designation', 'current_id__user', 'current_id__department', @@ -658,6 +708,8 @@ def finish_fileview(request, id): @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def finish(request, id): # file = get_object_or_404(File, ref_id=id) file1 = get_object_or_404(File, id=id) @@ -669,14 +721,19 @@ def finish(request, id): track.update(is_read=True) messages.success(request, 'File Archived') - return render(request, 'filetracking/finish.html', {'file': file1, 'track': track, 'fileid': id, - 'notifications': request.user.notifications.all()}) + context = { + 'file': file1, + 'track': track, + 'fileid': id, + 'notifications': request.user.notifications.all() + } + return render(request, 'filetracking/finish.html', ) def AjaxDropdown1(request): """ - This function returns the designation of receiver on the forward or compose file template. + This function returns the designation of receiver on the forward or compose file template. @param: request - trivial. @@ -699,7 +756,7 @@ def AjaxDropdown1(request): def AjaxDropdown(request): """ - This function returns the usernames of receiver on the forward or compose file template. + This function returns the usernames of receiver on the forward or compose file template. @param: request - trivial. @@ -719,12 +776,10 @@ def AjaxDropdown(request): return HttpResponse(JsonResponse(context), content_type='application/json') -def test(request): - return HttpResponse('success') - - @login_required(login_url = "/accounts/login") +@user_is_student +@dropdown_designation_valid def delete(request,id): """ The function is used the delete of a file and it returns to the drafts page. @@ -739,6 +794,8 @@ def delete(request,id): return redirect('/filetracking/draftdesign/') +@user_is_student +@dropdown_designation_valid def forward_inward(request,id): """ This function is used forward the files which are available in the inbox of the user . @@ -787,6 +844,8 @@ def unarchive_file(request, id): @login_required(login_url="/accounts/login") +@user_is_student +@dropdown_designation_valid def edit_draft_view(request, id, *args, **kwargs): """ The function is used to edit and send drafted files, and also alter their title and subject @@ -843,7 +902,8 @@ def edit_draft_view(request, id, *args, **kwargs): 'track': track, 'notifications': request.user.notifications.all() } - return render(request, 'filetracking/editdraft.html', context) + return redirect(reverse('filetracking:filetracking')) + receive = request.POST.get('receive') try: receive_design = Designation.objects.get(name=receive) @@ -857,10 +917,18 @@ def edit_draft_view(request, id, *args, **kwargs): 'file': file, 'notifications': request.user.notifications.all() } - return render(request, 'filetracking/editdraft.html', context) + return redirect(reverse('filetracking:filetracking')) upload_file = request.FILES.get('myfile') + if upload_file is None and file.upload_file is not None: + upload_file = file.upload_file + + # since frontend isnt reflecting uploaded file in edit draft, but upload_file may exist in File + # (this feature isnt working atm, duplicate is still stored) + #if upload_file == file.upload_file: + # upload_file = None + Tracking.objects.create( file_id=file, current_id=current_id, @@ -870,7 +938,10 @@ def edit_draft_view(request, id, *args, **kwargs): remarks=remarks, upload_file=upload_file, ) + + file_tracking_notif(request.user, receiver_id, subject) messages.success(request, 'File sent successfully') + return render(request, 'filetracking/composefile.html') designations = get_designation(request.user) @@ -903,4 +974,63 @@ def edit_draft_view(request, id, *args, **kwargs): return render(request, 'filetracking/editdraft.html', context) - +@login_required(login_url="/accounts/login/") +@user_is_student +@dropdown_designation_valid +@require_POST +def download_file(request, id): + file = get_object_or_404(File, id=id) + track = Tracking.objects.select_related('file_id__uploader__user', 'file_id__uploader__department', 'file_id__designation', 'current_id__user', 'current_id__department', + 'current_design__user', 'current_design__working', 'current_design__designation', 'receiver_id', 'receive_design').filter(file_id=id).order_by('receive_date') + + buffer = io.BytesIO() + doc = SimpleDocTemplate(buffer, pagesize=letter) + elements = [] + styles = getSampleStyleSheet() + style_heading = styles['Heading1'] + style_paragraph = styles['BodyText'] + + elements.append( + Paragraph(f"
Subject - {file.subject}
", style_heading)) + elements.append(Spacer(1, 12)) + elements.append( + Paragraph(f"Description: {file.description}", style_paragraph)) + elements.append(Spacer(1, 12)) + + for t in track: + sent_by = f"Sent by: {t.current_design} - {t.forward_date.strftime('%B %d, %Y %I:%M %p')}" + received_by = f"Received by: {t.receiver_id} - {t.receive_design}" + combined_info = f"{sent_by}       {received_by}" + elements.append(Paragraph(combined_info, style_paragraph)) + elements.append(Spacer(1, 12)) + remarks = f"Remarks: {t.remarks}" if t.remarks else "Remarks: No Remarks" + elements.append(Paragraph(remarks, style_paragraph)) + elements.append(Spacer(1, 12)) + attachment = f"Attachment: {os.path.basename(t.upload_file.name)}" if t.upload_file else "Attachment: No attachments" + elements.append(Paragraph(attachment, style_paragraph)) + elements.append(Paragraph('
', style_paragraph)) + elements.append(Spacer(2, 12)) + + doc.build(elements) + pdf_data = buffer.getvalue() + buffer.close() + + formal_filename = f'{file.uploader.department.name}-{file.upload_date.year}-{file.upload_date.month}-#{file.id}' + output_filename = f'iiitdmj-fts-{formal_filename}' + + zip_buffer = io.BytesIO() + with zipfile.ZipFile(zip_buffer, 'w') as zip_file: + pdf_filename = f'{file.uploader.department.name}-{file.upload_date.year}-{file.upload_date.month}-#{file.id}-notesheet.pdf' + zip_file.writestr(output_filename+'.pdf', pdf_data) + for t in track: + if t.upload_file: + zip_file.write(t.upload_file.path, + os.path.basename(t.upload_file.name)) + + zip_data = zip_buffer.getvalue() + zip_buffer.close() + + response = HttpResponse(zip_data, content_type='application/zip') + response['Content-Disposition'] = f'attachment; filename="{output_filename}.zip"' + + return response diff --git a/FusionIIIT/applications/globals/api/urls.py b/FusionIIIT/applications/globals/api/urls.py index 9f4e6c2b5..e6683eac7 100644 --- a/FusionIIIT/applications/globals/api/urls.py +++ b/FusionIIIT/applications/globals/api/urls.py @@ -7,6 +7,7 @@ url(r'^auth/login/', views.login, name='login-api'), url(r'^auth/logout/', views.logout, name='logout-api'), # generic profile endpoint + #code of corresponding view is modifiedtemporary because of mismatched designations url(r'^profile/(?P.+)/', views.profile, name='profile-api'), # current user profile url(r'^profile/', views.profile, name='profile-api'), diff --git a/FusionIIIT/applications/globals/api/views.py b/FusionIIIT/applications/globals/api/views.py index c6723d0ab..c8fd9f5b1 100644 --- a/FusionIIIT/applications/globals/api/views.py +++ b/FusionIIIT/applications/globals/api/views.py @@ -117,6 +117,9 @@ def profile(request, username=None): user = get_object_or_404(User, username=username) if username else request.user user_detail = serializers.UserSerializer(user).data profile = serializers.ExtraInfoSerializer(user.extrainfo).data + + print(user) + if profile['user_type'] == 'student': student = user.extrainfo.student skills = serializers.HasSerializer(student.has_set.all(),many=True).data @@ -143,6 +146,7 @@ def profile(request, username=None): } return Response(data=resp, status=status.HTTP_200_OK) elif profile['user_type'] == 'faculty': + print(username) return redirect('/eis/api/profile/' + (username+'/' if username else '')) elif profile['user_type'] == 'staff': resp = { diff --git a/FusionIIIT/applications/globals/migrations/0002_auto_20231116_2323.py b/FusionIIIT/applications/globals/migrations/0002_auto_20231116_2323.py new file mode 100644 index 000000000..51f5a76b5 --- /dev/null +++ b/FusionIIIT/applications/globals/migrations/0002_auto_20231116_2323.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.5 on 2023-11-16 23:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('globals', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='extrainfo', + name='user_status', + field=models.CharField(choices=[('NEW', 'NEW'), ('PRESENT', 'PRESENT')], default='PRESENT', max_length=50), + ), + ] diff --git a/FusionIIIT/applications/globals/static/globals/js/jquery-3.0.0.min.js b/FusionIIIT/applications/globals/static/globals/js/jquery-3.0.0.min.js new file mode 100644 index 000000000..62d410d95 --- /dev/null +++ b/FusionIIIT/applications/globals/static/globals/js/jquery-3.0.0.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.0.0 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.0.0",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:f.call(this)},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return a&&"[object Object]"===k.call(a)?(b=e(a))?(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n):!0:!1},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;d>f;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;return"string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a)?(d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e):void 0},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"===c||r.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\x00-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,ca=function(a,b){return b?"\x00"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"label"in b&&b.disabled===a||"form"in b&&b.disabled===a||"form"in b&&b.disabled===!1&&(b.isDisabled===a||b.isDisabled!==!a&&("label"in b||!ea(b))!==a)}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[0>c?c+b:c]}),even:pa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e)}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,e>i&&ya(a.slice(i,e)),f>e&&ya(a=a.slice(e)),f>e&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(_,aa),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=V.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(_,aa),$.test(j[0].type)&&qa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&sa(j),!a)return G.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||$.test(a)&&qa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){if(r.isFunction(b))return r.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return r.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(C.test(b))return r.filter(b,a,c);b=r.filter(b,a)}return r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType})}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;d>b;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;d>b;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/\S+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(f>b)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(1>=b&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){ +return j.call(r(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Y=/[A-Z]/g;function Z(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Y,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:X.test(c)?JSON.parse(c):c}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=W.get(f),1===f.nodeType&&!V.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),Z(f,d,e[d])));V.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=Z(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthf;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=V.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&ba(d)&&(e[f]=fa(d))):"none"!==c&&(e[f]="none",V.set(d,"display",c)));for(f=0;g>f;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ga(this,!0)},hide:function(){return ga(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){ba(this)?r(this).show():r(this).hide()})}});var ha=/^(?:checkbox|radio)$/i,ia=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,ja=/^$|\/(?:java|ecma)script/i,ka={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ka.optgroup=ka.option,ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead,ka.th=ka.td;function la(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function ma(a,b){for(var c=0,d=a.length;d>c;c++)V.set(a[c],"globalEval",!b||V.get(b[c],"globalEval"))}var na=/<|&#?\w+;/;function oa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;o>n;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(na.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ia.exec(f)||["",""])[1].toLowerCase(),i=ka[h]||ka._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=la(l.appendChild(f),"script"),j&&ma(g),c){k=0;while(f=g[k++])ja.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;cc;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?r(e,this).index(i)>-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h\x20\t\r\n\f]*)[^>]*)\/>/gi,ya=/\s*$/g;function Ca(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ga(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ha.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ha(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,"script"),Da),i=h.length;m>l;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,la(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ea),l=0;i>l;l++)j=h[l],ja.test(j.type||"")&&!V.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ba,""),k))}return a}function Ia(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(la(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&ma(la(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(xa,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;e>d;d++)Ga(f[d],g[d]);if(b)if(c)for(f=f||la(a),g=g||la(h),d=0,e=f.length;e>d;d++)Fa(f[d],g[d]);else Fa(a,h);return g=la(h,"script"),g.length>0&&ma(g,!i&&la(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!ya.test(a)&&!ka[(ia.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(la(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(la(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;f>=g;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ja=/^margin/,Ka=new RegExp("^("+$+")(?!px)[a-z%]+$","i"),La=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",pa.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,pa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Ma(a,b,c){var d,e,f,g,h=a.style;return c=c||La(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ka.test(g)&&Ja.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Na(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Oa=/^(none|table(?!-c[ea]).+)/,Pa={position:"absolute",visibility:"hidden",display:"block"},Qa={letterSpacing:"0",fontWeight:"400"},Ra=["Webkit","Moz","ms"],Sa=d.createElement("div").style;function Ta(a){if(a in Sa)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ra.length;while(c--)if(a=Ra[c]+b,a in Sa)return a}function Ua(a,b,c){var d=_.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Va(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=r.css(a,c+aa[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+aa[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+aa[f]+"Width",!0,e))):(g+=r.css(a,"padding"+aa[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+aa[f]+"Width",!0,e)));return g}function Wa(a,b,c){var d,e=!0,f=La(a),g="border-box"===r.css(a,"boxSizing",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),0>=d||null==d){if(d=Ma(a,b,f),(0>d||null==d)&&(d=a.style[b]),Ka.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Va(a,b,c||(g?"border":"content"),e,f)+"px"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ma(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=_.exec(c))&&e[1]&&(c=da(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Ma(a,b,d)),"normal"===e&&b in Qa&&(e=Qa[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){return c?!Oa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?Wa(a,b,d):ca(a,Pa,function(){return Wa(a,b,d)}):void 0},set:function(a,c,d){var e,f=d&&La(a),g=d&&Va(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=_.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ua(a,c,g)}}}),r.cssHooks.marginLeft=Na(o.reliableMarginLeft,function(a,b){return b?(parseFloat(Ma(a,"marginLeft"))||a.getBoundingClientRect().left-ca(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px":void 0}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+aa[d]+b]=f[d]||f[d-2]||f[0];return e}},Ja.test(a)||(r.cssHooks[a+b].set=Ua)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=La(a),e=b.length;e>g;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=aa[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function eb(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&ba(a),q=V.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],$a.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ga([a],!0),j=a.style.display||j,k=r.css(a,"display"),ga([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=V.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ga([a],!0),m.done(function(){p||ga([a]),V.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=db(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function fb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function gb(a,b,c){var d,e,f=0,g=gb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Ya||bb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Ya||bb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(fb(k,j.opts.specialEasing);g>f;f++)if(d=gb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,db,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}r.Animation=r.extend(gb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return da(c.elem,a,_.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(K);for(var c,d=0,e=a.length;e>d;d++)c=a[d],gb.tweeners[c]=gb.tweeners[c]||[],gb.tweeners[c].unshift(b)},prefilters:[eb],prefilter:function(a,b){b?gb.prefilters.unshift(a):gb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:e.duration="number"==typeof e.duration?e.duration:e.duration in r.fx.speeds?r.fx.speeds[e.duration]:r.fx.speeds._default,null!=e.queue&&e.queue!==!0||(e.queue="fx"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ba).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=gb(this,r.extend({},a),f);(e||V.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&_a.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=V.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(cb(b,!0),a,d,e)}}),r.each({slideDown:cb("show"),slideUp:cb("hide"),slideToggle:cb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Ya=r.now();b1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c); +}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\t\r\n\f]/g;function mb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=mb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(c)+" ").replace(lb," ").indexOf(b)>-1)return!0;return!1}});var nb=/\r/g,ob=/[\x20\t\r\n\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(nb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:r.trim(r.text(a)).replace(ob," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,"optgroup"))){if(b=r(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){return r.isArray(b)?a.checked=r.inArray(r(a).val(),b)>-1:void 0}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?r.event.trigger(a,b,c,!0):void 0}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,""),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&300>b||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",0>b&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;return o.cors||Pb&&!b.crossDomain?{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}:void 0}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("') + + +@login_required +def create_hostel_leave(request): + + if request.method == 'GET': + return render(request, 'hostelmanagement/create_leave.html') + elif request.method == 'POST': + data = request.POST # Assuming you are sending form data via POST request + student_name = data.get('student_name') + roll_num = data.get('roll_num') + phone_number = data.get('phone_number') # Retrieve phone number from form data + reason = data.get('reason') + start_date = data.get('start_date', timezone.now()) + end_date = data.get('end_date') + + + # Create HostelLeave object and save to the database + leave = HostelLeave.objects.create( + student_name=student_name, + roll_num=roll_num, + phone_number=phone_number, # Include phone number in the object creation + reason=reason, + start_date=start_date, + end_date=end_date, + + ) + caretakers = HallCaretaker.objects.all() + sender = request.user + type = "leave_request" + for caretaker in caretakers: + try: + # Send notification + hostel_notifications(sender, caretaker.staff.id.user, type) + except Exception as e: + # Handle notification sending error + print(f"Error sending notification to caretaker {caretaker.staff.user.username}: {e}") + + return JsonResponse({'message': 'HostelLeave created successfully'}, status=status.HTTP_201_CREATED) + +# hostel_complaints_list caretaker can see all hostel complaints + +@login_required +def hostel_complaint_list(request): + user_id = request.user.id + + try: + # Assuming the user's profile is stored in extrainfo + staff = request.user.extrainfo.id + except AttributeError: + staff = None + + if staff is not None and HallCaretaker.objects.filter(staff_id=staff).exists(): + complaints = HostelComplaint.objects.all() + return render(request, 'hostelmanagement/hostel_complaint.html', {'complaints': complaints}) + else: + return HttpResponse('') + + +@login_required +def get_students(request): + try: + staff = request.user.extrainfo.id + print(staff) + except AttributeError: + staff = None + + if HallCaretaker.objects.filter(staff_id=staff).exists(): + hall_id = HallCaretaker.objects.get(staff_id=staff).hall_id + print(hall_id) + hall_no = Hall.objects.get(id=hall_id) + print(hall_no) + student_details = StudentDetails.objects.filter(hall_id=hall_no) + + return render(request, 'hostelmanagement/student_details.html', {'students': student_details}) + + elif HallWarden.objects.filter(faculty_id=staff).exists(): + hall_id = HallWarden.objects.get(faculty_id=staff).hall_id + student_details = StudentDetails.objects.filter(hall_id=hall_no) + + return render(request, 'hostelmanagement/student_details.html', {'students': student_details}) + else: + return HttpResponse('') + +# Student can post complaints + + +class PostComplaint(APIView): + # Assuming you are using session authentication + authentication_classes = [SessionAuthentication] + # Allow only authenticated users to access the view + permission_classes = [IsAuthenticated] + + def dispatch(self, request, *args, **kwargs): + # print(request.user.username) + if not request.user.is_authenticated: + # Redirect to the login page if user is not authenticated + return redirect('/hostelmanagement') + return super().dispatch(request, *args, **kwargs) + + def get(self, request): + return render(request, 'hostelmanagement/post_complaint_form.html') + + def post(self, request): + hall_name = request.data.get('hall_name') + student_name = request.data.get('student_name') + roll_number = request.data.get('roll_number') + description = request.data.get('description') + contact_number = request.data.get('contact_number') + + # Assuming the student's name is stored in the user object + student_name = request.user.username + + complaint = HostelComplaint.objects.create( + hall_name=hall_name, + student_name=student_name, + roll_number=roll_number, + description=description, + contact_number=contact_number + ) + + # Use JavaScript to display a pop-up message after submission + return HttpResponse('') + + +# // student can see his leave status + +class my_leaves(View): + @method_decorator(login_required, name='dispatch') + def get(self, request, *args, **kwargs): + try: + # Get the user ID from the request's user + user_id = str(request.user) + + # Retrieve leaves registered by the current student based on their roll number + my_leaves = HostelLeave.objects.filter(roll_num__iexact=user_id) + # Construct the context to pass to the template + context = { + 'leaves': my_leaves + } + + # Render the template with the context data + return render(request, 'hostelmanagement/my_leaves.html', context) + + except User.DoesNotExist: + # Handle the case where the user with the given ID doesn't exist + return HttpResponse(f"User with ID {user_id} does not exist.") + + +class HallIdView(APIView): + authentication_classes = [] # Allow public access for testing + permission_classes = [] # Allow any user to access the view + + def get(self, request, *args, **kwargs): + hall_id = HostelAllotment.objects.values('hall_id') + return Response(hall_id, status=status.HTTP_200_OK) + + +@login_required(login_url=LOGIN_URL) +def logout_view(request): + logout(request) + return redirect("/") + + +@method_decorator(user_passes_test(is_superuser), name='dispatch') +class AssignCaretakerView(APIView): + authentication_classes = [SessionAuthentication] + permission_classes = [IsAuthenticated] + template_name = 'hostelmanagement/assign_caretaker.html' + + def get(self, request, *args, **kwargs): + hall = Hall.objects.all() + caretaker_usernames = Staff.objects.all() + return render(request, self.template_name, {'halls': hall, 'caretaker_usernames': caretaker_usernames}) + + def post(self, request, *args, **kwargs): + hall_id = request.data.get('hall_id') + caretaker_username = request.data.get('caretaker_username') + + try: + hall = Hall.objects.get(hall_id=hall_id) + caretaker_staff = Staff.objects.get( + id__user__username=caretaker_username) + + # Retrieve the previous caretaker for the hall, if any + prev_hall_caretaker = HallCaretaker.objects.filter(hall=hall).first() + # print(prev_hall_caretaker.staff.id) + # Delete any previous assignments of the caretaker in HallCaretaker table + HallCaretaker.objects.filter(staff=caretaker_staff).delete() + + # Delete any previous assignments of the caretaker in HostelAllotment table + HostelAllotment.objects.filter( + assignedCaretaker=caretaker_staff).delete() + + # Delete any previously assigned caretaker to the same hall + HallCaretaker.objects.filter(hall=hall).delete() + + # Assign the new caretaker to the hall in HallCaretaker table + hall_caretaker = HallCaretaker.objects.create( + hall=hall, staff=caretaker_staff) + + # # Update the assigned caretaker in Hostelallottment table + hostel_allotments = HostelAllotment.objects.filter(hall=hall) + for hostel_allotment in hostel_allotments: + hostel_allotment.assignedCaretaker = caretaker_staff + hostel_allotment.save() + + # Retrieve the current warden for the hall + current_warden = HallWarden.objects.filter(hall=hall).first() + + try: + history_entry = HostelTransactionHistory.objects.create( + hall=hall, + change_type='Caretaker', + previous_value= prev_hall_caretaker.staff.id if (prev_hall_caretaker and prev_hall_caretaker.staff) else 'None', + new_value=caretaker_username + ) + except Exception as e: + print("Error creating HostelTransactionHistory:", e) + + + # Create hostel history + try: + HostelHistory.objects.create( + hall=hall, + caretaker=caretaker_staff, + batch=hall.assigned_batch, + warden=current_warden.faculty if( current_warden and current_warden.faculty) else None + ) + except Exception as e: + print ("Error creating history",e) + return Response({'message': f'Caretaker {caretaker_username} assigned to Hall {hall_id} successfully'}, status=status.HTTP_201_CREATED) + + except Hall.DoesNotExist: + return Response({'error': f'Hall with ID {hall_id} not found'}, status=status.HTTP_404_NOT_FOUND) + except Staff.DoesNotExist: + return Response({'error': f'Caretaker with username {caretaker_username} not found'}, status=status.HTTP_404_NOT_FOUND) + except Exception as e: + return JsonResponse({'status': 'error', 'error': str(e)}, status=500) + + + +@method_decorator(user_passes_test(is_superuser), name='dispatch') +class AssignBatchView(View): + authentication_classes = [SessionAuthentication] + permission_classes = [IsAuthenticated] + # Assuming the HTML file is directly in the 'templates' folder + template_name = 'hostelmanagement/assign_batch.html' + + def get(self, request, *args, **kwargs): + hall = Hall.objects.all() + return render(request, self.template_name, {'halls': hall}) + + def update_student_hall_allotment(self, hall, assigned_batch): + hall_number = int(''.join(filter(str.isdigit, hall.hall_id))) + students = Student.objects.filter(batch=int(assigned_batch)) + + + for student in students: + student.hall_no = hall_number + student.save() + + + def post(self, request, *args, **kwargs): + try: + with transaction.atomic(): # Start a database transaction + + data = json.loads(request.body.decode('utf-8')) + hall_id = data.get('hall_id') + + hall = Hall.objects.get(hall_id=hall_id) + # previous_batch = hall.assigned_batch # Get the previous batch + previous_batch = hall.assigned_batch if hall.assigned_batch is not None else 0 # Get the previous batch + hall.assigned_batch = data.get('batch') + hall.save() + + + + + + # Update the assignedBatch field in HostelAllotment table for the corresponding hall + room_allotments = HostelAllotment.objects.filter(hall=hall) + for room_allotment in room_allotments: + room_allotment.assignedBatch = hall.assigned_batch + room_allotment.save() + + # retrieve the current caretaker and current warden for the hall + current_caretaker =HallCaretaker.objects.filter(hall=hall).first() + current_warden = HallWarden.objects.filter(hall=hall).first() + + # Record the transaction history + HostelTransactionHistory.objects.create( + hall=hall, + change_type='Batch', + previous_value=previous_batch, + new_value=hall.assigned_batch + ) + + # Create hostel history + try: + HostelHistory.objects.create( + hall=hall, + caretaker=current_caretaker.staff if (current_caretaker and current_caretaker.staff) else None, + + batch=hall.assigned_batch, + warden=current_warden.faculty if( current_warden and current_warden.faculty) else None + + ) + except Exception as e: + print ("Error creating history",e) + + self.update_student_hall_allotment(hall, hall.assigned_batch) + print("batch assigned successssssssssssssssssss") + messages.success(request, 'batch assigned succesfully') + + return JsonResponse({'status': 'success', 'message': 'Batch assigned successfully'}, status=200) + + except Hall.DoesNotExist: + return JsonResponse({'status': 'error', 'error': f'Hall with ID {hall_id} not found'}, status=404) + + except Exception as e: + return JsonResponse({'status': 'error', 'error': str(e)}, status=500) + + def test_func(self): + # Check if the user is a superuser + return self.request.user.is_superuser + + +@method_decorator(user_passes_test(is_superuser), name='dispatch') +class AssignWardenView(APIView): + authentication_classes = [SessionAuthentication] + permission_classes = [IsAuthenticated] + template_name = 'hostelmanagement/assign_warden.html' + + def post(self, request, *args, **kwargs): + hall_id = request.data.get('hall_id') + warden_id = request.data.get('warden_id') + try: + hall = Hall.objects.get(hall_id=hall_id) + warden = Faculty.objects.get(id__user__username=warden_id) + + # Retrieve the previous caretaker for the hall, if any + prev_hall_warden = HallWarden.objects.filter(hall=hall).first() + + # Delete any previous assignments of the warden in Hallwarden table + HallWarden.objects.filter(faculty=warden).delete() + + # Delete any previous assignments of the warden in HostelAllotment table + HostelAllotment.objects.filter(assignedWarden=warden).delete() + + # Delete any previously assigned warden to the same hall + HallWarden.objects.filter(hall=hall).delete() + + # Assign the new warden to the hall in Hallwarden table + hall_warden = HallWarden.objects.create(hall=hall, faculty=warden) + + #current caretker + current_caretaker =HallCaretaker.objects.filter(hall=hall).first() + print(current_caretaker) + + # Update the assigned warden in Hostelallottment table + hostel_allotments = HostelAllotment.objects.filter(hall=hall) + for hostel_allotment in hostel_allotments: + hostel_allotment.assignedWarden = warden + hostel_allotment.save() + + try: + history_entry = HostelTransactionHistory.objects.create( + hall=hall, + change_type='Warden', + previous_value= prev_hall_warden.faculty.id if (prev_hall_warden and prev_hall_warden.faculty) else 'None', + new_value=warden + ) + except Exception as e: + print("Error creating HostelTransactionHistory:", e) + + + # Create hostel history + try: + HostelHistory.objects.create( + hall=hall, + caretaker=current_caretaker.staff if (current_caretaker and current_caretaker.staff) else None, + + batch=hall.assigned_batch, + warden=warden + ) + except Exception as e: + print ("Error creating history",e) + + + return Response({'message': f'Warden {warden_id} assigned to Hall {hall_id} successfully'}, status=status.HTTP_201_CREATED) + + except Hall.DoesNotExist: + return Response({'error': f'Hall with ID {hall_id} not found'}, status=status.HTTP_404_NOT_FOUND) + except Faculty.DoesNotExist: + return Response({'error': f'Warden with username {warden_id} not found'}, status=status.HTTP_404_NOT_FOUND) + except Exception as e: + return JsonResponse({'status': 'error', 'error': str(e)}, status=500) + + +@method_decorator(user_passes_test(is_superuser), name='dispatch') +class AddHostelView(View): + template_name = 'hostelmanagement/add_hostel.html' + + def get(self, request, *args, **kwargs): + form = HallForm() + return render(request, self.template_name, {'form': form}) + + def post(self, request, *args, **kwargs): + form = HallForm(request.POST) + if form.is_valid(): + hall_id = form.cleaned_data['hall_id'] + + # # Check if a hall with the given hall_id already exists + # if Hall.objects.filter(hall_id=hall_id).exists(): + # messages.error(request, f'Hall with ID {hall_id} already exists.') + # return redirect('hostelmanagement:add_hostel') + + # Check if a hall with the given hall_id already exists + if Hall.objects.filter(hall_id=hall_id).exists(): + error_message = f'Hall with ID {hall_id} already exists.' + + return HttpResponse(error_message, status=400) + + # If not, create a new hall + form.save() + messages.success(request, 'Hall added successfully!') + # Redirect to the view showing all hostels + return HttpResponseRedirect(reverse("hostelmanagement:hostel_view")) + # return render(request, 'hostelmanagement/admin_hostel_list.html') + + # If form is not valid, render the form with errors + return render(request, self.template_name, {'form': form}) + + +class CheckHallExistsView(View): + + def get(self, request, *args, **kwargs): + + hall_id = request.GET.get('hall_id') + try: + hall = Hall.objects.get(hall_id=hall_id) + exists = True + except Hall.DoesNotExist: + exists = False + messages.MessageFailure(request, f'Hall {hall_id} already exist.') + return JsonResponse({'exists': exists}) + + +@method_decorator(user_passes_test(is_superuser), name='dispatch') +class AdminHostelListView(View): + template_name = 'hostelmanagement/admin_hostel_list.html' + + def get(self, request, *args, **kwargs): + halls = Hall.objects.all() + # Create a list to store additional details + hostel_details = [] + + # Loop through each hall and fetch assignedCaretaker and assignedWarden + for hall in halls: + try: + caretaker = HallCaretaker.objects.filter(hall=hall).first() + warden = HallWarden.objects.filter(hall=hall).first() + except HostelAllotment.DoesNotExist: + assigned_caretaker = None + assigned_warden = None + + hostel_detail = { + 'hall_id': hall.hall_id, + 'hall_name': hall.hall_name, + 'max_accomodation': hall.max_accomodation, + 'number_students': hall.number_students, + 'assigned_batch': hall.assigned_batch, + 'assigned_caretaker': caretaker.staff.id.user.username if caretaker else None, + 'assigned_warden': warden.faculty.id.user.username if warden else None, + } + + hostel_details.append(hostel_detail) + + return render(request, self.template_name, {'hostel_details': hostel_details}) + + +@method_decorator(user_passes_test(is_superuser), name='dispatch') +class DeleteHostelView(View): + def get(self, request, hall_id, *args, **kwargs): + # Get the hall instance + hall = get_object_or_404(Hall, hall_id=hall_id) + + # Delete related entries in other tables + hostelallotments = HostelAllotment.objects.filter(hall=hall) + hostelallotments.delete() + + # Delete the hall + hall.delete() + messages.success(request, f'Hall {hall_id} deleted successfully.') + + return HttpResponseRedirect(reverse("hostelmanagement:hostel_view")) + + +class HallIdView(APIView): + authentication_classes = [] # Allow public access for testing + permission_classes = [] # Allow any user to access the view + + def get(self, request, *args, **kwargs): + hall_id = HostelAllotment.objects.values('hall_id') + return Response(hall_id, status=status.HTTP_200_OK) + + +@login_required(login_url=LOGIN_URL) +def logout_view(request): + logout(request) + return redirect("/") + + +# //! alloted_rooms +def alloted_rooms(request, hall_id): + """ + This function returns the allotted rooms in a particular hall. + + @param: + request - HttpRequest object containing metadata about the user request. + hall_id - Hall ID for which the allotted rooms need to be retrieved. + + @variables: + allotted_rooms - stores all the rooms allotted in the given hall. + """ + # Query the hall by hall_id + hall = Hall.objects.get(hall_id=hall_id) + # Query all rooms allotted in the given hall + allotted_rooms = HallRoom.objects.filter(hall=hall, room_occupied__gt=0) + # Prepare a list of room details to be returned + room_details = [] + for room in allotted_rooms: + room_details.append({ + 'hall': room.hall.hall_id, + 'room_no': room.room_no, + 'block_no': room.block_no, + 'room_cap': room.room_cap, + 'room_occupied': room.room_occupied + }) + return JsonResponse(room_details, safe=False) + + +def alloted_rooms_main(request): + """ + This function returns the allotted rooms in all halls. + + @param: + request - HttpRequest object containing metadata about the user request. + + @variables: + all_halls - stores all the halls. + all_rooms - stores all the rooms allotted in all halls. + """ + # Query all halls + all_halls = Hall.objects.all() + + # Query all rooms allotted in all halls + all_rooms = [] + for hall in all_halls: + all_rooms.append(HallRoom.objects.filter( + hall=hall, room_occupied__gt=0)) + + # Prepare a list of room details to be returned + room_details = [] + for rooms in all_rooms: + for room in rooms: + room_details.append({ + 'hall': room.hall.hall_name, + 'room_no': room.room_no, + 'block_no': room.block_no, + 'room_cap': room.room_cap, + 'room_occupied': room.room_occupied + }) + + # Return the room_details as JSON response + return render(request, 'hostelmanagement/alloted_rooms_main.html', {'allotted_rooms': room_details, 'halls': all_halls}) + + +# //! all_staff +def all_staff(request, hall_id): + """ + This function returns all staff information for a specific hall. + + @param: + request - HttpRequest object containing metadata about the user request. + hall_id - The ID of the hall for which staff information is requested. + + + @variables: + all_staff - stores all staff information for the specified hall. + """ + + # Query all staff information for the specified hall + all_staff = StaffSchedule.objects.filter(hall_id=hall_id) + + # Prepare a list of staff details to be returned + staff_details = [] + for staff in all_staff: + staff_details.append({ + 'type': staff.staff_type, + 'staff_id': staff.staff_id_id, + 'hall_id': staff.hall_id, + 'day': staff.day, + 'start_time': staff.start_time, + 'end_time': staff.end_time + }) + + # Return the staff_details as JSON response + return JsonResponse(staff_details, safe=False) + + +# //! Edit Stuff schedule +class StaffScheduleView(APIView): + """ + API endpoint for creating or editing staff schedules. + """ + + authentication_classes = [] # Allow public access for testing + permission_classes = [] # Allow any user to access the view + + def patch(self, request, staff_id): + staff = get_object_or_404(Staff, pk=staff_id) + staff_type = request.data.get('staff_type') + start_time = request.data.get('start_time') + end_time = request.data.get('end_time') + day = request.data.get('day') + + + if start_time and end_time and day and staff_type: + # Check if staff schedule exists for the given day + existing_schedule = StaffSchedule.objects.filter( + staff_id=staff_id).first() + if existing_schedule: + existing_schedule.start_time = start_time + existing_schedule.end_time = end_time + existing_schedule.day = day + existing_schedule.staff_type = staff_type + existing_schedule.save() + return Response({"message": "Staff schedule updated successfully."}, status=status.HTTP_200_OK) + else: + # If staff schedule doesn't exist for the given day, return 404 + return Response({"error": "Staff schedule does not exist for the given day."}, status=status.HTTP_404_NOT_FOUND) + + return Response({"error": "Please provide start_time, end_time, and day."}, status=status.HTTP_400_BAD_REQUEST) + + +# //! Hostel Inventory + +@login_required +def get_inventory_form(request): + user_id = request.user + # print("user_id",user_id) + staff = user_id.extrainfo.id + # print("staff",staff) + + # Check if the user is present in the HallCaretaker table + if HallCaretaker.objects.filter(staff_id=staff).exists(): + # If the user is a caretaker, allow access + halls = Hall.objects.all() + return render(request, 'hostelmanagement/inventory_form.html', {'halls': halls}) + else: + # If the user is not a caretaker, redirect to the login page + # return redirect('login') # Adjust 'login' to your login URL name + return HttpResponse(f'') + + +@login_required +def edit_inventory(request, inventory_id): + # Retrieve hostel inventory object + inventory = get_object_or_404(HostelInventory, pk=inventory_id) + + # Check if the user is a caretaker + user_id = request.user + staff_id = user_id.extrainfo.id + + if HallCaretaker.objects.filter(staff_id=staff_id).exists(): + halls = Hall.objects.all() + + # Prepare inventory data for rendering + inventory_data = { + 'inventory_id': inventory.inventory_id, + 'hall_id': inventory.hall_id, + 'inventory_name': inventory.inventory_name, + 'cost': str(inventory.cost), # Convert DecimalField to string + 'quantity': inventory.quantity, + } + + # Render the inventory update form with inventory data + return render(request, 'hostelmanagement/inventory_update_form.html', {'inventory': inventory_data, 'halls': halls}) + else: + # If the user is not a caretaker, show a message and redirect + return HttpResponse('') + + +class HostelInventoryUpdateView(APIView): + authentication_classes = [SessionAuthentication] + permission_classes = [IsAuthenticated] + + @method_decorator(login_required) + def dispatch(self, *args, **kwargs): + return super().dispatch(*args, **kwargs) + + def post(self, request, inventory_id): + user_id = request.user + staff_id = user_id.extrainfo.id + + if not HallCaretaker.objects.filter(staff_id=staff_id).exists(): + return Response({'error': 'You are not authorized to update this hostel inventory'}, status=status.HTTP_401_UNAUTHORIZED) + + hall_id = request.data.get('hall_id') + inventory_name = request.data.get('inventory_name') + cost = request.data.get('cost') + quantity = request.data.get('quantity') + + # Validate required fields + if not all([hall_id, inventory_name, cost, quantity]): + return Response({'error': 'All fields are required'}, status=status.HTTP_400_BAD_REQUEST) + + # Retrieve hostel inventory object + hostel_inventory = get_object_or_404(HostelInventory, pk=inventory_id) + + # Update hostel inventory object + hostel_inventory.hall_id = hall_id + hostel_inventory.inventory_name = inventory_name + hostel_inventory.cost = cost + hostel_inventory.quantity = quantity + hostel_inventory.save() + + # Return success response + return Response({'message': 'Hostel inventory updated successfully'}, status=status.HTTP_200_OK) + + +class HostelInventoryView(APIView): + """ + API endpoint for CRUD operations on hostel inventory. + """ + # permission_classes = [IsAuthenticated] + + # authentication_classes = [] # Allow public access for testing + # permission_classes = [] # Allow any user to access the view + + authentication_classes = [SessionAuthentication] + permission_classes = [IsAuthenticated] + + @method_decorator(login_required) + def dispatch(self, *args, **kwargs): + return super().dispatch(*args, **kwargs) + + def get(self, request, hall_id): + user_id = request.user + staff_id = user_id.extrainfo.id + + if not HallCaretaker.objects.filter(staff_id=staff_id).exists(): + return HttpResponse('') + + # Retrieve hostel inventory objects for the given hall ID + inventories = HostelInventory.objects.filter(hall_id=hall_id) + + # Get all hall IDs + halls = Hall.objects.all() + + # Serialize inventory data + inventory_data = [] + for inventory in inventories: + inventory_data.append({ + 'inventory_id': inventory.inventory_id, + 'hall_id': inventory.hall_id, + 'inventory_name': inventory.inventory_name, + 'cost': str(inventory.cost), # Convert DecimalField to string + 'quantity': inventory.quantity, + }) + + inventory_data.sort(key=lambda x: x['inventory_id']) + + # Return inventory data as JSON response + return render(request, 'hostelmanagement/inventory_list.html', {'halls': halls, 'inventories': inventory_data}) + + def post(self, request): + user_id = request.user + staff_id = user_id.extrainfo.id + + if not HallCaretaker.objects.filter(staff_id=staff_id).exists(): + return Response({'error': 'You are not authorized to create a new hostel inventory'}, status=status.HTTP_401_UNAUTHORIZED) + + # Extract data from request + hall_id = request.data.get('hall_id') + inventory_name = request.data.get('inventory_name') + cost = request.data.get('cost') + quantity = request.data.get('quantity') + + # Validate required fields + if not all([hall_id, inventory_name, cost, quantity]): + return Response({'error': 'All fields are required'}, status=status.HTTP_400_BAD_REQUEST) + + # Create hostel inventory object + try: + hostel_inventory = HostelInventory.objects.create( + hall_id=hall_id, + inventory_name=inventory_name, + cost=cost, + quantity=quantity + ) + return Response({'message': 'Hostel inventory created successfully', 'hall_id': hall_id}, status=status.HTTP_201_CREATED) + except Exception as e: + return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + def delete(self, request, inventory_id): + user_id = request.user + staff_id = user_id.extrainfo.id + + if not HallCaretaker.objects.filter(staff_id=staff_id).exists(): + return Response({'error': 'You are not authorized to delete this hostel inventory'}, status=status.HTTP_401_UNAUTHORIZED) + + inventory = get_object_or_404(HostelInventory, pk=inventory_id) + inventory.delete() + return Response({'message': 'Hostel inventory deleted successfully'}, status=status.HTTP_204_NO_CONTENT) + + +def update_allotment(request, pk): + if request.method == 'POST': + try: + allotment = HostelAllottment.objects.get(pk=pk) + except HostelAllottment.DoesNotExist: + return JsonResponse({'error': 'HostelAllottment not found'}, status=404) + + try: + allotment.assignedWarden = Faculty.objects.get( + id=request.POST['warden_id']) + allotment.assignedCaretaker = Staff.objects.get( + id=request.POST['caretaker_id']) + allotment.assignedBatch = request.POST.get( + 'student_batch', allotment.assignedBatch) + allotment.save() + return JsonResponse({'success': 'HostelAllottment updated successfully'}) + except (Faculty.DoesNotExist, Staff.DoesNotExist, IntegrityError): + return JsonResponse({'error': 'Invalid data or integrity error'}, status=400) + + return JsonResponse({'error': 'Invalid request method'}, status=405) + + +@login_required +def request_guest_room(request): + """ + This function is used by the student to book a guest room. + @param: + request - HttpRequest object containing metadata about the user request. + """ + if request.method == "POST": + form = GuestRoomBookingForm(request.POST) + + if form.is_valid(): + # print("Inside valid") + hall = form.cleaned_data['hall'] + guest_name = form.cleaned_data['guest_name'] + guest_phone = form.cleaned_data['guest_phone'] + guest_email = form.cleaned_data['guest_email'] + guest_address = form.cleaned_data['guest_address'] + rooms_required = form.cleaned_data['rooms_required'] + total_guest = form.cleaned_data['total_guest'] + purpose = form.cleaned_data['purpose'] + arrival_date = form.cleaned_data['arrival_date'] + arrival_time = form.cleaned_data['arrival_time'] + departure_date = form.cleaned_data['departure_date'] + departure_time = form.cleaned_data['departure_time'] + nationality = form.cleaned_data['nationality'] + room_type = form.cleaned_data['room_type'] # Add room type + + + max_guests = { + 'single': 1, + 'double': 2, + 'triple': 3, + } + # Fetch available room count based on room type and hall + available_rooms_count = GuestRoom.objects.filter( + hall=hall, room_type=room_type, vacant=True + ).count() + + # Check if there are enough available rooms + if available_rooms_count < rooms_required: + messages.error(request, "Not enough available rooms.") + return HttpResponseRedirect(reverse("hostelmanagement:hostel_view")) + + # Check if the number of guests exceeds the capacity of selected rooms + if total_guest > rooms_required * max_guests.get(room_type, 1): + messages.error(request, "Number of guests exceeds the capacity of selected rooms.") + return HttpResponseRedirect(reverse("hostelmanagement:hostel_view")) + + + newBooking = GuestRoomBooking.objects.create(hall=hall, intender=request.user, guest_name=guest_name, guest_address=guest_address, + guest_phone=guest_phone, guest_email=guest_email, rooms_required=rooms_required, total_guest=total_guest, purpose=purpose, + arrival_date=arrival_date, arrival_time=arrival_time, departure_date=departure_date, departure_time=departure_time, nationality=nationality,room_type=room_type) + newBooking.save() + messages.success(request, "Room request submitted successfully!") + + + # Get the caretaker for the selected hall + hall_caretaker = HallCaretaker.objects.get(hall=hall) + caretaker = hall_caretaker.staff.id.user + # Send notification to caretaker + hostel_notifications(sender=request.user, recipient=caretaker, type='guestRoom_request') + + return HttpResponseRedirect(reverse("hostelmanagement:hostel_view")) + else: + messages.error(request, "Something went wrong") + return HttpResponseRedirect(reverse("hostelmanagement:hostel_view")) + + +@login_required +def update_guest_room(request): + if request.method == "POST": + if 'accept_request' in request.POST: + status = request.POST['status'] + guest_room_request = GuestRoomBooking.objects.get( + pk=request.POST['accept_request']) + guest_room_instance = GuestRoom.objects.get( + hall=guest_room_request.hall, room=request.POST['guest_room_id']) + + # Assign the guest room ID to guest_room_id field + guest_room_request.guest_room_id = str(guest_room_instance.id) + + # Update the assigned guest room's occupancy details + guest_room_instance.occupied_till = guest_room_request.departure_date + guest_room_instance.vacant = False # Mark the room as occupied + guest_room_instance.save() + + # Update the occupied_till field of the room_booked + room_booked = GuestRoom.objects.get( + hall=guest_room_request.hall, room=request.POST['guest_room_id']) + room_booked.occupied_till = guest_room_request.departure_date + room_booked.save() + + # Save the guest room request after updating the fields + guest_room_request.status = status + guest_room_request.save() + messages.success(request, "Request accepted successfully!") + + hostel_notifications(sender=request.user,recipient=guest_room_request.intender,type='guestRoom_accept') + + + elif 'reject_request' in request.POST: + guest_room_request = GuestRoomBooking.objects.get( + pk=request.POST['reject_request']) + guest_room_request.status = 'Rejected' + guest_room_request.save() + + messages.success(request, "Request rejected successfully!") + + hostel_notifications(sender=request.user,recipient=guest_room_request.intender,type='guestRoom_reject') + + else: + messages.error(request, "Invalid request!") + return HttpResponseRedirect(reverse("hostelmanagement:hostel_view")) + + +def available_guestrooms_api(request): + if request.method == 'GET': + + hall_id = request.GET.get('hall_id') + room_type = request.GET.get('room_type') + + if hall_id and room_type: + available_rooms_count = GuestRoom.objects.filter(hall_id=hall_id, room_type=room_type, vacant=True).count() + return JsonResponse({'available_rooms_count': available_rooms_count}) + + return JsonResponse({'error': 'Invalid request'}, status=400) + + +# //Caretaker can approve or reject leave applied by the student +@csrf_exempt +def update_leave_status(request): + if request.method == 'POST': + leave_id = request.POST.get('leave_id') + status = request.POST.get('status') + try: + leave = HostelLeave.objects.get(id=leave_id) + leave.status = status + leave.remark = request.POST.get('remark') + leave.save() + + # Send notification to the student + sender = request.user # Assuming request.user is the caretaker + + student_id = leave.roll_num # Assuming student is a foreign key field in HostelLeave model + recipient = User.objects.get(username=student_id) + type = "leave_accept" if status == "Approved" else "leave_reject" + hostel_notifications(sender, recipient, type) + + return JsonResponse({'status': status,'remarks':leave.remark,'message': 'Leave status updated successfully.'}) + except HostelLeave.DoesNotExist: + return JsonResponse({'status': 'error', 'message': 'Leave not found.'}, status=404) + else: + return JsonResponse({'status': 'error', 'message': 'Only POST requests are allowed.'}, status=405) + + +# //! Manage Fine +# //! Add Fine Functionality + + +@login_required +def show_fine_edit_form(request,fine_id): + user_id = request.user + staff = user_id.extrainfo.id + caretaker = HallCaretaker.objects.get(staff_id=staff) + hall_id = caretaker.hall_id + + fine = HostelFine.objects.filter(fine_id=fine_id) + + + + return render(request, 'hostelmanagement/impose_fine_edit.html', {'fines': fine[0]}) + +@login_required +def update_student_fine(request,fine_id): + if request.method == 'POST': + fine = HostelFine.objects.get(fine_id=fine_id) + print("------------------------------------------------") + print(request.POST) + fine.amount = request.POST.get('amount') + fine.status = request.POST.get('status') + fine.reason = request.POST.get('reason') + fine.save() + + return HttpResponse({'message': 'Fine has edited successfully'}, status=status.HTTP_200_OK) + + +@login_required +def impose_fine_view(request): + user_id = request.user + staff = user_id.extrainfo.id + students = Student.objects.all() + + if HallCaretaker.objects.filter(staff_id=staff).exists(): + return render(request, 'hostelmanagement/impose_fine.html', {'students': students}) + + return HttpResponse(f'') + + +class HostelFineView(APIView): + """ + API endpoint for imposing fines on students. + """ + authentication_classes = [SessionAuthentication] + permission_classes = [IsAuthenticated] + + @method_decorator(login_required) + def dispatch(self, *args, **kwargs): + return super().dispatch(*args, **kwargs) + + def post(self, request): + # Check if the user is a caretaker + user_id = request.user + staff = user_id.extrainfo.id + + try: + caretaker = HallCaretaker.objects.get(staff_id=staff) + except HallCaretaker.DoesNotExist: + return HttpResponse(f'') + + hall_id = caretaker.hall_id + + # Extract data from the request + student_id = request.data.get('student_id') + student_name = request.data.get('student_fine_name') + amount = request.data.get('amount') + reason = request.data.get('reason') + + # Validate the data + if not all([student_id, student_name, amount, reason]): + return HttpResponse({'error': 'Incomplete data provided.'}, status=status.HTTP_400_BAD_REQUEST) + + # Create the HostelFine object + try: + fine = HostelFine.objects.create( + student_id=student_id, + student_name=student_name, + amount=amount, + reason=reason, + hall_id=hall_id + ) + # Sending notification to the student about the imposed fine + + + + recipient = User.objects.get(username=student_id) + + sender = request.user + + type = "fine_imposed" + hostel_notifications(sender, recipient, type) + + return HttpResponse({'message': 'Fine imposed successfully.'}, status=status.HTTP_201_CREATED) + except Exception as e: + return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + +@login_required +def get_student_name(request, username): + try: + user = User.objects.get(username=username) + full_name = f"{user.first_name} {user.last_name}" if user.first_name or user.last_name else "" + return JsonResponse({"name": full_name}) + except User.DoesNotExist: + return JsonResponse({"error": "User not found"}, status=404) + + +@login_required +def hostel_fine_list(request): + user_id = request.user + staff = user_id.extrainfo.id + caretaker = HallCaretaker.objects.get(staff_id=staff) + hall_id = caretaker.hall_id + hostel_fines = HostelFine.objects.filter( + hall_id=hall_id).order_by('fine_id') + + if HallCaretaker.objects.filter(staff_id=staff).exists(): + return render(request, 'hostelmanagement/hostel_fine_list.html', {'hostel_fines': hostel_fines}) + + return HttpResponse(f'') + + +@login_required +def student_fine_details(request): + user_id = request.user.username + # print(user_id) + # staff=user_id.extrainfo.id + + # Check if the user_id exists in the Student table + # if HallCaretaker.objects.filter(staff_id=staff).exists(): + # return HttpResponse('') + + if not Student.objects.filter(id_id=user_id).exists(): + return HttpResponse('') + + # # Check if the user_id exists in the HostelFine table + if not HostelFine.objects.filter(student_id=user_id).exists(): + return HttpResponse('') + + # # Retrieve the fines associated with the current student + student_fines = HostelFine.objects.filter(student_id=user_id) + + return render(request, 'hostelmanagement/student_fine_details.html', {'student_fines': student_fines}) + + # return JsonResponse({'message': 'Nice'}, status=status.HTTP_200_OK) + + +class HostelFineUpdateView(APIView): + authentication_classes = [SessionAuthentication] + permission_classes = [IsAuthenticated] + + @method_decorator(login_required) + def dispatch(self, *args, **kwargs): + return super().dispatch(*args, **kwargs) + + def post(self, request, fine_id): + user_id = request.user + staff = user_id.extrainfo.id + + data = request.data + fine_idd = data.get('fine_id') + status_ = data.get('status') + # print("fine_idd",fine_idd) + # print("status_",status_) + + try: + caretaker = HallCaretaker.objects.get(staff_id=staff) + except HallCaretaker.DoesNotExist: + return Response({'error': 'You are not authorized to access this page'}, status=status.HTTP_403_FORBIDDEN) + + hall_id = caretaker.hall_id + + # Convert fine_id to integer + fine_id = int(fine_id) + + # Get hostel fine object + try: + hostel_fine = HostelFine.objects.get( + hall_id=hall_id, fine_id=fine_id) + except HostelFine.DoesNotExist: + raise NotFound(detail="Hostel fine not found") + + # Validate required fields + if status_ not in ['Pending', 'Paid']: + return Response({'error': 'Invalid status value'}, status=status.HTTP_400_BAD_REQUEST) + + # # Update status of the hostel fine + hostel_fine.status = status_ + hostel_fine.save() + + # Return success response + return Response({'message': 'Hostel fine status updated successfully!'}, status=status.HTTP_200_OK) + + def delete(self, request, fine_id): + user_id = request.user + staff = user_id.extrainfo.id + + try: + caretaker = HallCaretaker.objects.get(staff_id=staff) + except HallCaretaker.DoesNotExist: + return Response({'error': 'You are not authorized to access this page'}, status=status.HTTP_403_FORBIDDEN) + + hall_id = caretaker.hall_id + + # Convert fine_id to integer + fine_id = int(fine_id) + + # Get hostel fine object + try: + hostel_fine = HostelFine.objects.get( + hall_id=hall_id, fine_id=fine_id) + hostel_fine.delete() + except HostelFine.DoesNotExist: + raise NotFound(detail="Hostel fine not found") + + return Response({'message': 'Fine deleted successfully.'}, status=status.HTTP_204_NO_CONTENT) + + + + +class EditStudentView(View): + template_name = 'hostelmanagement/edit_student.html' + + def get(self, request, student_id): + student = Student.objects.get(id=student_id) + + context = {'student': student} + return render(request, self.template_name, context) + + def post(self, request, student_id): + student = Student.objects.get(id=student_id) + + # Update student details + student.id.user.first_name = request.POST.get('first_name') + student.id.user.last_name = request.POST.get('last_name') + student.programme = request.POST.get('programme') + student.batch = request.POST.get('batch') + student.hall_no = request.POST.get('hall_number') + student.room_no = request.POST.get('room_number') + student.specialization = request.POST.get('specialization') + + student.save() + + # Update phone number and address from ExtraInfo model + student.id.phone_no = request.POST.get('phone_number') + student.id.address = request.POST.get('address') + student.id.save() + student.save() + messages.success(request, 'Student details updated successfully.') + return redirect("hostelmanagement:hostel_view") + +class RemoveStudentView(View): + def post(self, request, student_id): + try: + student = Student.objects.get(id=student_id) + student.hall_no = 0 + student.save() + messages.success(request, 'Student removed successfully.') + return redirect("hostelmanagement:hostel_view") + return JsonResponse({'status': 'success', 'message': 'Student removed successfully'}) + except Student.DoesNotExist: + return JsonResponse({'status': 'error', 'message': 'Student not found'}, status=404) + except Exception as e: + return JsonResponse({'status': 'error', 'message': str(e)}, status=500) + + def dispatch(self, request, *args, **kwargs): + if request.method != 'POST': + return JsonResponse({'status': 'error', 'message': 'Method Not Allowed'}, status=405) + return super().dispatch(request, *args, **kwargs) + + diff --git a/FusionIIIT/applications/hr2/a.py b/FusionIIIT/applications/hr2/a.py new file mode 100644 index 000000000..a308ef3ad --- /dev/null +++ b/FusionIIIT/applications/hr2/a.py @@ -0,0 +1,75 @@ +def reverse_ltc_pre_processing(data): + reversed_data = {} + + # Copying over simple key-value pairs + simple_keys = [ + 'block_year', 'pf_no', 'basic_pay_salary', 'name', 'designation', 'department_info', + 'leave_availability', 'leave_start_date', 'leave_end_date', 'date_of_leave_for_family', + 'nature_of_leave', 'purpose_of_leave', 'hometown_or_not', 'place_of_visit', + 'address_during_leave', 'amount_of_advance_required', 'certified_family_dependents', + 'certified_advance', 'adjusted_month', 'date', 'phone_number_for_contact' + ] + for key in simple_keys: + value = data[key] + reversed_data[key] = value if value != 'None' else '' + + # Reversing array-like values + reversed_data['details_of_family_members_already_done'] = data['details_of_family_members_already_done'].split(',') + + family_members_about_to_avail = data['family_members_about_to_avail'].split(',') + for index, value in enumerate(family_members_about_to_avail): + family_members_about_to_avail[index] = value if value != 'None' else '' + + reversed_data['info_1_1'] = family_members_about_to_avail[0] + reversed_data['info_1_2'] = family_members_about_to_avail[1] + reversed_data['info_1_3'] = family_members_about_to_avail[2] + reversed_data['info_2_1'] = family_members_about_to_avail[3] + reversed_data['info_2_2'] = family_members_about_to_avail[4] + reversed_data['info_2_3'] = family_members_about_to_avail[5] + reversed_data['info_3_1'] = family_members_about_to_avail[6] + reversed_data['info_3_2'] = family_members_about_to_avail[7] + reversed_data['info_3_3'] = family_members_about_to_avail[8] + + # Reversing details_of_dependents + details_of_dependents = data['details_of_dependents'].split(',') + for i in range(1, 7): + for j in range(1, 4): + key = f'd_info_{i}_{j}' + value = details_of_dependents.pop(0) + reversed_data[key] = value if value != 'None' else '' + + return reversed_data + +# Sample data +data = { + 'block_year': '232', 'pf_no': '4324', 'basic_pay_salary': '324', 'name': 'sdf', 'designation': 'fds', + 'department_info': 'dfs', 'leave_availability': 'True', 'leave_start_date': '2024-03-13', + 'leave_end_date': '2024-03-17', 'date_of_leave_for_family': '2024-03-16', 'nature_of_leave': 'erds', + 'purpose_of_leave': 'fds', 'hometown_or_not': 'True', 'place_of_visit': 'fds', 'address_during_leave': 'dfsfsdf', + 'details_of_family_members_already_done': 'fds,dfs,dfs', 'family_members_about_to_avail': '1,dfsf,21,2,dsf,23,3,dfs,12', + 'details_of_dependents': '1,ds,12,2,sds,2,3,ds,13,None,None,None,None,None,None,None,None,None', 'amount_of_advance_required': '1221', + 'certified_family_dependents': '213', 'certified_advance': '213', 'adjusted_month': '213', 'date': '2024-03-15', + 'phone_number_for_contact': '21313123132' +} + +# Reverse processing +reversed_data = reverse_ltc_pre_processing(data) +print(reversed_data) + + + +{'block_year': 232, 'pf_no': None, 'basic_pay_salary': 324, 'name': 'sdf', 'designation': 'fds', + 'department_info': 'dfs', 'leave_availability': True, 'leave_start_date': datetime.date(2024, 3, 13), + 'leave_end_date': datetime.date(2024, 3, 17), 'date_of_leave_for_family': datetime.date(2024, 3, 16), + 'nature_of_leave': 'erds', 'purpose_of_leave': 'fds', 'hometown_or_not': True, 'place_of_visit': 'fds', + 'address_during_leave': 'dfsfsdf', 'amount_of_advance_required': 1221, 'certified_family_dependents': '213', + 'certified_advance': 213, 'adjusted_month': '213', 'date': datetime.date(2024, 3, 15), + 'phone_number_for_contact': 21313123132, + 'details_of_family_members_already_done': ['fds', 'dfs', 'dfs'], + 'info_1_1': '1', 'info_1_2': 'dfsf', 'info_1_3': '21', 'info_2_1': + '2', 'info_2_2': 'dsf', 'info_2_3': '23', 'info_3_1': '3', 'info_3_2': + 'dfs', 'info_3_3': '12', 'd_info_1_1': '1', 'd_info_1_2': 'ds', 'd_info_1_3': + '12', 'd_info_2_1': '2', 'd_info_2_2': 'sds', 'd_info_2_3': '2', 'd_info_3_1': '3', + 'd_info_3_2': 'ds', 'd_info_3_3': '13', 'd_info_4_1': '', 'd_info_4_2': '', 'd_info_4_3': '', + + 'd_info_5_1': '', 'd_info_5_2': '', 'd_info_5_3': '', 'd_info_6_1': '', 'd_info_6_2': '', 'd_info_6_3': ''} diff --git a/FusionIIIT/applications/hr2/admin.py b/FusionIIIT/applications/hr2/admin.py index ddd58944c..3c9b8379a 100644 --- a/FusionIIIT/applications/hr2/admin.py +++ b/FusionIIIT/applications/hr2/admin.py @@ -1,7 +1,7 @@ from django.contrib import admin -from .models import Employee,EmpConfidentialDetails,ForeignService,EmpDependents,EmpAppraisalForm,WorkAssignemnt - +from .models import * +# from .models import CPDAReimbursementform # Register your models here. admin.site.register(Employee) @@ -9,4 +9,10 @@ admin.site.register(EmpDependents) admin.site.register(ForeignService) admin.site.register(EmpAppraisalForm) -admin.site.register(WorkAssignemnt) \ No newline at end of file +admin.site.register(WorkAssignemnt) +admin.site.register(LeaveBalance) +admin.site.register(LeaveForm) +admin.site.register(LTCform) +admin.site.register(Appraisalform) +admin.site.register(CPDAAdvanceform) +admin.site.register(CPDAReimbursementform) \ No newline at end of file diff --git a/FusionIIIT/applications/hr2/api/form_views.py b/FusionIIIT/applications/hr2/api/form_views.py new file mode 100644 index 000000000..66d4de382 --- /dev/null +++ b/FusionIIIT/applications/hr2/api/form_views.py @@ -0,0 +1,538 @@ +from .serializers import LTC_serializer, CPDAAdvance_serializer, Appraisal_serializer, CPDAReimbursement_serializer, Leave_serializer, LeaveBalanace_serializer +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status +# from rest_framework.decorators import permission_classes, api_view +from rest_framework.permissions import IsAuthenticated, AllowAny +from applications.hr2.models import LTCform, CPDAAdvanceform, CPDAReimbursementform, LeaveForm, Appraisalform, LeaveBalance +from django.contrib.auth import get_user_model +from django.core.exceptions import MultipleObjectsReturned +from applications.filetracking.sdk.methods import * +from applications.globals.models import Designation, HoldsDesignation +from applications.filetracking.models import * +# from django.contrib.auth.models import User + + +class LTC(APIView): + serializer_class = LTC_serializer + permission_classes = (AllowAny, ) + + def post(self, request): + user_info = request.data[1] + print(request.data) + serializer = self.serializer_class(data=request.data[0]) + if serializer.is_valid(): + serializer.save() + fileId = create_file(uploader=user_info['uploader_name'], uploader_designation=user_info['uploader_designation'], receiver=user_info['receiver_name'], + receiver_designation=user_info['receiver_designation'], src_module="HR", src_object_id=str(serializer.data['id']), file_extra_JSON={"type": "LTC"}, attached_file=None) + # forwarded = forward_file(file_id=fileId, receiver=user_info['receiver_name'], receiver_designation=user_info['receiver_designation'], + # remarks="Forwarded to Receiver Inbox", file_extra_JSON={"type": "LTC"}) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + print(serializer.errors) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def get(self, request, *args, **kwargs): + pk = request.query_params.get("name") + try: + forms = LTCform.objects.get(created_by=pk) + serializer = self.serializer_class(forms, many=False) + except MultipleObjectsReturned: + forms = LTCform.objects.filter(created_by=pk) + serializer = self.serializer_class(forms, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + pk = request.query_params.get("id") + receiver = request.data[0] + # send_to = receiver['receiver'] + # receiver_value = User.objects.get(username=send_to) + # receiver_value_designation = HoldsDesignation.objects.filter( + # user=receiver_value) + # lis = list(receiver_value_designation) + # obj = lis[0].designation + form = LTCform.objects.get(id=pk) + serializer = self.serializer_class(form, data=request.data[1]) + if serializer.is_valid(): + serializer.save() + forward_file(file_id=receiver['file_id'], receiver=receiver['receiver'], receiver_designation=receiver['receiver_designation'], + remarks=receiver['remarks'], file_extra_JSON=receiver['file_extra_JSON']) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def delete(self, request, *args, **kwargs): + id = request.query_params.get("id") + is_archived = archive_file(file_id=id) + if (is_archived): + return Response(status=status.HTTP_200_OK) + else: + return Response(status=status.HTTP_400_BAD_REQUEST) + + +class FormManagement(APIView): + permission_classes = (AllowAny, ) + + def get(self, request, *args, **kwargs): + username = request.query_params.get("username") + designation = request.query_params.get("designation") + inbox = view_inbox(username=username, + designation=designation, src_module="HR") + print(inbox) + return Response(inbox, status=status.HTTP_200_OK) + + def post(self, request, *args, **kwargs): + username = request.data['receiver'] + receiver_value = User.objects.get(username=username) + receiver_value_designation = HoldsDesignation.objects.filter( + user=receiver_value) + lis = list(receiver_value_designation) + obj = lis[0].designation + forward_file(file_id=request.data['file_id'], receiver=request.data['receiver'], receiver_designation=request.data['receiver_designation'], + remarks=request.data['remarks'], file_extra_JSON=request.data['file_extra_JSON']) + return Response(status=status.HTTP_200_OK) + + +class CPDAAdvance(APIView): + serializer_class = CPDAAdvance_serializer + permission_classes = (AllowAny, ) + + def post(self, request): + print(request.data[0]) + user_info = request.data[1] + # receiver_value = User.objects.get(username=user_info['receiver_name']) + # receiver_value_designation = HoldsDesignation.objects.filter( + # user=receiver_value) + # lis = list(receiver_value_designation) + # obj = lis[0].designation + serializer = self.serializer_class(data=request.data[0]) + if serializer.is_valid(): + serializer.save() + print('1') + fileId = create_file(uploader=user_info['uploader_name'], uploader_designation=user_info['uploader_designation'], receiver=user_info['receiver_name'], + receiver_designation=user_info['receiver_designation'], src_module="HR", src_object_id=str(serializer.data['id']), file_extra_JSON={"type": "CPDAAdvance"}, attached_file=None) + # forwarded = forward_file(file_id=fileId, receiver=user_info['receiver_name'], receiver_designation=user_info['receiver_designation'], + # remarks="Forwarded to Receiver Inbox", file_extra_JSON={"type": "CPDAAdvance"}) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def get(self, request, *args, **kwargs): + pk = request.query_params.get("name") + try: + forms = CPDAAdvanceform.objects.get(created_by=pk) + serializer = self.serializer_class(forms, many=False) + except MultipleObjectsReturned: + forms = CPDAAdvanceform.objects.filter(created_by=pk) + serializer = self.serializer_class(forms, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + pk = request.query_params.get("id") + receiver = request.data[0] + send_to = receiver['receiver'] + print(send_to) + receiver_value = User.objects.get(username=send_to) + receiver_value_designation = HoldsDesignation.objects.filter( + user=receiver_value) + lis = list(receiver_value_designation) + obj = lis[0].designation + form = CPDAAdvanceform.objects.get(id=pk) + serializer = self.serializer_class(form, data=request.data[1]) + if serializer.is_valid(): + serializer.save() + forward_file(file_id=receiver['file_id'], receiver=receiver['receiver'], receiver_designation=receiver['receiver_designation'], + remarks=receiver['remarks'], file_extra_JSON=receiver['file_extra_JSON']) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + print(serializer.errors) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def delete(self, request, *args, **kwargs): + id = request.query_params.get("id") + is_archived = archive_file(file_id=id) + if (is_archived): + return Response(status=status.HTTP_200_OK) + else: + return Response(status=status.HTTP_400_BAD_REQUEST) + + +class CPDAReimbursement(APIView): + serializer_class = CPDAReimbursement_serializer + permission_classes = (AllowAny, ) + + def post(self, request): + user_info = request.data[1] + serializer = self.serializer_class(data=request.data[0]) + if serializer.is_valid(): + serializer.save() + fileId = create_file(uploader=user_info['uploader_name'], uploader_designation=user_info['uploader_designation'], receiver=user_info['receiver_name'], + receiver_designation=user_info['receiver_designation'], src_module="HR", src_object_id=str(serializer.data['id']), file_extra_JSON={"type": "CPDAReimbursement"}, attached_file=None) + # forwarded = forward_file(file_id=fileId, receiver=user_info['receiver_name'], receiver_designation=user_info['receiver_designation'], + # remarks="Forwarded to Receiver Inbox", file_extra_JSON={"type": "CPDAReimbursement"}) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + print(serializer.errors) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def get(self, request, *args, **kwargs): + pk = request.query_params.get("name") + try: + forms = CPDAReimbursementform.objects.get(created_by=pk) + serializer = self.serializer_class(forms, many=False) + except MultipleObjectsReturned: + forms = CPDAReimbursementform.objects.filter(created_by=pk) + serializer = self.serializer_class(forms, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + pk = request.query_params.get("id") + print(request.data) + receiver = request.data[0] + # send_to = receiver['receiver'] + # receiver_value = User.objects.get(username=send_to) + # receiver_value_designation = HoldsDesignation.objects.filter( + # user=receiver_value) + # lis = list(receiver_value_designation) + # obj = lis[0].designation + form = CPDAReimbursementform.objects.get(id=pk) + serializer = self.serializer_class(form, data=request.data[1]) + if serializer.is_valid(): + serializer.save() + forward_file(file_id=receiver['file_id'], receiver=receiver['receiver'], receiver_designation=receiver['receiver_designation'], + remarks=receiver['remarks'], file_extra_JSON=receiver['file_extra_JSON']) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + print(serializer.errors) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def delete(self, request, *args, **kwargs): + id = request.query_params.get("id") + is_archived = archive_file(file_id=id) + if (is_archived): + return Response(status=status.HTTP_200_OK) + else: + return Response(status=status.HTTP_400_BAD_REQUEST) + + +class Leave(APIView): + serializer_class = Leave_serializer + permission_classes = (AllowAny, ) + + def post(self, request): + user_info = request.data[1] + serializer = self.serializer_class(data=request.data[0]) + if serializer.is_valid(): + serializer.save() + fileId = create_file(uploader=user_info['uploader_name'], uploader_designation=user_info['uploader_designation'], receiver=user_info['receiver_name'], + receiver_designation=user_info['receiver_designation'], src_module="HR", src_object_id=str(serializer.data['id']), file_extra_JSON={"type": "Leave"}, attached_file=None) + # forwarded = forward_file(file_id=fileId, receiver=user_info['receiver_name'], receiver_designation=user_info['receiver_designation'], + # remarks="Forwarded to Receiver Inbox", file_extra_JSON={"type": "Leave"}) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + print(serializer.errors) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def get(self, request, *args, **kwargs): + pk = request.query_params.get("name") + try: + forms = LeaveForm.objects.get(created_by=pk) + serializer = self.serializer_class(forms, many=False) + except MultipleObjectsReturned: + forms = LeaveForm.objects.filter(created_by=pk) + serializer = self.serializer_class(forms, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + pk = request.query_params.get("id") + receiver = request.data[0] + # send_to = receiver['receiver'] + # receiver_value = User.objects.get(username=send_to) + # receiver_value_designation = HoldsDesignation.objects.filter( + # user=receiver_value) + # lis = list(receiver_value_designation) + # obj = lis[0].designation + form = LeaveForm.objects.get(id=pk) + serializer = self.serializer_class(form, data=request.data[1]) + if serializer.is_valid(): + serializer.save() + forward_file(file_id=receiver['file_id'], receiver=receiver['receiver'], receiver_designation=receiver['receiver_designation'], + remarks=receiver['remarks'], file_extra_JSON=receiver['file_extra_JSON']) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def delete(self, request, *args, **kwargs): + id = request.query_params.get("id") + is_archived = archive_file(file_id=id) + if (is_archived): + return Response(status=status.HTTP_200_OK) + else: + return Response(status=status.HTTP_400_BAD_REQUEST) + + +class Appraisal(APIView): + serializer_class = Appraisal_serializer + permission_classes = (AllowAny, ) + + def post(self, request): + user_info = request.data[1] + print(request.data) + serializer = self.serializer_class(data=request.data[0]) + if serializer.is_valid(): + serializer.save() + fileId = create_file(uploader=user_info['uploader_name'], uploader_designation=user_info['uploader_designation'], receiver=user_info['receiver_name'], + receiver_designation=user_info['receiver_designation'], src_module="HR", src_object_id=str(serializer.data['id']), file_extra_JSON={"type": "Appraisal"}, attached_file=None) + # forwarded = forward_file(file_id=fileId, receiver=user_info['receiver_name'], receiver_designation=user_info['receiver_designation'], + # remarks="Forwarded to Receiver Inbox", file_extra_JSON={"type": "Appraisal"}) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + print(serializer.errors) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def get(self, request, *args, **kwargs): + pk = request.query_params.get("name") + try: + forms = Appraisalform.objects.get(created_by=pk) + serializer = self.serializer_class(forms, many=False) + except MultipleObjectsReturned: + forms = Appraisalform.objects.filter(created_by=pk) + serializer = self.serializer_class(forms, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + pk = request.query_params.get("id") + print(request.data) + form = Appraisalform.objects.get(id=pk) + receiver = request.data[0] + send_to = receiver['receiver_name'] + receiver_value = User.objects.get(username=send_to) + receiver_value_designation = HoldsDesignation.objects.filter( + user=receiver_value) + lis = list(receiver_value_designation) + obj = lis[0].designation + serializer = self.serializer_class(form, data=request.data[1]) + if serializer.is_valid(): + serializer.save() + forward_file(file_id=receiver['file_id'], receiver=send_to, receiver_designation=receiver['receiver_designation'], + remarks=receiver['remarks'], file_extra_JSON=receiver['file_extra_JSON']) + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def delete(self, request, *args, **kwargs): + id = request.query_params.get("id") + is_archived = archive_file(file_id=id) + if (is_archived): + return Response(status=status.HTTP_200_OK) + else: + return Response(status=status.HTTP_400_BAD_REQUEST) + +# class Forward(APIView): +# def post(self, request, *args, **kwargs): +# forward_file(file_id = request.data['file_id'], receiver = request.data['receiver'], receiver_designation = 'hradmin', remarks = request.data['remarks'], file_extra_JSON = request.data['file_extra_JSON']) +# return Response(status = status.HTTP_200_OK) + + +class GetFormHistory(APIView): + permission_classes = (AllowAny, ) + + def get(self, request, *args, **kwargs): + print(request.query_params) + form_type = request.query_params.get("type") + id = request.query_params.get("id") + person = User.objects.get(username=id) + print(person.id) + id = person.id + if form_type == "LTC": + try: + forms = LTCform.objects.get(created_by=id) + serializer = LTC_serializer(forms, many=False) + return Response([serializer.data], status=status.HTTP_200_OK) + except MultipleObjectsReturned: + forms = LeaveForm.objects.filter(created_by=id) + serializer = LTC_serializer(forms, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + except LTCform.DoesNotExist: + return Response([], status=status.HTTP_200_OK) + elif form_type == "CPDAReimbursement": + try: + forms = CPDAReimbursementform.objects.get(created_by=id) + serializer = CPDAReimbursement_serializer(forms, many=False) + return Response([serializer.data], status=status.HTTP_200_OK) + except MultipleObjectsReturned: + forms = CPDAReimbursementform.objects.filter(created_by=id) + serializer = CPDAReimbursement_serializer(forms, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + except CPDAReimbursementform.DoesNotExist: + return Response([], status=status.HTTP_200_OK) + elif form_type == "CPDAAdvance": + try: + forms = CPDAAdvanceform.objects.get(created_by=id) + serializer = CPDAAdvance_serializer(forms, many=False) + return Response([serializer.data], status=status.HTTP_200_OK) + except MultipleObjectsReturned: + forms = CPDAAdvanceform.objects.filter(created_by=id) + serializer = CPDAAdvance_serializer(forms, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + except CPDAAdvanceform.DoesNotExist: + return Response([], status=status.HTTP_200_OK) + elif form_type == "Appraisal": + try: + forms = Appraisalform.objects.get(created_by=id) + serializer = Appraisal_serializer(forms, many=False) + return Response([serializer.data], status=status.HTTP_200_OK) + except MultipleObjectsReturned: + forms = Appraisalform.objects.filter(created_by=id) + serializer = Appraisal_serializer(forms, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + except Appraisalform.DoesNotExist: + return Response([], status=status.HTTP_200_OK) + elif form_type == "Leave": + try: + forms = LeaveForm.objects.get(created_by=id) + serializer = Leave_serializer(forms, many=False) + return Response([serializer.data], status=status.HTTP_200_OK) + except MultipleObjectsReturned: + forms = LeaveForm.objects.filter(created_by=id) + serializer = Leave_serializer(forms, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + except LeaveForm.DoesNotExist: + return Response([], status=status.HTTP_200_OK) + + +class TrackProgress(APIView): + permission_classes = (AllowAny, ) + + def get(self, request, *args, **kwargs): + file_id = request.query_params.get("id") + progress = view_history(file_id) + return Response({"status": progress}, status=status.HTTP_200_OK) + + +class FormFetch(APIView): + permission_classes = (AllowAny, ) + + def get(self, request, *args, **kwargs): + fileId = request.query_params.get("file_id") + form_id = request.query_params.get("id") + form_type = request.query_params.get("type") + if form_type == "LTC": + forms = LTCform.objects.get(id=form_id) + serializer = LTC_serializer(forms, many=False) + form = serializer.data + # print(form["created_by"]) + user = User.objects.get(id=int(form["created_by"])) + owner = Tracking.objects.filter(file_id=fileId) + current_owner = owner.last() + current_owner = current_owner.receiver_id + current_owner = current_owner.user + elif form_type == "CPDAReimbursement": + forms = CPDAReimbursementform.objects.get(id=form_id) + serializer = CPDAReimbursement_serializer(forms, many=False) + form = serializer.data + user = User.objects.get(id=int(form["created_by"])) + owner = Tracking.objects.filter(file_id=fileId) + current_owner = owner.last() + current_owner = current_owner.receiver_id + current_owner = current_owner.user + elif form_type == "CPDAAdvance": + forms = CPDAAdvanceform.objects.get(id=form_id) + serializer = CPDAAdvance_serializer(forms, many=False) + form = serializer.data + user = User.objects.get(id=int(form["created_by"])) + owner = Tracking.objects.filter(file_id=fileId) + current_owner = owner.last() + current_owner = current_owner.receiver_id + current_owner = current_owner.username + print(current_owner) + elif form_type == "Appraisal": + forms = Appraisalform.objects.get(id=form_id) + serializer = Appraisal_serializer(forms, many=False) + form = serializer.data + user = User.objects.get(id=int(form["created_by"])) + owner = Tracking.objects.filter(file_id=fileId) + current_owner = owner.last() + current_owner = current_owner.receiver_id + current_owner = current_owner.user + elif form_type == "Leave": + forms = LeaveForm.objects.get(id=form_id) + serializer = Leave_serializer(forms, many=False) + form = serializer.data + user = User.objects.get(id=int(form["created_by"])) + owner = Tracking.objects.filter(file_id=fileId) + current_owner = owner.last() + current_owner = current_owner.receiver_id + current_owner = current_owner.user + return Response({"form": serializer.data, "creator": user.username, "current_owner": current_owner}, status=status.HTTP_200_OK) + + +class CheckLeaveBalance(APIView): + permission_classes = (AllowAny, ) + serializer_class = LeaveBalanace_serializer + + def get(self, request, *args, **kwargs): + name = request.query_params.get("name") + person = User.objects.get(username=name) + id = person.id + leave_blance = LeaveBalance.objects.get(employee_id=id) + serializer = self.serializer_class(leave_blance, many=False) + return Response(serializer.data, status=status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + name = request.query_params.get("name") + person = User.objects.get(username=name) + id = person.id + leave_balance = LeaveBalance.objects.get(employee_id=id) + serializer = self.serializer_class(leave_balance, data=request.data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + +class DropDown(APIView): + permission_classes = (AllowAny, ) + + def get(self, request, *args, **kwargs): + user_id = request.query_params.get("username") + user = User.objects.get(username=user_id) + designations = HoldsDesignation.objects.filter(user=user.id) + designation_list = [] + for design in designations: + design = design.designation + design = design.name + designation_list.append(design) + return Response(designation_list, status=status.HTTP_200_OK) + + +class UserById(APIView): + permission_classes = (AllowAny, ) + + def get(self, request, *args, **kwargs): + user_id = request.query_params.get("id") + user = User.objects.get(id=user_id) + return Response({"username": user.username}, status=status.HTTP_200_OK) + + +class ViewArchived(APIView): + permission_classes = (AllowAny, ) + + def get(self, request, *args, **kwargs): + user_name = request.query_params.get("username") + user_designation = request.query_params.get("designation") + archived_inbox = view_archived( + username=user_name, designation=user_designation, src_module="HR") + return Response(archived_inbox, status=status.HTTP_200_OK) + + +class GetOutbox(APIView): + permission_classes = (AllowAny, ) + + def get(self, request, *args, **kwargs): + name = request.query_params.get("username") + user_designation = request.query_params.get("designation") + outbox = view_outbox( + username=name, designation=user_designation, src_module="HR") + return Response(outbox, status=status.HTTP_200_OK) \ No newline at end of file diff --git a/FusionIIIT/applications/hr2/api/serializers.py b/FusionIIIT/applications/hr2/api/serializers.py new file mode 100644 index 000000000..f10854eea --- /dev/null +++ b/FusionIIIT/applications/hr2/api/serializers.py @@ -0,0 +1,56 @@ +from rest_framework import serializers +from applications.hr2.models import LTCform, CPDAAdvanceform, CPDAReimbursementform, LeaveForm, Appraisalform, LeaveBalance + + +class LTC_serializer(serializers.ModelSerializer): + class Meta: + model = LTCform + fields = '__all__' + + def create(self, validated_data): + return LTCform.objects.create(**validated_data) + + +class CPDAAdvance_serializer(serializers.ModelSerializer): + class Meta: + model = CPDAAdvanceform + fields = '__all__' + + def create(self, validated_data): + return CPDAAdvanceform.objects.create(**validated_data) + + +class Appraisal_serializer(serializers.ModelSerializer): + class Meta: + model = Appraisalform + fields = '__all__' + + def create(self, validated_data): + return Appraisalform.objects.create(**validated_data) + + +class CPDAReimbursement_serializer(serializers.ModelSerializer): + class Meta: + model = CPDAReimbursementform + fields = '__all__' + + def create(self, validated_data): + return CPDAReimbursementform.objects.create(**validated_data) + + +class Leave_serializer(serializers.ModelSerializer): + class Meta: + model = LeaveForm + fields = '__all__' + + def create(self, validated_data): + return LeaveForm.objects.create(**validated_data) + + +class LeaveBalanace_serializer(serializers.ModelSerializer): + class Meta: + model = LeaveBalance + fields = '__all__' + + def create(self, validated_data): + return LeaveBalance.objects.create(**validated_data) \ No newline at end of file diff --git a/FusionIIIT/applications/hr2/api/urls.py b/FusionIIIT/applications/hr2/api/urls.py new file mode 100644 index 000000000..51396e8ef --- /dev/null +++ b/FusionIIIT/applications/hr2/api/urls.py @@ -0,0 +1,39 @@ +from django.conf.urls import url +from django.urls import path +# from . import views +from . import form_views + + +app_name = 'hr2' + +urlpatterns = [ + # LTC form + url('ltc/', form_views.LTC.as_view(), name='LTC_form'), + # cpda advance form + url('cpdaadv/', form_views.CPDAAdvance.as_view(), name='CPDAAdvance_form'), + # appraisal form + url('appraisal/', form_views.Appraisal.as_view(), name='Appraisal_form'), + # cpda reimbursement form + url('cpdareim/', form_views.CPDAReimbursement.as_view(), + name='CPDAReimbursement_form'), + # leave form + url('leave/', form_views.Leave.as_view(), name='Leave_form'), + url('formManagement/', form_views.FormManagement.as_view(), name='formManagement'), + url('tracking/', form_views.TrackProgress.as_view(), name='tracking'), + url('formFetch/', form_views.FormFetch.as_view(), name='fetch_form'), + # create for GetForms + url('getForms/', form_views.GetFormHistory.as_view(), name='getForms'), + url('leaveBalance/', form_views.CheckLeaveBalance.as_view(), name='leaveBalance'), + + # url(r'^$', views.service_book, name='hr2'), + # url(r'^hradmin/$', views.hr_admin, name='hradmin'), + # url(r'^edit/(?P\d+)/$', views.edit_employee_details, + # name='editEmployeeDetails'), + # url(r'^viewdetails/(?P\d+)/$', + # views.view_employee_details, name='viewEmployeeDetails'), + # url(r'^editServiceBook/(?P\d+)/$', + # views.edit_employee_servicebook, name='editServiceBook'), + # url(r'^administrativeProfile/$', views.administrative_profile, + # name='administrativeProfile'), + # url(r'^addnew/$', views.add_new_user, name='addnew'), +] diff --git a/FusionIIIT/applications/hr2/form_views.py b/FusionIIIT/applications/hr2/form_views.py new file mode 100644 index 000000000..3cc08fb93 --- /dev/null +++ b/FusionIIIT/applications/hr2/form_views.py @@ -0,0 +1,323 @@ +from .serializers import LTC_serializer, CPDAAdvance_serializer, Appraisal_serializer, CPDAReimbursement_serializer, Leave_serializer +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status +from rest_framework.decorators import permission_classes, api_view +from rest_framework.permissions import IsAuthenticated, AllowAny +from .models import LTCform, CPDAAdvanceform, CPDAReimbursementform, Leaveform, Appraisalform +from django.contrib.auth import get_user_model +from django.core.exceptions import MultipleObjectsReturned +from applications.filetracking.sdk.methods import * +from applications.globals.models import Designation, HoldsDesignation + +class LTC(APIView): + serializer_class = LTC_serializer + permission_classes = (AllowAny, ) + def post(self, request): + if 'Mobile-OS' in request.META: + user_info = request.data[0] + serializer = self.serializer_class(data = request.data[1]) + if serializer.is_valid(): + serializer.save() + file_id = create_file(uploader = user_info['uploader_name'], uploader_designation = user_info['uploader_designation'], receiver = "21BCS140", receiver_designation="hradmin", src_module="HR", src_object_id= str(serializer.data['id']), file_extra_JSON= {"type": "LTC"}, attached_file= None) + return Response(serializer.data, status= status.HTTP_200_OK) + else: + return Response(serializer.errors, status= status.HTTP_400_BAD_REQUEST) + id = request.query_params.get("id") + try: + employee = ExtraInfo.objects.get(user__id=id) + except: + raise Http404("Post does not exist! id doesnt exist") + + print(employee.user_type) + + + if(employee.user_type == 'faculty'): + template = 'hr2Module/ltc_form.html' + + if request.method == "POST": + family_mem_a = request.POST.get('id_family_mem_a', '') + family_mem_b = request.POST.get('id_family_mem_b', '') + family_mem_c = request.POST.get('id_family_mem_c', '') + + + detailsOfFamilyMembers = ', '.join(filter(None, [family_mem_a, family_mem_b, family_mem_c])) + + + request.POST = request.POST.copy() + request.POST['detailsOfFamilyMembersAlreadyDone'] = detailsOfFamilyMembers + + + family_members = [] + for i in range(1, 7): # Loop through input fields for each family member + name = request.POST.get(f'info_{i}_2', '') # Get the name + age = request.POST.get(f'info_{i}_3', '') # Get the age + if name and age: # Check if both name and age are provided + family_members.append(f"{name} ({age} years)") # Concatenate name and age + + family_members_str = ', '.join(family_members) + + # Populate the form with concatenated family member details + request.POST['familyMembersAboutToAvail'] = family_members_str + + dependents = [] + for i in range(1, 7): # Loop through input fields for each dependent + name = request.POST.get(f'd_info_{i}_2', '') # Get the name + age = request.POST.get(f'd_info_{i}_3', '') # Get the age + why_dependent = request.POST.get(f'd_info_{i}_4', '') # Get the reason for dependency + if name and age: # Check if both name and age are provided + dependents.append(f"{name} ({age} years), {why_dependent}") # Concatenate name, age, and reason + + + # Concatenate all dependent strings into a single string + dependents_str = ', '.join(dependents) + + # Populate the form with concatenated dependent details + request.POST['detailsOfDependents'] = dependents_str + + # print("first",request.POST['familyMembersAboutToAvail']) + pf_no = int(request.POST.get('pf_no')) if request.POST.get('pf_no') else None + basicPay = int(request.POST.get('basicPay')) if request.POST.get('basicPay') else None + amountOfAdvanceRequired = int(request.POST.get('amountOfAdvanceRequired')) if request.POST.get('amountOfAdvanceRequired') else None + phoneNumberForContact = int(request.POST.get('phoneNumberForContact')) if request.POST.get('phoneNumberForContact') else None + + + try: + ltc_request = LTCform.objects.create( + employee_id = id, + detailsOfFamilyMembersAlreadyDone=request.POST.get('detailsOfFamilyMembersAlreadyDone', ''), + familyMembersAboutToAvail=request.POST.get('familyMembersAboutToAvail', ''), + detailsOfDependents=request.POST.get('detailsOfDependents', ''), + name=request.POST.get('name', ''), + blockYear=request.POST.get('blockYear', ''), + pf_no=request.POST.get('pf_no', ''), + basicPay=request.POST.get('basicPay', ''), + designation=request.POST.get('designation', ''), + departmentInfo=request.POST.get('departmentInfo', ''), + leaveAvailability=request.POST.get('leaveAvailability', ''), + leaveStartDate=request.POST.get('leaveStartDate', ''), + leaveEndDate=request.POST.get('leaveEndDate', ''), + dateOfLeaveForFamily=request.POST.get('dateOfLeaveForFamily', ''), + natureOfLeave=request.POST.get('natureOfLeave', ''), + purposeOfLeave=request.POST.get('purposeOfLeave', ''), + hometownOrNot=request.POST.get('hometownOrNot', ''), + placeOfVisit=request.POST.get('placeOfVisit', ''), + addressDuringLeave=request.POST.get('addressDuringLeave', ''), + modeForVacation=request.POST.get('modeForVacation', ''), + detailsOfFamilyMembers=request.POST.get('detailsOfFamilyMembers', ''), + amountOfAdvanceRequired=request.POST.get('amountOfAdvanceRequired', ''), + certifiedFamilyDependents=request.POST.get('certifiedFamilyDependents', ''), + certifiedAdvance =request.POST.get('certifiedAdvance ', ''), + adjustedMonth=request.POST.get('adjustedMonth', ''), + date=request.POST.get('date', ''), + phoneNumberForContact=request.POST.get('phoneNumberForContact', '') + ) + print("done") + messages.success(request, "Ltc form filled successfully") + except Exception as e: + print("error" , e) + messages.warning(request, "Fill not correctly") + context = {'employee': employee} + return render(request, template, context) + + + # Query all LTC requests + ltc_requests = LTCform.objects.filter(employee_id=id) + + context = {'employee': employee, 'ltc_requests': ltc_requests} + + return render(request, template, context) + else: + return render(request, 'hr2Module/edit.html') + + + + def get(self, request, *args, **kwargs): + pk = request.query_params.get("name") + print(pk) + try: + forms = LTCform.objects.get(name = pk) + serializer = self.serializer_class(forms, many = False) + except MultipleObjectsReturned: + forms = LTCform.objects.filter(name = pk) + serializer = self.serializer_class(forms, many = True) + return Response(serializer.data, status = status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + pk = request.query_params.get("id") + print(pk) + form = LTCform.objects.get(id = pk) + print(form) + serializer = self.serializer_class(form, data = request.data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status = status.HTTP_200_OK) + else: + return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST) + +class FormManagement(APIView): + permission_classes = (AllowAny, ) + def get(self, request, *args, **kwargs): + username = request.query_params.get("username") + designation = request.query_params.get("designation") + inbox = view_inbox(username = username, designation = designation, src_module = "HR") + return Response(inbox, status = status.HTTP_200_OK) + + def post(self, request, *args, **kwargs): + username = request.data['receiver'] + receiver_value = User.objects.get(username=username) + receiver_value_designation= HoldsDesignation.objects.filter(user=receiver_value) + lis = list(receiver_value_designation) + obj=lis[0].designation + forward_file(file_id = request.data['file_id'], receiver = request.data['receiver'], receiver_designation = obj.name, remarks = request.data['remarks'], file_extra_JSON = request.data['file_extra_JSON']) + return Response(status = status.HTTP_200_OK) + + +class CPDAAdvance(APIView): + serializer_class = CPDAAdvance_serializer + permission_classes = (AllowAny, ) + def post(self, request): + user_info = request.data[0] + serializer = self.serializer_class(data = request.data[1]) + if serializer.is_valid(): + serializer.save() + file_id = create_file(uploader = user_info['uploader_name'], uploader_designation = user_info['uploader_designation'], receiver = "vkjain", receiver_designation="CSE HOD", src_module="HR", src_object_id= str(serializer.data['id']), file_extra_JSON= {"type": "CPDAAdvance"}, attached_file= None) + return Response(serializer.data, status= status.HTTP_200_OK) + else: + return Response(serializer.errors, status= status.HTTP_400_BAD_REQUEST) + + def get(self, request, *args, **kwargs): + pk = request.query_params.get("name") + print(pk) + try: + forms = CPDAAdvanceform.objects.get(name = pk) + serializer = self.serializer_class(forms, many = False) + except MultipleObjectsReturned: + forms = CPDAAdvanceform.objects.filter(name = pk) + serializer = self.serializer_class(forms, many = True) + return Response(serializer.data, status = status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + pk = request.query_params.get("id") + print(pk) + form = CPDAAdvanceform.objects.get(id = pk) + print(form) + serializer = self.serializer_class(form, data = request.data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status = status.HTTP_200_OK) + else: + return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST) + +class CPDAReimbursement(APIView): + serializer_class = CPDAReimbursement_serializer + permission_classes = (AllowAny, ) + def post(self, request): + user_info = request.data[0] + serializer = self.serializer_class(data = request.data[1]) + if serializer.is_valid(): + serializer.save() + file_id = create_file(uploader = user_info['uploader_name'], uploader_designation = user_info['uploader_designation'], receiver = "vkjain", receiver_designation="CSE HOD", src_module="HR", src_object_id= str(serializer.data['id']), file_extra_JSON= {"type": "CPDAReimbursement"}, attached_file= None) + return Response(serializer.data, status= status.HTTP_200_OK) + else: + return Response(serializer.errors, status= status.HTTP_400_BAD_REQUEST) + + def get(self, request, *args, **kwargs): + pk = request.query_params.get("name") + print(pk) + try: + forms = CPDAReimbursementform.objects.get(name = pk) + serializer = self.serializer_class(forms, many = False) + except MultipleObjectsReturned: + forms = CPDAReimbursementform.objects.filter(name = pk) + serializer = self.serializer_class(forms, many = True) + return Response(serializer.data, status = status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + pk = request.query_params.get("id") + print(pk) + form = CPDAReimbursementform.objects.get(id = pk) + print(form) + serializer = self.serializer_class(form, data = request.data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status = status.HTTP_200_OK) + else: + return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST) + +class Leave(APIView): + serializer_class = Leave_serializer + permission_classes = (AllowAny, ) + def post(self, request): + user_info = request.data[0] + serializer = self.serializer_class(data = request.data[1]) + if serializer.is_valid(): + serializer.save() + file_id = create_file(uploader = user_info['uploader_name'], uploader_designation = user_info['uploader_designation'], receiver = "vkjain", receiver_designation="CSE HOD", src_module="HR", src_object_id= str(serializer.data['id']), file_extra_JSON= {"type": "Leave"}, attached_file= None) + return Response(serializer.data, status= status.HTTP_200_OK) + else: + return Response(serializer.errors, status= status.HTTP_400_BAD_REQUEST) + + def get(self, request, *args, **kwargs): + pk = request.query_params.get("name") + print(pk) + try: + forms = Leaveform.objects.get(name = pk) + serializer = self.serializer_class(forms, many = False) + except MultipleObjectsReturned: + forms = Leaveform.objects.filter(name = pk) + serializer = self.serializer_class(forms, many = True) + return Response(serializer.data, status = status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + pk = request.query_params.get("id") + print(pk) + form = Leaveform.objects.get(id = pk) + print(form) + serializer = self.serializer_class(form, data = request.data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status = status.HTTP_200_OK) + else: + return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST) + +class Appraisal(APIView): + serializer_class = Appraisal_serializer + permission_classes = (AllowAny, ) + def post(self, request): + user_info = request.data[0] + serializer = self.serializer_class(data = request.data[1]) + if serializer.is_valid(): + serializer.save() + file_id = create_file(uploader = user_info['uploader_name'], uploader_designation = user_info['uploader_designation'], receiver = "vkjain", receiver_designation="CSE HOD", src_module="HR", src_object_id= str(serializer.data['id']), file_extra_JSON= {"type": "Appraisal"}, attached_file= None) + return Response(serializer.data, status= status.HTTP_200_OK) + else: + return Response(serializer.errors, status= status.HTTP_400_BAD_REQUEST) + + def get(self, request, *args, **kwargs): + pk = request.query_params.get("name") + print(pk) + try: + forms = Appraisalform.objects.get(name = pk) + serializer = self.serializer_class(forms, many = False) + except MultipleObjectsReturned: + forms = Appraisalform.objects.filter(name = pk) + serializer = self.serializer_class(forms, many = True) + return Response(serializer.data, status = status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + pk = request.query_params.get("id") + print(pk) + form = Appraisalform.objects.get(id = pk) + print(form) + serializer = self.serializer_class(form, data = request.data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status = status.HTTP_200_OK) + else: + return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST) + +class AssignerReviewer(APIView): + def post(self, request, *args, **kwargs): + forward_file(file_id = request.data['file_id'], receiver = "21BCS140", receiver_designation = 'hradmin', remarks = request.data['remarks'], file_extra_JSON = request.data['file_extra_JSON']) + return Response(status = status.HTTP_200_OK) \ No newline at end of file diff --git a/FusionIIIT/applications/hr2/models.py b/FusionIIIT/applications/hr2/models.py index cf7e0ee8c..01ca223c7 100644 --- a/FusionIIIT/applications/hr2/models.py +++ b/FusionIIIT/applications/hr2/models.py @@ -1,6 +1,7 @@ from django.db import models from applications.globals.models import ExtraInfo from django.core.validators import MaxValueValidator, MinValueValidator +from django.contrib.auth.models import User class Constants: # Class for various choices on the enumerations @@ -48,6 +49,7 @@ class Constants: ) + # Employee model class Employee(models.Model): """ @@ -141,3 +143,154 @@ class WorkAssignemnt(models.Model): end_date = models.DateField(max_length=6, null=True, blank=True) job_title = models.CharField(max_length=50, default='') orders_copy = models.FileField(blank=True, null=True) + +class LTCform(models.Model): + id = models.AutoField(primary_key=True) + employeeId = models.IntegerField() + name = models.CharField(max_length=100, null=True) + blockYear = models.TextField() # + pfNo = models.IntegerField(max_length=50) + basicPaySalary = models.IntegerField(null=True) + designation = models.CharField(max_length=50) + departmentInfo = models.CharField(max_length=50) + leaveRequired = models.BooleanField(default=False,null=True) # + leaveStartDate = models.DateField(null=True, blank=True) + leaveEndDate = models.DateField(null=True, blank=True) + dateOfDepartureForFamily = models.DateField(null=True, blank=True) # + natureOfLeave = models.TextField(null=True,blank=True) + purposeOfLeave = models.TextField(null=True,blank=True) + hometownOrNot = models.BooleanField(default=False) + placeOfVisit = models.TextField(max_length=100, null=True, blank=True) + addressDuringLeave = models.TextField(null=True) + modeofTravel = models.TextField(max_length=10, null=True,blank=True) # + detailsOfFamilyMembersAlreadyDone = models.JSONField(null=True,blank=True) + detailsOfFamilyMembersAboutToAvail = models.JSONField(max_length=100, null=True,blank=True) + detailsOfDependents = models.JSONField(blank=True,null=True) + amountOfAdvanceRequired = models.IntegerField(null=True, blank=True) + certifiedThatFamilyDependents = models.BooleanField(blank=True,null=True) + certifiedThatAdvanceTakenOn = models.DateField(null=True, blank=True) + adjustedMonth = models.TextField(max_length=50, null=True,blank=True) + submissionDate = models.DateField(null=True) + phoneNumberForContact = models.BigIntegerField() + approved = models.BooleanField(null=True) + approvedDate = models.DateField(auto_now_add=True, null=True) + created_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='LTC_created_by') + approved_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='LTC_approved_by') + + + +class CPDAAdvanceform(models.Model): + id = models.AutoField(primary_key=True) + employeeId = models.IntegerField(max_length=22, null=True) + name = models.CharField(max_length=40,null=True) + designation = models.CharField(max_length=40,null=True) + pfNo = models.IntegerField(max_length=30,null=True) + purpose = models.TextField(max_length=40, null=True) + amountRequired = models.IntegerField(max_length=30,null=True) + advanceDueAdjustment = models.DecimalField(max_digits=10, decimal_places=2, null=True,blank=True) + + submissionDate = models.DateField(blank=True, null=True) + + balanceAvailable = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True) + advanceAmountPDA = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True) + amountCheckedInPDA = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) + + approved = models.BooleanField(null=True) + approvedDate = models.DateField(auto_now_add=True, null=True) + created_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='CPDA_created_by') + approved_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='CPDA_approved_by') + +class LeaveForm(models.Model): + id = models.AutoField(primary_key=True) + employeeId = models.IntegerField(max_length=22,null=True) + name = models.CharField(max_length=40,null=True) + designation = models.CharField(max_length=40,null=True) + submissionDate = models.DateField(blank=True, null=True) + pfNo = models.IntegerField(max_length=30,null=True) + departmentInfo = models.CharField(max_length=40,null=True) + natureOfLeave = models.TextField(max_length=40,null=True) + leaveStartDate = models.DateField(blank=True, null=True) + leaveEndDate = models.DateField(blank=True, null=True) + + purposeOfLeave = models.TextField(max_length=40,null=True) + addressDuringLeave = models.TextField(max_length=40, blank=True, null=True) + + academicResponsibility = models.TextField(max_length=40, blank=True, null=True) + addministrativeResponsibiltyAssigned = models.TextField(max_length=40,null=True) + + approved = models.BooleanField(null=True) + approvedDate = models.DateField(auto_now_add=True, null=True) + created_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='Leave_created_by') + approved_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='Leave_approved_by') + +class LeaveBalance(models.Model): + id = models.AutoField(primary_key=True) + employeeId = models.OneToOneField(ExtraInfo, on_delete=models.CASCADE) + casualLeave = models.IntegerField(default=0) + specialCasualLeave = models.IntegerField(default=0) + earnedLeave = models.IntegerField(default=0) + commutedLeave = models.IntegerField(default=0) + restrictedHoliday = models.IntegerField(default=0) + stationLeave = models.IntegerField(default=0) + vacationLeave = models.IntegerField(default=0) + + +class Appraisalform(models.Model): + id = models.AutoField(primary_key=True) + employeeId = models.IntegerField(max_length=22,null=True) + name = models.CharField(max_length=22) + designation = models.CharField(max_length=50) + disciplineInfo = models.CharField(max_length=22, null=True) + specificFieldOfKnowledge = models.TextField(max_length=40, null=True) + currentResearchInterests = models.TextField(max_length=40, null=True) + coursesTaught = models.JSONField(max_length=100, null=True) + newCoursesIntroduced = models.JSONField(max_length=100, null=True) + newCoursesDeveloped = models.JSONField(max_length=100, null=True) + otherInstructionalTasks = models.TextField(max_length=100, null=True) + thesisSupervision = models.JSONField(max_length=100, null=True) + sponsoredReseachProjects = models.JSONField(max_length=100, null=True) + otherResearchElement = models.TextField(max_length=40, null=True) + publication = models.TextField(max_length=40, null=True) + referredConference = models.TextField(max_length=40, null=True) + conferenceOrganised = models.TextField(max_length=40, null=True) + membership = models.TextField(max_length=40, null=True) + honours = models.TextField(max_length=40, null=True) + editorOfPublications = models.TextField(max_length=40, null=True) + expertLectureDelivered = models.TextField(max_length=40, null=True) + membershipOfBOS = models.TextField(max_length=40, null=True) + otherExtensionTasks = models.TextField(max_length=40, null=True) + administrativeAssignment = models.TextField(max_length=40, null=True) + serviceToInstitute = models.TextField(max_length=40, null=True) + otherContribution = models.TextField(max_length=40, null=True) + performanceComments = models.TextField(max_length=100, null=True) + submissionDate = models.DateField(max_length=6, null=True) + + approved = models.BooleanField(null=True) + approvedDate = models.DateField(auto_now_add=True, null=True) + created_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='Appraisal_created_by') + approved_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='Appraisal_approved_by') + + +class CPDAReimbursementform(models.Model): + id = models.AutoField(primary_key=True) + employeeId = models.IntegerField(max_length=22,null=True) + name = models.CharField(max_length=50) + designation = models.CharField(max_length=50) + pfNo = models.IntegerField(max_length=20) + advanceTaken = models.IntegerField() + purpose = models.TextField() + adjustmentSubmitted = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) + balanceAvailable = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) + advanceDueAdjustment = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) + advanceAmountPDA = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) + amountCheckedInPDA = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) + submissionDate = models.DateField(auto_now_add=True) + approved = models.BooleanField(null=True) + approvedDate = models.DateField(auto_now_add=True, null=True) + created_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='CPDAR_created_by') + approved_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='CPDAR_approved_by') + + + + + diff --git a/FusionIIIT/applications/hr2/normal.py b/FusionIIIT/applications/hr2/normal.py new file mode 100644 index 000000000..0e344ff51 --- /dev/null +++ b/FusionIIIT/applications/hr2/normal.py @@ -0,0 +1,36 @@ +'block_year': ['232'], + 'pf_no': ['222'], + 'basic_pay_salary': ['2322'], + 'name': ['dsds'], + 'designation':['dsdsd'], + 'department_info': ['ds'], + 'leave_availability': ['True', 'True'], + 'leave_start_date': ['2024-02-22'], + 'leave_end_date': ['2024-02-22'], + 'date_of_leave_for_family': ['2024-02-22'], + 'nature_of_leave': ['dsds'], + 'purpose_of_leave': ['dsdsd'], + 'hometown_or_not': ['True'], + 'place_of_visit': [''], + 'address_during_leave': ['full street address'], + 'details_of_family_members_already_done': ['sds', 'dsd', 'dsd'], + 'info_1_1': ['1'], 'info_1_2': ['dsds'], 'info_1_3': ['12'], + 'info_2_1': ['2'], 'info_2_2': ['sds'], 'info_2_3': ['121'], + 'info_3_1': ['3'], 'info_3_2': ['dsds'], 'info_3_3': ['21'], + 'info_4_1': [''], 'info_4_2': [''], 'info_4_3': [''], + 'info_5_1': [''], 'info_5_2': [''], 'info_5_3': [''], + 'info_6_1': [''], 'info_6_2': [''], 'info_6_3': [''], + + 'd_info_1_1': ['1'], 'd_info_1_2': ['sds'], 'd_info_1_3': ['21'], 'd_info_1_4': ['sdd'], + + 'd_info_2_1': ['2'], 'd_info_2_2': ['dsd'], 'd_info_2_3': ['23'], 'd_info_2_4': ['sds'], + 'd_info_3_1': ['3'], 'd_info_3_2': ['sd'], 'd_info_3_3': ['21'], 'd_info_3_4': ['dds'], + 'd_info_4_1': [''], 'd_info_4_2': [''], 'd_info_4_3': [''], 'd_info_4_4': [''], + 'd_info_5_1': [''], 'd_info_5_2': [''], 'd_info_5_3': [''], 'd_info_5_4': [''], + 'd_info_6_1': [''], 'd_info_6_2': [''], 'd_info_6_3': [''], 'd_info_6_4': [''], + 'amount_of_advance_required': ['211'], + 'certified_family_dependents': ['dqwd'], + 'certified_advance': ['dqwd'], + 'adjusted_month': ['qwdwd'], + 'date': ['2024-02-22'], + 'phone_number_for_contact': ['2312123'] \ No newline at end of file diff --git a/FusionIIIT/applications/hr2/serializers.py b/FusionIIIT/applications/hr2/serializers.py new file mode 100644 index 000000000..b28cdcc45 --- /dev/null +++ b/FusionIIIT/applications/hr2/serializers.py @@ -0,0 +1,42 @@ +from rest_framework import serializers +from .models import LTCform, CPDAAdvanceform, CPDAReimbursementform, Leaveform, Appraisalform + +class LTC_serializer(serializers.ModelSerializer): + class Meta: + model = LTCform + fields = '__all__' + + def create(self, validated_data): + return LTCform.objects.create(**validated_data) + +class CPDAAdvance_serializer(serializers.ModelSerializer): + class Meta: + model = CPDAAdvanceform + fields = '__all__' + + def create(self, validated_data): + return CPDAAdvanceform.objects.create(**validated_data) + +class Appraisal_serializer(serializers.ModelSerializer): + class Meta: + model = Appraisalform + fields = '__all__' + + def create(self, validated_data): + return Appraisalform.objects.create(**validated_data) + +class CPDAReimbursement_serializer(serializers.ModelSerializer): + class Meta: + model = CPDAReimbursementform + fields = '__all__' + + def create(self, validated_data): + return CPDAReimbursementform.objects.create(**validated_data) + +class Leave_serializer(serializers.ModelSerializer): + class Meta: + model = Leaveform + fields = '__all__' + + def create(self, validated_data): + return Leaveform.objects.create(**validated_data) \ No newline at end of file diff --git a/FusionIIIT/applications/hr2/test.py b/FusionIIIT/applications/hr2/test.py new file mode 100644 index 000000000..89ec7917f --- /dev/null +++ b/FusionIIIT/applications/hr2/test.py @@ -0,0 +1,116 @@ +def ltc_pre_processing(request): + ltc_form_data = {} + + # Extract general information + ltc_form_data['name'] = request.POST['name'] + ltc_form_data['block_year'] = int(request.POST['block_year']) + ltc_form_data['pf_no'] = int(request.POST['pf_no']) + ltc_form_data['basic_pay_salary'] = int(request.POST['basic_pay_salary']) + ltc_form_data['designation'] = request.POST['designation'] + ltc_form_data['department_info'] = request.POST['department_info'] + ltc_form_data['leave_availability'] = request.POST.getlist('leave_availability') == ['True', 'True'] + ltc_form_data['leave_start_date'] = request.POST['leave_start_date'] + ltc_form_data['leave_end_date'] = request.POST['leave_end_date'] + ltc_form_data['date_of_leave_for_family'] = request.POST['date_of_leave_for_family'] + ltc_form_data['nature_of_leave'] = request.POST['nature_of_leave'] + ltc_form_data['purpose_of_leave'] = request.POST['purpose_of_leave'] + ltc_form_data['hometown_or_not'] = request.POST.get('hometown_or_not') == 'True' + ltc_form_data['place_of_visit'] = request.POST['place_of_visit'] + ltc_form_data['address_during_leave'] = request.POST['address_during_leave'] + + # Extract details of family members + family_members = [] + for i in range(1, 7): + if request.POST.get(f'info_{i}_1'): + family_member = ','.join(request.POST.getlist(f'info_{i}_{j}')[0] for j in range(1, 4)) + family_members.append(family_member) + ltc_form_data['details_of_family_members_already_done'] = ','.join(family_members) + + # Extract details of dependents + dependents = [] + for i in range(1, 7): + if request.POST.get(f'd_info_{i}_1'): + dependent = ','.join(request.POST.getlist(f'd_info_{i}_{j}')[0] for j in range(1, 5)) + dependents.append(dependent) + ltc_form_data['details_of_dependents'] = ','.join(dependents) + + # Extract remaining fields + ltc_form_data['amount_of_advance_required'] = int(request.POST['amount_of_advance_required']) + ltc_form_data['certified_family_dependents'] = request.POST['certified_family_dependents'] + ltc_form_data['certified_advance'] = int(request.POST['certified_advance']) + ltc_form_data['adjusted_month'] = request.POST['adjusted_month'] + ltc_form_data['date'] = request.POST['date'] + ltc_form_data['phone_number_for_contact'] = int(request.POST['phone_number_for_contact']) + + return ltc_form_data + +# Example usage +request_data = { + 'csrfmiddlewaretoken': ['yLyPMZMWRBnDU3hSh5kPGq6AgOFNY5WTK1HaZxAuiozCzXBf8qfOML5irZJd8MkM'], + 'block_year': ['232'], + 'pf_no': ['222'], + 'basic_pay_salary': ['2322'], + 'name': ['dsds'], + 'designation': ['dsdsd'], + 'department_info': ['ds'], + 'leave_availability': ['True', 'True'], + 'leave_start_date': ['2024-02-22'], + 'leave_end_date': ['2024-02-22'], + 'date_of_leave_for_family': ['2024-02-22'], + 'nature_of_leave': ['dsds'], + 'purpose_of_leave': ['dsdsd'], + 'hometown_or_not': ['True'], + 'place_of_visit': [''], + 'address_during_leave': ['full street address'], + 'details_of_family_members_already_done': ['sds', 'dsd', 'dsd'], + 'info_1_1': ['1'], + 'info_1_2': ['dsds'], + 'info_1_3': ['12'], + 'info_2_1': ['2'], + 'info_2_2': ['sds'], + 'info_2_3': ['121'], + 'info_3_1': ['3'], + 'info_3_2': ['dsds'], + 'info_3_3': ['21'], + 'info_4_1': [''], + 'info_4_2': [''], + 'info_4_3': [''], + 'info_5_1': [''], + 'info_5_2': [''], + 'info_5_3': [''], + 'info_6_1': [''], + 'info_6_2': [''], + 'info_6_3': [''], + 'd_info_1_1': ['1'], + 'd_info_1_2': ['sds'], + 'd_info_1_3': ['21'], + 'd_info_1_4': ['sdd'], + 'd_info_2_1': ['2'], + 'd_info_2_2': ['dsd'], + 'd_info_2_3': ['23'], + 'd_info_2_4': ['sds'], + 'd_info_3_1': ['3'], + 'd_info_3_2': ['sd'], + 'd_info_3_3': ['21'], + 'd_info_3_4': ['dds'], + 'd_info_4_1': [''], + 'd_info_4_2': [''], + 'd_info_4_3': [''], + 'd_info_4_4': [''], + 'd_info_5_1': [''], + 'd_info_5_2': [''], + 'd_info_5_3': [''], + 'd_info_5_4': [''], + 'd_info_6_1': [''], + 'd_info_6_2': [''], + 'd_info_6_3': [''], + 'd_info_6_4': [''], + 'amount_of_advance_required': ['211'], + 'certified_family_dependents': ['dqwd'], + 'certified_advance': ['dqwd'], + 'adjusted_month': ['qwdwd'], + 'date': ['2024-02-22'], + 'phone_number_for_contact': ['2312123'] +} + +print(ltc_pre_processing(request_data)) diff --git a/FusionIIIT/applications/hr2/urls.py b/FusionIIIT/applications/hr2/urls.py index 56918efb7..cfaddcec6 100644 --- a/FusionIIIT/applications/hr2/urls.py +++ b/FusionIIIT/applications/hr2/urls.py @@ -1,6 +1,7 @@ -from django.conf.urls import url +from django.conf.urls import url, include -from . import views +from applications.hr2 import views +from applications.hr2.api import form_views app_name = 'hr2' @@ -17,5 +18,83 @@ url(r'^administrativeProfile/$', views.administrative_profile, name='administrativeProfile'), url(r'^addnew/$', views.add_new_user, name='addnew'), + url(r'^ltc_form/(?P\d+)/$', views.ltc_form, + name='ltcForm'), + + url(r'^view_ltc_form/(?P\d+)/$', views.view_ltc_form, + name='view_ltc_form'), + url(r'^form_mangement_ltc/',views.form_mangement_ltc, name='form_mangement_ltc'), + url(r'dashboard/', views.dashboard, name='dashboard'), + url(r'^form_mangement_ltc_hr/(?P\d+)/$',views.form_mangement_ltc_hr, name='form_mangement_ltc_hr'), + url(r'^form_mangement_ltc_hod/',views.form_mangement_ltc_hod, name='form_mangement_ltc_hod'), + url(r'^search_employee/', views.search_employee, name='search_employee'), + url(r'^track_file/(?P\d+)/$', views.track_file, name='track_file'), + url('form_view_ltc/(?P\d+)/$', views.form_view_ltc, name='form_view_ltc'), + # url('file_handle/', views.file_handle, name='file_handle'), + url('file_handle_cpda/', views.file_handle_cpda, name='file_handle_cpda'), + url('file_handle_leave/', views.file_handle_leave, name='file_handle_leave'), + url('file_handle_ltc/', views.file_handle_ltc, name='file_handle_ltc'), + url('file_handle_appraisal/', views.file_handle_appraisal, name='file_handle_appraisal'), + url('file_handle_cpda_reimbursement/', views.file_handle_cpda_reimbursement, name='file_handle_cpda_reimbursement'), + + url(r'^cpda_form/(?P\d+)/$', views.cpda_form,name='cpdaForm'), + url(r'^view_cpda_form/(?P\d+)/$', views.view_cpda_form,name='view_cpda_form'), + url(r'^form_mangement_cpda/',views.form_mangement_cpda, name='form_mangement_cpda'), + url(r'^form_mangement_cpda_hr/(?P\d+)/$',views.form_mangement_cpda_hr, name='form_mangement_cpda_hr'), + url(r'^form_mangement_cpda_hod/',views.form_mangement_cpda_hod, name='form_mangement_cpda_hod'), + url('form_view_cpda/(?P\d+)/$', views.form_view_cpda, name='form_view_cpda'), + url(r'^api/',include('applications.hr2.api.urls')), + + url(r'^cpda_reimbursement_form/(?P\d+)/$', views.cpda_reimbursement_form,name='cpdaReimbursementForm'), + url(r'^view_cpda_reimbursement_form/(?P\d+)/$', views.view_cpda_reimbursement_form,name='view_cpda_reimbursement_form'), + url(r'form_view_cpda_reimbursement/(?P\d+)/$', views.form_view_cpda_reimbursement, name='form_view_cpda_reimbursement'), + url(r'^form_mangement_cpda_reimbursement/',views.form_mangement_cpda_reimbursement, name='form_mangement_cpda_reimbursement'), + url(r'^form_mangement_cpda_reimbursement_hr/(?P\d+)/$',views.form_mangement_cpda_reimbursement_hr, name='form_mangement_cpda_reimbursement_hr'), + url(r'^form_mangement_cpda_reimbursement_hod/',views.form_mangement_cpda_reimbursement_hod, name='form_mangement_cpda_reimbursement_hod'), + + url(r'^leave_form/(?P\d+)/$', views.leave_form,name='leaveForm'), + url(r'^view_leave_form/(?P\d+)/$', views.view_leave_form,name='view_leave_form'), + url(r'^form_mangement_leave/',views.form_mangement_leave, name='form_mangement_leave'), + url(r'^form_mangement_leave_hr/(?P\d+)/$',views.form_mangement_leave_hr, name='form_mangement_leave_hr'), + url(r'^form_mangement_leave_hod/',views.form_mangement_leave_hod, name='form_mangement_leave_hod'), + url('form_view_leave/(?P\d+)/$', views.form_view_leave, name='form_view_leave'), + + + + url(r'^appraisal_form/(?P\d+)/$', views.appraisal_form,name='appraisalForm'), + url(r'^view_appraisal_form/(?P\d+)/$', views.view_appraisal_form,name='view_appraisal_form'), + url(r'^form_mangement_appraisal/',views.form_mangement_appraisal, name='form_mangement_appraisal'), + url(r'^form_mangement_appraisal_hr/(?P\d+)/$',views.form_mangement_appraisal_hr, name='form_mangement_appraisal_hr'), + + url(r'^form_view_appraisal/(?P\d+)/$', views.form_view_appraisal, name='form_view_appraisal'), + url(r'^getform/$', views.getform , name='getform'), + url(r'^getformcpdaAdvance/$', views.getformcpdaAdvance , name='getformcpdaAdvance'), + url(r'^getformLeave/$', views.getformLeave , name='getformLeave'), + url(r'^getformAppraisal/$', views.getformAppraisal , name='getformAppraisal'), + url(r'^getformcpdaReimbursement/$', views.getformcpdaReimbursement , name='getformcpdaReimbursement'), + + + + + + + + + + + + + + + + + + + + + + + + ] diff --git a/FusionIIIT/applications/hr2/views.py b/FusionIIIT/applications/hr2/views.py index f2f9d4fcd..939564d30 100644 --- a/FusionIIIT/applications/hr2/views.py +++ b/FusionIIIT/applications/hr2/views.py @@ -1,4 +1,5 @@ -from django.shortcuts import render +import json +from django.shortcuts import render, get_object_or_404 from .models import * from applications.globals.models import ExtraInfo from applications.globals.models import * @@ -11,15 +12,23 @@ from applications.establishment.models import * from applications.establishment.views import * from applications.eis.models import * -from applications.globals.models import ExtraInfo, HoldsDesignation, DepartmentInfo +from applications.globals.models import ExtraInfo, HoldsDesignation, DepartmentInfo, Designation + from html import escape from io import BytesIO import re +from rest_framework import status +from decimal import Decimal + from django.contrib.auth.models import User from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import (get_object_or_404, redirect, render, render) +from django.http import JsonResponse +from applications.filetracking.sdk.methods import * +from django.core.files.base import File as DjangoFile +from django.views.decorators.csrf import csrf_exempt def edit_employee_details(request, id): @@ -322,15 +331,11 @@ def add_new_user(request): if request.method == "POST": form = NewUserForm(request.POST) eform = AddExtraInfo(request.POST) - # t_pass = request.POST['password1'] - # t_user = request.POST['username'] - + if form.is_valid(): user = form.save() messages.success(request, "New User added Successfully") else: - print(form.errors) - # print(request.POST['password1']) t_pass = '0000' if 'password1' in request.POST: t_pass = request.POST['password1'] @@ -347,7 +352,6 @@ def add_new_user(request): eform.save() messages.success(request, "Extra info of user saved successfully") elif not eform.is_valid: - print(eform.errors) messages.error(request,"Some error occured") form = NewUserForm @@ -358,19 +362,2153 @@ def add_new_user(request): except: raise Http404("Post does not exist") - # if request.method == "POST": - # form = EditServiceBookForm(request.POST, request.FILES) - - # if form.is_valid(): - # form.save() - # messages.success( - # request, "Employee Service Book details edited successfully") - # else: - # messages.warning(request, "Error in submitting form") - # pass - - # form = EditServiceBookForm(initial={'extra_info': employee.id}) + context = {'employee': employee, "register_form": form, "eform": eform } return render(request, template, context) + + + +def ltc_pre_processing(request): + data = {} + detailsOfFamilyMembersAlreadyDone = "" + + for memeber in request.POST.getlist('detailsOfFamilyMembersAlreadyDone'): + if(memeber == ""): + detailsOfFamilyMembersAlreadyDone = detailsOfFamilyMembersAlreadyDone + 'None' + ',' + else: + detailsOfFamilyMembersAlreadyDone = detailsOfFamilyMembersAlreadyDone + memeber + ',' + + data['detailsOfFamilyMembersAlreadyDone'] = detailsOfFamilyMembersAlreadyDone.rstrip(',') + + + detailsOfFamilyMembersAboutToAvail = "" + + for i in range(1,4): + for j in range(1,4): + key_is = f'info_{i}_{j}' + + if(request.POST.get(key_is) == ""): + detailsOfFamilyMembersAboutToAvail = detailsOfFamilyMembersAboutToAvail + 'None' + ',' + else: + detailsOfFamilyMembersAboutToAvail = detailsOfFamilyMembersAboutToAvail + request.POST.get(key_is) + ',' + + data['detailsOfFamilyMembersAboutToAvail'] = detailsOfFamilyMembersAboutToAvail.rstrip(',') + + + detailsOfDependents = "" + + for i in range(1,7): + for j in range(1,5): + key_is = f'd_info_{i}_{j}' + if(request.POST.get(key_is) == ""): + detailsOfDependents = detailsOfDependents + 'None' + ',' + else: + detailsOfDependents = detailsOfDependents + request.POST.get(key_is) + ',' + + data['detailsOfDependents'] = detailsOfDependents.rstrip(',') + + return data + + +def reverse_ltc_pre_processing(data): + reversed_data = {} + + # Copying over simple key-value pairs + simple_keys = [ + 'blockYear', + 'pfNo', + 'basicPaySalary', + 'name', + 'designation', + 'departmentInfo', + 'leaveRequired', + 'leaveStartDate', + 'leaveEndDate', + 'dateOfDepartureForFamily', + 'natureOfLeave', + 'purposeOfLeave', + 'hometownOrNot', + 'placeOfVisit', + 'addressDuringLeave', + 'amountOfAdvanceRequired', + 'certifiedThatFamilyDependents', + 'certifiedThatAdvanceTakenOn', + 'adjustedMonth', + 'submissionDate', + 'phoneNumberForContact' + ] + + + for key in simple_keys: + value = getattr(data, key) + reversed_data[key] = value if value != 'None' else '' + + # Reversing array-like values + reversed_data['detailsOfFamilyMembersAlreadyDone'] = getattr(data,'detailsOfFamilyMembersAlreadyDone').split(',') + + detailsOfFamilyMembersAboutToAvail = getattr(data,'detailsOfFamilyMembersAboutToAvail').split(',') + for index, value in enumerate(detailsOfFamilyMembersAboutToAvail): + detailsOfFamilyMembersAboutToAvail[index] = value if value != 'None' else '' + + reversed_data['info_1_1'] = detailsOfFamilyMembersAboutToAvail[0] + reversed_data['info_1_2'] = detailsOfFamilyMembersAboutToAvail[1] + reversed_data['info_1_3'] = detailsOfFamilyMembersAboutToAvail[2] + reversed_data['info_2_1'] = detailsOfFamilyMembersAboutToAvail[3] + reversed_data['info_2_2'] = detailsOfFamilyMembersAboutToAvail[4] + reversed_data['info_2_3'] = detailsOfFamilyMembersAboutToAvail[5] + reversed_data['info_3_1'] = detailsOfFamilyMembersAboutToAvail[6] + reversed_data['info_3_2'] = detailsOfFamilyMembersAboutToAvail[7] + reversed_data['info_3_3'] = detailsOfFamilyMembersAboutToAvail[8] + + # # Reversing details_of_dependents + detailsOfDependents = getattr(data,'detailsOfDependents').split(',') + for i in range(1, 7): + for j in range(1, 5): + key = f'd_info_{i}_{j}' + value = detailsOfDependents.pop(0) + reversed_data[key] = value if value != 'None' else '' + + return reversed_data + +def get_designation_by_user_id(user_id): + try: + # Query HoldsDesignation model to get the user's designation + designation_objs = HoldsDesignation.objects.filter(user=user_id) + return designation_objs.first().designation + except ExtraInfo.DoesNotExist: + return None + except HoldsDesignation.DoesNotExist: + return None + +def search_employee(request): + search_text = request.GET.get('search', '') + data = {'designation': 'Assistant Professor'} + try: + + employee = User.objects.get(username = search_text) + + + holds_designation = HoldsDesignation.objects.filter(user=employee) + holds_designation = list(holds_designation) + + + + data['designation'] = str(holds_designation[0].designation) + except ExtraInfo.DoesNotExist: + data = {'error': "Employee doesn't exist"} + + return JsonResponse(data) + +def ltc_form(request, id): + """ Views for edit details""" + try: + employee = ExtraInfo.objects.get(user__id=id) + except: + raise Http404("Employee does not exist! id doesnt exist") + user_id = id + creator = User.objects.get(id = user_id) + + if(employee.user_type == 'faculty' or employee.user_type == 'staff' or employee.user_type == 'student'): + template = 'hr2Module/ltc_form.html' + + if request.method == "POST": + try: + + data = ltc_pre_processing(request) + + + form1 = { + 'employeeId': id, + 'name': request.POST.get('name'), + 'blockYear': request.POST.get('blockYear'), + 'basicPaySalary': request.POST.get('basicPaySalary'), + 'designation': request.POST.get('designation'), + 'pfNo': request.POST.get('pfNo'), + 'departmentInfo': request.POST.get('departmentInfo'), + 'leaveRequired': request.POST.get('leaveRequired'), + 'leaveStartDate': request.POST.get('leaveStartDate'), + 'leaveEndDate': request.POST.get('leaveEndDate'), + 'dateOfDepartureForFamily': request.POST.get('dateOfDepartureForFamily'), + 'natureOfLeave': request.POST.get('natureOfLeave'), + 'purposeOfLeave': request.POST.get('purposeOfLeave'), + 'hometownOrNot': request.POST.get('hometownOrNot'), + 'placeOfVisit': request.POST.get('placeOfVisit'), + 'addressDuringLeave': request.POST.get('addressDuringLeave'), + 'detailsOfFamilyMembersAlreadyDone': data['detailsOfFamilyMembersAlreadyDone'], + 'detailsOfFamilyMembersAboutToAvail': data['detailsOfFamilyMembersAboutToAvail'], + 'detailsOfDependents': data['detailsOfDependents'], + 'amountOfAdvanceRequired': request.POST.get('amountOfAdvanceRequired'), + 'certifiedThatFamilyDependents': request.POST.get('certifiedThatFamilyDependents'), + 'certifiedThatAdvanceTakenOn': request.POST.get('certifiedThatAdvanceTakenOn'), + 'adjustedMonth': request.POST.get('adjustedMonth'), + 'submissionDate': request.POST.get('submissionDate'), + 'phoneNumberForContact': request.POST.get('phoneNumberForContact'), + 'username_employee': request.POST.get('username_employee'), + 'designation_employee': request.POST.get('designation_employee'), + 'created_by' : creator, + } + + + try: + ltc_form = LTCform.objects.create( + employeeId=id, + name=request.POST.get('name'), + blockYear=request.POST.get('blockYear'), + pfNo=request.POST.get('pfNo'), + basicPaySalary=request.POST.get('basicPaySalary'), + designation=request.POST.get('designation'), + departmentInfo=request.POST.get('departmentInfo'), + leaveRequired=request.POST.get('leaveAvailability'), + leaveStartDate=request.POST.get('leaveStartDate'), + leaveEndDate=request.POST.get('leaveEndDate'), + dateOfDepartureForFamily=request.POST.get('dateOfLeaveForFamily'), + natureOfLeave=request.POST.get('natureOfLeave'), + purposeOfLeave=request.POST.get('purposeOfLeave'), + hometownOrNot=request.POST.get('hometownOrNot'), + placeOfVisit=request.POST.get('placeOfVisit'), + addressDuringLeave=request.POST.get('addressDuringLeave'), + detailsOfFamilyMembersAlreadyDone=data['detailsOfFamilyMembersAlreadyDone'], + detailsOfFamilyMembersAboutToAvail=data['detailsOfFamilyMembersAboutToAvail'], + detailsOfDependents=data['detailsOfDependents'], + amountOfAdvanceRequired=request.POST.get('amountOfAdvanceRequired'), + certifiedThatFamilyDependents=request.POST.get('certifiedThatFamilyDependents'), + certifiedThatAdvanceTakenOn=request.POST.get('certifiedThatAdvanceTakenOn'), + adjustedMonth=request.POST.get('adjustedMonth'), + submissionDate=request.POST.get('submissionDate'), + phoneNumberForContact=request.POST.get('phoneNumberForContact'), + created_by=creator, + ) + + except Exception as e: + + print("An error occurred while creating the LTC form:", e) + + + + + uploader = employee.user + uploader_designation = 'Assistant Professor' + + get_designation = get_designation_by_user_id(employee.user) + if(get_designation): + uploader_designation = get_designation + + receiver = request.POST.get('username_employee') + receiver_designation = request.POST.get('designation_employee') + src_module = "HR" + src_object_id = str(ltc_form.id) + file_extra_JSON = {"type": "LTC"} + + + # Create a file representing the LTC form and send it to HR admin + file_id = create_file( + uploader=uploader, + uploader_designation=uploader_designation, + receiver=receiver, + receiver_designation=receiver_designation, + src_module=src_module, + src_object_id=src_object_id, + file_extra_JSON=file_extra_JSON, + attached_file=None # Attach any file if necessary + ) + + + messages.success(request, "Ltc form filled successfully!") + + + return redirect(request.path_info) + + except Exception as e: + messages.warning(request, "Fill not correctly") + context = {'employee': employee} + return render(request, template, context) + + + + # Query all LTC requests + ltc_requests = LTCform.objects.filter(employeeId=id) + + username = employee.user + uploader_designation = 'Assistant Professor' + + + designation = get_designation_by_user_id(employee.user) + if(designation): + uploader_designation = designation + + + inbox = view_inbox(username = username, designation = uploader_designation, src_module = "HR") + archived_files = view_archived(username = username, designation = uploader_designation, src_module = "HR") + filtered_inbox = [] + for i in inbox: + item = i.get('file_extra_JSON', {}) + if item.get('type') == 'LTC': + filtered_inbox.append(i) + + filtered_archived_files = [] + for i in archived_files: + item = i.get('file_extra_JSON', {}) + if item.get('type') == 'LTC': + filtered_archived_files.append(i) + + + + + + + context = {'employee': employee, 'ltc_requests': ltc_requests, 'inbox': filtered_inbox , 'designation':designation, 'archived_files': filtered_archived_files , 'user_id': user_id} + + return render(request, template, context) + else: + return render(request, 'hr2Module/edit.html') + +def form_view_ltc(request , id): + ltc_request = get_object_or_404(LTCform, id=id) + + user_id = ltc_request.created_by.id + + from_user = request.GET.get('param1') + from_designation = request.GET.get('param2') + file_id = request.GET.get('param3') + + template = 'hr2Module/view_ltc_form.html' + ltc_request = reverse_ltc_pre_processing(ltc_request) + + context = {'ltc_request' : ltc_request , "button" : 1 , "file_id" : file_id, "from_user" :from_user , "from_designation" : from_designation ,"id" : id, "user_id" : user_id} + + return render(request , template , context) + +def track_file(request, id): + # Assuming file_history is a list of dictionaries + template = 'hr2Module/ltc_form_trackfile.html' + file_history = view_history(file_id=id) + + + context = {'file_history': file_history} + + # Create a JSON response + return render(request ,template , context) + +def get_current_file_owner(file_id: int) -> User: + ''' + This functions returns the current owner of the file. + The current owner is the latest recipient of the file + ''' + latest_tracking = Tracking.objects.filter( + file_id=file_id).order_by('-receive_date').first() + latest_recipient = latest_tracking.receiver_id + return latest_recipient + +def file_handle_leave(request): + if request.method == 'POST': + form_data2 = request.POST + form_data=request.POST.get('context') + action = form_data2.get('action') + + form_data=json.loads(form_data) + form_id = form_data['form_id'] + file_id = form_data['file_id'] + from_user = form_data['from_user'] + from_designation = form_data['from_designation'] + username_employee = form_data['username_employee'] + designation_employee = form_data['designation_employee'] + + remark = form_data['remark_id'] + + + #database + leave_form = LeaveForm.objects.get(id=form_id) + + leave_form.save() + + #database + try: + leave_form = LeaveForm.objects.get(id=form_id) + except LeaveForm.DoesNotExist: + return JsonResponse({"error": "LeaveForm object with the provided ID does not exist"}, status=404) + + + + current_owner = get_current_file_owner(file_id) + + # if action value is 0 then forward the file + # if action value is 1 then reject the file + # if action value is 3 then approve the file + # otherwise archive the file + + if(action == '0'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = username_employee, receiver_designation = designation_employee,remarks = f"Forwarded by {current_owner} to {username_employee}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = username_employee, receiver_designation = designation_employee,remarks = f"Forwarded by {current_owner} to {username_employee}, Reason : {remark}", file_extra_JSON = "None") + messages.success(request, "File forwarded successfully") + elif(action == '1'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = leave_form.name, receiver_designation = leave_form.designation, remarks = f"Rejected by {current_owner}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = leave_form.name, receiver_designation = leave_form.designation, remarks = f"Rejected by {current_owner}, Reason : {remark}", file_extra_JSON = "None") + messages.success(request, "File rejected successfully") + elif(action == '2'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = leave_form.name, receiver_designation = leave_form.designation, remarks = f"Approved by {current_owner}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = leave_form.name, receiver_designation = leave_form.designation, remarks = f"Approved by {current_owner}, Reason : {remark}", file_extra_JSON = "None") + leave_form.approved = True + leave_form.approvedDate = timezone.now() + leave_form.approved_by = current_owner + leave_form.save() + messages.success(request, "File approved successfully") + else: + is_archived = archive_file(file_id=file_id) + if( is_archived ): + messages.error(request, "Error in file archived") + else: + messages.success(request, "Success in file archived") + + + return HttpResponse("Success") + else: + + return HttpResponse("Failure") + + +def file_handle_cpda(request): + if request.method == 'POST': + form_data2 = request.POST + form_data=request.POST.get('context') + action = form_data2.get('action') + + form_data=json.loads(form_data) + form_id = form_data['form_id'] + file_id = form_data['file_id'] + from_user = form_data['from_user'] + from_designation = form_data['from_designation'] + username_employee = form_data['username_employee'] + designation_employee = form_data['designation_employee'] + + advanceAmountPDA = form_data['advanceAmountPDA'] + balanceAvailable = form_data['balanceAvailable'] + amountCheckedInPDA = form_data['amountCheckedInPDA'] + + remark = form_data['remark_id'] + #change + + + #database + try: + cpda_form = CPDAAdvanceform.objects.get(id=form_id) + except CPDAAdvanceform.DoesNotExist: + return JsonResponse({"error": "CPDAform object with the provided ID does not exist"}, status=404) + + + if advanceAmountPDA == "": + advanceAmountPDA = None + else: + advanceAmountPDA = Decimal(advanceAmountPDA) + + if balanceAvailable == "": + balanceAvailable = None + else: + balanceAvailable = Decimal(balanceAvailable) + + if amountCheckedInPDA == "": + amountCheckedInPDA = None + else: + amountCheckedInPDA = Decimal(amountCheckedInPDA) + + + + + # Update the attribute + setattr(cpda_form, "advanceAmountPDA", advanceAmountPDA) + setattr(cpda_form, "balanceAvailable", balanceAvailable) + setattr(cpda_form, "amountCheckedInPDA", amountCheckedInPDA) + cpda_form.save() + + #database + try: + cpda_form = CPDAAdvanceform.objects.get(id=form_id) + except CPDAAdvanceform.DoesNotExist: + return JsonResponse({"error": "CPDAform object with the provided ID does not exist"}, status=404) + + + current_owner = get_current_file_owner(file_id) + + # if action value is 0 then forward the file + # if action value is 1 then reject the file + # if action value is 3 then approve the file + # otherwise archive the file + + if(action == '0'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = username_employee, receiver_designation = designation_employee,remarks = f"Forwarded by {current_owner} to {username_employee}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = username_employee, receiver_designation = designation_employee,remarks = f"Forwarded by {current_owner} to {username_employee}, Reason : {remark}", file_extra_JSON = "None") + messages.success(request, "File forwarded successfully") + elif(action == '1'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = cpda_form.name, receiver_designation = cpda_form.designation, remarks = f"Rejected by {current_owner}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = cpda_form.name, receiver_designation = cpda_form.designation, remarks = f"Rejected by {current_owner}, Reason : {remark}", file_extra_JSON = "None") + messages.success(request, "File rejected successfully") + elif(action == '2'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = cpda_form.name, receiver_designation = cpda_form.designation, remarks = f"Approved by {current_owner}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = cpda_form.name, receiver_designation = cpda_form.designation, remarks = f"Approved by {current_owner}, Reason : {remark}", file_extra_JSON = "None") + cpda_form.approved = True + cpda_form.approvedDate = timezone.now() + cpda_form.approved_by = current_owner + cpda_form.save() + messages.success(request, "File approved successfully") + else: + is_archived = archive_file(file_id=file_id) + if( is_archived ): + messages.error(request, "Error in file archived") + else: + messages.success(request, "Success in file archived") + + + return HttpResponse("Success") + else: + + return HttpResponse("Failure") + + + +def file_handle_cpda_reimbursement(request): + if request.method == 'POST': + form_data2 = request.POST + form_data=request.POST.get('context') + action = form_data2.get('action') + + form_data=json.loads(form_data) + form_id = form_data['form_id'] + file_id = form_data['file_id'] + from_user = form_data['from_user'] + from_designation = form_data['from_designation'] + username_employee = form_data['username_employee'] + designation_employee = form_data['designation_employee'] + + advanceDueAdjustment = form_data['advanceDueAdjustment'] + balanceAvailable = form_data['balanceAvailable'] + amountCheckedInPDA = form_data['amountCheckedInPDA'] + + remark = form_data['remark_id'] + #change + + + #database + try: + cpda_form = CPDAReimbursementform.objects.get(id=form_id) + except CPDAReimbursementform.DoesNotExist: + return JsonResponse({"error": "CPDAReimbursementform object with the provided ID does not exist"}, status=404) + + + if advanceDueAdjustment == "": + advanceDueAdjustment = None + else: + advanceDueAdjustment = Decimal(advanceDueAdjustment) + + if balanceAvailable == "": + balanceAvailable = None + else: + balanceAvailable = Decimal(balanceAvailable) + + if amountCheckedInPDA == "": + amountCheckedInPDA = None + else: + amountCheckedInPDA = Decimal(amountCheckedInPDA) + + + # Update the attribute + setattr(cpda_form, "advanceDueAdjustment", advanceDueAdjustment) + setattr(cpda_form, "balanceAvailable", balanceAvailable) + setattr(cpda_form, "amountCheckedInPDA", amountCheckedInPDA) + cpda_form.save() + + #database + try: + cpda_form = CPDAReimbursementform.objects.get(id=form_id) + except CPDAReimbursementform.DoesNotExist: + return JsonResponse({"error": "CPDAReimbursementform object with the provided ID does not exist"}, status=404) + + + current_owner = get_current_file_owner(file_id) + + # if action value is 0 then forward the file + # if action value is 1 then reject the file + # if action value is 3 then approve the file + # otherwise archive the file + + if(action == '0'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = username_employee, receiver_designation = designation_employee,remarks = f"Forwarded by {current_owner} to {username_employee}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = username_employee, receiver_designation = designation_employee,remarks = f"Forwarded by {current_owner} to {username_employee}, Reason : {remark}", file_extra_JSON = "None") + messages.success(request, "File forwarded successfully") + elif(action == '1'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = cpda_form.name, receiver_designation = cpda_form.designation, remarks = f"Rejected by {current_owner}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = cpda_form.name, receiver_designation = cpda_form.designation, remarks = f"Rejected by {current_owner}, Reason : {remark}", file_extra_JSON = "None") + messages.success(request, "File rejected successfully") + elif(action == '2'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = cpda_form.name, receiver_designation = cpda_form.designation, remarks = f"Approved by {current_owner}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = cpda_form.name, receiver_designation = cpda_form.designation, remarks = f"Approved by {current_owner}, Reason : {remark}", file_extra_JSON = "None") + cpda_form.approved = True + cpda_form.approvedDate = timezone.now() + cpda_form.approved_by = current_owner + cpda_form.save() + messages.success(request, "File approved successfully") + else: + is_archived = archive_file(file_id=file_id) + if( is_archived ): + messages.error(request, "Error in file archived") + else: + messages.success(request, "Success in file archived") + + + return HttpResponse("Success") + else: + + return HttpResponse("Failure") + + + + +def file_handle_ltc(request): + if request.method == 'POST': + form_data2 = request.POST + form_data=request.POST.get('context') + action = form_data2.get('action') + + form_data=json.loads(form_data) + form_id = form_data['form_id'] + file_id = form_data['file_id'] + from_user = form_data['from_user'] + from_designation = form_data['from_designation'] + username_employee = form_data['username_employee'] + designation_employee = form_data['designation_employee'] + + remark = form_data['remark_id'] + #change + + + #database + try: + ltc_form = LTCform.objects.get(id=form_id) + except LTCform.DoesNotExist: + return JsonResponse({"error": "LTCform object with the provided ID does not exist"}, status=404) + + + ltc_form.save() + + + current_owner = get_current_file_owner(file_id) + + + # if action value is 0 then forward the file + # if action value is 1 then reject the file + # if action value is 3 then approve the file + # otherwise archive the file + + if(action == '0'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = username_employee, receiver_designation = designation_employee,remarks = f"Forwarded by {current_owner} to {username_employee}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = username_employee, receiver_designation = designation_employee,remarks = f"Forwarded by {current_owner} to {username_employee}, Reason : {remark}", file_extra_JSON = "None") + messages.success(request, "File forwarded successfully") + elif(action == '1'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = ltc_form.name, receiver_designation = ltc_form.designation, remarks = f"Rejected by {current_owner}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = ltc_form.name, receiver_designation = ltc_form.designation, remarks = f"Rejected by {current_owner}, Reason : {remark}", file_extra_JSON = "None") + messages.success(request, "File rejected successfully") + elif(action == '2'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = ltc_form.name, receiver_designation = ltc_form.designation, remarks = f"Approved by {current_owner}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = ltc_form.name, receiver_designation = ltc_form.designation, remarks = f"Approved by {current_owner}, Reason : {remark}", file_extra_JSON = "None") + ltc_form.approved = True + ltc_form.approvedDate = timezone.now() + ltc_form.approved_by = current_owner + ltc_form.save() + messages.success(request, "File approved successfully") + else: + is_archived = archive_file(file_id=file_id) + if( is_archived ): + messages.error(request, "Error in file archived") + else: + messages.success(request, "Success in file archived") + + + return HttpResponse("Success") + else: + + return HttpResponse("Failure") + +def file_handle_appraisal(request): + if request.method == 'POST': + form_data2 = request.POST + form_data=request.POST.get('context') + action = form_data2.get('action') + + form_data=json.loads(form_data) + form_id = form_data['form_id'] + file_id = form_data['file_id'] + from_user = form_data['from_user'] + from_designation = form_data['from_designation'] + username_employee = form_data['username_employee'] + designation_employee = form_data['designation_employee'] + + + remark = form_data['remark_id'] + try: + appraisal_form = Appraisalform.objects.get(id=form_id) + except Appraisalform.DoesNotExist: + return JsonResponse({"error": "Appraisalform object with the provided ID does not exist"}, status=404) + + + # Update the attribute + setattr(appraisal_form, "form_id", form_id) + + appraisal_form.save() + + current_owner = get_current_file_owner(file_id) + + #database + try: + appraisal_form = Appraisalform.objects.get(id=form_id) + except Appraisalform.DoesNotExist: + return JsonResponse({"error": "Appraisalform object with the provided ID does not exist"}, status=404) + + + # if action value is 0 then forward the file + # if action value is 1 then reject the file + # if action value is 3 then approve the file + # otherwise archive the file + + if(action == '0'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = username_employee, receiver_designation = designation_employee,remarks = f"Forwarded by {current_owner} to {username_employee}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = username_employee, receiver_designation = designation_employee,remarks = f"Forwarded by {current_owner} to {username_employee}, Reason : {remark}", file_extra_JSON = "None") + messages.success(request, "File forwarded successfully") + elif(action == '1'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = appraisal_form.name, receiver_designation = appraisal_form.designation, remarks = f"Rejected by {current_owner}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = appraisal_form.name, receiver_designation = appraisal_form.designation, remarks = f"Rejected by {current_owner}, Reason : {remark}", file_extra_JSON = "None") + messages.success(request, "File rejected successfully") + elif(action == '2'): + if(remark == ""): + track_id = forward_file(file_id = file_id, receiver = appraisal_form.name, receiver_designation = appraisal_form.designation, remarks = f"Approved by {current_owner}", file_extra_JSON = "None") + else: + track_id = forward_file(file_id = file_id, receiver = appraisal_form.name, receiver_designation = appraisal_form.designation, remarks = f"Approved by {current_owner}, Reason : {remark}", file_extra_JSON = "None") + appraisal_form.approved = True + appraisal_form.approvedDate = timezone.now() + appraisal_form.approved_by = current_owner + appraisal_form.save() + messages.success(request, "File approved successfully") + else: + is_archived = archive_file(file_id=file_id) + if( is_archived ): + messages.error(request, "Error in file archived") + else: + messages.success(request, "Success in file archived") + + + return HttpResponse("Success") + else: + + return HttpResponse("Failure") + + +def view_ltc_form(request, id): + ltc_request = get_object_or_404(LTCform, id=id) + + ltc_request = reverse_ltc_pre_processing(ltc_request) + + + context = { + 'ltc_request': ltc_request + } + return render(request,'hr2Module/view_ltc_form.html',context) + +def form_mangement_ltc(request): + if(request.method == "GET"): + username = "21BCS185" + designation = "hradmin" + inbox = view_inbox(username = username, designation = designation, src_module = "HR") + + + # Extract src_object_id values + src_object_ids = [item['src_object_id'] for item in inbox] + + ltc_requests = [] + + for src_object_id in src_object_ids: + ltc_request = get_object_or_404(LTCform, id=src_object_id) + ltc_requests.append(ltc_request) + + context= { + 'ltc_requests' : ltc_requests, + 'hr' : "1", + } + + + return render(request, 'hr2Module/ltc_form.html',context) + + +def form_mangement_ltc_hr(request,id): + uploader = "21BCS183" + uploader_designation = "student" + receiver = "21BCS181" + receiver_designation = "HOD" + src_module = "HR" + src_object_id = id, + file_extra_JSON = {"key": "value"} + + # Create a file representing the LTC form and send it to HR admin + file_id = create_file( + uploader=uploader, + uploader_designation=uploader_designation, + receiver=receiver, + receiver_designation=receiver_designation, + src_module=src_module, + src_object_id=src_object_id, + file_extra_JSON=file_extra_JSON, + attached_file=None # Attach any file if necessary + ) + + + messages.success(request, "Ltc form filled successfully") + + return HttpResponse("Sucess") + +def form_mangement_ltc_hod(request): + if(request.method == "GET"): + username = "21BCS181" + designation = "HOD" + inbox = view_inbox(username = username, designation = designation, src_module = "HR") + + + # Extract src_object_id values + src_object_ids = [item['src_object_id'] for item in inbox] + + ltc_requests = [] + + for src_object_id in src_object_ids: + ltc_request = get_object_or_404(LTCform, id=src_object_id) + ltc_requests.append(ltc_request) + + context= { + 'ltc_requests' : ltc_requests, + 'hr' : "1", + } + + + return render(request, 'hr2Module/ltc_form.html',context) + + + +@login_required(login_url='/accounts/login') +def dashboard(request): + user = request.user + + user_id = ExtraInfo.objects.get(user=user).user_id + context = {'user_id': user_id} + return render(request, 'hr2Module/dashboard.html',context) + + +# cpda form ----------------------------------------------------------- + +def reverse_cpda_pre_processing(data): + reversed_data = {} + + simple_keys = [ + 'name', 'designation', 'pfNo', 'purpose', 'amountRequired', 'advanceDueAdjustment', + 'submissionDate', + 'balanceAvailable', 'advanceAmountPDA' ,'amountCheckedInPDA', + ] + + + for key in simple_keys: + value = getattr(data, key) + reversed_data[key] = value if value != 'None' else '' + + return reversed_data + + +def cpda_form(request, id): + """ Views for edit details""" + try: + employee = ExtraInfo.objects.get(user__id=id) + except: + raise Http404("Employee does not exist! id doesnt exist") + + user_id = id + creator = User.objects.get(id = user_id) + + if(employee.user_type == 'faculty' or employee.user_type == 'staff' or employee.user_type == 'student' ): + template = 'hr2Module/cpda_form.html' + + if request.method == "POST": + try: + advanceAmountPDA = request.POST.get('advanceAmountPDA') + if advanceAmountPDA == "": + advanceAmountPDA = None + else: + advanceAmountPDA = Decimal(advanceAmountPDA) + + balanceAvailable = request.POST.get('balanceAvailable') + if balanceAvailable == "": + balanceAvailable = None + else: + balanceAvailable = Decimal(balanceAvailable) + + amountCheckedInPDA = request.POST.get('amountCheckedInPDA') + if amountCheckedInPDA == "": + amountCheckedInPDA = None + else: + amountCheckedInPDA = Decimal(amountCheckedInPDA) + + + form_2 = { + 'employeeId' : id, + 'name' : request.POST.get('name'), + 'designation' : request.POST.get('designation'), + 'pfNo' : request.POST.get('pfNo'), + 'purpose' : request.POST.get('purpose'), + 'amountRequired' : request.POST.get('amountRequired'), + 'advanceDueAdjustment' : request.POST.get('advanceDueAdjustment'), + 'submissionDate' : request.POST.get('submissionDate'), + 'balanceAvailable' : request.POST.get('balanceAvailable'), + 'advanceAmountPDA' : request.POST.get('advanceAmountPDA'), + 'amountCheckedInPDA' : request.POST.get('amountCheckedInPDA'), + 'created_by' : creator, + } + + cpda_form = CPDAAdvanceform.objects.create( + employeeId = id, + name = request.POST.get('name'), + designation = request.POST.get('designation'), + pfNo = request.POST.get('pfNo'), + purpose = request.POST.get('purpose'), + amountRequired = request.POST.get('amountRequired'), + advanceDueAdjustment = request.POST.get('advanceDueAdjustment'), + submissionDate = request.POST.get('submissionDate'), + balanceAvailable = request.POST.get('balanceAvailable'), + advanceAmountPDA = request.POST.get('advanceAmountPDA'), + amountCheckedInPDA = request.POST.get('amountCheckedInPDA'), + created_by=creator, + + ) + + + uploader = employee.user + uploader_designation = 'Assistant Professor' + + get_designation = get_designation_by_user_id(employee.user) + if(get_designation): + uploader_designation = get_designation + + receiver = request.POST.get('username_employee') + receiver_designation = request.POST.get('designation_employee') + src_module = "HR" #dikkat + src_object_id = str(cpda_form.id) + file_extra_JSON = {"type": "CPDAAdvance"} + + # Create a file representing the CPDA form + file_id = create_file( + uploader=uploader, + uploader_designation=uploader_designation, + receiver=receiver, + receiver_designation=receiver_designation, + src_module=src_module, + src_object_id=src_object_id, + file_extra_JSON=file_extra_JSON, + attached_file=None # Attach any file if necessary + ) + + + + messages.success(request, "CPDA form filled successfully") + + return redirect(request.path_info) + + except Exception as e: + messages.warning(request, "Fill not correctly") + context = {'employee': employee} + return render(request, template, context) + + cpda_requests = CPDAAdvanceform.objects.filter(employeeId=id) + + username = employee.user + uploader_designation = 'Assistant Professor' + + + designation = get_designation_by_user_id(employee.user) + if(designation): + uploader_designation = designation + + + inbox = view_inbox(username = username, designation = uploader_designation, src_module = "HR") + + archived_files = view_archived(username = username, designation = uploader_designation, src_module = "HR") + + filtered_inbox = [] + for i in inbox: + item = i.get('file_extra_JSON', {}) + if item.get('type') == 'CPDAAdvance': + filtered_inbox.append(i) + + filtered_archived_files = [] + for i in archived_files: + item = i.get('file_extra_JSON', {}) + if item.get('type') == 'CPDAAdvance': + filtered_archived_files.append(i) + + context = {'employee': employee, 'cpda_requests': cpda_requests, 'inbox': filtered_inbox , 'designation':designation, 'archived_files': filtered_archived_files,'user_id':user_id} + + + messages.success(request, "CPDA form filled successfully!") + return render(request, template, context) + else: + return render(request, 'hr2Module/edit.html') + + +def form_view_cpda(request , id): + cpda_request = get_object_or_404(CPDAAdvanceform, id=id) + user_id = cpda_request.created_by.id + from_user = request.GET.get('param1') + from_designation = request.GET.get('param2') + file_id = request.GET.get('param3') + + + + template = 'hr2Module/view_cpda_form.html' + cpda_request = reverse_cpda_pre_processing(cpda_request) + + context = {'cpda_request' : cpda_request , "button" : 1 , "file_id" : file_id, "from_user" :from_user , "from_designation" : from_designation,"id":id,"user_id":user_id} + + return render(request , template , context) + + +def view_cpda_form(request, id): + cpda_request = get_object_or_404(CPDAAdvanceform, id=id) + + cpda_request = reverse_cpda_pre_processing(cpda_request) + + + context = { + 'cpda_request': cpda_request + } + return render(request,'hr2Module/view_cpda_form.html',context) + + +def form_mangement_cpda(request): + if(request.method == "GET"): + username = "21BCS185" + designation = "hradmin" + inbox = view_inbox(username = username, designation = designation, src_module = "HR") + + + # Extract src_object_id values + src_object_ids = [item['src_object_id'] for item in inbox] + + + cpda_requests = [] + + for src_object_id in src_object_ids: + cpda_request = get_object_or_404(CPDAAdvanceform, id=src_object_id) + cpda_requests.append(cpda_request) + + context= { + 'cpda_requests' : cpda_requests, + 'hr' : "1", + } + + + return render(request, 'hr2Module/cpda_form.html',context) + +def form_mangement_cpda_hr(request,id): + uploader = "21BCS183" + uploader_designation = "student" + receiver = "21BCS181" + receiver_designation = "HOD" + src_module = "HR" + src_object_id = id, + file_extra_JSON = {"key": "value"} + + # Create a file representing the CPDA form and send it to HR admin + file_id = create_file( + uploader=uploader, + uploader_designation=uploader_designation, + receiver=receiver, + receiver_designation=receiver_designation, + src_module=src_module, + src_object_id=src_object_id, + file_extra_JSON=file_extra_JSON, + attached_file=None # Attach any file if necessary + ) + + + messages.success(request, "CPda form filled successfully") + + + return HttpResponse("Success") + + +def form_mangement_cpda_hod(request): + if(request.method == "GET"): + username = "21BCS181" + designation = "HOD" + inbox = view_inbox(username = username, designation = designation, src_module = "HR") + + + # Extract src_object_id values + src_object_ids = [item['src_object_id'] for item in inbox] + + + cpda_requests = [] + + for src_object_id in src_object_ids: + cpda_request = get_object_or_404(CPDAAdvanceform, id=src_object_id) + cpda_requests.append(cpda_request) + + context= { + 'cpda_requests' : cpda_requests, + 'hr' : "1", + } + + + return render(request, 'hr2Module/cpda_form.html',context) + + +# Leave form ------------------------------------------------------------- + +def reverse_leave_pre_processing(data): + reversed_data = {} + + # Copying over simple key-value pairs + simple_keys = [ + 'name', 'designation', 'submissionDate', 'pfNo', 'departmentInfo', 'natureOfLeave', + 'leaveStartDate', 'leaveEndDate', 'purposeOfLeave', 'addressDuringLeave', 'academicResponsibility', + 'addministrativeResponsibiltyAssigned' + ] + + + for key in simple_keys: + value = getattr(data, key) + reversed_data[key] = value if value != 'None' else '' + + return reversed_data + + +def leave_form(request, id): + """ Views for edit details""" + try: + employee = ExtraInfo.objects.get(user__id=id) + except: + raise Http404("Employee does not exist! id doesnt exist") + + user_id = id + creator = User.objects.get(id = user_id) + + if(employee.user_type == 'faculty' or employee.user_type == 'student' or employee.user_type == 'staff'): + template = 'hr2Module/leave_form.html' + + if request.method == "POST": + try: + + + form_3 = { + 'employeeId' : id, + 'name' : request.POST.get('name'), + 'designation' : request.POST.get('designation'), + 'submissionDate' : request.POST.get('submissionDate'), + 'pfNo' : request.POST.get('pfNo'), + 'departmentInfo' : request.POST.get('departmentInfo'), + 'natureOfLeave' : request.POST.get('natureOfLeave'), + 'leaveStartDate' : request.POST.get('leaveStartDate'), + 'leaveEndDate' : request.POST.get('leaveEndDate'), + 'purposeOfLeave' : request.POST.get('purposeOfLeave'), + 'addressDuringLeave' : request.POST.get('addressDuringLeave'), + 'academicResponsibility' : request.POST.get('academicResponsibility'), + 'addministrativeResponsibiltyAssigned' : request.POST.get('addministrativeResponsibiltyAssigned'), + 'created_by' : creator, + } + + leave_form = LeaveForm.objects.create( + employeeId = id, + name = request.POST.get('name'), + designation = request.POST.get('designation'), + submissionDate = request.POST.get('submissionDate'), + pfNo = request.POST.get('pfNo'), + departmentInfo = request.POST.get('departmentInfo'), + leaveStartDate = request.POST.get('leaveStartDate'), + leaveEndDate = request.POST.get('leaveEndDate'), + natureOfLeave = request.POST.get('natureOfLeave'), + purposeOfLeave = request.POST.get('purposeOfLeave'), + addressDuringLeave = request.POST.get('addressDuringLeave'), + academicResponsibility = request.POST.get('academicResponsibility'), + addministrativeResponsibiltyAssigned = request.POST.get('addministrativeResponsibiltyAssigned'), + created_by=creator, + ) + + + uploader = employee.user + uploader_designation = 'Assistant Professor' + + + get_designation = get_designation_by_user_id(employee.user) + if(get_designation): + uploader_designation = get_designation + + receiver = request.POST.get('username_employee') + receiver_designation = request.POST.get('designation_employee') + src_module = "HR" + src_object_id = str(leave_form.id) + file_extra_JSON = {"type": "Leave"} + + + # Create a file representing the CPDA form + file_id = create_file( + uploader=uploader, + uploader_designation=uploader_designation, + receiver=receiver, + receiver_designation=receiver_designation, + src_module=src_module, + src_object_id=src_object_id, + file_extra_JSON=file_extra_JSON, + attached_file=None # Attach any file if necessary + ) + + + messages.success(request, "Leave form filled successfully") + + return redirect(request.path_info) + + except Exception as e: + messages.warning(request, "Fill not correctly") + context = {'employee': employee} + return render(request, template, context) + + # Query all Leave requests + leave_requests = LeaveForm.objects.filter(employeeId=id) + + username = employee.user + uploader_designation = 'Assistant Professor' + + designation = get_designation_by_user_id(employee.user) + if(designation): + uploader_designation = designation + + + inbox = view_inbox(username = username, designation = uploader_designation, src_module = "HR") + + archived_files = view_archived(username = username, designation = uploader_designation, src_module = "HR") + + filtered_inbox = [] + for i in inbox: + item = i.get('file_extra_JSON', {}) + if item.get('type') == 'Leave': + filtered_inbox.append(i) + + filtered_archived_files = [] + for i in archived_files: + item = i.get('file_extra_JSON', {}) + if item.get('type') == 'Leave': + filtered_archived_files.append(i) + + + + context = {'employee': employee, 'leave_requests': leave_requests, 'inbox': filtered_inbox , 'designation':designation, 'archived_files': filtered_archived_files,'user_id':user_id} + + messages.success(request, "Leave form filled successfully!") + return render(request, template, context) + else: + return render(request, 'hr2Module/edit.html') + + + +def form_view_leave(request , id): + + leave_request = get_object_or_404(LeaveForm, id=id) + user_id = leave_request.created_by.id + from_user = request.GET.get('param1') + from_designation = request.GET.get('param2') + file_id = request.GET.get('param3') + + + template = 'hr2Module/view_leave_form.html' + leave_request = reverse_leave_pre_processing(leave_request) + + context = {'leave_request' : leave_request , "button" : 1 , "file_id" : file_id, "from_user" :from_user , "from_designation" : from_designation, "id" : id,"user_id":user_id} + + return render(request , template , context) + +# ek or bna lena +def view_leave_form(request, id): + leave_request = get_object_or_404(LeaveForm, id=id) + + + + leave_request = reverse_leave_pre_processing(leave_request) + + + context = { + 'leave_request': leave_request + } + return render(request,'hr2Module/view_leave_form.html',context) + + +def form_mangement_leave(request): + if(request.method == "GET"): + username = "21BCS185" + designation = "hradmin" + inbox = view_inbox(username = username, designation = designation, src_module = "HR") + + + # Extract src_object_id values + src_object_ids = [item['src_object_id'] for item in inbox] + + leave_requests = [] + + for src_object_id in src_object_ids: + leave_request = get_object_or_404(LeaveForm, id=src_object_id) + leave_requests.append(leave_request) + + context= { + 'leave_requests' : leave_requests, + 'hr' : "1", + } + + + return render(request, 'hr2Module/leave_form.html',context) + + +def form_mangement_leave_hr(request,id): + uploader = "21BCS183" + uploader_designation = "student" + receiver = "21BCS181" + receiver_designation = "HOD" + src_module = "HR" + src_object_id = id, + file_extra_JSON = {"key": "value"} + + # Create a file representing the Leave form and send it to HR admin + file_id = create_file( + uploader=uploader, + uploader_designation=uploader_designation, + receiver=receiver, + receiver_designation=receiver_designation, + src_module=src_module, + src_object_id=src_object_id, + file_extra_JSON=file_extra_JSON, + attached_file=None # Attach any file if necessary + ) + + + messages.success(request, "Leave form filled successfully") + + return HttpResponse("Sucess") + +def form_mangement_leave_hod(request): + if(request.method == "GET"): + username = "21BCS181" + designation = "HOD" + inbox = view_inbox(username = username, designation = designation, src_module = "HR") + + + # Extract src_object_id values + src_object_ids = [item['src_object_id'] for item in inbox] + + + leave_requests = [] + + for src_object_id in src_object_ids: + leave_request = get_object_or_404(LeaveForm, id=src_object_id) + leave_requests.append(leave_request) + + context= { + 'leave_requests' : leave_requests, + 'hr' : "1", + } + + + return render(request, 'hr2Module/leave_form.html',context) + + + +def appraisal_form(request, id): + """ Views for edit details""" + try: + employee = ExtraInfo.objects.get(user__id=id) + except: + raise Http404("Employee does not exist! id doesnt exist") + + user_id = id + creator = User.objects.get(id = user_id) + + if(employee.user_type == 'faculty' or employee.user_type == 'staff' or employee.user_type == 'student'): + template = 'hr2Module/appraisal_form.html' + + if request.method == "POST": + try: + + data = appraisal_pre_processing(request) + + + form_4 = { + 'employeeId': id, + 'name': request.POST.get('name'), + 'designation': request.POST.get('designation'), + 'disciplineInfo': request.POST.get('disciplineInfo'), + 'specificFieldOfKnowledge': request.POST.get('specificFieldOfKnowledge'), + 'currentResearchInterests': request.POST.get('currentResearchInterests'), + 'coursesTaught': data['coursesTaught'], + 'newCoursesIntroduced': data['newCoursesIntroduced'], + 'newCoursesDeveloped': data['newCoursesDeveloped'], + 'otherInstructionalTasks': request.POST.get('otherInstructionalTasks'), + 'thesisSupervision': data['thesisSupervision'], + 'sponsoredReseachProjects': data['sponsoredReseachProjects'], + 'otherResearchElement': request.POST.get('otherResearchElement'), + 'publication': request.POST.get('publication'), + 'referredConference': request.POST.get('referredConference'), + 'conferenceOrganised': request.POST.get('conferenceOrganised'), + 'membership': request.POST.get('membership'), + 'honours ' : request.POST.get('honours'), + 'editorOfPublications': request.POST.get('editorOfPublications'), + 'expertLectureDelivered': request.POST.get('expertLectureDelivered'), + 'membershipOfBOS': request.POST.get('membershipOfBOS'), + 'otherExtensionTasks': request.POST.get('otherExtensionTasks'), + 'administrativeAssignment': request.POST.get('administrativeAssignment'), + 'serviceToInstitute': request.POST.get('serviceToInstitute'), + 'otherContribution': request.POST.get('otherContribution'), + 'performanceComments' : request.POST.get('performanceComments'), + 'submissionDate' : request.POST.get('submissionDate'), + 'approved' : request.POST.get('approved'), + 'approvedDate' : request.POST.get('approvedDate'), + 'created_by' : creator, + + } + + + appraisal_form = Appraisalform.objects.create( + employeeId= id, + name= request.POST.get('name'), + designation= request.POST.get('designation'), + disciplineInfo= request.POST.get('disciplineInfo'), + specificFieldOfKnowledge= request.POST.get('specificFieldOfKnowledge'), + currentResearchInterests= request.POST.get('currentResearchInterests'), + coursesTaught= data['coursesTaught'], + newCoursesIntroduced= data['newCoursesIntroduced'], + newCoursesDeveloped= data['newCoursesDeveloped'], + otherInstructionalTasks= request.POST.get('otherInstructionalTasks'), + thesisSupervision= data['thesisSupervision'], + sponsoredReseachProjects= data['sponsoredReseachProjects'], + otherResearchElement= request.POST.get('otherResearchElement'), + publication= request.POST.get('publication'), + referredConference= request.POST.get('referredConference'), + conferenceOrganised= request.POST.get('conferenceOrganised'), + membership= request.POST.get('membership'), + honours = request.POST.get('honours'), + editorOfPublications= request.POST.get('editorOfPublications'), + expertLectureDelivered= request.POST.get('expertLectureDelivered'), + membershipOfBOS= request.POST.get('membershipOfBOS'), + otherExtensionTasks= request.POST.get('otherExtensionTasks'), + administrativeAssignment= request.POST.get('administrativeAssignment'), + serviceToInstitute= request.POST.get('serviceToInstitute'), + otherContribution= request.POST.get('otherContribution'), + performanceComments = request.POST.get('performanceComments'), + submissionDate = request.POST.get('submissionDate'), + approved = request.POST.get('approved'), + approvedDate = request.POST.get('approvedDate'), + created_by=creator, + + + ) + + uploader = employee.user + uploader_designation = 'Assistant Professor' + + get_designation = get_designation_by_user_id(employee.user) + if(get_designation): + uploader_designation = get_designation + + receiver = request.POST.get('username_employee') + receiver_designation = request.POST.get('designation_employee') + src_module = "HR" + src_object_id = str(appraisal_form.id) + file_extra_JSON = {"type": "Appraisal"} + + + # Create a file representing the AppraisL form and send it to HR admin + file_id = create_file( + uploader=uploader, + uploader_designation=uploader_designation, + receiver=receiver, + receiver_designation=receiver_designation, + src_module=src_module, + src_object_id=src_object_id, + file_extra_JSON=file_extra_JSON, + attached_file=None # Attach any file if necessary + ) + + + messages.success(request, "Appraisal form filled successfully") + + return redirect(request.path_info) + + except Exception as e: + messages.warning(request, "Fill not correctly") + context = {'employee': employee} + return render(request, template, context) + + + + appraisal_requests = Appraisalform.objects.filter(employeeId=id) + + username = employee.user + uploader_designation = 'Assistant Professor' + + + + designation = get_designation_by_user_id(employee.user) + if(designation): + uploader_designation = designation + + + inbox = view_inbox(username = username, designation = uploader_designation, src_module = "HR") + + archived_files = view_archived(username = username, designation = uploader_designation, src_module = "HR") + + filtered_inbox = [] + for i in inbox: + item = i.get('file_extra_JSON', {}) + if item.get('type') == 'Appraisal': + filtered_inbox.append(i) + + filtered_archived_files = [] + for i in archived_files: + item = i.get('file_extra_JSON', {}) + if item.get('type') == 'Appraisal': + filtered_archived_files.append(i) + + + context = {'employee': employee, 'appraisal_requests': appraisal_requests, 'inbox': filtered_inbox , 'designation':designation, 'archived_files': filtered_archived_files,'user_id':user_id} + + messages.success(request, "Appraisal form filled successfully!") + return render(request, template, context) + else: + return render(request, 'hr2Module/edit.html') + + + +def form_view_appraisal(request , id): + appraisal_request = get_object_or_404(Appraisalform, id=id) + user_id = appraisal_request.created_by.id + from_user = request.GET.get('param1') + from_designation = request.GET.get('param2') + file_id = request.GET.get('param3') + + + template = 'hr2Module/view_appraisal_form.html' + appraisal_request = reverse_appraisal_pre_processing(appraisal_request) + + context = {'appraisal_request' : appraisal_request , "button" : 1 , "file_id" : file_id, "from_user" :from_user , "from_designation" : from_designation,"id":id,"user_id":user_id} + + return render(request , template , context) + + +def view_appraisal_form(request, id): + appraisal_request = get_object_or_404(Appraisalform, id=id) + + + appraisal_request = reverse_appraisal_pre_processing(appraisal_request) + + context = { + 'appraisal_request': appraisal_request + } + return render(request,'hr2Module/view_appraisal_form.html',context) + + + +def form_mangement_appraisal(request): + if(request.method == "GET"): + username = "21BCS185" + designation = "hradmin" + inbox = view_inbox(username = username, designation = designation, src_module = "HR") + + + src_object_ids = [item['src_object_id'] for item in inbox] + + appraisal_requests = [] + + for src_object_id in src_object_ids: + appraisal_request = get_object_or_404(Appraisalform, id=src_object_id) + appraisal_requests.append(appraisal_request) + + context= { + 'appraisal_requests' : appraisal_requests, + 'hr' : "1", + } + + + return render(request, 'hr2Module/appraisal_form.html',context) + + +def form_mangement_appraisal_hr(request,id): + uploader = "21BCS183" + uploader_designation = "student" + receiver = "21BCS181" + receiver_designation = "HOD" + src_module = "HR" + src_object_id = id, + file_extra_JSON = {"key": "value"} + + # Create a file representing the Appraisal form and send it to HR admin + file_id = create_file( + uploader=uploader, + uploader_designation=uploader_designation, + receiver=receiver, + receiver_designation=receiver_designation, + src_module=src_module, + src_object_id=src_object_id, + file_extra_JSON=file_extra_JSON, + attached_file=None # Attach any file if necessary + ) + + + messages.success(request, "Appraisal form filled successfully") + + return HttpResponse("Sucess") + + + +def appraisal_pre_processing(request): + data = {} + + + coursesTaught = "" + + for i in range(1,3): + for j in range(1,8): + key_is = f'info_{i}_{j}' + + if(request.POST.get(key_is) == ""): + coursesTaught = coursesTaught + 'None' + ',' + else: + coursesTaught = coursesTaught + request.POST.get(key_is) + ',' + + data['coursesTaught'] = coursesTaught.rstrip(',') + + newCoursesIntroduced = "" + + for i in range(3,5): + for j in range(1,4): + key_is = f'info_{i}_{j}' + + if(request.POST.get(key_is) == ""): + newCoursesIntroduced = newCoursesIntroduced + 'None' + ',' + else: + newCoursesIntroduced = newCoursesIntroduced + request.POST.get(key_is) + ',' + + data['newCoursesIntroduced'] = newCoursesIntroduced.rstrip(',') + + + newCoursesDeveloped = "" + + for i in range(5,7): + for j in range(1,5): + key_is = f'info_{i}_{j}' + + if(request.POST.get(key_is) == ""): + newCoursesDeveloped = newCoursesDeveloped + 'None' + ',' + else: + newCoursesDeveloped = newCoursesDeveloped + request.POST.get(key_is) + ',' + + data['newCoursesDeveloped'] = newCoursesDeveloped.rstrip(',') + + thesisSupervision = "" + + for i in range(7,9): + for j in range(1,6): + key_is = f'info_{i}_{j}' + + if(request.POST.get(key_is) == ""): + thesisSupervision = thesisSupervision + 'None' + ',' + else: + thesisSupervision = thesisSupervision + request.POST.get(key_is) + ',' + + data['thesisSupervision'] = thesisSupervision.rstrip(',') + + + + sponsoredReseachProjects = "" + + for i in range(9,10): + for j in range(1,8): + key_is = f'info_{i}_{j}' + + if(request.POST.get(key_is) == ""): + sponsoredReseachProjects = sponsoredReseachProjects + 'None' + ',' + else: + sponsoredReseachProjects = sponsoredReseachProjects + request.POST.get(key_is) + ',' + + data['sponsoredReseachProjects'] = sponsoredReseachProjects.rstrip(',') + + + return data + + + + +def reverse_appraisal_pre_processing(data): + reversed_data = {} + + # Copying over simple key-value pairs + simple_keys = [ + 'name', 'designation', 'disciplineInfo', 'specificFieldOfKnowledge', 'designation', 'currentResearchInterests', + 'otherInstructionalTasks', 'otherResearchElement', 'publication', 'referredConference', + 'conferenceOrganised', 'membership', 'honours', 'editorOfPublications', + 'expertLectureDelivered', 'membershipOfBOS', 'otherExtensionTasks', + 'administrativeAssignment', 'serviceToInstitute', 'otherContribution', 'performanceComments', + 'submissionDate' + ] + + + for key in simple_keys: + value = getattr(data, key) + reversed_data[key] = value if value != 'None' else '' + + courses_taught = getattr(data,'coursesTaught').split(',') + for index, value in enumerate(courses_taught): + courses_taught[index] = value if value != 'None' else '' + + reversed_data['info_1_1'] = courses_taught[0] + reversed_data['info_1_2'] = courses_taught[1] + reversed_data['info_1_3'] = courses_taught[2] + reversed_data['info_1_4'] = courses_taught[3] + reversed_data['info_1_5'] = courses_taught[4] + reversed_data['info_1_6'] = courses_taught[5] + reversed_data['info_1_7'] = courses_taught[6] + reversed_data['info_2_1'] = courses_taught[7] + reversed_data['info_2_2'] = courses_taught[8] + reversed_data['info_2_3'] = courses_taught[9] + reversed_data['info_2_4'] = courses_taught[10] + reversed_data['info_2_5'] = courses_taught[11] + reversed_data['info_2_6'] = courses_taught[12] + reversed_data['info_2_7'] = courses_taught[13] + + # # Reversing details_of_dependents + new_courses_introduced = getattr(data,'newCoursesIntroduced').split(',') + for i in range(3, 5): + for j in range(1, 4): + key = f'info_{i}_{j}' + value = new_courses_introduced.pop(0) + reversed_data[key] = value if value != 'None' else '' + + + + newCoursesDeveloped = getattr(data,'newCoursesDeveloped').split(',') + for i in range(5, 7): + for j in range(1, 5): + key = f'info_{i}_{j}' + value = newCoursesDeveloped.pop(0) + reversed_data[key] = value if value != 'None' else '' + + + + thesis_reasearch = getattr(data,'otherResearchElement').split(',') + for i in range(7, 9): + for j in range(1, 6): + key = f'info_{i}_{j}' + if thesis_reasearch: + value = thesis_reasearch.pop() + else: + # Handle the case where the list is empty + print("The list is empty, cannot pop from it.") + # value = thesis_reasearch.pop(0) + reversed_data[key] = value if value != 'None' else '' + + + + sponsored_research = getattr(data,'sponsoredReseachProjects').split(',') + for i in range(9, 10): + for j in range(1, 8): + key = f'info_{i}_{j}' + value = sponsored_research.pop(0) + reversed_data[key] = value if value != 'None' else '' + + return reversed_data + + + +def reverse_cpda_reimbursement_pre_processing(data): + reversed_data = {} + + simple_keys = [ + 'name', 'designation', 'pfNo', 'purpose', 'advanceTaken', 'adjustmentSubmitted', + 'submissionDate', + 'balanceAvailable', 'advanceDueAdjustment', 'amountCheckedInPDA', + ] + + + for key in simple_keys: + value = getattr(data, key) + reversed_data[key] = value if value != 'None' else '' + + return reversed_data + + +def cpda_reimbursement_form(request, id): + """ Views for edit details""" + try: + employee = ExtraInfo.objects.get(user__id=id) + except: + raise Http404("Employee does not exist! id doesnt exist") + + user_id = id + creator = User.objects.get(id = user_id) + + if(employee.user_type == 'faculty' or employee.user_type == 'staff' or employee.user_type == 'student' ): + template = 'hr2Module/cpda_reimbursement_form.html' + + if request.method == "POST": + try: + + form_2 = { + 'employeeId' : id, + 'name' : request.POST.get('name'), + 'designation' : request.POST.get('designation'), + 'pfNo' : request.POST.get('pfNo'), + 'purpose' : request.POST.get('purpose'), + 'advanceTaken' : request.POST.get('advanceTaken'), + 'advanceDueAdjustment' : request.POST.get('advanceDueAdjustment'), + 'submissionDate' : request.POST.get('submissionDate'), + 'balanceAvailable' : request.POST.get('balanceAvailable'), + 'adjustmentSubmitted' : request.POST.get('adjustmentSubmitted'), + 'amountCheckedInPDA' : request.POST.get('amountCheckedInPDA'), + 'created_by' : creator, + } + + cpda_form = CPDAReimbursementform.objects.create( + employeeId = id, + name = request.POST.get('name'), + designation = request.POST.get('designation'), + pfNo = request.POST.get('pfNo'), + purpose = request.POST.get('purpose'), + advanceTaken = request.POST.get('advanceTaken'), + advanceDueAdjustment = request.POST.get('advanceDueAdjustment'), + submissionDate = request.POST.get('submissionDate'), + balanceAvailable = request.POST.get('balanceAvailable'), + adjustmentSubmitted = request.POST.get('adjustmentSubmitted'), + amountCheckedInPDA = request.POST.get('amountCheckedInPDA'), + created_by=creator, + + ) + + + uploader = employee.user + uploader_designation = 'Assistant Professor' + + get_designation = get_designation_by_user_id(employee.user) + if(get_designation): + uploader_designation = get_designation + + receiver = request.POST.get('username_employee') + receiver_designation = request.POST.get('designation_employee') + src_module = "HR" + src_object_id = str(cpda_form.id) + file_extra_JSON = {"type": "CPDAReimbursement"} + + # Create a file representing the CPDA form + file_id = create_file( + uploader=uploader, + uploader_designation=uploader_designation, + receiver=receiver, + receiver_designation=receiver_designation, + src_module=src_module, + src_object_id=src_object_id, + file_extra_JSON=file_extra_JSON, + attached_file=None # Attach any file if necessary + ) + + messages.success(request, "cpdareimbursement form filled successfully") + + return redirect(request.path_info) + + except Exception as e: + messages.warning(request, "Fill not correctly") + context = {'employee': employee} + return render(request, template, context) + + cpda_reimbursement_requests = CPDAReimbursementform.objects.filter(employeeId=id) + + username = employee.user + uploader_designation = 'Assistant Professor' + + + designation = get_designation_by_user_id(employee.user) + if(designation): + uploader_designation = designation + + + inbox = view_inbox(username = username, designation = uploader_designation, src_module = "HR") + + archived_files = view_archived(username = username, designation = uploader_designation, src_module = "HR") + + filtered_inbox = [] + for i in inbox: + item = i.get('file_extra_JSON', {}) + if item.get('type') == 'CPDAReimbursement': + filtered_inbox.append(i) + + filtered_archived_files = [] + for i in archived_files: + item = i.get('file_extra_JSON', {}) + if item.get('type') == 'CPDAReimbursement': + filtered_archived_files.append(i) + + + context = {'employee': employee, 'cpda_reimbursement_requests': cpda_reimbursement_requests, 'inbox': filtered_inbox , 'designation':designation, 'archived_files': filtered_archived_files,'user_id':user_id} + + + messages.success(request, "cpdareimbursement form filled successfully!") + return render(request, template, context) + else: + return render(request, 'hr2Module/edit.html') + + + + +def form_view_cpda_reimbursement(request , id): + cpda_reimbursement_request = get_object_or_404(CPDAReimbursementform, id=id) + user_id = cpda_reimbursement_request.created_by.id + # isko recheck krna h + from_user = request.GET.get('param1') + from_designation = request.GET.get('param2') + file_id = request.GET.get('param3') + + template = 'hr2Module/view_cpda_reimbursement_form.html' + cpda_reimbursement_request = reverse_cpda_reimbursement_pre_processing(cpda_reimbursement_request) + + context = {'cpda_reimbursement_request' : cpda_reimbursement_request , "button" : 1 , "file_id" : file_id, "from_user" :from_user , "from_designation" : from_designation,"id":id,"user_id":user_id} + + return render(request , template , context) + + +def view_cpda_reimbursement_form(request, id): + cpda_reimbursement_request = get_object_or_404(CPDAReimbursementform, id=id) + + cpda_reimbursement_request = reverse_cpda_reimbursement_pre_processing(cpda_reimbursement_request) + + context = { + 'cpda_reimbursement_request': cpda_reimbursement_request + } + return render(request,'hr2Module/view_cpda_reimbursement_form.html',context) + + + +def form_mangement_cpda_reimbursement(request): + if(request.method == "GET"): + username = "21BCS185" + designation = "hradmin" + inbox = view_inbox(username = username, designation = designation, src_module = "HR") + + + # Extract src_object_id values + src_object_ids = [item['src_object_id'] for item in inbox] + + + cpda_reimbursement_requests = [] + + for src_object_id in src_object_ids: + cpda_reimbursement_request = get_object_or_404(CPDAReimbursementform, id=src_object_id) + cpda_reimbursement_requests.append(cpda_reimbursement_request) + + context= { + 'cpda_reimbursement_requests' : cpda_reimbursement_requests, + 'hr' : "1", + } + + + return render(request, 'hr2Module/cpda_reimbursement_form.html',context) + +def form_mangement_cpda_reimbursement_hr(request,id): + uploader = "21BCS183" + uploader_designation = "student" + receiver = "21BCS181" + receiver_designation = "HOD" + src_module = "HR" + src_object_id = id, + file_extra_JSON = {"key": "value"} + + # Create a file representing the CPDA form and send it to HR admin + file_id = create_file( + uploader=uploader, + uploader_designation=uploader_designation, + receiver=receiver, + receiver_designation=receiver_designation, + src_module=src_module, + src_object_id=src_object_id, + file_extra_JSON=file_extra_JSON, + attached_file=None # Attach any file if necessary + ) + + + messages.success(request, "CPda form filled successfully") + + + return HttpResponse("Success") + + +def form_mangement_cpda_reimbursement_hod(request): + if(request.method == "GET"): + username = "21BCS181" + designation = "HOD" + inbox = view_inbox(username = username, designation = designation, src_module = "HR") + + + # Extract src_object_id values + src_object_ids = [item['src_object_id'] for item in inbox] + + + cpda_reimbursement_requests = [] + + for src_object_id in src_object_ids: + cpda_reimbursement_request = get_object_or_404(CPDAReimbursementform, id=src_object_id) + cpda_reimbursement_requests.append(cpda_reimbursement_request) + + context= { + 'cpda_reimbursement_requests' : cpda_reimbursement_requests, + 'hr' : "1", + } + + + return render(request, 'hr2Module/cpda_reimbursement_form.html',context) + + +def getform(request): + form_type = request.GET.get("type") + id = request.GET.get("id") + + if form_type == "LTC": + try: + forms = LTCform.objects.filter(created_by=id) + + form_data = [] + for form in forms: + form_data.append({ + 'id': form.id, + 'name': form.name, + 'designation': form.designation, + 'submissionDate': form.submissionDate.strftime("%Y-%m-%d") if form.submissionDate else None, + 'is_approved' : form.approved, + + }) + + return JsonResponse(form_data, safe=False) # Return JSON response + except LTCform.DoesNotExist: + return JsonResponse({"message": "No LTC forms found."}, status=404) + +def getformcpdaAdvance(request): + form_type = request.GET.get("type") + id = request.GET.get("id") + + if form_type == "CPDAAdvance": + try: + forms = CPDAAdvanceform.objects.filter(created_by=id) + form_data = [] + for form in forms: + form_data.append({ + 'id': form.id, + 'name': form.name, + 'designation': form.designation, + 'submissionDate': form.submissionDate.strftime("%Y-%m-%d") if form.submissionDate else None, + 'is_approved' : form.approved, + }) + + return JsonResponse(form_data, safe=False) # Return JSON response + except CPDAAdvanceform.DoesNotExist: + return JsonResponse({"message": "No CPDAAdvance forms found."}, status=404) + + +def getformLeave(request): + form_type = request.GET.get("type") + id = request.GET.get("id") + + if form_type == "Leave": + try: + forms = LeaveForm.objects.filter(created_by=id) + form_data = [] + for form in forms: + form_data.append({ + 'id': form.id, + 'name': form.name, + 'designation': form.designation, + 'submissionDate': form.submissionDate.strftime("%Y-%m-%d") if form.submissionDate else None, + 'is_approved' : form.approved, + # Add other fields as needed + }) + + return JsonResponse(form_data, safe=False) # Return JSON response + except LeaveForm.DoesNotExist: + return JsonResponse({"message": "No Leave forms found."}, status=404) + + +def getformAppraisal(request): + form_type = request.GET.get("type") + id = request.GET.get("id") + + if form_type == "Appraisal": + try: + forms = Appraisalform.objects.filter(created_by=id) + form_data = [] + for form in forms: + form_data.append({ + 'id': form.id, + 'name': form.name, + 'designation': form.designation, + 'submissionDate': form.submissionDate.strftime("%Y-%m-%d") if form.submissionDate else None, + 'is_approved' : form.approved, + }) + + return JsonResponse(form_data, safe=False) # Return JSON response + except Appraisalform.DoesNotExist: + return JsonResponse({"message": "No Appraisal forms found."}, status=404) + + + +def getformcpdaReimbursement(request): + form_type = request.GET.get("type") + id = request.GET.get("id") + + if form_type == "CPDAReimbursement": + try: + forms = CPDAReimbursementform.objects.filter(created_by=id) + form_data = [] + for form in forms: + form_data.append({ + 'id': form.id, + 'name': form.name, + 'designation': form.designation, + 'submissionDate': form.submissionDate.strftime("%Y-%m-%d") if form.submissionDate else None, + 'is_approved' : form.approved, + # Add other fields as needed + }) + + return JsonResponse(form_data, safe=False) # Return JSON response + except CPDAReimbursementform.DoesNotExist: + return JsonResponse({"message": "No CPDAReimbursement forms found."}, status=404) + + + diff --git a/FusionIIIT/applications/notifications_extension/api/urls.py b/FusionIIIT/applications/notifications_extension/api/urls.py index 1b420e336..62238c007 100644 --- a/FusionIIIT/applications/notifications_extension/api/urls.py +++ b/FusionIIIT/applications/notifications_extension/api/urls.py @@ -20,6 +20,7 @@ DepartmentNotificationAPIView, OfficeDeanRSPCNotificationAPIView, ResearchProceduresNotificationAPIView, + HostelModuleNotificationAPIView, MarkAsRead, Delete, NotificationsList, @@ -48,4 +49,5 @@ path('department_notification/', DepartmentNotificationAPIView.as_view(), name='department_notification'), path('office_dean_RSPC_notification/', OfficeDeanRSPCNotificationAPIView.as_view(), name='office_dean_RSPC_notification'), path('research_procedures_notification/', ResearchProceduresNotificationAPIView.as_view(), name='research_procedures_notification'), + path('hostel_notifications/', HostelModuleNotificationAPIView.as_view(), name='hostel_notifications'), ] diff --git a/FusionIIIT/applications/notifications_extension/api/views.py b/FusionIIIT/applications/notifications_extension/api/views.py index b87b488da..c5017f79f 100644 --- a/FusionIIIT/applications/notifications_extension/api/views.py +++ b/FusionIIIT/applications/notifications_extension/api/views.py @@ -29,7 +29,8 @@ AssistantshipClaim_account_notify, department_notif, office_module_DeanRSPC_notif, - research_procedures_notif) + research_procedures_notif, + hostel_notifications) @@ -327,7 +328,20 @@ def post(self, request, *args, **kwargs): research_procedures_notif(sender, recipient, type) return Response({'message': 'Notification sent successfully'}, status=status.HTTP_201_CREATED) - + +class HostelModuleNotificationAPIView(APIView): + def post(self, request, *args, **kwargs): + # Extract data from the request, you can customize this based on your needs + sender = request.user + recipient_id = request.data.get('recipient') + type = request.data.get('type') + User = get_user_model() + recipient = User.objects.get(pk=recipient_id) + # Trigger the notification function + hostel_notifications(sender, recipient, type) + + return Response({'message': 'Notification sent successfully'}, status=status.HTTP_201_CREATED) + class MarkAsRead(APIView): def put(self,request,**args): diff --git a/FusionIIIT/applications/notifications_extension/views.py b/FusionIIIT/applications/notifications_extension/views.py index 59a37547a..a95e7a798 100644 --- a/FusionIIIT/applications/notifications_extension/views.py +++ b/FusionIIIT/applications/notifications_extension/views.py @@ -26,5 +26,9 @@ def mark_as_read_and_redirect(request, slug=None): if(notification.data['module'] == 'Complaint System'): complaint_id=notification.description return HttpResponseRedirect(reverse(notification.data['url'],kwargs={'detailcomp_id1':complaint_id})) + elif(notification.data['module'] == 'Course Management'): + course_code = notification.data['course_code'] + print(course_code) + return HttpResponseRedirect(reverse(notification.data['url'],kwargs={'course_code': course_code})) else: - return HttpResponseRedirect(reverse(notification.data['url'])) \ No newline at end of file + return HttpResponseRedirect(reverse(notification.data['url'])) diff --git a/FusionIIIT/applications/online_cms/admin.py b/FusionIIIT/applications/online_cms/admin.py index ac9eb780a..8b8cab7ab 100644 --- a/FusionIIIT/applications/online_cms/admin.py +++ b/FusionIIIT/applications/online_cms/admin.py @@ -2,14 +2,13 @@ from .models import (Assignment, CourseDocuments, CourseVideo, Forum, ForumReply, Quiz, QuizQuestion, QuizResult, StudentAnswer, - StudentAssignment, Topics) + StudentAssignment, Topics,Student_grades) class QuizResultAdmin(admin.ModelAdmin): model = QuizResult raw_id_fields = ("student_id",) admin.site.register(CourseDocuments) - admin.site.register(CourseVideo) admin.site.register(Quiz) @@ -29,3 +28,5 @@ class QuizResultAdmin(admin.ModelAdmin): admin.site.register(Forum) admin.site.register(ForumReply) + +admin.site.register(Student_grades) diff --git a/FusionIIIT/applications/online_cms/forms.py b/FusionIIIT/applications/online_cms/forms.py index e656a838f..c03a8e160 100644 --- a/FusionIIIT/applications/online_cms/forms.py +++ b/FusionIIIT/applications/online_cms/forms.py @@ -1,10 +1,13 @@ +# from django import forms import datetime from datetime import time, timedelta #import information from the models from django import forms # from .models import StoreMarks -from applications.academic_information.models import Student_attendance +from applications.academic_information.models import (Student_attendance,Timetable) + +from .models import * #the types of exam whose marks can be stored from edit marks in assessment, related to StoreMarks table in models EXAM_TYPES= [ ('quiz1', 'Quiz 1'), @@ -112,4 +115,27 @@ def clean(self): examtype = self.cleaned_data.get("exam_type") enteredmarks = self.cleaned_data.get("entered_marks") - return self.cleaned_data \ No newline at end of file + return self.cleaned_data + +class GradingSchemeForm(forms.Form): + quiz_weightage = forms.DecimalField(label='Quiz', max_digits=10, decimal_places=2) + midsem_weightage = forms.DecimalField(label='Mid Semester', max_digits=10, decimal_places=2) + assignment_weightage = forms.DecimalField(label='Assignment', max_digits=10, decimal_places=2) + endsem_weightage = forms.DecimalField(label='End Semester', max_digits=10, decimal_places=2) + project_weightage = forms.DecimalField(label='Project', max_digits=10, decimal_places=2) + + +class AcademicTimetableForm(forms.ModelForm): + """ + the form to add a new academic timetable to the database. + It consist of year, programme and the timetable file upload + + @attrubutes: + model - the model used is the Timetable class + fields - the fields shown in the form for the user to fill up is year, programme and timetable file upload + widgets - defining the id, required and placeholder of the filed in the form + + """ + class Meta: + model = Timetable + fields = ('programme', 'batch', 'branch', 'time_table') diff --git a/FusionIIIT/applications/online_cms/helpers.py b/FusionIIIT/applications/online_cms/helpers.py index 8fb9f530e..22bd1659a 100644 --- a/FusionIIIT/applications/online_cms/helpers.py +++ b/FusionIIIT/applications/online_cms/helpers.py @@ -5,12 +5,25 @@ def semester(roll): - month = datetime.now().month - sem = 0 - if month >= 8 and month <= 12: - sem = 1 - semester = (datetime.now().year-int(roll))*2+sem - return semester + if not roll.isnumeric(): + s='' + s+='2' + s+='0' + s+=roll[0] + s+=roll[1] + month = datetime.now().month + sem = 0 + if month >= 8 and month <= 12: + sem = 1 + semester = (datetime.now().year-int(s))*2+sem + return semester + else: + month = datetime.now().month + sem = 0 + if month >= 8 and month <= 12: + sem = 1 + semester = (datetime.now().year-int(roll))*2+sem + return semester #storing media files like images, videos and assignments def create_thumbnail(course_code,course, row, name, ext, attach_str, thumb_time, thumb_size): @@ -19,4 +32,4 @@ def create_thumbnail(course_code,course, row, name, ext, attach_str, thumb_time, filename = filename + name.replace(' ', '-') + '-' + attach_str + '.png' process = 'ffmpeg -y -i ' + filepath + ' -vframes ' + str(1) + ' -an -s ' process = process + thumb_size + ' -ss ' + str(thumb_time) + ' ' + filename - subprocess.call(process, shell=True) + subprocess.call(process, shell=True) \ No newline at end of file diff --git a/FusionIIIT/applications/online_cms/migrations/0001_initial.py b/FusionIIIT/applications/online_cms/migrations/0001_initial.py index 2990b152b..9f3c47375 100644 --- a/FusionIIIT/applications/online_cms/migrations/0001_initial.py +++ b/FusionIIIT/applications/online_cms/migrations/0001_initial.py @@ -193,4 +193,4 @@ class Migration(migrations.Migration): ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.course')), ], ), - ] + ] \ No newline at end of file diff --git a/FusionIIIT/applications/online_cms/models.py b/FusionIIIT/applications/online_cms/models.py index a34e5c3ee..74f2a93bd 100644 --- a/FusionIIIT/applications/online_cms/models.py +++ b/FusionIIIT/applications/online_cms/models.py @@ -1,12 +1,21 @@ from django.db import models #import models used from academic procedure and academic information modules and globals -from applications.academic_information.models import Course, Student, Curriculum -from applications.academic_procedures.models import Register +from applications.academic_information.models import Student, Curriculum +from applications.programme_curriculum.models import Course as Courses, CourseInstructor from applications.globals.models import ExtraInfo +#the modules for containing course content +class Modules(models.Model): + module_name = models.CharField(max_length=50) + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) + + def __str__(self): + return self.module_name + #the documents in the course (slides , ppt) added by the faculty and can be downloaded by the students class CourseDocuments(models.Model): - course_id = models.ForeignKey(Course, on_delete=models.CASCADE) + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) + module_id = models.ForeignKey(Modules, on_delete=models.CASCADE, default = 1) upload_time = models.DateTimeField(auto_now=True) description = models.CharField(max_length=100) document_name = models.CharField(max_length=40) @@ -14,10 +23,20 @@ class CourseDocuments(models.Model): def __str__(self): return '{} - {}'.format(self.course_id, self.document_name) + +#the attendance files added by the faculty and can be downloaded by the students +class AttendanceFiles(models.Model): + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) + upload_time = models.DateTimeField(auto_now=True) + file_name = models.CharField(max_length=40) + file_url = models.CharField(max_length=100, null=True) + + def __str__(self): + return '{} - {}'.format(self.course_id, self.file_name) #videos added by the faculty and can be downloaded by students class CourseVideo(models.Model): - course_id = models.ForeignKey(Course, on_delete=models.CASCADE) + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) upload_time = models.DateTimeField(auto_now=True) description = models.CharField(max_length=100) video_name = models.CharField(max_length=40) @@ -28,7 +47,7 @@ def __str__(self): #For storing the questions topic wise class Topics(models.Model): - course_id = models.ForeignKey(Course, on_delete=models.CASCADE) + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) topic_name = models.TextField(max_length=200) def __str__(self): @@ -37,7 +56,7 @@ def __str__(self): #details of a question bank of which course it is class QuestionBank(models.Model): instructor_id = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) - course_id = models.ForeignKey(Course, on_delete=models.CASCADE) + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) name = models.CharField(max_length=100) #name of question bank def __str__(self): @@ -65,7 +84,7 @@ class Question(models.Model): #details of quiz are stored class Quiz(models.Model): - course_id = models.ForeignKey(Course, on_delete=models.CASCADE) + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) quiz_name = models.CharField(max_length=20) end_time = models.DateTimeField() start_time = models.DateTimeField() @@ -95,7 +114,7 @@ def __str__(self): #the details of practice quiz (objective assignment)---- under development class Practice(models.Model): - course_id = models.ForeignKey(Course, on_delete=models.CASCADE) + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) prac_quiz_name = models.CharField(max_length=20) negative_marks = models.FloatField(default=0) number_of_question = models.IntegerField(default=0) @@ -140,7 +159,7 @@ def __str__(self): #details of the assignment uploaded by the faculty class Assignment(models.Model): - course_id = models.ForeignKey(Course, on_delete=models.CASCADE) + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) upload_time = models.DateTimeField(auto_now=True) submit_date = models.DateTimeField() assignment_name = models.CharField(max_length=100) @@ -180,7 +199,7 @@ def __str__(self): #to store the comment of student and lecturer class Forum(models.Model): - course_id = models.ForeignKey(Course, on_delete=models.CASCADE) + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) commenter_id = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) comment_time = models.DateTimeField(auto_now=True) comment = models.TextField(max_length=2000) @@ -202,4 +221,67 @@ class ForumReply(models.Model): def __str__(self): return '{} - {} - {}'.format(self.pk, self.forum_ques, self.forum_reply) + +class GradingScheme(models.Model): + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) + # quiz = models.DecimalField(max_digits=10, decimal_places=2,default=0) + # assignment = models.DecimalField(max_digits=10, decimal_places=2,default=0) + # midsem = models.DecimalField(max_digits=10, decimal_places=2,default=0) + # endsem = models.DecimalField(max_digits=10, decimal_places=2,default=0) + # projects = models.DecimalField(max_digits=10, decimal_places=2,default=0) + type_of_evaluation = models.TextField(max_length=255, default=None) + weightage = models.DecimalField(max_digits=10, decimal_places=2,default=0) + + def __str__(self): + return '{} - {}'.format( + self.pk, self.course_id) + +class GradingScheme_grades(models.Model): + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) + O_Lower = models.DecimalField(max_digits=10, decimal_places=2, default=0) + O_Upper = models.DecimalField(max_digits=10, decimal_places=2, default=0) + A_plus_Lower = models.DecimalField(max_digits=10, decimal_places=2, default=0) + A_plus_Upper = models.DecimalField(max_digits=10, decimal_places=2, default=0) + A_Lower = models.DecimalField(max_digits=10, decimal_places=2, default=0) + A_Upper = models.DecimalField(max_digits=10, decimal_places=2, default=0) + B_plus_Lower = models.DecimalField(max_digits=10, decimal_places=2, default=0) + B_plus_Upper = models.DecimalField(max_digits=10, decimal_places=2, default=0) + B_Lower = models.DecimalField(max_digits=10, decimal_places=2, default=0) + B_Upper = models.DecimalField(max_digits=10, decimal_places=2, default=0) + C_plus_Lower = models.DecimalField(max_digits=10, decimal_places=2, default=0) + C_plus_Upper = models.DecimalField(max_digits=10, decimal_places=2, default=0) + C_Lower = models.DecimalField(max_digits=10, decimal_places=2, default=0) + C_Upper = models.DecimalField(max_digits=10, decimal_places=2, default=0) + D_plus_Lower = models.DecimalField(max_digits=10, decimal_places=2, default=0) + D_plus_Upper = models.DecimalField(max_digits=10, decimal_places=2, default=0) + D_Lower = models.DecimalField(max_digits=10, decimal_places=2, default=0) + D_Upper = models.DecimalField(max_digits=10, decimal_places=2, default=0) + F_Lower = models.DecimalField(max_digits=10, decimal_places=2, default=0) + F_Upper = models.DecimalField(max_digits=10, decimal_places=2, default=0) + + def __str__(self): + return '{} - {}'.format(self.pk, self.course_id) +class Student_grades(models.Model): + course_id = models.ForeignKey(Courses, on_delete=models.CASCADE) + semester = models.IntegerField(default=1) + year = models.IntegerField(default=2016) + roll_no = models.TextField(max_length=2000) + total_marks = models.DecimalField(max_digits=10, decimal_places=2, default=0) + grade = models.TextField(max_length=2000) + batch = models.IntegerField(default=2021) + + def __str__(self): + return '{} - {}'.format(self.pk, self.course_id) + +class Attendance(models.Model): + student_id = models.ForeignKey(Student,on_delete=models.CASCADE) +# course_id = models.ForeignKey(Course) +# attend = models.CharField(max_length=6, choices=Constants.ATTEND_CHOICES) + instructor_id = models.ForeignKey(CourseInstructor, on_delete=models.CASCADE) +# curriculum_id = models.ForeignKey(Curriculum, on_delete=models.CASCADE) + date = models.DateField() + present = models.BooleanField(default=False) + + def __str__(self): + return self.course_id \ No newline at end of file diff --git a/FusionIIIT/applications/online_cms/urls.py b/FusionIIIT/applications/online_cms/urls.py index c24c69cc2..f5d3996be 100644 --- a/FusionIIIT/applications/online_cms/urls.py +++ b/FusionIIIT/applications/online_cms/urls.py @@ -1,72 +1,86 @@ +from django.conf import settings +from django.conf.urls.static import static from django.conf.urls import url - from . import views -app_name = 'online_cms' +app_name = 'online_cms' urlpatterns = [ - + url(r'^$', views.viewcourses, name='viewcourses'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/$', views.course, name='course'), - # url(r'^(?P[A-z]+[0-9]+[A-z]?)/edit_marks$', views.edit_marks, name='edit_marks'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/get_exam_data$', views.get_exam_data, name='get_exam_data'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/forum$', views.forum, + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/$', views.course, name='course'), + # url(r'^(?P[A-Z0-9]+)/edit_marks$', views.edit_marks, name='edit_marks'), + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/get_exam_data$', views.get_exam_data, name='get_exam_data'), + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/forum$', views.forum, name='forum'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/ajax_reply$', views.ajax_reply, + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/ajax_reply$', views.ajax_reply, name='ajax_reply'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/ajax_new$', views.ajax_new, + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/ajax_new$', views.ajax_new, name='ajax_new'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/ajax_remove$', views.ajax_remove, + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/ajax_remove$', views.ajax_remove, name='ajax_remove'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/upload_assignment$', views.upload_assignment, + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/upload_assignment$', views.upload_assignment, name='upload_assignment'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/add_documents$', views.add_document, + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/add_modules$', views.add_modules, + name='add_modules'), + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/add_documents$', views.add_document, name='add_document'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/add_assignment$', + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/add_assignment$', views.add_assignment, name='add_assignment'), - # url(r'^(?P[A-z]+[0-9]+[A-z]?)/add_video$', views.add_videos, + # url(r'^(?P[A-Z0-9]+)/add_video$', views.add_videos, # name='add_videos'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/delete/$', views.delete, + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/delete/$', views.delete, name='delete'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/ajax_assess$', views.ajax_assess, + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/ajax_assess$', views.ajax_assess, name='ajax_assess'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/ajax_feedback$', views.ajax_feedback, + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/ajax_feedback$', views.ajax_feedback, name='ajax_feedback'), url(r'^quiz/(?P[0-9]+)/$', views.quiz, name='quiz'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/create_quiz/$', views.create_quiz, name='create_quiz'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/edit_quiz/(?P[0-9]+)/$', + url(r'^(?P[A-Z0-9]+)/create_quiz/$', views.create_quiz, name='create_quiz'), + url(r'^(?P[A-Z0-9]+)/edit_quiz/(?P[0-9]+)/$', views.edit_quiz, name='edit_quiz'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/edit_quiz/(?P[0-9]+)/(?P[0-9]+)$', + url(r'^(?P[A-Z0-9]+)/edit_quiz/(?P[0-9]+)/(?P[0-9]+)$', views.edit_quiz_topic, name='edit_quiz_topic'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/(?P[0-9]+)/add_question_topic$', + url(r'^(?P[A-Z0-9]+)/(?P[0-9]+)/add_question_topic$', views.add_question_topicwise, name='add_question_topicwise'), url(r'^(?P[0-9]+?)/(?P[0-9]+)/add_questions_to_quiz$', views.add_questions_to_quiz, name='add_questions_to_quiz'), url( - r'^(?P[A-z]+[0-9]+[A-z]?)/(?P[0-9]+)/(?P[0-9]+)/remove_quiz_question$', + r'^(?P[A-Z0-9]+)/(?P[0-9]+)/(?P[0-9]+)/remove_quiz_question$', views.remove_quiz_question, name='remove_quiz_question'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/preview_quiz/(?P[0-9]+)/$', views.preview_quiz, + url(r'^(?P[A-Z0-9]+)/preview_quiz/(?P[0-9]+)/$', views.preview_quiz, name='preview_quiz'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/edit_quiz_details/(?P[0-9]+)/$', + url(r'^(?P[A-Z0-9]+)/edit_quiz_details/(?P[0-9]+)/$', views.edit_quiz_details, name='edit_quiz_details'), url(r'^(?P[0-9]+)/ajax$', views.ajax_q, name='ajax_q'), url(r'^(?P[0-9]+)/submit$', views.submit, name='submit'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/remove_quiz$', views.remove_quiz, + url(r'^(?P[A-Z0-9]+)/remove_quiz$', views.remove_quiz, name='remove_quiz'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/remove_bank$', views.remove_bank, + url(r'^(?P[A-Z0-9]+)/remove_bank$', views.remove_bank, name='remove_bank'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/remove_topic$', views.remove_topic, + url(r'^(?P[A-Z0-9]+)/remove_topic$', views.remove_topic, name='remove_topic'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/create_bank$', views.create_bank, + url(r'^(?P[A-Z0-9]+)/create_bank$', views.create_bank, name='create_bank'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/create_topic$', views.create_topic, + url(r'^(?P[A-Z0-9]+)/create_topic$', views.create_topic, name='create_topic'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/(?P[0-9]+)/(?P[0-9]+)$', + url(r'^(?P[A-Z0-9]+)/(?P[0-9]+)/(?P[0-9]+)$', views.edit_qb_topics, name='edit_qb_topics'), url(r'^(?P[0-9]+?)/(?P[0-9]+)/(?P[0-9]+)/add_question$', views.add_question, name='add_question'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/(?P[0-9]+)/(?P[0-9]+)/remove_question$', + url(r'^(?P[A-Z0-9]+)/(?P[0-9]+)/(?P[0-9]+)/remove_question$', views.remove_question, name='remove_question'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/edit_bank/(?P[0-9]+)$', + url(r'^(?P[A-Z0-9]+)/edit_bank/(?P[0-9]+)$', views.edit_bank, name='edit_bank'), - url(r'^(?P[A-z]+[0-9]+[A-z]?)/attendance$', views.submit_attendance, - name='submit_attendance'),] + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/attendance$', views.submit_attendance, + name='submit_attendance'), + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/add_attendance$', views.add_attendance, + name='add_attendance'), + url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/create_grading_scheme$', + views.create_grading_scheme, name='Create_grading_scheme'), + url(r'^admin/add_academic_calendar', views.add_academic_calendar, name='Add Calendar'), + url(r'^admin/update_calendar', views.update_calendar, name='Add Calendar'), + url(r'^admin/add_timetable', views.add_timetable, name="add_timetable"), + url(r'^admin/delete_timetable', views.delete_timetable, name='delete_timetable'), + url(r'^(?P[A-z0-9]+)/(?P[\d.]+)/submit_marks$',views.submit_marks, name='submit_marks'), + ] + diff --git a/FusionIIIT/applications/online_cms/views.py b/FusionIIIT/applications/online_cms/views.py index cc74626f3..415b957da 100644 --- a/FusionIIIT/applications/online_cms/views.py +++ b/FusionIIIT/applications/online_cms/views.py @@ -11,13 +11,15 @@ from django.conf import settings from django.contrib.auth.decorators import login_required from django.core.files.storage import FileSystemStorage -from django.http import HttpResponse, HttpResponseBadRequest +from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseRedirect from django.shortcuts import redirect, render from django.utils import timezone - -from applications.academic_information.models import (Course, Curriculum_Instructor,Curriculum, - Student,Student_attendance) -from applications.academic_procedures.models import Register +from django.core.serializers import serialize +from decimal import Decimal +from applications.academic_information.models import (Student,Student_attendance,Calendar, Timetable) +from applications.programme_curriculum.models import Course as Courses +from applications.programme_curriculum.models import CourseInstructor +from applications.academic_procedures.models import course_registration from applications.globals.models import ExtraInfo from applications.globals.models import * @@ -25,7 +27,7 @@ # from .helpers import create_thumbnail, semester from .models import * from .helpers import create_thumbnail, semester - +from notification.views import course_management_notif @login_required def viewcourses(request): @@ -37,47 +39,59 @@ def viewcourses(request): extrainfo = ExtraInfo.objects.select_related().get(user=user) #get the type of user if extrainfo.user_type == 'student': #if student is using student = Student.objects.select_related('id').get(id=extrainfo) - roll = student.id.id[:4] #get the roll no. of the student - register = Register.objects.select_related().filter(student_id=student, semester=semester(roll)) #info of registered student + roll = student.id.id[:2] #get the roll no. of the student + register = course_registration.objects.select_related().filter(student_id=student) + #info of registered student courses = collections.OrderedDict() #courses in which student is registerd for reg in register: #info of the courses - instructor = Curriculum_Instructor.objects.select_related().get(course_id=reg.course_id) + instructor = CourseInstructor.objects.select_related().get(course_id = reg.course_id) courses[reg] = instructor + return render(request, 'coursemanagement/coursemanagement1.html', {'courses': courses, 'extrainfo': extrainfo}) - else: #if the user is lecturer - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) #get info of the instructor + elif extrainfo.user_type == 'faculty': #if the user is lecturer + instructor = CourseInstructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) #get info of the instructor curriculum_list = [] for x in instructor: - c = Curriculum.objects.select_related().get(curriculum_id = x.curriculum_id.curriculum_id) + c = Courses.objects.select_related().get(pk = x.course_id) curriculum_list.append(c) - return render(request, 'coursemanagement/coursemanagement1.html', {'instructor': instructor, 'extrainfo': extrainfo, 'curriculum_list': curriculum_list}) + + elif request.session.get('currentDesignationSelected') == 'acadadmin': + acadTtForm = AcademicTimetableForm() + calendar = Calendar.objects.all() + timetable = Timetable.objects.all() + return render(request, 'coursemanagement/academicinfo.html', + {'acadTtForm': acadTtForm, + 'academic_calendar':calendar, + 'timetable':timetable}) + else: + return HttpResponseRedirect('/dashboard/') @login_required -def course(request, course_code): +def course(request, course_code, version): ''' desc: Home page for each courses for Student/Faculty ''' user = request.user extrainfo = ExtraInfo.objects.select_related().get(user=user) + notifs = request.user.notifications.all() if extrainfo.user_type == 'student': #if the user is student .. funtionality used by him/her + if request.session.get('currentDesignationSelected') != 'student': + return HttpResponseRedirect('/dashboard/') student = Student.objects.select_related('id').get(id=extrainfo) - roll = student.id.id[:4] - #info about courses he is registered in - curriculum = Curriculum.objects.select_related('course_id').get(course_code=course_code) - course = curriculum.course_id + course = Courses.objects.select_related().get(code=course_code, version = version) #instructor of the course - instructor = Curriculum_Instructor.objects.select_related().get(curriculum_id=curriculum) + instructor = CourseInstructor.objects.select_related().get(course_id = course, batch_id = student.batch_id) #course material uploaded by the instructor # videos = CourseVideo.objects.filter(course_id=course) videos = [] @@ -119,52 +133,72 @@ def course(request, course_code): videos.append(video_data) else: - channel_url = "https://www.googleapis.com/youtube/v3/channels" - playlist_url = "https://www.googleapis.com/youtube/v3/playlistItems" - videos_url = "https://www.googleapis.com/youtube/v3/videos" - - videos_list = [] - channel_params = { - 'part': 'contentDetails', - 'id': 'channel_id', - 'key': settings.YOUTUBE_DATA_API_KEY, - } - r = requests.get(channel_url, params=channel_params) - results = r.json()['items'][0]['contentDetails']['relatedPlaylists']['uploads'] - - playlist_params = { - 'key': settings.YOUTUBE_DATA_API_KEY, - 'part': 'snippet', - 'playlistId': results, - 'maxResults': 5, - } - p = requests.get(playlist_url, params=playlist_params) - results1 = p.json()['items'] - - for result in results1: - # print(results) - videos_list.append(result['snippet']['resourceId']['videoId']) + x = 0 + # channel_url = "https://www.googleapis.com/youtube/v3/channels" + # playlist_url = "https://www.googleapis.com/youtube/v3/playlistItems" + # videos_url = "https://www.googleapis.com/youtube/v3/videos" + + # videos_list = [] + # channel_params = { + # 'part': 'contentDetails', + # 'id': 'channel_id', + # 'key': settings.YOUTUBE_DATA_API_KEY, + # } + # r = requests.get(channel_url, params=channel_params) + # results = r.json()['items'][0]['contentDetails']['relatedPlaylists']['uploads'] + + # playlist_params = { + # 'key': settings.YOUTUBE_DATA_API_KEY, + # 'part': 'snippet', + # 'playlistId': results, + # 'maxResults': 5, + # } + # p = requests.get(playlist_url, params=playlist_params) + # results1 = p.json()['items'] + + # for result in results1: + # # print(results) + # videos_list.append(result['snippet']['resourceId']['videoId']) + + # videos_params = { + # 'key': settings.YOUTUBE_DATA_API_KEY, + # 'part': 'snippet', + # 'id': ','.join(videos_list) + # } + + # v = requests.get(videos_url, params=videos_params) + # results2 = v.json()['items'] + # videos = [] + # for res in results2: + # video_data = { + # 'id': res['id'], + # 'title': res['snippet']['title'], + # } + + # videos.append(video_data) + # print(videos) - videos_params = { - 'key': settings.YOUTUBE_DATA_API_KEY, - 'part': 'snippet', - 'id': ','.join(videos_list) - } + modules = Modules.objects.select_related().filter(course_id=course) + slides = CourseDocuments.objects.select_related().filter(course_id=course) - v = requests.get(videos_url, params=videos_params) - results2 = v.json()['items'] - videos = [] - for res in results2: - video_data = { - 'id': res['id'], - 'title': res['snippet']['title'], - } + modules_with_slides = collections.OrderedDict() + for m in modules: + sl = [] + for slide in slides: + if slide.module_id.id == m.id: + sl.append(slide) + if len(sl) == 0: + modules_with_slides[m] = 0 + else: + modules_with_slides[m] = sl - videos.append(video_data) - # print(videos) - slides = CourseDocuments.objects.select_related().filter(course_id=course) quiz = Quiz.objects.select_related().filter(course_id=course) assignment = Assignment.objects.select_related().filter(course_id=course) + submitable_assignments = [] + for assi in assignment: + if assi.submit_date.date() >= datetime.date.today(): + submitable_assignments.append(assi) + student_assignment = [] for assi in assignment: sa = StudentAssignment.objects.select_related().filter(assignment_id=assi, student_id=student) @@ -174,18 +208,42 @@ def course(request, course_code): marks_pk to store the quizs taken by student quizs=>quizs that are not over ''' - marks = [] - quizs = [] - marks_pk = [] - #quizzes details - for q in quiz: - qs = QuizResult.objects.select_related().filter(quiz_id=q, student_id=student) - qs_pk = qs.values_list('quiz_id', flat=True) - if q.end_time > timezone.now(): - quizs.append(q) - if qs: - marks.append(qs[0]) - marks_pk.append(qs_pk[0]) + # marks = [] + # quizs = [] + # marks_pk = [] + # #quizzes details + # for q in quiz: + # qs = QuizResult.objects.select_related().filter(quiz_id=q, student_id=student) + # qs_pk = qs.values_list('quiz_id', flat=True) + # if q.end_time > timezone.now(): + # quizs.append(q) + # if qs: + # marks.append(qs[0]) + # marks_pk.append(qs_pk[0]) + + present_attendance = {} + total_attendance=None + a = Attendance.objects.select_related().filter(student_id=student , instructor_id = instructor) + total_attendance = len(a) + count = 0 + for row in a: + if(row.present): + count+=1 + present_attendance[row.date] = 1 + else: + present_attendance[row.date] = 0 + attendance_percent = 0 + if(total_attendance): + attendance_percent = count/total_attendance*100 + attendance_percent = round(attendance_percent,2) + + attendance_file = {} + try: + attendance_file = AttendanceFiles.objects.select_related().filter(course_id=course) + except AttendanceFiles.DoesNotExist: + attendance_file = {} + + lec = 0 comments = Forum.objects.select_related().filter(course_id=course).order_by('comment_time') answers = collections.OrderedDict() @@ -196,28 +254,32 @@ def course(request, course_code): answers[comment] = fr1 return render(request, 'coursemanagement/viewcourse.html', {'course': course, - 'quizs': marks, - 'quizs_pk': marks_pk, - 'fut_quiz': quizs, - 'videos': videos, + 'modules': modules_with_slides, 'instructor': instructor, 'slides': slides, 'extrainfo': extrainfo, 'answers': answers, 'assignment': assignment, + 'submitable_assignment':submitable_assignments, 'student_assignment': student_assignment, + 'total_attendance' : total_attendance, + 'present_attendance':present_attendance, + 'attendance_percent': attendance_percent, 'Lecturer': lec, - 'curriculum': curriculum}) + 'attendance_file':attendance_file, + 'notifications': notifs}) else: - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + if request.session.get('currentDesignationSelected') != "faculty" and request.session.get('currentDesignationSelected') != "Associate Professor" and request.session.get('currentDesignationSelected') != "Professor" and request.session.get('currentDesignationSelected') != "Assistant Professor": + return HttpResponseRedirect('/dashboard/') + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - registered_students = Register.objects.select_related('student_id').filter(curr_id = ins.curriculum_id.curriculum_id) + if ins.course_id.code == course_code and ins.course_id.version == Decimal(version): + registered_students = course_registration.objects.select_related('student_id').filter(course_id = ins.course_id) students = {} test_marks = {} for x in registered_students: - students[x.student_id.id.id] = (x.student_id.id.user.first_name + " " + x.student_id.id.user.last_name, x.id) + students[x.student_id.id.id] = (x.student_id.id.user.first_name + " " + x.student_id.id.user.last_name) # stored_marks = StoreMarks.objects.filter(mid = x.r_id) # for x in stored_marks: # test_marks[x.id] = (x.mid.r_id,x.exam_type,x.marks) @@ -226,84 +288,103 @@ def course(request, course_code): #for x in stored_marks: # print(x) - curriculum = ins.curriculum_id - course = ins.curriculum_id.course_id + course = ins.course_id result_topics = Topics.objects.select_related().filter(course_id = course) if (len(list(result_topics))!=0): topics = result_topics else: topics = None present_attendance = {} - total_attendance=None - for x in registered_students: - a = Student_attendance.objects.select_related().filter(student_id=x.student_id , instructor_id = ins) - total_attendance = len(a) - count =0 - for row in a: - if(row.present): - count += 1 - present_attendance[x.student_id.id.id] = count + total_attendance=None + for x in registered_students: + a = Attendance.objects.select_related().filter(student_id=x.student_id , instructor_id = ins) + total_attendance = len(a) + count =0 + for row in a: + if(row.present): + count += 1 + + attendance_percent = 0 + if(total_attendance): + attendance_percent = count/total_attendance*100 + attendance_percent = round(attendance_percent,2) + present_attendance[x.student_id.id.id] = { + 'count': count, + 'attendance_percent': attendance_percent + } lec = 1 - - # videos = CourseVideo.objects.filter(course_id=course) - channel_url = "https://www.googleapis.com/youtube/v3/channels" - playlist_url = "https://www.googleapis.com/youtube/v3/playlistItems" - videos_url = "https://www.googleapis.com/youtube/v3/videos" - - videos_list = [] - channel_params = { - 'part': 'contentDetails', - # 'forUsername': 'TechGuyWeb', - 'id': 'UCdGQeihs84hyCssI2KuAPmA', - 'key': settings.YOUTUBE_DATA_API_KEY, - } - r = requests.get(channel_url, params=channel_params) - results = r.json()['items'][0]['contentDetails']['relatedPlaylists']['uploads'] - - playlist_params = { - 'key': settings.YOUTUBE_DATA_API_KEY, - 'part': 'snippet', - 'playlistId': results, - 'maxResults': 5, - } - p = requests.get(playlist_url, params=playlist_params) - results1 = p.json()['items'] - - for result in results1: - videos_list.append(result['snippet']['resourceId']['videoId']) - - videos_params = { - 'key': settings.YOUTUBE_DATA_API_KEY, - 'part': 'snippet', - 'id': ','.join(videos_list) - } - - v = requests.get(videos_url, params=videos_params) - results2 = v.json()['items'] videos = [] - for res in results2: - video_data = { - 'id': res['id'], - 'title': res['snippet']['title'], - } - - videos.append(video_data) + + # videos = CourseVideo.objects.filter(course_id=course) + # channel_url = "https://www.googleapis.com/youtube/v3/channels" + # playlist_url = "https://www.googleapis.com/youtube/v3/playlistItems" + # videos_url = "https://www.googleapis.com/youtube/v3/videos" + + # videos_list = [] + # channel_params = { + # 'part': 'contentDetails', + # # 'forUsername': 'TechGuyWeb', + # 'id': 'UCdGQeihs84hyCssI2KuAPmA', + # 'key': settings.YOUTUBE_DATA_API_KEY, + # } + # r = requests.get(channel_url, params=channel_params) + # results = r.json()['items'][0]['contentDetails']['relatedPlaylists']['uploads'] + + # playlist_params = { + # 'key': settings.YOUTUBE_DATA_API_KEY, + # 'part': 'snippet', + # 'playlistId': results, + # 'maxResults': 5, + # } + # p = requests.get(playlist_url, params=playlist_params) + # results1 = p.json()['items'] + + # for result in results1: + # videos_list.append(result['snippet']['resourceId']['videoId']) + + # videos_params = { + # 'key': settings.YOUTUBE_DATA_API_KEY, + # 'part': 'snippet', + # 'id': ','.join(videos_list) + # } + + # v = requests.get(videos_url, params=videos_params) + # results2 = v.json()['items'] + # videos = [] + # for res in results2: + # video_data = { + # 'id': res['id'], + # 'title': res['snippet']['title'], + # } + + # videos.append(video_data) + modules = Modules.objects.select_related().filter(course_id=course) slides = CourseDocuments.objects.select_related().filter(course_id=course) - quiz = Quiz.objects.select_related().filter(course_id=course) - marks = [] - quizs = [] + modules_with_slides = collections.OrderedDict() + for m in modules: + sl = [] + for slide in slides: + if slide.module_id.id == m.id: + sl.append(slide) + if len(sl) == 0: + modules_with_slides[m] = 0 + else: + modules_with_slides[m] = sl + # quiz = Quiz.objects.select_related().filter(course_id=course) + # marks = [] + # quizs = [] assignment = Assignment.objects.select_related().filter(course_id=course) student_assignment = [] for assi in assignment: sa = StudentAssignment.objects.select_related().filter(assignment_id=assi) student_assignment.append(sa) - for q in quiz: - qs = QuizResult.objects.select_related().filter(quiz_id=q) - if q.end_time > timezone.now(): - quizs.append(q) - if len(qs) != 0: - marks.append(qs) + # for q in quiz: + # qs = QuizResult.objects.select_related().filter(quiz_id=q) + # if q.end_time > timezone.now(): + # quizs.append(q) + # if len(qs) != 0: + # marks.append(qs) comments = Forum.objects.select_related().filter(course_id=course).order_by('comment_time') answers = collections.OrderedDict() for comment in comments: @@ -311,16 +392,26 @@ def course(request, course_code): fr1 = ForumReply.objects.select_related().filter(forum_ques=comment) if not fr: answers[comment] = fr1 - qb = QuestionBank.objects.select_related().filter(instructor_id=extrainfo, course_id=course) + # qb = QuestionBank.objects.select_related().filter(instructor_id=extrainfo, course_id=course) + + gradingscheme = GradingScheme.objects.select_related().filter(course_id=course) + try: + gradingscheme_grades = GradingScheme_grades.objects.select_related().get(course_id=course) + except GradingScheme_grades.DoesNotExist: + gradingscheme_grades = {} + + try: + student_grades = Student_grades.objects.select_related().filter(course_id=course) + except Student_grades.DoesNotExist: + student_grades = {} + + return render(request, 'coursemanagement/viewcourse.html', {'instructor': instructor, 'extrainfo': extrainfo, - 'curriculum': curriculum, 'students' : students, 'registered_students': registered_students, - 'fut_quiz': quizs, - 'quizs': marks, - 'videos': videos, + 'modules': modules_with_slides, 'slides': slides, 'topics':topics, 'course': course, @@ -328,16 +419,20 @@ def course(request, course_code): 'assignment': assignment, 'student_assignment': student_assignment, 'Lecturer': lec, - 'questionbank': qb, + 'notifications': notifs, 'students': students, 'total_attendance' : total_attendance, 'present_attendance':present_attendance, - 'test_marks': test_marks + 'test_marks': test_marks, + 'gradingscheme':gradingscheme, + 'gradingscheme_grades': gradingscheme_grades, + 'student_grades' : student_grades }) + #when student uploads the assignment's solution @login_required -def upload_assignment(request, course_code): +def upload_assignment(request, course_code, version): extrainfo = ExtraInfo.objects.select_related().get(user=request.user) if extrainfo.user_type == "student": student = Student.objects.select_related('id').get(id=extrainfo) @@ -349,9 +444,9 @@ def upload_assignment(request, course_code): assign = Assignment.objects.get(pk=assi_name) filename, file_extenstion = os.path.splitext(request.FILES.get('img').name) except: - return HttpResponse("Please fill each and every field correctly!") + return HttpResponse("Please fill each and every field correctly!", status=422) filename = name - full_path = settings.MEDIA_ROOT + "/online_cms/" + course_code + "/assi/" #storing the media files + full_path = settings.MEDIA_ROOT + "/online_cms/" + course_code + "/" + version + "/assi/" #storing the media files full_path = full_path + assign.assignment_name + "/" + student.id.id + "/" url = settings.MEDIA_URL + filename if not os.path.isdir(full_path): @@ -359,7 +454,8 @@ def upload_assignment(request, course_code): subprocess.call(cmd, shell=True) fs = FileSystemStorage(full_path, url) fs.save(name + file_extenstion, doc) #saving the media files - uploaded_file_url = full_path+ "/" + name + file_extenstion + # uploaded_file_url = full_path+ "/" + name + file_extenstion + uploaded_file_url = "/media/online_cms/" + course_code + "/" + version + "/assi/" + assign.assignment_name + "/" + student.id.id + "/" + name + file_extenstion # to save the solution of assignment the database sa = StudentAssignment( student_id=student, @@ -372,71 +468,141 @@ def upload_assignment(request, course_code): else: return HttpResponse("not found") +# when faculty creates modules +@login_required +def add_modules(request, course_code, version): + extrainfo = ExtraInfo.objects.select_related().get(user=request.user) + if extrainfo.user_type == "faculty": #user should be faculty only + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) #get the course information + + for ins in instructor: + if ins.course_id.code == course_code and ins.course_id.version == Decimal(version): + course = ins.course_id + + try: + module_name = request.POST.get('module_name') + except: + return HttpResponse("Please fill each and every field correctly!",status=422) + + Modules.objects.create( + course_id=course, + module_name=module_name + ) + return HttpResponse("Module creation successful") + else: + return HttpResponse("Not found", status=400) + # when faculty uploads the slides, ppt @login_required -def add_document(request, course_code): +def add_document(request, course_code, version): extrainfo = ExtraInfo.objects.select_related().get(user=request.user) if extrainfo.user_type == "faculty": #user should be faculty only - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) #get the course information + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) #get the course information for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code and ins.course_id.version == Decimal(version): + course = ins.course_id try: description = request.POST.get('description') doc = request.FILES.get('img') name = request.POST.get('name') + module_id = request.POST.get('module_id') filename, file_extenstion = os.path.splitext(request.FILES.get('img').name) except: - return HttpResponse("Please fill each and every field correctly!") + return HttpResponse("Please fill each and every field correctly!",status=422) #for storing the media files properly filename = name - full_path = settings.MEDIA_ROOT + "/online_cms/" + course_code + "/doc/" + full_path = settings.MEDIA_ROOT + "/online_cms/" + course_code + "/" + version + "/doc/" url = settings.MEDIA_URL + filename + file_extenstion if not os.path.isdir(full_path): cmd = "mkdir " + full_path subprocess.call(cmd, shell=True) fs = FileSystemStorage(full_path, url) fs.save(filename + file_extenstion, doc) - uploaded_file_url = full_path + filename + file_extenstion + # uploaded_file_url = full_path + filename + file_extenstion + uploaded_file_url = "/media/online_cms/" + course_code + "/" + version + "/doc/" + filename + file_extenstion #save the info/details in the database CourseDocuments.objects.create( course_id=course, upload_time=datetime.datetime.now(), description=description, document_url=uploaded_file_url, - document_name=name+file_extenstion + document_name=name+file_extenstion, + module_id_id=module_id ) return HttpResponse("Upload successful.") else: - return HttpResponse("not found") + return HttpResponse("Not found") + +# if faculty uploads the attendance file +@login_required +def add_attendance(request, course_code, version): + extrainfo = ExtraInfo.objects.select_related().get(user=request.user) + if extrainfo.user_type == "faculty": #user should be faculty only + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) #get the course information + + for ins in instructor: + if ins.course_id.code == course_code and ins.course_id.version == Decimal(version): + course = ins.course_id + + try: + doc = request.FILES.get('img') + name = request.POST.get('name') + filename, file_extenstion = os.path.splitext(request.FILES.get('img').name) + except: + return HttpResponse("Please fill each and every field correctly!",status=422) + #for storing the media files properly + filename = name + full_path = settings.MEDIA_ROOT + "/online_cms/" + course_code + "/" + version + "/attendance/" + url = settings.MEDIA_URL + filename + file_extenstion + if not os.path.isdir(full_path): + cmd = "mkdir " + full_path + subprocess.call(cmd, shell=True) + fs = FileSystemStorage(full_path, url) + fs.save(filename + file_extenstion, doc) + # uploaded_file_url = full_path + filename + file_extenstion + uploaded_file_url = "/media/online_cms/" + course_code + "/" + version + "/attendance/" + filename + file_extenstion + #save the info/details in the database + AttendanceFiles.objects.create( + course_id=course, + upload_time=datetime.datetime.now(), + file_url=uploaded_file_url, + file_name=name+file_extenstion + ) + return HttpResponse("Upload successful.") + else: + return HttpResponse("Not found") #it is to delete things(assignment, slides, videos, ) from the dustin icon or delete buttons @login_required -def delete(request, course_code): +def delete(request, course_code, version): data_type = request.POST.get('type') user = request.user extrainfo = ExtraInfo.objects.select_related().get(user=user) #get the course and user information first if extrainfo.user_type == "faculty": - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) #get the course information + for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code and ins.course_id.version == Decimal(version): + course = ins.course_id if extrainfo.user_type == 'student': - curriculum_details = Curriculum.objects.select_related('course_id').filter(course_code=course_code) + curriculum_details = Courses.objects.select_related().filter(code=course_code, version=version) course = curriculum_details - course1 = curriculum_details[0].course_id - curriculum1 = course[0] + pk = request.POST.get('pk') + path = "" #to delete videos if data_type == 'video': video = CourseVideo.objects.get(pk=pk, course_id=course) path = video.video_url video.delete() + elif data_type == 'module': + module = Modules.objects.select_related().get(pk=pk, course_id=course) + module.delete() #to delete slides/documents elif data_type == 'slide': slide = CourseDocuments.objects.select_related().get(pk=pk, course_id=course) @@ -452,8 +618,10 @@ def delete(request, course_code): lec_assi = Assignment.objects.select_related().get(pk=pk) path = lec_assi.assignment_url lec_assi.delete() - cmd = "rm "+path - subprocess.call(cmd, shell=True) + if path: + cmd = "rm "+path + subprocess.call(cmd, shell=True) + data = { 'msg': 'Data Deleted successfully'} return HttpResponse(json.dumps(data), content_type='application/json') @@ -463,10 +631,11 @@ def add_videos(request, course_code): extrainfo = ExtraInfo.objects.select_related().get(user=request.user) #only faculty can add the videos if extrainfo.user_type == "faculty": - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) + for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code: + course = ins.course_id try: description = request.POST.get('description') #the media files required vid = request.FILES.get('img') @@ -496,24 +665,24 @@ def add_videos(request, course_code): create_thumbnail(course_code,course, video, name, file_extenstion, 'Small', 1, '170:127') return HttpResponse("Upload successful.") else: - return HttpResponse("not found") + return HttpResponse("Not found") @login_required -def forum(request, course_code): +def forum(request, course_code, version): # take care of sem extrainfo = ExtraInfo.objects.select_related().get(user=request.user) if extrainfo.user_type == "student": student = Student.objects.select_related('id').get(id=extrainfo) roll = student.id.id[:4] - course = Course.objects.select_related().get(course_id=course_code, sem=semester(roll)) + course = Courses.objects.select_related().get(course=course_code, version=version) else: - instructor = Curriculum_Instructor.objects.select_related().filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.course_id.course_id == course_code: - course = ins.course_id + if ins.course_id.code == course_code and ins.course_id.version == Decimal(version): + course = ins.course_id.pk comments = Forum.objects.select_related().filter(course_id=course).order_by('comment_time') - instructor = Curriculum_Instructor.objects.get(course_id=course) + instructor = CourseInstructor.objects.get(course_id=course) if instructor.instructor_id.user.pk == request.user.pk: lec = 1 else: @@ -529,22 +698,21 @@ def forum(request, course_code): @login_required -def ajax_reply(request, course_code): +def ajax_reply(request, course_code, version): extrainfo = ExtraInfo.objects.select_related().get(user=request.user) if extrainfo.user_type == "student": student = Student.objects.select_related('id').get(id=extrainfo) roll = student.id.id[:4] - curriculum_details = Curriculum.objects.select_related('course_id').filter(course_code=course_code) #curriculum id #print(curriculum_details[0].course_id) #print(Curriculum.objects.values_list('curriculum_id')) - course = curriculum_details[0].course_id + course = Courses.objects.select_related().filter(code=course_code, version=version) # course = Course.objects.get(course_id=course_code, sem=semester(roll)) else: - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code and ins.course_id.version == Decimal(version): + course = ins.course_id.pk ex = ExtraInfo.objects.select_related().get(user=request.user) f = Forum( course_id=course, @@ -565,34 +733,64 @@ def ajax_reply(request, course_code): @login_required -def ajax_new(request, course_code): - extrainfo = ExtraInfo.objects.select_related().get(user=request.user) - if extrainfo.user_type == "student": - student = Student.objects.select_related('id').get(id=extrainfo) - roll = student.id.id[:4] - #course = Course.objects.get(course_id=course_code, sem=semester(roll)) - curriculum_details = Curriculum.objects.select_related('course_id').filter(course_code=course_code) #curriculum id - #print(curriculum_details[0].course_id) - #print(Curriculum.objects.values_list('curriculum_id')) - course = curriculum_details[0].course_id +def ajax_new(request, course_code, version): + # extrainfo = ExtraInfo.objects.select_related().get(user=request.user) + # if extrainfo.user_type == "student": + # student = Student.objects.select_related('id').get(id=extrainfo) + # roll = student.id.id[:4] + # #course = Course.objects.get(course_id=course_code, sem=semester(roll)) + # curriculum_details = Curriculum.objects.select_related('course_id').filter(course_code=course_code) #curriculum id + # #print(curriculum_details[0].course_id) + # #print(Curriculum.objects.values_list('curriculum_id')) + # course = curriculum_details[0].course_id + # else: + + # instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + # for ins in instructor: + # if ins.curriculum_id.course_code == course_code: + # course = ins.curriculum_id.course_id + # ex = ExtraInfo.objects.select_related().get(user=request.user) + # f = Forum( + # course_id=course, + # commenter_id=ex, + # comment=request.POST.get('question') + # ) + # f.save() + # name = request.user.first_name + " " + request.user.last_name + # time = f.comment_time.strftime('%b. %d, %Y, %I:%M %p') + + # data = {'pk': f.pk, 'question': f.comment, 'replier': f.commenter_id.user.username, + # 'time': time, 'name': name} + ex = ExtraInfo.objects.select_related().get(user=request.user) + if ex.user_type == "student": + print() else: - - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + HttpResponse('Announcement in Progress') + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=ex) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id - ex = ExtraInfo.objects.select_related().get(user=request.user) - f = Forum( - course_id=course, - commenter_id=ex, - comment=request.POST.get('question') - ) - f.save() - name = request.user.first_name + " " + request.user.last_name - time = f.comment_time.strftime('%b. %d, %Y, %I:%M %p') + if ins.course_id.code == course_code and ins.course_id.version == Decimal(version): + course = ins.course_id + registered_students = course_registration.objects.filter(course_id = ins.course_id) + + f = Forum( + course_id=course, + commenter_id=ex, + comment=request.POST.get('question') + ) + f.save() + name = request.user.first_name + " " + request.user.last_name + time = f.comment_time.strftime('%b. %d, %Y, %I:%M %p') + data = {'pk': f.pk, 'question': f.comment, 'replier': f.commenter_id.user.username, + 'time': time, 'name': name} + # course_json = serialize('json', [course]) + + student = [] + for reg_student in registered_students: + student.append(Student.objects.get(id = str(reg_student.student_id)).id.user) + # student = Student.objects.get(id = str(reg_student.student_id)) + + course_management_notif(request.user, student, request.POST.get('question'), course.pk, str(course.name),course_code, "announcement") - data = {'pk': f.pk, 'question': f.comment, 'replier': f.commenter_id.user.username, - 'time': time, 'name': name} return HttpResponse(json.dumps(data), content_type='application/json') @@ -621,28 +819,30 @@ def ajax_remove(request, course_code): @login_required -def add_assignment(request, course_code): #from faculty side +def add_assignment(request, course_code, version): #from faculty side extrainfo = ExtraInfo.objects.select_related().get(user=request.user) if extrainfo.user_type == "faculty": - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code and ins.course_id.version == Decimal(version): + course = ins.course_id + registered_students = course_registration.objects.filter(course_id = ins.course_id) try: assi = request.FILES.get('img') name = request.POST.get('name') filename, file_extenstion = os.path.splitext(request.FILES.get('img').name) except: - return HttpResponse("Please Enter The Form Properly") + return HttpResponse("Please Enter The Form Properly",status=422) filename = name - full_path = settings.MEDIA_ROOT + "/online_cms/" + course_code + "/assi/" + name + "/" + full_path = settings.MEDIA_ROOT + "/online_cms/" + course_code + "/" + version + "/assi/" + name + "/" url = settings.MEDIA_URL + filename if not os.path.isdir(full_path): cmd = "mkdir " + full_path subprocess.call(cmd, shell=True) fs = FileSystemStorage(full_path, url) fs.save(filename+file_extenstion, assi) - uploaded_file_url = full_path + filename + file_extenstion + uploaded_file_url = "/media/online_cms/"+ course_code + "/" + version + "/assi/" + name + "/" + filename + file_extenstion + # uploaded_file_url = full_path + filename + file_extenstion assign = Assignment( course_id=course, submit_date=request.POST.get('myDate'), @@ -650,7 +850,12 @@ def add_assignment(request, course_code): #from faculty side assignment_name=name ) assign.save() - return HttpResponse("Upload successful.") + student = [] + for reg_student in registered_students: + student.append(Student.objects.get(id = str(reg_student.student_id)).id.user) + print(student) + course_management_notif(request.user, student, "New Assignment Created!", course.pk, str(course.name),course_code,0) + return HttpResponse("Assignment created successfully.") else: return HttpResponse("not found") @@ -661,10 +866,10 @@ def edit_bank(request, course_code, qb_code): extrainfo = ExtraInfo.objects.select_related().get(user=user) lec = 1 if extrainfo.user_type == "faculty": - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code: + course = ins.course_id qb = QuestionBank.objects.select_related().filter(id=qb_code) topics = Topics.objects.select_related().filter(course_id=course) Topic = {} @@ -692,10 +897,10 @@ def create_bank(request, course_code): user = request.user extrainfo = ExtraInfo.objects.select_related().get(user=user) if extrainfo.user_type == "faculty": - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code: + course = ins.course_id qb = QuestionBank.objects.create(instructor_id=extrainfo, course_id=course, name=request.POST.get('qbname')) return redirect('/ocms/' + course_code + '/edit_bank/'+str(qb.id)) @@ -705,10 +910,10 @@ def create_topic(request, course_code): user = request.user extrainfo = ExtraInfo.objects.select_related().get(user=user) if extrainfo.user_type == "faculty": - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code: + course = ins.course_id topic = Topics.objects.create(course_id=course, topic_name=request.POST.get('topic_name')) return redirect('/ocms/' + course_code) @@ -719,10 +924,10 @@ def remove_bank(request, course_code): user = request.user extrainfo = ExtraInfo.objects.select_related().get(user=user) if extrainfo.user_type == "faculty": - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code: + course = ins.course_id qb = QuestionBank.objects.select_related().get(id=request.POST.get('pk')) qb.delete() qb = QuestionBank.objects.select_related().filter(instructor_id=extrainfo, course_id=course) @@ -734,10 +939,10 @@ def remove_topic(request, course_code): user = request.user extrainfo = ExtraInfo.objects.select_related().get(user=user) if extrainfo.user_type == "faculty": - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code: + course = ins.course_id topic = Topics.objects.select_related().get(id=request.POST.get('pk')) topic.delete() n_topics = Topics.objects.select_related().filter(course_id=course) @@ -748,7 +953,7 @@ def remove_topic(request, course_code): @login_required def add_question(request, course_id, qb_code, topic_id): user = request.user - course = Course.objects.select_related().get(pk=course_id) + course = Courses.objects.select_related().get(pk=course_id) curriculum = Curriculum.objects.select_related().get(course_id=course) course_code = curriculum.course_code extrainfo = ExtraInfo.objects.select_related().get(user=user) @@ -806,9 +1011,9 @@ def edit_qb_topics(request, course_code, qb_code, topic_id): extrainfo = ExtraInfo.objects.select_related().get(user=user) lec = 1 if extrainfo.user_type == "faculty": - instructor = Curriculum_Instructor.objects.select_related().filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.course_id.course_id == course_code: + if ins.course_id.code == course_code: course = ins.course_id qb = QuestionBank.objects.select_related().filter(pk=qb_code) topic = Topics.objects.select_related().get(id=topic_id) @@ -907,11 +1112,10 @@ def create_quiz(request, course_code): extrainfo = ExtraInfo.objects.select_related().get(user=request.user) if extrainfo.user_type == 'faculty': - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - curriculum = ins.curriculum_id - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code: + course = ins.course_id for ins in instructor: if ins.curriculum_id.course_code == course_code: @@ -1008,11 +1212,11 @@ def edit_quiz(request, course_code, quiz_code): extrainfo = ExtraInfo.objects.select_related().get(user=request.user) if extrainfo.user_type == 'faculty': lec = 1 - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - curriculum = ins.curriculum_id - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code: + course = ins.course_id + registered_students = course_registration.objects.filter(course_id = ins.course_id) # errors = None quiz = Quiz.objects.select_related().get(pk=quiz_code) questions = QuizQuestion.objects.select_related('question').filter(quiz_id=quiz) @@ -1043,10 +1247,11 @@ def edit_quiz_topic(request, course_code, quiz_code, topic_id): extrainfo = ExtraInfo.objects.select_related().get(user=user) lec = 1 if extrainfo.user_type == "faculty": - instructor = Curriculum_Instructor.objects.select_related().filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.course_id.course_id == course_code: + if ins.course_id.code == course_code: course = ins.course_id + registered_students = course_registration.objects.filter(course_id = ins.course_id) quiz_question = QuizQuestion.objects.select_related('question').filter(quiz_id=quiz_code) quest = [] quiz = Quiz.objects.select_related().get(pk=quiz_code) @@ -1076,10 +1281,10 @@ def remove_quiz_question(request, course_code, quiz_code, topic_id): def add_question_topicwise(request, course_code, quiz_id): extrainfo = ExtraInfo.objects.select_related().get(user=request.user) if extrainfo.user_type == 'faculty': - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code: + course = ins.course_id ques_bank = request.POST.get('qbank') quiz = Quiz.objects.select_related().get(pk=quiz_id) topic = request.POST.get('topic') @@ -1104,7 +1309,7 @@ def add_question_topicwise(request, course_code, quiz_id): @login_required def add_questions_to_quiz(request, course_id, quiz_id): - course = Course.objects.select_related().get(pk=course_id) + course = Courses.objects.select_related().get(pk=course_id) curriculum = Curriculum.objects.select_related().get(course_id = course) course_code = curriculum.course_code extrainfo = ExtraInfo.objects.select_related().get(user=request.user) @@ -1124,10 +1329,10 @@ def add_questions_to_quiz(request, course_id, quiz_id): def preview_quiz(request, course_code, quiz_code): extrainfo = ExtraInfo.objects.select_related().get(user=request.user) if extrainfo.user_type == 'faculty': - instructor = Curriculum_Instructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) for ins in instructor: - if ins.curriculum_id.course_code == course_code: - course = ins.curriculum_id.course_id + if ins.course_id.code == course_code: + course = ins.course_id quiz = Quiz.objects.select_related().get(pk=quiz_code) questions = QuizQuestion.objects.select_related().filter(quiz_id=quiz) @@ -1158,15 +1363,27 @@ def remove_quiz(request, course_code): @login_required -def ajax_assess(request, course_code): - sa = StudentAssignment.objects.select_related().get(pk=request.POST.get('pk')) - sa.score = request.POST.get('marks') - sa.save() - return HttpResponse("Marks uploaded") +def ajax_assess(request, course_code, version): + extrainfo = ExtraInfo.objects.select_related().get(user=request.user) + if extrainfo.user_type == "faculty": + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) + for ins in instructor: + if ins.course_id.code == course_code and ins.course_id.version == Decimal(version): + course = ins.course_id + # registered_students = Register.objects.filter(curr_id = ins.curriculum_id.curriculum_id) + sa = StudentAssignment.objects.select_related().get(pk=request.POST.get('pk')) + sa.score = request.POST.get('marks') + sa.save() + student = [] + student.append(sa.student_id.id.user) + # for reg_student in registered_students: + # # student.append(Student.objects.get(id = str(reg_student.student_id)).id.user) + course_management_notif(request.user, student, "An Assignment has been graded!", course.pk, str(course.name),course_code, 0) + return HttpResponse("Marks uploaded") @login_required -def ajax_feedback(request, course_code): +def ajax_feedback(request, course_code, version): sa = StudentAssignment.objects.select_related().get(pk=request.POST.get('pk')) sa.feedback = request.POST.get('feedback') sa.save() @@ -1365,13 +1582,14 @@ def get_exam_data(request,course_code): #it is store the type of exam helpful #to store the attendance of the student by taking from templates (attendance.html) @login_required -def submit_attendance(request, course_code): +def submit_attendance(request, course_code, version): user = request.user extrainfo = ExtraInfo.objects.select_related().get(user=user) + course_id = Courses.objects.select_related().get(code=course_code, version=version) if extrainfo.user_type == 'faculty': #only faculty can change the attendance of the students - instructor_old = Curriculum_Instructor.objects.select_related().filter(instructor_id=extrainfo) + instructor_old = CourseInstructor.objects.select_related().filter(instructor_id=extrainfo, course_id=course_id) for x in instructor_old: instructor = x @@ -1381,7 +1599,10 @@ def submit_attendance(request, course_code): if form.is_valid(): # for item in form.cleaned_data['Present_absent']: # print(item) - date = request.POST['date'] + try: + date = request.POST['date'] + except: + return HttpResponse("Please Enter The Form Properly") #mark the attendance according to the student roll no. @@ -1396,7 +1617,7 @@ def submit_attendance(request, course_code): if student in present_students: present = True - Student_attendance.objects.create( + Attendance.objects.create( student_id = s_id, instructor_id = instructor, date = date, @@ -1405,3 +1626,305 @@ def submit_attendance(request, course_code): return HttpResponse("Feedback uploaded") + +#to store the grading scheme created by the faculty +@login_required +def create_grading_scheme(request, course_code, version): + + user = request.user + extrainfo = ExtraInfo.objects.select_related().get(user=user) + course_id = Courses.objects.select_related().get(code=course_code, version=version) + if extrainfo.user_type == 'faculty': #only faculty can change the attendance of the students + if request.method == 'POST': + + form_data = {} + form_data = request.POST.copy() + del form_data['add_item_wtg'] + del form_data['add_eval_type'] + del form_data['csrfmiddlewaretoken'] + + # data to be sent to the gradingscheme table + key_list = list(form_data.keys()) + + no_of_evaluation_types = len(form_data) - 20 + + for i in range(no_of_evaluation_types): + already_existing_data = GradingScheme.objects.filter(course_id=course_id, type_of_evaluation=key_list[i]) + if already_existing_data.exists(): + grading_scheme_object = already_existing_data.first() + grading_scheme_object.weightage = form_data[key_list[i]] + grading_scheme_object.save() + else: + grading_scheme = GradingScheme.objects.create( + course_id=course_id, + type_of_evaluation=key_list[i], + weightage=form_data[key_list[i]] + ) + grading_scheme.save() + + # data to be sent to gradingscheme_grades table + already_existing_data2 = GradingScheme_grades.objects.filter(course_id=course_id) + if already_existing_data2.exists(): + already_existing_data2.update( + course_id = course_id, + O_Lower = form_data['O_Lower'], + O_Upper = form_data['O_Upper'], + A_plus_Lower = form_data['A_plus_Lower'], + A_plus_Upper = form_data['A_plus_Upper'], + A_Lower = form_data['A_Lower'], + A_Upper = form_data['A_Upper'], + B_plus_Lower = form_data['B_plus_Lower'], + B_plus_Upper = form_data['B_plus_Upper'], + B_Lower = form_data['B_Lower'], + B_Upper = form_data['B_Upper'], + C_plus_Lower = form_data['C_plus_Lower'], + C_plus_Upper = form_data['C_plus_Upper'], + C_Lower = form_data['C_Lower'], + C_Upper = form_data['C_Upper'], + D_plus_Lower = form_data['D_plus_Lower'], + D_plus_Upper = form_data['D_plus_Upper'], + D_Lower = form_data['D_Lower'], + D_Upper = form_data['D_Upper'], + F_Lower = form_data['F_Lower'], + F_Upper = form_data['F_Upper'] + ) + else: + grading_scheme_grades = GradingScheme_grades.objects.create( + course_id = course_id, + O_Lower = form_data['O_Lower'], + O_Upper = form_data['O_Upper'], + A_plus_Lower = form_data['A_plus_Lower'], + A_plus_Upper = form_data['A_plus_Upper'], + A_Lower = form_data['A_Lower'], + A_Upper = form_data['A_Upper'], + B_plus_Lower = form_data['B_plus_Lower'], + B_plus_Upper = form_data['B_plus_Upper'], + B_Lower = form_data['B_Lower'], + B_Upper = form_data['B_Upper'], + C_plus_Lower = form_data['C_plus_Lower'], + C_plus_Upper = form_data['C_plus_Upper'], + C_Lower = form_data['C_Lower'], + C_Upper = form_data['C_Upper'], + D_plus_Lower = form_data['D_plus_Lower'], + D_plus_Upper = form_data['D_plus_Upper'], + D_Lower = form_data['D_Lower'], + D_Upper = form_data['D_Upper'], + F_Lower = form_data['F_Lower'], + F_Upper = form_data['F_Upper'] + ) + grading_scheme_grades.save() + course(request, course_code, version) + return HttpResponse("Upload successful.") + + +@login_required +def add_academic_calendar(request): + """ + to add an entry to the academic calendar to be uploaded + + @param: + request - contains metadata about the requested page. + + @variables: + from_date - The starting date for the academic calendar event. + to_date - The ending date for the academic caldendar event. + desc - Description for the academic calendar event. + c = object to save new event to the academic calendar. + """ + user = request.user + extrainfo = ExtraInfo.objects.select_related().get(user=user) + + if extrainfo.id == 'id_admin': + calendar = Calendar.objects.all() + context= { + 'academic_calendar' :calendar, + 'tab_id' :['4','1'] + } + if request.method == "POST": + try: + from_date = request.POST.getlist('from_date') + to_date = request.POST.getlist('to_date') + desc = request.POST.getlist('description')[0] + from_date = from_date[0].split('-') + from_date = [int(i) for i in from_date] + from_date = datetime.datetime(*from_date).date() + to_date = to_date[0].split('-') + to_date = [int(i) for i in to_date] + to_date = datetime.datetime(*to_date).date() + except Exception as e: + from_date="" + to_date="" + desc="" + pass + c = Calendar( + from_date=from_date, + to_date=to_date, + description=desc) + c.save() + HttpResponse("Calendar Added") + + return render(request, 'coursemanagement/academicinfo.html', context) + + + +@login_required +def update_calendar(request): + """ + to update an entry to the academic calendar to be updated. + + @param: + request - contains metadata about the requested page. + + @variables: + from_date - The starting date for the academic calendar event. + to_date - The ending date for the academic caldendar event. + desc - Description for the academic calendar event. + prev_desc - Description for the previous event which is to be updated. + get_calendar_details = Get the object of the calendar instance from the database for the previous Description. + + """ + user = request.user + extrainfo = ExtraInfo.objects.select_related().get(user=user) + + if extrainfo.id == 'id_admin': + calendar = Calendar.objects.all() + context= { + 'academic_calendar' :calendar, + 'tab_id' :['4','1'] + } + if request.method == "POST": + try: + from_date = request.POST.getlist('from_date') + to_date = request.POST.getlist('to_date') + desc = request.POST.getlist('description')[0] + prev_desc = request.POST.getlist('prev_desc')[0] + from_date = from_date[0].split('-') + from_date = [int(i) for i in from_date] + from_date = datetime.datetime(*from_date).date() + to_date = to_date[0].split('-') + to_date = [int(i) for i in to_date] + to_date = datetime.datetime(*to_date).date() + get_calendar_details = Calendar.objects.all().filter(description=prev_desc).first() + get_calendar_details.description = desc + get_calendar_details.from_date = from_date + get_calendar_details.to_date = to_date + get_calendar_details.save() + except Exception as e: + from_date="" + to_date="" + desc="" + return render(request, 'coursemanagement/academicinfo.html', context) + return render(request, 'coursemanagement/academicinfo.html', context) + +@login_required +def add_timetable(request): + """ + acad-admin can upload the time table(any type of) of the semester. + + @param: + request - contains metadata about the requested page. + + @variables: + acadTtForm - data of delete dictionary in post request + timetable - all timetable from database + """ + user = request.user + extrainfo = ExtraInfo.objects.select_related().get(user=user) + + if extrainfo.id == 'id_admin': + if request.method == 'POST': + try: + timetable = request.FILES.get('img') + programme = request.POST.get('programme') + batch = request.POST.get('batch') + branch = request.POST.get('branch') + filename, file_extenstion = os.path.splitext(request.FILES.get('img').name) + except: + return HttpResponse("Please Enter The Form Properly", status=400) + + full_path = settings.MEDIA_ROOT + "/Administrator/academic_information/" + url = settings.MEDIA_URL + filename + if not os.path.isdir(full_path): + cmd = "mkdir " + full_path + subprocess.call(cmd, shell=True) + fs = FileSystemStorage(full_path, url) + fs.save(filename+file_extenstion, timetable) + uploaded_file_url = "Administrator/academic_information/" + filename + file_extenstion + # uploaded_file_url = full_path + filename + file_extenstion + timetb = Timetable( + time_table = uploaded_file_url, + programme = programme, + batch = batch, + branch = branch + ) + timetb.save() + + return HttpResponse("Upload successful.") + else: + return HttpResponse("Not found.") + +@login_required +def delete_timetable(request): + """ + acad-admin can delete the outdated timetable from the server. + + @param: + request - contains metadata about the requested page. + + @variables: + data - data of delete dictionary in post request + t - Object of time table to be deleted + """ + user = request.user + extrainfo = ExtraInfo.objects.select_related().get(user=user) + + + if extrainfo.id == 'id_admin': + if request.method == "POST": + pk = request.POST.get('pk') + t = Timetable.objects.get(pk=pk) + t.delete() + return HttpResponse("TimeTable Deleted") + +@login_required +def submit_marks(request, course_code, version): + + user = request.user + extrainfo = ExtraInfo.objects.select_related().get(user=user) + course_id = Courses.objects.select_related().get(code=course_code, version=version) + if extrainfo.user_type == 'faculty': + if request.method == 'POST': + + form_data = {} + form_data = request.POST.copy() + del form_data['csrfmiddlewaretoken'] + year = datetime.datetime.now().year + + # print('number is ', int(len(form_data.getlist('stu_marks'))/3)) + for i in range(int(len(form_data.getlist('stu_marks'))/3)): + student = Student.objects.select_related().get(id=str(form_data.getlist('stu_marks')[(i*3)])) + batch = str(student.batch) + # print(batch) + already_existing_data = Student_grades.objects.filter(roll_no=str(form_data.getlist('stu_marks')[(i*3)])) + if already_existing_data.exists(): + already_existing_data.update( + semester = student.curr_semester_no, + year = year, + roll_no = str(form_data.getlist('stu_marks')[(i*3)]), + total_marks = (form_data.getlist('stu_marks')[(i*3+1)]), + grade = str(form_data.getlist('stu_marks')[(i*3+2)]), + batch = batch, + course_id = course_id, + ) + else: + student_grades = Student_grades.objects.create( + semester = student.curr_semester_no, + year = year, + roll_no = str(form_data.getlist('stu_marks')[(i*3)]), + total_marks = (form_data.getlist('stu_marks')[(i*3+1)]), + grade = str(form_data.getlist('stu_marks')[(i*3+2)]), + batch = batch, + course_id = course_id, + ) + student_grades.save() + return HttpResponse("Upload successful.") \ No newline at end of file diff --git a/FusionIIIT/media/New_Text_Document_2_wgRF9M5.txt b/FusionIIIT/applications/otheracademic/__init__.py similarity index 100% rename from FusionIIIT/media/New_Text_Document_2_wgRF9M5.txt rename to FusionIIIT/applications/otheracademic/__init__.py diff --git a/FusionIIIT/applications/otheracademic/admin.py b/FusionIIIT/applications/otheracademic/admin.py new file mode 100644 index 000000000..17991a755 --- /dev/null +++ b/FusionIIIT/applications/otheracademic/admin.py @@ -0,0 +1,18 @@ +from django.contrib import admin + +# Register your models here. + +from applications.otheracademic.models import GraduateSeminarFormTable,LeaveFormTable,BonafideFormTableUpdated,AssistantshipClaimFormStatusUpd,NoDues,LeavePG,LeavePGUpdTable + +admin.site.register(LeaveFormTable) + +admin.site.register(BonafideFormTableUpdated) +admin.site.register(GraduateSeminarFormTable) + +admin.site.register(AssistantshipClaimFormStatusUpd) + +admin.site.register(NoDues) +admin.site.register(LeavePGUpdTable) +admin.site.register(LeavePG) + + diff --git a/FusionIIIT/applications/otheracademic/apps.py b/FusionIIIT/applications/otheracademic/apps.py new file mode 100644 index 000000000..9b5920f10 --- /dev/null +++ b/FusionIIIT/applications/otheracademic/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class OtheracademicConfig(AppConfig): + + name = 'otheracademic' diff --git a/FusionIIIT/applications/otheracademic/migrations/0001_initial.py b/FusionIIIT/applications/otheracademic/migrations/0001_initial.py new file mode 100644 index 000000000..3a2317c25 --- /dev/null +++ b/FusionIIIT/applications/otheracademic/migrations/0001_initial.py @@ -0,0 +1,226 @@ +# Generated by Django 3.1.5 on 2024-04-16 20:30 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('globals', '__first__'), + ] + + operations = [ + migrations.CreateModel( + name='GraduateSeminarFormTable', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('roll_no', models.CharField(max_length=20)), + ('semester', models.CharField(max_length=100)), + ('date_of_seminar', models.DateField()), + ], + options={ + 'db_table': 'GraduateSeminarFormTable', + }, + ), + migrations.CreateModel( + name='NoDues', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('library_clear', models.BooleanField(default=False)), + ('library_notclear', models.BooleanField(default=False)), + ('hostel_clear', models.BooleanField(default=False)), + ('hostel_notclear', models.BooleanField(default=False)), + ('mess_clear', models.BooleanField(default=False)), + ('mess_notclear', models.BooleanField(default=False)), + ('ece_clear', models.BooleanField(default=False)), + ('ece_notclear', models.BooleanField(default=False)), + ('physics_lab_clear', models.BooleanField(default=False)), + ('physics_lab_notclear', models.BooleanField(default=False)), + ('mechatronics_lab_clear', models.BooleanField(default=False)), + ('mechatronics_lab_notclear', models.BooleanField(default=False)), + ('cc_clear', models.BooleanField(default=False)), + ('cc_notclear', models.BooleanField(default=False)), + ('workshop_clear', models.BooleanField(default=False)), + ('workshop_notclear', models.BooleanField(default=False)), + ('signal_processing_lab_clear', models.BooleanField(default=False)), + ('signal_processing_lab_notclear', models.BooleanField(default=False)), + ('vlsi_clear', models.BooleanField(default=False)), + ('vlsi_notclear', models.BooleanField(default=False)), + ('design_studio_clear', models.BooleanField(default=False)), + ('design_studio_notclear', models.BooleanField(default=False)), + ('design_project_clear', models.BooleanField(default=False)), + ('design_project_notclear', models.BooleanField(default=False)), + ('bank_clear', models.BooleanField(default=False)), + ('bank_notclear', models.BooleanField(default=False)), + ('icard_dsa_clear', models.BooleanField(default=False)), + ('icard_dsa_notclear', models.BooleanField(default=False)), + ('account_clear', models.BooleanField(default=False)), + ('account_notclear', models.BooleanField(default=False)), + ('btp_supervisor_clear', models.BooleanField(default=False)), + ('btp_supervisor_notclear', models.BooleanField(default=False)), + ('discipline_office_clear', models.BooleanField(default=False)), + ('discipline_office_notclear', models.BooleanField(default=False)), + ('student_gymkhana_clear', models.BooleanField(default=False)), + ('student_gymkhana_notclear', models.BooleanField(default=False)), + ('alumni_clear', models.BooleanField(default=False)), + ('alumni_notclear', models.BooleanField(default=False)), + ('placement_cell_clear', models.BooleanField(default=False)), + ('placement_cell_notclear', models.BooleanField(default=False)), + ('discipline_office_dsa_clear', models.BooleanField(default=False)), + ('discipline_office_dsa_notclear', models.BooleanField(default=False)), + ('hostel_credential', models.CharField(max_length=100)), + ('bank_credential', models.CharField(max_length=100)), + ('btp_credential', models.CharField(max_length=100)), + ('cse_credential', models.CharField(max_length=100)), + ('design_credential', models.CharField(max_length=100)), + ('acad_credential', models.CharField(max_length=100)), + ('ece_credential', models.CharField(max_length=100)), + ('library_credential', models.CharField(max_length=100)), + ('me_credential', models.CharField(max_length=100)), + ('mess_credential', models.CharField(max_length=100)), + ('physics_credential', models.CharField(max_length=100)), + ('discipline_credential', models.CharField(max_length=100)), + ('acad_admin_float', models.BooleanField(default=False)), + ('roll_no', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), + ], + options={ + 'db_table': 'NoDues', + }, + ), + migrations.CreateModel( + name='LeavePGUpdTable', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('student_name', models.CharField(max_length=100)), + ('programme', models.CharField(max_length=100)), + ('discipline', models.CharField(max_length=100)), + ('Semester', models.CharField(max_length=100)), + ('date_from', models.DateField()), + ('date_to', models.DateField()), + ('date_of_application', models.DateField()), + ('upload_file', models.FileField(upload_to='leave_doc')), + ('address', models.CharField(max_length=100)), + ('purpose', models.TextField()), + ('leave_type', models.CharField(choices=[('Casual', 'Casual'), ('Medical', 'Medical'), ('Vacation', 'Vacation'), ('Duty', 'Duty')], max_length=20)), + ('mobile_no', models.CharField(max_length=100)), + ('parent_mobile_no', models.CharField(max_length=100)), + ('alt_mobile_no', models.CharField(max_length=100)), + ('ta_approved', models.BooleanField()), + ('ta_rejected', models.BooleanField()), + ('hod_approved', models.BooleanField()), + ('hod_rejected', models.BooleanField()), + ('ta_supervisor', models.CharField(max_length=100)), + ('hod', models.CharField(max_length=100)), + ('roll_no', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), + ], + options={ + 'db_table': 'LeavePGUpdTable', + }, + ), + migrations.CreateModel( + name='LeavePG', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('student_name', models.CharField(max_length=100)), + ('programme', models.CharField(max_length=100)), + ('discipline', models.CharField(max_length=100)), + ('Semester', models.CharField(max_length=100)), + ('date_from', models.DateField()), + ('date_to', models.DateField()), + ('date_of_application', models.DateField()), + ('upload_file', models.FileField(upload_to='leave_doc')), + ('address', models.CharField(max_length=100)), + ('purpose', models.TextField()), + ('leave_type', models.CharField(choices=[('Casual', 'Casual'), ('Medical', 'Medical'), ('Vacation', 'Vacation'), ('Duty', 'Duty')], max_length=20)), + ('mobile_no', models.CharField(max_length=100)), + ('parent_mobile_no', models.CharField(max_length=100)), + ('alt_mobile_no', models.CharField(max_length=100)), + ('ta_approved', models.BooleanField()), + ('ta_rejected', models.BooleanField()), + ('hod_approved', models.BooleanField()), + ('hod_rejected', models.BooleanField()), + ('ta_supervisor', models.CharField(max_length=100)), + ('hod', models.CharField(max_length=100)), + ('roll_no', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), + ], + options={ + 'db_table': 'LeavePG', + }, + ), + migrations.CreateModel( + name='LeaveFormTable', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('student_name', models.CharField(max_length=100)), + ('date_from', models.DateField()), + ('date_to', models.DateField()), + ('date_of_application', models.DateField()), + ('upload_file', models.FileField(blank=True, upload_to='')), + ('address', models.CharField(max_length=100)), + ('purpose', models.TextField()), + ('leave_type', models.CharField(choices=[('Casual', 'Casual'), ('Medical', 'Medical')], max_length=20)), + ('approved', models.BooleanField()), + ('rejected', models.BooleanField()), + ('hod', models.CharField(max_length=100)), + ('roll_no', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), + ], + options={ + 'db_table': 'LeaveFormTable', + }, + ), + migrations.CreateModel( + name='BonafideFormTableUpdated', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('student_names', models.CharField(max_length=100)), + ('branch_types', models.CharField(max_length=50)), + ('semester_types', models.CharField(max_length=20)), + ('purposes', models.TextField()), + ('date_of_applications', models.DateField()), + ('approve', models.BooleanField()), + ('reject', models.BooleanField()), + ('download_file', models.FileField(default='not available', upload_to='Bonafide')), + ('roll_nos', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), + ], + options={ + 'db_table': 'BonafideFormTableUpdated', + }, + ), + migrations.CreateModel( + name='AssistantshipClaimFormStatusUpd', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('student_name', models.CharField(max_length=100)), + ('discipline', models.CharField(max_length=100)), + ('dateFrom', models.DateField()), + ('dateTo', models.DateField()), + ('bank_account', models.CharField(max_length=100)), + ('student_signature', models.FileField(upload_to='student_signatures/')), + ('dateApplied', models.DateField()), + ('ta_supervisor', models.CharField(max_length=100)), + ('thesis_supervisor', models.CharField(max_length=100)), + ('hod', models.CharField(max_length=100)), + ('applicability', models.CharField(max_length=100)), + ('TA_approved', models.BooleanField()), + ('TA_rejected', models.BooleanField()), + ('Ths_approved', models.BooleanField()), + ('Ths_rejected', models.BooleanField()), + ('HOD_approved', models.BooleanField()), + ('HOD_rejected', models.BooleanField()), + ('Acad_approved', models.BooleanField()), + ('Acad_rejected', models.BooleanField()), + ('amount', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('rate', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('half_day_leave', models.IntegerField(default=0)), + ('full_day_leave', models.IntegerField(default=0)), + ('roll_no', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), + ], + options={ + 'db_table': 'AssistantshipClaimFormStausUpd', + }, + ), + ] diff --git a/FusionIIIT/applications/otheracademic/migrations/__init__.py b/FusionIIIT/applications/otheracademic/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/FusionIIIT/applications/otheracademic/models.py b/FusionIIIT/applications/otheracademic/models.py new file mode 100644 index 000000000..b361b849f --- /dev/null +++ b/FusionIIIT/applications/otheracademic/models.py @@ -0,0 +1,328 @@ +from datetime import datetime + +from applications.globals.models import ExtraInfo, HoldsDesignation, Designation +from django.db import models +from django import forms +from django.contrib.auth.models import User +from applications.academic_information.models import Student +from django.core.exceptions import ValidationError + + +class LeaveFormTable(models.Model): + """ + Records information related to student leave requests. + + 'leave_from' and 'leave_to' store the start and end date of the leave request. + 'date_of_application' stores the date when the leave request was applied. + 'related_document' stores any related documents or notes for the leave request. + 'place' stores the location where the leave is requested. + 'reason' stores the reason for the leave request. + 'leave_type' stores the type of leave from a dropdown. + """ + LEAVE_TYPES = ( + ('Casual', 'Casual'), + ('Medical', 'Medical'), + + ) + + + student_name = models.CharField(max_length=100) + roll_no = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) + date_from = models.DateField() + date_to = models.DateField() + date_of_application = models.DateField() + upload_file = models.FileField(blank=True) + address = models.CharField(max_length=100) + purpose = models.TextField() + leave_type = models.CharField(max_length=20, choices=LEAVE_TYPES) + approved = models.BooleanField() + rejected = models.BooleanField() + hod= models.CharField(max_length=100) + + class Meta: + db_table='LeaveFormTable' + + +class LeavePG(models.Model): + """ + Records information related to student leave requests. + + 'leave_from' and 'leave_to' store the start and end date of the leave request. + 'date_of_application' stores the date when the leave request was applied. + 'related_document' stores any related documents or notes for the leave request. + 'place' stores the location where the leave is requested. + 'reason' stores the reason for the leave request. + 'leave_type' stores the type of leave from a dropdown. + """ + LEAVE_TYPES = ( + ('Casual', 'Casual'), + ('Medical', 'Medical'), + ('Vacation', 'Vacation'), + ('Duty', 'Duty') + + ) + + + + student_name = models.CharField(max_length=100) + roll_no = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) + programme = models.CharField(max_length=100) + discipline = models.CharField(max_length=100) + Semester = models.CharField(max_length=100) + date_from = models.DateField() + date_to = models.DateField() + date_of_application = models.DateField() + upload_file = models.FileField(blank=True) + address = models.CharField(max_length=100) + purpose = models.TextField() + leave_type = models.CharField(max_length=20, choices=LEAVE_TYPES) + ta_supervisor = models.CharField(max_length=100) + mobile_no = models.CharField(max_length=100) + parent_mobile_no = models.CharField(max_length=100) + alt_mobile_no = models.CharField(max_length=100) + ta_approved = models.BooleanField() + ta_rejected = models.BooleanField() + thesis_approved = models.BooleanField() + thesis_rejected = models.BooleanField() + hod_approved = models.BooleanField() + hod_rejected = models.BooleanField() + ta_supervisor=models.CharField(max_length=100) + thesis_supervisor=models.CharField(max_length=100) + hod=models.CharField(max_length=100) + + + class Meta: + db_table='LeavePG' + + + + +class LeavePGUpdTable(models.Model): + """ + Records information related to student leave requests. + + 'leave_from' and 'leave_to' store the start and end date of the leave request. + 'date_of_application' stores the date when the leave request was applied. + 'related_document' stores any related documents or notes for the leave request. + 'place' stores the location where the leave is requested. + 'reason' stores the reason for the leave request. + 'leave_type' stores the type of leave from a dropdown. + """ + LEAVE_TYPES = ( + ('Casual', 'Casual'), + ('Medical', 'Medical'), + ('Vacation', 'Vacation'), + ('Duty', 'Duty') + + ) + + + student_name = models.CharField(max_length=100) + roll_no = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) + programme = models.CharField(max_length=100) + discipline = models.CharField(max_length=100) + Semester = models.CharField(max_length=100) + date_from = models.DateField() + date_to = models.DateField() + date_of_application = models.DateField() + upload_file = models.FileField(upload_to='leave_doc') + address = models.CharField(max_length=100) + purpose = models.TextField() + leave_type = models.CharField(max_length=20, choices=LEAVE_TYPES) + ta_supervisor = models.CharField(max_length=100) + mobile_no = models.CharField(max_length=100) + parent_mobile_no = models.CharField(max_length=100) + alt_mobile_no = models.CharField(max_length=100) + ta_approved = models.BooleanField() + ta_rejected = models.BooleanField() + hod_approved = models.BooleanField() + hod_rejected = models.BooleanField() + ta_supervisor=models.CharField(max_length=100) + hod=models.CharField(max_length=100) + + + class Meta: + db_table='LeavePGUpdTable' + + + +class GraduateSeminarFormTable(models.Model): + + roll_no = models.CharField(max_length=20) + semester= models.CharField(max_length=100) + date_of_seminar = models.DateField() + + + class Meta: + db_table='GraduateSeminarFormTable' + + + +class BonafideFormTableUpdated(models.Model): + + + + student_names = models.CharField(max_length=100) + roll_nos = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) + branch_types = models.CharField(max_length=50) + semester_types = models.CharField(max_length=20) + purposes = models.TextField() + date_of_applications= models.DateField() + approve = models.BooleanField() + reject = models.BooleanField() + download_file = models.FileField(upload_to='Bonafide',default="not available") + + + + class Meta: + db_table='BonafideFormTableUpdated' + + + +# class AssistantshipClaimFormStatusUpd(models.Model): +# roll_no = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) +# student_name = models.CharField(max_length=100) +# discipline = models.CharField(max_length=100) +# dateFrom = models.DateField() +# dateTo = models.DateField() +# # month = models.CharField(max_length=50) +# # year = models.CharField(max_length=50) +# bank_account = models.CharField(max_length=100) +# student_signature = models.FileField(upload_to='student_signatures/') # Change to FileField +# dateApplied = models.DateField() +# ta_supervisor = models.CharField(max_length=100) +# thesis_supervisor = models.CharField(max_length=100) +# applicability = models.CharField(max_length=100) + +# TA_approved = models.BooleanField() +# TA_rejected = models.BooleanField() +# Ths_approved = models.BooleanField() +# Ths_rejected = models.BooleanField() +# HOD_approved = models.BooleanField() +# HOD_rejected = models.BooleanField() +# Acad_approved = models.BooleanField() +# Acad_rejected = models.BooleanField() + +# class Meta: +# db_table = 'AssistantshipClaimFormStausUpd' + + + + + + + +class AssistantshipClaimFormStatusUpd(models.Model): + roll_no = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) + student_name = models.CharField(max_length=100) + discipline = models.CharField(max_length=100) + dateFrom = models.DateField() + dateTo = models.DateField() + + bank_account = models.CharField(max_length=100) + student_signature = models.FileField(upload_to='student_signatures/') + dateApplied = models.DateField() + ta_supervisor = models.CharField(max_length=100) + thesis_supervisor = models.CharField(max_length=100) + hod = models.CharField(max_length=100) + applicability = models.CharField(max_length=100) + + TA_approved = models.BooleanField() + TA_rejected = models.BooleanField() + Ths_approved = models.BooleanField() + Ths_rejected = models.BooleanField() + HOD_approved = models.BooleanField() + HOD_rejected = models.BooleanField() + Acad_approved = models.BooleanField() + Acad_rejected = models.BooleanField() + + amount = models.DecimalField(max_digits=10, decimal_places=2, default=0) + rate = models.DecimalField(max_digits=10, decimal_places=2, default=0) + half_day_leave = models.IntegerField(default=0) + full_day_leave = models.IntegerField(default=0) + + remark = models.TextField(default='') # New field with an empty default value + + def clean(self): + start_date = self.cleaned_data['start_date'] + end_date = self.cleaned_data['end_date'] + + if end_date <= start_date: + raise forms.ValidationError("End date must be later than start date") + + return super(AssistantshipClaimFormStatusUpd, self).clean() + + class Meta: + db_table = 'AssistantshipClaimFormStausUpd' + + + + + + + +class NoDues(models.Model): + roll_no = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) + name = models.CharField(max_length=100) + + library_clear = models.BooleanField(default=False) + library_notclear = models.BooleanField(default=False) + hostel_clear = models.BooleanField(default=False) + hostel_notclear = models.BooleanField(default=False) + mess_clear = models.BooleanField(default=False) + mess_notclear = models.BooleanField(default=False) + ece_clear = models.BooleanField(default=False) + ece_notclear = models.BooleanField(default=False) + physics_lab_clear = models.BooleanField(default=False) + physics_lab_notclear = models.BooleanField(default=False) + mechatronics_lab_clear = models.BooleanField(default=False) + mechatronics_lab_notclear = models.BooleanField(default=False) + cc_clear = models.BooleanField(default=False) + cc_notclear = models.BooleanField(default=False) + workshop_clear = models.BooleanField(default=False) + workshop_notclear = models.BooleanField(default=False) + signal_processing_lab_clear = models.BooleanField(default=False) + signal_processing_lab_notclear = models.BooleanField(default=False) + vlsi_clear = models.BooleanField(default=False) + vlsi_notclear = models.BooleanField(default=False) + design_studio_clear = models.BooleanField(default=False) + design_studio_notclear = models.BooleanField(default=False) + design_project_clear = models.BooleanField(default=False) + design_project_notclear = models.BooleanField(default=False) + bank_clear = models.BooleanField(default=False) + bank_notclear = models.BooleanField(default=False) + icard_dsa_clear = models.BooleanField(default=False) + icard_dsa_notclear = models.BooleanField(default=False) + account_clear = models.BooleanField(default=False) + account_notclear = models.BooleanField(default=False) + btp_supervisor_clear = models.BooleanField(default=False) + btp_supervisor_notclear = models.BooleanField(default=False) + discipline_office_clear = models.BooleanField(default=False) + discipline_office_notclear = models.BooleanField(default=False) + student_gymkhana_clear = models.BooleanField(default=False) + student_gymkhana_notclear = models.BooleanField(default=False) + alumni_clear = models.BooleanField(default=False) + alumni_notclear = models.BooleanField(default=False) + placement_cell_clear = models.BooleanField(default=False) + placement_cell_notclear = models.BooleanField(default=False) + # discipline_office_dsa_clear=models.BooleanField(default=False) + # discipline_office_dsa_notclear=models.BooleanField(default=False) + + hostel_credential = models.CharField(max_length=100) + bank_credential = models.CharField(max_length=100) + btp_credential = models.CharField(max_length=100) + cse_credential = models.CharField(max_length=100) + design_credential = models.CharField(max_length=100) + acad_credential = models.CharField(max_length=100) + ece_credential = models.CharField(max_length=100) + library_credential = models.CharField(max_length=100) + me_credential = models.CharField(max_length=100) + mess_credential = models.CharField(max_length=100) + physics_credential = models.CharField(max_length=100) + discipline_credential = models.CharField(max_length=100) + + acad_admin_float = models.BooleanField(default=False) + + class Meta: + db_table = 'NoDues' + diff --git a/FusionIIIT/applications/otheracademic/tests.py b/FusionIIIT/applications/otheracademic/tests.py new file mode 100644 index 000000000..7ce503c2d --- /dev/null +++ b/FusionIIIT/applications/otheracademic/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/FusionIIIT/applications/otheracademic/urls.py b/FusionIIIT/applications/otheracademic/urls.py new file mode 100644 index 000000000..25cc72051 --- /dev/null +++ b/FusionIIIT/applications/otheracademic/urls.py @@ -0,0 +1,213 @@ +from django.conf.urls import url + +from . import views + +app_name = 'otheracademic' + +urlpatterns = [ + #UG Leave + url(r'^$', views.otheracademic, name='otheracademic'), + url(r'^leaveform/$', views.leaveform, name='leaveform'), + + url(r'^leave_form_submit/$', views.leave_form_submit, name='leave_form_submit'), + url(r'^leaveApproveForm/$', views.leaveApproveForm, name='leaveApproveForm'), + url(r'^leaveStatus/$', views.leaveStatus, name='leaveStatus'), + + url(r'^leaveStatus_Dip/$', views.leaveStatus_Dip, name='leaveStatus_Dip'), + + url(r'^approve_leave/(?P\d+)/$', views.approve_leave, name='approve_leave'), + url(r'^reject_leave/(?P\d+)/$', views.reject_leave, name='reject_leave'), + + #PG/Mtech Leave + url(r'^leavePG/$', views.leavePG, name='leavePG'), + url(r'^leavePgSubmit/$', views.leavePgSubmit, name='leavePgSubmit'), + url(r'^leaveApproveTA/$', views.leaveApproveTA, name='leaveApproveTA'), + url(r'^approve_leave_ta(?P\d+)/$', views.approve_leave_ta, name='approve_leave_ta'), + url(r'^reject_leave_ta(?P\d+)/$', views.reject_leave_ta, name='reject_leave_ta'), + url(r'^leaveApproveThesis/$', views.leaveApproveThesis, name='leaveApproveThesis'), + url(r'^approve_leave_thesis(?P\d+)/$', views.approve_leave_thesis, name='approve_leave_thesis'), + url(r'^reject_leave_thesis(?P\d+)/$', views.reject_leave_thesis, name='reject_leave_thesis'), + url(r'^leaveApproveHOD/$', views.leaveApproveHOD, name='leaveApproveHOD'), + url(r'^approve_leave_hod(?P\d+)/$', views.approve_leave_hod, name='approve_leave_hod'), + url(r'^reject_leave_hod(?P\d+)/$', views.reject_leave_hod, name='reject_leave_hod'), + url(r'^leaveStatusPG/$', views.leaveStatusPG, name='leaveStatusPG'), + url(r'^leaveStatusPG_Dip/$', views.leaveStatusPG_Dip, name='leaveStatusPG_Dip'), + + url(r'^graduateseminar/$', views.graduateseminar, name='graduateseminar'), + url(r'^graduate_form_submit/$', views.graduate_form_submit, name='graduate_form_submit'), + url(r'^graduate_status/$', views.graduate_status, name='graduate_status'), + url(r'^graduateSeminarStatus_Dip/$', views.graduateSeminarStatus_Dip, name='graduateSeminarStatus_Dip'), + url(r'^bonafide/$', views.bonafide, name='bonafide'), + url(r'^bonafide_form_submit/$', views.bonafide_form_submit, name='bonafide_form_submit'), + url(r'^bonafideApproveForm/$', views.bonafideApproveForm, name='bonafideApproveForm'), + url(r'^approve_bonafide/(?P\d+)/$', views.approve_bonafide, name='approve_bonafide'), + url(r'^reject_bonafide/(?P\d+)/$', views.reject_bonafide, name='reject_bonafide'), + url(r'^bonafideStatus/$', views.bonafideStatus, name='bonafideStatus'), + url(r'^upload_file/(?P\d+)/$', views.upload_file, name='upload_file'), + # url(r'^assistantship/$', views.assistantship, name='assistantship'), + url(r'^submitform/$', views.assistantship_form_submission, name='assistantship_form_submission'), + # url(r'^approveform/$', views.assistantship_form_approval, name='assistantship_approval'), + # url(r'^noduesverification/$', views.nodues, name='nodues'), + url(r'^PG_page/$', views.PG_page, name='PG_page'), + + url(r'^noduesverification/$', views.nodues, name='nodues'), + + url(r'^Bank_nodues/$', views.Bank_nodues, name='Bank_nodues'), + url(r'^BTP_nodues/$', views.BTP_nodues, name='BTP_nodues'), + url(r'^CSE_nodues/$', views.CSE_nodues, name='CSE_nodues'), + url(r'^Design_nodues/$', views.Design_nodues, name='Design_nodues'), + url(r'^dsa_nodues/$', views.dsa_nodues, name='dsa_nodues'), + url(r'^Ece_nodues/$', views.Ece_nodues, name='Ece_nodues'), + url(r'^hostel_nodues/$', views.hostel_nodues, name='hostel_nodues'), + url(r'^ME_nodues/$', views.ME_nodues, name='ME_nodues'), + url(r'^library_nodues/$', views.library_nodues, name='library_nodues'), + url(r'^mess_nodues/$', views.mess_nodues, name='mess_nodues'), + url(r'^Physics_nodues/$', views.Physics_nodues, name='Physics_nodues'), + url(r'^discipline_nodues/$', views.discipline_nodues, name='discipline_nodues'), + + url(r'^nodues_apply/$', views.nodues_apply, name='nodues_apply'), + url(r'^nodues_status/$', views.nodues_status, name='nodues_status'), + + url(r'^update_dues_status/$', views.update_dues_status, name='update_dues_status'), + url(r'^submit_nodues_form/$', views.submit_nodues_form, name='submit_nodues_form'), + url(r'^nodues_apply/$', views.nodues_apply, name='nodues_apply'), + + + url(r'^approve_BTP(?P\d+)/$', views.approve_BTP, name='approve_BTP'), + url(r'^reject_BTP(?P\d+)/$', views.reject_BTP, name='reject_BTP'), + + url(r'^approve_bank(?P\d+)/$', views.approve_bank, name='approve_bank'), + url(r'^reject_bank(?P\d+)/$', views.reject_bank, name='reject_bank'), + + url(r'^approve_CSE(?P\d+)/$', views.approve_CSE, name='approve_CSE'), + url(r'^reject_CSE(?P\d+)/$', views.reject_CSE, name='reject_CSE'), + + url(r'^approve_design_project(?P\d+)/$', views.approve_design_project, name='approve_design_project'), + url(r'^reject_design-project(?P\d+)/$', views.reject_design_project, name='reject_design_project'), + + url(r'^approve_design_studio(?P\d+)/$', views.approve_design_studio, name='approve_design_studio'), + url(r'^reject_design_studio(?P\d+)/$', views.reject_design_studio, name='reject_design_studio'), + + url(r'^approve_icard(?P\d+)/$', views.approve_icard, name='approve_icard'), + url(r'^reject_icard(?P\d+)/$', views.reject_icard, name='reject_icard'), + + url(r'^approve_placement(?P\d+)/$', views.approve_placement, name='approve_placement'), + url(r'^reject_placement(?P\d+)/$', views.reject_placement, name='reject_placement'), + + url(r'^approve_account(?P\d+)/$', views.approve_account, name='approve_account'), + url(r'^reject_account(?P\d+)/$', views.reject_account, name='reject_account'), + + url(r'^approve_alumni(?P\d+)/$', views.approve_alumni, name='approve_alumni'), + url(r'^reject_alumni(?P\d+)/$', views.reject_alumni, name='reject_alumni'), + + url(r'^approve_gym(?P\d+)/$', views.approve_gym, name='approve_gym'), + url(r'^reject_gym(?P\d+)/$', views.reject_gym, name='reject_gym'), + + url(r'^approve_discipline(?P\d+)/$', views.approve_discipline, name='approve_discipline'), + url(r'^reject_discipline(?P\d+)/$', views.reject_discipline, name='reject_discipline'), + + url(r'^approve_signal(?P\d+)/$', views.approve_signal, name='approve_signal'), + url(r'^reject_signal(?P\d+)/$', views.reject_signal, name='reject_signal'), + + url(r'^approve_vlsi(?P\d+)/$', views.approve_vlsi, name='approve_vlsi'), + url(r'^reject_vlsi(?P\d+)/$', views.reject_vlsi, name='reject_vlsi'), + + url(r'^approve_ece(?P\d+)/$', views.approve_ece, name='approve_ece'), + url(r'^reject_ece(?P\d+)/$', views.reject_ece, name='reject_ece'), + + url(r'^approve_hostel(?P\d+)/$', views.approve_hostel, name='approve_hostel'), + url(r'^reject_hostel(?P\d+)/$', views.reject_hostel, name='reject_hostel'), + + url(r'^approve_library(?P\d+)/$', views.approve_library, name='approve_library'), + url(r'^reject_library(?P\d+)/$', views.reject_library, name='reject_library'), + + url(r'^approve_workshop(?P\d+)/$', views.approve_workshop, name='approve_workshop'), + url(r'^reject_workshop(?P\d+)/$', views.reject_workshop, name='reject_workshop'), + + url(r'^approve_mecha(?P\d+)/$', views.approve_mecha, name='approve_mecha'), + url(r'^reject_mecha(?P\d+)/$', views.reject_mecha, name='reject_mecha'), + + url(r'^approve_mess(?P\d+)/$', views.approve_mess, name='approve_mess'), + url(r'^reject_mess(?P\d+)/$', views.reject_mess, name='reject_mess'), + + url(r'^approve_physics(?P\d+)/$', views.approve_physics, name='approve_physics'), + url(r'^reject_physics(?P\d+)/$', views.reject_physics, name='reject_physics'), + + + + + url(r'^approve_BTP_not(?P\d+)/$', views.approve_BTP_not, name='approve_BTP_not'), + url(r'^approve_bank_not(?P\d+)/$', views.approve_bank_not, name='approve_bank_not'), + url(r'^approve_CSE_not(?P\d+)/$', views.approve_CSE_not, name='approve_CSE_not'), + url(r'^approve_design_project_not(?P\d+)/$', views.approve_design_project_not, name='approve_design_project_not'), + url(r'^approve_design_studio_not(?P\d+)/$', views.approve_design_studio_not, name='approve_design_studio_not'), + url(r'^approve_icard_not(?P\d+)/$', views.approve_icard_not, name='approve_icard_not'), + url(r'^approve_placement_not(?P\d+)/$', views.approve_placement_not, name='approve_placement_not'), + url(r'^approve_account_not(?P\d+)/$', views.approve_account_not, name='approve_account_not'), + url(r'^approve_alumni_not(?P\d+)/$', views.approve_alumni_not, name='approve_alumni_not'), + url(r'^approve_gym_not(?P\d+)/$', views.approve_gym_not, name='approve_gym_not'), + url(r'^approve_discipline_not(?P\d+)/$', views.approve_discipline_not, name='approve_discipline_not'), + url(r'^approve_signal_not(?P\d+)/$', views.approve_signal_not, name='approve_signal_not'), + url(r'^approve_vlsi_not(?P\d+)/$', views.approve_vlsi_not, name='approve_vlsi_not'), + url(r'^approve_ece_not(?P\d+)/$', views.approve_ece_not, name='approve_ece_not'), + url(r'^approve_hostel_not(?P\d+)/$', views.approve_hostel_not, name='approve_hostel_not'), + url(r'^approve_library_not(?P\d+)/$', views.approve_library_not, name='approve_library_not'), + url(r'^approve_workshop_not(?P\d+)/$', views.approve_workshop_not, name='approve_workshop_not'), + url(r'^approve_mecha_not(?P\d+)/$', views.approve_mecha_not, name='approve_mecha_not'), + url(r'^approve_mess_not(?P\d+)/$', views.approve_mess_not, name='approve_mess_not'), + url(r'^approve_physics_not(?P\d+)/$', views.approve_physics_not, name='approve_physics_not'), + + + + url(r'^Bank_nodues_not/$', views.Bank_nodues_not, name='Bank_nodues_not'), + url(r'^BTP_nodues_not/$', views.BTP_nodues_not, name='BTP_nodues_not'), + url(r'^CSE_nodues_not/$', views.CSE_nodues_not, name='CSE_nodues_not'), + url(r'^Design_nodues_not/$', views.Design_nodues_not, name='Design_nodues_not'), + url(r'^dsa_nodues_not/$', views.dsa_nodues_not, name='dsa_nodues_not'), + url(r'^Ece_nodues_not/$', views.Ece_nodues_not, name='Ece_nodues_not'), + url(r'^hostel_nodues_not/$', views.hostel_nodues_not, name='hostel_nodues_not'), + url(r'^ME_nodues_not/$', views.ME_nodues_not, name='ME_nodues_not'), + url(r'^library_nodues_not/$', views.library_nodues_not, name='library_nodues_not'), + url(r'^mess_nodues_not/$', views.mess_nodues_not, name='mess_nodues_not'), + url(r'^Physics_nodues_not/$', views.Physics_nodues_not, name='Physics_nodues_not'), + url(r'^discipline_nodues_not/$', views.discipline_nodues_not, name='discipline_nodues_not'), + + + + url(r'^noduesStatus_acad/$', views.noduesStatus_acad, name='noduesStatus_acad'), + + + url(r'^assistantship/$', views.assistantship, name='assistantship'), + url(r'^submitform/$', views.assistantship_form_submission, name='assistantship_form_submission'), + # url(r'^approveform/$', views.assistantship_form_approval, name='assistantship_approval'), + + url(r'^approveform/$', views.assistantship_form_approval, name='assistantship_form_approval'), + url(r'^assitantship/thesis_approveform/$', views.assistantship_thesis, name='assistantship_thesis'), + url(r'^assitantship/hod_approveform/$', views.assistantship_hod, name='assistantship_hod'), + url(r'^assitantship/acad_approveform/$', views.assistantship_acad_approveform, name='assistantship_acad_approveform'), + url(r'^assistantship_status/$', views.assistantship_status, name='assistantship_status'), + url(r'^assistantship_log/$', views.assistantship_log, name='assistantship_log'), + + # url(r'^noduesverification/$', views.nodues, name='nodues'), + + url(r'^assistanship_ta_approve(?P\d+)/$', views.assistanship_ta_approve, name='assistanship_ta_approve'), + url(r'^assistanship_ta_reject(?P\d+)/$', views.assistanship_ta_reject, name='assistanship_ta_reject'), + url(r'^assistanship_thesis_approve(?P\d+)/$', views.assistanship_thesis_approve, name='assistanship_thesis_approve'), + url(r'^assistanship_thesis_reject(?P\d+)/$', views.assistanship_thesis_reject, name='assistanship_thesis_reject'), + url(r'^assistanship_hod_approve(?P\d+)/$', views.assistanship_hod_approve, name='assistanship_hod_approve'), + url(r'^assistanship_hod_reject(?P\d+)/$', views.assistanship_hod_reject, name='assistanship_hod_reject'), + url(r'^assistanship_acad_approve(?P\d+)/$', views.assistanship_acad_approve, name='assistanship_acad_approve'), + url(r'^assistanship_acad_reject(?P\d+)/$', views.assistanship_acad_reject, name='assistanship_acad_reject'), + + + url(r'^othersPage/$', views.othersPage, name='othersPage'), + + url(r'^othersLeave/$', views.othersLeave, name='othersLeave'), + url(r'^othersGraduate/$', views.othersGraduate, name='othersGraduate'), + url(r'^othersAssistantship/$', views.othersAssistantship, name='othersAssistanship'), + url(r'^othersNoDues/$', views.othersNoDues, name='othersNoDues'), + + + +] + diff --git a/FusionIIIT/applications/otheracademic/views.py b/FusionIIIT/applications/otheracademic/views.py new file mode 100644 index 000000000..b099f2f78 --- /dev/null +++ b/FusionIIIT/applications/otheracademic/views.py @@ -0,0 +1,2312 @@ + +from django.shortcuts import render +from django.contrib import messages +from django.shortcuts import render, get_object_or_404, redirect,render + +from applications.globals.models import ExtraInfo, HoldsDesignation, Designation +from django.core import serializers +from django.template.defaulttags import csrf_token +from django.http import HttpResponse, HttpResponseRedirect, JsonResponse +from django.contrib.auth.decorators import login_required +from django.db import IntegrityError +from django.core import serializers +from django.contrib.auth.models import User +from timeit import default_timer as time +from notification.views import office_module_notif,file_tracking_notif +from django.http import JsonResponse +from django.views.decorators.csrf import csrf_exempt +from .models import LeaveFormTable,BonafideFormTableUpdated,GraduateSeminarFormTable,AssistantshipClaimFormStatusUpd,LeavePG,NoDues +from django.shortcuts import render, get_object_or_404 +from datetime import date +from applications.filetracking.models import * +from applications.filetracking.sdk.methods import * + +from notification.views import otheracademic_notif + + + +@login_required +def otheracademic(request): + """ + + + Description: + This function checks the user's programme (B.Tech, M.Tech, or PhD) to determine whether they are an undergraduate or postgraduate student. It then renders the corresponding academic page accordingly. + - If the user is an undergraduate student (B.Tech), the function renders the UG_page.html template. + - If the user is a postgraduate student (M.Tech or PhD), the function renders the PG_page.html template. + """ + if request.user.extrainfo.user_type != "student": + return render(request, "otheracademic/othersPage.html") + else : + user = get_object_or_404(User, username=request.user.username) + if user.extrainfo.student.programme == "B.Tech": + return render(request, "otheracademic/UG_page.html") + elif user.extrainfo.student.programme == "M.Tech" or user.extrainfo.student.programme == "PhD": + return render(request, "otheracademic/PG_page.html") + else: + return HttpResponse(request,"NOt Available For you") + +@login_required +def leaveform(request): + """ + View function for accessing the leave form page. + + """ + return render(request, 'otheracademic/leaveform.html') + + +@csrf_exempt # Exempt CSRF verification for this view +@login_required +def leave_form_submit(request): + """ + View function for submitting a leave form. + + Description: + This function handles form submission for leave requests, processes the data, and saves it to the database. + It also notifies the relevant authority about the new leave application. + """ + if request.method == 'POST': + # Extract data from the request + data = request.POST + file = request.FILES.get('related_document') + hodname = data.get('hod_credential') + + # Create a new LeaveFormTable instance and save it to the database + leave = LeaveFormTable.objects.create( + student_name=request.user.first_name+request.user.last_name, + roll_no=request.user.extrainfo, + date_from=data.get('date_from'), + date_to=data.get('date_to'), + leave_type=data.get('leave_type'), + upload_file=file, + address=data.get('address'), + purpose=data.get('purpose'), + date_of_application=date.today(), + approved=False, # Initially not approved + rejected=False, # Initially not rejected + hod=data.get('hod_credential') + ) + + leave_hod = User.objects.get(username=hodname) + receiver_value = User.objects.get(username=request.user.username) + receiver_value_designation = HoldsDesignation.objects.filter(user=receiver_value) + lis = list(receiver_value_designation) + obj = lis[0].designation + + + + file_id = create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=leave_hod, + receiver_designation="student", + src_module="otheracademic", + src_object_id=leave.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='ug_leave' + ) + + message = "A new leave application" + otheracademic_notif(request.user, leave_hod, 'ug_leave_hod', leave.id, 'student', message) + if leave: + messages.success(request, "You successfully submitted your form") + + return HttpResponseRedirect('/otheracademic/leaveform') + + +def leaveApproveForm(request): + """ + View function for accessing the leave approval form. + + Description: + This function retrieves leave requests for approval by the designated authority (e.g., HOD) and displays them in a list. + """ + user=get_object_or_404(User,username=request.user.username) + design=request.session['currentDesignationSelected'] + if 'HOD' in design : + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + leave_ids = [msg['src_object_id'] for msg in inbox if msg['subject'] == 'ug_leave'] + + form_data = LeaveFormTable.objects.filter(id__in=leave_ids) + return render(request, 'otheracademic/leaveformreciever.html', {'form_data': form_data}) + else: + return HttpResponse("Not available for you or You are not a HOD.") + + +def leaveStatus(request): + """ + View function for accessing the leave status page for the student. + + Description: + This function retrieves and displays the leave status of the currently logged-in student. + """ + form_data = LeaveFormTable.objects.filter(roll_no=request.user.extrainfo) + roll_no = request.user.username + return render(request, 'otheracademic/leaveStatus.html', {'form_data': form_data, 'roll_no' : roll_no}) + + +def leaveStatus_Dip(request): + """ + View function for track the record of leave applied. + + + """ + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + leave_ids = [msg['src_object_id'] for msg in inbox if msg['subject'] == 'ug_leave'] + + form_data = LeaveFormTable.objects.filter(id__in=leave_ids) + return render(request, 'otheracademic/leaveStatus_Dip.html', {'form_data': form_data}) + +@login_required +def approve_leave(request, leave_id): + """ + View function for approving a leave request. + + Parameters: + leave_id (int): The ID of the leave request to be approved. + + Description: + This function approves the leave request with the specified ID and updates its status accordingly. + """ + leave_entry = LeaveFormTable.objects.get(id=leave_id) + leave_entry.approved = True + leave_entry.save() + messages.success(request, "Successfully Approved") + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Leave Application Status approve/rejected' + otheracademic_notif(request.user,leave_receive, 'ug_leave_hod_approve', leave_entry.id, 'student', message) + + + + return redirect('/otheracademic/leaveApproveForm') + + +def reject_leave(request, leave_id): + """ + View function for rejecting a leave request. + + Parameters: + leave_id (int): The ID of the leave request to be rejected. + + Description: + This function rejects the leave request with the specified ID and updates its status accordingly. + """ + leave_entry = LeaveFormTable.objects.get(id=leave_id) + leave_entry.rejected = True + leave_entry.save() + messages.success(request, "Successfully Rejected") + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Leave Application Status approve/rejected' + otheracademic_notif(request.user,leave_receive, 'ug_leave_hod_approve', leave_entry.id, 'student', message) + + return redirect('/otheracademic/leaveApproveForm') + + + + + +# PG/MTECh +@login_required +def leavePG(request): + """ + View function for accessing the leave page for postgraduate students. + + Description: + This function checks if the logged-in user is a postgraduate student (M.Tech or PhD). If so, it renders the leavePG.html template, allowing them to apply for leave. + If the user is not a postgraduate student, it returns an "NOT AVAILABLE" message. + """ + user = get_object_or_404(User, username=request.user.username) + if user.extrainfo.student.programme == "M.Tech" or "PhD": + return render(request, 'otheracademic/leavePG.html') + else: + return HttpResponse("NOT AVAILABLE") + + +def leavePgSubmit(request): + """ + View function for submitting a leave form by postgraduate students. + + Description: + This function handles form submission for leave requests by postgraduate students. + It processes the data, saves it to the database, notifies the TA supervisor about the new leave application, + and redirects the user to the leave form page. + + -In this function hod is charfield ,basically it ask the credential in charfied but by using user.get.object() it return the foreign key of hod and after that we can proceed furthur. + this is used to overcome the problem of database data + """ + if request.method == 'POST': + data = request.POST + file = request.FILES.get('related_document') + hodname = data.get('hod_credential') + ta = data.get('ta_supervisor') + thesis = data.get('thesis_credential') + + leave = LeavePG.objects.create( + student_name=request.user.first_name+request.user.last_name, + roll_no=request.user.extrainfo, + programme=request.user.extrainfo.student.programme, + discipline=request.user.extrainfo.department, + Semester=data.get('Semester'), + date_from=data.get('date_from'), + date_to=data.get('date_to'), + date_of_application=date.today(), + upload_file=file, + address=data.get('address'), + purpose=data.get('purpose'), + leave_type=data.get('leave_type'), + ta_supervisor=data.get('ta_supervisor'), + mobile_no=data.get('mobile_no'), + parent_mobile_no=data.get('parent_mobile_no'), + alt_mobile_no=data.get('alt_mobile_no'), + ta_approved=False, + ta_rejected=False, + thesis_approved=False, + thesis_rejected=False, + hod_approved=False, + hod_rejected=False, + hod=hodname, + thesis_supervisor = thesis, + ) + + tasupervisor = User.objects.get(username=ta) + receiver_value = User.objects.get(username=request.user.username) + receiver_value_designation = HoldsDesignation.objects.filter(user=receiver_value) + lis = list(receiver_value_designation) + obj = lis[0].designation + + file_id = create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=tasupervisor, + receiver_designation="student", + src_module="otheracademic", + src_object_id=leave.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='pg_leave' + ) + + message = "A new leave application" + otheracademic_notif(request.user, tasupervisor,'pg_leave_ta', leave.id, 'student', message) + if leave: + messages.success(request, "You have successfully submitted your form") + + return HttpResponseRedirect('/otheracademic/leavePG') + + +def leaveApproveTA(request): + """ + View function for accessing the leave approval page for TA supervisors. + + Description: + This function retrieves leave requests for approval by the TA supervisor and displays them in a list. + """ + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + leave_ids = [msg['src_object_id'] for msg in inbox if msg['subject'] == 'pg_leave'] + + form_data = LeavePG.objects.filter(id__in=leave_ids) + roll_no = request.user.username + return render(request, 'otheracademic/leaveApproveTA.html', {'form_data': form_data,'roll_no' : roll_no}) + + +def approve_leave_ta(request, leave_id): + """ + View function for approving a leave request by TA supervisor. + + Description: + This function approves the leave request with the specified ID by TA supervisor and updates its status accordingly and forwarded to hod. + """ + leave_entry = get_object_or_404(LeavePG, id=leave_id) + leave_entry.ta_approved = True + leave_entry.save() + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Leave Application Status approve/rejected' + otheracademic_notif(request.user,leave_receive, 'pg_leave_ta_approve', leave_entry.id, 'student', message) + + + + receiver_value = User.objects.get(username=request.user.username) + receiver_value_designation = HoldsDesignation.objects.filter(user=receiver_value) + lis = list(receiver_value_designation) + obj = lis[0].designation + + + file_id_forward = create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=leave_entry.thesis_supervisor, + receiver_designation="student", + src_module="otheracademic", + src_object_id=leave_id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='pg_leave' + ) + + message = "A new leave application forwarded of PG student" + thesis_user = User.objects.get(username=leave_entry.thesis_supervisor) + otheracademic_notif(request.user, thesis_user, 'pg_leave_thesis', leave_id, 'student', message) + + + return redirect('/otheracademic/leaveApproveTA') # Redirect to appropriate page after approval + + +def reject_leave_ta(request, leave_id): + """ + View function for rejecting a leave request by TA supervisor. + + Description: + This function rejects the leave request with the specified ID by TA supervisor and updates its status accordingly. + """ + leave_entry = LeavePG.objects.get(id=leave_id) + leave_entry.ta_rejected = True + leave_entry.save() + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Leave Application Status approve/rejected' + otheracademic_notif(request.user,leave_receive, 'pg_leave_ta_approve', leave_entry.id, 'student', message) + + + return redirect('/otheracademic/leaveApproveTA') # Redirect to appropriate page after rejection + +def leaveApproveThesis(request): + """ + View function for accessing the leave approval page for TA supervisors. + + Description: + This function retrieves leave requests for approval by the TA supervisor and displays them in a list. + """ + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + leave_ids = [msg['src_object_id'] for msg in inbox if msg['subject'] == 'pg_leave'] + + form_data = LeavePG.objects.filter(id__in=leave_ids) + roll_no = request.user.username + return render(request, 'otheracademic/leaveApproveThesis.html', {'form_data': form_data, 'roll_no' : roll_no}) + + +def approve_leave_thesis(request, leave_id): + """ + View function for approving a leave request by TA supervisor. + + Description: + This function approves the leave request with the specified ID by TA supervisor and updates its status accordingly and forwarded to hod. + """ + leave_entry = LeavePG.objects.get(id=leave_id) + leave_entry.thesis_approved = True + leave_entry.save() + + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Leave Application Status approve/rejected' + otheracademic_notif(request.user,leave_receive, 'pg_leave_ta_approve', leave_entry.id, 'student', message) + + + receiver_value = User.objects.get(username=request.user.username) + receiver_value_designation = HoldsDesignation.objects.filter(user=receiver_value) + lis = list(receiver_value_designation) + obj = lis[0].designation + leave_entry = get_object_or_404(LeavePG, id=leave_id) + + file_id_forward = create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=leave_entry.hod, + receiver_designation="student", + src_module="otheracademic", + src_object_id=leave_id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='pg_leave' + ) + message = "A new leave application" + hod_user = User.objects.get(username=leave_entry.hod) + otheracademic_notif(request.user, hod_user, 'pg_leave_hod', leave_id, 'student', message) + + + return redirect('/otheracademic/leaveApproveThesis') # Redirect to appropriate page after approval + + +def reject_leave_thesis(request, leave_id): + """ + View function for rejecting a leave request by TA supervisor. + + Description: + This function rejects the leave request with the specified ID by TA supervisor and updates its status accordingly. + """ + leave_entry = LeavePG.objects.get(id=leave_id) + leave_entry.thesis_rejected = True + leave_entry.save() + + + return redirect('/otheracademic/leaveApproveThesis') # Redirect to appropriate page after rejection + + +def leaveApproveHOD(request): + """ + View function for accessing the leave approval page for HOD. + + Description: + This function retrieves leave requests for approval by the HOD and displays them in a list. + """ + user=get_object_or_404(User,username=request.user.username) + design=request.session['currentDesignationSelected'] + if 'HOD' in design : + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + leave_ids = [msg['src_object_id'] for msg in inbox if msg['subject'] == 'pg_leave'] + form_data = LeavePG.objects.filter(id__in=leave_ids) + roll_no = request.user.username + return render(request, 'otheracademic/leaveApproveHOD.html', {'form_data': form_data, 'roll_no' : roll_no}) + else: + return HttpResponse("Not Avaible For You...OR You are not the HOD") + +def approve_leave_hod(request, leave_id): + """ + View function for approving a leave request by HOD. + + Description: + This function approves the leave request with the specified ID by HOD and updates its status accordingly. + """ + leave_entry = LeavePG.objects.get(id=leave_id) + leave_entry.hod_approved = True + leave_entry.save() + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Leave Application Status approve/rejected' + otheracademic_notif(request.user,leave_receive, 'pg_leave_ta_approve', leave_entry.id, 'student', message) + + + return redirect('/otheracademic/leaveApproveHOD') # Redirect to appropriate page after approval + + +def reject_leave_hod(request, leave_id): + """ + View function for rejecting a leave request by HOD. + + Description: + This function rejects the leave request with the specified ID by HOD and updates its status accordingly. + """ + leave_entry = LeavePG.objects.get(id=leave_id) + leave_entry.hod_rejected = True + + leave_entry.save() + + return redirect('/otheracademic/leaveApproveHOD') # Redirect to appropriate page after rejection + + +def leaveStatusPG(request): + """ + View function for accessing the leave status page for postgraduate students. + + Description: + This function retrieves and displays the leave status of postgraduate students. + """ + form_data = LeavePG.objects.all() + roll_no = request.user.username + return render(request, 'otheracademic/leaveStatusPG.html', {'form_data': form_data, 'roll_no': roll_no}) + + +def leaveStatusPG_Dip(request): + """ + View function for accessing the leave logged data of PG . + + Description: + This function retrieves and displays the leave logged data of PG leave for future reference. + """ + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + leave_ids = [msg['src_object_id'] for msg in inbox if msg['subject'] == 'pg_leave'] + + form_data = LeavePG.objects.filter(id__in=leave_ids) + return render(request, 'otheracademic/leaveStatusPG_Dip.html', {'form_data': form_data}) + + + + + + + + +def graduateseminar(request): + """ + This function is used to log the graduate seminar form and show the status. + + """ + user=get_object_or_404(User,username=request.user.username) + design=request.session['currentDesignationSelected'] + if 'deptadmin' in design : + return render(request,'otheracademic/graduateseminarForm.html') + else : + return HttpResponse("Not Available for You") + +def graduate_form_submit(request): + if request.method == 'POST': + # Extract data from the request + data = request.POST + # file = request.FILES.get('related_document') + + + # Create a new LeaveFormTable instance and save it to the database + graduate=GraduateSeminarFormTable.objects.create( + + roll_no=data.get('roll_no'), + semester=data.get('semester'), + date_of_seminar=data.get('date_of_seminar'), + + ) + graduate.save() + return redirect('/otheracademic/graduateseminar') + +def graduate_status(request): + + form_data = GraduateSeminarFormTable.objects.all() + roll_no = request.user.username + return render(request, 'otheracademic/graduateSeminarStatus.html',{'form_data' : form_data, 'roll_no' : roll_no }) + +def graduateSeminarStatus_Dip(request): + receiver_value = User.objects.get(username=request.user.username) + receiver_value_designation= HoldsDesignation.objects.filter(user=receiver_value) + lis = list(receiver_value_designation) + obj=lis[0].designation + + + if obj : + form_data = GraduateSeminarFormTable.objects.all() + return render(request, 'otheracademic/graduateSeminarStatus_Dip.html',{'form_data' : form_data }) + else : + return HttpResponse("Not Available") + + + + + + + + + + +def bonafide(request): + """ + This function is used for solve the problem of Bonafied.In this Student apply for the bonafide . + + + + + + """ + return render(request,'otheracademic/bonafideForm.html') + + + + + +def bonafide_form_submit(request): + """ + Bonafide form submitted to acadadmin + """ + if request.method == 'POST': + # Extract data from the request + data = request.POST + file = request.FILES.get('related_document') + + + # Create a new LeaveFormTable instance and save it to the database + bonafide=BonafideFormTableUpdated.objects.create( + student_names=request.user.first_name+request.user.last_name, + roll_nos=request.user.extrainfo, + branch_types = data.get('branch'), + semester_types = data.get('semester'), + purposes = data.get('purpose'), + date_of_applications = data.get('date_of_application'), + approve=False, # Initially not approved + reject=False, # Initially not rejected + download_file = "not available", + ) + messages.success(request,'form submitted successfully') + bonafide.save() + acad_admin_des_id = Designation.objects.get(name="acadadmin") + user_ids = HoldsDesignation.objects.filter(designation_id=acad_admin_des_id.id).values_list('user_id', flat=True) + # print(user_ids) + # print(user_ids[0]) + # acad_admins = ExtraInfo.objects.get(user_id=user_ids[0]) + # # print(acad_admins) + # user=ExtraInfo.objects.get(pk=acad_admins.id) + bonafide_receiver = User.objects.get(id=user_ids[0]) + message='A Bonafide applicationn received' + otheracademic_notif(request.user,bonafide_receiver, 'bonafide', 1, 'student', message) + return HttpResponseRedirect('/otheracademic/bonafide') + + +def bonafideApproveForm(request): + + """ + Bonafide form approveform where it got option to accept and reject the application + """ + user=get_object_or_404(User,username=request.user.username) + design=request.session['currentDesignationSelected'] + + if 'acadadmin' in design : + form_data = BonafideFormTableUpdated.objects.all() + return render(request, 'otheracademic/bonafideApprove.html', {'form_data': form_data}) + else: + return HttpResponse("Not available For You") + +def approve_bonafide(request, leave_id): + + """ + Approve Bonafide form + """ + file = request.FILES.get('related_document') + leave_entry = BonafideFormTableUpdated.objects.get(id=leave_id) + leave_entry.approve = True + leave_entry.save() + bonafide_aceptor = User.objects.get(username=leave_entry.roll_nos_id) + message='A Bonafide uploaded' + otheracademic_notif(request.user,bonafide_aceptor, 'bonafide_accept', 1, 'student', message) + return redirect('/otheracademic/bonafideApproveForm') # Redirect to appropriate page after approval + +def reject_bonafide(request, leave_id): + """ + Reject Bonafide Form + """ + leave_entry = BonafideFormTableUpdated.objects.get(id=leave_id) + leave_entry.reject = True + leave_entry.save() + bonafide_aceptor = User.objects.get(username=leave_entry.roll_no_id) + message='A Bonafide rejected' + otheracademic_notif(request.user,bonafide_aceptor, 'bonafide_accept', 1, 'student', message) + return redirect('/otheracademic/bonafideApproveForm') # Redirect to appropriate page after rejection + +def bonafideStatus(request): + """ + Bonafide Status shown to student with option of download + """ + + form_data = BonafideFormTableUpdated.objects.all() + roll_no = request.user.username + return render(request, 'otheracademic/bonafideStatus.html',{'form_data' : form_data, 'roll_no' : roll_no }) + + +# views.py + + + + +def upload_file(request, entry_id): + + """ + Bonafide uploaded by acadadmin + """ + if request.method == 'POST' and request.FILES.get('related_document'): + related_document = request.FILES['related_document'] + + # Assuming you want to update the 'download_file' field of your model + bonafide_entry = BonafideFormTableUpdated.objects.get(id=entry_id) + bonafide_entry.download_file = related_document + bonafide_entry.save() + + return HttpResponse("File Uploaded Successfuly") + else: + return HttpResponse("No File Attached") + + + + + +def nodues(request): + """ + No Dues Form where student can apply for no dues + """ + return render(request,'otheracademic/noduesverification.html') + + +def PG_page(request): + return render(request,'otheracademic/PG_page.html') + + +def nodues_status(request): + form_data = NoDues.objects.all() + roll_no = request.user.username + print(form_data) + return render(request, 'otheracademic/nodues_status.html',{'form_data' : form_data, 'roll_no' : roll_no }) + + +def noduesStatus_acad(request): + form_data = NoDues.objects.all() + return render(request, 'otheracademic/noduesStatus_acad.html',{'form_data' : form_data }) + + +def nodues_apply(request): + form_data = NoDues.objects.all() + roll_no = request.user.username + return render(request,'otheracademic/nodues_apply.html', {'form_data' : form_data, 'roll_no' : roll_no}) + + + +def update_dues_status(request): + if request.method == 'POST': + roll_no = request.POST.get('roll_no') + clear = request.POST.get('clear') # 'true' if clear, 'false' if not clear + # Convert clear to boolean + clear = clear.lower() == 'true' + + # Update clearance status in the database + try: + student = NoDues.objects.get(roll_no=roll_no) + if clear: + student.clear_status = True + student.not_clear_status = False + else: + student.clear_status = False + student.not_clear_status = True + student.save() + return JsonResponse({'message': 'Clearance status updated successfully'}, status=200) + except NoDues.DoesNotExist: + return JsonResponse({'error': 'Student not found'}, status=404) + else: + return JsonResponse({'error': 'Invalid request method'}, status=405) + + + + +@csrf_exempt # Exempt CSRF verification for this view +def submit_nodues_form(request): + + """ + Submit the No Dues form for a student + description:- + + There are many actors in this problem like authory of:- + library, + mess, + hostel, + Physics Lab, + ECE Lab, + Computer Centre, + mechatronics_lab, + Vlsi, + Design, + Bank, + BTP, + Placement cell etc....... + + Students apply this form and this forwarded to all this actor to approve/reject + + + There is also example Bank_nodues_not for those student whose in first time application is rejected and when they go to second time it will be approved by them. + + + """ + if request.method == 'POST': + # Extract data from the request + data = request.POST + hostel_credential = data.get('hostel_credential'), + bank_credential = data.get('bank_credential'), + btp_credential = data.get('btp_credential'), + cse_credential = data.get('cse_credential'), + design_credential = data.get('design_credential'), + acad_credential = data.get('acad_credential'), + ece_credential = data.get('ece_credential'), + library_credential = data.get('library_credential'), + me_credential = data.get('me_credential'), + mess_credential = data.get('mess_credential'), + physics_credential = data.get('physics_credential'), + discipline_credential = data.get('discipline_credential'), + + + + nodues=NoDues.objects.create( + roll_no=request.user.extrainfo, + name=data.get('name'), + library_clear=False, + library_notclear=False, + hostel_clear=False, + hostel_notclear=False, + mess_clear=False, + mess_notclear=False, + ece_clear=False, + ece_notclear=False, + physics_lab_clear=False, + physics_lab_notclear=False, + mechatronics_lab_clear=False, + mechatronics_lab_notclear=False, + cc_clear=False, + cc_notclear=False, + workshop_clear=False, + workshop_notclear=False, + signal_processing_lab_clear=False, + signal_processing_lab_notclear=False, + vlsi_clear=False, + vlsi_notclear=False, + design_studio_clear=False, + design_studio_notclear=False, + design_project_clear=False, + design_project_notclear=False, + bank_clear=False, + bank_notclear=False, + icard_dsa_clear=False, + icard_dsa_notclear=False, + account_clear=False, + account_notclear=False, + btp_supervisor_clear=False, + btp_supervisor_notclear=False, + discipline_office_clear=False, + discipline_office_notclear=False, + student_gymkhana_clear=False, + student_gymkhana_notclear=False, + # discipline_office_dsa_clear=False, + # discipline_office_dsa_notclear=False, + alumni_clear=False, + alumni_notclear=False, + placement_cell_clear=False, + placement_cell_notclear=False, + + hostel_credential = data.get('hostel_credential'), + bank_credential = data.get('bank_credential'), + btp_credential = data.get('btp_credential'), + cse_credential = data.get('cse_credential'), + design_credential = data.get('design_credential'), + acad_credential = data.get('acad_credential'), + ece_credential = data.get('ece_credential'), + library_credential = data.get('library_credential'), + me_credential = data.get('me_credential'), + mess_credential = data.get('mess_credential'), + physics_credential = data.get('physics_credential'), + discipline_credential = data.get('discipline_credential'), + + acad_admin_float = False, + + ) + hostel_receiver=User.objects.get(username=data.get('hostel_credential')) + + receiver_value = User.objects.get(username=request.user.username) + receiver_value_designation = HoldsDesignation.objects.filter(user=receiver_value) + lis = list(receiver_value_designation) + obj = lis[0].designation + file_hostel = create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=hostel_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new hostel application of no dues" + otheracademic_notif(request.user,hostel_receiver, 'hostel_nodues', nodues.id, 'student', message) + + + #bnk_receiver + bank_receiver=User.objects.get(username=data.get('bank_credential')) + file_bank= create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=bank_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new bank application of no dues" + otheracademic_notif(request.user,bank_receiver, 'bank_nodues', nodues.id, 'student', message) + + #btp_receiver + btp_receiver=User.objects.get(username=data.get('btp_credential')) + file_bank= create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=btp_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new btp application of no dues" + otheracademic_notif(request.user,btp_receiver, 'btp_nodues', nodues.id, 'student', message) + + #cse_receiver + cse_receiver=User.objects.get(username=data.get('cse_credential')) + file_bank= create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=bank_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new cse application of no dues" + otheracademic_notif(request.user,cse_receiver, 'cse_nodues', nodues.id, 'student', message) + #design_receiver + design_receiver=User.objects.get(username=data.get('design_credential')) + file_bank= create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=design_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new design application of no dues" + otheracademic_notif(request.user,design_receiver, 'design_nodues', nodues.id, 'student', message) + + #acad_receiver + acad_receiver=User.objects.get(username=data.get('acad_credential')) + file_bank= create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=acad_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new acad application of no dues" + otheracademic_notif(request.user,acad_receiver, 'acad_nodues', nodues.id, 'student', message) + + #ece_receiver + ece_receiver=User.objects.get(username=data.get('ece_credential')) + file_bank= create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=ece_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new ece application of no dues" + otheracademic_notif(request.user,ece_receiver, 'ece_nodues', nodues.id, 'student', message) + + #library_receiver + library_receiver=User.objects.get(username=data.get('library_credential')) + file_bank= create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=library_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new library application of no dues" + otheracademic_notif(request.user,library_receiver, 'library_nodues', nodues.id, 'student', message) + # me_receiver + me_receiver=User.objects.get(username=data.get('me_credential')) + file_bank= create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=me_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new ME application of no dues" + otheracademic_notif(request.user,me_receiver, 'me_nodues', nodues.id, 'student', message) + + #mess_receiver + mess_receiver=User.objects.get(username=data.get('mess_credential')) + file_bank= create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=mess_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new mess application of no dues" + otheracademic_notif(request.user,mess_receiver, 'mess_nodues', nodues.id, 'student', message) + + #physics_receiver + physics_receiver=User.objects.get(username=data.get('physics_credential')) + file_bank= create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=physics_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new physics application of no dues" + otheracademic_notif(request.user,physics_receiver, 'physics_nodues', nodues.id, 'student', message) + + + #discipline_receiver + discipline_receiver=User.objects.get(username=data.get('discipline_credential')) + file_bank= create_file( + uploader=request.user.username, + uploader_designation=obj, + receiver=discipline_receiver, + receiver_designation="student", + src_module="otheracademic", + src_object_id=nodues.id, + file_extra_JSON={"value": 2}, + attached_file=None, + subject='no_dues' + ) + + message = "A new discipline application of no dues" + otheracademic_notif(request.user,discipline_receiver, 'discipline_nodues', nodues.id, 'student', message) + messages.success(request,'You successfully applied for no_dues') + + + + # print(roll_no_id) + return HttpResponseRedirect('/otheracademic/nodues_apply') + + + + +def approve_BTP(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.btp_supervisor_clear= True + leave_entry.btp_supervisor_notclear = False + btp_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Btp nodues approved" + otheracademic_notif(request.user,btp_receiver , 'nodues_approve', leave_entry.id, "student", message) + + # Display success message + messages.success(request, "Successfully approved and forwarded.") + + leave_entry.save() + return redirect('/otheracademic/BTP_nodues') # Red + +def approve_BTP_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.btp_supervisor_clear= True + leave_entry.btp_supervisor_notclear = False + leave_entry.save() + return redirect('/otheracademic/BTP_nodues_not') # Red + + + +def reject_BTP(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.btp_supervisor_clear= False + leave_entry.btp_supervisor_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Btp nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/BTP_nodues') # Red + + + + + +def approve_bank(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.bank_clear= True + leave_entry.bank_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "bank nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Bank_nodues') # Red + +def approve_bank_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.bank_clear= True + leave_entry.bank_notclear = False + leave_entry.save() + return redirect('/otheracademic/Bank_nodues_not') # Red + + + +def reject_bank(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.bank_clear= False + leave_entry.bank_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "bank nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + + leave_entry.save() + return redirect('/otheracademic/Bank_nodues') # Red + +def approve_CSE(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.cc_clear= True + leave_entry.cc_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Cse nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/CSE_nodues') # Red + +def approve_CSE_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.cc_clear= True + leave_entry.cc_notclear = False + leave_entry.save() + return redirect('/otheracademic/CSE_nodues_not') # Red + + + +def reject_CSE(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.cc_clear= False + leave_entry.cc_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Cse nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/CSE_nodues') # Red + +def approve_design_project(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.design_project_clear= True + leave_entry.design_project_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Design project nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Design_nodues') # Red + +def approve_design_project_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.design_project_clear= True + leave_entry.design_project_notclear = False + leave_entry.save() + return redirect('/otheracademic/Design_nodues_not') # Red + + + +def reject_design_project(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.design_project_clear= False + leave_entry.design_project_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Design project nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Design_nodues') # Red + +def approve_design_studio(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.design_studio_clear= True + leave_entry.design_studio_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Design studio nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Design_nodues') # Red + +def approve_design_studio_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.design_studio_clear= True + leave_entry.design_studio_notclear = False + leave_entry.save() + return redirect('/otheracademic/Design_nodues_not') # Red + +def reject_design_studio(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.design_studio_clear= False + leave_entry.design_studio_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Design studio nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Design_nodues') # Red + + + +def approve_icard(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.icard_dsa_clear= True + leave_entry.icard_dsa_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "icard nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/dsa_nodues') # Red + +def approve_icard_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.icard_dsa_clear= True + leave_entry.icard_dsa_notclear = False + leave_entry.save() + return redirect('/otheracademic/dsa_nodues_not') # Red + + + +def reject_icard(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.icard_dsa_clear= False + leave_entry.icard_dsa_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "icard nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/dsa_nodues') # Red + +def approve_placement(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.placement_cell_clear= True + leave_entry.placement_cell_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "placement nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/dsa_nodues') # Red + +def approve_placement_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.placement_cell_clear= True + leave_entry.placement_cell_notclear = False + leave_entry.save() + return redirect('/otheracademic/dsa_nodues_not') # Red + + + +def reject_placement(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.placement_cell_clear= False + leave_entry.placement_cell_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "placement nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/dsa_nodues') # Red + +def approve_account(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.account_clear= True + leave_entry.account_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "account nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Bank_nodues') # Red + +def approve_account_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.account_clear= True + leave_entry.account_notclear = False + leave_entry.save() + return redirect('/otheracademic/Bank_nodues_not') # Red + + + +def reject_account(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.account_clear= False + leave_entry.account_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "account nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Bank_nodues') # Red + +def approve_alumni(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.alumni_clear= True + leave_entry.alumni_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "alumni nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/dsa_nodues') # Realumni + +def approve_alumni_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.alumni_clear= True + leave_entry.alumni_notclear = False + leave_entry.save() + return redirect('/otheracademic/dsa_nodues_not') # Realumni + + + +def reject_alumni(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.alumni_clear= False + leave_entry.alumni_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "alumni nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/dsa_nodues') # Red + +def approve_gym(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.student_gymkhana_clear= True + leave_entry.student_gymkhana_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "gym nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/dsa_nodues') # Red + +def approve_gym_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.student_gymkhana_clear= True + leave_entry.student_gymkhana_notclear = False + leave_entry.save() + return redirect('/otheracademic/dsa_nodues_not') # Red + + + +def reject_gym(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.student_gymkhana_clear= False + leave_entry.student_gymkhana_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "gym nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/dsa_nodues') # Red + +def approve_discipline(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.discipline_office_clear= True + leave_entry.discipline_office_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Discipline office nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/discipline_nodues') # Red + +def approve_discipline_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.discipline_office_clear= True + leave_entry.discipline_office_notclear = False + leave_entry.save() + return redirect('/otheracademic/discipline_nodues_not') # Red + + + +def reject_discipline(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.discipline_office_clear= False + leave_entry.discipline_office_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Discipline office nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/dsa_nodues') # Red + +def approve_signal(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.signal_processing_lab_clear= True + leave_entry.signal_processing_lab_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "signal nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Ece_nodues') # Realumni + +def approve_signal_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.signal_processing_lab_clear= True + leave_entry.signal_processing_lab_notclear = False + leave_entry.save() + return redirect('/otheracademic/Ece_nodues_not') # Realumni + + + +def reject_signal(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.signal_processing_lab_clear= False + leave_entry.signal_processing_lab_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "signal nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Ece_nodues') # Red + + +def approve_vlsi(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.vlsi_clear= True + leave_entry.vlsi_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "vlsi nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Ece_nodues') # Realumni + +def approve_vlsi_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.vlsi_clear= True + leave_entry.vlsi_notclear = False + leave_entry.save() + return redirect('/otheracademic/Ece_nodues_not') # Realumni + + + +def reject_vlsi(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.vlsi_clear= False + leave_entry.vlsi_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Vlsi nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Ece_nodues') # Red + +def approve_ece(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.ece_clear= True + leave_entry.ece_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Ece nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Ece_nodues') # Realumni + +def approve_ece_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.ece_clear= True + leave_entry.ece_notclear = False + leave_entry.save() + return redirect('/otheracademic/Ece_nodues_not') # Realumni + + + +def reject_ece(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.ece_clear= False + leave_entry.ece_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "Ece nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Ece_nodues') # Red + + +def approve_hostel(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.hostel_clear= True + leave_entry.hostel_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "hostel nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/hostel_nodues') # Realumni + +def approve_hostel_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.hostel_clear= True + leave_entry.hostel_notclear = False + leave_entry.save() + return redirect('/otheracademic/hostel_nodues_not') # Realumni + + + +def reject_hostel(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.hostel_clear= False + leave_entry.hostel_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "hostel nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/hostel_nodues') # Red + + + +def approve_library(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.library_clear= True + leave_entry.library_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "library nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/library_nodues') # Realumni + +def approve_library_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.library_clear= True + leave_entry.library_notclear = False + leave_entry.save() + return redirect('/otheracademic/library_nodues_not') # Realumni + + + +def reject_library(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.library_clear= False + leave_entry.library_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "library nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/library_nodues') # Red + + +def approve_workshop(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.workshop_clear= True + leave_entry.workshop_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "workshop nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/ME_nodues') # Realumni + +def approve_workshop_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.workshop_clear= True + leave_entry.workshop_notclear = False + leave_entry.save() + return redirect('/otheracademic/ME_nodues_not') # Realumni + + + +def reject_workshop(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.workshop_clear= False + leave_entry.workshop_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "workshop nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/ME_nodues') # Red + + +def approve_mecha(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.mechatronics_lab_clear= True + leave_entry.mechatronics_lab_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "mecha nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/ME_nodues') # Realumni + +def approve_mecha_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.mechatronics_lab_clear= True + leave_entry.mechatronics_lab_notclear = False + leave_entry.save() + return redirect('/otheracademic/ME_nodues_not') # Realumni + + + +def reject_mecha(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.mechatronics_lab_clear= False + leave_entry.mechatronics_lab_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "mecha nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/ME_nodues') # Red + + +def approve_mess(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.mess_clear= True + leave_entry.mess_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "mess nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/mess_nodues') # Realumni + +def approve_mess_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.mess_clear= True + leave_entry.mess_notclear = False + leave_entry.save() + return redirect('/otheracademic/mess_nodues_not') # Realumni + + + +def reject_mess(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.mess_clear= False + leave_entry.mess_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "mess nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/mess_nodues') # Red + +def approve_physics(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.physics_lab_clear= True + leave_entry.physics_lab_notclear = False + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "physics nodues approved" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Physics_nodues') # Realumni + +def approve_physics_not(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.physics_lab_clear= True + leave_entry.physics_lab_notclear = False + leave_entry.save() + return redirect('/otheracademic/Physics_nodues_not') # Realumni + + + +def reject_physics(request, no_dues_id): + leave_entry = NoDues.objects.get(id=no_dues_id) + leave_entry.physics_lab_clear= False + leave_entry.physics_lab_notclear = True + nodues_receiver=User.objects.get(username=leave_entry.roll_no_id) + message = "physics nodues rejected" + otheracademic_notif(request.user,nodues_receiver , 'nodues_status', leave_entry.id, "student", message) + leave_entry.save() + return redirect('/otheracademic/Physics_nodues') # Red + + +def Bank_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + # form_data=NoDues.objects.all() + return render(request,'otheracademic/Bank_nodues.html',{'form_data': form_data}) + +def Bank_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/Bank_nodues_not.html',{'form_data': form_data}) + +def BTP_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/BTP_nodues.html',{'form_data': form_data}) + +def BTP_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/BTP_nodues_not.html',{'form_data': form_data}) + +def CSE_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/CSE_nodues.html',{'form_data': form_data}) + +def CSE_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/CSE_nodues_not.html',{'form_data': form_data}) + + +def Design_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/Design_nodues.html',{'form_data': form_data}) + +def Design_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/Design_nodues_not.html',{'form_data': form_data}) + + +def dsa_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/dsa_nodues.html',{'form_data': form_data}) + +def dsa_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/dsa_nodues_not.html',{'form_data': form_data}) + + +def Ece_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/Ece_nodues.html',{'form_data': form_data}) + +def Ece_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/Ece_nodues_not.html',{'form_data': form_data}) + + +def hostel_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/hostel_nodues.html',{'form_data': form_data}) + +def hostel_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/hostel_nodues_not.html',{'form_data': form_data}) + + +def ME_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/ME_nodues.html',{'form_data': form_data}) + +def ME_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/ME_nodues_not.html',{'form_data': form_data}) + + +def mess_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/mess_nodues.html',{'form_data': form_data}) + +def mess_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/mess_nodues_not.html',{'form_data': form_data}) + + +def Physics_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/Physics_nodues.html',{'form_data': form_data}) + +def Physics_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/Physics_nodues_not.html',{'form_data': form_data}) + +def discipline_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/Discipline_nodues.html',{'form_data': form_data}) + +def discipline_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/Discipline_nodues_not.html',{'form_data': form_data}) + +def library_nodues(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/library_nodues.html',{'form_data': form_data}) + +def library_nodues_not(request): + inbox=view_inbox(username=request.user.username,designation="student",src_module="otheracademic") + leave_ids=[msg ['src_object_id'] for msg in inbox if msg['subject']=='no_dues'] + + form_data = NoDues.objects.filter(id__in=leave_ids) + return render(request,'otheracademic/library_nodues_not.html',{'form_data': form_data}) + + + + + + + +def noduesStatus_acad(request): + if(request.user.username == "acadadmin"): + form_data = NoDues.objects.all() + return render(request, 'otheracademic/noduesStatus_acad.html',{'form_data' : form_data }) + else : + return HttpResponse("Not Available for you.") + +def nodues_apply(request): + return render(request,'otheracademic/nodues_apply.html') + + + +def update_dues_status(request): + if request.method == 'POST': + roll_no = request.POST.get('roll_no') + clear = request.POST.get('clear') # 'true' if clear, 'false' if not clear + # Convert clear to boolean + clear = clear.lower() == 'true' + + # Update clearance status in the database + try: + student = NoDues.objects.get(roll_no=roll_no) + if clear: + student.clear_status = True + student.not_clear_status = False + else: + student.clear_status = False + student.not_clear_status = True + student.save() + return JsonResponse({'message': 'Clearance status updated successfully'}, status=200) + except NoDues.DoesNotExist: + return JsonResponse({'error': 'Student not found'}, status=404) + else: + return JsonResponse({'error': 'Invalid request method'}, status=405) + +#assistantship + + + +@login_required +def assistantship(request): + + """ + This function solve the problem of assistantship apply by mtech and phd students for thhe monthly stipend. + The form firstly approved by TA_supervisor ---->then it forwarded to---->Thesis_Supervisor------>HOD------>acadadmin + After approval status is shown to the student + + + + + """ + user = get_object_or_404(User, username=request.user.username) + if user.extrainfo.student.programme == 'M.Tech' or 'PhD': + return render(request, 'otheracademic/assistantshipclaimform.html') + else: + return HttpResponse("NOt available") +@login_required +def assistantship_form_submission(request): + a=get_object_or_404(User,username=request.user.username) + y=ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() + # num=1 + # comp_id=y.id + if request.method == 'POST': + # Retrieve form data + print(request.POST) + student_name = request.POST.get('student_name') + roll_no = request.POST.get('roll_no') + discipline = request.POST.get('discipline') + date_from = request.POST.get('date_from') + date_to = request.POST.get('date_to') + bank_account_no = request.POST.get('bank_account_no') + signature = request.FILES.get('signature') + applicability = request.POST.get('applicability') + ta_supervisor = request.POST.get('ta_supervisor') + thesis_supervisor = request.POST.get('thesis_supervisor') + date_applied = request.POST.get('date_of_application'), + hod=request.POST.get('hod_credential') + + + current_date = date.today() + + + + assistant = AssistantshipClaimFormStatusUpd.objects.create(student_name=request.user.first_name+request.user.last_name,roll_no=request.user.extrainfo, + discipline=discipline, + dateFrom=date_from, + dateTo=date_to, + bank_account=bank_account_no, + student_signature=signature, + dateApplied= current_date , + ta_supervisor=ta_supervisor, + thesis_supervisor=thesis_supervisor, + applicability=applicability, + TA_approved=False, + TA_rejected=False, + Ths_approved=False, + Ths_rejected=False, + HOD_approved=False, + HOD_rejected=False, + Acad_approved=False, + Acad_rejected=False, + hod=hod + + + + ) + + current_user=get_object_or_404(User,username=request.user.username) + ta_supervisor_id=User.objects.get(username=ta_supervisor) + ts=User.objects.get(username=thesis_supervisor) + + user_details=User.objects.get(id=y.user_id) + des=HoldsDesignation.objects.filter(user=user_details).all() + file_id = create_file(uploader = request.user.username, uploader_designation=des[0].designation, receiver =ta_supervisor, receiver_designation = "student", src_module = "otheracademic", src_object_id = assistant.id, file_extra_JSON = {"value": 2}, attached_file = None,subject="assistantship") + print(request.user) + print(file_id) + message="A new assistantship application raised" + otheracademic_notif(request.user,ta_supervisor_id ,'ast_ta',assistant.id,"student",message) + # if date_from>=date_to: + # messages.warning(request,"enter") + # return HttpResponseRedirect('/otheracademic/assistantship') + # Redirect to a success page or return a success message + messages.success(request,"Your form is successfully submitted") + return HttpResponseRedirect('/otheracademic/assistantship') # Replace '/otheracademic/assistantship' with the actual URL you want to redirect to + + else: + # Return an error response for invalid request method + return HttpResponse('Invalid request method') + + + + + + +def assistantship_form_approval(request): + # Retrieve data from the database + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + # print(inbox) + # print(request.user.username) + + # Find the src_object_id where subject is 'assistantship' + assistantship_ids = [msg['src_object_id'] for msg in inbox if msg['subject'] == 'assistantship'] + + # Filter form_data queryset based on the ids found + form_data = AssistantshipClaimFormStatusUpd.objects.filter(id__in=assistantship_ids) + roll_no = request.user.username + return render(request, 'otheracademic/assistantship_approval.html', {'form_data': form_data, 'roll_no' : roll_no}) + +def assistantship_thesis(request): + # Retrieve data from the database + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + + assistantship_ids = [msg['src_object_id' ] for msg in inbox if msg['subject'] == 'assistantship'] + + # Filter form_data queryset based on the ids found + form_data = AssistantshipClaimFormStatusUpd.objects.filter(id__in=assistantship_ids) + roll_no = request.user.username + return render(request, 'otheracademic/thesis_supervisor_approve.html', {'form_data': form_data, 'roll_no' : roll_no}) + + +def assistantship_hod(request): + # Retrieve data from the database + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + print(inbox) + assistantship_ids = [msg['src_object_id'] for msg in inbox if msg['subject'] == 'assistantship'] + + # Filter form_data queryset based on the ids found + form_data = AssistantshipClaimFormStatusUpd.objects.filter(id__in=assistantship_ids) + roll_no = request.user.username + return render(request, 'otheracademic/hod_approval.html', {'form_data': form_data, 'roll_no' : roll_no}) + + + + +def assistantship_status(request): + form_data = AssistantshipClaimFormStatusUpd.objects.all() + roll_no = request.user.username + return render(request, 'otheracademic/assistantship_status.html', { 'form_data' : form_data, 'roll_no' : roll_no}) + + +def assistantship_log(request): + user=get_object_or_404(User,username=request.user.username) + if(user.extrainfo.department.name == 'Academics'): + form_data = AssistantshipClaimFormStatusUpd.objects.all() + return render(request, 'otheracademic/assistantship_log.html', { 'form_data' : form_data}) + else: + return HttpResponse("Not Avalable For You.") + +def find_id_from_inbox(inbox_data, src_obj_id): + for item in inbox_data: + if item.get('src_object_id') == src_obj_id: + return item.get('id') + return None # Return None if src_obj_id is not found in the inbox + + + +def assistanship_ta_approve(request, ass_id): + # Obtain inbox data + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + + # Find the object with the given ID from the AssistantshipClaimFormStatusUpd model + leave_entry = get_object_or_404(AssistantshipClaimFormStatusUpd, id=ass_id) + + # Access the thesis_supervisor attribute of leave_entry + print(leave_entry.thesis_supervisor) + thesis_supervisor_user = User.objects.get(username=leave_entry.thesis_supervisor) + + # Update TA_approved field to True + leave_entry.TA_approved = True + leave_entry.save() + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Assistanstship Claim form status' + otheracademic_notif(request.user,leave_receive, 'ast_ta_accept', leave_entry.id, 'student', message) + ass_id_from_inbox = find_id_from_inbox(inbox, ass_id) + print(ass_id_from_inbox) + a=get_object_or_404(User,username=request.user.username) + y=ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() + user_details=User.objects.get(id=y.user_id) + des=HoldsDesignation.objects.filter(user=user_details).all() + + forwarded_file_id = create_file(uploader = request.user.username, uploader_designation=des[0].designation, receiver =leave_entry.thesis_supervisor, receiver_designation = "student", src_module = "otheracademic", src_object_id =ass_id, file_extra_JSON = {"value": 2}, attached_file = None,subject="assistantship") + + message = "Assistantship status form forwarded" + otheracademic_notif(request.user, thesis_supervisor_user, 'ast_thesis', ass_id, "student", message) + + # Display success message + messages.success(request, "Successfully approved and forwarded.") + + # Redirect to the approveform page + return redirect('/otheracademic/approveform') + + + +def assistanship_ta_reject(request, ass_id): + leave_entry = AssistantshipClaimFormStatusUpd.objects.get(id = ass_id) + leave_entry.TA_rejected = True + leave_entry.save() + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Assistanstship Claim form status' + otheracademic_notif(request.user,leave_receive, 'ast_ta_accept', leave_entry.id, 'student', message) + messages.success(request, "Successfully rejected.") + return redirect('/otheracademic/approveform') + +def assistanship_thesis_approve(request, ass_id): + + leave_entry = get_object_or_404(AssistantshipClaimFormStatusUpd, id=ass_id) + + # Access the thesis_supervisor attribute of leave_entry + print(leave_entry.thesis_supervisor) + csehod_user = User.objects.get(username=leave_entry.hod) + + # Update TA_approved field to True + leave_entry.Ths_approved = True + leave_entry.save() + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Assistanstship Claim form status' + otheracademic_notif(request.user,leave_receive, 'ast_ta_accept', leave_entry.id, 'student', message) + # ass_id_from_inbox = find_id_from_inbox(inbox, ass_id) + # print(ass_id_from_inbox) + a=get_object_or_404(User,username=request.user.username) + y=ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() + user_details=User.objects.get(id=y.user_id) + des=HoldsDesignation.objects.filter(user=user_details).all() + + forwarded_hod = create_file(uploader = request.user.username, uploader_designation=des[0].designation, receiver =leave_entry.hod, receiver_designation = "student", src_module = "otheracademic", src_object_id =ass_id, file_extra_JSON = {"value": 2}, attached_file = None,subject="assistantship") + + + + message = "Assistantship status received" + otheracademic_notif(request.user,csehod_user , 'ast_hod', ass_id, "student", message) + + # Display success message + messages.success(request, "Successfully approved and forwarded.") + + # Redirect to the approveform page + return redirect('/otheracademic/assitantship/thesis_approveform') + + + +def assistanship_thesis_reject(request, ass_id): + leave_entry = AssistantshipClaimFormStatusUpd.objects.get(id = ass_id) + leave_entry.Ths_rejected = True + leave_entry.save() + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Assistanstship Claim form status' + otheracademic_notif(request.user,leave_receive, 'ast_ta_accept', leave_entry.id, 'student', message) + messages.success(request, "Successfully rejected.") + return redirect('/otheracademic/assitantship/thesis_approveform') + + +def assistanship_hod_approve(request, ass_id): + + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + leave_entry = get_object_or_404(AssistantshipClaimFormStatusUpd, id=ass_id) + leave_entry.HOD_approved = True + leave_entry.save() + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Assistanstship Claim form status' + otheracademic_notif(request.user,leave_receive, 'ast_ta_accept', leave_entry.id, 'student', message) + + a=get_object_or_404(User,username=request.user.username) + y=ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() + user_details=User.objects.get(id=y.user_id) + des=HoldsDesignation.objects.filter(user=user_details).all() + + acad_admin_des_id = Designation.objects.get(name="acadadmin") + user_ids = HoldsDesignation.objects.filter(designation_id=acad_admin_des_id.id).values_list('user_id', flat=True) + + acadadmin_receiver = User.objects.get(id=user_ids[0]) + + + forwarded_acad = create_file(uploader = request.user.username, uploader_designation=des[0].designation, receiver =acadadmin_receiver, receiver_designation ="student", src_module = "otheracademic", src_object_id =ass_id, file_extra_JSON = {"value": 2}, attached_file = None,subject="assistantship") + + message = "Assistantship status received" + otheracademic_notif(request.user,acadadmin_receiver , 'ast_acadadmin', ass_id, "student", message) + + # Display success message + messages.success(request, "Successfully approved and forwarded.") + + # Redirect to the approveform page + return redirect('/otheracademic/assitantship/hod_approveform') + + + +def assistanship_hod_reject(request, ass_id): + leave_entry = AssistantshipClaimFormStatusUpd.objects.get(id = ass_id) + leave_entry.HOD_rejected = True + leave_entry.save() + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Assistanstship Claim form status' + otheracademic_notif(request.user,leave_receive, 'ast_ta_accept', leave_entry.id, 'student', message) + messages.success(request, "Successfully rejected.") + + return redirect('/otheracademic/assitantship/hod_approveform') + + +def assistantship_acad_approveform(request): + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + print(inbox) + assistantship_ids = [msg['src_object_id'] for msg in inbox if msg['subject'] == 'assistantship'] + + # Filter form_data queryset based on the ids found + user=get_object_or_404(User,username=request.user.username) + if(user.extrainfo.department.name == 'Academics'): + form_data = AssistantshipClaimFormStatusUpd.objects.filter(id__in=assistantship_ids) + return render(request, 'otheracademic/acadadmin_approval.html', { 'form_data' : form_data}) + else: + return HttpResponse("Not Avalable For You.") + + +def assistanship_acad_approve(request, ass_id): + # Obtain inbox data + inbox = view_inbox(username=request.user.username, designation="student", src_module="otheracademic") + + # Find the object with the given ID from the AssistantshipClaimFormStatusUpd model + leave_entry = get_object_or_404(AssistantshipClaimFormStatusUpd, id=ass_id) + + # Access the thesis_supervisor attribute of leave_entry + # print(leave_entry.thesis_supervisor) + # acadadmin = User.objects.get(username='acadadmin') + + # Update TA_approved field to True + leave_entry.Acad_approved = True + leave_entry.save() + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Assistanstship Claim form status' + otheracademic_notif(request.user,leave_receive, 'ast_ta_accept', leave_entry.id, 'student', message) + + a=get_object_or_404(User,username=request.user.username) + y=ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() + user_details=User.objects.get(id=y.user_id) + des=HoldsDesignation.objects.filter(user=user_details).all() + + + # forwarded_acad = create_file(uploader = request.user.username, uploader_designation=des[0].designation, receiver ='acadadmin', receiver_designation ="student", src_module = "otheracademic", src_object_id =ass_id, file_extra_JSON = {"value": 2}, attached_file = None,subject="assistantship") + + # message = "Assistantship status received" + # otheracademic_notif(request.user,acadadmin , 'alert', ass_id, "student", message) + + # Display success message + messages.success(request, "Successfully approved and forwarded.") + + # Redirect to the approveform page + return redirect('/otheracademic/assitantship/hod_approveform') + + + +def assistanship_acad_reject(request, ass_id): + leave_entry = AssistantshipClaimFormStatusUpd.objects.get(id = ass_id) + leave_entry.Acad_rejected = True + leave_entry.save() + leave_receive = User.objects.get(username=leave_entry.roll_no_id) + message='Assistanstship Claim form status' + otheracademic_notif(request.user,leave_receive, 'ast_ta_accept', leave_entry.id, 'student', message) + messages.success(request, "Successfully rejected.") + + return redirect('/otheracademic/assitantship/hod_approveform') + + + +def othersPage(request): + return render(request, 'otheracademic/othersPage.html') + +def othersLeave(request): + return render(request, 'otheracademic/othersLeave.html') + +def othersNoDues(request): + return render(request, 'otheracademic/othersNoDues.html') + +def othersAssistantship(request): + return render(request, 'otheracademic/othersAssistantship.html') + +def othersGraduate(request): + return render(request, 'otheracademic/othersGraduate.html') + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FusionIIIT/applications/programme_curriculum/api/serializers.py b/FusionIIIT/applications/programme_curriculum/api/serializers.py new file mode 100644 index 000000000..995bc2f72 --- /dev/null +++ b/FusionIIIT/applications/programme_curriculum/api/serializers.py @@ -0,0 +1,123 @@ +from rest_framework import serializers +from applications.programme_curriculum.models import Programme, Discipline, Curriculum, Semester, Course, Batch, CourseSlot, CourseInstructor + +# this is for Programme model .... + + +class ProgrammeSerializer(serializers.ModelSerializer): + discipline = serializers.SerializerMethodField() + programmes = serializers.SerializerMethodField() + + def get_discipline(self, obj): + disciplines = obj.get_discipline_objects.all() + return ', '.join([discipline.name for discipline in disciplines]) # Join disciplines into a single string + + def get_programmes(self, obj): + return obj.name + + class Meta: + model = Programme + fields = [ 'programmes', 'discipline'] + + + +# this is for Discipline ... +class DisciplineSerializer(serializers.ModelSerializer): + class Meta: + model = Discipline + fields = "__all__" + + + +# this is for Curriculum .... +# fields in fronted form --> name, version , batch , no of semester +class BatchSerializer(serializers.ModelSerializer): + class Meta: + model = Batch + fields = ['name', 'year'] + + + +class CurriculumBatchSerializer(serializers.ModelSerializer): + class Meta: + model = Curriculum + fields = ['name', 'version', 'no_of_semester'] + +class CurriculumSerializer(serializers.ModelSerializer): + class Meta: + model = Curriculum + fields = ['name', 'version', 'batches', 'no_of_semester'] + + def to_representation(self, instance): + representation = super().to_representation(instance) + batches = instance.batches.all() + representations = [] + for batch in batches: + batch_representation = { + 'name': representation['name'], + 'version': representation['version'], + 'no_of_semester': representation['no_of_semester'], + 'batch': f"{representation['name']} {batch.year}" + } + representations.append(batch_representation) + return representations + + + +class ProgrammeInfoSerializer(serializers.ModelSerializer): + + class Meta: + model = Programme + fields = ['category', 'name', 'programme_begin_year'] + + + + +# this is for Semester model ... +# no frontend form for this model ... +class SemesterSerializer(serializers.ModelSerializer): + class Meta: + model = Semester + fields = "__all__" + + + +# this is for course model ... +# fields in frontend form --> coursecode, coursename, credit +class CourseSerializer(serializers.ModelSerializer): + class Meta: + model = Course + fields = "__all__" + + + +# this is for Batch model ... +# field in frontend form --> name, discipline, year, curriculum . +# class BatchSerializer(serializers.ModelSerializer): +# class Meta: +# model = Batch +# fields = "__all__" + + +# for this 2 there is no frontend form ... + + +# CourseSlot model serializers ... +class CourseSlotSerializer(serializers.ModelSerializer): + class Meta: + model = CourseSlot + fields = "__all__" + + + +# CourseInstructor model serializers ... +class CourseInstructorSerializer(serializers.ModelSerializer): + class Meta: + model = CourseInstructor + fields = "__all__" + + +class ProgrammePostSerializer(serializers.ModelSerializer): + class Meta: + model = Programme + fields = ['id', 'category', 'name', 'programme_begin_year'] diff --git a/FusionIIIT/applications/programme_curriculum/api/views.py b/FusionIIIT/applications/programme_curriculum/api/views.py new file mode 100644 index 000000000..1c10092ad --- /dev/null +++ b/FusionIIIT/applications/programme_curriculum/api/views.py @@ -0,0 +1,141 @@ +from rest_framework.decorators import api_view +from rest_framework.response import Response +from django.shortcuts import get_object_or_404 +from rest_framework import status + +from applications.programme_curriculum.models import ( + Programme, + Discipline, + Curriculum, + Semester, + Course, + Batch, + CourseSlot, + CourseInstructor, +) + +from .serializers import ( + ProgrammeSerializer, + CurriculumSerializer, + ProgrammePostSerializer, + SemesterSerializer, + DisciplineSerializer, + CourseSerializer, + CourseSlotSerializer, + BatchSerializer, + ProgrammeInfoSerializer, +) + +from applications.programme_curriculum.filters import ( + CourseFilter, + BatchFilter, + CurriculumFilter, +) +from rest_framework import generics + + +@api_view(["GET", "POST"]) +def view_ug_programmes(request): + """ + This function is used to display all the ug programmes offered by the institute. + """ + ug = Programme.objects.filter(category="UG") + + ug_serializer = ProgrammeSerializer(ug, many=True) + + return Response(ug_serializer.data) + + +@api_view(["GET", "POST"]) +def view_pg_programmes(request): + """ + This function is used to display all the ug programmes offered by the institute. + """ + ug = Programme.objects.filter(category="PG") + + ug_serializer = ProgrammeSerializer(ug, many=True) + + return Response(ug_serializer.data) + + +@api_view(["GET", "POST"]) +def view_phd_programmes(request): + """ + This function is used to display all the ug programmes offered by the institute. + """ + ug = Programme.objects.filter(category="PHD") + + ug_serializer = ProgrammeSerializer(ug, many=True) + + return Response(ug_serializer.data) + + +@api_view(["GET"]) +def get_programme_info(request): + if request.method == "GET": + # Fetch all programmes + programmes = Programme.objects.all() + + # Serialize the data + serializer = ProgrammeInfoSerializer(programmes, many=True) + + # Return the serialized data as response + return Response(serializer.data) + + +@api_view(["GET"]) +def view_curriculumns(request): + if request.method == "GET": + # Fetch all programmes + curriculums = Curriculum.objects.all() + serializer = CurriculumSerializer(curriculums, many=True) + return Response(serializer.data) + + +@api_view(["POST"]) +def create_programme(request): + if request.method == "POST": + # Extract data from the request + category = request.data.get("category") + name = request.data.get("name") + programme_begin_year = request.data.get("programme_begin_year") + discipline_names = request.data.get( + "discipline" + ) # Assuming discipline names are sent as a list + + # Validate data + if not category or not name or not programme_begin_year or not discipline_names: + return Response( + { + "message": "Please provide category, name, programme_begin_year, and discipline in the request body" + }, + status=status.HTTP_400_BAD_REQUEST, + ) + + # Create Programme object + programme = Programme.objects.create( + category=category, name=name, programme_begin_year=programme_begin_year + ) + + # Find Discipline objects and associate them with the Programme + disciplines = [] + for discipline_name in discipline_names: + try: + discipline = Discipline.objects.get(name=discipline_name) + discipline.programmes.add(programme) + disciplines.append(discipline) + except Discipline.DoesNotExist: + # If discipline does not exist, you may handle it according to your application's logic + # For example, you can create the discipline here + pass + + # Serialize the Programme object + serializer = ProgrammePostSerializer(programme) + + return Response( + { + "programme": serializer.data, + "disciplines": [discipline.name for discipline in disciplines], + }, + status=status.HTTP_201_CREATED, + ) diff --git a/FusionIIIT/applications/programme_curriculum/migrations/0001_initial.py b/FusionIIIT/applications/programme_curriculum/migrations/0001_initial.py index bb794c796..ea11ebc7c 100644 --- a/FusionIIIT/applications/programme_curriculum/migrations/0001_initial.py +++ b/FusionIIIT/applications/programme_curriculum/migrations/0001_initial.py @@ -207,4 +207,4 @@ class Migration(migrations.Migration): 'unique_together': {('course_id', 'instructor_id', 'batch_id')}, }, ), - ] + ] \ No newline at end of file diff --git a/FusionIIIT/applications/programme_curriculum/models.py b/FusionIIIT/applications/programme_curriculum/models.py index 01d235aa4..e781af115 100644 --- a/FusionIIIT/applications/programme_curriculum/models.py +++ b/FusionIIIT/applications/programme_curriculum/models.py @@ -417,4 +417,4 @@ class Meta: # unique_together = ('file_id', 'current_id','receive_id','receive_design') unique_together = ('file_id', 'current_id','current_design','disciplines') - + \ No newline at end of file diff --git a/FusionIIIT/applications/programme_curriculum/urls.py b/FusionIIIT/applications/programme_curriculum/urls.py index 4d06893b1..c40dad9a0 100644 --- a/FusionIIIT/applications/programme_curriculum/urls.py +++ b/FusionIIIT/applications/programme_curriculum/urls.py @@ -2,7 +2,7 @@ from django.urls import path, include from . import views from django.contrib import admin - +from applications.programme_curriculum.api import views as v2 app_name = 'programme_curriculum' urlpatterns = [ @@ -19,6 +19,7 @@ path('course//', views.view_a_course, name='view_a_course'), path('disciplines/', views.view_all_discplines, name='view_all_discplines'), path('batches/', views.view_all_batches, name='view_all_batches'), + path('admin_programmes/', views.admin_view_all_programmes, name='admin_view_all_programmes'), path('admin_working_curriculums/', views.admin_view_all_working_curriculums, name='admin_view_all_working_curriculums'), @@ -65,4 +66,12 @@ path('forward_course_forms//',views.forward_course_forms,name='forward_course_forms'), path('view_inward_files//',views.view_inward_files,name='view_inward_files'), path('outward_files/',views.outward_files,name='outward_files'), + + # urls for api view + path('api/programmes_ug/', v2.view_ug_programmes, name='view_ug_programmes_api'), + path('api/programmes_pg/', v2.view_pg_programmes, name='view_pg_programmes_api'), + path('api/programmes_phd/', v2.view_phd_programmes, name='view_phd_programmes_api'), + path('api/programme_info/', v2.get_programme_info, name='programme_info_api'), + path('api/curriculumns/', v2.view_curriculumns, name='curriculumns_api'), + path('api/add_programme/', v2.create_programme, name='add_programme_api'), ] diff --git a/FusionIIIT/applications/programme_curriculum/views.py b/FusionIIIT/applications/programme_curriculum/views.py index f331737b9..a1e40c6d1 100644 --- a/FusionIIIT/applications/programme_curriculum/views.py +++ b/FusionIIIT/applications/programme_curriculum/views.py @@ -136,8 +136,6 @@ def view_all_working_curriculums(request): curriculums = curriculumfilter.qs return render(request,url+'view_all_working_curriculums.html',{'curriculums':curriculums, 'curriculumfilter': curriculumfilter}) - - def view_semesters_of_a_curriculum(request, curriculum_id): """ This function is used to Display all Semester of a Curriculum. diff --git a/FusionIIIT/applications/ps1/api/views.py b/FusionIIIT/applications/ps1/api/views.py index 37d6546e4..587c02e8a 100644 --- a/FusionIIIT/applications/ps1/api/views.py +++ b/FusionIIIT/applications/ps1/api/views.py @@ -53,7 +53,6 @@ def createProposal(request): designation = Designation.objects.get(id=HoldsDesignation.objects.select_related('user', 'working', 'designation').get(id=design).designation_id) upload_file = request.FILES.get('myfile') item_name = request.data.get('item_name') - grade = request.data.get('grade') quantity = request.data.get('quantity') present_stock = request.data.get('present_stock') estimated_cost = request.data.get('estimated_cost') @@ -89,7 +88,6 @@ def createProposal(request): estimated_cost=estimated_cost, purpose=purpose, specification=specification, - grade=grade, item_type=item_type, nature=nature, indigenous=indigenous, @@ -445,12 +443,11 @@ def currentStockView(request,id): else: return Response({"message": "Invalid designation"}, status=status.HTTP_403_FORBIDDEN) - grouped_items = stocks.values('StockEntryId__item_id__item_type', 'StockEntryId__item_id__grade', 'department').annotate(total_quantity=Count('id')) + grouped_items = stocks.values('StockEntryId__item_id__item_type', 'department').annotate(total_quantity=Count('id')) grouped_items_list = [ { 'item_type': item['StockEntryId__item_id__item_type'], - 'grade': item['StockEntryId__item_id__grade'], 'department': DepartmentInfo.objects.get(id=item['department']).name, 'total_quantity': item['total_quantity'] } @@ -462,25 +459,22 @@ def currentStockView(request,id): elif request.method == 'POST': # Handle POST request department = request.data.get('department') - grade = request.data.get('grade') item_type = request.data.get('item_type') - if not department or not grade or not item_type: + if not department or not item_type: return Response({"message": "Missing required parameters"}, status=status.HTTP_400_BAD_REQUEST) # Filter StockItem based on provided filters StockItems = StockItem.objects.filter( department=department, - StockEntryId__item_id__grade=grade, StockEntryId__item_id__item_type=item_type ) - grouped_items = StockItems.values('StockEntryId__item_id__item_type', 'StockEntryId__item_id__grade', 'department').annotate(total_quantity=Count('id')) + grouped_items = StockItems.values('StockEntryId__item_id__item_type', 'department').annotate(total_quantity=Count('id')) grouped_items_list = [ { 'item_type': item['StockEntryId__item_id__item_type'], - 'grade': item['StockEntryId__item_id__grade'], 'department': DepartmentInfo.objects.get(id=department).name, 'total_quantity': item['total_quantity'] } @@ -544,11 +538,9 @@ def stockTransfer(request,id): temp1=IndentFile.objects.get(file_info=temp) item_type_required =temp1.item_type - item_grade_required = temp1.grade available_items=StockItem.objects.filter( StockEntryId__item_id__item_type=item_type_required, - StockEntryId__item_id__grade=item_grade_required, inUse=False ) diff --git a/FusionIIIT/applications/ps1/models.py b/FusionIIIT/applications/ps1/models.py index d5aa60d93..ffbe50020 100644 --- a/FusionIIIT/applications/ps1/models.py +++ b/FusionIIIT/applications/ps1/models.py @@ -15,7 +15,6 @@ class IndentFile(models.Model): estimated_cost=models.IntegerField(null=True, blank=False) purpose=models.CharField(max_length=250,blank=False ) specification=models.CharField(max_length=250) - grade = models.CharField(max_length=1, choices=[('A', 'A'), ('B', 'B'), ('C', 'C')],default='A') item_type=models.CharField(max_length=250) nature=models.BooleanField(default = False) indigenous= models.BooleanField(default = False) @@ -34,14 +33,11 @@ class Meta: class Constants: Locations = ( - ('H1', 'Vashistha Hostel'), - ('H4', 'Vivekananda Hostel'), - ('H3', 'AryaBhatta Hostel'), - ('SR1', 'Storage Room 1'), - ('SR2', 'Storage Room 2'), - ('SR3', 'Storage Room 3'), - ('SR4', 'Storage Room 4'), - ('SR5', 'Storage Room 5'), + ('SR1', 'LHTC'), + ('SR2', 'Computer Center'), + ('SR3', 'Panini Hostel'), + ('SR4', 'Lab complex'), + ('SR5', 'Admin Block'), ) class StockEntry(models.Model): diff --git a/FusionIIIT/applications/ps1/urls.py b/FusionIIIT/applications/ps1/urls.py index 793d34ec5..148e0c753 100644 --- a/FusionIIIT/applications/ps1/urls.py +++ b/FusionIIIT/applications/ps1/urls.py @@ -12,21 +12,22 @@ url(r'^composed_indents/$', views.composed_indents, name='composed_indents'), # here id is the Holdsdesignation id. - url(r'^indentview/(?P\d+)$', views.indentview, name='indentview'), + url(r'^indentview/(?P\d+)/$', views.indentview, name='indentview'), + url(r'^archieveview/(?P\d+)/$', views.archieveview, name='archieveview'), url(r'^drafts/$', views.drafts, name='drafts'), - url(r'^draftview/(?P\d+)$', views.draftview, name='draftview'), + url(r'^draftview/(?P\d+)/$', views.draftview, name='draftview'), url(r'^inwardIndent/$', views.inward, name='inward'), # indentview2 is to get all the indentFiles inwarded towards the request.user. - url(r'^indentview2/(?P\d+)$', views.indentview2, name='indentview2'), - url(r'^confirmdelete/(?P\d+)$', views.confirmdelete, name='confirm_delete'), - url(r'^delete/(?P\d+)$',views.delete, name='delete'), + url(r'^indentview2/(?P\d+)/$', views.indentview2, name='indentview2'), + url(r'^confirmdelete/(?P\d+)/$', views.confirmdelete, name='confirm_delete'), + url(r'^delete/(?P\d+)/$',views.delete, name='delete'), # forward Indent is to see a specific forwarded indent to ourselves url(r'^forwardindent/(?P\d+)/$', views.forwardindent, name='forwardindent'), url(r'^createdindent/(?P\d+)/$', views.createdindent, name='createdindent'), - + url(r'^forwardedIndent/(?P\d+)/$', views.forwardedIndent, name='forwardedIndent'), url(r'^entry/$', views.entry, name='entry'), url(r'^StockEntry/$', views.Stock_Entry, name='Stock_Entry'), @@ -43,6 +44,7 @@ # to display stock items which are having similar item_type ,grade and department.(used in current_stock_view) url(r'^stock_item_view/$', views.stock_item_view, name='stock_item_view'), + url(r'^archieved_indents/$', views.archieved_files, name='archieved_indents_view'), @@ -62,7 +64,7 @@ url(r'^stock_transfer/$', views.stock_transfer, name='stock_transfer'), url(r'^view_transfer/$', views.view_transfer, name='view_transfer'), - url(r'^outboxview2/$', views.outboxview2, name='outboxview2'), + url(r'^outboxview2/(?P\d+)/$', views.outboxview2, name='outboxview2'), url(r'^outboxview/$', views.outboxview, name='outboxview'), diff --git a/FusionIIIT/applications/ps1/views.py b/FusionIIIT/applications/ps1/views.py index f3e603ec5..c07889c43 100644 --- a/FusionIIIT/applications/ps1/views.py +++ b/FusionIIIT/applications/ps1/views.py @@ -14,6 +14,8 @@ from django.utils import timezone from datetime import datetime from applications.globals.models import DepartmentInfo +from applications.filetracking.sdk.methods import * +from datetime import datetime import re import json @@ -34,6 +36,8 @@ @login_required(login_url = "/accounts/login/") def ps1(request): + notifs = request.user.notifications.all() + des_obj = HoldsDesignation.objects.filter(user=request.user) if des_obj: @@ -88,16 +92,24 @@ def create_proposal(request): financial_approval=False purchased =request.POST.get('purchased') """ + if request.session['currentDesignationSelected'] in dept_admin_design + ["ps_admin"]: + return redirect('/purchase-and-store/inwardIndent') print("request.user.id : ", request.user.id) - + notifs = request.user.notifications.all() if request.method =="POST": try: if 'save' in request.POST: uploader = request.user.extrainfo subject = request.POST.get('title') description = request.POST.get('desc') - design = request.POST.get('design') - designation = Designation.objects.get(id = HoldsDesignation.objects.select_related('user','working','designation').get(id = design).designation_id) + # design = request.POST.get('design') + design = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first() + + #print('design : ',design,'design2' , design2); + + + designation = Designation.objects.get(id = HoldsDesignation.objects.select_related('user','working','designation').get(id = design.id).designation_id) + upload_file = request.FILES.get('myfile') item_name=request.POST.get('item_name') quantity= request.POST.get('quantity') @@ -117,16 +129,20 @@ def create_proposal(request): financial_approval=False purchased =False - file=File.objects.create( + ##get the uploader username + uploader = request.user.username + print("uploader : ",uploader) + file_id=create_draft( uploader=uploader, - description=description, - subject=subject, - designation=designation, - upload_file=upload_file + uploader_designation=designation, + src_module="ps1", + src_object_id="", + file_extra_JSON={"value": 2}, + attached_file=upload_file ) IndentFile.objects.create( - file_info=file, + file_info=get_object_or_404(File, pk=file_id), item_name= item_name, quantity=quantity, present_stock=present_stock, @@ -149,13 +165,24 @@ def create_proposal(request): if 'send' in request.POST: - print('request.POST : ',request.POST); + # print('request.POST : ',request.POST); + uploader = request.user.extrainfo subject = request.POST.get('title') description = request.POST.get('desc') - design = request.POST.get('design') - designation = Designation.objects.get(id = HoldsDesignation.objects.select_related('user','working','designation').get(id = design).designation_id) + # design = request.POST.get('design') + + design = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first() + + designation = Designation.objects.get(id = HoldsDesignation.objects.select_related('user','working','designation').get(id = design.id).designation_id) + + # print(designation) + # print(design) + # print('design : ',design.id); + + + upload_file = request.FILES.get('myfile') item_name=request.POST.get('item_name') quantity= request.POST.get('quantity') @@ -164,7 +191,6 @@ def create_proposal(request): purpose=request.POST.get('purpose') specification=request.POST.get('specification') item_type=request.POST.get('item_type') - grade=request.POST.get('grade') nature=request.POST.get('nature') indigenous=request.POST.get('indigenous') replaced =request.POST.get('replaced') @@ -177,22 +203,16 @@ def create_proposal(request): purchased = False designations = HoldsDesignation.objects.select_related('user','working','designation').filter(user = request.user) - for des in designations: - if request.session['currentDesignationSelected'] == "Director": - head_approval=True - director_approval=True - financial_approval=True - break - + if request.session['currentDesignationSelected'] == "Director": + head_approval=True + director_approval=True + financial_approval=True # current_id = request.user.extrainfo # remarks = request.POST.get('remarks') - sender = request.POST.get('design') - current_design = HoldsDesignation.objects.select_related('user','working','designation').get(id=sender) - receiver = request.POST.get('receiver') try: @@ -230,7 +250,6 @@ def create_proposal(request): specification=specification, item_type=item_type, nature=nature, - grade=grade, indigenous=indigenous, replaced = replaced , budgetary_head=budgetary_head, @@ -255,8 +274,9 @@ def create_proposal(request): today = timezone.now().strftime('%Y-%m-%d') currDesig = request.session['currentDesignationSelected'] - dept_admin_design = ['dept_admin1', 'dept_admin2', 'dept_admin3'] # Replace with actual department admin designations - isAdmin = currDesig == 'ps_admin' or currDesig in dept_admin_design + dept_admin_designs = dept_admin_design + isAdmin = currDesig == 'ps_admin' or currDesig in dept_admin_designs + notifs = request.user.notifications.all() context = { 'file': file, @@ -265,30 +285,46 @@ def create_proposal(request): 'designations': designations, 'today': today, 'isAdmin': isAdmin, + 'notifications':notifs } return render(request, 'ps1/composeIndent.html', context) -# @login_required(login_url = "/accounts/login") -# def compose_indent(request): -# file = File.objects.select_related('uploader__user','uploader__department','designation').all() -# extrainfo = ExtraInfo.objects.select_related('user','department').all() -# holdsdesignations = HoldsDesignation.objects.select_related('user','working','designation').all() -# designations = HoldsDesignation.objects.select_related('user','working','designation').filter(user = request.user) -# context = { -# 'file': file, -# 'extrainfo': extrainfo, -# 'holdsdesignations': holdsdesignations, -# 'designations': designations, -# } -# return render(request, 'ps1/composeIndent.html', context) + +@login_required(login_url = "/accounts/login") +def composed_indents(request): + """ + The function is used to get all the files created by user(employee). + It gets all files created by user by filtering file(table) object by user i.e, uploader. + It displays user and file details of a file(table) of filetracking(model) in the + template of 'Saved files' tab. + + @param: + request - trivial. + + @variables: + draft - The File object filtered by uploader(user). + extrainfo - The Extrainfo object. + context - Holds data needed to make necessary changes in the template. + """ + + # draft = File.objects.filter(uploader=request.user.extrainfo) + # draft = File.objects.filter(uploader=request.user.extrainfo).order_by('-upload_date') + + # print(File.objects) + # extrainfo = ExtraInfo.objects.all() + # designation = Designation.objects.get(id=HoldsDesignation.objects.get(user=request.user).designation_id) + if request.session['currentDesignationSelected'] == "student": + return redirect('/dashboard') + designation = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first() + print(designation) - + return redirect(f'/purchase-and-store/indentview/{designation.id}') @login_required(login_url = "/accounts/login") -def composed_indents(request): +def archieved_files(request): """ The function is used to get all the files created by user(employee). It gets all files created by user by filtering file(table) object by user i.e, uploader. @@ -310,16 +346,13 @@ def composed_indents(request): # print(File.objects) # extrainfo = ExtraInfo.objects.all() # designation = Designation.objects.get(id=HoldsDesignation.objects.get(user=request.user).designation_id) - des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() if request.session['currentDesignationSelected'] == "student": return redirect('/dashboard') - designation = HoldsDesignation.objects.filter(user=request.user) - context = { - # 'draft': draft, - # 'extrainfo': extrainfo, - 'designation': designation, - } - return render(request, 'ps1/composed_indents.html', context) + + designation = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first() + + + return redirect(f'/purchase-and-store/archieveview/{designation.id}') @@ -366,21 +399,24 @@ def drafts(request): # print(File.objects) # extrainfo = ExtraInfo.objects.all() # designation = Designation.objects.get(id=HoldsDesignation.objects.get(user=request.user).designation_id) - des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() if request.session['currentDesignationSelected'] == "student": return redirect('/dashboard') - designation = HoldsDesignation.objects.filter(user=request.user) - context = { - # 'draft': draft, - # 'extrainfo': extrainfo, - 'designation': designation, - } - return render(request, 'ps1/drafts.html', context) + + designation = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first() + + + return redirect(f'/purchase-and-store/draftview/{designation.id}') @login_required(login_url = "/accounts/login") def indentview(request,id): - print("id : ",id); - + print("id : ",id) + if request.session['currentDesignationSelected'] == "student": + return redirect('/dashboard') + + designation = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first() + + if str(id) != str(designation.id): + return redirect(f'/purchase-and-store/indentview/{designation.id}') tracking_objects=Tracking.objects.all() tracking_obj_ids=[obj.file_id for obj in tracking_objects] draft_indent = IndentFile.objects.filter(file_info__in=tracking_obj_ids) @@ -391,14 +427,52 @@ def indentview(request,id): abcd = HoldsDesignation.objects.get(pk=id) s = str(abcd).split(" - ") designations = s[1] + notifs = request.user.notifications.all() context = { 'indents' : indents, 'extrainfo': extrainfo, 'designations': designations, + 'notifications':notifs } return render(request, 'ps1/indentview.html', context) +@login_required(login_url = "/accounts/login") +def archieveview(request,id): + if request.session['currentDesignationSelected'] == "student": + return redirect('/dashboard') + + designation = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first() + + if str(id) != str(designation.id): + return redirect(f'/purchase-and-store/archieveview/{designation.id}') + print("id : ",id); + print("request.user : ",request.user); + + abcd = HoldsDesignation.objects.get(pk=id) + s = str(abcd).split(" - ") + designations = s[1] + print("designations : ",designations); + + archived_files = view_archived( + username=request.user, + designation=designations, + src_module="ps1" + ) + + print("archived_files : ",archived_files); + for files in archived_files: + files['upload_date']=datetime.fromisoformat(files['upload_date']) + files['upload_date']=files['upload_date'].strftime("%B %d, %Y, %I:%M %p") + + notifs = request.user.notifications.all() + context = { + 'archieves' : archived_files, + 'designations': designations, + 'notifications':notifs + } + return render(request, 'ps1/archieve_view.html', context) + # @login_required(login_url = "/accounts/login") # def draftview_multiple_items_indent(request,id): @@ -445,10 +519,13 @@ def indentview(request,id): @login_required(login_url = "/accounts/login") def draftview(request,id): - - des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() if request.session['currentDesignationSelected'] == "student": return redirect('/dashboard') + + designation = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first() + + if str(id) != str(designation.id): + return redirect(f'/purchase-and-store/draftview/{designation.id}') indents= IndentFile.objects.filter(file_info__in=request.user.extrainfo.uploaded_files.all()).select_related('file_info') indent_ids=[indent.file_info for indent in indents] @@ -461,16 +538,25 @@ def draftview(request,id): abcd = HoldsDesignation.objects.get(pk=id) s = str(abcd).split(" - ") designations = s[1] + notifs = request.user.notifications.all() context = { 'draft': draft_files, 'extrainfo': extrainfo, 'designations': designations, + 'notifications':notifs } return render(request, 'ps1/draftview.html', context) @login_required(login_url = "/accounts/login") def indentview2(request,id): + if request.session['currentDesignationSelected'] == "student": + return redirect('/dashboard') + + designation = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first() + + if str(id) != str(designation.id): + return redirect(f'/purchase-and-store/indentview2/{designation.id}') abcd = HoldsDesignation.objects.get(pk=id) s = str(abcd).split(" - ") designations = s[1] @@ -482,10 +568,13 @@ def indentview2(request,id): for item in data: item['upload_date'] = datetime.fromisoformat(item['upload_date']) + + notifs = request.user.notifications.all() context = { 'receive_design':abcd, 'in_file': data, + 'notifications':notifs } return render(request, 'ps1/indentview2.html', context) @@ -511,16 +600,13 @@ def inward(request): in_file - The Tracking object filtered by receiver_id i.e, present working user. context - Holds data needed to make necessary changes in the template. """ - des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() - if str(des.designation) == "student": + if request.session['currentDesignationSelected'] == "student": return redirect('/dashboard') - designation = HoldsDesignation.objects.filter(user=request.user) - context = { - 'designation': designation, - } + designation = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first() + - return render(request, 'ps1/inwardIndent.html', context) + return redirect(f'/purchase-and-store/indentview2/{designation.id}') @@ -573,8 +659,23 @@ def forwardindent(request, id): file=indent.file_info # start = timer() track = Tracking.objects.select_related('file_id__uploader__user','file_id__uploader__department','file_id__designation','current_id__user','current_id__department', -'current_design__user','current_design__working','current_design__designation','receiver_id','receive_design').filter(file_id=file) +'current_design__user','current_design__working','current_design__designation','receiver_id','receive_design').filter(file_id=file).order_by('forward_date') # end = timer() + + lastTrackInstance = track.last(); + + # print(lastTrackInstance.receiver_id ," : " ,lastTrackInstance.receive_design) + # print(request.user); + # print(request.user == lastTrackInstance.receiver_id) + + fileHistory=view_history(file.id) + lastElement = fileHistory[-1] + current_id=lastElement['current_id'] + isArchivable = False + print(request.user.username,"request.user.username") + print(current_id,"current_id") + if current_id == request.user.username: + isArchivable = True if request.method == "POST": # print('Mohit Will Win : ' , request.POST); @@ -583,10 +684,24 @@ def forwardindent(request, id): file.complete_flag = True file.save() + if 'Archieve' in request.POST: + print("inside archieve") + is_archived = archive_file(file_id=file.id) + print("is_archived : ",is_archived) + + if is_archived: + messages.success(request, 'Indent File Archived successfully') + return redirect('/purchase-and-store/forwardedIndent/{0}'.format(file.id)) + else: + messages.error(request, 'Indent File could not be archived') + if 'send' in request.POST: current_id = request.user.extrainfo remarks = request.POST.get('remarks') - sender_design_id = request.POST.get('sender') + + sender_design_id = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first().id + + sender_designationobj = HoldsDesignation.objects.get(id=sender_design_id).designation sender_designation_name = sender_designationobj.name @@ -595,6 +710,10 @@ def forwardindent(request, id): receiver = receiverHdobj.user.username receive_design = receiverHdobj.designation.name + # print("sender_design_id : ", sender_design_id ); + + + try: receiver_id = User.objects.get(username=receiver) except Exception as e: @@ -617,6 +736,7 @@ def forwardindent(request, id): 'designations': designations, 'file': file, 'track': track, + 'lastTrackingInstance':lastTrackInstance } return render(request, 'ps1/forwardindent.html', context) @@ -631,19 +751,14 @@ def forwardindent(request, id): file_attachment=upload_file ) - - - if (str(receive_design) in dept_admin_design): - indent.head_approval=True - elif (( - (sender_designation_name in dept_admin_design) - or - (sender_designation_name == "ps_admin") - ) - and (str(receive_design) == "Accounts Admin")): - indent.director_approval=True - indent.financial_approval=True - indent.head_approval=True + # CREATOR -> HOD -> DIRECTOR/REGISTRAR -> DEPT_ADMIN -> + if((sender_designation_name in ["HOD (CSE)", "HOD (ECE)", "HOD (ME)", "HOD (SM)", "HOD (Design)", "HOD (Liberal Arts)", "HOD (Natural Science)"]) and (str(receive_design) in ["Director","Registrar"])): + indent.head_approval=True + elif ((sender_designation_name in ["Director","Registrar"]) and (str(receive_design) in dept_admin_design)): + indent.director_approval=True + elif ((sender_designation_name == "Accounts Admin") and ((str(receive_design) in dept_admin_design) or str(receive_design) == "ps_admin")): + indent.financial_approval=True + designs =[] designations = HoldsDesignation.objects.select_related('user','working','designation').filter(user=request.user) @@ -668,7 +783,9 @@ def forwardindent(request, id): 'designations':designations, 'file': file, 'track': track, - 'indent':indent + 'indent':indent, + 'isArchivable':isArchivable, + 'lastTrackingInstance':lastTrackInstance } return render(request, 'ps1/forwardindent.html', context) @@ -720,6 +837,9 @@ def createdindent(request, id): current_design = HoldsDesignation.objects.select_related('user','working','designation').get(id=sender) receiver = request.POST.get('receiver') + print("receiver: ", receiver) + print("receiverid : ", User.objects.get(username=receiver)) + try: receiver_id = User.objects.get(username=receiver) except Exception as e: @@ -751,15 +871,24 @@ def createdindent(request, id): return render(request, 'ps1/createdindent.html', context) upload_file = request.FILES.get('myfile') # return HttpResponse ("success") - Tracking.objects.create( - file_id=file, - current_id=current_id, - current_design=current_design, - receive_design=receive_design, - receiver_id=receiver_id, + receiver_obj = User.objects.get(username=receiver) + forwarded_file_id = forward_file( + file_id=file.id, + receiver=receiver, + receiver_designation=receive_design, + file_extra_JSON={"key": 2}, remarks=remarks, - upload_file=upload_file, + file_attachment=upload_file ) + # Tracking.objects.create( + # file_id=file, + # current_id=current_id, + # current_design=current_design, + # receive_design=receive_design, + # receiver_id=receiver_id, + # remarks=remarks, + # upload_file=upload_file, + # ) messages.success(request, 'Indent File sent successfully') @@ -774,7 +903,52 @@ def createdindent(request, id): return render(request, 'ps1/createdindent.html', context) +@login_required(login_url = "/accounts/login") +def forwardedIndent(request, id): + """ + The function is used to forward created indent files by user(employee) . + @param: + request - trivial. + id - id of the file object which the user intends to forward to other employee. + @variables: + file - The File object. + track - The Tracking object. + remarks = Remarks posted by user. + receiver = Receiver to be selected by user for forwarding file. + receiver_id = Receiver_id who has been selected for forwarding file. + upload_file = File attached by user. + extrainfo = ExtraInfo object. + holdsdesignations = HoldsDesignation objects. + context - Holds data needed to make necessary changes in the template. + """ + des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() + if request.session['currentDesignationSelected'] == "student": + return redirect('/dashboard') + # start = timer() + + # end = timer() + indent=IndentFile.objects.select_related('file_info').get(file_info=id) + file=indent.file_info + # start = timer() + track = Tracking.objects.select_related('file_id__uploader__user','file_id__uploader__department','file_id__designation','current_id__user','current_id__department', +'current_design__user','current_design__working','current_design__designation','receiver_id','receive_design').filter(file_id=file) + # end = timer() + + + + + + + designations = HoldsDesignation.objects.select_related('user','working','designation').filter(user=request.user) + + context = { + 'designations':designations, + 'file': file, + 'track': track, + 'indent':indent, + } + return render(request, 'ps1/forwardedIndent.html', context) def AjaxDropdown1(request): des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() @@ -922,22 +1096,19 @@ def current_stock_view(request): if request.method=="POST": print('the requested data : ', request.POST) department = request.POST.get('department') - grade = request.POST.get('grade') type = request.POST.get('type') # StockEntryId__item_id__file_info_grade StockItems = StockItem.objects.filter( department=department, - StockEntryId__item_id__grade=grade, StockEntryId__item_id__item_type=type ) - grouped_items = StockItems.values('StockEntryId__item_id__item_type', 'StockEntryId__item_id__grade','department').annotate(total_quantity=Count('id')) + grouped_items = StockItems.values('StockEntryId__item_id__item_type', 'department').annotate(total_quantity=Count('id')) grouped_items_list = [ { 'item_type': item['StockEntryId__item_id__item_type'], - 'grade': item['StockEntryId__item_id__grade'], 'department': DepartmentInfo.objects.get(id=department), 'total_quantity': item['total_quantity'] } @@ -946,6 +1117,8 @@ def current_stock_view(request): firstStock=StockItems.first() + + return render(request,'ps1/current_stock_view.html',{'stocks':grouped_items_list,'first_stock':firstStock, 'stockItems':StockItems}) @@ -954,33 +1127,32 @@ def current_stock_view(request): # THIS IS HARDCODED FOR NOW . itemsTypes=['Equipment','Machinery','Furniture','Fixture'] - grades=['A','B','C'] departmentUser=request.user.extrainfo.department if request.session['currentDesignationSelected'] in dept_admin_design: # if department admin then only show the stocks of that department to them print(dept_admin_to_dept[request.session['currentDesignationSelected']]); - deptId = DepartmentInfo.objects.get(name=dept_admin_to_dept[request.session['currentDesignationSelected']]) + deptId = DepartmentInfo.objects.values('id', 'name').get(name=dept_admin_to_dept[request.session['currentDesignationSelected']]) departments=[deptId] StockItems = StockItem.objects.filter(department=deptId) elif request.session['currentDesignationSelected'] == "ps_admin": - departments=DepartmentInfo.objects.all() + departments=DepartmentInfo.objects.values('id','name').all() + StockItems = StockItem.objects.all() else : return redirect('/dashboard') - grouped_items = StockItems.values('StockEntryId__item_id__item_type', 'StockEntryId__item_id__grade','department').annotate(total_quantity=Count('id')) + grouped_items = StockItems.values('StockEntryId__item_id__item_type','department').annotate(total_quantity=Count('id')) grouped_items_list = [ { 'item_type': item['StockEntryId__item_id__item_type'], - 'grade': item['StockEntryId__item_id__grade'], - 'department': DepartmentInfo.objects.get(id=item['department']), + 'department': DepartmentInfo.objects.values('id','name').get(id=item['department']), 'departmentId': item['department'], 'total_quantity': item['total_quantity'] } @@ -988,9 +1160,9 @@ def current_stock_view(request): ] - return render(request,'ps1/current_stock_view_filter.html',{'itemsTypes':itemsTypes,'grades':grades,'departments':departments,'stocks':grouped_items_list}) + return render(request,'ps1/current_stock_view_filter.html',{'itemsTypes':itemsTypes,'departments':departments,'stocks':grouped_items_list}) -# to display stock items which are having similar item_type ,grade and department.(used in current_stock_view) +# to display stock items which are having similar item_type and department.(used in current_stock_view) @login_required(login_url = "/accounts/login") def stock_item_view(request): @@ -1000,13 +1172,11 @@ def stock_item_view(request): if request.method=="POST": departmentId = request.POST.get('departmentId') - grade = request.POST.get('grade') type = request.POST.get('item_type') # StockEntryId__item_id__file_info_grade StockItems = StockItem.objects.filter( department=departmentId, - StockEntryId__item_id__grade=grade, StockEntryId__item_id__item_type=type ) @@ -1020,7 +1190,6 @@ def stock_entry_view(request): if request.session['currentDesignationSelected'] not in dept_admin_design + ["ps_admin"]: return redirect('/dashboard') - department = request.user.extrainfo.department if request.session['currentDesignationSelected'] in dept_admin_design: # if department admin then only show the stocks of that department to them @@ -1305,11 +1474,9 @@ def stock_transfer(request): temp1=IndentFile.objects.get(file_info=temp) item_type_required =temp1.item_type - item_grade_required = temp1.grade available_items = StockItem.objects.filter( StockEntryId__item_id__item_type=item_type_required, # Foreign key traversal to IndentFile model - StockEntryId__item_id__grade=item_grade_required, # Foreign key traversal to IndentFile model inUse=False # Filter for inUse=False ) @@ -1339,7 +1506,6 @@ def view_transfer(request): return render(request,'ps1/view_transfer.html',{'stockTransfers': stockTransfers}) - @login_required(login_url = "/accounts/login") def outboxview2(request,id): abcd = HoldsDesignation.objects.get(pk=id) @@ -1360,12 +1526,13 @@ def outboxview2(request,id): @login_required(login_url = "/accounts/login") def outboxview(request): - designation = HoldsDesignation.objects.filter(user=request.user) - context = { - 'designation': designation, - } + if request.session['currentDesignationSelected'] == "student": + return redirect('/dashboard') + + designation = HoldsDesignation.objects.filter(user=request.user, designation__name=request.session['currentDesignationSelected']).first() + - return render(request, 'ps1/outboxview.html', context) + return redirect(f'/purchase-and-store/outboxview2/{designation.id}') @login_required(login_url="/accounts/login") diff --git a/FusionIIIT/applications/research_procedures/admin.py b/FusionIIIT/applications/research_procedures/admin.py index 77adc5b1c..e9cb225c4 100644 --- a/FusionIIIT/applications/research_procedures/admin.py +++ b/FusionIIIT/applications/research_procedures/admin.py @@ -1,30 +1,21 @@ from django.contrib import admin -from applications.research_procedures.models import Patent, ResearchGroup,ResearchProject,ConsultancyProject,TechTransfer +from applications.research_procedures.models import * from django.utils.html import format_html # Adding a custom admin view for patent -class PatentAdmin(admin.ModelAdmin): - - list_filter = ('status',) - search_fields = ['title', 'application_id'] - - def _status(self, obj): - color = "orange" - if obj.status == "Approved": - color = "green" - elif obj.status == "Disapproved": - color = "red" - return format_html('%s' % (color, obj.status)) - - list_display = ["faculty_id","title","_status"] - class ResearchGroupAdmin(admin.ModelAdmin): list_display = ["name","description"] # Register your models here. -admin.site.register(Patent,PatentAdmin) -admin.site.register(ResearchProject) -admin.site.register(ConsultancyProject) -admin.site.register(TechTransfer) + +admin.site.register(projects) +admin.site.register(staff_allocations) +admin.site.register(financial_outlay) +admin.site.register(category) +# admin.site.register(requests) +# admin.site.register(rspc_inventory) +# admin.site.register(project_staff_info) + + # admin.site.register(ResearchGroup,ResearchGroupAdmin) \ No newline at end of file diff --git a/FusionIIIT/applications/research_procedures/api/serializers.py b/FusionIIIT/applications/research_procedures/api/serializers.py index 86ed8b726..5c4a8bc34 100644 --- a/FusionIIIT/applications/research_procedures/api/serializers.py +++ b/FusionIIIT/applications/research_procedures/api/serializers.py @@ -1,8 +1,51 @@ from rest_framework.serializers import ModelSerializer -from applications.research_procedures.models import Patent +from rest_framework import serializers + +from applications.research_procedures.models import * # Create a Serializer for Model Patent -class PatentSerializer(ModelSerializer): +class ProjectSerializer(ModelSerializer): + class Meta: + # model = projects + fields = '__all__' + +class Project_serializer(serializers.ModelSerializer): + class Meta: + model = projects + fields = '__all__' + + def create(self, validated_data): + return projects.objects.create(**validated_data) + +class financial_outlay_serializer(serializers.ModelSerializer): + class Meta: + model = financial_outlay + fields = '__all__' + + def create(self, validated_data): + return financial_outlay.objects.create(**validated_data) + +class category_serializer(serializers.ModelSerializer): class Meta: - model = Patent - fields = '__all__' \ No newline at end of file + model = category + fields = '__all__' + + def create(self, validated_data): + return category.objects.create(**validated_data) + +class staff_allocations_serializer(serializers.ModelSerializer): + class Meta: + model = staff_allocations + fields = '__all__' + + def create(self, validated_data): + return staff_allocations.objects.create(**validated_data) + +class requests_serializer(serializers.ModelSerializer): + class Meta: + model = requests + fields = '__all__' + + def create(self, validated_data): + return requests.objects.create(**validated_data) + diff --git a/FusionIIIT/applications/research_procedures/api/urls.py b/FusionIIIT/applications/research_procedures/api/urls.py index 67a7e1fd3..232dda90c 100644 --- a/FusionIIIT/applications/research_procedures/api/urls.py +++ b/FusionIIIT/applications/research_procedures/api/urls.py @@ -1,8 +1,45 @@ from rest_framework.routers import DefaultRouter -from .views import PatentViewSet +from .views import * +from django.urls import include,path +from django.conf.urls import url +from . import views + +app_name="research_procedures" router = DefaultRouter() -router.register(r'patent', PatentViewSet) +# router.register(r'patent', PatentViewSet) urlpatterns = router.urls + +urlpatterns = [ + # url(r'^$', views.view_projects, name='patent_registration'), + # url(r'^update$', views.patent_status_update, name='patent_status_update'), + # url(r'^research_group$', views.research_group_create, name='research_group_create'), + # url(r'^project_insert$',views.project_insert,name='project_insert'), + # url(r'^consult_insert$',views.consult_insert,name='consult_insert'), + # url(r'^add_projects$',views.add_projects,name='add_projects'), + # url(r'^view_projects$',views.view_projects,name='view_projects'), + # # path('add_requests///',views.add_requests,name='add_requests'), + # url(r'^api/',include('applications.research_procedures.api.urls')), + # path('view_requests//',views.view_requests), + path('projects',views.view_projects), + # path('view_project_info//',views.view_project_info), + # path('submit_closure_report//',views.submit_closure_report, name="submit_closure_report"), + # path('add_fund_requests//',views.add_fund_requests, name="add_fund_requests"), + # path('add_staff_requests//',views.add_staff_requests, name="add_staff_requests"), + # path('view_project_inventory//',views.view_project_inventory, name="view_project_inventory"), + # path('view_project_staff//',views.view_project_staff, name="view_project_staff"), + # path('add_financial_outlay//',views.add_financial_outlay, name="add_financial_outlay"), + # path('financial_outlay//',views.financial_outlay_form, name="financial_outlay_form"), + # path('view_financial_outlay//',views.view_financial_outlay, name="view_financial_outlay"), + # path('add_staff_details//',views.add_staff_details, name="add_staff_details"), + # path('view_staff_details//',views.view_staff_details, name="view_staff_details"), + # path('add_staff_request//',views.add_staff_request, name="add_staff_request"), + # path('inbox',views.inbox, name="inbox"), + # path('view_request_inbox',views.view_request_inbox, name="view_request_inbox"), + # path('forward_request',views.forward_request, name="forward_request"), + + + +] print("URL patterns",urlpatterns) \ No newline at end of file diff --git a/FusionIIIT/applications/research_procedures/api/views.py b/FusionIIIT/applications/research_procedures/api/views.py index 169ffde1a..3addf40d4 100644 --- a/FusionIIIT/applications/research_procedures/api/views.py +++ b/FusionIIIT/applications/research_procedures/api/views.py @@ -1,9 +1,752 @@ from rest_framework.viewsets import ModelViewSet -from applications.research_procedures.models import Patent -from .serializers import PatentSerializer +from applications.research_procedures.models import * +from .serializers import * from rest_framework.permissions import IsAuthenticatedOrReadOnly +from django.shortcuts import redirect, render, get_object_or_404 +from rest_framework.response import Response +from django.contrib import messages +from applications.research_procedures.models import * +from applications.globals.models import ExtraInfo, HoldsDesignation, Designation +from django.core.files.storage import FileSystemStorage +from django.core.exceptions import ObjectDoesNotExist +from notification.views import research_procedures_notif +from django.urls import reverse +from django.contrib.auth.decorators import login_required +import datetime +from django.utils import timezone + +from collections import defaultdict +from applications.filetracking.sdk.methods import * + +# # Faculty can file patent and view status of it. + +# @login_required +# def patent_registration(request): + + +# return render(request ,"rs/research.html") + +# @login_required +# #dean_rspc can update status of patent. +# def patent_status_update(request): + +# user = request.user +# user_extra_info = ExtraInfo.objects.get(user=user) +# user_designations = HoldsDesignation.objects.filter(user=user) +# if request.method=='POST': +# if(user_designations.exists()): +# if(user_designations.first().designation.name == "dean_rspc" and user_extra_info.user_type == "faculty"): +# patent_application_id = request.POST.get('id') +# patent = Patent.objects.get(application_id=patent_application_id) +# patent.status = request.POST.get('status') +# patent.save() +# messages.success(request, 'Patent status updated successfully') +# # Create a notification for the user about the patent status update +# dean_rspc_user = HoldsDesignation.objects.get(designation=Designation.objects.filter(name='dean_rspc').first()).working +# research_procedures_notif(dean_rspc_user,patent.faculty_id.user,request.POST.get('status')) +# else: +# messages.error(request, 'Only Dean RSPC can update status of patent') +# return redirect(reverse("research_procedures:patent_registration")) + +# @login_required +# def research_group_create(request): + +# user = request.user +# user_extra_info = ExtraInfo.objects.get(user=user) +# if request.method=='POST': +# if user_extra_info.user_type == "faculty": +# form = ResearchGroupForm(request.POST) + +# if form.is_valid(): +# form.save() +# messages.success(request, 'Research group created successfully') +# else: +# messages.error(request, 'Only Faculty can create research group') +# return redirect(reverse("research_procedures:patent_registration")) + +# @login_required +# def project_insert(request): +# user = get_object_or_404(ExtraInfo, user=request.user) +# pf = user.id + +# research_project = ResearchProject() +# research_project.user = request.user +# research_project.pf_no = pf +# research_project.pi = request.POST.get('pi') +# research_project.co_pi = request.POST.get('co_pi') +# research_project.title = request.POST.get('title') +# research_project.financial_outlay = request.POST.get('financial_outlay') +# research_project.funding_agency = request.POST.get('funding_agency') +# research_project.status = request.POST.get('status') +# x = request.POST.get('start') +# if x[:5] == "Sept." : +# x = "Sep." + x[5:] +# if (request.POST.get('start') != None and request.POST.get('start') != '' and request.POST.get('start') != 'None'): +# try: +# research_project.start_date = datetime.datetime.strptime(x, "%B %d, %Y") +# except: +# research_project.start_date = datetime.datetime.strptime(x, "%b. %d, %Y") +# x = request.POST.get('end') +# if x[:5] == "Sept." : +# x = "Sep." + x[5:] +# if (request.POST.get('end') != None and request.POST.get('end') != '' and request.POST.get('end') != 'None'): +# try: +# research_project.finish_date = datetime.datetime.strptime(x, "%B %d, %Y") +# except: +# research_project.finish_date = datetime.datetime.strptime(x, "%b. %d, %Y") +# x = request.POST.get('sub') +# if x[:5] == "Sept." : +# x = "Sep." + x[5:] +# if (request.POST.get('sub') != None and request.POST.get('sub') != '' and request.POST.get('sub') != 'None'): +# try: +# research_project.date_submission = datetime.datetime.strptime(x, "%B %d, %Y") +# except: +# research_project.date_submission = datetime.datetime.strptime(x, "%b. %d, %Y") +# research_project.save() +# messages.success(request, 'Successfully created research project') +# return redirect(reverse("research_procedures:patent_registration")) + +# @login_required +# def consult_insert(request): +# user = get_object_or_404(ExtraInfo, user=request.user) +# pf = user.id +# consultancy_project = ConsultancyProject() +# consultancy_project.user = request.user +# consultancy_project.pf_no = pf +# consultancy_project.consultants = request.POST.get('consultants') +# consultancy_project.client = request.POST.get('client') +# consultancy_project.title = request.POST.get('title') +# consultancy_project.financial_outlay = request.POST.get('financial_outlay') +# x = request.POST.get('start') +# if x[:5] == "Sept." : +# x = "Sep." + x[5:] +# if (request.POST.get('start') != None and request.POST.get('start') != '' and request.POST.get('start') != 'None'): +# try: +# consultancy_project.start_date = datetime.datetime.strptime(x, "%B %d, %Y") +# except: +# consultancy_project.start_date = datetime.datetime.strptime(x, "%b. %d, %Y") +# x = request.POST.get('end') +# if x[:5] == "Sept." : +# x = "Sep." + x[5:] +# if (request.POST.get('end') != None and request.POST.get('end') != '' and request.POST.get('end') != 'None'): +# try: +# consultancy_project.end_date = datetime.datetime.strptime(x, "%B %d, %Y") +# except: +# consultancy_project.end_date = datetime.datetime.strptime(x, "%b. %d, %Y") +# consultancy_project.save() +# messages.success(request,"Successfully created consultancy project") +# return redirect(reverse("research_procedures:patent_registration")) + +# def add_projects(request): +# if request.method== "POST": +# obj= request.POST +# projectname= obj.get('project_name') +# projecttype= obj.get('project_type') +# fo= obj.get('financial_outlay') +# pid= obj.get('project_investigator_id') +# copid=obj.get('co_project_investigator_id') +# sa= obj.get('sponsored_agency') +# startd= obj.get('start_date') +# subd= obj.get('finish_date') +# finishd= obj.get('finish_date') +# years= obj.get('number_of_years') +# # project_description= obj.get('description') +# project_info_file= request.FILES.get('project_info_file') + +# check = User.objects.filter(username=pid) +# # print(check[0].username) + + + +# check= HoldsDesignation.objects.filter(user__username=pid , designation__name= "Professor") +# if not check.exists(): +# check= HoldsDesignation.objects.filter(user__username=pid , designation__name= "Assistant Professor") + +# if not check.exists(): +# messages.error(request,"Request not added, no such project investigator exists 2") +# return render(request,"rs/projects.html") + + +# check= HoldsDesignation.objects.filter(user__username=copid , designation__name= "Professor") +# if not check.exists(): +# check= HoldsDesignation.objects.filter(user__username=copid , designation__name= "Assistant Professor") + +# if not check.exists(): +# messages.error(request,"Request not added, no such project investigator exists 2") +# return render(request,"rs/projects.html") + + +# obj= projects.objects.all() +# if len(obj)==0 : +# projectid=1 + +# else : +# projectid= obj[0].project_id+1 + +# userpi_instance = User.objects.get(username=pid) +# usercpi_instance = User.objects.get(username=copid) + +# projects.objects.create( +# project_id=projectid, +# project_name=projectname, +# project_type=projecttype, +# status=0, +# project_investigator_id=userpi_instance, +# co_project_investigator_id=usercpi_instance, +# sponsored_agency=sa, +# start_date=startd, +# submission_date=finishd, +# finish_date=finishd, +# years=years, +# project_info_file=project_info_file + +# ) +# project_investigator_designation = HoldsDesignation.objects.get(user=userpi_instance).designation + +# file_x= create_file( +# uploader=request.user.username, +# uploader_designation="rspc_admin", +# receiver= pid, +# receiver_designation=project_investigator_designation, +# src_module="research_procedures", +# src_object_id= projectid, +# file_extra_JSON= { "message": "Project added successfully"}, +# attached_file= project_info_file, +# ) + +# messages.success(request,"Project added successfully") +# categories = category.objects.all() + +# data = { +# "pid": pid, +# "years": list(range(1, int(years) + 1)), +# "categories": categories, +# } + +# return redirect("/research_procedures/financial_outlay/"+str(projectid)) +# return render(request,"rs/projects.html") + +# def add_fund_requests(request,pj_id): +# data= { +# "pj_id": pj_id +# } +# return render(request,"rs/add_fund_requests.html",context=data) + +# def add_staff_requests(request,pj_id): +# data= { +# "pj_id": pj_id +# } +# return render(request,"rs/add_staff_requests.html",context=data) + +# def add_requests(request,id,pj_id): +# if request.method == 'POST': +# obj=request.POST + + +# if(id=='0') : +# projectid = pj_id +# reqtype = obj.get('request_type') +# stats =0 +# desc= obj.get('description') +# amt= obj.get('amount') + +# check= projects.objects.filter(project_id=projectid) +# if not check.exists(): +# messages.error(request,"Request not added, no such project exists") +# return render(request,"rs/add_fund_requests.html") + +# check= projects.objects.filter(project_id= projectid, project_investigator_id__username=pi_id) +# if not check.exists(): +# messages.error(request,"Request not added, no such project investigator exists") +# return render(request,"rs/add_fund_requests.html") + + +# pi_id_instance=User.objects.get(username= request.user.username ) +# project_instance=projects.objects.get(project_id=projectid) + +# obj= requests.objects.all() +# if len(obj)==0 : +# requestid=1 + +# else : +# requestid= obj[0].request_id+1 + +# requests.objects.create( +# request_id=requestid, +# project_id=project_instance, +# request_type="funds", +# project_investigator_id=pi_id_instance, +# status=stats, description=desc, amount= amt +# ) +# rspc_inventory.objects.create( +# inventory_id=requestid, +# project_id=project_instance, +# project_investigator_id=pi_id_instance, +# status=stats, +# description=desc, amount= amt +# ) +# messages.success(request,"Request added successfully") +# return render(request,"rs/add_fund_requests.html") + +# if(id=='1'): +# projectid = obj.get('project_id') +# pi_id = obj.get('project_investigator_id') +# stats = obj.get('status') +# desc= obj.get('description') + +# obj= requests.objects.all() +# if len(obj)==0 : +# requestid=1 + +# else : +# requestid= obj[0].request_id+1 + + +# check= projects.objects.filter(project_id=projectid) +# if not check.exists(): +# messages.error(request,"Request not added, no such project exists") +# return render(request,"rs/add_fund_requests.html") + +# check= projects.objects.filter(project_id= projectid, project_investigator_id__username=pi_id) +# if not check.exists(): +# messages.error(request,"Request not added, no such project investigator exists") +# return render(request,"rs/add_fund_requests.html") + +# pi_id_instance=User.objects.get(username=pi_id) +# project_instance=projects.objects.get(project_id=projectid) + +# requests.objects.create( +# request_id=requestid, +# project_id=project_instance, +# request_type="staff", +# project_investigator_id=pi_id_instance, +# description=desc +# ) +# messages.success(request,"Request added successfully") +# return redirect("/research_procedures") +# return render(request, "rs/add_requests.html") + + + +def view_projects(request): + queryset= projects.objects.all() + + rspc_admin = HoldsDesignation.objects.get(designation__name="rspc_admin") + rspc_admin =rspc_admin.user.username + if request.user.username == rspc_admin: + data= { + "projects": queryset, + "username": request.user.username, + } + return render(request,"rs/view_projects_rspc.html", context= data) + + queryset= projects.objects.filter(project_investigator_id__username= request.user.username) + + data= { + "projects": queryset, + "username": request.user.username, + } + # print(data) + # print(request.user.username) + + return Response(data, status=status.HTTP_200_OK) + +# def view_requests(request,id): + +# if id== '1': +# queryset= requests.objects.filter(request_type= "staff") +# elif id== '0': +# rspc_admin = HoldsDesignation.objects.get(designation__name="rspc_admin") +# rspc_admin =rspc_admin.user.username +# if request.user.username == rspc_admin : +# queryset= rspc_inventory.objects.all() +# data= { +# "requests": queryset, +# "username": request.user.username +# } +# return render(request,"rs/view_requests.html", context= data) + + +# queryset= rspc_inventory.objects.filter(project_investigator_id = request.user.username ) +# else: +# render(request,"/404.html") + +# data= { +# "requests": queryset, +# "username": request.user.username, +# "id":id, +# } + +# # print(data) +# # print(request.user.username) + +# return render(request,"rs/view_requests.html", context= data) + +# def view_financial_outlay(request,pid): + +# table_data=financial_outlay.objects.filter(project_id=pid).order_by('category', 'sub_category') +# project= projects.objects.get(project_id=pid); + +# years = set(table_data.values_list('year', flat=True)) + +# category_data = {} +# for category in table_data.values_list('category', flat=True).distinct(): +# category_data[category] = table_data.filter(category=category) + + +# data = { +# 'table_title': 'Total Budget Outlay', +# 'table_caption': '...', # Add caption if needed +# 'project_name':project.project_name, +# 'years': list(years), +# 'category_data': category_data, +# } + +# # print(data) +# return render(request,"rs/view_financial_outlay.html", context= data) + +# def submit_closure_report(request,id): +# id= int(id) +# obj= projects.objects.get(project_id=id) +# obj.status= 1; +# obj.save() + +# queryset= projects.objects.filter(project_investigator_id = request.user.username) + +# # print(queryset) + +# data= { +# "projects": queryset, +# "username": request.user.username +# } +# messages.success(request,"Closure report submitted successfully") +# return render(request,"rs/view_projects_rspc.html",context=data) + +# def view_project_inventory(request,pj_id): +# pj_id=int(pj_id) +# queryset= requests.objects.filter(project_id=pj_id,request_type="funds") + + +# # print(queryset) + +# data= { +# "requests": queryset, +# "username": request.user.username +# } +# return render(request,"rs/view_project_inventory.html",context=data) + +# def view_project_staff(request,pj_id): +# pj_id=int(pj_id) +# queryset= requests.objects.filter(project_id=pj_id,request_type="staff") + + +# # print(queryset) + +# data= { +# "requests": queryset, +# "username": request.user.username +# } +# return render(request,"rs/view_project_staff.html",context=data) + +# def projectss(request): +# return render(request,"rs/projects.html") + +# def view_project_info(request,id): +# id= int(id) +# obj= projects.objects.get(project_id=id) + + + +# data = { +# "project": obj, +# } + +# return render(request,"rs/view_project_info.html", context= data) + +# def financial_outlay_form(request,pid): +# pid= int(pid) +# project= projects.objects.get(project_id=pid); +# categories = category.objects.all().distinct(); + +# categories_with_subcategories = category.objects.values('category_name', 'sub_category_name') + +# # Organize the data into a dictionary +# category_subcategory_map = {} +# for item in categories_with_subcategories: +# category_name = item['category_name'] +# subcategory = item['sub_category_name'] +# if category_name in category_subcategory_map: +# category_subcategory_map[category_name].append(subcategory) +# else: +# category_subcategory_map[category_name] = [subcategory] + +# # Pass the organized data to the template + +# data = { +# "project_id": project.project_id, +# "project_name":project.project_name, +# "years": list(range(1, int(project.years) + 1)), +# "category_subcategory_map": category_subcategory_map + +# } + +# return render(request,"rs/add_financial_outlay.html", context= data) +# # return render(request,"rs/add_financial_outlay.html", context= data) + + + +# def add_staff_details(request, pid): +# if request.method == 'POST': +# obj = request.POST +# for key, value in obj.items(): +# if key.startswith('staff_id'): +# year_count = key.split('-')[-2] +# staff_count = key.split('-')[-1] +# staff_id_key = f'staff_id-{year_count}-{staff_count}' +# staff_name_key = f'staff_name-{year_count}-{staff_count}' +# qualification_key = f'qualification-{year_count}-{staff_count}' +# stipend_key = f'stipend-{year_count}-{staff_count}' +# year = year_count +# staff_id = obj.get(staff_id_key, '').strip() +# staff_name = obj.get(staff_name_key, '').strip() +# qualification = obj.get(qualification_key, '').strip() +# stipend = obj.get(stipend_key, '').strip() +# project_instance = projects.objects.get(project_id=pid) +# # print(type(staff_id)) +# ob = staff_allocations.objects.all() + +# if len(ob) == 0: +# fid = 1 +# else: +# fid = ob[0].staff_allocation_id + 1 + +# staff_id_instance = User.objects.get(username=staff_id) + + +# staff_allocations.objects.create( +# staff_allocation_id=fid, +# project_id=project_instance, +# staff_id=staff_id_instance, +# staff_name=staff_name, +# qualification=qualification, +# year=year, +# stipend=stipend +# ) + +# return redirect("/research_procedures/view_staff_details/"+str(pid)) + +# project = projects.objects.get(project_id=pid) + +# years_passed = int((datetime.datetime.now().date() - project.start_date).days / 365.25) + +# data = { +# "project_id": project.project_id, +# "project_name" : project.project_name, +# "years": list(range(1, int(project.years) + 1)), +# "year": int(years_passed) + 1, +# } + +# return render(request, "rs/add_staff_details.html", context=data) + + +# def view_staff_details(request,pid): + +# staff_records = staff_allocations.objects.filter(project_id=pid) + +# # Initialize a dictionary to hold data year-wise +# data_by_year = {} +# project = projects.objects.get(project_id=pid) + +# # Iterate through each staff record +# for record in staff_records: +# year = record.year +# if year not in data_by_year: +# data_by_year[year] = [] +# data_by_year[year].append({ +# 'staff_id' : record.staff_id, +# 'staff_name': record.staff_name, +# 'qualification': record.qualification, +# 'stipend': record.stipend +# }) +# # Pass the organized data to the template +# context = { +# 'data_by_year': data_by_year, +# 'project_name':project.project_name +# } +# rspc_admin = HoldsDesignation.objects.get(designation__name="rspc_admin") + + +# return render(request, "rs/view_staff_details.html", context) + + + +# def add_financial_outlay(request,pid): +# if request.method == 'POST': + +# project = projects.objects.get(project_id=pid) +# project.financial_outlay_status = 1 +# project.save() + +# obj = request.POST +# for key, value in obj.items(): +# if key.startswith('category-select'): +# year_count = key.split('-')[-2] +# category_count = key.split('-')[-1] +# subcategory_key = f'subcategory-select-{year_count}-{category_count}' +# amount_key = f'amount-{year_count}-{category_count}' + +# category = value +# subcategory = obj.get(subcategory_key, ['']) +# amount = obj.get(amount_key, ['']) +# year = int(year_count) + +# # print(year) +# # print(amount) +# # print(subcategory) +# # print(category) +# project_instance=projects.objects.get(project_id=pid) + + +# ob= financial_outlay.objects.all() +# if len(ob)==0 : +# fid=1 + +# else : +# fid= ob[0].financial_outlay_id+1 +# financial_outlay.objects.create( +# financial_outlay_id=fid, +# project_id=project_instance, +# category=category, +# sub_category=subcategory, +# amount=amount, +# year=year, +# status=0, +# staff_limit=0 +# ) + + +# return redirect("/research_procedures/view_financial_outlay/"+str(pid)) + +# def inbox(request): + + +# user_designation= getDesignation(request.user.username) +# print(user_designation) +# data = view_inbox(request.user.username,user_designation, "research_procedures") +# files= [] +# count =0 +# for i in data: +# count+=1 +# file1= File.objects.get(id=i['id']) +# files.append((count, file1)) + + +# data={ + +# "inbox": data, +# "files": files +# } +# # print(data) +# return render(request, "rs/inbox.html",context= data) + +# def add_staff_request(request,id): +# if request.method == 'POST': +# obj= request.POST +# projectid = int(id) +# receiver = obj.get('receiver') + + +# sender = request.user.username +# file_to_forward= request.FILES.get('file_to_forward') +# project_instance=projects.objects.get(project_id=projectid) +# receiver_instance=User.objects.get(username=receiver) +# sender_designation= HoldsDesignation.objects.get(user= request.user).designation +# receiver_designation = HoldsDesignation.objects.get(user= receiver_instance).designation + +# file_x= create_file( +# uploader=sender, +# uploader_designation=sender_designation, +# receiver= receiver_instance.username, +# receiver_designation=receiver_designation, +# src_module="research_procedures", +# src_object_id= projectid, +# file_extra_JSON= { "message": "Staff request added ("+ str(projectid)+ ")"}, +# attached_file= file_to_forward, +# ) +# messages.success(request,"Staff request added successfully") + +# return redirect("/research_procedures/view_project_info/"+ str(projectid)) + +# def view_request_inbox(request): +# user_designation= getDesignation(request.user.username) +# print(user_designation) +# data = view_inbox(request.user.username,user_designation, "research_procedures") +# files= [] +# count =0 +# for i in data: +# count+=1 +# file1= File.objects.get(id=i['id']) +# files.append((count, file1)) + + +# data={ + +# "inbox": data, +# "files": files +# } +# # print(data) +# # return render(request, "rs/view_request_inbox.html",context= data) +# return Response(data, status=status.HTTP_200_OK) + + +# def forward_request(request): +# if request.method == 'POST': +# obj= request.POST +# fileid = int(obj.get('file_id')) +# receiver = obj.get('receiver') +# message= obj.get('message') +# receiver_instance= User.objects.get(username=receiver) +# receiver_designation= HoldsDesignation.objects.get(user=receiver_instance).designation +# sender = request.user.username + +# filex= get_file_by_id(fileid) + +# file2=create_file( +# uploader=sender, +# uploader_designation= getDesignation(sender), +# receiver= receiver, +# receiver_designation=receiver_designation, +# src_module="research_procedures", +# src_object_id= filex.src_object_id, +# file_extra_JSON= { "message": message}, +# attached_file= filex.upload_file, +# ) + +# delete_file(fileid) +# messages.success(request,"Request forwarded successfully") +# return redirect("/research_procedures/view_request_inbox") + + +# return redirect("/research_procedures/view_request_inbox") + +# def getDesignation(us): +# user_inst = User.objects.get(username= us) +# user_designation= HoldsDesignation.objects.get(user= user_inst).designation +# return user_designation + +# def get_file_by_id(id): +# file1= File.objects.get(id=id) +# print(file1) +# return file1 + +# def delete_file(id): +# file1= File.objects.get(id=id) +# tracking= Tracking.objects.get(file_id=file1) +# tracking.delete() +# file1.delete() +# return + + + + -class PatentViewSet(ModelViewSet): - queryset = Patent.objects.all() - serializer_class = PatentSerializer - permission_classes = [ IsAuthenticatedOrReadOnly ] \ No newline at end of file diff --git a/FusionIIIT/applications/research_procedures/forms.py b/FusionIIIT/applications/research_procedures/forms.py index f12601a38..b291b2dae 100644 --- a/FusionIIIT/applications/research_procedures/forms.py +++ b/FusionIIIT/applications/research_procedures/forms.py @@ -1,40 +1,40 @@ from django import forms -from .models import ResearchGroup +from .models import * from django.contrib.auth.models import User -class ResearchGroupForm(forms.ModelForm): +# class ResearchGroupForm(forms.ModelForm): - students = forms.ModelMultipleChoiceField(queryset=User.objects.all(), widget=forms.SelectMultiple(attrs={'class':'ui fluid search dropdown'})) - faculty = forms.ModelMultipleChoiceField(queryset=User.objects.all(), widget=forms.SelectMultiple(attrs={'class':'ui fluid search dropdown'})) +# students = forms.ModelMultipleChoiceField(queryset=User.objects.all(), widget=forms.SelectMultiple(attrs={'class':'ui fluid search dropdown'})) +# faculty = forms.ModelMultipleChoiceField(queryset=User.objects.all(), widget=forms.SelectMultiple(attrs={'class':'ui fluid search dropdown'})) - def __init__(self, *args, **kwargs): - if kwargs.get('instance'): - initial = kwargs.setdefault('initial', {}) - initial['students_under_group'] = [t.pk for t in kwargs['instance'].students_under_group.all()] - initial['faculty_under_group'] = [t.pk for t in kwargs['instance'].faculty_under_group.all()] +# def __init__(self, *args, **kwargs): +# if kwargs.get('instance'): +# initial = kwargs.setdefault('initial', {}) +# initial['students_under_group'] = [t.pk for t in kwargs['instance'].students_under_group.all()] +# initial['faculty_under_group'] = [t.pk for t in kwargs['instance'].faculty_under_group.all()] - forms.ModelForm.__init__(self, *args, **kwargs) +# forms.ModelForm.__init__(self, *args, **kwargs) - def save(self, commit=True): - instance = forms.ModelForm.save(self, False) +# def save(self, commit=True): +# instance = forms.ModelForm.save(self, False) - old_save_m2m = self.save_m2m - def save_m2m(): - old_save_m2m() - instance.students_under_group.clear() - instance.students_under_group.add(*self.cleaned_data['students']) - instance.faculty_under_group.clear() - instance.faculty_under_group.add(*self.cleaned_data['faculty']) - self.save_m2m = save_m2m +# old_save_m2m = self.save_m2m +# def save_m2m(): +# old_save_m2m() +# instance.students_under_group.clear() +# instance.students_under_group.add(*self.cleaned_data['students']) +# instance.faculty_under_group.clear() +# instance.faculty_under_group.add(*self.cleaned_data['faculty']) +# self.save_m2m = save_m2m - if commit: - instance.save() - self.save_m2m() +# if commit: +# instance.save() +# self.save_m2m() - return instance +# return instance - class Meta: - model = ResearchGroup - fields = ('name','students','faculty','description',) \ No newline at end of file +# class Meta: +# model = ResearchGroup +# fields = ('name','students','faculty','description',) \ No newline at end of file diff --git a/FusionIIIT/applications/research_procedures/migrations/0001_initial.py b/FusionIIIT/applications/research_procedures/migrations/0001_initial.py index 2befdff1a..4de9b80a1 100644 --- a/FusionIIIT/applications/research_procedures/migrations/0001_initial.py +++ b/FusionIIIT/applications/research_procedures/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1.5 on 2024-04-15 23:58 +# Generated by Django 3.1.5 on 2024-04-14 19:17 import datetime from django.conf import settings diff --git a/FusionIIIT/applications/research_procedures/models.py b/FusionIIIT/applications/research_procedures/models.py index 559b56fd9..9279939d2 100644 --- a/FusionIIIT/applications/research_procedures/models.py +++ b/FusionIIIT/applications/research_procedures/models.py @@ -1,6 +1,6 @@ from django.db import models from django.db import models -from applications.globals.models import ExtraInfo +from applications.globals.models import * from django.contrib.auth.models import User import datetime @@ -11,96 +11,127 @@ class Constants: ('Pending' , 'Pending') ) -class Patent(models.Model): - """ - Holds Patents filed by faculty. - - @fields: - faculty_id - Extra information of the faculty who filed the patent. - title - Title of the patent - ipd_form - IPD form of the patent - ipd_form_file - Contains the url of the ipd_form pdf uploaded by the faculty - project_details - Project details of the patent - project_details_file - Contains the url of the project_details pdf uploaded by the faculty - status - Status of the patent - """ - - application_id = models.AutoField(primary_key=True) - faculty_id = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) - title = models.CharField(max_length=120) - ipd_form = models.FileField(null = True, blank= True) - project_details = models.FileField(null = True, blank= True) - ipd_form_file = models.TextField(null=True, blank=True) - project_details_file = models.TextField(null=True, blank=True) - status = models.CharField(choices=Constants.RESPONSE_TYPE, max_length=20, default='Pending') - - def _str_(self): - return str(self.title) - - -class ResearchGroup(models.Model): - name = models.CharField(max_length=120) - faculty_under_group = models.ManyToManyField(User,related_name="allfaculty") - students_under_group = models.ManyToManyField(User,related_name="allstudents") - description = models.TextField() - - def _str_(self): - return str(self.name) - - -class ResearchProject(models.Model): - user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True,null=True) - pf_no = models.IntegerField() - ptype = models.CharField(max_length=100, default="Research") - pi = models.CharField(max_length=1000, default=" ") - co_pi = models.CharField(max_length=1500, default=" ") - title = models.TextField(max_length=5000, default=" ") - funding_agency = models.CharField(max_length=250, default=" ", null=True) - financial_outlay = models.CharField(max_length=150, default=" ", null=True) - STATUS_TYPE_CHOICES = ( - ('Awarded', 'Awarded'), - ('Submitted', 'Submitted'), - ('Ongoing', 'Ongoing'), - ('Completed', 'Completed') - ) - status = models.CharField(max_length = 10, choices = STATUS_TYPE_CHOICES) - start_date = models.DateField(null=True, blank=True) - finish_date = models.DateField(null=True, blank=True) - date_submission = models.DateField(null=True, blank=True) - date_entry = models.DateField(null=True, blank=True, default=datetime.datetime.now) + +class projects(models.Model): + project_id= models.IntegerField(primary_key= True) + project_name= models.CharField(max_length=600) + project_type= models.CharField(max_length=500) + # financial_outlay= models.IntegerField() + project_investigator_id=models.ForeignKey(User,related_name='pi_id', on_delete=models.CASCADE) + # rspc_admin_id=models.CharField(max_length=500) + co_project_investigator_id=models.ForeignKey(User,related_name='copi_id' ,on_delete=models.CASCADE, null=True) + sponsored_agency= models.CharField(max_length=500) + start_date=models.DateField() + submission_date=models.DateField() + finish_date=models.DateField() + years= models.IntegerField() + status= models.IntegerField(default=0) + project_info_file=models.FileField( null=True, blank=True) + # project_description=models.CharField(max_length=500 ,default="description") + financial_outlay_status=models.IntegerField(default=0) + def __str__(self): - return 'PF No.: {} pi: {} title: {}'.format(self.pf_no,self.pi, self.title) - -class ConsultancyProject(models.Model): - user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True,null=True) - pf_no = models.IntegerField() - consultants = models.CharField(max_length=150) - title = models.CharField(max_length=1000) - client = models.CharField(max_length=1000) - financial_outlay = models.IntegerField() - start_date = models.DateField(null=True, blank=True) - end_date = models.DateField(null=True, blank=True) - duration = models.CharField(max_length=500, null=True, blank=True) - date_entry = models.DateField(null=True, blank=True, default=datetime.datetime.now) - STATUS_TYPE_CHOICES = ( - ('Completed', 'Completed'), - ('Submitted', 'Submitted'), - ('Ongoing', 'Ongoing') - ) - status = models.CharField(default = 'Ongoing', max_length = 10, choices = STATUS_TYPE_CHOICES, null=True, blank=True) - remarks = models.CharField(max_length=1000, null=True, blank=True) + return str(self.project_id) + + class Meta: + ordering = ['-project_id'] + +class financial_outlay(models.Model): + financial_outlay_id= models.IntegerField(primary_key=True) + project_id= models.ForeignKey(projects, on_delete=models.CASCADE) + category=models.CharField(max_length=500) + sub_category=models.CharField(max_length=500) + amount=models.IntegerField() + year=models.IntegerField() + status= models.IntegerField(default=0) + staff_limit=models.IntegerField(default=0) + utilized_amount=models.IntegerField(default=0,null= True) + + def __str__(self): + return str(self.financial_outlay_id) + + class Meta: + ordering = ['-financial_outlay_id'] + + +class category(models.Model): + category_id= models.IntegerField(primary_key=True) + category_name= models.CharField(max_length=500) + sub_category_name= models.CharField(max_length=500) + + + def __str__(self): + return str(self.category_id) + + class Meta: + ordering = ['-category_id'] + + +class staff_allocations(models.Model): + staff_allocation_id=models.IntegerField(primary_key=True) + project_id= models.ForeignKey(projects, on_delete=models.CASCADE) + staff_id=models.ForeignKey(User, on_delete=models.CASCADE) + staff_name=models.CharField(max_length=500) + qualification=models.CharField(max_length=500) + year=models.IntegerField() + stipend=models.IntegerField() + staff_type=models.CharField(max_length=100,default="research") + start_date=models.DateField(default=datetime.date.today()) #default=datetime.date.today() + end_date=models.DateField(null=True, blank=True) def __str__(self): - return 'PF No.: {} Consultants: {}'.format(self.pf_no, self.consultants) + return str(self.staff_allocation_id) + + + + class Meta: + ordering = ['-staff_allocation_id'] -class TechTransfer(models.Model): - user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True,null=True) - pf_no = models.IntegerField() - details = models.CharField(max_length=500, default=" ") - date_entry = models.DateField(null=True, blank=True, default=datetime.datetime.now) - start_date = models.DateField(null=True,blank=True) - end_date = models.DateField(null=True,blank=True) +class requests(models.Model): + request_id=models.IntegerField(primary_key=True) + project_id= models.ForeignKey(projects, on_delete=models.CASCADE) + request_type=models.CharField(max_length=500) + project_investigator_id=models.ForeignKey(User, related_name='rj_pi' , on_delete= models.CASCADE) + approval_status= models.IntegerField(default=0) #value 0 means pending def __str__(self): - return 'PF No.: {} Details: {}'.format(self.pf_no, self.details) \ No newline at end of file + return str(self.request_id) + + class Meta: + ordering = ['-request_id'] + +# class requests(models.Model): +# request_id=models.IntegerField(primary_key=True) +# project_id= models.ForeignKey(projects, on_delete=models.CASCADE) +# request_type=models.CharField(max_length=500) +# project_investigator_id=models.ForeignKey(User, related_name='rj_pi' , on_delete= models.CASCADE) +# status= models.IntegerField(default=0) #value 0 means pending +# description=models.CharField(max_length=400,default=None, null= True) +# amount= models.IntegerField(default=0) #value 0 means pending + +# class Meta: +# ordering = ['-request_id'] + +# class rspc_inventory(models.Model): +# inventory_id=models.IntegerField(primary_key=True) +# project_id= models.ForeignKey(projects, on_delete=models.CASCADE) +# project_investigator_id=models.ForeignKey(User, related_name="rin_pi" , on_delete= models.CASCADE) +# status= models.IntegerField(default=0) #value 0 means pending +# description=models.CharField(max_length=400) +# amount= models.IntegerField(default=0) #value 0 means pending + +# class project_staff_info(models.Model): +# staff_id=models.CharField(primary_key=True,max_length=400) +# project_investigator_id= models.ForeignKey(User, on_delete=models.CASCADE) +# project_id=models.ForeignKey(projects, related_name='p_pji', on_delete=models.CASCADE) +# staff_name=models.CharField(max_length=400) +# status=models.IntegerField(default=0) +# description=models.CharField(max_length=400) + + + + + + + diff --git a/FusionIIIT/applications/research_procedures/tests.py b/FusionIIIT/applications/research_procedures/tests.py index c6fa3f281..e6b4dfb93 100644 --- a/FusionIIIT/applications/research_procedures/tests.py +++ b/FusionIIIT/applications/research_procedures/tests.py @@ -1,4 +1,15 @@ from django.test import TestCase - +from django.shortcuts import render +from django.http import HttpResponse +from django.http import JsonResponse +import json +from applications.research_procedures.models import * # Create your tests here . +def testfun(request): + # received_json_data=json.loads(request.body) + # print(received_json_data['name']) + data = {} + + return JsonResponse(list(data),safe=False) + \ No newline at end of file diff --git a/FusionIIIT/applications/research_procedures/urls.py b/FusionIIIT/applications/research_procedures/urls.py index 05e653c74..02a3d332a 100644 --- a/FusionIIIT/applications/research_procedures/urls.py +++ b/FusionIIIT/applications/research_procedures/urls.py @@ -1,16 +1,45 @@ -from django.urls import include +from django.urls import include,path from django.conf.urls import url from . import views - +from . import tests app_name="research_procedures" urlpatterns = [ - url(r'^$', views.patent_registration, name='patent_registration'), + url(r'^$', views.view_projects, name='patent_registration'), url(r'^update$', views.patent_status_update, name='patent_status_update'), url(r'^research_group$', views.research_group_create, name='research_group_create'), url(r'^project_insert$',views.project_insert,name='project_insert'), url(r'^consult_insert$',views.consult_insert,name='consult_insert'), - url(r'^transfer_insert$',views.transfer_insert,name='transfer_insert'), + url(r'^add_projects$',views.add_projects,name='add_projects'), + url(r'^view_projects$',views.view_projects,name='view_projects'), + # path('add_requests///',views.add_requests,name='add_requests'), url(r'^api/',include('applications.research_procedures.api.urls')), + # path('view_requests//',views.view_requests), + path('view_project_info//',views.view_project_info), + # path('submit_closure_report//',views.submit_closure_report, name="submit_closure_report"), + # path('add_fund_requests//',views.add_fund_requests, name="add_fund_requests"), + # path('add_staff_requests//',views.add_staff_requests, name="add_staff_requests"), + # path('view_project_inventory//',views.view_project_inventory, name="view_project_inventory"), + # path('view_project_staff//',views.view_project_staff, name="view_project_staff"), + path('add_financial_outlay//',views.add_financial_outlay, name="add_financial_outlay"), + path('financial_outlay//',views.financial_outlay_form, name="financial_outlay_form"), + path('view_financial_outlay//',views.view_financial_outlay, name="view_financial_outlay"), + path('add_staff_details//',views.add_staff_details, name="add_staff_details"), + path('view_staff_details//',views.view_staff_details, name="view_staff_details"), + path('add_staff_request//',views.add_staff_request, name="add_staff_request"), + path('inbox',views.inbox, name="inbox"), + path('view_request_inbox',views.view_request_inbox, name="view_request_inbox"), + path('forward_request//',views.forward_request, name="forward_request"), + path('update_financial_outlay//',views.update_financial_outlay,name="update_financial_outlay"), + path('approve_request//',views.approve_request,name="approve_request"), + path('view_file//',views.view_file,name="view_file"), + path('update_time_period//',views.update_time_period,name="update_time_period"), + path('change_year//',views.change_year,name="change_year"), + path('change_end_date//',views.change_end_date,name="change_end_date"), + path('download_project_pdf//', views.download_project_pdf, name='download_project_pdf'), + # path('serve-pdf//', serve_pdf, name='serve_pdf'), + + + url(r'^test/$',tests.testfun,name = 'test'), ] \ No newline at end of file diff --git a/FusionIIIT/applications/research_procedures/views.py b/FusionIIIT/applications/research_procedures/views.py index 0b17aa3ee..9c7132296 100644 --- a/FusionIIIT/applications/research_procedures/views.py +++ b/FusionIIIT/applications/research_procedures/views.py @@ -1,107 +1,37 @@ from django.shortcuts import redirect, render, get_object_or_404 from django.contrib import messages -from applications.research_procedures.models import Patent, ResearchGroup, ResearchProject, ConsultancyProject, TechTransfer +from applications.research_procedures.models import * from applications.globals.models import ExtraInfo, HoldsDesignation, Designation from django.core.files.storage import FileSystemStorage +from django.core.exceptions import ObjectDoesNotExist from notification.views import research_procedures_notif from django.urls import reverse -from .forms import ResearchGroupForm +from .forms import * from django.contrib.auth.decorators import login_required import datetime +from django.utils import timezone +from .models import * +from collections import defaultdict +from applications.filetracking.sdk.methods import * +from io import BytesIO +from django.http import HttpResponse +from reportlab.lib import colors +from reportlab.lib.pagesizes import letter +from reportlab.platypus import SimpleDocTemplate, Table, TableStyle,Spacer +from .models import projects, financial_outlay # Faculty can file patent and view status of it. + @login_required def patent_registration(request): - """ - This function is used to register a patent and to retrieve all patents filed by the faculty. - - @param: - request - contains metadata about the requested page. - - @variables: - user - the user who is currently logged in. - extrainfo - extra information of the user. - user_designations - The designations of the user currently logged in. - patent - The new patent to be registered. - patents - All the patents filed by the faculty. - dean_rspc_user - The Dean RSPC user who can modify status of the patent. - ipd_form_pdf - The pdf file of the IPD form of the patent sent by the user. - project_details_pdf - The pdf file of the project details of the patent sent by the user. - file_system - The file system to store the files. - - - """ - - user = request.user - user_extra_info = ExtraInfo.objects.get(user=user) - user_designations = HoldsDesignation.objects.filter(user=user) - patent = Patent() - context = {} - - context['patents'] = Patent.objects.all() - context['user_extra_info'] = user_extra_info - context['user_designations'] = user_designations - - - if request.method=='POST': - if ("ipd_form_file" in request.FILES) and ("project_details_file" in request.FILES) and ("title" in request.POST): - if(user_extra_info.user_type == "faculty"): - patent.faculty_id = user_extra_info - patent.title = request.POST.get('title') - ipd_form_pdf = request.FILES['ipd_form_file'] - if(ipd_form_pdf.name.endswith('.pdf')): - patent.ipd_form = request.FILES['ipd_form_file'] - file_system = FileSystemStorage() - ipd_form_pdf_name = file_system.save(ipd_form_pdf.name,ipd_form_pdf) - patent.ipd_form_file = file_system.url(ipd_form_pdf_name) - else: - messages.error(request, 'Please upload pdf file') - return render(request ,"rs/research.html",context) - - project_details_pdf = request.FILES['project_details_file'] - if(project_details_pdf.name.endswith('.pdf')): - patent.project_details=request.FILES['project_details_file'] - file_system = FileSystemStorage() - project_details_pdf_name = file_system.save(project_details_pdf.name,project_details_pdf) - patent.project_details_file = file_system.url(project_details_pdf_name) - messages.success(request, 'Patent filed successfully') - else: - messages.error(request, 'Please upload pdf file') - return render(request ,"rs/research.html",context) - - # creating notifications for user and dean_rspc about the patent - dean_rspc_user = HoldsDesignation.objects.get(designation=Designation.objects.filter(name='dean_rspc').first()).working - research_procedures_notif(request.user,request.user,"submitted") - research_procedures_notif(request.user,dean_rspc_user,"created") - patent.status='Pending' - patent.save() - else: - messages.error(request, 'Only Faculty can file patent') - else: - messages.error(request,"All fields are required") - patents = Patent.objects.all() - context['patents'] = patents - context['research_groups'] = ResearchGroup.objects.all() - context['research_group_form'] = ResearchGroupForm() - return render(request ,"rs/research.html",context) + + return render(request ,"rs/research.html") @login_required #dean_rspc can update status of patent. def patent_status_update(request): - """ - This function is used to update the status of the patent. - @param: - request - contains metadata about the requested page. - @variables: - user - the user who is currently logged in. - extrainfo - extra information of the user. - user_designations - The designations of the user currently logged in. - patent - The patent whose status is to be updated. - patents - All the patents filed by the faculty. - dean_rspc_user - The Dean RSPC user who can modify status of the patent. - - """ + user = request.user user_extra_info = ExtraInfo.objects.get(user=user) user_designations = HoldsDesignation.objects.filter(user=user) @@ -122,24 +52,13 @@ def patent_status_update(request): @login_required def research_group_create(request): - """ - This function is used to create a research group. - @param: - request - contains metadata about the requested page. - @variables: - user - the user who is currently logged in. - extrainfo - extra information of the user. - user_designations - The designations of the user currently logged in. - research_group - The research group to be created. - research_groups - All the research groups. - dean_rspc_user - The Dean RSPC user who can modify status of the patent. - - """ + user = request.user user_extra_info = ExtraInfo.objects.get(user=user) if request.method=='POST': if user_extra_info.user_type == "faculty": form = ResearchGroupForm(request.POST) + if form.is_valid(): form.save() messages.success(request, 'Research group created successfully') @@ -220,14 +139,955 @@ def consult_insert(request): messages.success(request,"Successfully created consultancy project") return redirect(reverse("research_procedures:patent_registration")) +@login_required +def add_projects(request): + + # designation = getDesignation(request.user.username) + # print("designation is " + designation) + # if designation != 'rspc_admin': + # messages.error(request, 'Only RSPC Admin can add projects') + # return redirect("/research_procedures") + if request.session.get('currentDesignationSelected') != 'rspc_admin': + messages.error(request, 'Only RSPC Admin can add projects') + return redirect("/research_procedures") + + if request.method== "POST": + obj= request.POST + projectname= obj.get('project_name') + projecttype= obj.get('project_type') + fo= obj.get('financial_outlay') + pid= obj.get('project_investigator_id') + copid=obj.get('co_project_investigator_id') + sa= obj.get('sponsored_agency') + startd= obj.get('start_date') + subd= obj.get('finish_date') + finishd= obj.get('finish_date') + years= obj.get('number_of_years') + # project_description= obj.get('description') + project_info_file= request.FILES.get('project_info_file') + + check = User.objects.filter(username=pid) + + # print(check[0].username) + + check= HoldsDesignation.objects.filter(user__username= pid, designation__name= "Professor") #checking for pid to exist + + if not check.exists(): + check= HoldsDesignation.objects.filter(user__username=pid , designation__name= "Assistant Professor") + + if not check.exists(): + messages.error(request,"Request not added, no such project investigator exists ") + return render(request,"rs/projects.html") + + + + check= HoldsDesignation.objects.filter(user__username= copid, designation__name= "Professor") #checking for copid to exist + + if not check.exists(): + check= HoldsDesignation.objects.filter(user__username=copid , designation__name= "Assistant Professor") + + if not check.exists(): + messages.error(request,"Request not added, no such co project investigator exists ") + return render(request,"rs/projects.html") + + + obj= projects.objects.all() + + + if len(obj)==0 : + projectid=1 + + else : + projectid= obj[0].project_id+1 + + for project in obj: + if project.project_name==projectname: + messages.error(request,"Request not added, project name already exists") + return render(request,"rs/projects.html") + + + + + + userpi_instance = User.objects.get(username=pid) + usercpi_instance = User.objects.get(username=copid) + + projects.objects.create( + project_id=projectid, + project_name=projectname, + project_type=projecttype, + status=0, + project_investigator_id=userpi_instance, + co_project_investigator_id=usercpi_instance, + sponsored_agency=sa, + start_date=startd, + submission_date=finishd, + finish_date=finishd, + years=years, + project_info_file=project_info_file + + ) + project_investigator_designation = HoldsDesignation.objects.get(user=userpi_instance).designation + + file_x= create_file( + uploader=request.user.username, + uploader_designation="rspc_admin", + receiver= pid, + subject= projectname, + receiver_designation=project_investigator_designation, + src_module="research_procedures", + src_object_id= projectid, + file_extra_JSON= { "message": "Project added successfully"}, + attached_file= project_info_file, + ) + + research_procedures_notif(request.user, userpi_instance, "Project Added") + + tracking_obj = Tracking.objects.get(file_id__id=file_x) + file_obj= File.objects.get(id=file_x) + + tracking_obj.upload_file= file_obj.upload_file + tracking_obj.remarks= "Project added by RSPC Admin" + tracking_obj.save() + messages.success(request,"Project added successfully") + categories = category.objects.all() + + notifs = request.user.notifications.all() + data = { + 'notifications': notifs, + "pid": pid, + "years": list(range(1, int(years) + 1)), + "categories": categories, + } + + return redirect("/research_procedures/financial_outlay/"+str(projectid)) + return render(request,"rs/projects.html") + +@login_required +def add_fund_requests(request,pj_id): + data= { + "pj_id": pj_id + } + return render(request,"rs/add_fund_requests.html",context=data) + +@login_required +def add_staff_requests(request,pj_id): + data= { + "pj_id": pj_id + } + return render(request,"rs/add_staff_requests.html",context=data) + +@login_required +def add_requests(request,id,pj_id): + if request.method == 'POST': + obj=request.POST + + + if(id=='0') : + projectid = pj_id + reqtype = obj.get('request_type') + stats =0 + desc= obj.get('description') + amt= obj.get('amount') + + check= projects.objects.filter(project_id=projectid) + if not check.exists(): + messages.error(request,"Request not added, no such project exists") + return render(request,"rs/add_fund_requests.html") + + check= projects.objects.filter(project_id= projectid, project_investigator_id__username=pi_id) + if not check.exists(): + messages.error(request,"Request not added, no such project investigator exists") + return render(request,"rs/add_fund_requests.html") + + + pi_id_instance=User.objects.get(username= request.user.username ) + project_instance=projects.objects.get(project_id=projectid) + + obj= requests.objects.all() + if len(obj)==0 : + requestid=1 + + else : + requestid= obj[0].request_id+1 + + requests.objects.create( + request_id=requestid, + project_id=project_instance, + request_type="funds", + project_investigator_id=pi_id_instance, + status=stats, description=desc, amount= amt + ) + rspc_inventory.objects.create( + inventory_id=requestid, + project_id=project_instance, + project_investigator_id=pi_id_instance, + status=stats, + description=desc, amount= amt + ) + messages.success(request,"Request added successfully") + return render(request,"rs/add_fund_requests.html") + + if(id=='1'): + projectid = obj.get('project_id') + pi_id = obj.get('project_investigator_id') + stats = obj.get('status') + desc= obj.get('description') + + obj= requests.objects.all() + if len(obj)==0 : + requestid=1 + + else : + requestid= obj[0].request_id+1 + + + check= projects.objects.filter(project_id=projectid) + if not check.exists(): + messages.error(request,"Request not added, no such project exists") + return render(request,"rs/add_fund_requests.html") + + check= projects.objects.filter(project_id= projectid, project_investigator_id__username=pi_id) + if not check.exists(): + messages.error(request,"Request not added, no such project investigator exists") + return render(request,"rs/add_fund_requests.html") + + pi_id_instance=User.objects.get(username=pi_id) + project_instance=projects.objects.get(project_id=projectid) + + requests.objects.create( + request_id=requestid, + project_id=project_instance, + request_type="staff", + project_investigator_id=pi_id_instance, + description=desc + ) + messages.success(request,"Request added successfully") + return redirect("/research_procedures") + return render(request, "rs/add_requests.html") + + +@login_required +def view_projects(request): + queryset= projects.objects.all() + projects_per_page = 6 + page_number = request.GET.get('page') + + start_index = (int(page_number) - 1) * projects_per_page if page_number else 0 + end_index = start_index + projects_per_page + + paginated_projects = queryset[start_index:end_index] + + # Calculate total pages + total_pages = (queryset.count() + projects_per_page - 1) // projects_per_page + + rspc_admin = HoldsDesignation.objects.get(designation__name="rspc_admin") + rspc_admin =rspc_admin.user.username + if request.user.username == rspc_admin: + notifs = request.user.notifications.all() + total_pages_list = [i for i in range(1, total_pages + 1)] + data = { + 'notifications': notifs, + 'projects': paginated_projects, + 'total_pages': total_pages_list, + 'current_page': int(page_number) if page_number else 1, + "username": request.user.username, + } + return render(request,"rs/view_projects_rspc.html", context= data) + + queryset= projects.objects.filter(project_investigator_id__username= request.user.username) + start_index = (int(page_number) - 1) * projects_per_page if page_number else 0 + end_index = start_index + projects_per_page + + paginated_projects = queryset[start_index:end_index] + + # Calculate total pages + total_pages = (queryset.count() + projects_per_page - 1) // projects_per_page + total_pages_list = [i for i in range(1, total_pages + 1)] + data= { + 'projects': paginated_projects, + 'total_pages': total_pages_list, + 'current_page': int(page_number) if page_number else 1, + "username": request.user.username, + } + # print(data) + # print(request.user.username) + + return render(request,"rs/view_projects_rspc.html", context= data) + +@login_required +def view_requests(request,id): + + if id== '1': + queryset= requests.objects.filter(request_type= "staff") + elif id== '0': + rspc_admin = HoldsDesignation.objects.get(designation__name="rspc_admin") + rspc_admin =rspc_admin.user.username + if request.user.username == rspc_admin : + queryset= rspc_inventory.objects.all() + notifs = request.user.notifications.all() + data = { + 'notifications': notifs, + "requests": queryset, + "username": request.user.username + } + return render(request,"rs/view_requests.html", context= data) + + + queryset= rspc_inventory.objects.filter(project_investigator_id = request.user.username ) + else: + render(request,"/404.html") + + data= { + "requests": queryset, + "username": request.user.username, + "id":id, + } + + # print(data) + # print(request.user.username) + + return render(request,"rs/view_requests.html", context= data) + +@login_required +def view_financial_outlay(request,pid): + + table_data=financial_outlay.objects.filter(project_id=pid).order_by('category', 'sub_category') + project= projects.objects.get(project_id=pid); + + years = set(table_data.values_list('year', flat=True)) + + category_data = {} + for category in table_data.values_list('category', flat=True).distinct(): + category_data[category] = table_data.filter(category=category) + + + data = { + 'table_title': 'Total Budget Outlay', + 'table_caption': '...', # Add caption if needed + 'project_name':project.project_name, + 'years': list(years), + 'category_data': category_data, + } + + # print(data) + return render(request,"rs/view_financial_outlay.html", context= data) + + + + +@login_required +def submit_closure_report(request,id): + id= int(id) + obj= projects.objects.get(project_id=id) + obj.status= 1; + obj.save() + + queryset= projects.objects.filter(project_investigator_id = request.user.username) + + # print(queryset) + + data= { + "projects": queryset, + "username": request.user.username + } + messages.success(request,"Closure report submitted successfully") + return render(request,"rs/view_projects_rspc.html",context=data) + +@login_required +def view_project_inventory(request,pj_id): + pj_id=int(pj_id) + queryset= requests.objects.filter(project_id=pj_id,request_type="funds") + + + # print(queryset) + + data= { + "requests": queryset, + "username": request.user.username + } + return render(request,"rs/view_project_inventory.html",context=data) + +@login_required +def view_project_staff(request,pj_id): + pj_id=int(pj_id) + queryset= requests.objects.filter(project_id=pj_id,request_type="staff") + + + # print(queryset) + + data= { + "requests": queryset, + "username": request.user.username + } + return render(request,"rs/view_project_staff.html",context=data) + + + +def view_project_info(request,id): + id= int(id) + obj= projects.objects.get(project_id=id) + + + + data = { + "project": obj, + } + + return render(request,"rs/view_project_info.html", context= data) + +@login_required +def financial_outlay_form(request,pid): + pid= int(pid) + project= projects.objects.get(project_id=pid); + categories = category.objects.all().distinct(); + + categories_with_subcategories = category.objects.values('category_name', 'sub_category_name') + + # Organize the data into a dictionary + category_subcategory_map = {} + for item in categories_with_subcategories: + category_name = item['category_name'] + subcategory = item['sub_category_name'] + if category_name in category_subcategory_map: + category_subcategory_map[category_name].append(subcategory) + else: + category_subcategory_map[category_name] = [subcategory] + + # Pass the organized data to the template + + data = { + "project_id": project.project_id, + "project_name":project.project_name, + "years": list(range(1, int(project.years) + 1)), + "category_subcategory_map": category_subcategory_map + + } + + return render(request,"rs/add_financial_outlay.html", context= data) +# return render(request,"rs/add_financial_outlay.html", context= data) + + +@login_required +def add_staff_details(request, pid): + if request.session.get('currentDesignationSelected') != 'rspc_admin': + messages.error(request, 'Only RSPC Admin can add staff details') + return redirect("/research_procedures") + if request.method == 'POST': + obj = request.POST + for key, value in obj.items(): + if key.startswith('staff_id'): + year_count = key.split('-')[-2] + staff_count = key.split('-')[-1] + staff_id_key = f'staff_id-{year_count}-{staff_count}' + staff_name_key = f'staff_name-{year_count}-{staff_count}' + qualification_key = f'qualification-{year_count}-{staff_count}' + stipend_key = f'stipend-{year_count}-{staff_count}' + year = year_count + staff_id = obj.get(staff_id_key, '').strip() + staff_name = obj.get(staff_name_key, '').strip() + qualification = obj.get(qualification_key, '').strip() + stipend = obj.get(stipend_key, '').strip() + project_instance = projects.objects.get(project_id=pid) + # print(type(staff_id)) + ob = staff_allocations.objects.all() + + if len(ob) == 0: + fid = 1 + else: + fid = ob[0].staff_allocation_id + 1 + + if not User.objects.filter(username=staff_id).exists(): + + messages.error(request, "Staff with ID " + staff_id + " does not exist") + return redirect("/research_procedures/add_staff_details/"+str(pid)) + + staff_id_instance = User.objects.get(username=staff_id) + + + staff_allocations.objects.create( + staff_allocation_id=fid, + project_id=project_instance, + staff_id=staff_id_instance, + staff_name=staff_name, + qualification=qualification, + year=year, + stipend=stipend + ) + + return redirect("/research_procedures/view_staff_details/"+str(pid)) + + project = projects.objects.get(project_id=pid) + + years_passed = int((datetime.datetime.now().date() - project.start_date).days / 365.25) + + data = { + "project_id": project.project_id, + "project_name" : project.project_name, + "years": list(range(1, int(project.years) + 1)), + "year": int(years_passed) + 1, + } + + return render(request, "rs/add_staff_details.html", context=data) + +@login_required +def view_staff_details(request,pid): + + staff_records = staff_allocations.objects.filter(project_id=pid) + + # Initialize a dictionary to hold data year-wise + data_by_year = {} + project = projects.objects.get(project_id=pid) + + # Iterate through each staff record + for record in staff_records: + year = record.year + if year not in data_by_year: + data_by_year[year] = [] + data_by_year[year].append({ + 'staff_allocation_id': record.staff_allocation_id, + 'staff_id' : record.staff_id, + 'staff_name': record.staff_name, + 'qualification': record.qualification, + 'stipend': record.stipend, + 'start_date': record.start_date, + 'end_date': record.end_date, + }) +# Pass the organized data to the template + context = { + 'data_by_year': data_by_year, + 'project_name':project.project_name + } + rspc_admin = HoldsDesignation.objects.get(designation__name="rspc_admin") + + + return render(request, "rs/view_staff_details.html", context) + + +@login_required +def add_financial_outlay(request,pid): + if request.method == 'POST': + + project = projects.objects.get(project_id=pid) + project.financial_outlay_status = 1 + project.save() + + obj = request.POST + for key, value in obj.items(): + if key.startswith('category-select'): + year_count = key.split('-')[-2] + category_count = key.split('-')[-1] + subcategory_key = f'subcategory-select-{year_count}-{category_count}' + amount_key = f'amount-{year_count}-{category_count}' + + category = value + subcategory = obj.get(subcategory_key, ['']) + amount = obj.get(amount_key, ['']) + year = int(year_count) + + # print(year) + # print(amount) + # print(subcategory) + # print(category) + project_instance=projects.objects.get(project_id=pid) + + + ob= financial_outlay.objects.all() + if len(ob)==0 : + fid=1 + + else : + fid= ob[0].financial_outlay_id+1 + financial_outlay.objects.create( + financial_outlay_id=fid, + project_id=project_instance, + category=category, + sub_category=subcategory, + amount=amount, + year=year, + status=0, + staff_limit=0 + ) + + + return redirect("/research_procedures/view_financial_outlay/"+str(pid)) + +@login_required +def inbox(request): + + projects_per_page = 6 + page_number = request.GET.get('page') + + start_index = (int(page_number) - 1) * projects_per_page if page_number else 0 + end_index = start_index + projects_per_page + + + + user_designation= request.session.get('currentDesignationSelected') + + print(user_designation) + user_designation= get_designation_instance(user_designation) + + + user_obj = get_user_by_username(request.user.username) + + # There was some issue using view_inbox function, so I had to write the code here + + data= Tracking.objects.filter(receiver_id=user_obj, receive_design=user_designation, file_id__src_module="research_procedures").order_by('-receive_date') + print(data) + files= [] + count =0 + for file in data: + count+=1 + files.append( File.objects.get(id=file.file_id.id) ) + + print(files) + paginated_projects = data[start_index:end_index] + + # Calculate total pages + total_pages = (data.count() + projects_per_page - 1) // projects_per_page + total_pages_list = [i for i in range(1, total_pages + 1)] + data1={ + 'inbox': paginated_projects, + 'total_pages': total_pages_list, + 'current_page': int(page_number) if page_number else 1, + "files": paginated_projects, + } + # print(data) + return render(request, "rs/inbox.html",context= data1) + +def view_file(request, id): + file1= File.objects.get(id=id) + tracks= Tracking.objects.filter(file_id=file1) + current_user = Tracking.objects.filter(file_id=file1).order_by('-receive_date')[0].current_id + + return render(request, "rs/view_file.html", context= {"file": file1, "tracks": tracks, "current_user": current_user}) + +@login_required +def add_staff_request(request,id): + if request.method == 'POST': + obj= request.POST + projectid = int(id) + receiver_designation = obj.get('receiver') + + receiver_designation= get_designation_instance(receiver_designation) + receiver = get_user_by_designation(receiver_designation).username + + subject= obj.get('subject') + sender = request.user.username + file_to_forward= request.FILES.get('file_to_forward') + project_instance=projects.objects.get(project_id=projectid) + receiver_instance=User.objects.get(username=receiver) + sender_designation= HoldsDesignation.objects.get(user= request.user).designation + receiver_designation = receiver_designation + + file_x= create_file( + uploader=sender, + uploader_designation=sender_designation, + receiver= receiver_instance.username, + receiver_designation=receiver_designation, + src_module="research_procedures", + src_object_id= projectid, + subject= subject, + file_extra_JSON= { "message": "Request Added." }, + attached_file= file_to_forward, + ) + + tracking_obj = Tracking.objects.get(file_id__id=file_x) + file_obj= File.objects.get(id=file_x) + + tracking_obj.upload_file= file_obj.upload_file + tracking_obj.remarks= "Request Added by " + request.user.username + tracking_obj.save() + + + messages.success(request,"request added successfully") + + return redirect("/research_procedures/view_project_info/"+ str(projectid)) + +@login_required +def view_request_inbox(request): + user_designation= getDesignation(request.user.username) + print(user_designation) + data = view_inbox(request.user.username,user_designation, "research_procedures") + print(data) + files= [] + count =0 + for i in data: + count+=1 + file1= File.objects.get(id=i['id']) + files.append((count, file1)) + + + data={ + + "inbox": data, + "files": files + } + # print(data) + return render(request, "rs/view_request_inbox.html",context= data) + +@login_required +def forward_request(request,id): + # forward_file( + # file_id: int, + # receiver: str, + # receiver_designation: str, + # file_extra_JSON: dict, + # remarks: str = "", + # file_attachment: Any = None) -> int: + if request.method == 'POST': + obj= request.POST + + fileid = int(id) + filez= File.objects.get(id=fileid) + + remarks = obj.get('remarks') + receiver_designation =obj.get('receiver_designation') + if receiver_designation == 'project_investigator': + project= projects.objects.get(project_id= filez.src_object_id ) + receiver_instance= project.project_investigator_id + receiver_designation= getDesignation(receiver_instance.username) + else: + receiver_instance= HoldsDesignation.objects.get(designation__name=receiver_designation).user + attachment= request.FILES.get('attachment') + receiver= receiver_instance.username + + filex= forward_file( + file_id= fileid, + receiver= receiver, + receiver_designation=receiver_designation, + file_extra_JSON= { "message": "Request forwarded."}, + remarks= remarks, + file_attachment= attachment, + ) + if(receiver_designation == 'Professor' or receiver_designation == 'Assistant Professor' or receiver_designation == 'rspc_admin'): + research_procedures_notif(request.user, receiver_instance, "Request update") + messages.success(request,"Request forwarded successfully") + + + return redirect("/research_procedures/inbox") + + + return redirect("/research_procedures/view_request_inbox") + + + + +def update_time_period(request,id): + if request.method== "POST": + + obj = request.POST + up_year= obj.get('updated_year') + + project = get_object_or_404(projects, project_id=id) + + project.years=up_year + + project.save() + + return redirect("/research_procedures/financial_outlay/"+str(id)) + + +@login_required +def update_financial_outlay(request,pid): + + + #post method + if(request.session.get('currentDesignationSelected') != 'rspc_admin'): + messages.error(request, 'Only RSPC Admin can update financial outlay') + return redirect("/research_procedures") + + if request.method=="POST" : + + obj = request.POST + financial_outlay_id = obj.get('financial_outlay_id') + # print("sdfkjsdfd") + used_amount = obj.get('used_amount') + if used_amount is None or used_amount == '': + messages.error(request,"Enter amount") + return redirect("/research_procedures/update_financial_outlay/" + str(pid)) + financial_outlay_instance = financial_outlay.objects.get(financial_outlay_id=financial_outlay_id) + # financial_outlay_instance.status = 1 + financial_outlay_instance.utilized_amount += int(used_amount) + financial_outlay_instance.save() + messages.success(request,"Financial Outlay updated successfully") + return redirect("/research_procedures/update_financial_outlay/"+str(pid)) + + + + #get method + table_data=financial_outlay.objects.filter(project_id=pid).order_by('category', 'sub_category') + project= projects.objects.get(project_id=pid); + + years = set(table_data.values_list('year', flat=True)) + + category_data = {} + for category in table_data.values_list('category', flat=True).distinct(): + category_data[category] = table_data.filter(category=category) + + + data = { + 'table_title': 'Total Budget Outlay', + 'table_caption': '...', # Add caption if needed + 'project_name':project.project_name, + 'years': list(years), + 'category_data': category_data, + 'project_id': pid, + } + + # print(data) + return render(request,"rs/update_financial_outlay.html", context= data) + +@login_required +def approve_request(request,id): + + + + if request.method == 'POST': + obj= request.POST + fileid = id + message= "Request approved by " + request.user.username + designation = get_designation_instance("rspc_admin") + receiver_instance= get_user_by_designation(designation) + receiver_designation= designation + receiver= receiver_instance.username + sender = request.user.username + filex= get_file_by_id(fileid) + file2=create_file( + uploader=sender, + uploader_designation= getDesignation(sender), + receiver= receiver, + receiver_designation=receiver_designation, + src_module="research_procedures", + src_object_id= filex.src_object_id, + file_extra_JSON= { "message": message + " by "+ sender}, + attached_file= filex.upload_file, + ) + delete_file(fileid) + messages.success(request,"Request approved successfully") + return redirect("/research_procedures/inbox") + + + +def download_project_pdf(request, project_id): + # Retrieve project and financial outlay information + project = projects.objects.get(project_id=project_id) + financial_outlays = financial_outlay.objects.filter(project_id=project_id) + + # Create a buffer for the PDF + buffer = BytesIO() + + # Create a PDF document + pdf = SimpleDocTemplate(buffer, pagesize=letter) + elements = [] + + # Construct project info table data + project_data = [['Project ID', 'Project Name', 'Project Type', 'Sponsored Agency', 'Start Date', 'Finish Date'], + [project.project_id, project.project_name, project.project_type, project.sponsored_agency, + project.start_date, project.finish_date]] + + # Construct financial outlay table data + financial_outlay_data = [['Financial Outlay ID', 'Category', 'Subcategory', 'Amount', 'Year']] + for outlay in financial_outlays: + financial_outlay_data.append([outlay.financial_outlay_id, outlay.category, outlay.sub_category, outlay.amount, outlay.year]) + + # Create project info table + project_table = Table(project_data) + project_table.setStyle(TableStyle([('BACKGROUND', (0, 0), (-1, 0), colors.grey), + ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), + ('ALIGN', (0, 0), (-1, -1), 'CENTER'), + ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), + ('BOTTOMPADDING', (0, 0), (-1, 0), 12), + ('BACKGROUND', (0, 1), (-1, -1), colors.beige), + ('GRID', (0, 0), (-1, -1), 1, colors.black)])) + + # Create financial outlay table + financial_outlay_table = Table(financial_outlay_data) + financial_outlay_table.setStyle(TableStyle([('BACKGROUND', (0, 0), (-1, 0), colors.grey), + ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), + ('ALIGN', (0, 0), (-1, -1), 'CENTER'), + ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), + ('BOTTOMPADDING', (0, 0), (-1, 0), 12), + ('BACKGROUND', (0, 1), (-1, -1), colors.beige), + ('GRID', (0, 0), (-1, -1), 1, colors.black)])) + + # Add tables to elements + elements.append(project_table) + elements.append(Spacer(1, 20)) + elements.append(financial_outlay_table) + + # Build the PDF + pdf.build(elements) + + # Close the PDF buffer and return the response with PDF content for download + buffer.seek(0) + response = HttpResponse(buffer.getvalue(), content_type='application/pdf') + response['Content-Disposition'] = f'attachment; filename=project_{project_id}.pdf' + return response + + +def change_year(request,id): + if request.method == 'POST': + obj= request.POST + projectid = int(id) + year = obj.get('year') + project_instance=projects.objects.get(project_id=projectid) + project_instance.years= year + project_instance.save() + messages.success(request,"Year changed successfully") + return redirect("/research_procedures/view_financial_outlay/"+str(projectid)) + +def change_end_date(request,id): + if request.method == "POST": + obj= request.POST + staff_allocations_id = int(id) + end_date = obj.get('end_date') + staff_allocation_instance = staff_allocations.objects.get(staff_allocation_id=staff_allocations_id) + staff_allocation_instance.end_date = end_date + staff_allocation_instance.save() + messages.success(request,"End date changed successfully") + return redirect("/research_procedures/view_staff_details/"+str(staff_allocation_instance.project_id.project_id)) + +def getDesignation(us): + user_inst = User.objects.get(username= us) + + user_designation= HoldsDesignation.objects.filter(user= user_inst) + if user_designation.exists(): + user_designation= user_designation.first().designation.name + + return user_designation + +def get_file_by_id(id): + file1= File.objects.get(id=id) + print(file1) + return file1 + +def delete_file(id): + file1= File.objects.get(id=id) + tracking= Tracking.objects.get(file_id=file1) + tracking.delete() + file1.delete() + return + +def get_user_by_username(username): + return User.objects.get(username=username) + +def get_user_by_designation(designation): + return HoldsDesignation.objects.get(designation=designation).user + +def get_designation_instance(designation): + return Designation.objects.get(name=designation) + +def get_obj_by_username_and_designation(username,designation): + user_instance = get_user_by_username(username) + designation_instance = get_designation_instance(designation) + + return HoldsDesignation.objects.filter(user=user_instance, designation=designation_instance) + + + + + -def transfer_insert(request): - user = get_object_or_404(ExtraInfo, user=request.user) - pf = user.id - tech_transfer = TechTransfer() - tech_transfer.pf_no = pf - tech_transfer.details = request.POST.get('details') - tech_transfer.save() - messages.success(request,"Successfully created Technology Transfer") - return redirect(reverse("research_procedures:patent_registration")) \ No newline at end of file diff --git a/FusionIIIT/applications/scholarships/urls.py b/FusionIIIT/applications/scholarships/urls.py index 77a292977..769dec040 100755 --- a/FusionIIIT/applications/scholarships/urls.py +++ b/FusionIIIT/applications/scholarships/urls.py @@ -19,4 +19,4 @@ url(r'^updateEndDate/$', views.updateEndDate, name='updateEndDate'), url(r'^deleteRelease/$', views.deleteRelease, name='deleteRelease'), -] +] \ No newline at end of file diff --git a/FusionIIIT/applications/scholarships/views.py b/FusionIIIT/applications/scholarships/views.py index 0d95daa96..9bffc3fb8 100755 --- a/FusionIIIT/applications/scholarships/views.py +++ b/FusionIIIT/applications/scholarships/views.py @@ -110,22 +110,12 @@ def convener_view(request): # It updates the student Notification table on the spacs head sending the mcm invitation if batch == 'All': active_batches = range(datetime.datetime.now().year - 4 , datetime.datetime.now().year + 1) - # active_batches=str(active_batches) - # active_batches.split(',') - print(active_batches) - querybatch = [] - for curbatch in active_batches: - if curbatch > 2019: - curbatch=curbatch%2000 - querybatch.append(curbatch) - print( active_batches) - query = reduce(or_, (Q(id__id__startswith=batch) for batch in querybatch)) - print(query) + + query = reduce(or_, (Q(id__id__startswith=int(batch)-2000) for batch in active_batches)) recipient = Student.objects.filter(programme=programme).filter(query) else: - if(int(batch)>2019): - curbatch=int(batch)%2000 - recipient = Student.objects.filter(programme=programme, id__id__startswith=curbatch) + recipient = Student.objects.filter(programme=programme, id__id__startswith=int(batch)-2000) + # Notification starts print(recipient) @@ -133,6 +123,7 @@ def convener_view(request): for student in recipient: scholarship_portal_notif(convenor, student.id.user, 'award_' + award) # Notification if award == 'Merit-cum-Means Scholarship': + print("MCM") rel = Release.objects.get(date_time=d_time) Notification.objects.select_related('student_id','release_id').bulk_create([Notification( release_id=rel, @@ -140,6 +131,7 @@ def convener_view(request): notification_mcm_flag=True, invite_mcm_accept_flag=False) for student in recipient]) else: + print("convo") rel = Release.objects.get(date_time=d_time) Notification.objects.select_related('student_id','release_id').bulk_create([Notification( release_id=rel, @@ -169,8 +161,10 @@ def convener_view(request): year = datetime.datetime.now().year Mcm.objects.select_related('award_id','student').filter(id=pk).update(status='Accept') request.session['last_clicked'] = 'Accept_MCM' - Previous_winner.objects.create( - student=student_id, year=year, award_id=award) + zest=Previous_winner.objects.filter(student = student_id, year=year, award_id=award) + print(zest) + if(len(zest)==0): + Previous_winner.objects.create(student=student_id, year=year, award_id=award) convenor = request.user recipient = student_id scholarship_portal_notif(convenor, recipient.id.user, 'Accept_MCM') @@ -194,8 +188,10 @@ def convener_view(request): student_id = Director_gold.objects.select_related('student','award_id').get(id=pk).student year = datetime.datetime.now().year Director_gold.objects.select_related('student','award_id').filter(id=pk).update(status='Accept') - Previous_winner.objects.create( - student=student_id, year=year, award_id=award) + zest=Previous_winner.objects.filter(student = student_id, year=year, award_id=award) + print(zest) + if(len(zest)==0): + Previous_winner.objects.create(student=student_id, year=year, award_id=award) convenor = request.user recipient = student_id scholarship_portal_notif( @@ -222,12 +218,13 @@ def convener_view(request): student_id = Director_silver.objects.select_related('student','award_id').get(id=pk).student year = datetime.datetime.now().year Director_silver.objects.select_related('student','award_id').filter(id=pk).update(status='Accept') - Previous_winner.objects.create( - student=student_id, year=year, award_id=award) + zest=Previous_winner.objects.filter(student = student_id, year=year, award_id=award) + print(zest) + if(len(zest)==0): + Previous_winner.objects.create(student=student_id, year=year, award_id=award) convenor = request.user recipient = student_id - scholarship_portal_notif( - convenor, recipient.id.user, 'Accept_Silver') + scholarship_portal_notif(convenor, recipient.id.user, 'Accept_Silver') request.session['last_clicked'] = 'Accept_Silver' messages.success(request, 'Application is accepted') return HttpResponseRedirect('/spacs/convener_view') @@ -238,8 +235,7 @@ def convener_view(request): Director_silver.objects.select_related('student','award_id').filter(id=pk).update(status='Reject') convenor = request.user recipient = student_id - scholarship_portal_notif( - convenor, recipient.id.user, 'Reject_Silver') + scholarship_portal_notif(convenor, recipient.id.user, 'Reject_Silver') request.session['last_clicked'] = 'Reject_Silver' messages.success(request, 'Application is rejected') return HttpResponseRedirect('/spacs/convener_view') @@ -250,8 +246,10 @@ def convener_view(request): student_id = Proficiency_dm.objects.select_related('student','award_id').get(id=pk).student year = datetime.datetime.now().year Proficiency_dm.objects.select_related('student','award_id').filter(id=pk).update(status='Accept') - Previous_winner.objects.create( - student=student_id, year=year, award_id=award) + zest=Previous_winner.objects.filter(student = student_id, year=year, award_id=award) + print(zest) + if(len(zest)==0): + Previous_winner.objects.create(student=student_id, year=year, award_id=award) convenor = request.user recipient = student_id scholarship_portal_notif(convenor, recipient.id.user, 'Accept_DM') @@ -454,6 +452,7 @@ def getWinners(request): return JsonResponse(context) def get_MCM_Flag(request): # Here we are extracting mcm_flag + print("get mcm_flags here") x = Notification.objects.select_related('student_id','release_id').filter(student_id=request.user.extrainfo.id) for i in x: i.invite_mcm_accept_flag = True @@ -470,7 +469,9 @@ def get_MCM_Flag(request): # Here we are extracting mcm_flag # return HttpResponseRedirect('/spacs/student_view') def getConvocationFlag(request): # Here we are extracting convocation_flag - x = Notification.objects.select_related('student_id', 'release_id').filter(student_id=request.user.extrainfo.id) + + print("get convo_flags here") + x = Notification.objects.filter(student_id=request.user.extrainfo.id) for i in x: i.invite_convocation_accept_flag = True i.save() @@ -1093,45 +1094,27 @@ def sendStudentRenderRequest(request, additionalParams={}): student_batch = getBatch(request.user.extrainfo.student) for dates in release: if checkDate(dates.startdate, dates.enddate): - curBatch = dates.batch - checkBatch = str(request.user.extrainfo.student)[0:4] - batchCondition = False - if checkBatch[2] >= "A" and checkBatch[2] <= "Z": - if(curBatch == 'All'): - batchRange = range(datetime.datetime.now().year - 4, datetime.datetime.now().year + 1) - for batches in batchRange : - if int(checkBatch[0:2]) == batches % 2000: - batchCondition = True - elif curBatch == checkBatch: - batchCondition = True - else: - if(curBatch == 'All'): - batchRange = range(datetime.datetime.now().year - 4, datetime.datetime.now().year + 1) - for batch in batchRange: - if str(checkBatch) == batch: - batchCondition = True - elif curBatch == checkBatch: - True - print("bye") - - - print(curBatch, checkBatch) - if dates.award == 'Merit-cum-Means Scholarship' and batchCondition and dates.programme == request.user.extrainfo.student.programme: + print("sudheer's test --->") + print(request.user.extrainfo.student) + print(str(request.user.extrainfo.student)[0:2]) + if dates.award == 'Merit-cum-Means Scholarship' and dates.batch == "20"+str(request.user.extrainfo.student)[0:2]and dates.programme == request.user.extrainfo.student.programme: x_notif_mcm_flag = True if no_of_mcm_filled > 0: update_mcm_flag = True - elif dates.award == 'Convocation Medals' and dates.batch == student_batch and dates.programme == request.user.extrainfo.student.programme: + elif dates.award == 'Convocation Medals' and dates.batch == "20"+str(request.user.extrainfo.student)[0:2]and dates.programme == request.user.extrainfo.student.programme: x_notif_con_flag = True if no_of_con_filled > 0: update_con_flag = True else: - if dates.award == "Merit-cum-Means Scholarship" and dates.batch == student_batch: + + + if dates.award == "Merit-cum-Means Scholarship" and dates.batch =="20"+ str(request.user.extrainfo.student)[0:2]: try: x = Notification.objects.select_related('student_id','release_id').get( student_id=request.user.extrainfo.id, release_id=dates.id).delete() except: pass - elif dates.award == 'Convocation Medals' and dates.batch == student_batch: + elif dates.award == 'Convocation Medals' and dates.batch == "20"+str(request.user.extrainfo.student)[0:2]: try: x = Notification.objects.select_related('student_id','release_id').get( student_id=request.user.extrainfo.id, release_id=dates.id).delete() @@ -1139,9 +1122,11 @@ def sendStudentRenderRequest(request, additionalParams={}): pass x = Notification.objects.select_related('student_id','release_id').filter(student_id=request.user.extrainfo.id).order_by('-release_id__date_time') + print(x) show_mcm_flag = False show_convocation_flag = False for i in x: + print(i.invite_convocation_accept_flag) if i.invite_mcm_accept_flag == True: show_mcm_flag = True break @@ -1187,4 +1172,4 @@ def getCommonParams(request): context = {'mcm': mcm, 'awards': awards, 'student': student, 'gold': gold, 'silver': silver, 'dandm': dandm, 'con': con, 'assis': assis, 'hd': hd, 'hd1': hd1, 'last_clicked': last_clicked, 'year_range': year_range, 'active_batches': active_batches} - return context + return context \ No newline at end of file diff --git a/FusionIIIT/media/0.98MB.png b/FusionIIIT/media/0.98MB.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_57t5s4b.png b/FusionIIIT/media/0.98MB_57t5s4b.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_57t5s4b.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_7FiXoj8.png b/FusionIIIT/media/0.98MB_7FiXoj8.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_7FiXoj8.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_L99QaqW.png b/FusionIIIT/media/0.98MB_L99QaqW.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_L99QaqW.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_LMwYOps.png b/FusionIIIT/media/0.98MB_LMwYOps.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_LMwYOps.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_P93Gzkf.png b/FusionIIIT/media/0.98MB_P93Gzkf.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_P93Gzkf.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_b8VDHuo.png b/FusionIIIT/media/0.98MB_b8VDHuo.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_b8VDHuo.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_e6cGhm4.png b/FusionIIIT/media/0.98MB_e6cGhm4.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_e6cGhm4.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_ib1hWcs.png b/FusionIIIT/media/0.98MB_ib1hWcs.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_ib1hWcs.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_igbRwIm.png b/FusionIIIT/media/0.98MB_igbRwIm.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_igbRwIm.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_jTd86LL.png b/FusionIIIT/media/0.98MB_jTd86LL.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_jTd86LL.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_jXilZaV.png b/FusionIIIT/media/0.98MB_jXilZaV.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_jXilZaV.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_o5whyyv.png b/FusionIIIT/media/0.98MB_o5whyyv.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_o5whyyv.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_oPouQfP.png b/FusionIIIT/media/0.98MB_oPouQfP.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_oPouQfP.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_oQkgkRh.png b/FusionIIIT/media/0.98MB_oQkgkRh.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_oQkgkRh.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_pmemS4n.png b/FusionIIIT/media/0.98MB_pmemS4n.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_pmemS4n.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_qXDyVYy.png b/FusionIIIT/media/0.98MB_qXDyVYy.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_qXDyVYy.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_rNj6b4q.png b/FusionIIIT/media/0.98MB_rNj6b4q.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_rNj6b4q.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_tz69HNE.png b/FusionIIIT/media/0.98MB_tz69HNE.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_tz69HNE.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_utFsMj9.png b/FusionIIIT/media/0.98MB_utFsMj9.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_utFsMj9.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_xIcO1Zb.png b/FusionIIIT/media/0.98MB_xIcO1Zb.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_xIcO1Zb.png and /dev/null differ diff --git a/FusionIIIT/media/0.98MB_yoy2RBN.png b/FusionIIIT/media/0.98MB_yoy2RBN.png deleted file mode 100644 index 7160beec9..000000000 Binary files a/FusionIIIT/media/0.98MB_yoy2RBN.png and /dev/null differ diff --git a/FusionIIIT/media/0.99MB.jpg b/FusionIIIT/media/0.99MB.jpg deleted file mode 100644 index b3f96bf29..000000000 Binary files a/FusionIIIT/media/0.99MB.jpg and /dev/null differ diff --git a/FusionIIIT/media/0.99MB_DHG7YXd.jpg b/FusionIIIT/media/0.99MB_DHG7YXd.jpg deleted file mode 100644 index b3f96bf29..000000000 Binary files a/FusionIIIT/media/0.99MB_DHG7YXd.jpg and /dev/null differ diff --git a/FusionIIIT/media/0.99MB_EGLIPZ2.jpg b/FusionIIIT/media/0.99MB_EGLIPZ2.jpg deleted file mode 100644 index b3f96bf29..000000000 Binary files a/FusionIIIT/media/0.99MB_EGLIPZ2.jpg and /dev/null differ diff --git a/FusionIIIT/media/0.99MB_HHduay1.jpg b/FusionIIIT/media/0.99MB_HHduay1.jpg deleted file mode 100644 index b3f96bf29..000000000 Binary files a/FusionIIIT/media/0.99MB_HHduay1.jpg and /dev/null differ diff --git a/FusionIIIT/media/0.99MB_JTYIGIj.jpg b/FusionIIIT/media/0.99MB_JTYIGIj.jpg deleted file mode 100644 index b3f96bf29..000000000 Binary files a/FusionIIIT/media/0.99MB_JTYIGIj.jpg and /dev/null differ diff --git a/FusionIIIT/media/0.99MB_aAwWnr2.jpg b/FusionIIIT/media/0.99MB_aAwWnr2.jpg deleted file mode 100644 index b3f96bf29..000000000 Binary files a/FusionIIIT/media/0.99MB_aAwWnr2.jpg and /dev/null differ diff --git a/FusionIIIT/media/0.99MB_e0LQOmD.jpg b/FusionIIIT/media/0.99MB_e0LQOmD.jpg deleted file mode 100644 index b3f96bf29..000000000 Binary files a/FusionIIIT/media/0.99MB_e0LQOmD.jpg and /dev/null differ diff --git a/FusionIIIT/media/0.99MB_lsfSTir.jpg b/FusionIIIT/media/0.99MB_lsfSTir.jpg deleted file mode 100644 index b3f96bf29..000000000 Binary files a/FusionIIIT/media/0.99MB_lsfSTir.jpg and /dev/null differ diff --git a/FusionIIIT/media/1.png b/FusionIIIT/media/1.png deleted file mode 100644 index 9c8220bd3..000000000 Binary files a/FusionIIIT/media/1.png and /dev/null differ diff --git a/FusionIIIT/media/1_vo8bfvr4k9iNktDWxd1F2g.jpeg b/FusionIIIT/media/1_vo8bfvr4k9iNktDWxd1F2g.jpeg deleted file mode 100644 index 83a35d102..000000000 Binary files a/FusionIIIT/media/1_vo8bfvr4k9iNktDWxd1F2g.jpeg and /dev/null differ diff --git a/FusionIIIT/media/1_vo8bfvr4k9iNktDWxd1F2g_5F4vkCu.jpeg b/FusionIIIT/media/1_vo8bfvr4k9iNktDWxd1F2g_5F4vkCu.jpeg deleted file mode 100644 index 83a35d102..000000000 Binary files a/FusionIIIT/media/1_vo8bfvr4k9iNktDWxd1F2g_5F4vkCu.jpeg and /dev/null differ diff --git a/FusionIIIT/media/1_vo8bfvr4k9iNktDWxd1F2g_792jnyr.jpeg b/FusionIIIT/media/1_vo8bfvr4k9iNktDWxd1F2g_792jnyr.jpeg deleted file mode 100644 index 83a35d102..000000000 Binary files a/FusionIIIT/media/1_vo8bfvr4k9iNktDWxd1F2g_792jnyr.jpeg and /dev/null differ diff --git a/FusionIIIT/media/48KB.jpg b/FusionIIIT/media/48KB.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/48KB.jpg and /dev/null differ diff --git a/FusionIIIT/media/48KB_2JSfQTH.jpg b/FusionIIIT/media/48KB_2JSfQTH.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/48KB_2JSfQTH.jpg and /dev/null differ diff --git a/FusionIIIT/media/48KB_PmnwtUs.jpg b/FusionIIIT/media/48KB_PmnwtUs.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/48KB_PmnwtUs.jpg and /dev/null differ diff --git a/FusionIIIT/media/48KB_TISNA0m.jpg b/FusionIIIT/media/48KB_TISNA0m.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/48KB_TISNA0m.jpg and /dev/null differ diff --git a/FusionIIIT/media/48KB_TyyHR1E.jpg b/FusionIIIT/media/48KB_TyyHR1E.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/48KB_TyyHR1E.jpg and /dev/null differ diff --git a/FusionIIIT/media/48KB_ezsXDVu.jpg b/FusionIIIT/media/48KB_ezsXDVu.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/48KB_ezsXDVu.jpg and /dev/null differ diff --git a/FusionIIIT/media/4KB.png b/FusionIIIT/media/4KB.png deleted file mode 100644 index 911f3ee02..000000000 Binary files a/FusionIIIT/media/4KB.png and /dev/null differ diff --git a/FusionIIIT/media/4KB_VuQkbvP.png b/FusionIIIT/media/4KB_VuQkbvP.png deleted file mode 100644 index 911f3ee02..000000000 Binary files a/FusionIIIT/media/4KB_VuQkbvP.png and /dev/null differ diff --git a/FusionIIIT/media/4KB_YKxdDGZ.png b/FusionIIIT/media/4KB_YKxdDGZ.png deleted file mode 100644 index 911f3ee02..000000000 Binary files a/FusionIIIT/media/4KB_YKxdDGZ.png and /dev/null differ diff --git a/FusionIIIT/media/564KB.png b/FusionIIIT/media/564KB.png deleted file mode 100644 index d475b5856..000000000 Binary files a/FusionIIIT/media/564KB.png and /dev/null differ diff --git a/FusionIIIT/media/564KB_tAorR6k.png b/FusionIIIT/media/564KB_tAorR6k.png deleted file mode 100644 index d475b5856..000000000 Binary files a/FusionIIIT/media/564KB_tAorR6k.png and /dev/null differ diff --git a/FusionIIIT/media/564KB_w8K2FLg.png b/FusionIIIT/media/564KB_w8K2FLg.png deleted file mode 100644 index d475b5856..000000000 Binary files a/FusionIIIT/media/564KB_w8K2FLg.png and /dev/null differ diff --git a/FusionIIIT/media/976KB.png b/FusionIIIT/media/976KB.png deleted file mode 100644 index 2c83209f4..000000000 Binary files a/FusionIIIT/media/976KB.png and /dev/null differ diff --git a/FusionIIIT/media/976KB_LsFRDHW.png b/FusionIIIT/media/976KB_LsFRDHW.png deleted file mode 100644 index 2c83209f4..000000000 Binary files a/FusionIIIT/media/976KB_LsFRDHW.png and /dev/null differ diff --git a/FusionIIIT/media/ASSIGNMENT.pdf b/FusionIIIT/media/ASSIGNMENT.pdf deleted file mode 100644 index 5f59b08c0..000000000 Binary files a/FusionIIIT/media/ASSIGNMENT.pdf and /dev/null differ diff --git a/FusionIIIT/media/ASSIGNMENT_M9FShVJ.pdf b/FusionIIIT/media/ASSIGNMENT_M9FShVJ.pdf deleted file mode 100644 index 5f59b08c0..000000000 Binary files a/FusionIIIT/media/ASSIGNMENT_M9FShVJ.pdf and /dev/null differ diff --git a/FusionIIIT/media/Administrator/academic_information/sheet.xlsx b/FusionIIIT/media/Administrator/academic_information/sheet.xlsx new file mode 100644 index 000000000..274ab022f Binary files /dev/null and b/FusionIIIT/media/Administrator/academic_information/sheet.xlsx differ diff --git a/FusionIIIT/media/Capture_832VvV6.PNG b/FusionIIIT/media/Capture_832VvV6.PNG deleted file mode 100644 index 9e858c70a..000000000 Binary files a/FusionIIIT/media/Capture_832VvV6.PNG and /dev/null differ diff --git a/FusionIIIT/media/Capture_NCxCLwL.PNG b/FusionIIIT/media/Capture_NCxCLwL.PNG deleted file mode 100644 index e9fc35e68..000000000 Binary files a/FusionIIIT/media/Capture_NCxCLwL.PNG and /dev/null differ diff --git a/FusionIIIT/media/Capture_TphWQy5.PNG b/FusionIIIT/media/Capture_TphWQy5.PNG deleted file mode 100644 index 9e858c70a..000000000 Binary files a/FusionIIIT/media/Capture_TphWQy5.PNG and /dev/null differ diff --git a/FusionIIIT/media/Capture_V7GzWgM.PNG b/FusionIIIT/media/Capture_V7GzWgM.PNG deleted file mode 100644 index 9e858c70a..000000000 Binary files a/FusionIIIT/media/Capture_V7GzWgM.PNG and /dev/null differ diff --git a/FusionIIIT/media/Capture_lHfdqEG.PNG b/FusionIIIT/media/Capture_lHfdqEG.PNG deleted file mode 100644 index 9e858c70a..000000000 Binary files a/FusionIIIT/media/Capture_lHfdqEG.PNG and /dev/null differ diff --git a/FusionIIIT/media/Capture_ofqjYvS.PNG b/FusionIIIT/media/Capture_ofqjYvS.PNG deleted file mode 100644 index 9e858c70a..000000000 Binary files a/FusionIIIT/media/Capture_ofqjYvS.PNG and /dev/null differ diff --git a/FusionIIIT/media/Chrysanthemum.jpg b/FusionIIIT/media/Chrysanthemum.jpg deleted file mode 100644 index 757c2a628..000000000 Binary files a/FusionIIIT/media/Chrysanthemum.jpg and /dev/null differ diff --git a/FusionIIIT/media/Chrysanthemum_KIrrQ5X.jpg b/FusionIIIT/media/Chrysanthemum_KIrrQ5X.jpg deleted file mode 100644 index 757c2a628..000000000 Binary files a/FusionIIIT/media/Chrysanthemum_KIrrQ5X.jpg and /dev/null differ diff --git a/FusionIIIT/media/Chrysanthemum_boupFDj.jpg b/FusionIIIT/media/Chrysanthemum_boupFDj.jpg deleted file mode 100644 index 757c2a628..000000000 Binary files a/FusionIIIT/media/Chrysanthemum_boupFDj.jpg and /dev/null differ diff --git a/FusionIIIT/media/Desert.jpg b/FusionIIIT/media/Desert.jpg deleted file mode 100644 index 0b88c9133..000000000 Binary files a/FusionIIIT/media/Desert.jpg and /dev/null differ diff --git a/FusionIIIT/media/Desert_H55mbwi.jpg b/FusionIIIT/media/Desert_H55mbwi.jpg deleted file mode 100644 index 0b88c9133..000000000 Binary files a/FusionIIIT/media/Desert_H55mbwi.jpg and /dev/null differ diff --git a/FusionIIIT/media/Desert_sMVqJfr.jpg b/FusionIIIT/media/Desert_sMVqJfr.jpg deleted file mode 100644 index 0b88c9133..000000000 Binary files a/FusionIIIT/media/Desert_sMVqJfr.jpg and /dev/null differ diff --git a/FusionIIIT/media/IMG-20180914-WA0001.jpg b/FusionIIIT/media/IMG-20180914-WA0001.jpg deleted file mode 100644 index 8867752da..000000000 Binary files a/FusionIIIT/media/IMG-20180914-WA0001.jpg and /dev/null differ diff --git a/FusionIIIT/media/IP_Project_Brain_Haemorrhage.pdf b/FusionIIIT/media/IP_Project_Brain_Haemorrhage.pdf deleted file mode 100644 index 5af26ab52..000000000 Binary files a/FusionIIIT/media/IP_Project_Brain_Haemorrhage.pdf and /dev/null differ diff --git a/FusionIIIT/media/IP_Project_Brain_Haemorrhage_9XhG25i.pdf b/FusionIIIT/media/IP_Project_Brain_Haemorrhage_9XhG25i.pdf deleted file mode 100644 index 5af26ab52..000000000 Binary files a/FusionIIIT/media/IP_Project_Brain_Haemorrhage_9XhG25i.pdf and /dev/null differ diff --git a/FusionIIIT/media/Lighthouse_2MzJMjV.jpg b/FusionIIIT/media/Lighthouse_2MzJMjV.jpg deleted file mode 100644 index 494be09b8..000000000 Binary files a/FusionIIIT/media/Lighthouse_2MzJMjV.jpg and /dev/null differ diff --git a/FusionIIIT/media/Lighthouse_asJUMg0.jpg b/FusionIIIT/media/Lighthouse_asJUMg0.jpg deleted file mode 100644 index 494be09b8..000000000 Binary files a/FusionIIIT/media/Lighthouse_asJUMg0.jpg and /dev/null differ diff --git a/FusionIIIT/media/Lighthouse_k8vR5gc.jpg b/FusionIIIT/media/Lighthouse_k8vR5gc.jpg deleted file mode 100644 index 494be09b8..000000000 Binary files a/FusionIIIT/media/Lighthouse_k8vR5gc.jpg and /dev/null differ diff --git a/FusionIIIT/media/Lighthouse_kv2ONOy.jpg b/FusionIIIT/media/Lighthouse_kv2ONOy.jpg deleted file mode 100644 index 494be09b8..000000000 Binary files a/FusionIIIT/media/Lighthouse_kv2ONOy.jpg and /dev/null differ diff --git a/FusionIIIT/media/Parivartan_Desktop.jpg b/FusionIIIT/media/Parivartan_Desktop.jpg deleted file mode 100644 index 0b6773b5b..000000000 Binary files a/FusionIIIT/media/Parivartan_Desktop.jpg and /dev/null differ diff --git a/FusionIIIT/media/Parivartan_Desktop_2AZxa7A.jpg b/FusionIIIT/media/Parivartan_Desktop_2AZxa7A.jpg deleted file mode 100644 index 0b6773b5b..000000000 Binary files a/FusionIIIT/media/Parivartan_Desktop_2AZxa7A.jpg and /dev/null differ diff --git a/FusionIIIT/media/Parivartan_Desktop_A3za29C.jpg b/FusionIIIT/media/Parivartan_Desktop_A3za29C.jpg deleted file mode 100644 index 0b6773b5b..000000000 Binary files a/FusionIIIT/media/Parivartan_Desktop_A3za29C.jpg and /dev/null differ diff --git a/FusionIIIT/media/Parivartan_Desktop_D3gcCwQ.jpg b/FusionIIIT/media/Parivartan_Desktop_D3gcCwQ.jpg deleted file mode 100644 index 0b6773b5b..000000000 Binary files a/FusionIIIT/media/Parivartan_Desktop_D3gcCwQ.jpg and /dev/null differ diff --git a/FusionIIIT/media/Parivartan_Desktop_WObTsJy.jpg b/FusionIIIT/media/Parivartan_Desktop_WObTsJy.jpg deleted file mode 100644 index 0b6773b5b..000000000 Binary files a/FusionIIIT/media/Parivartan_Desktop_WObTsJy.jpg and /dev/null differ diff --git a/FusionIIIT/media/Parivartan_Desktop_pucd5dp.jpg b/FusionIIIT/media/Parivartan_Desktop_pucd5dp.jpg deleted file mode 100644 index 0b6773b5b..000000000 Binary files a/FusionIIIT/media/Parivartan_Desktop_pucd5dp.jpg and /dev/null differ diff --git a/FusionIIIT/media/Parivartan_Desktop_sQh5sCr.jpg b/FusionIIIT/media/Parivartan_Desktop_sQh5sCr.jpg deleted file mode 100644 index 0b6773b5b..000000000 Binary files a/FusionIIIT/media/Parivartan_Desktop_sQh5sCr.jpg and /dev/null differ diff --git a/FusionIIIT/media/R19BZ0dfQ1NDNF9QUk9EX0FQLlxBUFxQUk9EXEdvVG9NeURlc2t0b3AyMFxHb1RvTXlEZXNrdG9wMg--.ica b/FusionIIIT/media/R19BZ0dfQ1NDNF9QUk9EX0FQLlxBUFxQUk9EXEdvVG9NeURlc2t0b3AyMFxHb1RvTXlEZXNrdG9wMg--.ica deleted file mode 100644 index 91a31a332..000000000 --- a/FusionIIIT/media/R19BZ0dfQ1NDNF9QUk9EX0FQLlxBUFxQUk9EXEdvVG9NeURlc2t0b3AyMFxHb1RvTXlEZXNrdG9wMg--.ica +++ /dev/null @@ -1,76 +0,0 @@ -[Encoding] -InputEncoding=UTF8 - -[WFClient] -CDMAllowed=False -CLIPBOARDALLOWED=False -ProxyFavorIEConnectionSetting=Yes -ProxyTimeout=30000 -ProxyType=Auto -ProxyUseFQDN=Off -RemoveICAFile=yes -TransparentKeyPassthrough=Local -TransportReconnectEnabled=Off -Version=2 -VirtualCOMPortEmulation=On - -[ApplicationServers] -XA0008_GoToMyDeskto= - -[XA0008_GoToMyDeskto] -Address=;40;STA847546794;875677C91ECA49699902808E05782B -AutologonAllowed=On -BrowserProtocol=HTTPonTCP -CGPSecurityTicket=On -ClientAudio=On -DesiredColor=8 -DesiredHRES=0 -DesiredVRES=0 -DisableCtrlAltDel=Off -DoNotUseDefaultCSL=On -FontSmoothingType=0 -HDXoverUDP=Off -HTTPBrowserAddress=! -InitialProgram=#XA0008_GoToMyDeskto -Launcher=WI -LaunchReference=2FCB7AABF5E0F23777A748B167C751 -LocHttpBrowserAddress=! -LongCommandLine= -LPWD=235 -NRWD=151 -ProxyTimeout=30000 -ProxyType=Auto -SecureChannelProtocol=Detect -SessionsharingKey=KzQ0nZ+F/Kvu3YOEOdLNqmFKhdt8KyOz -SFRAllowed=Off -SSLCiphers=all -SSLEnable=On -SSLProxyHost=mydesk-ap-r.credit-suisse.com:443 -startSCD=1591082680062 -Title=GoToMyDesktop2 -TransportDriver=TCP/IP -TRWD=0 -TWIMode=On -UseLocalUserAndPassword=On -WinStationDriver=ICA 3.0 - -[Compress] -DriverNameWin16=pdcompw.dll -DriverNameWin32=pdcompn.dll - -[EncRC5-0] -DriverNameWin16=pdc0w.dll -DriverNameWin32=pdc0n.dll - -[EncRC5-128] -DriverNameWin16=pdc128w.dll -DriverNameWin32=pdc128n.dll - -[EncRC5-40] -DriverNameWin16=pdc40w.dll -DriverNameWin32=pdc40n.dll - -[EncRC5-56] -DriverNameWin16=pdc56w.dll -DriverNameWin32=pdc56n.dll - diff --git a/FusionIIIT/media/SFTBR-04.PDF b/FusionIIIT/media/SFTBR-04.PDF deleted file mode 100644 index af7279bbb..000000000 Binary files a/FusionIIIT/media/SFTBR-04.PDF and /dev/null differ diff --git a/FusionIIIT/media/SamplePNGImage_500kbmb.png b/FusionIIIT/media/SamplePNGImage_500kbmb.png deleted file mode 100644 index b374d33c1..000000000 --- a/FusionIIIT/media/SamplePNGImage_500kbmb.png +++ /dev/null @@ -1,1122 +0,0 @@ - - - Download Sample Videos / Dummy Videos For Demo Use - - - - - - - - - - - - - - - - - -
- - -
-
- - - -
-
-
-
- -
- - -
- -
- - -
- -
-
-
- - - -
- -

Download Sample Videos

- -

Are you a mobile app developer?

-

Are you looking for videos of different resolution and sizes to test while designing or developing a mobile app?

-

Sample-Videos.com is a 100% FREE service that allows programmers, testers, designers, developers to download sample videos for demo/test use. No matter what video format they use (MP4, FLV, MKV, 3GP); they will be able to test videos on any Smartphone without any hustle. This is a one stop destination for all sample video testing needs. Just search below for the relevant video formats in specific sizes, download them, and start testing.

-

A mobile screen resolution can be a big challenge when it comes to watching videos online or offline. By testing out videos one can be rest assured regarding the video playback in an app, without annoying the end users. Choose from four different video extensions i.e. 3GP, MKV, FLV, and MP4. The best thing is all of these are free and very easy to download. We provide you with a specific and perfect resolution in all sizes possible with just one simple click. Check out the one which suits your requirements. All you need to do is hit the DOWNLOAD button, and get started.

- - -
-

Download .mp4 Sample Video

- -
- - - - - - - - - - - - - - -
Size(mb)FormatResolutionOne Click Download
1mp41280x720Click
2mp41280x720Click
5mp41280x720Click
10mp41280x720Click
- - - -
20mp41280x720Click
30mp41280x720Click
1mp4720x480Click
2mp4720x480Click
5mp4720x480Click
10mp4720x480Click
20mp4720x480Click
30mp4720x480Click
1mp4640x360Click
2mp4640x360Click
5mp4640x360Click
10mp4640x360Click
20mp4640x360Click
30mp4640x360Click
1mp4360x240Click
2mp4360x240Click
5mp4360x240Click
10mp4360x240Click
20mp4360x240Click
30mp4360x240Click
- -
- -
-
- -

Download .flv Sample Video

-
- - - - - - - - - - - - - - -
Size(mb)FormatResolutionOne Click Download
1flv1280x720Click
2flv1280x720Click
5flv1280x720Click
10flv1280x720Click
- - - -
20flv1280x720Click
30flv1280x720Click
1flv720x480Click
2flv720x480Click
5flv720x480Click
10flv720x480Click
20flv720x480Click
30flv720x480Click
1flv640x360Click
2flv640x360Click
5flv640x360Click
10flv640x360Click
20flv640x360Click
30flv640x360Click
1flv360x240Click
2flv360x240Click
5flv360x240Click
10flv360x240Click
20flv360x240Click
30flv360x240Click
-
- -
-
- -

Download .mkv Sample Video

-
- - - - - - - - - - - - - - -
Size(mb)FormatResolutionOne Click Download
1mkv1280x720Click
2mkv1280x720Click
5mkv1280x720Click
10mkv1280x720Click
- - - -
20mkv1280x720Click
30mkv1280x720Click
1mkv720x480Click
2mkv720x480Click
5mkv720x480Click
10mkv720x480Click
20mkv720x480Click
30mkv720x480Click
1mkv640x360Click
2mkv640x360Click
5mkv640x360Click
10mkv640x360Click
20mkv640x360Click
30mkv640x360Click
1mkv360x240Click
2mkv360x240Click
5mkv360x240Click
10mkv360x240Click
20mkv360x240Click
30mkv360x240Click
- -
- -
-
- -

Download .3gp Sample Video

-
- - - - - - - - - - - - - - - -
Size(mb)FormatResolutionOne Click Download
13gp176x144Click
23gp176x144Click
53gp176x144Click
103gp176x144Click
- - - -
13gp320x240Click
23gp320x240Click
53gp320x240Click
103gp320x240Click
203gp320x240Click
303gp320x240Click
- -
- -
- - - - -
- - -
-
- - - - - -
-
- -
-
-
- -
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
- - - - - - - -
- - - - -
- - -
- -
- - -
- - - - - - - - - - - - - -
-
- © Sample Video Developers - www.bigbuckbunny.org -
-
- - - - - - - - - - - - - - - - - - - - - -
- - diff --git a/FusionIIIT/media/SamplePNGImage_500kbmb_0BkXR0Y.png b/FusionIIIT/media/SamplePNGImage_500kbmb_0BkXR0Y.png deleted file mode 100644 index b374d33c1..000000000 --- a/FusionIIIT/media/SamplePNGImage_500kbmb_0BkXR0Y.png +++ /dev/null @@ -1,1122 +0,0 @@ - - - Download Sample Videos / Dummy Videos For Demo Use - - - - - - - - - - - - - - - - - -
- - -
-
- - - -
-
-
-
- -
- - -
- -
- - -
- -
-
-
- - - -
- -

Download Sample Videos

- -

Are you a mobile app developer?

-

Are you looking for videos of different resolution and sizes to test while designing or developing a mobile app?

-

Sample-Videos.com is a 100% FREE service that allows programmers, testers, designers, developers to download sample videos for demo/test use. No matter what video format they use (MP4, FLV, MKV, 3GP); they will be able to test videos on any Smartphone without any hustle. This is a one stop destination for all sample video testing needs. Just search below for the relevant video formats in specific sizes, download them, and start testing.

-

A mobile screen resolution can be a big challenge when it comes to watching videos online or offline. By testing out videos one can be rest assured regarding the video playback in an app, without annoying the end users. Choose from four different video extensions i.e. 3GP, MKV, FLV, and MP4. The best thing is all of these are free and very easy to download. We provide you with a specific and perfect resolution in all sizes possible with just one simple click. Check out the one which suits your requirements. All you need to do is hit the DOWNLOAD button, and get started.

- - -
-

Download .mp4 Sample Video

- -
- - - - - - - - - - - - - - -
Size(mb)FormatResolutionOne Click Download
1mp41280x720Click
2mp41280x720Click
5mp41280x720Click
10mp41280x720Click
- - - -
20mp41280x720Click
30mp41280x720Click
1mp4720x480Click
2mp4720x480Click
5mp4720x480Click
10mp4720x480Click
20mp4720x480Click
30mp4720x480Click
1mp4640x360Click
2mp4640x360Click
5mp4640x360Click
10mp4640x360Click
20mp4640x360Click
30mp4640x360Click
1mp4360x240Click
2mp4360x240Click
5mp4360x240Click
10mp4360x240Click
20mp4360x240Click
30mp4360x240Click
- -
- -
-
- -

Download .flv Sample Video

-
- - - - - - - - - - - - - - -
Size(mb)FormatResolutionOne Click Download
1flv1280x720Click
2flv1280x720Click
5flv1280x720Click
10flv1280x720Click
- - - -
20flv1280x720Click
30flv1280x720Click
1flv720x480Click
2flv720x480Click
5flv720x480Click
10flv720x480Click
20flv720x480Click
30flv720x480Click
1flv640x360Click
2flv640x360Click
5flv640x360Click
10flv640x360Click
20flv640x360Click
30flv640x360Click
1flv360x240Click
2flv360x240Click
5flv360x240Click
10flv360x240Click
20flv360x240Click
30flv360x240Click
-
- -
-
- -

Download .mkv Sample Video

-
- - - - - - - - - - - - - - -
Size(mb)FormatResolutionOne Click Download
1mkv1280x720Click
2mkv1280x720Click
5mkv1280x720Click
10mkv1280x720Click
- - - -
20mkv1280x720Click
30mkv1280x720Click
1mkv720x480Click
2mkv720x480Click
5mkv720x480Click
10mkv720x480Click
20mkv720x480Click
30mkv720x480Click
1mkv640x360Click
2mkv640x360Click
5mkv640x360Click
10mkv640x360Click
20mkv640x360Click
30mkv640x360Click
1mkv360x240Click
2mkv360x240Click
5mkv360x240Click
10mkv360x240Click
20mkv360x240Click
30mkv360x240Click
- -
- -
-
- -

Download .3gp Sample Video

-
- - - - - - - - - - - - - - - -
Size(mb)FormatResolutionOne Click Download
13gp176x144Click
23gp176x144Click
53gp176x144Click
103gp176x144Click
- - - -
13gp320x240Click
23gp320x240Click
53gp320x240Click
103gp320x240Click
203gp320x240Click
303gp320x240Click
- -
- -
- - - - -
- - -
-
- - - - - -
-
- -
-
-
- -
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
- - - - - - - -
- - - - -
- - -
- -
- - -
- - - - - - - - - - - - - -
-
- © Sample Video Developers - www.bigbuckbunny.org -
-
- - - - - - - - - - - - - - - - - - - - - -
- - diff --git a/FusionIIIT/media/Screenshot_1.png b/FusionIIIT/media/Screenshot_1.png deleted file mode 100644 index 03aed985d..000000000 Binary files a/FusionIIIT/media/Screenshot_1.png and /dev/null differ diff --git a/FusionIIIT/media/Screenshot_1_ZRkbwbZ.png b/FusionIIIT/media/Screenshot_1_ZRkbwbZ.png deleted file mode 100644 index 03aed985d..000000000 Binary files a/FusionIIIT/media/Screenshot_1_ZRkbwbZ.png and /dev/null differ diff --git a/FusionIIIT/media/Screenshot_2020-07-01_CBIR_Using_Color_Difference_Histogram_-_Retrieval_-_Jupyter_Notebook.png b/FusionIIIT/media/Screenshot_2020-07-01_CBIR_Using_Color_Difference_Histogram_-_Retrieval_-_Jupyter_Notebook.png deleted file mode 100644 index 80bfcf678..000000000 Binary files a/FusionIIIT/media/Screenshot_2020-07-01_CBIR_Using_Color_Difference_Histogram_-_Retrieval_-_Jupyter_Notebook.png and /dev/null differ diff --git a/FusionIIIT/media/Solution.jpeg b/FusionIIIT/media/Solution.jpeg deleted file mode 100644 index c4467fe4b..000000000 Binary files a/FusionIIIT/media/Solution.jpeg and /dev/null differ diff --git a/FusionIIIT/media/a1.PNG b/FusionIIIT/media/a1.PNG deleted file mode 100644 index 1d1e6039d..000000000 Binary files a/FusionIIIT/media/a1.PNG and /dev/null differ diff --git a/FusionIIIT/media/ajju.pdf b/FusionIIIT/media/ajju.pdf deleted file mode 100644 index 8c794c0a0..000000000 Binary files a/FusionIIIT/media/ajju.pdf and /dev/null differ diff --git a/FusionIIIT/media/ajju_ipTPZnA.pdf b/FusionIIIT/media/ajju_ipTPZnA.pdf deleted file mode 100644 index 8c794c0a0..000000000 Binary files a/FusionIIIT/media/ajju_ipTPZnA.pdf and /dev/null differ diff --git a/FusionIIIT/media/allane.pdf b/FusionIIIT/media/allane.pdf deleted file mode 100644 index aea95724d..000000000 Binary files a/FusionIIIT/media/allane.pdf and /dev/null differ diff --git a/FusionIIIT/media/allane_mqBZZDj.pdf b/FusionIIIT/media/allane_mqBZZDj.pdf deleted file mode 100644 index aea95724d..000000000 Binary files a/FusionIIIT/media/allane_mqBZZDj.pdf and /dev/null differ diff --git a/FusionIIIT/media/bonafide.pdf b/FusionIIIT/media/bonafide.pdf deleted file mode 100644 index 9469632b6..000000000 Binary files a/FusionIIIT/media/bonafide.pdf and /dev/null differ diff --git a/FusionIIIT/media/bonafide_3p6qeQY.pdf b/FusionIIIT/media/bonafide_3p6qeQY.pdf deleted file mode 100644 index 9469632b6..000000000 Binary files a/FusionIIIT/media/bonafide_3p6qeQY.pdf and /dev/null differ diff --git a/FusionIIIT/media/bonafide_W7s1Auu.pdf b/FusionIIIT/media/bonafide_W7s1Auu.pdf deleted file mode 100644 index 9469632b6..000000000 Binary files a/FusionIIIT/media/bonafide_W7s1Auu.pdf and /dev/null differ diff --git a/FusionIIIT/media/bonafide_b25Y6TV.pdf b/FusionIIIT/media/bonafide_b25Y6TV.pdf deleted file mode 100644 index 9469632b6..000000000 Binary files a/FusionIIIT/media/bonafide_b25Y6TV.pdf and /dev/null differ diff --git a/FusionIIIT/media/demo.zip b/FusionIIIT/media/demo.zip deleted file mode 100644 index 15cb0ecb3..000000000 Binary files a/FusionIIIT/media/demo.zip and /dev/null differ diff --git a/FusionIIIT/media/demo_0SCeEho.zip b/FusionIIIT/media/demo_0SCeEho.zip deleted file mode 100644 index 15cb0ecb3..000000000 Binary files a/FusionIIIT/media/demo_0SCeEho.zip and /dev/null differ diff --git a/FusionIIIT/media/demo_Ecf0ATC.zip b/FusionIIIT/media/demo_Ecf0ATC.zip deleted file mode 100644 index 15cb0ecb3..000000000 Binary files a/FusionIIIT/media/demo_Ecf0ATC.zip and /dev/null differ diff --git a/FusionIIIT/media/demo_uqf8R7p.zip b/FusionIIIT/media/demo_uqf8R7p.zip deleted file mode 100644 index 15cb0ecb3..000000000 Binary files a/FusionIIIT/media/demo_uqf8R7p.zip and /dev/null differ diff --git a/FusionIIIT/media/documents/wrist_band.jpg b/FusionIIIT/media/documents/wrist_band.jpg deleted file mode 100644 index abbbdceda..000000000 Binary files a/FusionIIIT/media/documents/wrist_band.jpg and /dev/null differ diff --git a/FusionIIIT/media/event.jpg b/FusionIIIT/media/event.jpg deleted file mode 100644 index bb88b387b..000000000 Binary files a/FusionIIIT/media/event.jpg and /dev/null differ diff --git a/FusionIIIT/media/event.pdf b/FusionIIIT/media/event.pdf deleted file mode 100644 index b92477282..000000000 Binary files a/FusionIIIT/media/event.pdf and /dev/null differ diff --git a/FusionIIIT/media/event_n6JOVni.pdf b/FusionIIIT/media/event_n6JOVni.pdf deleted file mode 100644 index b92477282..000000000 Binary files a/FusionIIIT/media/event_n6JOVni.pdf and /dev/null differ diff --git a/FusionIIIT/media/feeds/profile_pictures/Snapchat-1401287705.jpg b/FusionIIIT/media/feeds/profile_pictures/Snapchat-1401287705.jpg deleted file mode 100644 index 4dc7ab350..000000000 Binary files a/FusionIIIT/media/feeds/profile_pictures/Snapchat-1401287705.jpg and /dev/null differ diff --git a/FusionIIIT/media/feeds/profile_pictures/rahul.jpg b/FusionIIIT/media/feeds/profile_pictures/rahul.jpg deleted file mode 100644 index e9a3f8fd0..000000000 Binary files a/FusionIIIT/media/feeds/profile_pictures/rahul.jpg and /dev/null differ diff --git a/FusionIIIT/media/feeds/profile_pictures/sid.jpg b/FusionIIIT/media/feeds/profile_pictures/sid.jpg deleted file mode 100644 index d18c7e75e..000000000 Binary files a/FusionIIIT/media/feeds/profile_pictures/sid.jpg and /dev/null differ diff --git a/FusionIIIT/media/image.jpg b/FusionIIIT/media/image.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_007RJnp.jpg b/FusionIIIT/media/image_007RJnp.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_007RJnp.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_08EzmEH.jpg b/FusionIIIT/media/image_08EzmEH.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_08EzmEH.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_6xkgtat.jpg b/FusionIIIT/media/image_6xkgtat.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_6xkgtat.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_8Al2hkC.jpg b/FusionIIIT/media/image_8Al2hkC.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_8Al2hkC.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_DArY4kM.jpg b/FusionIIIT/media/image_DArY4kM.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_DArY4kM.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_Dj9wBVK.jpg b/FusionIIIT/media/image_Dj9wBVK.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_Dj9wBVK.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_DnBzrXz.jpg b/FusionIIIT/media/image_DnBzrXz.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_DnBzrXz.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_EHN0uUR.jpg b/FusionIIIT/media/image_EHN0uUR.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_EHN0uUR.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_ERAUsuR.jpg b/FusionIIIT/media/image_ERAUsuR.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_ERAUsuR.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_FCiEnEA.jpg b/FusionIIIT/media/image_FCiEnEA.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_FCiEnEA.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_GDxnCEC.jpg b/FusionIIIT/media/image_GDxnCEC.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_GDxnCEC.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_Gt3KGJq.jpg b/FusionIIIT/media/image_Gt3KGJq.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_Gt3KGJq.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_Gt3KGJq_bdxtRTW.jpg b/FusionIIIT/media/image_Gt3KGJq_bdxtRTW.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_Gt3KGJq_bdxtRTW.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_Gt3KGJq_rXplFd4.jpg b/FusionIIIT/media/image_Gt3KGJq_rXplFd4.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_Gt3KGJq_rXplFd4.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_Gt3KGJq_sTQs693.jpg b/FusionIIIT/media/image_Gt3KGJq_sTQs693.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_Gt3KGJq_sTQs693.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_IsZTv03.jpg b/FusionIIIT/media/image_IsZTv03.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_IsZTv03.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_LUkx8md.jpg b/FusionIIIT/media/image_LUkx8md.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_LUkx8md.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_OFiO2Bh.jpg b/FusionIIIT/media/image_OFiO2Bh.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_OFiO2Bh.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_OLuWcRU.jpg b/FusionIIIT/media/image_OLuWcRU.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_OLuWcRU.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_Onw3X55.jpg b/FusionIIIT/media/image_Onw3X55.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_Onw3X55.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_SGKG9Zh.jpg b/FusionIIIT/media/image_SGKG9Zh.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_SGKG9Zh.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_UiGJa1M.jpg b/FusionIIIT/media/image_UiGJa1M.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_UiGJa1M.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_VAHo0g5.jpg b/FusionIIIT/media/image_VAHo0g5.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_VAHo0g5.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_Z5HxbWe.jpg b/FusionIIIT/media/image_Z5HxbWe.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_Z5HxbWe.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_ZHDevJQ.jpg b/FusionIIIT/media/image_ZHDevJQ.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_ZHDevJQ.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_behus5I.jpg b/FusionIIIT/media/image_behus5I.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_behus5I.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_iBr1k6y.jpg b/FusionIIIT/media/image_iBr1k6y.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_iBr1k6y.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_kKfwblf.jpg b/FusionIIIT/media/image_kKfwblf.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_kKfwblf.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_nJznh8V.jpg b/FusionIIIT/media/image_nJznh8V.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_nJznh8V.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_nbHQErT.jpg b/FusionIIIT/media/image_nbHQErT.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_nbHQErT.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_qsbU8zn.jpg b/FusionIIIT/media/image_qsbU8zn.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_qsbU8zn.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_r9niVQQ.jpg b/FusionIIIT/media/image_r9niVQQ.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_r9niVQQ.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_vanCtHs.jpg b/FusionIIIT/media/image_vanCtHs.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_vanCtHs.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_xStQjYa.jpg b/FusionIIIT/media/image_xStQjYa.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_xStQjYa.jpg and /dev/null differ diff --git a/FusionIIIT/media/image_xZWkinz.jpg b/FusionIIIT/media/image_xZWkinz.jpg deleted file mode 100644 index 725dd6a15..000000000 Binary files a/FusionIIIT/media/image_xZWkinz.jpg and /dev/null differ diff --git a/FusionIIIT/media/mj.png b/FusionIIIT/media/mj.png deleted file mode 100644 index 4a086b80a..000000000 Binary files a/FusionIIIT/media/mj.png and /dev/null differ diff --git a/FusionIIIT/media/mj_Al5ccBb.png b/FusionIIIT/media/mj_Al5ccBb.png deleted file mode 100644 index 4a086b80a..000000000 Binary files a/FusionIIIT/media/mj_Al5ccBb.png and /dev/null differ diff --git a/FusionIIIT/media/mj_J3NIY2c.png b/FusionIIIT/media/mj_J3NIY2c.png deleted file mode 100644 index 4a086b80a..000000000 Binary files a/FusionIIIT/media/mj_J3NIY2c.png and /dev/null differ diff --git a/FusionIIIT/media/mj_NfL2mTM.png b/FusionIIIT/media/mj_NfL2mTM.png deleted file mode 100644 index 4a086b80a..000000000 Binary files a/FusionIIIT/media/mj_NfL2mTM.png and /dev/null differ diff --git a/FusionIIIT/media/mj_ZImWkc8.png b/FusionIIIT/media/mj_ZImWkc8.png deleted file mode 100644 index 4a086b80a..000000000 Binary files a/FusionIIIT/media/mj_ZImWkc8.png and /dev/null differ diff --git a/FusionIIIT/media/mmmm.png b/FusionIIIT/media/mmmm.png deleted file mode 100644 index 52a802bb0..000000000 Binary files a/FusionIIIT/media/mmmm.png and /dev/null differ diff --git a/FusionIIIT/media/mmmm_dFrFt7K.png b/FusionIIIT/media/mmmm_dFrFt7K.png deleted file mode 100644 index 52a802bb0..000000000 Binary files a/FusionIIIT/media/mmmm_dFrFt7K.png and /dev/null differ diff --git a/FusionIIIT/media/output-onlinepngtools_5.png b/FusionIIIT/media/output-onlinepngtools_5.png deleted file mode 100644 index 782551f21..000000000 Binary files a/FusionIIIT/media/output-onlinepngtools_5.png and /dev/null differ diff --git a/FusionIIIT/media/output-onlinepngtools_5_47NIAdi.png b/FusionIIIT/media/output-onlinepngtools_5_47NIAdi.png deleted file mode 100644 index 782551f21..000000000 Binary files a/FusionIIIT/media/output-onlinepngtools_5_47NIAdi.png and /dev/null differ diff --git a/FusionIIIT/media/output-onlinepngtools_5_ZAOVWvi.png b/FusionIIIT/media/output-onlinepngtools_5_ZAOVWvi.png deleted file mode 100644 index 782551f21..000000000 Binary files a/FusionIIIT/media/output-onlinepngtools_5_ZAOVWvi.png and /dev/null differ diff --git a/FusionIIIT/media/photo-1480365501497-199581be0e66.jpg b/FusionIIIT/media/photo-1480365501497-199581be0e66.jpg deleted file mode 100644 index 55c4b20bc..000000000 Binary files a/FusionIIIT/media/photo-1480365501497-199581be0e66.jpg and /dev/null differ diff --git a/FusionIIIT/media/sample.jpg b/FusionIIIT/media/sample.jpg deleted file mode 100644 index 0a18df12f..000000000 Binary files a/FusionIIIT/media/sample.jpg and /dev/null differ diff --git a/FusionIIIT/media/sample_a2In3HQ.jpg b/FusionIIIT/media/sample_a2In3HQ.jpg deleted file mode 100644 index 0a18df12f..000000000 Binary files a/FusionIIIT/media/sample_a2In3HQ.jpg and /dev/null differ diff --git a/FusionIIIT/media/sample_maFMAz9.jpg b/FusionIIIT/media/sample_maFMAz9.jpg deleted file mode 100644 index 0a18df12f..000000000 Binary files a/FusionIIIT/media/sample_maFMAz9.jpg and /dev/null differ diff --git a/FusionIIIT/media/window.png b/FusionIIIT/media/window.png deleted file mode 100644 index 4ddc642a5..000000000 Binary files a/FusionIIIT/media/window.png and /dev/null differ diff --git a/FusionIIIT/media/window_QaSCiCB.png b/FusionIIIT/media/window_QaSCiCB.png deleted file mode 100644 index 4ddc642a5..000000000 Binary files a/FusionIIIT/media/window_QaSCiCB.png and /dev/null differ diff --git a/FusionIIIT/media/wrist_band.jpg b/FusionIIIT/media/wrist_band.jpg deleted file mode 100644 index abbbdceda..000000000 Binary files a/FusionIIIT/media/wrist_band.jpg and /dev/null differ diff --git a/FusionIIIT/media/wrist_band_104sJ7l.jpg b/FusionIIIT/media/wrist_band_104sJ7l.jpg deleted file mode 100644 index abbbdceda..000000000 Binary files a/FusionIIIT/media/wrist_band_104sJ7l.jpg and /dev/null differ diff --git a/FusionIIIT/notification/views.py b/FusionIIIT/notification/views.py index 23cddf49b..f57ffe54c 100644 --- a/FusionIIIT/notification/views.py +++ b/FusionIIIT/notification/views.py @@ -3,37 +3,39 @@ from notifications.signals import notify # Create your views here. + def leave_module_notif(sender, recipient, type, date=None): url = 'leave:leave' module = 'Leave Module' - sender=sender - recipient=recipient - verb='' - if type=='leave_applied': - verb="Your leave has been successfully submitted." - elif type=='request_accepted': + sender = sender + recipient = recipient + verb = '' + if type == 'leave_applied': + verb = "Your leave has been successfully submitted." + elif type == 'request_accepted': verb = "Your responsibility has been accepted " - elif type=='request_declined': + elif type == 'request_declined': verb = "Your responsibility has been declined " - elif type=='leave_accepted': + elif type == 'leave_accepted': verb = "You leave request has been accepted " elif type == 'leave_forwarded': verb = "You leave request has been forwarded " - elif type=='leave_rejected': + elif type == 'leave_rejected': verb = "You leave request has been rejected " - elif type=='offline_leave': + elif type == 'offline_leave': verb = "Your offline leave has been updated " - elif type=='replacement_request': + elif type == 'replacement_request': verb = "You have a replacement request " - elif type=='leave_request': + elif type == 'leave_request': verb = "You have a leave request from " - elif type=='leave_withdrawn': + elif type == 'leave_withdrawn': verb = "The leave has been withdrawn for " + date - elif type=='replacement_cancel': + elif type == 'replacement_cancel': verb = "Your replacement has been cancelled for "+date + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=verb) - notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) def placement_cell_notif(sender, recipient, type): url = 'placement:placement' @@ -42,25 +44,30 @@ def placement_cell_notif(sender, recipient, type): recipient = recipient verb = '' - notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=verb) + def academics_module_notif(sender, recipient, type): - url='' - module="Academic's Module" + url = '' + module = "Academic's Module" sender = sender recipient = recipient verb = type - notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=verb) + def office_module_notif(sender, recipient): - url='office_module:officeOfRegistrar' - module="Academic's Module" + url = 'office_module:officeOfRegistrar' + module = "Academic's Module" sender = sender recipient = recipient verb = "New file received" - notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=verb) def central_mess_notif(sender, recipient, type, message=None): @@ -80,7 +87,7 @@ def central_mess_notif(sender, recipient, type, message=None): verb = 'Your vacation request has been' + message elif type == 'meeting_invitation': verb = message - elif type =='special_request': + elif type == 'special_request': verb = "Your special food request has been " + message elif type == 'added_committee': verb = "You have been added to the mess committee. " @@ -117,45 +124,52 @@ def visitors_hostel_notif(sender, recipient, type): notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) -def healthcare_center_notif(sender, recipient, type): +def healthcare_center_notif(sender, recipient, type, message): url='healthcenter:healthcenter' module='Healthcare Center' sender = sender recipient = recipient verb = '' - + flag='' if type == 'appoint': verb = "Your Appointment has been booked" elif type == 'amb_request': verb = "Your Ambulance request has been placed" - elif type == 'Presc': + elif type == 'presc': verb = "You have been prescribed some medicine" elif type == 'appoint_req': verb = "You have a new appointment request" + elif type == 'feedback_submitted': + verb = "Your feedback has been submitted" + elif type == 'feedback_res': + verb = "You have a new feedback" elif type == 'amb_req': verb = "You have a new ambulance request" + elif type == 'new_announce': + verb = message + flag='announcement' elif type == 'rel_forward': verb = "You have a new medical relief forward request" elif type == 'rel_approve': verb = "You have a new medical relief approval request" elif type == 'rel_approved': verb = 'Your medical relief request has been approved' + notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb, flag=flag) - notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) - - -def file_tracking_notif(sender, recipient,title): - url='filetracking:inward' - module='File Tracking' +def file_tracking_notif(sender, recipient, title): + url = 'filetracking:inward' + module = 'File Tracking' sender = sender recipient = recipient verb = title - notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=verb) + def scholarship_portal_notif(sender, recipient, type): - url='spacs:spacs' - module='Scholarship Portal' + url = 'spacs:spacs' + module = 'Scholarship Portal' sender = sender recipient = recipient verb = '' @@ -181,51 +195,54 @@ def scholarship_portal_notif(sender, recipient, type): verb = "Your Convocation form for D&M Proficiency Gold Medal has been accepted " elif type == 'Reject_Silver': verb = "Your Convocation form for D&M Proficiency Gold Medal has been rejected " - notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=verb) - - -def complaint_system_notif(sender, recipient, type, complaint_id,student,message): - if(student==0): +def complaint_system_notif(sender, recipient, type, complaint_id, student, message): + if (student == 0): url = ('complaint:detail') else: - url=('complaint:detail2') - module='Complaint System' + url = ('complaint:detail2') + module = 'Complaint System' sender = sender recipient = recipient verb = message description = complaint_id - notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb,description=description) + notify.send(sender=sender, recipient=recipient, url=url, + module=module, verb=verb, description=description) + def office_dean_PnD_notif(sender, recipient, type): url = 'office_module:officeOfDeanPnD' module = 'Office of Dean PnD Module' - sender=sender - recipient=recipient - verb='' - if type=='requisition_filed': + sender = sender + recipient = recipient + verb = '' + if type == 'requisition_filed': verb = "Your requisition has been successfully submitted." - elif type=='request_accepted': + elif type == 'request_accepted': verb = "Your requisition has been accepted." - elif type=='request_rejected': + elif type == 'request_rejected': verb = "Your requisition has been rejected." - elif type=='assignment_created': + elif type == 'assignment_created': verb = "Assignment has been created." - elif type=='assignment_received': + elif type == 'assignment_received': verb = "You have received an assignment." - elif type=='assignment_reverted': + elif type == 'assignment_reverted': verb = "Assignment has been reverted." - elif type=='assignment_approved': + elif type == 'assignment_approved': verb = "Assignment has been approved." - elif type=='assignment_rejected': + elif type == 'assignment_rejected': verb = "Assignment has been rejected." - notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=verb) + def office_module_DeanS_notif(sender, recipient, type): - url='office_module:officeOfDeanStudents' - module='Office Module' + url = 'office_module:officeOfDeanStudents' + module = 'Office Module' sender = sender recipient = recipient verb = "" @@ -253,7 +270,8 @@ def office_module_DeanS_notif(sender, recipient, type): elif type == 'budget_alloted': verb = "Budget has been alloted by Junior Superintendent" - notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=verb) def gymkhana_voting(sender, recipient, type, title, desc): @@ -286,7 +304,8 @@ def gymkhana_session(sender, recipient, type, club, desc, venue): verb = "" if type == 'new_session': - verb = "A session by {} Club will be organised in {}".format(club, venue) + verb = "A session by {} Club will be organised in {}".format( + club, venue) notify.send(sender=sender, recipient=recipient, @@ -306,7 +325,8 @@ def gymkhana_event(sender, recipient, type, club, event_name, desc, venue): verb = "" if type == 'new_event': - verb = "{} event by {} Club will be organised in {}".format(event_name, club, venue) + verb = "{} event by {} Club will be organised in {}".format( + event_name, club, venue) notify.send(sender=sender, recipient=recipient, @@ -316,39 +336,45 @@ def gymkhana_event(sender, recipient, type, club, event_name, desc, venue): description=desc ) -def AssistantshipClaim_notify(sender,recipient,month,year): - - message="Your Assistantshipclaim of {} month year {} is approved ".format(month,year) + +def AssistantshipClaim_notify(sender, recipient, month, year): + + message = "Your Assistantshipclaim of {} month year {} is approved ".format( + month, year) url = 'academic-procedures:academic_procedures' module = 'Assistantship Request' - notify.send(sender=sender,recipient= recipient, url=url, module=module, verb=message) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=message) +def AssistantshipClaim_faculty_notify(sender, recipient): -def AssistantshipClaim_faculty_notify(sender,recipient): - - message=" Assistantshipclaim is requested " + message = " Assistantshipclaim is requested " url = 'academic-procedures:academic_procedures' module = 'Assistantship Request' - notify.send(sender=sender,recipient= recipient, url=url, module=module, verb=message) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=message) -def AssistantshipClaim_acad_notify(sender,recipient): - message = "AssistantshipClaim is requested " +def AssistantshipClaim_acad_notify(sender, recipient): + message = "AssistantshipClaim is requested " url = 'academic-procedures:academic_procedures' module = 'Assistantship Request' - notify.send(sender=sender,recipient= recipient, url=url, module=module, verb=message) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=message) -def AssistantshipClaim_account_notify(sender,stu, recipient): +def AssistantshipClaim_account_notify(sender, stu, recipient): message = "Assistantship claim of{} is forwaded ".format(stu) url = 'academic-procedures:academic_procedures' module = 'Assistantship Request' - notify.send(sender=sender,recipient= recipient, url=url, module=module, verb=message) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=message) + def department_notif(sender, recipient, type): - url='dep:dep' - module='department' + url = 'dep:dep' + module = 'department' sender = sender recipient = recipient verb = type @@ -374,13 +400,29 @@ def examination_notif(sender, recipient, type): module=module, verb=verb, flag=flag) +def examination_notif(sender, recipient, type,request): + url='examination:examination' + module='examination' + sender = sender + recipient = recipient + verb = type + flag = "examination" + + notify.send(sender=sender, + recipient=recipient, + url=url, + module=module, + verb=verb, + flag=flag) + print("test3") + # return render(request, 'examination/announcement_req.html') def office_module_DeanRSPC_notif(sender, recipient, type): - url='office:officeOfDeanRSPC' - module='Office Module' + url = 'office:officeOfDeanRSPC' + module = 'Office Module' sender = sender recipient = recipient verb = "" @@ -392,11 +434,11 @@ def office_module_DeanRSPC_notif(sender, recipient, type): elif type == 'Pending': verb = "Kindly wait for the response" - - notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=verb) -def research_procedures_notif(sender,recipient,type): +def research_procedures_notif(sender, recipient, type): url = 'research_procedures:patent_registration' module = 'Research Procedures' sender = sender @@ -416,3 +458,110 @@ def research_procedures_notif(sender,recipient,type): notify.send(sender=sender,recipient=recipient,url=url,module=module,verb=verb) +def hostel_notifications(sender, recipient, type): + url = 'hostelmanagement:hostel_view' + module = 'Hostel Management' + + sender = sender + recipient = recipient + verb = "" + if type == "leave_accept": + verb = "Your leave request has been Accepted." + elif type == "leave_reject": + verb = "Your leave request has been Rejected." + elif type == "guestRoom_accept": + verb = "Your Guest Room request has been Accepted." + elif type == "guestRoom_reject": + verb = "Your Guest Room request has been Rejected." + elif type == "leave_request": + verb = "You have a new Leave Request." + elif type == "guestRoom_request": + verb = "You have a new Guest Room Request." + elif type == "fine_imposed": + verb = "A fine has been imposed on you." + + notify.send(sender=sender,recipient=recipient,url=url,module=module,verb=verb) + +def prog_and_curr_notif(sender, recipient,title): + url='programme_curriculum:inward_files' + module='Programme and Curriculum' + sender = sender + recipient = recipient + verb = title + notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + +def course_management_notif(sender, recipient, type, course, course_name, course_code, flag): + url = 'online_cms:course' + module="Course Management" + sender = sender + recipient = recipient + verb = type + + notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb, flag=flag, course_code=course_code, course=course, cname = course_name) + + +def otheracademic_notif(sender, recipient, type, otheracademic_id,student,message): + if(type=='ug_leave_hod'): + url = ('otheracademic:otheracademic') + elif type=='pg_leave_ta' : + url = ('otheracademic:leaveApproveTA') + elif type=='pg_leave_hod' : + url = ('otheracademic:otheracademic') + elif type=='ast_ta' : + url = ('otheracademic:assistantship_form_approval') + elif type=='ast_thesis' : + url = ('otheracademic:assistantship_thesis') + + elif type=='ast_acadadmin' : + url = ('otheracademic:assistantship_acad_approveform') + elif type=='ast_hod' : + url = ('otheracademic:assistantship_hod') + elif type=='hostel_nodues' : + url = ('otheracademic:hostel_nodues') + elif type=='bank_nodues' : + url = ('otheracademic:Bank_nodues') + elif type=='btp_nodues' : + url = ('otheracademic:BTP_nodues') + elif type=='cse_nodues' : + url = ('otheracademic:CSE_nodues') + elif type=='design_nodues' : + url = ('otheracademic:Design_nodues') + elif type=='acad_nodues' : + url = ('otheracademic:dsa_nodues') + elif type=='ece_nodues' : + url = ('otheracademic:Ece_nodues') + elif type=='library_nodues' : + url = ('otheracademic:library_nodues') + elif type=='mess_nodues' : + url = ('otheracademic:mess_nodues') + elif type=='physics_nodues' : + url = ('otheracademic:Physics_nodues') + elif type=='discipline_nodues' : + url = ('otheracademic:discipline_nodues') + elif type=='me_nodues' : + url = ('otheracademic:ME_nodues') + elif type=="ug_leave_hod_approve": + url = ('otheracademic:leaveStatus') + elif type=="bonafide_acadadmin": + url = ('otheracademic:bonafideApproveForm') + elif type=="bonafide_accept": + url = ('otheracademic:bonafideStatus') + elif type=="ast_ta_accept": + url = ('otheracademic:assistantship_status') + elif type=="nodues_status": + url = ('otheracademic:nodues_status') + elif type=="pg_leave_ta_approve": + url = ('otheracademic:leaveStatusPG') + elif type=="pg_leave_thesis": + url = ('otheracademic:leaveApproveThesis') + else: + url=('otheracademic:otheracademic') + + + module='otheracademic' + sender = sender + recipient = recipient + verb = message + description = otheracademic_id + + notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb,description=description) \ No newline at end of file diff --git a/FusionIIIT/templates/academic_procedures/academic.html b/FusionIIIT/templates/academic_procedures/academic.html index 35eebf446..217e011b5 100644 --- a/FusionIIIT/templates/academic_procedures/academic.html +++ b/FusionIIIT/templates/academic_procedures/academic.html @@ -183,10 +183,10 @@ {% include 'academic_procedures/registeredCourse.html' %}
- {% include 'academic_procedures/register.html' %} + {% include 'academic_procedures/auto_pre_registration.html' %}
- {% include 'academic_procedures/finalregister.html' %} + {% include 'academic_procedures/auto_finalregister.html' %}
@@ -204,7 +204,12 @@ Add/drop courses - + + Backlogs + + + Replace +
- +
+ {% include 'academic_procedures/backlog.html' %} +
+
+ {% include 'academic_procedures/replace.html' %} +
@@ -325,6 +335,9 @@ {% comment %} TODO: the right rail! {% endcomment %} + {% block sidepanel%} + {% include 'notifications/academic_procedures_sidepanel.html' %} + {% endblock %} {% comment %}The right-rail segment ends here!{% endcomment %} diff --git a/FusionIIIT/templates/academic_procedures/academicfac.html b/FusionIIIT/templates/academic_procedures/academicfac.html index dd74efff5..53095463c 100644 --- a/FusionIIIT/templates/academic_procedures/academicfac.html +++ b/FusionIIIT/templates/academic_procedures/academicfac.html @@ -25,7 +25,13 @@ style="max-width: 320px;"> {% if fac_flag %} - + {% if request.user.extrainfo.user_type == 'fx' or request.user.extrainfo.user_type == 'faculty' %} + + Assigned Course + + + {% endif %} + Course Management @@ -61,9 +67,60 @@ Kartik {% endcomment %} +
+
+
+ + + + + + + + + + + + + + + + + + + {% for course in assigned_courses %} + + + + + + + -
+ + +
+ + + {%endfor%} + +

Course Name

Course Code

Course Version

Programme

Branch

Year

Download Roll List

{{course.course_id.name }} {{course.course_id.code }} {{course.course_id.version }} {{course.batch_id.name }} {{course.batch_id.discipline.name }} {{course.batch_id.year }} +
+ {% csrf_token %} + + + +
+
+
+
+
+ +


@@ -78,7 +135,7 @@ - + + + {% endfor %} @@ -164,6 +231,9 @@ {% comment %} TODO: the right rail! {% endcomment %} + {% block sidepanel%} + {% include 'notifications/academic_procedures_sidepanel.html' %} + {% endblock %} {% comment %}The right-rail segment ends here!{% endcomment %} @@ -181,4 +251,4 @@ -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/academic_procedures/addCourse.html b/FusionIIIT/templates/academic_procedures/addCourse.html index c58b1ac45..42f38a05d 100755 --- a/FusionIIIT/templates/academic_procedures/addCourse.html +++ b/FusionIIIT/templates/academic_procedures/addCourse.html @@ -11,7 +11,7 @@
{% if adc_date_flag %} - {% if details.cpi >= 6.0 %} + {% if details.cpi >= 0.0 %} {% if add_courses_options %}
{% csrf_token %} diff --git a/FusionIIIT/templates/academic_procedures/allot_courses.html b/FusionIIIT/templates/academic_procedures/allot_courses.html index 5d4fc0e45..f5ac54c7e 100644 --- a/FusionIIIT/templates/academic_procedures/allot_courses.html +++ b/FusionIIIT/templates/academic_procedures/allot_courses.html @@ -27,7 +27,7 @@

Note : Provide the data in Excel Sheet in following format:

RollNo | CourseSlot Name | CourseCode | CourseName -

Download +

Download the sample Excel, fill the data accordingly and then upload the same

diff --git a/FusionIIIT/templates/academic_procedures/auto_finalregister.html b/FusionIIIT/templates/academic_procedures/auto_finalregister.html new file mode 100644 index 000000000..95788c24d --- /dev/null +++ b/FusionIIIT/templates/academic_procedures/auto_finalregister.html @@ -0,0 +1,251 @@ +{% load static %} +{% block finalregister %} + + + + +
Final Registration
+ +
+ {% if curr_sem.semester_no != 8 %} + {% if frd %} + {% if final_registration_flag == True %} +

+

You have already registered for this semester!!!
+

+ + + {% else %} +
+ + {% csrf_token %} +
+ + + + + +
+ +
+
+ + +
+
+ +
+
+
+ + +
+ +
+ +
+
+ +
+
+
+ + +
+
+ + +
+
+
+ + +
+ +
+
+ + +
+
+
+
+
+
+
+ + + +
+
+ +
+
+ +
+ +
+ + + {% comment %}
+ {% csrf_token %} + +

Fee Payment

+ + + + + + {% endcomment %} + {% endif %} + {% else %} +
+

Final Registration Date is yet to come

+
+ {% endif %} + {% else %} +
+

You are not Eligible for Registration !!

+
+ {% endif %} +
+{% endblock %} + + + + + + + + \ No newline at end of file diff --git a/FusionIIIT/templates/academic_procedures/auto_pre_registration.html b/FusionIIIT/templates/academic_procedures/auto_pre_registration.html new file mode 100644 index 000000000..b9129ca23 --- /dev/null +++ b/FusionIIIT/templates/academic_procedures/auto_pre_registration.html @@ -0,0 +1,437 @@ + + + + +{% load static %} +{% block resiterstudent %} + + +
Pre-Registration for Next Semester Courses
+
+ {% if curr_sem.semester_no != 8 %} + {% if prd %} + {% if pre_registration_flag %} + +
You have already registered at + {% if pre_registration_timestamp is not None %} + {{pre_registration_timestamp}} + {% endif %} + !!! +
+
View Courses
+
Hide courses
+
+
+
+

{{obj.course_id.code}} {{obj.course_id.name}}{{ obj.batch_id }}{{ obj.batch_id.name}} {{obj.batch_id.year}}-{{obj.batch_id.discipline.name}} +
MANAGE
+ +
+
+ + + + + + + + + + + {% for course_slot,courses in pre_registered_course_show.items %} + + + + + + + + + + {% endfor %} + + +
+ + + {% else %} +
+ {% csrf_token %} + + + + + + + + + + + + + + + {% for course_slot in next_sem_registration_courses %} + {% if course_slot.type == "Swayam" %} + {% with "x"|ljust:swayam_courses_count as dummy_range %} + {% for _ in dummy_range %} + + + + + + + + + + + {% endfor %} + {% endwith %} + {% else %} + + + + + + + + + + + + + {% endif %} + {% endfor %} + + + + +
#Slot nameSlot typeSemesterCreditsSelect
{{ forloop.counter0|add:forloop.parentloop.counter0|add:"+1" }}.{{course_slot.name}}{{course_slot.type}}{{next_sem.semester_no}} + + {{course_slot.courses.all.0.credit}} +
+ +
+
{{forloop.counter}}.{{course_slot.name}}{{course_slot.type}}{{next_sem.semester_no}} + + {{course_slot.courses.all.0.credit}} +
+ +
+
+
+
+ +
+
+
+ +
+
+
+

You need minimum {{curr_sem.curriculum.min_credit}} credits for semester {{next_sem.semester_no}}

+
+ + {% endif %} + {% else %} + {% if prd_start_date%} + +
Pre Registration will start on {{prd_start_date}}. +
+ {% else %} + +
Pre Registration date hasn't come yet +
+ {% endif %} + {% endif %} + {% else %} +
+

You are not Eligible for Registration !!

+
+ {% endif %} + + + + + +{% endblock %} + + + + diff --git a/FusionIIIT/templates/academic_procedures/backlog.html b/FusionIIIT/templates/academic_procedures/backlog.html new file mode 100644 index 000000000..c2e7897da --- /dev/null +++ b/FusionIIIT/templates/academic_procedures/backlog.html @@ -0,0 +1,76 @@ +{% load static %} +
Backlog Courses
+
+ + + + + + + + + + + + + {% for i in auto_backlog_courses_list %} + + {% for j in i %} + + {% endfor %} + + + {% endfor %} +
Course NameCourse CodeVersionCreditGrade
Apply For Registration
{{ j }}
+ {%if adc_date_flag%} + + {%else %} + + {%endif%} +
+
+ + diff --git a/FusionIIIT/templates/academic_procedures/current_sem.html b/FusionIIIT/templates/academic_procedures/current_sem.html index 59ed5ab02..dedcf982a 100755 --- a/FusionIIIT/templates/academic_procedures/current_sem.html +++ b/FusionIIIT/templates/academic_procedures/current_sem.html @@ -94,6 +94,15 @@
{{curr_sem.semester_no}}
+ +
MANAGE
+ +
+ {% endfor %} diff --git a/FusionIIIT/templates/academic_procedures/dropCourse.html b/FusionIIIT/templates/academic_procedures/dropCourse.html index a44f365a6..e310ec14e 100755 --- a/FusionIIIT/templates/academic_procedures/dropCourse.html +++ b/FusionIIIT/templates/academic_procedures/dropCourse.html @@ -1,7 +1,7 @@ {% load static %} {% block complainthistory %} -
Drop Couse(s)
+
Drop Course(s)
@@ -52,7 +52,7 @@
{% else %} - No Courses to drop +
No Courses to drop
{% endif %} {% else %}
You have to wait for the date
diff --git a/FusionIIIT/templates/academic_procedures/finalregister.html b/FusionIIIT/templates/academic_procedures/finalregister.html index 2349c5f01..387aa659f 100755 --- a/FusionIIIT/templates/academic_procedures/finalregister.html +++ b/FusionIIIT/templates/academic_procedures/finalregister.html @@ -212,10 +212,6 @@

Fee Payment

- - - - + + + diff --git a/FusionIIIT/templates/academic_procedures/studentCourses.html b/FusionIIIT/templates/academic_procedures/studentCourses.html index 7c1a9152c..1a15c3d1a 100644 --- a/FusionIIIT/templates/academic_procedures/studentCourses.html +++ b/FusionIIIT/templates/academic_procedures/studentCourses.html @@ -8,6 +8,27 @@ .modal('show') ; }); + function courseDropCalled(event) { + // Prevent the default action of the link + event.preventDefault(); + + // Get the URL from the link's href attribute + let url = event.target.href; + + // Perform AJAX request + $.ajax({ + url: url, + type: 'GET', + success: function(data) { + // Reload the page after successful deletion + location.reload(); + }, + error: function(xhr, status, error) { + // Handle errors if needed + console.error(error); + } + }); + } @@ -81,7 +102,7 @@ + href="/academic-procedures/acad_person/verifyCourse/drop/?id={{ items.reg_id|urlencode }}" onclick="courseDropCalled(event)" > DROP diff --git a/FusionIIIT/templates/academic_procedures/studentSwayam.html b/FusionIIIT/templates/academic_procedures/studentSwayam.html new file mode 100644 index 000000000..6a912f3e9 --- /dev/null +++ b/FusionIIIT/templates/academic_procedures/studentSwayam.html @@ -0,0 +1,322 @@ +{% load static %} + + + + +
+
+ {% if dict2 %} + +           +           +           +           + Name = {{ dict2.firstname }} {{ dict2.lastname }} +           +           +           + Roll No = {{ dict2.roll_no }} + + {% endif %} + {% if details %} + + + + + + + + + + + + + + + + + + + + + {% for items in details %} + + + + + + + + + + + + + + {% endfor %} + + +
+ Reg ID# + + Course ID + + Course Name + + Credits + + Semester + + Replace Course +
+ {{ items.rid }} + + {{ items.course_id }} + + {{ items.course_name }} + + {{ items.credits }} + + {{ items.sem }} + + +
+ + + + + + +
+ +
+ {% else %} +
+


+
+ NO RECORDS FOUND +
+ {% endif %} + +
+ {% comment %} {% endcomment %} + + + + +
+
+ + + \ No newline at end of file diff --git a/FusionIIIT/templates/academic_procedures/student_table.html b/FusionIIIT/templates/academic_procedures/student_table.html index cf74029d7..696f06cc7 100755 --- a/FusionIIIT/templates/academic_procedures/student_table.html +++ b/FusionIIIT/templates/academic_procedures/student_table.html @@ -101,7 +101,8 @@ var student_id = $(this).attr('data'); $.ajax({ type: 'post', - url: '/academic-procedures/process_verification_request/', + // url: '/academic-procedures/process_verification_request/', + url: '/academic-procedures/auto_process_verification_request/', data: { student_id: student_id, status_req: 'accept', @@ -129,10 +130,12 @@ $('.reg-disapprove').on('click', function(e){ var id = $(this).attr('data-two'); var student_id = $(this).attr('data'); - var reason = $('#fname').val(); + // var reason = $('#fname').val(); + var reason = $(this).closest('.verify').find('.reason').val(); $.ajax({ type: 'post', - url: '/academic-procedures/process_verification_request/', + // url: '/academic-procedures/process_verification_request/', + url: '/academic-procedures/auto_process_verification_request/', data: { student_id: student_id, status_req: 'reject', diff --git a/FusionIIIT/templates/academic_procedures/studentlist.html b/FusionIIIT/templates/academic_procedures/studentlist.html index 8f43ce3d5..b3c3ea209 100755 --- a/FusionIIIT/templates/academic_procedures/studentlist.html +++ b/FusionIIIT/templates/academic_procedures/studentlist.html @@ -61,7 +61,7 @@ Verify Student Registration for Semester {{ date.semflag }} : {{ date.year }}
- +
{% if course_verification_date %}
diff --git a/FusionIIIT/templates/academic_procedures/swayam_list.html b/FusionIIIT/templates/academic_procedures/swayam_list.html new file mode 100644 index 000000000..12c50c1de --- /dev/null +++ b/FusionIIIT/templates/academic_procedures/swayam_list.html @@ -0,0 +1,57 @@ +{% comment %} ACAD ADMIN WILL REPLACE COURSES WITH SWAYAM COURSES HERE {% endcomment%} +{% load static %} +{% block allot_swayam %} + + + + + +{% comment %}The tab menu starts here!{% endcomment %} + +
+
+ + {% csrf_token %} +
+ + +
+
+ +
+ + +
+
+ +
+
+ +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/ais/account.html b/FusionIIIT/templates/ais/account.html index 9f64e467f..15e92bad6 100644 --- a/FusionIIIT/templates/ais/account.html +++ b/FusionIIIT/templates/ais/account.html @@ -1,7 +1,6 @@ {% extends 'globals/base.html' %} {% load static %} - {% block title %} Academic Information System {% endblock %} diff --git a/FusionIIIT/templates/ais/ais.html b/FusionIIIT/templates/ais/ais.html index be1e8e0ed..d749b0270 100755 --- a/FusionIIIT/templates/ais/ais.html +++ b/FusionIIIT/templates/ais/ais.html @@ -47,7 +47,7 @@

@@ -135,7 +146,7 @@
-
+
{% block generateSheet %} {% include 'ais/generateSheet.html' %} {% endblock %} @@ -170,18 +181,26 @@ {% endblock %}
-
- {% block min_credfloat_courses %} - {% include 'ais/new.html' %} + + + + + + + +
+ {% block config_pre_registration %} + {% include 'ais/pre_registration_courses.html' %} {% endblock %}
- {% block curriculum %} - {% include 'ais/curriculum.html' %} + {% block config_pre_reg_courses %} + {% include 'ais/config_courseslot_courses.html' %} {% endblock %}
+
{% block branch_change %} {% include 'academic_procedures/academicadminforbranch.html' %} @@ -206,17 +225,33 @@ {% include 'ais/student_dashboard.html' %} {% endblock %}
+ +
+ {% block allot_swayam %} + {% include 'academic_procedures/swayam_list.html' %} + {% endblock %} +
+ + +
+ {% block curriculum %} + {% include 'ais/curriculum.html' %} + {% endblock %} +
- + {% block sidepanel%} + {% include 'notifications/academic_procedures_sidepanel.html' %} {% endblock %}
-
--> +
{% endblock %} diff --git a/FusionIIIT/templates/ais/config_courseslot_courses.html b/FusionIIIT/templates/ais/config_courseslot_courses.html new file mode 100644 index 000000000..ca3bcba67 --- /dev/null +++ b/FusionIIIT/templates/ais/config_courseslot_courses.html @@ -0,0 +1,140 @@ + + + +{% load static %} +{% block config_courseslot_courses %} + + + +
+ +
+ +
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
+ + + + +{% endblock %} + + + + + + diff --git a/FusionIIIT/templates/ais/generateSheet.html b/FusionIIIT/templates/ais/generateSheet.html index fe03efbfd..59613a28d 100755 --- a/FusionIIIT/templates/ais/generateSheet.html +++ b/FusionIIIT/templates/ais/generateSheet.html @@ -21,7 +21,7 @@ success: function(jsondata) { $("#loading").hide(); - console.log(jsondata); + // console.log(jsondata); $('#course_list').html(jsondata.html); }, error: function(data) @@ -33,7 +33,7 @@ -
+
{% csrf_token %}
diff --git a/FusionIIIT/templates/ais/pre_registration_courses.html b/FusionIIIT/templates/ais/pre_registration_courses.html new file mode 100644 index 000000000..e861ec3c8 --- /dev/null +++ b/FusionIIIT/templates/ais/pre_registration_courses.html @@ -0,0 +1,254 @@ + + + + +{% load static %} +{% block config_pre_registration %} + + + +
+
+
+ + +
+ +
+ + +
+
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+ + +
+ +
+ +
+ + + + {% csrf_token %} + + + + + + +
+ + +
+
+
+ + + +{% endblock %} + + + + diff --git a/FusionIIIT/templates/ais/profile.html b/FusionIIIT/templates/ais/profile.html index 479de29f6..d30c5fa0e 100755 --- a/FusionIIIT/templates/ais/profile.html +++ b/FusionIIIT/templates/ais/profile.html @@ -29,7 +29,7 @@

Note : Provide the data in Excel Sheet in following format:

RollNo | First Name | Last Name | Email | Sex | DOB | Father's Name | Mother's Name | Category | Phone No | Address | Department | Specialization | Hall No -

Download the sample Excel, fill the data accordingly and then upload the same

+

Download the sample Excel, fill the data accordingly and then upload the same

diff --git a/FusionIIIT/templates/ais/student_dashboard.html b/FusionIIIT/templates/ais/student_dashboard.html index 06ad5ae92..9d1a4c45a 100644 --- a/FusionIIIT/templates/ais/student_dashboard.html +++ b/FusionIIIT/templates/ais/student_dashboard.html @@ -21,7 +21,7 @@
- +
diff --git a/FusionIIIT/templates/coursemanagement/academicinfo.html b/FusionIIIT/templates/coursemanagement/academicinfo.html new file mode 100644 index 000000000..23021753b --- /dev/null +++ b/FusionIIIT/templates/coursemanagement/academicinfo.html @@ -0,0 +1,192 @@ +{% extends 'globals/base.html' %} +{% load static %} + + +{% block title %} +Academic Information System +{% endblock %} + +{% block css %} + + + + + + + +{% endblock %} + +{% block body %} +{% block navBar %} +{% include 'dashboard/navbar.html' %} +{% endblock %} + + +
+ +
+ +
+ + {% block usercard %} + {% include 'globals/usercard.html' %} + {% endblock %} + +
+ + +

+ +
+ +
+ +
+ {% block calendar %} + {% include 'coursemanagement/calendar.html' %} + {% endblock %} +
+ +
+ {% block timetable %} + {% include 'coursemanagement/timetable.html' %} + {% endblock %} +
+ +
+ +
+ + +
+
+{% endblock %} + +{% block javascript %} + + + + + + + + + + +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/coursemanagement/addcontent.html b/FusionIIIT/templates/coursemanagement/addcontent.html index 22e9986c7..f740b3a16 100644 --- a/FusionIIIT/templates/coursemanagement/addcontent.html +++ b/FusionIIIT/templates/coursemanagement/addcontent.html @@ -1,21 +1,46 @@ {% load static %} {% block addcontent %} - - -
+
+

Add a Module

+
+ Add Module +
+ +

Add a Slide

Add Slides
+ - +{% endif %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/coursemanagement/coursemanagement1.html b/FusionIIIT/templates/coursemanagement/coursemanagement1.html index 678d79b71..b0d9b3982 100644 --- a/FusionIIIT/templates/coursemanagement/coursemanagement1.html +++ b/FusionIIIT/templates/coursemanagement/coursemanagement1.html @@ -53,7 +53,7 @@
{% comment %} The left-rail segment starts here! {% endcomment %} -
+
{% comment %}The user image card starts here!{% endcomment %} {% block usercard %} {% include 'globals/usercard.html' %} {% endblock %} {% comment %}The user image card ends here!{% endcomment %} @@ -66,7 +66,7 @@
{% comment %} The left-rail segment ends here! {% endcomment %} {% comment %} The central-rail segment starts here! {% endcomment %} -
+
{% comment %}The view courses start here!{% endcomment %}
{% comment %}The CSS starts here!{% endcomment %} {% comment %}The CSS ends here!{% endcomment %} {% comment %}The tab menu starts here!{% endcomment %} @@ -85,15 +85,15 @@

Course Code Name Of the Course - {% ifequal extrainfo.designation|stringformat:"s" "student" %} - Instructor {% endifequal %} + {% if extrainfo.user_type == 'student'%} + Instructor {% endif %} - {% ifequal extrainfo.designation|stringformat:"s" "student" %} {% for course,instructor in courses.items %} + {% if extrainfo.user_type == 'student'%} {% for course,instructor in courses.items %} - {{course.course_id.course_name}} - {{course.course_id.course_id}} + {{course.curr_id.course_code}} + {{course.curr_id.course_id.course_name}} {{instructor.instructor_id.user.username}} {% endfor %} {% else %} @@ -105,510 +105,30 @@

{% endfor %} - {% endifequal %} + {% endif %}

- - {% comment %}The Basic Course details segment ends here!{% endcomment %} {% comment %}The Assignment segment starts here!{% endcomment %} - -
- -

-
- -
- -
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
- -
- {% comment %}The assignment ends here!{% endcomment %} {% comment %}The video segment starts here!{% endcomment %} -
-

Software Engineering Videos

-
-
-
-
-
- -
-
- -
- -
-
- -
-
- -
-
-
-
- -
-
- -
- -

Computer Networks Videos

-
-
-
-
-
- -
-
- -
- -
-
- -
-
- -
-
-
-
- -
-
- -
- -

Operating System Videos Videos

-
-
-
-
-
- -
-
- -
- -
-
- -
-
- -
-
-
-
- -
-
- -
- - -
- - - - - {% comment %}The video segment ends here!{% endcomment %} {% comment %}The slides segment starts here!{% endcomment %} - -
-

Software Engineering Slides

- -
-
-
- - - - -
-
- - - - - -
-
- - - - - -
-
- - - - -
-
- -
- - - -

Computer Networks Slides

- -
-
-
- - - - -
-
- - - - - -
-
- - - - - -
-
- - - - -
-
- -
- - -

Operating Systems Slides

- -
-
-
- - - - -
-
- - - - - -
-
- - - - - -
-
- - - - -
-
- -
- - - - -
- - - {% comment %}The Slides segment ends here!{% endcomment %} {% comment %}The time-table segment starts here!{% endcomment %} - -
-

Class Time Table

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Days9-10 AM10-11 AM11-12 AM12-01 PM2:30-3:30 PM3:30-5:30 PM
MondaySeptemberjhlilk22NoNoNoNo
Monday January jamiehYesNoNoNo
Monday May 11,jilsewYesNoNoNo
- -

Quiz Time Table

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Days9-10 AM10-11 AM11-12 AM12-01 PM2:30-3:30 PM3:30-5:30 PM
MondaySeptemberjhlilk22NoNoNoNo
Monday January jamiehYesNoNoNo
Monday May 11,jilsewYesNoNoNo
- -
- - {% comment %}The time-table segment ends here!{% endcomment %} {% comment %}The quiz segment starts here!{% endcomment %} -
-
- -
- Hours -
- -
- Minutes -
- -
- Seconds -
- -
- -

-
- - -
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- {% comment %}The view courses end here!{% endcomment %} {% comment %}The submit assignment starts here!{% endcomment %} - -
- {% block submitassignments %} {% include 'coursemanagement/submitassignments.html' %} {% endblock %} -
- - {% comment %}The submit assignment ends here!{% endcomment %} {% comment %}The view performance starts here!{% endcomment %} - -
- {% block viewperformance %} {% include 'coursemanagement/viewperformance.html' %} {% endblock %}
- - {% comment %}The view performance ends here!{% endcomment %} {% comment %}The assessment starts here!{% endcomment %} - -
- {% block assessment %} {% include 'coursemanagement/assessment.html' %} {% endblock %} -
- - {% comment %}The assessment ends here!{% endcomment %} {% comment %}The add contents starts here!{% endcomment %} {% comment %} -
- {% block addcontent %} {% include 'coursemanagement/addcontent.html' %} {% endblock %} -
- {% endcomment %} {% comment %}The add content ends here!{% endcomment %} - - {% comment %}The Attendance starts here!{% endcomment %} {% comment %} -
- {% block attendance %} {% include 'coursemanagement/attendance.html' %} {% endblock %} -
- {% endcomment %} {% comment %}The Attendance ends here!{% endcomment %} - - - - - - - -
- {% comment %}The central-rail segment ends here!{% endcomment %} {% comment %}The right-rail segment starts here!{% endcomment %} +
- {% comment %}The grid ends here!{% endcomment %} {% endblock %} {% block javascript %} - - + -
- - --> + + + + + + + +{% endblock %} diff --git a/FusionIIIT/templates/coursemanagement/manageEval.html b/FusionIIIT/templates/coursemanagement/manageEval.html new file mode 100644 index 000000000..cddde7918 --- /dev/null +++ b/FusionIIIT/templates/coursemanagement/manageEval.html @@ -0,0 +1,192 @@ +{% load static %} +{% block css %} + + +{% endblock %} +{% block manageEval %} +
+

Manage Evaluations

+ +
+ {% csrf_token %} + +
+ + + + + + + + + + + + {% if student_grades %} + {% for row in student_grades %} + + + + + + + {% endfor %} + {% else%} + {% for stu in registered_students %} + + + + + + + {% endfor %} + {% endif %} + +
S.No.Roll NoTotal Marks (%) +
Grade
+
Generate
+
{{forloop.counter}} + + + + + +
{{forloop.counter}} + + + + + +
+ +
+
+
+ + + + + + + + + +{% endblock %} diff --git a/FusionIIIT/templates/coursemanagement/submitassignments.html b/FusionIIIT/templates/coursemanagement/submitassignments.html index 217a12bde..073fb9d71 100644 --- a/FusionIIIT/templates/coursemanagement/submitassignments.html +++ b/FusionIIIT/templates/coursemanagement/submitassignments.html @@ -1,7 +1,7 @@ {% load static %} {% block submitassignments %} - + + + + + - + @@ -773,24 +962,24 @@

Quiz Time Table

.modal('show'); }); - + - - - + + + {% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/coursemanagement/viewperformance.html b/FusionIIIT/templates/coursemanagement/viewperformance.html index 386b6a9af..fa3b027b6 100644 --- a/FusionIIIT/templates/coursemanagement/viewperformance.html +++ b/FusionIIIT/templates/coursemanagement/viewperformance.html @@ -1,20 +1,21 @@ {% load static %} {% block viewperformance %} - + +{% comment %} tabs contains Announcement_List {% endcomment %} +
+ {% if user.extrainfo.department.name == "Design" %} +
+
+
+ + +
+ + {% comment %} {% if ann_list %} {% endcomment %} + + + + + + + + + + + + {% for stu in announcements.design %} + + + + + + + {% if stu.upload_announcement %} + + {% endif %} + + {% endfor %} + {% for stu in announcements.all %} + + + + + + + {% if stu.upload_announcement %} + + {% endif %} + + {% endfor %} + +
Announcement DateAnnouncement ByProgrammeBatch  MessageFile
{{ stu.ann_date.date }}{{ stu.maker_id.user }}{{ stu.programme }}{{ stu.batch }}{{ stu.message }}
{{ stu.ann_date.date }}{{ stu.maker_id.user }}{{ stu.programme }}{{ stu.batch }}{{ stu.message }}
+ {% comment %} {% endif %} {% endcomment %} + {% comment %}

{% endcomment %} +
+ +
+
+
+
+
+ {% endif %} +
+ + {% comment %} tabs content students {% endcomment %} +
+
+
+
+ + {% comment %}Get student Data{% endcomment %} +
+
+ + PhD Students +
+ +
+ + + + + + + +
+
+
+
+
+
+ +
+
+
+
+ + + +
+
+
+
+ + {% with fac_list.staffNcse as faculty %} + {% block file-requests %} + {% include "department/file_request.html" %} + {% endblock %} + {% endwith %} + + {% comment %}
{% endcomment %} +
+
+
+
+ +
+
+
+
+ + {% block request_history %} + {% include "department/request_history.html" %} + {% endblock %} + + {% comment %}
{% endcomment %} +
+
+
+
+ +
+ {% comment %}
{% endcomment %} +
+
+
+
+
+
+
+
+ {% comment %}
{% endcomment %} +
+
+
+
+
+
+
+
+ {% comment %}
{% endcomment %} +
+
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/department/ece_dep.html b/FusionIIIT/templates/department/ece_dep.html index 2a202f2e4..b3e0083e6 100644 --- a/FusionIIIT/templates/department/ece_dep.html +++ b/FusionIIIT/templates/department/ece_dep.html @@ -17,17 +17,27 @@

Welcome to ECE Department

Faculty - + Students - + {% if user.extrainfo.department.name == "ECE" %} Announcements + {% endif %} + {% comment %} + Requests + {% endcomment %} + + + Alumni + + + Track records
@@ -112,10 +122,12 @@

{% comment %} {% if ann_list %} {% endcomment %} - - + + + + - + {% comment %} @@ -128,14 +140,14 @@

{% for fcu in fac_list.ece_f %}

{% with "/eis/profile/"|add:fcu.user.username as link %} - - - + + + {% comment %} - {% comment %} + {% endcomment %} {% endwith %} @@ -155,6 +167,7 @@

{% comment %} tabs contains Announcement_List {% endcomment %}
+ {% if user.extrainfo.department.name == "ECE" %}
@@ -208,6 +221,7 @@

+ {% endif %}
{% comment %} tabs content students {% endcomment %} @@ -242,13 +256,13 @@


@@ -267,26 +281,26 @@

{% comment %} {% endcomment %}
@@ -354,5 +368,23 @@

+
+
+
+
+ {% comment %}
{% endcomment %} +
+
+
+
+
+
+
+
+ {% comment %}
{% endcomment %} +
+
+
+
{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/department/file_request.html b/FusionIIIT/templates/department/file_request.html index 033e43c50..05c3337ef 100644 --- a/FusionIIIT/templates/department/file_request.html +++ b/FusionIIIT/templates/department/file_request.html @@ -10,7 +10,7 @@ {% endcomment %} {% comment %}
{% endcomment %} -
+
{% csrf_token %}
@@ -77,16 +77,11 @@
{% endcomment %} -
- - - -
-
- +
+ {% comment %}
{% endcomment %} {% comment %}
{% endcomment %} diff --git a/FusionIIIT/templates/department/index.html b/FusionIIIT/templates/department/index.html index 10ebb1c26..4aaf7b6cd 100644 --- a/FusionIIIT/templates/department/index.html +++ b/FusionIIIT/templates/department/index.html @@ -24,15 +24,13 @@
{% comment %}The user image card starts here!{% endcomment %} - {% block usercard %} - {% include 'globals/usercard.html' %} - {% endblock %} {% comment %}The user image card ends here!{% endcomment %} - -
+ + {% comment %}
{% endcomment %} + {% comment %}The Tab-Menu starts here!{% endcomment %} {% comment %}The Tab-Menu ends here!{% endcomment %} @@ -70,7 +74,7 @@ {% comment %} The central-rail segment starts here! {% endcomment %} -
+
{% comment %}CSE Department!{% endcomment %} @@ -105,6 +109,14 @@ {% endblock %}
{% comment %}SM{% endcomment %} + + {% comment %}Design Department!{% endcomment %} +
+ {% block DESIGN_Dep %} + {% include "department/design_dep.html" %} + {% endblock %} + {% comment %}Design Department!{% endcomment %} +
diff --git a/FusionIIIT/templates/department/me_dep.html b/FusionIIIT/templates/department/me_dep.html index 12a417dbe..4cb7fbe47 100644 --- a/FusionIIIT/templates/department/me_dep.html +++ b/FusionIIIT/templates/department/me_dep.html @@ -21,13 +21,20 @@

Welcome to ME Department

Students - + {% if user.extrainfo.department.name == "ME" %} Announcements - - + {% endif %} + {% comment %} + Requests + {% endcomment %} + + Alumni + + + Track records
@@ -181,10 +188,12 @@

{% comment %} {% if ann_list %} {% endcomment %}

id faculty name Serial No. Faculty Name Research Interest Email sex sex date_of_birth address phone_no
{{ fcu.id }}{{fcu.title}} {{ fcu.user.first_name}} {{ fcu.user.last_name}}{{ forloop.counter }}{{ fcu.id }} {{ fcu.sex }} {{ fcu.date_of_birth }} {{ fcu.address }} {{ fcu.phone_no }}{{ fcu.user_type }}{{ fcu.user_type }} {{ fcu.department.name }} {{ fcu.id.faculty_about.github }}
- - + + + + - + {% comment %} @@ -197,9 +206,9 @@

{% for fcu in fac_list.me_f %}

{% with "/eis/profile/"|add:fcu.user.username as link %} - - - + + + {% comment %} @@ -224,6 +233,7 @@

{% comment %} tabs contains Announcement_List {% endcomment %}
+ {% if user.extrainfo.department.name == "ME" %}
@@ -282,6 +292,7 @@

+ {% endif %}
{% comment %} tabs content students {% endcomment %} @@ -316,13 +327,13 @@


@@ -340,26 +351,26 @@

{% comment %} {% endcomment %}
@@ -428,5 +439,23 @@

+
+
+
+
+ {% comment %}
{% endcomment %} +
+
+
+
+
+
+
+
+ {% comment %}
{% endcomment %} +
+
+
+
{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/department/request_history.html b/FusionIIIT/templates/department/request_history.html index 40e445d2b..bb036876c 100644 --- a/FusionIIIT/templates/department/request_history.html +++ b/FusionIIIT/templates/department/request_history.html @@ -7,7 +7,7 @@
{% comment %} {% if ann_list %} {% endcomment %} -

id faculty name Serial No. Faculty Name Research Interest Email sex sex date_of_birth address phone_no
{{ fcu.id }}{{fcu.title}} {{ fcu.user.first_name}} {{ fcu.user.last_name}}{{ forloop.counter }}{{ fcu.id }}{{ fcu.title }} {{ fcu.sex }} {{ fcu.date_of_birth }} {{ fcu.address }}
+
diff --git a/FusionIIIT/templates/department/request_status.html b/FusionIIIT/templates/department/request_status.html index f86eeb403..daeeb3672 100644 --- a/FusionIIIT/templates/department/request_status.html +++ b/FusionIIIT/templates/department/request_status.html @@ -11,7 +11,7 @@

View Requests

{% comment %} {% if ann_list %} {% endcomment %} -
Request Date Request To
+
diff --git a/FusionIIIT/templates/department/sm_dep.html b/FusionIIIT/templates/department/sm_dep.html index 2ddd097a4..8c672f25a 100644 --- a/FusionIIIT/templates/department/sm_dep.html +++ b/FusionIIIT/templates/department/sm_dep.html @@ -21,13 +21,20 @@

Welcome to SM Department

Students - + {% if user.extrainfo.department.name == "SM" %} Announcements - + {% endif %} + {% comment %} Requests + {% endcomment %} + + Alumni + + + Track records @@ -125,24 +132,26 @@

{% comment %} {% if ann_list %} {% endcomment %}

Request Date Maker
- - - + + + + + + {% comment %} {% comment %} {% endcomment %} - {%if fac_list.sm_f%} {% for fcu in fac_list.sm_f %} {% with "/eis/profile/"|add:fcu.user.username as link %} - - - + + + {% comment %} --> @@ -167,6 +176,7 @@

{% comment %} tabs contains Announcement_List {% endcomment %}
+ {% if user.extrainfo.department.name == "SM" %}
@@ -225,6 +235,7 @@

+ {% endif %}
@@ -260,13 +271,13 @@


@@ -284,26 +295,26 @@

{% comment %} {% endcomment %}
@@ -372,5 +383,23 @@

+
+
+
+
+ {% comment %}
{% endcomment %} +
+
+
+
+
+
+
+
+ {% comment %}
{% endcomment %} +
+
+
+
{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/examination/all_course_grade_filled.html b/FusionIIIT/templates/examination/all_course_grade_filled.html new file mode 100644 index 000000000..d88fc919d --- /dev/null +++ b/FusionIIIT/templates/examination/all_course_grade_filled.html @@ -0,0 +1,38 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + +{% endblock %} + + +{% block content %} +
+

Enter Student Marks

+ +
+
+ ALL GRADES ARE FILLED READY TO VERIFY +
+

Please check back later or contact support for assistance.

+
+ +
+{% endblock %} diff --git a/FusionIIIT/templates/examination/announcement_req.html b/FusionIIIT/templates/examination/announcement_req.html new file mode 100644 index 000000000..99bb51e9c --- /dev/null +++ b/FusionIIIT/templates/examination/announcement_req.html @@ -0,0 +1,139 @@ +{% extends 'globals/base.html' %} +{% load static %} + + +{% block title %} + Announcement - Faculty View +{% endblock %} + + +{% block body %} + {% block navBar %} + {% include 'dashboard/navbar.html' %} + {% endblock %} + + {% comment %}The grid starts here!{% endcomment %} +
+ + {% comment %}The left-margin segment!{% endcomment %} +
+ + {% comment %} + The left-rail segment starts here! + {% endcomment %} +
+ + {% comment %}The user image card starts here!{% endcomment %} + {% block usercard %} + {% include 'globals/usercard.html' %} + {% endblock %} + {% comment %}The user image card ends here!{% endcomment %} + + + +
+ + {% comment %}The Tab-Menu starts here!{% endcomment %} + + {% comment %}The Tab-Menu ends here!{% endcomment %} + +
+ {% comment %} + The left-rail segment ends here! + {% endcomment %} + + + + {% comment %} + The central-rail segment starts here! + {% endcomment %} +
+ + {% comment %}Make announcement{% endcomment %} +
+ {% block make_announcement %} + {% if user_designation == "faculty" %} + {% include "examination/exam_make_announcement_fac.html" %} + {% elif user_designation == "staff" %} + {% include "examination/exam_make_announcement_staff.html" %} + {% endif %} + {% endblock %} +
+ {% comment %}Make announcement{% endcomment %} + + {% comment %}See announcement{% endcomment %} +
+ {% block browse_announcement %} + {% if user_designation == "faculty" %} + {% include "department/browse_announcements.html" %} + {% elif user_designation == "staff" %} + {% include "department/browse_announcements_staff.html" %} + {% endif %} + {% endblock %} +
+ {% comment %}See announcement{% endcomment %} + + {% comment %}status of request!{% endcomment %} +
+ {% block request_status %} + {% include "department/request_status.html" %} + {% endblock %} +
+ {% comment %}status of request!{% endcomment %} + + + +
+ +
+
+ {% comment %} + TODO: the right rail! + {% endcomment %} +
+
+ {% comment %}The right-rail segment ends here!{% endcomment %} + + {% comment %}The right-margin segment!{% endcomment %} +
+ + +
+ {% comment %}The grid ends here!{% endcomment %} + + +{% include 'department/alert.html' %} +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/examination/authenticate.html b/FusionIIIT/templates/examination/authenticate.html new file mode 100644 index 000000000..3e3d41bea --- /dev/null +++ b/FusionIIIT/templates/examination/authenticate.html @@ -0,0 +1,152 @@ +{% extends 'examination/base.html' %} +{% block sidetabmenu %} + + + + + + + + +{% endblock %} + +{% block content %} +

Authenticate Course

+
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+ +
+ +
+ + + +
+ +
+ + + +{% endblock %} + + + diff --git a/FusionIIIT/templates/examination/authenticategrades.html b/FusionIIIT/templates/examination/authenticategrades.html new file mode 100644 index 000000000..a397b56ec --- /dev/null +++ b/FusionIIIT/templates/examination/authenticategrades.html @@ -0,0 +1,76 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + +{% endblock %} + +{% block content %} +
+

Authenticate

+ {% if registrations %} +
+ {% csrf_token %} +
+ {% for registration in registrations %} +
+ + +

{{ registration.course_id.name }} - {{ registration.course_id.code }}- [v-{{ registration.course_id.version }}]-{{ registration.course_year}}

+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+ {% endfor %} +
+ + + {% else %} +
+
+ NO STUDENTS REGISTERED IN THIS COURSE IN THIS YEAR +
+

Please check back later or contact support for assistance.

+
+ {% endif %} +
+ + + + + +{% endblock %} diff --git a/FusionIIIT/templates/examination/base.html b/FusionIIIT/templates/examination/base.html new file mode 100644 index 000000000..02caa8ef8 --- /dev/null +++ b/FusionIIIT/templates/examination/base.html @@ -0,0 +1,83 @@ +{% extends 'globals/base.html' %} +{% load static %} + +{% block title %} + examination +{% endblock %} + +{% block css %} + + +{% endblock %} + +{% block body %} + {% block navBar %} + {% include 'dashboard/navbar.html' %} + {% endblock %} + +
+ + {% comment %}The left-margin segment!{% endcomment %} +
+ + {% comment %}The left-rail segment starts here!{% endcomment %} +
+ + {% comment %}The user image card starts here!{% endcomment %} + {% block usercard %} + {% include 'globals/usercard.html' %} + {% endblock %} + {% comment %}The user image card ends here!{% endcomment %} + +
+ + {% comment %}The Tab-Menu starts here!{% endcomment %} + {% block sidetabmenu %} + {% endblock %} + {% comment %}The Tab-Menu ends here!{% endcomment %} +
+ + {% comment %} + The left-rail segment ends here! + {% endcomment %} + + {% comment %} + The central-rail segment starts here! + {% endcomment %} + +
+ + {% block content %} + {% endblock %} + +
+ {% comment %}The central-rail segment ends here!{% endcomment %} + + {% comment %}The right-rail segment starts here!{% endcomment %} +
+
+ {% comment %} + TODO: the right rail! + {% endcomment %} + {% block rightcontent %} + {% endblock %} + +
+
+ {% comment %}The right-rail segment ends here!{% endcomment %} + + {% comment %}The right-margin segment!{% endcomment %} +
+ +
+ {% comment %}The grid ends here!{% endcomment %} +{% endblock %} + +{% block javascript %} + + + +{% endblock %} + + + diff --git a/FusionIIIT/templates/examination/calculate_spi.html b/FusionIIIT/templates/examination/calculate_spi.html new file mode 100644 index 000000000..8c4c6e6d2 --- /dev/null +++ b/FusionIIIT/templates/examination/calculate_spi.html @@ -0,0 +1,4 @@ +{% with total_credits=total_credits|add:course_credits %} + {% with total_grade_points=total_grade_points|add:((grade_points * course_credits)) %} + {% endwith %} +{% endwith %} \ No newline at end of file diff --git a/FusionIIIT/templates/examination/entergrades.html b/FusionIIIT/templates/examination/entergrades.html new file mode 100644 index 000000000..9ea5ef430 --- /dev/null +++ b/FusionIIIT/templates/examination/entergrades.html @@ -0,0 +1,71 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + +{% endblock %} + + +{% block content %} +
+

Enter Student Marks

+ + {% if registrations %} +
+ {% csrf_token %} +
+
id faculty name sex Serial No. Faculty Name Research Interest Email sex date_of_birth address phone_no user_type department github
{{ fcu.id }}{{fcu.title}} {{ fcu.user.first_name}} {{ fcu.user.last_name}}{{ forloop.counter }}{{ fcu.id }}{{ fcu.title }}{{ fcu.sex }} {{ fcu.date_of_birth }} {{ fcu.address }}
+ + + + + + + + + + {% for registration in registrations %} + + + + + + + {% endfor %} + +
Student IDSemester IDCourse IDGrade
{{ registration.student_id_id }}{{ registration.semester_id.id }}{{ registration.course_id.id }} + + + + +
+

+ + + {% else %} +
+
+ NO STUDENTS REGISTERED IN THIS COURSE THIS SEMESTER +
+

Please check back later or contact support for assistance.

+
+ {% endif %} +
+{% endblock %} diff --git a/FusionIIIT/templates/examination/exam_make_announcement_fac.html b/FusionIIIT/templates/examination/exam_make_announcement_fac.html new file mode 100644 index 000000000..a449dc3d7 --- /dev/null +++ b/FusionIIIT/templates/examination/exam_make_announcement_fac.html @@ -0,0 +1,164 @@ +{% load static %} +{% block make_announcements %} + + {% comment %}The tab menu starts here!{% endcomment %} + + +
+
+ +
+ {% csrf_token %} +
+ Make a new Announcement for Students: +
+ +
+ +
+ +
+ + +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ + +
+ +
+ + +
+ + + +
+ + + +
+
+ +
+ +
+
+
+
+ +{% endblock %} + +{% block javascript %} + + + + +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/examination/exam_make_announcement_staff.html b/FusionIIIT/templates/examination/exam_make_announcement_staff.html new file mode 100644 index 000000000..6d5873364 --- /dev/null +++ b/FusionIIIT/templates/examination/exam_make_announcement_staff.html @@ -0,0 +1,165 @@ +{% load static %} +{% block make_announcements %} + + {% comment %}The tab menu starts here!{% endcomment %} + + +
+
+ +
+ {% csrf_token %} +
+ Make a new Announcement for Students: +
+ +
+ +
+ +
+ + +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ + +
+ +
+ + +
+ + + +
+ + + +
+
+ +
+ +
+
+
+
+ +{% endblock %} + +{% block javascript %} + + + + +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/examination/examination.html b/FusionIIIT/templates/examination/examination.html new file mode 100644 index 000000000..fd8e643f9 --- /dev/null +++ b/FusionIIIT/templates/examination/examination.html @@ -0,0 +1,22 @@ +{% extends 'examination/base.html' %} +{% block sidetabmenu %} + +{% endblock %} diff --git a/FusionIIIT/templates/examination/generate_transcript.html b/FusionIIIT/templates/examination/generate_transcript.html new file mode 100644 index 000000000..6b1cf4a9e --- /dev/null +++ b/FusionIIIT/templates/examination/generate_transcript.html @@ -0,0 +1,215 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + + + +{% endblock %} + +{% block content %} +
+

Transcript

+
+
+ {% for course, grade in courses_grades.items %} + {% if forloop.first %} +
Roll No: {{ grade.grade.roll_no }}
+ {% endif %} + {% endfor %} +
+
+ {% for course, grade in courses_grades.items %} + {% if forloop.first %} +
Semester: {{ grade.grade.semester }}
+ {% endif %} + {% endfor %} +
+
+ + {% if not courses_grades %} +
Marks not yet submitted.
+ {% else %} + + + + + + + + + + + + {% for course_detail, data in courses_grades.items %} + + + + + + + + {% endfor %} + +
Course NameCourse CodeCreditsGradeall_auth
{{ course_detail.name }}{{ course_detail.code }}{{ course_detail.credit }} + {% if data.all_authenticators_true %} + {{ data.grade.grade }} + {% else %} + Course must be authenticated to generate grade + {% endif %} + {{data.all_authenticators_true}}
+
+

Semester Performance Index (SPI)

+
+
+ +
+
SPI
+
+
+
+

Cumulative Performance Index (CPI)

+
+
+ +
+
CPI
+
+
+ + {% endif %} +
+{% endblock %} diff --git a/FusionIIIT/templates/examination/generate_transcript_form.html b/FusionIIIT/templates/examination/generate_transcript_form.html new file mode 100644 index 000000000..e0bd04fae --- /dev/null +++ b/FusionIIIT/templates/examination/generate_transcript_form.html @@ -0,0 +1,73 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + +{% endblock %} + +{% block content %} +
+

Generate Transcript Form

+
+ {% csrf_token %} +
+ + +
+ +
+ + +
+ +
+ + +
+
+ + +
+ + +
+
+{% endblock %} diff --git a/FusionIIIT/templates/examination/generate_transcript_students.html b/FusionIIIT/templates/examination/generate_transcript_students.html new file mode 100644 index 000000000..6bc1edd66 --- /dev/null +++ b/FusionIIIT/templates/examination/generate_transcript_students.html @@ -0,0 +1,98 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + + + +{% endblock %} + +{% block content %} +
+

Show Result for {{ semester }} - semester

+ +
+ + + + + + + + + {% for student in students %} + + + + + {% empty %} + + + + {% endfor %} + +
+ Student Roll No + + + Actions
{{ student.id_id }} + +
No students available
+
+
+ + +{% endblock %} diff --git a/FusionIIIT/templates/examination/gradeSubmission.html b/FusionIIIT/templates/examination/gradeSubmission.html new file mode 100644 index 000000000..c79b41b7f --- /dev/null +++ b/FusionIIIT/templates/examination/gradeSubmission.html @@ -0,0 +1,92 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + +{% endblock %} + +{% block content %} +

Submit Results

+
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ + + +
+ +
+ + + +{% endblock %} + diff --git a/FusionIIIT/templates/examination/gradeSubmissionForm.html b/FusionIIIT/templates/examination/gradeSubmissionForm.html new file mode 100644 index 000000000..6a77bc472 --- /dev/null +++ b/FusionIIIT/templates/examination/gradeSubmissionForm.html @@ -0,0 +1,226 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + + +{% endblock %} + +{% block content %} +
+

SUBMIT STUDENT MARKS

+ {% if registrations %} +
+ {% csrf_token %} +
+ + + + + + + + + + + + + + {% for registration in registrations %} + + + + + + + + + + + + {% endfor %} + +
+ Student ID + + + batchCourse IDsemester Academic Year + Total Marks + + + Grade
{{ registration.student_id_id}}{{ registration.student_id.batch }}{{ registration.course_id.name }}{{ registration.semester_id_id }}{{ year}} + + + + + + + + + +
+
+ {% comment %} {% endcomment %} + + +
+
+ +
+ {% else %} +
+
+ NO STUDENTS REGISTERED IN THIS COURSE THIS SEMESTER +
+

Please check back later or contact support for assistance.

+
+ {% endif %} +
+ + + + + + +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/examination/grades_updated.html b/FusionIIIT/templates/examination/grades_updated.html new file mode 100644 index 000000000..d2a4b3a85 --- /dev/null +++ b/FusionIIIT/templates/examination/grades_updated.html @@ -0,0 +1,95 @@ +{% extends 'examination/base.html' %} +{% block sidetabmenu %} + + + + + + + + +{% endblock %} + + +{% block content %} +
+

+
+
+ successfully Grades UPDATED +
+

Please check back later or contact support for assistance.

+
+ +
+{% endblock %} + diff --git a/FusionIIIT/templates/examination/message.html b/FusionIIIT/templates/examination/message.html new file mode 100644 index 000000000..73ca5caa4 --- /dev/null +++ b/FusionIIIT/templates/examination/message.html @@ -0,0 +1,70 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + + +{% endblock %} + +{% block content %} +
+
+
+ {{message}} +
+ +

Please check back later or contact support for assistance.

+
+
+ +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/examination/notReady_publish.html b/FusionIIIT/templates/examination/notReady_publish.html new file mode 100644 index 000000000..85de66c85 --- /dev/null +++ b/FusionIIIT/templates/examination/notReady_publish.html @@ -0,0 +1,151 @@ +{% extends 'examination/base.html' %} +{% block sidetabmenu %} + +{% endblock %} + +{% block content %} + +

Publish Result

+
+ +{% comment %} Combined {% endcomment %} +
+ +{% comment %} First Row {% endcomment %} +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+ + +{% comment %} Second Row {% endcomment %} + +
+ +
+
+ +
+ +
+ + + +
+ +
+ + + +{% comment %} Warning {% endcomment %} + +
+ +

Course Grades are not yet verified

+

Please verify all courses

+ + + + + + +
+ + + + + + + + + + + +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/examination/publish.html b/FusionIIIT/templates/examination/publish.html new file mode 100644 index 000000000..b4ed29319 --- /dev/null +++ b/FusionIIIT/templates/examination/publish.html @@ -0,0 +1,135 @@ +{% extends 'examination/base.html' %} +{% block sidetabmenu %} + +{% endblock %} + +{% block content %} + +

Publish Result

+
+ +{% comment %} Combined {% endcomment %} +
+ +{% comment %} First Row {% endcomment %} +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+ + +{% comment %} Second Row {% endcomment %} + +
+ +
+
+ +
+ +
+ + + + + + + + + +
+ + + + + + + +
+ +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/examination/submit.html b/FusionIIIT/templates/examination/submit.html new file mode 100644 index 000000000..3964b7062 --- /dev/null +++ b/FusionIIIT/templates/examination/submit.html @@ -0,0 +1,95 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + +{% endblock %} + +{% block content %} +

Submit Result

+
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ + + +
+ +
+ + + +{% endblock %} + diff --git a/FusionIIIT/templates/examination/submitGrade.html b/FusionIIIT/templates/examination/submitGrade.html new file mode 100644 index 000000000..e17d06330 --- /dev/null +++ b/FusionIIIT/templates/examination/submitGrade.html @@ -0,0 +1,113 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + +{% endblock %} + +{% block content %} +

Update Result

+
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ + + +
+ +
+ + + +{% endblock %} + diff --git a/FusionIIIT/templates/examination/timetable.html b/FusionIIIT/templates/examination/timetable.html new file mode 100644 index 000000000..a3517c2af --- /dev/null +++ b/FusionIIIT/templates/examination/timetable.html @@ -0,0 +1,58 @@ + +{% extends 'examination/base.html' %} +{% block sidetabmenu %} + +{% endblock %} + +{% block content %} + +

Time Table

+
+ +
+

Show Time Table

+ + + +
+{% comment %} + +
+
+ +
+ +
{% endcomment %} + +
+ +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/examination/updateEntergrades.html b/FusionIIIT/templates/examination/updateEntergrades.html new file mode 100644 index 000000000..7e82cf370 --- /dev/null +++ b/FusionIIIT/templates/examination/updateEntergrades.html @@ -0,0 +1,217 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + + +{% endblock %} + +{% block content %} +
+

VERIFY STUDENT MARKS

+ {% if registrations %} +
+ {% csrf_token %} +
+ + + + + + + + + + + + + {% for registration in registrations %} + + + + + + + + + + {% endfor %} + +
+ Student ID + + + batchCourse IDsemester + Total Marks + + + Grade
{{ registration.roll_no }}{{ registration.batch }}{{ registration.course_id }}{{ registration.semester }}{{ registration.total_marks }} + + + + +
+
+ {% comment %} {% endcomment %} + + +
+
+ +
+ {% else %} +
+
+ NO STUDENTS REGISTERED IN THIS COURSE THIS SEMESTER +
+

Please check back later or contact support for assistance.

+
+ {% endif %} +
+ + + + + + +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/examination/verify.html b/FusionIIIT/templates/examination/verify.html new file mode 100644 index 000000000..b05ae97ad --- /dev/null +++ b/FusionIIIT/templates/examination/verify.html @@ -0,0 +1,154 @@ +{% extends 'examination/base.html' %} +{% block sidetabmenu %} + + + + + + + + +{% endblock %} + +{% block content %} +

Verify Result

+
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ + + +
+ +
+ + + +{% endblock %} + + + diff --git a/FusionIIIT/templates/examination/verifygrades.html b/FusionIIIT/templates/examination/verifygrades.html new file mode 100644 index 000000000..e340fd8fa --- /dev/null +++ b/FusionIIIT/templates/examination/verifygrades.html @@ -0,0 +1,170 @@ +{% extends 'examination/base.html' %} + +{% block sidetabmenu %} + +{% endblock %} + +{% block content %} +
+

VERIFY STUDENT MARKS

+ {% if registrations %} +
+ {% csrf_token %} +
+ + + + + + + + + + + {% for registration in registrations %} + + + + + + + {% endfor %} + +
Student IDSemester IDCourse IDGrade
{{ registration.student_id }}{{ registration.semester_id }}{{ registration.course_id }} + + + + +
+
+ {% comment %} {% endcomment %} + + +
+
+ +
+ {% else %} +
+
+ NO STUDENTS REGISTERED IN THIS COURSE THIS SEMESTER +
+

Please check back later or contact support for assistance.

+
+ {% endif %} +
+ + + + + + +{% endblock %} \ No newline at end of file diff --git a/FusionIIIT/templates/filetracking/composefile.html b/FusionIIIT/templates/filetracking/composefile.html index 1b0d2ee33..cb0117cce 100644 --- a/FusionIIIT/templates/filetracking/composefile.html +++ b/FusionIIIT/templates/filetracking/composefile.html @@ -2,8 +2,6 @@ {% load static %} {% block filetracking_tab %} - {% comment %}the compounder prescription tab starts here {% endcomment %} - - {% comment %}the ambulance schedule tab starts here {% endcomment %} +
{% csrf_token %} +
- - - - -
+
- -
- - - -
- - -
- - -
- - -
+ +
-
+
+ + +
-
- - -
+
+ + +
-
+
+ + +
-
- +
+ + +
+
- -
-
-
- -
- -
- -
- -
- -
+
+
+ +
- +
+
- -
-
- -
-
- {% comment %}the compounder prescription tab ends here {% endcomment %} - @@ -216,7 +156,6 @@

} function populateDropdown(values) { - console.log(values) var dropdown = $('#receiver_dropdown'); dropdown.empty(); $.each(values, function(index, value) { @@ -224,16 +163,44 @@

}); } }); - -{% endblock %} + function preventUnsavedUnload(e) { + if (formIsModified() && notSaving(e)) { + e.preventDefault(); + } + }; - - +{% endblock %} diff --git a/FusionIIIT/templates/filetracking/drafts.html b/FusionIIIT/templates/filetracking/drafts.html index fc040394f..0014a68f0 100644 --- a/FusionIIIT/templates/filetracking/drafts.html +++ b/FusionIIIT/templates/filetracking/drafts.html @@ -7,7 +7,7 @@ diff --git a/FusionIIIT/templates/filetracking/editdraft.html b/FusionIIIT/templates/filetracking/editdraft.html index cb49e7296..aa7423f7e 100644 --- a/FusionIIIT/templates/filetracking/editdraft.html +++ b/FusionIIIT/templates/filetracking/editdraft.html @@ -4,17 +4,14 @@ {% block filetracking_tab %} -
- +