From c2360b6b285b2f166eed755418d40c0ba5b0dff5 Mon Sep 17 00:00:00 2001 From: Divyanshu Sharma <21bcs079@iiitdmj.ac.in> Date: Sun, 18 Feb 2024 14:14:18 +0530 Subject: [PATCH] added apis for AC2 module and created backlog model --- .../academic_information/admin.py | 1 - .../academic_procedures/api/urls.py | 18 +- .../academic_procedures/api/views.py | 303 ++++++++++++------ .../migrations/0003_backlog_courses.py | 26 ++ .../academic_procedures/models.py | 18 +- .../applications/academic_procedures/urls.py | 3 +- .../migrations/0002_auto_20240218_1217.py | 18 ++ .../academic_procedures/addCourse.html | 2 +- 8 files changed, 284 insertions(+), 105 deletions(-) create mode 100644 FusionIIIT/applications/academic_procedures/migrations/0003_backlog_courses.py create mode 100644 FusionIIIT/applications/globals/migrations/0002_auto_20240218_1217.py 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_procedures/api/urls.py b/FusionIIIT/applications/academic_procedures/api/urls.py index f868315f9..e56aabebd 100644 --- a/FusionIIIT/applications/academic_procedures/api/urls.py +++ b/FusionIIIT/applications/academic_procedures/api/urls.py @@ -7,24 +7,30 @@ url(r'^stu/pre_registration' , views.student_pre_registration , name = 'pre_registration'), url(r'^stu/final_registration' , views.student_final_registration , name = 'final_registration'), 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/add_course' , views.add_course , name ='add_course') , # url(r'^stu/dropCourse' , views.dropCourse , name = 'dropCourse'), # url(r'^stu/replaceCourse' , views.replaceCourse , name = 'replaceCourse') + + url(r'^acad/view_registrations' , views.acad_view_reigstrations , name='acad_view_registrations'), url(r'^acad/get_course_list' , views.get_course_list , name = 'get_course_list' ), - url(r'^test/', views.test , name = 'test'), - url(r'^get_user_info' , views.get_user_info , name = 'get_user_info'), + 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'^fac/', views.academic_procedures_faculty, name='faculty_procedures'), + 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') diff --git a/FusionIIIT/applications/academic_procedures/api/views.py b/FusionIIIT/applications/academic_procedures/api/views.py index 6c4cc8026..7a127aae9 100644 --- a/FusionIIIT/applications/academic_procedures/api/views.py +++ b/FusionIIIT/applications/academic_procedures/api/views.py @@ -11,14 +11,15 @@ from rest_framework.permissions import AllowAny from rest_framework.response import Response -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, FinalRegistrations, SemesterMarks, - BranchChange , StudentRegistrationChecks, Semester , FeePayments ) + 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, @@ -35,46 +36,11 @@ User = get_user_model() 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 - 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) +#--------------------------------------- APIs of student---------------------------------------------------------- + # with this student can get all his details in one api call @api_view(['GET']) @@ -289,50 +255,48 @@ def academic_procedures_student(request): return Response(data=resp, status=status.HTTP_200_OK) -@api_view(['GET']) -def test(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() - obj = user_details.student - - current_date = date_time.date() - current_year = date_time.year - batch = obj.batch_id - - user_branch = user_details.department.name - cpi = obj.cpi - cur_spi='Sem results not available' # To be fetched from db if result uploaded +# api for student for adding courses for next semester +@api_view(['POST']) +def add_course(request): + try: + current_user = request.user + current_user_id = serializers.UserSerializer(current_user).data["id"] + s_id = current_user.extrainfo.id - details = { - 'current_user': current_user_data, - 'user_branch' : str(user_branch), - 'cpi' : cpi, - 'spi' : cur_spi - } - return Response(data = details , status=status.HTTP_200_OK) + 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 -# api for student for adding courses for next semester -@api_view(['POST']) -def add_course(request): - current_user = request.user - - if request.content_type == "application/json": - course_name = request.data["course_name"] - course_id = request.data["course_id"] - else: - course_name = request.POST["course_name"] - course_id = request.POST["course_id"] + sem_id_instance = Semester.objects.get(id = request.data.get('semester')) + sem_id = serializers.SemesterSerializer(sem_id_instance).data["id"] - res = {'message' : 'Course successfully added' , 'course_name' : course_name , 'course_id' : course_id} - return Response(data = res , status = status.HTTP_200_OK) + count = request.data.get('ct') + count = int(count) + reg_curr=[] + for i in range(1, count+1): + choice = "choice["+str(i)+"]" + slot = "slot["+str(i)+"]" + try: + course_id = Courses.objects.get(id = request.data.get(choice)) + courseslot_id = CourseSlot.objects.get(id = request.data.get(slot)) + # Check if maximum course registration limit has not reached and student has not already registered for that course + 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_instance, + course_slot_id = courseslot_id, + semester_id=sem_id_instance + ) + if p not in reg_curr: + reg_curr.append(p) + except Exception as e: + continue + course_registration.objects.bulk_create(reg_curr) + return Response(data = {"message" : "Courses have been added successfully."} , status = status.HTTP_200_OK) + except Exception as e: + return Response(data = {"error" : str(e) }, status= status.HTTP_500_INTERNAL_SERVER_ERROR) # simple api for getting to know the details of user who have logined in the system @@ -348,27 +312,30 @@ def get_user_info(request): return Response(data = details , status= status.HTTP_200_OK) -# with this acad admin can fetch the list of courses for any batch , semester and brach +# with this api student can see the list of courses offered to him in upcoming semester @api_view(['GET']) -def get_course_list(request): - - programme = request.data['programme'] - branch = request.data['branch'] - batch = request.data['batch'] - +def view_offered_courses(request): try : - print(programme , branch , batch) obj = Curriculum.objects.filter( programme = request.data['programme'], branch = request.data['branch'], - batch = request.data["batch"] + 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) - # obj = Curriculum.objects.filter(curriculum_id_=curriculum_id, course_type_ = course_type, programme_ = programme, batch_ = batch, branch_ = branch, sem_ = sem, optional_ = optional) - + # 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']) @@ -522,13 +489,125 @@ def student_final_registration(request): +#--------------------------------------- APIs of acad person---------------------------------------------------------- + + +# with this acad admin can fetch the list of courses for any batch , semester and brach +@api_view(['GET']) +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) + +#--------------------------------------- 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) + + 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) @@ -547,6 +626,48 @@ def student_final_registration(request): # 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) + + + diff --git a/FusionIIIT/applications/academic_procedures/migrations/0003_backlog_courses.py b/FusionIIIT/applications/academic_procedures/migrations/0003_backlog_courses.py new file mode 100644 index 000000000..d66fd5b16 --- /dev/null +++ b/FusionIIIT/applications/academic_procedures/migrations/0003_backlog_courses.py @@ -0,0 +1,26 @@ +# Generated by Django 3.1.5 on 2024-02-18 12:17 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('academic_information', '0001_initial'), + ('programme_curriculum', '0002_auto_20240217_1700'), + ('academic_procedures', '0002_auto_20240217_1700'), + ] + + operations = [ + migrations.CreateModel( + name='backlog_courses', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('is_summer_course', models.BooleanField(default=False)), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), + ('semester_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.semester')), + ('student_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), + ], + ), + ] diff --git a/FusionIIIT/applications/academic_procedures/models.py b/FusionIIIT/applications/academic_procedures/models.py index 14b8f1dfe..67db09837 100644 --- a/FusionIIIT/applications/academic_procedures/models.py +++ b/FusionIIIT/applications/academic_procedures/models.py @@ -671,16 +671,12 @@ 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) - - - ''' @@ -696,3 +692,17 @@ class Meta: db_table = 'course_registration' +class backlog_courses(models.Model): + ''' + Current Purpose : stores information regarding the backlog courses of a student + + 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(Courses, on_delete=models.CASCADE) + is_summer_course = models.BooleanField(default= False) \ No newline at end of file diff --git a/FusionIIIT/applications/academic_procedures/urls.py b/FusionIIIT/applications/academic_procedures/urls.py index e6817a812..4bfce817b 100644 --- a/FusionIIIT/applications/academic_procedures/urls.py +++ b/FusionIIIT/applications/academic_procedures/urls.py @@ -53,8 +53,7 @@ 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), diff --git a/FusionIIIT/applications/globals/migrations/0002_auto_20240218_1217.py b/FusionIIIT/applications/globals/migrations/0002_auto_20240218_1217.py new file mode 100644 index 000000000..2e41f26f4 --- /dev/null +++ b/FusionIIIT/applications/globals/migrations/0002_auto_20240218_1217.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.5 on 2024-02-18 12:17 + +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/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 %}