diff --git a/.gitignore b/.gitignore index bc7a548db..83d6642c9 100644 --- a/.gitignore +++ b/.gitignore @@ -75,4 +75,6 @@ package-lock.json .DS_Store +**/generated.pdf +.ruff_cache/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..979f857c5 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,14 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.2.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.6.9 + hooks: + - id: ruff + args: [ --fix ] + - id: ruff-format diff --git a/FusionIIIT/Fusion/middleware/custom_middleware.py b/FusionIIIT/Fusion/middleware/custom_middleware.py index fd8528e6e..74f7d7d72 100644 --- a/FusionIIIT/Fusion/middleware/custom_middleware.py +++ b/FusionIIIT/Fusion/middleware/custom_middleware.py @@ -2,7 +2,7 @@ from django.contrib.auth.signals import user_logged_in from django.dispatch import receiver from applications.globals.models import (ExtraInfo, Feedback, HoldsDesignation, - Issue, IssueImage, DepartmentInfo) + Issue, IssueImage, DepartmentInfo,ModuleAccess) from django.shortcuts import get_object_or_404, redirect, render def user_logged_in_middleware(get_response): @@ -35,7 +35,19 @@ def user_logged_in_handler(sender, user, request, **kwargs): print(i) request.session['currentDesignationSelected'] = designation[0] - request.session['allDesignations'] = designation + request.session['allDesignations'] = designation + first_designation = designation[0] + module_access = ModuleAccess.objects.filter(designation=first_designation).first() + + if module_access: + access_rights = {} + + field_names = [field.name for field in ModuleAccess._meta.get_fields() if field.name not in ['id', 'designation']] + + for field_name in field_names: + access_rights[field_name] = getattr(module_access, field_name) + + request.session['moduleAccessRights'] = access_rights print("logged iN") # Set the flag in the session to indicate that the function has bee+n executed @@ -47,4 +59,4 @@ def middleware(request): response = get_response(request) return response - return middleware \ No newline at end of file + return middleware \ No newline at end of file diff --git a/FusionIIIT/Fusion/settings/common.py b/FusionIIIT/Fusion/settings/common.py index 8fe12c577..563baddb9 100644 --- a/FusionIIIT/Fusion/settings/common.py +++ b/FusionIIIT/Fusion/settings/common.py @@ -51,6 +51,7 @@ # email of sender EMAIL_HOST_USER = 'fusionmailservice@iiitdmj.ac.in' +# EMAIL_HOST_PASSWORD = 'password' EMAIL_PORT = 587 ACCOUNT_EMAIL_REQUIRED = True @@ -79,8 +80,8 @@ # CELERY STUFF -# CELERY_BROKER_URL = 'redis://localhost:6379' -# CELERY_RESULT_BACKEND = 'redis://localhost:6379' +CELERY_BROKER_URL = 'redis://localhost:6379' +CELERY_RESULT_BACKEND = 'redis://localhost:6379' CELERY_ACCEPT_CONTENT = ['application/json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' @@ -128,6 +129,7 @@ 'applications.ps1', 'applications.programme_curriculum', 'applications.placement_cell', + 'applications.otheracademic', 'applications.recruitment', 'applications.scholarships', 'applications.visitor_hostel', @@ -279,7 +281,10 @@ DATA_UPLOAD_MAX_NUMBER_FIELDS = 10240 YOUTUBE_DATA_API_KEY = 'api_key' +CORS_ALLOWED_ORIGINS = [ + "http://localhost:5173", # Add your frontend origin here +] +CORS_ALLOW_CREDENTIALS = True -CORS_ORIGIN_ALLOW_ALL = True ALLOW_PASS_RESET = True diff --git a/FusionIIIT/Fusion/urls.py b/FusionIIIT/Fusion/urls.py index fafbab944..0aa36b92a 100755 --- a/FusionIIIT/Fusion/urls.py +++ b/FusionIIIT/Fusion/urls.py @@ -22,6 +22,8 @@ from django.contrib import admin from django.contrib.auth import views as auth_views +from django.views.static import serve + urlpatterns = [ url(r'^', include('applications.globals.urls')), @@ -37,6 +39,8 @@ url(r'^__debug__/', include(debug_toolbar.urls)), url(r'^research_procedures/', include('applications.research_procedures.urls')), url(r'^accounts/', include('allauth.urls')), + + # url(r'^api/iwdModuleV2/', include('applications.iwdModuleV2.api.urls')), url(r'^eis/', include('applications.eis.urls')), @@ -61,4 +65,6 @@ 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')), + url(r'^media/(?P.*)$', serve, {"document_root": settings.MEDIA_ROOT},), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/FusionIIIT/applications/academic_information/api/urls.py b/FusionIIIT/applications/academic_information/api/urls.py index 39a89fdb3..dfda1c00d 100644 --- a/FusionIIIT/applications/academic_information/api/urls.py +++ b/FusionIIIT/applications/academic_information/api/urls.py @@ -14,7 +14,8 @@ # url(r'^meeting',views.meeting_api,name='meeting-get-api'), - # url(r'^calendar',views.calendar_api,name='calendar-get-api'), + url(r'^calendar',views.ListCalendarView.as_view(),name='calendar-get-api'), + url(r'^update-calendar',views.update_calendar,name='calendar-update-api'), # url(r'^holiday',views.holiday_api,name='holiday-get-api'), diff --git a/FusionIIIT/applications/academic_information/api/views.py b/FusionIIIT/applications/academic_information/api/views.py index bbe6aebef..4ed4d13ee 100644 --- a/FusionIIIT/applications/academic_information/api/views.py +++ b/FusionIIIT/applications/academic_information/api/views.py @@ -12,6 +12,7 @@ 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 +from rest_framework.generics import ListCreateAPIView @api_view(['GET']) @permission_classes([IsAuthenticated]) @@ -82,7 +83,26 @@ def calendar_api(request): 'calendar' :calendar_serialized, } return Response(data=resp,status=status.HTTP_200_OK) - + +class ListCalendarView(ListCreateAPIView): + permission_classes = [IsAuthenticated] + authentication_classes=[TokenAuthentication] + serializer_class = serializers.CalendarSerializers + queryset = Calendar.objects.all() + +@api_view(['PUT']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def update_calendar(request): + if request.method == "PUT": + id = request.data.get("id") + instance = Calendar.objects.get(pk = id) + instance.from_date = request.data.get("from_date") + instance.to_date = request.data.get("to_date") + instance.description = request.data.get("description") + instance.save() + + return Response({"message": "Updated successfully!"}) @api_view(['GET']) @permission_classes([IsAuthenticated]) diff --git a/FusionIIIT/applications/academic_information/migrations/0001_initial.py b/FusionIIIT/applications/academic_information/migrations/0001_initial.py index 4b0f359c3..22fd38161 100644 --- a/FusionIIIT/applications/academic_information/migrations/0001_initial.py +++ b/FusionIIIT/applications/academic_information/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-07-16 15:44 from django.db import migrations, models import django.db.models.deletion @@ -9,8 +9,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('globals', '0001_initial'), ('programme_curriculum', '0001_initial'), + ('globals', '0001_initial'), ] operations = [ diff --git a/FusionIIIT/applications/academic_information/views.py b/FusionIIIT/applications/academic_information/views.py index b3702b3ef..2fab71e2f 100755 --- a/FusionIIIT/applications/academic_information/views.py +++ b/FusionIIIT/applications/academic_information/views.py @@ -30,7 +30,7 @@ from applications.academic_procedures.views import acad_proced_global_context , get_sem_courses from applications.programme_curriculum.models import Batch - +from django.db.models import Q @login_required @@ -845,6 +845,8 @@ def generatexlsheet(request): # print(request.POST) try: batch = request.POST['batch']#batch hai year wala (2020 , 21) + if batch == "": + batch = datetime.datetime.now().year course_id = int(request.POST['course']) # id of course in integer course = course = Courses.objects.get(id=course_id) @@ -858,17 +860,26 @@ def generatexlsheet(request): obj="" registered_courses = [] - for i in obj: - if i.student_id.batch_id.year == int(batch): - registered_courses.append(i) + registered_courses = course_registration.objects.filter( + Q(working_year=int(batch)) & + Q(course_id=course) & + Q(student_id__finalregistration__verified=True) + ) + + # for i in obj: + # if i.student_id.batch_id.year == int(batch): + # registered_courses.append(i) ans = [] + student_ids = set() for i in registered_courses: - k = [] - k.append(i.student_id.id.id) - k.append(i.student_id.id.user.first_name) - k.append(i.student_id.id.user.last_name) - k.append(i.student_id.id.department) - ans.append(k) + if i.student_id.id.id not in student_ids: + student_ids.add(i.student_id.id.id ) + k = [] + k.append(i.student_id.id.id) + k.append(i.student_id.id.user.first_name) + k.append(i.student_id.id.user.last_name) + k.append(i.student_id.id.department) + ans.append(k) ans.sort() output = BytesIO() diff --git a/FusionIIIT/applications/academic_procedures/api/serializers.py b/FusionIIIT/applications/academic_procedures/api/serializers.py index ee3d46743..e210d8586 100644 --- a/FusionIIIT/applications/academic_procedures/api/serializers.py +++ b/FusionIIIT/applications/academic_procedures/api/serializers.py @@ -3,7 +3,9 @@ from applications.academic_procedures.models import (ThesisTopicProcess, InitialRegistrations,InitialRegistration, FinalRegistration, FinalRegistrations, SemesterMarks, - BranchChange , StudentRegistrationChecks, Semester, backlog_course , CourseSlot , FeePayments , Course, course_registration) + BranchChange , StudentRegistrationChecks, Semester, backlog_course , CourseSlot , FeePayments , course_registration) + +from applications.programme_curriculum.models import Course from applications.academic_information.api.serializers import (CurriculumInstructorSerializer, CurriculumSerializer , CourseSerializer , StudentSerializers ) @@ -73,7 +75,10 @@ class Meta: model = CourseSlot fields = ('__all__') + class CourseSerializer(serializers.ModelSerializer): + class Meta: model = Course - fields = ('__all__') \ No newline at end of file + fields = ['id','code','name','credit'] + \ 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 1f46e8d4d..786c12760 100644 --- a/FusionIIIT/applications/academic_procedures/api/urls.py +++ b/FusionIIIT/applications/academic_procedures/api/urls.py @@ -18,6 +18,7 @@ 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/verify_course' , views.verify_course , name='verify_course'), 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' ), diff --git a/FusionIIIT/applications/academic_procedures/api/views.py b/FusionIIIT/applications/academic_procedures/api/views.py index 167ec6c84..bd3f2dc13 100644 --- a/FusionIIIT/applications/academic_procedures/api/views.py +++ b/FusionIIIT/applications/academic_procedures/api/views.py @@ -14,9 +14,9 @@ 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 Course - -from applications.academic_procedures.models import (Course, Student, Curriculum , ThesisTopicProcess, InitialRegistrations, +from applications.academic_procedures.models import ( Student, Curriculum , ThesisTopicProcess, InitialRegistrations, FinalRegistration, SemesterMarks,backlog_course, BranchChange , StudentRegistrationChecks, Semester , FeePayments , course_registration) @@ -33,7 +33,7 @@ get_detailed_sem_courses, InitialRegistration) -from applications.academic_procedures.views import get_sem_courses, get_student_registrtion_check, get_cpi, academics_module_notif +from applications.academic_procedures.views import get_sem_courses, get_student_registrtion_check, get_cpi, academics_module_notif, get_final_registration_choices, get_currently_registered_course, get_add_course_options, get_drop_course_options, get_replace_course_options from . import serializers @@ -129,6 +129,7 @@ def academic_procedures_student(request): 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) @@ -139,36 +140,7 @@ 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 @@ -229,8 +201,7 @@ def academic_procedures_student(request): 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) + # student_registration_check_final = get_student_registrtion_check(obj,next_sem_id) cpi = get_cpi(user_details.id) @@ -246,21 +217,27 @@ def academic_procedures_student(request): 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(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) + # 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) + + print("nextsem",next_sem_id.semester_no) + student_registration_check = get_student_registrtion_check(obj,next_sem_id.id) + print("adf",student_registration_check) + 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 + + if(student_registration_check): + pre_registration_flag = student_registration_check.pre_registration_flag + final_registration_flag = student_registration_check.final_registration_flag + # if(student_registration_check): teaching_credit_registration_course = None if phd_flag: @@ -268,6 +245,81 @@ def academic_procedures_student(request): teaching_credit_registration_course_data = serializers.CurriculumSerializer(teaching_credit_registration_course, many=True).data + 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.append({"slot_name": 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 + + next_sem_branch_course = get_sem_courses(next_sem_id, batch) + current_sem_branch_course = get_sem_courses(curr_sem_id, batch) + next_sem_registration_courses = get_sem_courses(next_sem_id, batch) + final_registration_choice, unavailable_courses_nextsem = get_final_registration_choices(next_sem_registration_courses,batch.year) + currently_registered_course = get_currently_registered_course(obj,next_sem_id) + + # currently_registered_course_show = [] + # for registered_course in currently_registered_course: + # currently_registered_course_show.append({"course_code":registered_course[1].code,"course_name":registered_course[1].name,"course_credit":registered_course[1].credit}) + + 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}) + + + 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 + + add_courses_options = get_add_course_options(current_sem_branch_course, currently_registered_course, batch.year) + + add_courses_options_show = [] + for course_option in add_courses_options: + course_slot = course_option[0] + courses = course_option[1] + courselist = [] + for course in courses: + courselist.append({'course_id': course.id, 'name': course.name, 'credit': course.credit, 'course_code': course.code}); + add_courses_options_show.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 }) + + + drop_courses_options = get_drop_course_options(currently_registered_course) + drop_courses_options_show = [] + + for course in drop_courses_options: + drop_courses_options_show.append({'course_id': course.id, 'name': course.name, 'credit': course.credit, 'course_code': course.code}) + + replace_courses_options = get_replace_course_options(currently_registered_course, batch.year) + print("replace",replace_courses_options) + + 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({'course_name':i.curr_id.name, 'course_code': i.curr_id.code, 'course_version': i.curr_id.version, 'course_credit': i.curr_id.credit ,'course_grade': 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]) + registers = obj.register_set.all() course_list = [] for i in registers: @@ -298,10 +350,11 @@ def academic_procedures_student(request): resp = { 'details': details, - 'currently_registered': currently_registered_courses_data, - 'pre_registered_courses' : pre_registered_courses, + 'user_sem' : user_sem, + # 'currently_registered_course': currently_registered_course, + # 'pre_registered_courses' : pre_registered_courses, 'pre_registered_courses_show' : pre_registered_course_show, - 'final_registered_course' : final_registered_courses, + # 'final_registered_courses' : final_registered_courses, 'final_registered_course_show' : final_registered_course_show, 'current_credits' : current_credits, 'courses_list': next_sem_branch_courses_data, @@ -309,9 +362,8 @@ def academic_procedures_student(request): '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, - 'final_registration_flag': final_registration_flag, - - + 'backlogCourseList': auto_backlog_courses_list, + 'student_flag' : student_flag, 'ug_flag' : ug_flag, 'masters_flag' : masters_flag, @@ -324,12 +376,15 @@ def academic_procedures_student(request): 'frd': final_registration_date_flag, 'adc_date_flag': add_or_drop_course_date_flag, - 'drop_courses_options' : currently_registered_courses_data, + 'add_courses_options': add_courses_options_show, + 'drop_courses_options' : drop_courses_options_show, + # 'replace_courses_options' : replace_courses_options, + '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, + 'pre_registration_flag': pre_registration_flag, 'teaching_credit_registration_course' : teaching_credit_registration_course_data, 'attendance': attendance_data, @@ -340,8 +395,9 @@ def academic_procedures_student(request): @api_view(['GET']) def get_all_courses(request): try: - obj = Course.objects.all() + obj = Courses.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) @@ -393,6 +449,7 @@ def add_course(request): 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): + print("space left = True") p = course_registration( course_id=course_id_instance, student_id=current_user, @@ -414,6 +471,7 @@ def add_course(request): res = {'message' : 'Courses successfully added' , "courses_added" : course_registration_data } return Response(data = res , status = status.HTTP_200_OK) except Exception as e: + print(e) return Response(data = str(e) , status= status.HTTP_500_INTERNAL_SERVER_ERROR) @@ -608,8 +666,6 @@ def final_registration(request): 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) @@ -667,7 +723,7 @@ def student_final_registration(request): ) obj.save() try: - registration_status = StudentRegistrationChecks.objects.filter(student_id = current_user["id"], semester_id = sem_id).update(final_registration_flag = True) + registration_status = StudentRegistrationChecks.objects.filter(student_id = current_user_instance, 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) @@ -814,7 +870,7 @@ def add_course_to_slot(request): 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: + except Courses.DoesNotExist: return JsonResponse({'error': 'Course does not exist.'}, status=400) # with this api request acad person can remove any course from a specific slot @@ -839,6 +895,8 @@ def remove_course_from_slot(request): # 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) @@ -979,7 +1037,91 @@ def verify_registration(request): return JsonResponse({'status': 'error', 'message': 'Error in processing'}) - +@api_view(['POST']) +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() + 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)): + # return Response() + + roll_no = request.data["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} + obj2 = Student.objects.all().select_related( + 'id', 'id__user', 'id__department').filter(id=roll_no).first() + + 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( + roll_no, curr_sem_id) + + idd = obj2 + for z in current_sem_courses: + z = z[1] + 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 + 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 + 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() + semester_no_list=[] + for i in semester_list: + semester_no_list.append(int(i.semester_no)) + # return JsonResponse( + # {'details': details, + # # 'dict2': dict2, + # 'course_list': serializers.CourseSerializer(course_list, many=True).data, + # # 'semester_list': semester_list, + # 'date': date} + # ) + + return JsonResponse({ + 'details': details, + 'course_list': serializers.CourseSerializer(course_list, many=True).data, + 'semester_list': serializers.SemesterSerializer(semester_list, many=True).data, + 'date': date + }) # These apis were implemented before but now don't use them they have some errors diff --git a/FusionIIIT/applications/academic_procedures/migrations/0001_initial.py b/FusionIIIT/applications/academic_procedures/migrations/0001_initial.py index 42142593d..71f23d8c2 100644 --- a/FusionIIIT/applications/academic_procedures/migrations/0001_initial.py +++ b/FusionIIIT/applications/academic_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-07-16 15:44 import datetime from django.db import migrations, models @@ -11,9 +11,9 @@ class Migration(migrations.Migration): initial = True dependencies = [ + ('programme_curriculum', '0001_initial'), ('globals', '0001_initial'), ('academic_information', '0001_initial'), - ('programme_curriculum', '0001_initial'), ] operations = [ @@ -368,6 +368,16 @@ class Migration(migrations.Migration): 'db_table': 'Bonafide', }, ), + migrations.CreateModel( + name='backlog_course', + 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='academic_information.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')), + ], + ), migrations.CreateModel( name='AssistantshipClaim', fields=[ @@ -402,4 +412,4 @@ class Migration(migrations.Migration): 'unique_together': {('curr_id', 'student_id')}, }, ), - ] \ No newline at end of file + ] diff --git a/FusionIIIT/applications/academic_procedures/models.py b/FusionIIIT/applications/academic_procedures/models.py index 6a3d5dcc7..2015a1ee8 100644 --- a/FusionIIIT/applications/academic_procedures/models.py +++ b/FusionIIIT/applications/academic_procedures/models.py @@ -686,7 +686,7 @@ class course_registration(models.Model): # grade = models.CharField(max_length=10) #course_registration_year = models.IntegerField() def __str__(self): - return self.semester_id + return str(self.semester_id.semester_no) class Meta: db_table = 'course_registration' diff --git a/FusionIIIT/applications/academic_procedures/views.py b/FusionIIIT/applications/academic_procedures/views.py index 526881364..5b2ea0f20 100644 --- a/FusionIIIT/applications/academic_procedures/views.py +++ b/FusionIIIT/applications/academic_procedures/views.py @@ -26,7 +26,7 @@ Student_attendance) from applications.central_mess.models import(Monthly_bill, Payments) - +from applications.online_cms.models import (Student_grades) from applications.programme_curriculum.models import (CourseSlot, Course as Courses, Batch, Semester , CourseInstructor) from applications.globals.models import (DepartmentInfo, Designation, ExtraInfo, Faculty, HoldsDesignation) @@ -90,7 +90,7 @@ def academic_procedures(request): 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": @@ -478,11 +478,11 @@ def academic_procedures_student(request): cur_spi='Sem results not available' # To be fetched from db if result uploaded backlogCourseList = [] - auto_backlog_courses = list(SemesterMarks.objects.filter(student_id = obj , grade = 'F')) + auto_backlog_courses = list(Student_grades.objects.filter(roll_no = 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]) + if not i.course_id.courseslots.filter(type__contains="Optional").exists(): + auto_backlog_courses_list.append([i.course_id.name, i.course_id.code, i.course_id.version, i.course_id.credit , i.grade]) backlogCourses = backlog_course.objects.select_related('course_id' , 'student_id' , 'semester_id' ).filter(student_id=obj) for i in backlogCourses: @@ -574,10 +574,10 @@ def academic_procedures_student(request): } ) - 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: @@ -916,7 +916,7 @@ def gen_course_list(request): course_id = request.POST['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( + obj=course_registration.objects.filter(course_id__id=course_id, working_year=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') @@ -924,13 +924,22 @@ def gen_course_list(request): 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}) + verified_students = [] + for registration in obj: + final_registration = FinalRegistration.objects.filter( + course_id=course, + semester_id=registration.semester_id, + student_id=registration.student_id, + verified=True + ).exists() + if final_registration: + verified_students.append({ + "rollno": registration.student_id.id.user.username, + "name": registration.student_id.id.user.first_name + " " + registration.student_id.id.user.last_name, + "department": registration.student_id.id.department.name + }) html = render_to_string('academic_procedures/gen_course_list.html', - {'students': students, 'batch':batch, 'course':course_id}, request) + {'students': verified_students, 'batch':batch, 'course':course_id}, request) maindict = {'html': html} obj = json.dumps(maindict) return HttpResponse(obj, content_type='application/json') @@ -965,8 +974,7 @@ def verify_course(request): acadadmin = temp.working k = str(user_details).split() final_user = k[2] - - if (str(acadadmin) != request.session.get('currentDesignationSelected')): + if ('acadadmin' != request.session.get('currentDesignationSelected')): return HttpResponseRedirect('/academic-procedures/') roll_no = request.POST["rollNo"] obj = ExtraInfo.objects.all().select_related( @@ -1088,7 +1096,7 @@ def acad_branch_change(request): k = str(user_details).split() final_user = k[2] - if (str(acadadmin) != request.session.get('currentDesignationSelected')): + if ('acadadmin' != request.session.get('currentDesignationSelected')): return HttpResponseRedirect('/academic-procedures/') # year = datetime.datetime.now().year @@ -1559,8 +1567,12 @@ def allot_courses(request): # 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) + course_registrations=[] final_registrations=[] + pre_registrations=[] + student_checks=[] # print('>>>>>>>>>>>>>>>>>>>' , sheet.nrows) + currroll=set() for i in range(1,sheet.nrows): roll_no = str(sheet.cell(i,0).value).split(".")[0] # print("Roll No from Excel:", roll_no) @@ -1568,21 +1580,37 @@ def allot_courses(request): course_code = sheet.cell_value(i,2) course_name = sheet.cell_value(i,3) 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()) + if(roll_no not in currroll): + student_check=StudentRegistrationChecks(student_id = student, semester_id = sem_id, pre_registration_flag = True,final_registration_flag = False) + student_checks.append(student_check) + currroll.add(roll_no) # print(">>>>>",roll_no,course_slot_name,course_code,course_name) except Exception as e: print('----------------------' , e) + pre_registration=InitialRegistration(student_id=student,course_slot_id=course_slot, + course_id=course,semester_id=sem_id,priority=1) + pre_registrations.append(pre_registration) final_registration=FinalRegistration(student_id=student,course_slot_id=course_slot, course_id=course,semester_id=sem_id) final_registrations.append(final_registration) + + courseregistration=course_registration(working_year=datetime.datetime.now().year,course_id=course,semester_id=sem_id,student_id=student,course_slot_id=course_slot) + course_registrations.append(courseregistration) + + try: + InitialRegistration.objects.bulk_create(pre_registrations) + StudentRegistrationChecks.objects.bulk_create(student_checks) FinalRegistration.objects.bulk_create(final_registrations) + course_registration.objects.bulk_create(course_registrations) messages.success(request, 'Successfully uploaded!') return HttpResponseRedirect('/academic-procedures/main') # return HttpResponse("Success") @@ -1630,7 +1658,7 @@ def user_check(request): final_user="" pass - if (str(acadadmin) != request.session.get('currentDesignationSelected')): + if ('acadadmin' != request.session.get('currentDesignationSelected')): return True else: return False @@ -2021,7 +2049,8 @@ def get_currently_registered_courses(id, user_sem): return ans def get_currently_registered_course(id, sem_id): - obj = course_registration.objects.all().filter(student_id = id, semester_id=sem_id) + # obj = course_registration.objects.all().filter(student_id = id, semester_id=sem_id) + obj = course_registration.objects.all().filter(student_id = id) courses = [] for i in obj: courses.append((i.course_slot_id,i.course_id)) @@ -2066,13 +2095,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 @@ -2585,7 +2614,7 @@ def verify_registration(request): 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") + academicadmin = get_object_or_404(User, username = request.user.username) 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() @@ -2633,7 +2662,7 @@ def auto_verify_registration(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") + academicadmin = get_object_or_404(User, username = request.user.username) # 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() @@ -3776,8 +3805,8 @@ def add_course_to_slot(request): 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 = CourseSlot.objects.filter(name=course_slot_name).first() + course = Courses.objects.filter(code=course_code).first() course_slot.courses.add(course) return JsonResponse({'message': f'Course {course_code} added to slot {course_slot_name} successfully.'}, status=200) @@ -3796,8 +3825,8 @@ def remove_course_from_slot(request): 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 = CourseSlot.objects.filter(name=course_slot_name).first() + course = Courses.objects.filter(code=course_code).first() course_slot.courses.remove(course) return JsonResponse({'message': f'Course {course_code} removed from slot {course_slot_name} successfully.'}, status=200) except CourseSlot.DoesNotExist: @@ -3903,7 +3932,7 @@ def replaceSwayam(request): k = str(user_details).split() final_user = k[2] - if (str(acadadmin) != request.session.get('currentDesignationSelected')): + if ('acadadmin' != request.session.get('currentDesignationSelected')): return HttpResponseRedirect('/academic-procedures/') roll_no = request.POST["rollNo"] obj = ExtraInfo.objects.all().select_related( diff --git a/FusionIIIT/applications/central_mess/api/serializers.py b/FusionIIIT/applications/central_mess/api/serializers.py index 582f2725e..1e077d6d4 100644 --- a/FusionIIIT/applications/central_mess/api/serializers.py +++ b/FusionIIIT/applications/central_mess/api/serializers.py @@ -98,4 +98,8 @@ class Meta: class DeregistrationRequestSerializer(serializers.ModelSerializer): class Meta: model = Deregistration_Request + fields = ('__all__') +class UpdatePaymentRequestSerializer(serializers.ModelSerializer): + class Meta: + model = Update_Payment 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 7f4c03286..9f0af6c1d 100644 --- a/FusionIIIT/applications/central_mess/api/urls.py +++ b/FusionIIIT/applications/central_mess/api/urls.py @@ -26,4 +26,6 @@ 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'), + url('updatePaymentRequestApi', views.UpdatePaymentRequestApi.as_view(), name='updatePaymentRequestApi'), + url('get_mess_balance_statusApi', views.Get_Mess_Balance_Status.as_view(), name='get_mess_balance_statusApi'), ] \ 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 a6fbe4a97..f91453d5b 100644 --- a/FusionIIIT/applications/central_mess/api/views.py +++ b/FusionIIIT/applications/central_mess/api/views.py @@ -1,7 +1,9 @@ #APIs +from datetime import date, datetime, timedelta from django.db.models import F from rest_framework.views import APIView from rest_framework.response import Response +# from FusionIIIT.notification.views import central_mess_notif from .serializers import * from django.shortcuts import get_object_or_404 from applications.central_mess.models import * @@ -9,6 +11,8 @@ from applications.globals.models import ExtraInfo, HoldsDesignation, Designation from django.http import JsonResponse +today_g = datetime.datetime.now() + class FeedbackApi(APIView): def get(self, request): @@ -61,6 +65,29 @@ def put(self, request): feedback_request.save() return Response({'status':200}) + + def delete(self, request): + data = request.data + student_id = data.get('student_id') + mess = data.get('mess') + feedback_type = data.get('feedback_type') + description = data.get('description') + fdate = data.get('fdate') + + # Locate the feedback record + feedback_request = get_object_or_404( + Feedback, + student_id=student_id, + mess=mess, + feedback_type=feedback_type, + description=description, + fdate=fdate, + ) + + # Delete the feedback record + feedback_request.delete() + + return Response({'status': 200, 'message': 'Feedback deleted successfully.'}) class MessinfoApi(APIView): @@ -126,6 +153,7 @@ def post(self, request): class Monthly_billApi(APIView): def get(self, request): + monthly_bill_obj = Monthly_bill.objects.all(); serialized_obj = Monthly_billSerializer(monthly_bill_obj, many=True) return Response({'status':200, 'payload':serialized_obj.data}) @@ -168,31 +196,36 @@ def post(self, request): class PaymentsApi(APIView): def get(self, request): + username = get_object_or_404(User,username=request.user.username) + idd = ExtraInfo.objects.get(user=username) + student = Student.objects.get(id=idd.id) payments_obj = Payments.objects.all(); + payments_obj = payments_obj.filter(student_id=student) serialized_obj = PaymentsSerializer(payments_obj, many=True) return Response({'status':200, 'payload':serialized_obj.data}) - def post(self, request): - data = request.data + # def post(self, request): + # data = request.data - # sem = data['sem'] - # year = data['year'] - amount_paid = data['amount_paid'] + # # sem = data['sem'] + # # year = data['year'] + # amount_paid = data['amount_paid'] - username = get_object_or_404(User,username=request.user.username) - idd = ExtraInfo.objects.get(user=username) - student = Student.objects.get(id=idd.id) + # username = get_object_or_404(User,username=request.user.username) + # idd = ExtraInfo.objects.get(user=username) + # student = Student.objects.get(id=idd.id) - obj = Payments( - student_id = student, - # sem = sem, - # year = year, - amount_paid = amount_paid, - ) - obj.save() - return Response({'status':200}) + # obj = Payments( + # student_id = student, + # # sem = sem, + # # year = year, + # amount_paid = amount_paid, + # ) + # obj.save() + # return Response({'status':200}) + class MenuApi(APIView): def get(self, request): menu_obj = Menu.objects.all(); @@ -201,6 +234,7 @@ def get(self, request): def post(self, request): data = request.data + print(data) mess_option = data['mess_option'] meal_time = data['meal_time'] @@ -224,17 +258,44 @@ def post(self, request): data = request.data # student_id = data['mess_option'] + flag=1 start_date = data['start_date'] end_date = data['end_date'] purpose = data['purpose'] status = data['status'] + """ + status: + '2' -> approved + '1' -> pending + '0' -> declined + """ app_date = data['app_date'] leave_type = data['leave_type'] + if (end_date < start_date): + flag = 0 + return Response({'status': 3, 'message': 'Please check the dates'}) + username = get_object_or_404(User,username=request.user.username) idd = ExtraInfo.objects.get(user=username) student = Student.objects.get(id=idd.id) + date_format = "%Y-%m-%d" + b = datetime.datetime.strptime(str(start_date), date_format) + d = datetime.datetime.strptime(str(end_date), date_format) + + rebate_check = Rebate.objects.filter(student_id=student, status='2') + for r in rebate_check: + a = datetime.datetime.strptime(str(r.start_date), date_format) + c = datetime.datetime.strptime(str(r.end_date), date_format) + if ((b <= a and (d >= a and d <= c)) or (b >= a and (d >= a and d <= c)) + or (b <= a and (d >= c)) or ((b >= a and b <= c) and (d >= c))): + flag = 0 + data = { + 'status': 3, + 'message': "Already applied for these dates", + } + return Response({'status': 3, 'message': 'Already applied for these dates'}) obj = Rebate( student_id = student, @@ -245,6 +306,10 @@ def post(self, request): end_date= end_date, start_date = start_date ) + + if flag == 1: + message = 'Your leave request has been accepted between dates ' + str(b.date()) + ' and ' + str(d.date()) + # central_mess_notif(request.user, student.id.user, 'leave_request', message) obj.save() return Response({'status':200}) @@ -404,8 +469,7 @@ def get(self, request): def post(self, request): data = request.data - - + start_date = data['start_date'] end_date = data['end_date'] status = data['status'] @@ -568,13 +632,11 @@ def post(self,request): return response class Get_Reg_Records(APIView): - - def post(self,request): - student = request.data['student_id'] - reg_record = Reg_records.objects.filter(student_id=student) - + def get(self,request): + student_id = request.GET.get('student_id') + reg_record = Reg_records.objects.filter(student_id=student_id) serialized_obj = reg_recordSerialzer(reg_record,many=True) - return Response({'payload':serialized_obj.data}) + return Response({'payload':serialized_obj.data}) class Get_Student_bill(APIView): @@ -656,6 +718,7 @@ def put(self, request): reg_main = Reg_main.objects.get(student_id=student) reg_main.current_mess_status = "Registered" reg_main.balance = F('balance') + amount + reg_main.mess_option = mess_option except Reg_main.DoesNotExist: reg_main = Reg_main.objects.create( student_id=student, @@ -719,4 +782,162 @@ def put(self, request): 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 + return Response({'error': str(e)}, status=400) + +# class DeregistrationApi(APIView): +# def post(self, request): +# try: +# data = request.data +# print(data) +# student_id = data['student_id'] +# end_date = data['end_date'] + +# username = get_object_or_404(User, username=student_id) +# idd = ExtraInfo.objects.get(user=username) +# student = Student.objects.get(id=idd.id) + +# 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) + +class UpdatePaymentRequestApi(APIView): + def get(self, request): + student_id = request.query_params.get('student_id') + if student_id: + update_payment_requests = Update_Payment.objects.filter(student_id=student_id) + else: + update_payment_requests = Update_Payment.objects.all() + + serializer = UpdatePaymentRequestSerializer(update_payment_requests, many=True) + return Response({'status': 200, 'payload': serializer.data}) + + def post(self, request): + serializer = UpdatePaymentRequestSerializer(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'] + payment_date = data['payment_date'] + amount = data['amount'] + Txn_no = data['Txn_no'] + img = data['img'] + new_status = data['status'] + new_remark = data['update_payment_remark'] + + username = get_object_or_404(User, username=student_id) + idd = ExtraInfo.objects.get(user=username) + student = Student.objects.get(id=idd.id) + + UpdatePayment_request = get_object_or_404(Update_Payment, student_id = student_id, payment_date = payment_date, amount = amount, Txn_no = Txn_no) + + UpdatePayment_request.status = new_status + UpdatePayment_request.update_payment_remark = new_remark + UpdatePayment_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() + + reg_main = Reg_main.objects.get(student_id=student) + reg_main.balance = F('balance') + amount + reg_main.save() + + return Response({'status': 200}) + except Exception as e: + print({'error': str(e)}) + return Response({'error': str(e)}, status=400) + +from rest_framework.parsers import MultiPartParser, FormParser +from rest_framework import status +from openpyxl import load_workbook + +class UpdateBillExcelAPI(APIView): + parser_classes = (MultiPartParser, FormParser) + + def post(self, request): + if 'file' not in request.FILES: + return Response({'error': 'No file provided'}, status=status.HTTP_400_BAD_REQUEST) + + file = request.FILES['file'] + if not file.name.endswith(('.xlsx', '.xls')): + return Response({'error': 'Invalid file format. Only .xlsx and .xls are allowed.'}, status=status.HTTP_400_BAD_REQUEST) + + try: + wb = load_workbook(file) + sheet = wb.active + flag = False + + for row in sheet.iter_rows(min_row=2): + student_id = str(row[0].value).upper() + try: + student = Student.objects.select_related('id', 'id__user', 'id__department').get(id=student_id) + except Student.DoesNotExist: + continue + + month = str(row[1].value) + year = row[2].value + amt = row[3].value + rebate_cnt = row[4].value + rebate_amt = row[5].value + total_amt = row[6].value + try: + bill = Monthly_bill.objects.get(student_id=student_id, month=month, year=year) + reg_main = Reg_main.objects.get(student_id=student_id) + reg_main.balance += bill.total_bill + bill.amount = amt + bill.rebate_count = rebate_cnt + bill.rebate_amount = rebate_amt + bill.total_bill = total_amt + reg_main.balance -= total_amt + + bill.save() + reg_main.save() + except Monthly_bill.DoesNotExist: + bill = Monthly_bill( + student_id=student, + month=month, + year=year, + amount=amt, + rebate_count=rebate_cnt, + rebate_amount=rebate_amt, + total_bill=total_amt + ) + bill.save() + + return Response({'message': 'File processed successfully'}, status=status.HTTP_200_OK) + + except Exception as e: + return Response({'error': f'An error occurred: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + +class Get_Mess_Balance_Status(APIView): + def get(self, request): + username = get_object_or_404(User,username=request.user.username) + idd = ExtraInfo.objects.get(user=username) + student_id = Student.objects.get(id=idd.id) + 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_id) + # y = Menu.objects.filter(mess_option=mess_optn.mess_option) + current_rem_balance = mess_optn.balance + current_mess_status = mess_optn.current_mess_status + except: + mess_optn={} + mess_optn={'mess_option':'no-mess'} + # y = Menu.objects.filter(mess_option="mess1") + current_rem_balance = 0 + current_mess_status = 'Deregistered' + + return Response({'payload': {'mess_option': mess_optn.mess_option, 'current_rem_balance': current_rem_balance, 'current_mess_status': current_mess_status}}) diff --git a/FusionIIIT/applications/central_mess/migrations/0001_initial.py b/FusionIIIT/applications/central_mess/migrations/0001_initial.py index c197e0231..5ac270527 100644 --- a/FusionIIIT/applications/central_mess/migrations/0001_initial.py +++ b/FusionIIIT/applications/central_mess/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-07-16 15:44 import applications.central_mess.models import datetime @@ -63,6 +63,19 @@ class Migration(migrations.Migration): ('student_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), ], ), + migrations.CreateModel( + name='Update_Payment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('Txn_no', models.CharField(max_length=20)), + ('img', models.ImageField(default=None, upload_to='images/')), + ('amount', models.IntegerField(default=0)), + ('status', models.CharField(default='pending', max_length=10)), + ('update_remark', models.CharField(default='NA', max_length=50)), + ('payment_date', models.DateField(default=None, null=True)), + ('student_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), + ], + ), migrations.CreateModel( name='Special_request', fields=[ @@ -186,7 +199,7 @@ class Migration(migrations.Migration): ('amount_paid', models.IntegerField(default=0)), ('payment_month', models.CharField(default=applications.central_mess.models.current_month, max_length=20)), ('payment_year', models.IntegerField(default=applications.central_mess.models.current_year)), - ('payment_date', models.DateField(default=datetime.date(2024, 4, 15))), + ('payment_date', models.DateField(default=datetime.date(2024, 7, 16))), ('student_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), ], options={ @@ -221,4 +234,4 @@ class Migration(migrations.Migration): 'unique_together': {('student_id', 'mess_option')}, }, ), - ] + ] \ No newline at end of file diff --git a/FusionIIIT/applications/central_mess/migrations/0002_auto_20241012_1459.py b/FusionIIIT/applications/central_mess/migrations/0002_auto_20241012_1459.py new file mode 100644 index 000000000..eb0679027 --- /dev/null +++ b/FusionIIIT/applications/central_mess/migrations/0002_auto_20241012_1459.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1.5 on 2024-10-12 14:59 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('central_mess', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='payments', + name='payment_date', + field=models.DateField(default=datetime.date.today), + ), + migrations.AlterUniqueTogether( + name='payments', + unique_together=set(), + ), + ] + \ No newline at end of file diff --git a/FusionIIIT/applications/central_mess/migrations/0003_auto_20250209_1736.py b/FusionIIIT/applications/central_mess/migrations/0003_auto_20250209_1736.py new file mode 100644 index 000000000..181e0e991 --- /dev/null +++ b/FusionIIIT/applications/central_mess/migrations/0003_auto_20250209_1736.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.5 on 2025-02-09 17:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('central_mess', '0002_auto_20241012_1459'), + ] + + operations = [ + migrations.AlterField( + model_name='registration_request', + name='img', + field=models.ImageField(default=None, upload_to='mess/images/registration_request/%Y/%m/%d/'), + ), + ] diff --git a/FusionIIIT/applications/central_mess/models.py b/FusionIIIT/applications/central_mess/models.py index f92614ba1..c9ef74c14 100644 --- a/FusionIIIT/applications/central_mess/models.py +++ b/FusionIIIT/applications/central_mess/models.py @@ -154,10 +154,10 @@ class Payments(models.Model): amount_paid = models.IntegerField(default=0) payment_month = models.CharField(max_length=20, default=current_month) payment_year = models.IntegerField(default = current_year) - payment_date = models.DateField(default= datetime.date.today()) + payment_date = models.DateField(default= datetime.date.today) - class Meta: - unique_together = (('student_id', 'payment_date')) + # class Meta: + # unique_together = (('student_id', 'payment_date')) def __str__(self): return '{}'.format(self.student_id.id) @@ -283,7 +283,7 @@ def __str__(self): class Registration_Request(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) + img = models.ImageField(upload_to='mess/images/registration_request/%Y/%m/%d/',default=None) amount=models.IntegerField(default=0) status=models.CharField(max_length=10,default='pending') registration_remark=models.CharField(max_length=50,default='NA') diff --git a/FusionIIIT/applications/central_mess/views.py b/FusionIIIT/applications/central_mess/views.py index 255f34e40..60a4abb3b 100644 --- a/FusionIIIT/applications/central_mess/views.py +++ b/FusionIIIT/applications/central_mess/views.py @@ -335,7 +335,7 @@ def mess(request): context = { 'menu': menu_data, # 'reg_menu': y, - # 'messinfo': mess_optn, + 'messinfo': mess_optn, 'monthly_bill': monthly_bill, # 'total_due': amount_due, 'vaca': vaca_obj, diff --git a/FusionIIIT/applications/complaint_system/api/urls.py b/FusionIIIT/applications/complaint_system/api/urls.py index 480cd9af7..5d7cacd0b 100644 --- a/FusionIIIT/applications/complaint_system/api/urls.py +++ b/FusionIIIT/applications/complaint_system/api/urls.py @@ -26,4 +26,4 @@ url(r'^removesupervisor/(?P[0-9]+)',views.edit_supervisor_api,name='supervisor-delete-api'), url(r'^updatesupervisor/(?P[0-9]+)',views.edit_supervisor_api,name='supervisor-put-api'), -] +] \ No newline at end of file diff --git a/FusionIIIT/applications/complaint_system/api/views.py b/FusionIIIT/applications/complaint_system/api/views.py index 304697017..c12b73ddb 100644 --- a/FusionIIIT/applications/complaint_system/api/views.py +++ b/FusionIIIT/applications/complaint_system/api/views.py @@ -23,7 +23,7 @@ def complaint_details_api(request,detailcomp_id1): if complaint_detail.worker_id is None: worker_detail_serialized = {} else : - worker_detail = Workers.objects.get(id=complaint_detail.worker_id.id) + worker_detail = worker_detail.objects.get(id=complaint_detail.worker_id) worker_detail_serialized = serializers.WorkersSerializers(instance=worker_detail).data complainer = User.objects.get(username=complaint_detail.complainer.user.username) complainer_serialized = serializers.UserSerializers(instance=complainer).data @@ -154,7 +154,7 @@ def caretaker_api(request): user = get_object_or_404(User ,username=request.user.username) user = ExtraInfo.objects.all().filter(user = user).first() try : - supervisor = Supervisor.objects.get(sup_id=user) + supervisor = Supervisor.objects.get(staff_id=user) except Supervisor.DoesNotExist: return Response({'message':'Logged in user does not have the permissions'},status=status.HTTP_203_NON_AUTHORITATIVE_INFORMATION) serializer = serializers.CaretakerSerializers(data=request.data) @@ -170,7 +170,7 @@ def edit_caretaker_api(request,c_id): user = get_object_or_404(User ,username=request.user.username) user = ExtraInfo.objects.all().filter(user = user).first() try : - supervisor = Supervisor.objects.get(sup_id=user) + supervisor = Supervisor.objects.get(staff_id=user) except Supervisor.DoesNotExist: return Response({'message':'Logged in user does not have the permissions'},status=status.HTTP_203_NON_AUTHORITATIVE_INFORMATION) try: @@ -230,4 +230,3 @@ def edit_supervisor_api(request,s_id): serializer.save() return Response(serializer.data,status=status.HTTP_200_OK) return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST) - diff --git a/FusionIIIT/applications/complaint_system/migrations/0001_initial.py b/FusionIIIT/applications/complaint_system/migrations/0001_initial.py index 44df90d3c..e40ba5606 100644 --- a/FusionIIIT/applications/complaint_system/migrations/0001_initial.py +++ b/FusionIIIT/applications/complaint_system/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-07-16 15:44 from django.db import migrations, models import django.db.models.deletion diff --git a/FusionIIIT/applications/complaint_system/serializers.py b/FusionIIIT/applications/complaint_system/serializers.py new file mode 100644 index 000000000..d224dcaf3 --- /dev/null +++ b/FusionIIIT/applications/complaint_system/serializers.py @@ -0,0 +1,90 @@ +from rest_framework import serializers +from .models import StudentComplain, Caretaker +from applications.globals.models import ExtraInfo + +# Added StudentComplainSerializer +class StudentComplainSerializer(serializers.ModelSerializer): + class Meta: + model = StudentComplain + fields = "__all__" + +# Added CaretakerSerializer +class CaretakerSerializer(serializers.ModelSerializer): + class Meta: + model = Caretaker + fields = "__all__" + +# Optionally, add ExtraInfoSerializer if needed +class ExtraInfoSerializer(serializers.ModelSerializer): + class Meta: + model = ExtraInfo + fields = "__all__" +from rest_framework import serializers +from .models import StudentComplain, Caretaker +from applications.globals.models import ExtraInfo + +# Serializer for StudentComplain (already added previously) +class StudentComplainSerializer(serializers.ModelSerializer): + class Meta: + model = StudentComplain + fields = '__all__' + +# Serializer for Caretaker (already added previously) +class CaretakerSerializer(serializers.ModelSerializer): + class Meta: + model = Caretaker + fields = '__all__' + +# Serializer for Feedback submission +class FeedbackSerializer(serializers.Serializer): + feedback = serializers.CharField() + rating = serializers.IntegerField() + +# Serializer for Resolve Pending complaints +class ResolvePendingSerializer(serializers.Serializer): + yesorno = serializers.ChoiceField(choices=[('Yes', 'Yes'), ('No', 'No')]) + comment = serializers.CharField(required=False) +# serializers.py + +from rest_framework import serializers +from .models import StudentComplain, Caretaker +from applications.globals.models import ExtraInfo + +# Serializer for StudentComplain (already added previously) +class StudentComplainSerializer(serializers.ModelSerializer): + class Meta: + model = StudentComplain + fields = '__all__' + +# Serializer for Caretaker (already added previously) +class CaretakerSerializer(serializers.ModelSerializer): + class Meta: + model = Caretaker + fields = '__all__' + +# Serializer for Feedback submission +class FeedbackSerializer(serializers.Serializer): + feedback = serializers.CharField() + rating = serializers.IntegerField() + +# Serializer for Resolve Pending complaints +class ResolvePendingSerializer(serializers.Serializer): + yesorno = serializers.ChoiceField(choices=[('Yes', 'Yes'), ('No', 'No')]) + comment = serializers.CharField(required=False, allow_blank=True) +# serializers.py + +from rest_framework import serializers +from .models import StudentComplain, Caretaker, Workers +from applications.globals.models import ExtraInfo + +# Serializer for StudentComplain (already added previously) +class StudentComplainSerializer(serializers.ModelSerializer): + class Meta: + model = StudentComplain + fields = '__all__' + +# Serializer for Workers (added to handle Workers model) +class WorkersSerializer(serializers.ModelSerializer): + class Meta: + model = Workers + fields = '__all__' diff --git a/FusionIIIT/applications/complaint_system/urls.py b/FusionIIIT/applications/complaint_system/urls.py index 2bd0c87e0..c39a5d965 100644 --- a/FusionIIIT/applications/complaint_system/urls.py +++ b/FusionIIIT/applications/complaint_system/urls.py @@ -1,49 +1,78 @@ -from django.conf.urls import url,include +#urls.py -from . import views +# complaint/urls.py +from django.urls import path +from .views import ( + CheckUser, + UserComplaintView, + CaretakerFeedbackView, + SubmitFeedbackView, + ComplaintDetailView, +) +from .views import ( + CaretakerLodgeView, + CaretakerView, + FeedbackCareView, + ResolvePendingView, + ComplaintDetailView, + SearchComplaintView, + SubmitFeedbackCaretakerView, +) +from .views import ( + SupervisorLodgeView, + SupervisorView, + FeedbackSuperView, + CaretakerIdKnowMoreView, + SupervisorComplaintDetailView, + SupervisorResolvePendingView, + SupervisorSubmitFeedbackView, +) + +from django.urls import path +from .views import ( + RemoveWorkerView, + ForwardCompaintView, + DeleteComplaintView, + ChangeStatusView, + ChangeStatusSuperView, + GenerateReportView, + # Other imported views +) -app_name = 'complaint' -urlpatterns = [ - url(r'^$', views.check, name='complaint'), - # url(r'^login/$', views.login1, name='complaint'), - url(r'^user/$', views.user), - url(r'^user/caretakerfb/$' , views.caretaker_feedback), - url(r'^user/(?P[0-9]+)/$', views.submitfeedback), - url(r'^user/detail/(?P[0-9]+)/$', views.detail,name='detail'), - # url(r'^user/check_complaint/$', views.save_comp), - - # caretaker - url(r'^caretaker/lodge/$', views.caretakerlodge), - url(r'^caretaker/$', views.caretaker, name='caretaker'), - url(r'^caretaker/feedback/(?P[0-9]+)/$', views.feedback_care), - url(r'^caretaker/pending/(?P[0-9]+)/$', views.resolvepending), - url(r'^caretaker/detail2/(?P[0-9]+)/$', views.detail), - url(r'^caretaker/search_complaint$', views.search_complaint), - url(r'^caretaker/(?P[0-9]+)/feedback/$', views.submitfeedbackcaretaker), - - - # supervisor - url(r'^supervisor/lodge/$', views.supervisorlodge), - url(r'^supervisor/$', views.supervisor), - url(r'^supervisor/feedback/(?P[0-9]+)/$', views.feedback_super), - url(r'^supervisor/caretaker_id_know_more/(?P[0-9]+)/$', views.caretaker_id_know_more), - # url(r'^supervisor/caretaker_id_know_more/(?P[0-9]+)/complaint_reassign_super/(?P[0-9]+)/$', views.complaint_reassign_super, name = 'complaint_reassign_super'), - url(r'^supervisor/detail/(?P[0-9]+)/$', views.detail3, name = 'detail3'), - url(r'^supervisor/pending/(?P[0-9]+)/$', views.resolvependingsuper), - url(r'^supervisor/(?P[0-9]+)/$', views.submitfeedbacksuper), - - - - # CRUD task - url(r'^caretaker/worker_id_know_more/(?P[0-9]+)/removew/$', views.removew), - url(r'^caretaker/(?P[0-9]+)/$', views.assign_worker,name='assign_worker'), - url(r'^caretaker/deletecomplaint/(?P[0-9]+)/$', views.deletecomplaint), - # url(r'^caretaker/(?P[0-9]+)/$', views.assign_worker), - url(r'^caretaker/(?P[0-9]+)/(?P[0-9]+)/$', views.changestatus), - url(r'^supervisor/(?P[0-9]+)/(?P[0-9]+)/$', views.changestatussuper), +app_name = "complaint" - url(r'^api/',include('applications.complaint_system.api.urls')) +urlpatterns = [ + path("", CheckUser.as_view(), name="complaint"), + path("user/", UserComplaintView.as_view(), name="user-complaints"), + path("user/caretakerfb/", CaretakerFeedbackView.as_view(), name="caretaker-feedback"), + path("user//", SubmitFeedbackView.as_view(), name="submit-feedback"), + path("user/detail//", ComplaintDetailView.as_view(), name="detail"), + # Other URL patterns + path('caretaker/lodge/', CaretakerLodgeView.as_view()), # Converted to DRF + path('caretaker/', CaretakerView.as_view(), name='caretaker'), # Converted to DRF + path('caretaker/feedback//', FeedbackCareView.as_view()), # Converted to DRF + path('caretaker/pending//', ResolvePendingView.as_view()), # Converted to DRF + path('caretaker/detail2//', ComplaintDetailView.as_view()), # Converted to DRF + path('caretaker/search_complaint', SearchComplaintView.as_view()), # Converted to DRF + path('caretaker//feedback/', SubmitFeedbackCaretakerView.as_view()), # Converted to DRF + # Supervisor URLs + path('supervisor/lodge/', SupervisorLodgeView.as_view()), + path('supervisor/', SupervisorView.as_view()), + path('supervisor/feedback//', FeedbackSuperView.as_view()), + path('supervisor/caretaker_id_know_more//', CaretakerIdKnowMoreView.as_view()), + # The following URL is commented out as per the original code + # path('supervisor/caretaker_id_know_more//complaint_reassign_super//', views.complaint_reassign_super, name='complaint_reassign_super'), + path('supervisor/detail//', SupervisorComplaintDetailView.as_view(), name='detail3'), + path('supervisor/pending//', SupervisorResolvePendingView.as_view()), + path('supervisor//', SupervisorSubmitFeedbackView.as_view()), + # CRUD task URLs + path('caretaker/worker_id_know_more//removew/', RemoveWorkerView.as_view()), + path('caretaker//', ForwardCompaintView.as_view(), name='assign_worker'), + path('caretaker/deletecomplaint//', DeleteComplaintView.as_view()), + path('caretaker///', ChangeStatusView.as_view()), + path('supervisor///', ChangeStatusSuperView.as_view()), + path('generate-report/', GenerateReportView.as_view(), name='generate-report-api'), ] \ No newline at end of file diff --git a/FusionIIIT/applications/complaint_system/views.py b/FusionIIIT/applications/complaint_system/views.py index 9d3dd7316..da1ee656a 100644 --- a/FusionIIIT/applications/complaint_system/views.py +++ b/FusionIIIT/applications/complaint_system/views.py @@ -1,509 +1,236 @@ +#views.py import datetime from datetime import date, datetime, timedelta from django.contrib import messages -from django import forms from django.contrib.auth import authenticate, login -from django.contrib.auth.decorators import login_required -from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import get_object_or_404, render -from applications.globals.models import User , ExtraInfo, HoldsDesignation +from applications.globals.models import User, ExtraInfo, HoldsDesignation from notifications.models import Notification -from .models import Caretaker, StudentComplain, Supervisor, Workers, SectionIncharge -from notification.views import complaint_system_notif - +from .models import Caretaker, StudentComplain, Supervisor +from notification.views import complaint_system_notif from applications.filetracking.sdk.methods import * from applications.filetracking.models import * from operator import attrgetter -#function for reassign to another worker -# @login_required -# def complaint_reassign(request,wid,iid): - # current_user = get_object_or_404(User, username=request.user.username) - # y = ExtraInfo.objects.all().select_related('user','department').filter(user=current_user).first() - # if request.method == 'POST': - # type = request.POST.get('submit', '') - # a = get_object_or_404(User, username=request.user.username) - # y = ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() - # comp_id = y.id - # if type == 'assign': - - # complaint_finish = request.POST.get('complaint_finish', '') - # worker_id = request.POST.get('assign_worker', '') - # w = Workers.objects.select_related('secincharge_id','secincharge_id__staff_id','secincharge_id__staff_id__user','secincharge_id__staff_id__department').get(id=worker_id) - # StudentComplain.objects.select_for_update().filter(id=iid).\ - # update(worker_id=w, status=1) - # url = '/complaint/secincharge/worker_id_know_more/'+wid; - # complainer_details = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=iid) - # student=0 - # message = "Your complaint has been re-assigned" - # complaint_system_notif(request.user, complainer_details.complainer.user ,'reassign_worker_alert',complainer_details.id,student,message) - # return HttpResponseRedirect(url) - - # else: - # y = ExtraInfo.objects.all().select_related('user','department').get(id=y.id) - # a = SectionIncharge.objects.select_related('staff_id','staff_id__user','staff_id__department').get(staff_id=y) - # b = a.work_type - # comp_id = y.id - # try: - # detail = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=iid).first() - # total_secincharge = SectionIncharge.objects.select_related('staff_id','staff_id__user','staff_id__department').all() - # total_secincharges_in_area = SectionIncharge.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(work_type=b) - # worker = [] - # workertemp = [] - # flag = '' - # temp = detail.location - # try: - - # if Workers.objects.select_related('secincharge_id','secincharge_id__staff_id','secincharge_id__staff_id__user','secincharge_id__staff_id__department').filter(secincharge_id=a).count() == 0: - # flag = 'no_worker' - # else: - # workertemp = Workers.objects.select_related('secincharge_id','secincharge_id__staff_id','secincharge_id__staff_id__user','secincharge_id__staff_id__department').filter(secincharge_id=a) - # j = 1 - # for i in workertemp: - # worker.append(i) - - # except SectionIncharge.DoesNotExist: - # flag = 'no_worker' - - # except StudentComplain.DoesNotExist: - # return HttpResponse("

Not a valid complaint

") - # return render(request, "complaintModule/reassignworker.html", - # {'detail': detail, 'worker': worker, 'flag': - # flag, 'total_secincharge': total_secincharge,'a':a, 'wid':wid, 'total_secincharges_in_area':total_secincharges_in_area}) - - - -# @login_required -# def complaint_reassign_super(request,caretaker_id,iid): - # current_user = get_object_or_404(User, username=request.user.username) - # y = ExtraInfo.objects.all().select_related('user','department').filter(user=current_user).first() - # sup = Supervisor.objects.select_related('sup_id','sup_id__user','sup_id__department').get(sup_id = y) - # this_area = sup.area - # if request.method == 'POST': - # a = get_object_or_404(User, username=request.user.username) - # y = ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() - # comp_id = y.id - - -#for SectionIncharge -@login_required -def assign_worker(request, comp_id1): - current_user = get_object_or_404(User, username=request.user.username) - y = ExtraInfo.objects.all().select_related('user','department').filter(user=current_user).first() - """ - The function is used to assign workers to complaints. - @param: - request - trivial. - comp_idl - id of the complaint which the user intends to support/unsupport. - - @variables: - type - takes the value either assign or redirect. - a - To handle error. - y - Foreign key . - context - Holds data needed to make necessary changes in the template. - """ - if request.method == 'POST': - type = request.POST.get('submit', '') - a = get_object_or_404(User, username=request.user.username) - y = ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() - comp_id = y.id - - - complaint_details = StudentComplain.objects.all().filter(id=comp_id1) - - - - complaint_type=complaint_details[0].complaint_type - - supervisor=Supervisor.objects.all().filter(type=complaint_type) - if not supervisor.exists(): - return HttpResponse("

Supervisor does not exist of this complaint type

") - - supervisor_details=ExtraInfo.objects.all().filter(id=supervisor[0].sup_id.id) - - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(id=comp_id1).\ - update(status=1) - - sup = HoldsDesignation.objects.select_related('user','working','designation').filter(user = supervisor_details[0].user_id) - - - files=File.objects.all().filter(src_object_id=comp_id1) - - supervisor_username=User.objects.all().filter(id=supervisor_details[0].user_id) - file=forward_file(file_id= files.first().id, - receiver=supervisor_username[0].username, - receiver_designation=sup[0].designation, - file_extra_JSON= {}, - remarks = "", - file_attachment= None) - print(file) - - - return HttpResponseRedirect('/complaint/caretaker/') - else: - y = ExtraInfo.objects.all().select_related('user','department').get(id=y.id) - # a = SectionIncharge.objects.select_related('staff_id','staff_id__user','staff_id__department').get(staff_id=y) - - comp_id = y.id - try: - detail = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=comp_id1).first() - # total_caretaker = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').all() - # total_caretakers_in_area = Supervisor.objects.select_related('sup_id') - # supervisors_in_area= HoldsDesignation.objects.select_related('user','working','designation').get(total_caretakers_in_area = dsgn) - # workertemp = [] - # worker = [] - # flag = '' - # temp = detail.location - # try: - # if Workers.objects.select_related('secincharge_id','secincharge_id__staff_id','secincharge_id__staff_id__user','secincharge_id__staff_id__department').filter(secincharge_id=a).count() == 0: - # flag = 'no_worker' - # else: - # workertemp1 = Workers.objects.select_related('secincharge_id','secincharge_id__staff_id','secincharge_id__staff_id__user','secincharge_id__staff_id__department').filter(secincharge_id=a) - # workertemp = workertemp1.filter(worker_type=detail.complaint_type) - # j = 1 - # for i in workertemp: - # worker.append(i) - - # except SectionIncharge.DoesNotExist: - # flag = 'no_worker' - - except StudentComplain.DoesNotExist: - return HttpResponse("

Not a valid complaint

") - return render(request, "complaintModule/assignworker.html", - {'detail': detail}) - - -#for SectionIncharge -@login_required -def discharge_worker(request,wid,cid): - current_user = get_object_or_404(User, username=request.user.username) - y = ExtraInfo.objects.all().select_related('user','department').filter(user=current_user).first() - - this_worker = Workers.objects.select_related('secincharge_id','secincharge_id__staff_id','secincharge_id__staff_id__user','secincharge_id__staff_id__department').get(id=wid) - com_in_concern= StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=cid); - com_in_concern.worker_id=None; - com_in_concern.status=0; - StudentComplain.objects.select_for_update().filter(id=cid).\ - update(worker_id=None, status=0) - url='/complaint/secincharge/detail2/'+cid; - return HttpResponseRedirect(url) - - - -@login_required -def caretaker_feedback(request): - """ - This function deals with submission of complaints for a particular type of caretaker - - """ - a = get_object_or_404(User, username=request.user.username) - if request.method == 'POST': - - feedback = request.POST.get('feedback', '') - rating = request.POST.get('rating', '') - caretaker_type = request.POST.get('caretakertype','') - all_caretaker = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(area=caretaker_type).order_by('-id') - newrate=0 - for x in all_caretaker: - rate=x.rating - if(rate==0): - newrate=int(rating) - else: - a1=int(rate) - b1=int(rating) - c1=(a1+b1)/2 - newrate=c1 - Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(area=caretaker_type).\ - update(myfeedback=feedback, rating=newrate) - return HttpResponseRedirect('/complaint/user/') - else: - - return render(request, "complaintModule/submit_feedback_caretaker.html", {'a': a}) - - -#for SectionIncharge -@login_required -def worker_id_know_more(request, work_id): - """ - function to know pending complaints assigned to the worker - """ - this_worker = Workers.objects.select_related('secincharge_id','secincharge_id__staff_id','secincharge_id__staff_id__user','secincharge_id__staff_id__department').get(id=work_id) - num = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(worker_id=this_worker).count(); - complaints_list = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(worker_id=this_worker); - complaints_list_onhold = [] - for i in complaints_list: - if i.status == 1: - complaints_list_onhold.append(i) - numpend = len(complaints_list_onhold) - work_under_secincharge1 = this_worker.secincharge_id.staff_id.user.first_name - work_under_secincharge2 = this_worker.secincharge_id.staff_id.user.last_name - return render(request, "complaintModule/worker_id_know_more.html",{'this_worker':this_worker,'work_under_secincharge1':work_under_secincharge1,'work_under_secincharge2':work_under_secincharge2, 'num':num, 'complaints_list':complaints_list, 'complaints_list_onhold':complaints_list_onhold, 'numpend':numpend}) - - - -@login_required -def check(request): - """ - The function is used to check the type of user . - There are three types of users student,staff or faculty. - @param: - request - trivial. - - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - if request.user.is_authenticated: - a = get_object_or_404(User, username=request.user.username) - b = ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() - temp = ExtraInfo.objects.all().select_related('user','department').filter(user_type='faculty') - print('----------------------------') - print(len(temp)) - temp = ExtraInfo.objects.all().select_related('user','department').filter(user_type='fx') - print('----------------------------') - print(len(temp)) - print('----------------------------') - print(b.user_type) - print('----------------------------') - print('----------------------------') - print('----------------------------') - supervisor_list=Supervisor.objects.all() - caretaker_list=Caretaker.objects.all() - is_supervisor=False - is_caretaker=False +# Import DRF classes +from rest_framework.views import APIView +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from .serializers import ( + StudentComplainSerializer, + CaretakerSerializer, + ExtraInfoSerializer, +) + +# Converted to DRF APIView +class CheckUser(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request): + """ + The function is used to check the type of user. + There are three types of users: student, staff, or faculty. + Returns the user type and the appropriate endpoint. + """ + a = request.user + b = ExtraInfo.objects.select_related("user", "department").filter(user=a).first() + supervisor_list = Supervisor.objects.all() + caretaker_list = Caretaker.objects.all() + is_supervisor = False + is_caretaker = False for i in supervisor_list: - if b.id==i.sup_id_id: - is_supervisor=True + if b.id == i.sup_id_id: + is_supervisor = True break for i in caretaker_list: - if b.id==i.staff_id_id: - is_caretaker=True + if b.id == i.staff_id_id: + is_caretaker = True break if is_supervisor: - return HttpResponseRedirect('/complaint/supervisor/') + return Response({"user_type": "supervisor", "next_url": "/complaint/supervisor/"}) elif is_caretaker: - return HttpResponseRedirect('/complaint/caretaker/') - - elif b.user_type == 'student': - return HttpResponseRedirect('/complaint/user/') - # elif b.user_type == 'fx': - # return HttpResponseRedirect('/complaint/supervisor/') - elif b.user_type == 'staff': - return HttpResponseRedirect('/complaint/user/') - elif b.user_type == 'faculty': - return HttpResponseRedirect('/complaint/user/') + return Response({"user_type": "caretaker", "next_url": "/complaint/caretaker/"}) + elif b.user_type == "student": + return Response({"user_type": "student", "next_url": "/complaint/user/"}) + elif b.user_type == "staff": + return Response({"user_type": "staff", "next_url": "/complaint/user/"}) + elif b.user_type == "faculty": + return Response({"user_type": "faculty", "next_url": "/complaint/user/"}) else: - return HttpResponse("

wrong user credentials

") - else: - return HttpResponseRedirect('/') - - -@login_required - -def user(request): - """ - The function is used to register a complaint - @param: - request - trivial. - - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - 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': - comp_type = request.POST.get('complaint_type', '') - location = request.POST.get('Location', '') - specific_location = request.POST.get('specific_location', '') - comp_file = request.FILES.get('myfile') - - details = request.POST.get('details', '') - status = 0 - # finish time is according to complaint type + return Response({"error": "wrong user credentials"}, status=400) + +# Converted to DRF APIView +class UserComplaintView(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request): + """ + Returns the list of complaints made by the user. + """ + a = request.user + y = ExtraInfo.objects.select_related("user", "department").filter(user=a).first() + complaints = StudentComplain.objects.filter(complainer=y).order_by("-id") + serializer = StudentComplainSerializer(complaints, many=True) + return Response(serializer.data) + + def post(self, request): + """ + Allows the user to register a new complaint. + """ + a = request.user + y = ExtraInfo.objects.select_related("user", "department").filter(user=a).first() + data = request.data.copy() + data["complainer"] = y.id + data["status"] = 0 + comp_type = data.get("complaint_type", "") + # Finish time is according to complaint type complaint_finish = datetime.now() + timedelta(days=2) - if comp_type == 'Electricity': + if comp_type == "Electricity": complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'carpenter': + elif comp_type == "Carpenter": complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'plumber': + elif comp_type == "Plumber": complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'garbage': + elif comp_type == "Garbage": complaint_finish = datetime.now() + timedelta(days=1) - elif comp_type == 'dustbin': + elif comp_type == "Dustbin": complaint_finish = datetime.now() + timedelta(days=1) - elif comp_type == 'internet': + elif comp_type == "Internet": complaint_finish = datetime.now() + timedelta(days=4) - elif comp_type == 'other': + elif comp_type == "Other": complaint_finish = datetime.now() + timedelta(days=3) - - if location!="": - - user_details=User.objects.get(id=y.user_id) - - obj1, created = StudentComplain.objects.get_or_create(complainer=y, - complaint_type=comp_type, - location=location, - specific_location=specific_location, - details=details, - status=status, - complaint_finish=complaint_finish, - upload_complaint=comp_file) - - - - - - - if location == "hall-1": - dsgn ="hall1caretaker" - elif location =="hall-3": - dsgn ="hall3caretaker" - elif location =="hall-4": - dsgn ="hall4caretaker" - elif location =="CC1": - dsgn ="cc1convener" - elif location =="CC2": - dsgn ="CC2 convener" - elif location == "core_lab": - dsgn = "corelabcaretaker" - elif location =="LHTC": - dsgn ="lhtccaretaker" - elif location =="NR2": - dsgn ="nr2caretaker" - elif location =="Maa Saraswati Hostel": - dsgn ="mshcaretaker" - elif location =="Nagarjun Hostel": - dsgn ="nhcaretaker" - elif location =="Panini Hostel": - dsgn ="phcaretaker" + data["complaint_finish"] = complaint_finish.date() + + serializer = StudentComplainSerializer(data=data) + if serializer.is_valid(): + complaint = serializer.save() + # Handle file uploads, notifications, etc. + # Omitted for brevity. + return Response(serializer.data, status=201) else: - dsgn = "rewacaretaker" - caretaker_name = HoldsDesignation.objects.select_related('user','working','designation').get(designation__name = dsgn) - - c1=HoldsDesignation.objects.filter(user_id=y.user_id).all() - print(c1[0].designation) - file_id = create_file(uploader=user_details.username, - uploader_designation=c1[0].designation, - receiver=caretaker_name.user.username, - receiver_designation=caretaker_name.designation, - src_module="complaint", - src_object_id= str(obj1.id), - file_extra_JSON= {}, - attached_file = None) - - # print(" wertyuioiuhygfdsdfghjk") - print(file_id) - - # This is to allow the student - student = 0 - message = "A New Complaint has been lodged" - complaint_system_notif(request.user, caretaker_name.user,'lodge_comp_alert',obj1.id,student,message) - # complaint_system_notif(request.user, secincharge_name.staff_id.user,'lodge_comp_alert',obj1.id,1,message) - - messages.success(request,message) - - - - return HttpResponseRedirect('/complaint/user') - - else: - 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) - + return Response(serializer.errors, status=400) + +# Converted to DRF APIView +class CaretakerFeedbackView(APIView): + permission_classes = [IsAuthenticated] + + def post(self, request): + """ + Allows the user to submit feedback for a particular type of caretaker. + """ + feedback = request.data.get("feedback", "") + rating = request.data.get("rating", "") + caretaker_type = request.data.get("caretakertype", "") + try: + rating = int(rating) + except ValueError: + return Response({"error": "Invalid rating"}, status=400) + all_caretaker = Caretaker.objects.filter(area=caretaker_type).order_by("-id") + for x in all_caretaker: + rate = x.rating + if rate == 0: + newrate = rating + else: + newrate = (rate + rating) / 2 + x.myfeedback = feedback + x.rating = newrate + x.save() + return Response({"success": "Feedback submitted"}) + +# Converted to DRF APIView +class SubmitFeedbackView(APIView): + permission_classes = [IsAuthenticated] + + def post(self, request, complaint_id): + """ + Allows the user to submit feedback for a complaint. + """ + feedback = request.data.get("feedback", "") + rating = request.data.get("rating", "") - notification = Notification.objects.filter(recipient=a.id) - notification = notification.filter(data__exact={'url':'complaint:detail','module':'Complaint System'}) - # notification_message = [] - # for notification in x: - # to = User.objects.get(id=notification.actor_object_id).username - # from django.utils.timesince import timesince as timesince_ - # duration = timesince_(notification.timestamp,None) - # notification_message.append(notification.verb+' by '+ to + ' ' + duration + ' ago ') + try: + rating = int(rating) + except ValueError: + return Response({"error": "Invalid rating"}, status=400) + try: + StudentComplain.objects.filter(id=complaint_id).update(feedback=feedback, flag=rating) + a = StudentComplain.objects.filter(id=complaint_id).first() + care = Caretaker.objects.filter(area=a.location).first() + rate = care.rating + if rate == 0: + newrate = rating + else: + newrate = int((rating + rate) / 2) + care.rating = newrate + care.save() + return Response({"success": "Feedback submitted"}) + except: + return Response({"error": "Internal server errror"}, status=500) + +# Converted to DRF APIView +class ComplaintDetailView(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request, detailcomp_id1): + """ + Returns the details of a complaint. + """ + try: + complaint = StudentComplain.objects.select_related( + "complainer", "complainer_user", "complainer_department" + ).get(id=detailcomp_id1) + except StudentComplain.DoesNotExist: + return Response({"error": "Complaint not found"}, status=404) + serializer = StudentComplainSerializer(complaint) + return Response(serializer.data) + # Import DRF classes +from rest_framework.views import APIView +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from rest_framework import status + +# Import necessary models and serializers +from .serializers import ( + StudentComplainSerializer, + CaretakerSerializer, + FeedbackSerializer, + ResolvePendingSerializer, +) +# Other imports remain the same +import datetime +from datetime import datetime, timedelta +from django.contrib import messages +from django.contrib.auth import authenticate, login +from django.shortcuts import get_object_or_404, render +from applications.globals.models import User, ExtraInfo, HoldsDesignation +from notifications.models import Notification +from .models import Caretaker, StudentComplain, Supervisor +from notification.views import complaint_system_notif +from applications.filetracking.sdk.methods import * +from applications.filetracking.models import * +from operator import attrgetter - c1=HoldsDesignation.objects.filter(user_id=y.user_id).all() - print(c1[0].designation) - # c2=Designation.objects.filter(i) - - - - - outbox_files = view_outbox( - username=user_details.username, - designation=c1[0].designation, - src_module="complaint" - ) - print(outbox_files) - - outbox=[] - comp_list=set() - for i in outbox_files: - - outbox.append(i) - print(outbox) - for i in outbox: - file_history = view_history(file_id=i['id']) - print(i['id']) - comp=File.objects.filter(id=i['id']) - print(comp[0].src_object_id) - complaint=StudentComplain.objects.all().filter(id=comp[0].src_object_id) - print(complaint) - if complaint[0].complainer.user.username == user_details.username : - comp_list.add(complaint) - # file_history = view_history(file_id=i['id']) - - # comp=File.objects.filter(uploader=file_history[0]['current_id']) - # for j in comp: - # c=StudentComplain.objects.all().filter(id=j.src_object_id) - # comp_list.add(c) - # print(c[0]) - - # break - complaint_final_list=[] - for i in comp_list: - complaint_final_list.append(i[0]) - - sorted_history = sorted(complaint_final_list, key=attrgetter('complaint_date'), reverse=True) - print(complaint_final_list) - return render(request, "complaintModule/complaint_user.html", - {'outbox': sorted_history,'notification':notification, 'comp_id': y.id, 'history':outbox}) - - -@login_required -def save_comp(request): - """ - The function is used to save the complaint entered by the user - @param: - request - trivial. - - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - if request.method == 'POST': - comp_id = request.POST.get('comp_id', '') - comp_type = request.POST.get('complaint_type', '') - location = request.POST.get('Location', '') - specific_location = request.POST.get('specific_location', '') - comp_file = request.FILES.get('myfile') - details = request.POST.get('details', '') +# Converted to DRF APIView +class CaretakerLodgeView(APIView): + permission_classes = [IsAuthenticated] + + def post(self, request): + """ + Allows the caretaker to lodge a new complaint. + """ + # Get the current user + a = request.user + y = ExtraInfo.objects.select_related('user', 'department').filter(user=a).first() + + data = request.data.copy() + data['complainer'] = y.id + data['status'] = 0 + comp_type = data.get('complaint_type', '') + # Finish time is according to complaint type complaint_finish = datetime.now() + timedelta(days=2) if comp_type == 'Electricity': complaint_finish = datetime.now() + timedelta(days=2) @@ -519,516 +246,253 @@ def save_comp(request): complaint_finish = datetime.now() + timedelta(days=4) elif comp_type == 'other': complaint_finish = datetime.now() + timedelta(days=3) + data['complaint_finish'] = complaint_finish.date() + + serializer = StudentComplainSerializer(data=data) + if serializer.is_valid(): + complaint = serializer.save() + + # Notification logic (if any) + location = data.get('location', '') + if location == "hall-1": + dsgn = "hall1caretaker" + elif location == "hall-3": + dsgn = "hall3caretaker" + elif location == "hall-4": + dsgn = "hall4caretaker" + elif location == "CC1": + dsgn = "cc1convener" + elif location == "CC2": + dsgn = "CC2 convener" + elif location == "core_lab": + dsgn = "corelabcaretaker" + elif location == "LHTC": + dsgn = "lhtccaretaker" + elif location == "NR2": + dsgn = "nr2caretaker" + elif location == "Maa Saraswati Hostel": + dsgn = "mshcaretaker" + elif location == "Nagarjun Hostel": + dsgn = "nhcaretaker" + elif location == "Panini Hostel": + dsgn = "phcaretaker" + else: + dsgn = "rewacaretaker" + caretaker_name = HoldsDesignation.objects.select_related('user', 'working', 'designation').get(designation__name=dsgn) - y = ExtraInfo.objects.all().select_related('user','department').get(id=comp_id) - x = StudentComplain(complainer=y, - complaint_type=comp_type, - location=location, - specific_location=specific_location, - details=details, - complaint_finish=complaint_finish, - upload_complaint =comp_file) - - x.save() - - return HttpResponseRedirect('/complaint/user/') - - - -@login_required -def caretaker(request): - """ - The function is used to display details to the caretaker such as registered complaints - @param: - request - trivial. - - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - current_user = get_object_or_404(User, username=request.user.username) - y = ExtraInfo.objects.all().select_related('user','department').filter(user=current_user).first() - - if request.method == 'POST': - # type = request.POST.get('submit', '') - # worker_type = request.POST.get('complaint_type', '') - # name = request.POST.get('name', '') - # phone = request.POST.get('phone_no', '') - # age = request.POST.get('age', '') - # try: - # y = ExtraInfo.objects.all().select_related('user','department').get(id=y.id) - # a = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').get(staff_id=y) - # except Exception as e: - # a = None - # y = None - # intage = int(age) - # intphone = int(phone) - # if len(phone) == 10 and intage > 20 and intage < 50 and intphone > 1999999999: - # x = Workers(caretaker_id=a, - # name=name, - # age=age, - # phone=phone, - # worker_type=worker_type) - # if not Workers.objects.filter(caretaker_id=a,name=name, age=age,phone=phone,worker_type=worker_type).exists(): - # x.save() - - # if len(phone) == 10 and intage > 20 and intage < 50 and intphone > 1999999999: - # obj, created = Workers.objects.get_or_create(caretaker_id=a, - # name=name, - # age=age, - # phone=phone, - # worker_type=worker_type) - - # b = a.area - # historytemp = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(location=b).order_by('-id') - # history = [] - # j = 1 - # k = 1 - # for i in historytemp: - # history.append(i) - # # if j%2 == 1: - # # history.append(i) - # # j = j+1 - - # for h in history: - # h.serial_no = k - # k=k+1 - user_details=User.objects.get(id=y.user_id) - # if user_details.username=="shyams": - # desgn="hall3caretaker" - # if user_details.username=="hall4caretaker": - # desgn="hall4caretaker" - - # total_worker = [] - - - # total_workertemp = Workers.objects.select_related('caretaker_id','caretaker_id__staff_id','caretaker_id__staff_id__user','caretaker_id__staff_id__department').filter(caretaker_id=a) - # j = 1 - # for i in total_workertemp: - # if j%2 != 0: - # total_worker.append(i) - # j = j + 1 - + # Send notification + student = 1 + message = "A New Complaint has been lodged" + complaint_system_notif(request.user, caretaker_name.user, 'lodge_comp_alert', complaint.id, student, message) - # for i in total_workertemp: - # total_worker.append(i) - - complaint_assign_no = [] - comp_type = request.POST.get('complaint_type', '') - location = request.POST.get('Location', '') - specific_location = request.POST.get('specific_location', '') - comp_file = request.FILES.get('myfile') - - details = request.POST.get('details', '') - status = 0 - # finish time is according to complaint type - complaint_finish = datetime.now() + timedelta(days=2) - if comp_type == 'Electricity': - complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'carpenter': - complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'plumber': - complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'garbage': - complaint_finish = datetime.now() + timedelta(days=1) - elif comp_type == 'dustbin': - complaint_finish = datetime.now() + timedelta(days=1) - elif comp_type == 'internet': - complaint_finish = datetime.now() + timedelta(days=4) - elif comp_type == 'other': - complaint_finish = datetime.now() + timedelta(days=3) - # y = ExtraInfo.objects.all().select_related('user','department').get(id=comp_id) - #check if location given - if location!="": - user_details=User.objects.get(id=y.user_id) - obj1, created = StudentComplain.objects.get_or_create(complainer=y, - complaint_type=comp_type, - location=location, - specific_location=specific_location, - details=details, - status=status, - complaint_finish=complaint_finish, - upload_complaint=comp_file) - - - if location == "hall-1": - dsgn ="hall1caretaker" - elif location =="hall-3": - dsgn ="hall3caretaker" - elif location =="hall-4": - dsgn ="hall4caretaker" - elif location =="CC1": - dsgn ="cc1convener" - elif location =="CC2": - dsgn ="CC2 convener" - elif location == "core_lab": - dsgn = "corelabcaretaker" - elif location =="LHTC": - dsgn ="lhtccaretaker" - elif location =="NR2": - dsgn ="nr2caretaker" - elif location =="Maa Saraswati Hostel": - dsgn ="mshcaretaker" - elif location =="Nagarjun Hostel": - dsgn ="nhcaretaker" - elif location =="Panini Hostel": - dsgn ="phcaretaker" + return Response(serializer.data, status=status.HTTP_201_CREATED) else: - dsgn = "rewacaretaker" - caretaker_name = HoldsDesignation.objects.select_related('user','working','designation').get(designation__name = dsgn) - print(caretaker_name.user.username) - print(user_details.username) - print(caretaker_name.designation) - - user_details=User.objects.get(id=y.user_id) - des=HoldsDesignation.objects.filter(user=user_details).all() - file_id = create_file(uploader=user_details.username, - uploader_designation=des[0].designation, - receiver=caretaker_name.user.username, - receiver_designation=dsgn, - src_module="complaint", - src_object_id= str(obj1.id), - file_extra_JSON= {}, - attached_file = None) - - - # This is to allow the student - student = 1 - message = "A New Complaint has been lodged" - complaint_system_notif(request.user, caretaker_name.user,'lodge_comp_alert',obj1.id,student,message) - - # return render(request, "complaintModule/complaint_user.html", - # {'history': history, 'comp_id': comp_id }) - # next = request.POST.get('next', '/') - - messages.success(request,message) - # return HttpResponseRedirect('/complaint/user') - - - # for x in total_worker: - # worker = Workers.objects.select_related('caretaker_id','caretaker_id__staff_id','caretaker_id__staff_id__user','caretaker_id__staff_id__department').get(id=x.id) - # temp = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(worker_id=worker).count() - # worker.total_complaint = temp - # complaint_assign_no.append(worker) - - notification = Notification.objects.filter(recipient=current_user.id) - notification = notification.filter(data__exact={'url':'complaint:detail2','module':'Complaint System'}) - - return HttpResponseRedirect('/complaint/caretaker') - - - - else: - # y = ExtraInfo.objects.all().select_related('user','department').get(id=y.id) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def get(self, request): + """ + Returns the list of complaints lodged by the caretaker. + """ + a = request.user + y = ExtraInfo.objects.select_related('user', 'department').filter(user=a).first() + complaints = StudentComplain.objects.filter(complainer=y).order_by('-id') + serializer = StudentComplainSerializer(complaints, many=True) + return Response(serializer.data) + +# Converted to DRF APIView +class CaretakerView(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request): + """ + Returns the list of complaints assigned to the caretaker. + """ + current_user = request.user + y = ExtraInfo.objects.select_related('user', 'department').filter(user=current_user).first() + try: + a = Caretaker.objects.select_related('staff_id').get(staff_id=y.id) + b = a.area + complaints = StudentComplain.objects.filter(location=b).order_by('-id') + serializer = StudentComplainSerializer(complaints, many=True) + return Response(serializer.data) + except Caretaker.DoesNotExist: + return Response({'error': 'Caretaker does not exist'}, status=status.HTTP_404_NOT_FOUND) + +# Converted to DRF APIView +class FeedbackCareView(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request, feedcomp_id): + """ + Returns the feedback details for a specific complaint. + """ + try: + detail = StudentComplain.objects.select_related('complainer', 'complainer_user', 'complainer_department').get(id=feedcomp_id) + serializer = StudentComplainSerializer(detail) + return Response(serializer.data) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) + +# Converted to DRF APIView +class ResolvePendingView(APIView): + permission_classes = [IsAuthenticated] + + def post(self, request, cid): + """ + Allows the caretaker to resolve a pending complaint. + """ + serializer = ResolvePendingSerializer(data=request.data) + print("Incoming data:", request.data) + if serializer.is_valid(): + newstatus = serializer.validated_data['yesorno'] + comment = serializer.validated_data.get('comment', '') + intstatus = 2 if newstatus == 'Yes' else 3 + StudentComplain.objects.filter(id=cid).update(status=intstatus, comment=comment) + + # Send notification to the complainer + try: + complainer_details = StudentComplain.objects.select_related('complainer').get(id=cid) + student = 0 + if newstatus == 'Yes': + message = "Congrats! Your complaint has been resolved" + notification_type = 'comp_resolved_alert' + else: + message = "Your complaint has been declined" + notification_type = 'comp_declined_alert' + + complaint_system_notif(request.user, complainer_details.complainer.user, notification_type, complainer_details.id, student, message) + return Response({'success': 'Complaint status updated'}) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - a = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').get(staff_id=y.id) - b = a.area - history = [] - - - complaint_assign_no = [] - user_details=User.objects.get(id=y.user_id) - - notification = Notification.objects.filter(recipient=current_user.id) - notification = notification.filter(data__exact={'url':'complaint:detail2','module':'Complaint System'}) - user_details=User.objects.get(id=y.user_id) - - - des=HoldsDesignation.objects.filter(user=user_details).all() - print("######") - print(user_details.username) - print(des[0].designation) - print("&&&&&") - outbox_files = view_outbox( - username=user_details.username, - designation=des[0].designation, - src_module="complaint" - ) + def get(self, request, cid): + """ + Returns the details of the complaint to be resolved. + """ + try: + complaint = StudentComplain.objects.select_related('complainer', 'complainer_user', 'complainer_department').get(id=cid) + serializer = StudentComplainSerializer(complaint) + return Response(serializer.data) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) - outbox=[] - comp_list=set() - for i in outbox_files: - # print(i) - outbox.append(i) - - for i in outbox: - file_history = view_history(file_id=i['id']) - print(i['id']) - print("********") - comp=File.objects.filter(id=i['id']) - print(comp[0].src_object_id) - print("------") - complaint=StudentComplain.objects.all().filter(id=comp[0].src_object_id) - print(complaint[0].complainer.user.username) - - print("......") - if complaint[0].complainer.user.username== user_details.username : - comp_list.add(complaint) - - # break - complaint_final_list=[] - for i in comp_list: - complaint_final_list.append(i[0]) - - sorted_history_out = sorted(complaint_final_list, key=attrgetter('complaint_date'), reverse=True) +# Converted to DRF APIView +class ComplaintDetailView(APIView): + permission_classes = [IsAuthenticated] - inbox_files = view_inbox( - username=user_details.username, - designation=des[0].designation, - src_module="complaint" - ) - print(inbox_files) - - inbox=[] - comp_list_in=set() - for i in inbox_files: - # print(i) - inbox.append(i) - file_history_list=[] - for i in inbox: - file_history = view_history(file_id=i['id']) - print(i['id']) - comp=File.objects.filter(id=i['id']) - print(comp[0].src_object_id) - complaint=StudentComplain.objects.all().filter(id=comp[0].src_object_id) - print(complaint) - comp_list_in.add(complaint) - - complaint_final_list_in=[] - for i in comp_list_in: - complaint_final_list_in.append(i[0]) - - # print(complaint_final_list_in) - sorted_history = sorted(complaint_final_list_in, key=attrgetter('complaint_date'), reverse=True) - - return render(request, "complaintModule/complaint_caretaker.html", - { 'history': sorted_history, - 'comp_id': y.id, - 'carehistory':sorted_history_out, - 'notification':notification, - 'care_id': a}) - -@login_required -def remove_worker_from_complaint(request,complaint_id): - """ - The function is used by secincharge to remove a worker - already assigned to a complaint - @param: - request - trivial - complaint_id - used to get complaint_id registered - """ - complaint = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(complaint_id=complaint_id).update(worker_id='') - return HttpResponseRedirect('/complaint/caretaker/') - - - - -@login_required -def changestatus(request, complaint_id, status): - """ - The function is used by caretaker to change the status of a complaint. - @param: - request - trivial. - complaint_id - used to get complaint_id registered. - status-used to get the current status of complaints - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - if status == '3': - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=complaint_id).\ - update(status=status, worker_id='') - return HttpResponseRedirect('/complaint/caretaker/') - elif status == '2': - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=complaint_id).\ - update(status=status, worker_id='') - return HttpResponseRedirect('/complaint/caretaker/') - else: - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=complaint_id).\ - update(status=status) - return HttpResponseRedirect('/complaint/caretaker/') - - - - -@login_required -def changestatussuper(request, complaint_id, status): - """ - The function is used by caretaker to change the status of a complaint. - @param: - request - trivial. - complaint_id - used to get complaint_id registered. - status-used to get the current status of complaints - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - if status == '3': - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(id=complaint_id).\ - update(status=status, worker_id='') - return HttpResponseRedirect('/complaint/supervisor/') - elif status == '2': - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(id=complaint_id).\ - update(status=status, worker_id='') - return HttpResponseRedirect('/complaint/supervisor/') - else: - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(id=complaint_id).\ - update(status=status) - return HttpResponseRedirect('/complaint/supervisor/') - - -@login_required -def removew(request, work_id): - """ - The function is used by secincharge to remove workers. - @param: - request - trivial. - work_id - id of the issue object which the user intends to support/unsupport. - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - worker = Workers.objects.select_related('secincharge_id','secincharge_id__staff_id','secincharge_id__staff_id__user','secincharge_id__staff_id__department').get(id=work_id) - temp = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(worker_id=worker).count() - if temp == 0: - worker.delete() - return HttpResponseRedirect('/complaint/secincharge/') - else: - return HttpResponse('

Worker is assign some complaint

') - - - - - -@login_required -def submitfeedback(request, complaint_id): - """ - The function is used by the complainant to enter feedback after the complaint has been resolved - @param: - request - trivial. - complaint_id - id of the registerd complaint. - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - - if request.method == 'POST': - feedback = request.POST.get('feedback', '') - rating = request.POST.get('rating', '') - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=complaint_id).\ - update(feedback=feedback, flag=rating) - a = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=complaint_id).first() - care = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(area=a.location).first() - rate = care.rating - newrate = 0 - if rate == 0: - newrate = rating + def get(self, request, detailcomp_id1): + """ + Returns the details of a complaint for the caretaker. + """ + try: + complaint = StudentComplain.objects.select_related().get(id=detailcomp_id1) + serializer = StudentComplainSerializer(complaint) + print(serializer.data) + return Response(serializer.data) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) + +# Converted to DRF APIView +class SearchComplaintView(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request): + """ + Searches for complaints based on query parameters. + """ + # Implement search logic based on query parameters + # For now, return all complaints + complaints = StudentComplain.objects.all() + serializer = StudentComplainSerializer(complaints, many=True) + return Response(serializer.data) + +# Converted to DRF APIView +class SubmitFeedbackCaretakerView(APIView): + permission_classes = [IsAuthenticated] + + def post(self, request, complaint_id): + """ + Allows the caretaker to submit feedback for a complaint. + """ + serializer = FeedbackSerializer(data=request.data) + if serializer.is_valid(): + feedback = serializer.validated_data['feedback'] + rating = serializer.validated_data['rating'] + try: + rating = int(rating) + except ValueError: + return Response({'error': 'Invalid rating'}, status=status.HTTP_400_BAD_REQUEST) + StudentComplain.objects.filter(id=complaint_id).update(feedback=feedback, flag=rating) + + a = StudentComplain.objects.select_related('complainer', 'complainer_user', 'complainer_department').filter(id=complaint_id).first() + care = Caretaker.objects.filter(area=a.location).first() + rate = care.rating + newrate = int((rating + rate) / 2) if rate != 0 else rating + care.rating = newrate + care.save() + return Response({'success': 'Feedback submitted'}) else: - a1 = int(rating) - b1 = int(rate) - c1 = int((a1+b1)/2) - newrate = c1 + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(area=a.location).update(rating=newrate) - return HttpResponseRedirect('/complaint/user/') - - else: - a = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=complaint_id) - return render(request, "complaintModule/submit_feedback.html", {'a': a}) - - - - -#for SectionIncharge -@login_required -def deletecomplaint(request, comp_id1): - """ - function to delete complaint - """ - StudentComplain.objects.get(id=comp_id1).delete() - return HttpResponseRedirect('/complaint/secincharge/') - - - -def testEntry(): - list1 = [('eecivil','NR2'),('eecivil','Rewa_Residency'),('eecivil','LHTC'),('eecivil','core_lab')] - - # to delete supervisors - # all_ent = Supervisor.objects.all() - # for ent in all_ent: - # ent.delete() - - # adding all supervisors - for n in list1: - user = User.objects.all().get(username=n[0]) - ei_obj = ExtraInfo.objects.all().get(user =user) - print(ei_obj.user.username) - test = Supervisor(sup_id=ei_obj, area = n[1]) - test.save() - -@login_required -def supervisor(request): - """ - The function is used to display all registered complaints to the supervisor - @param: - request - trivial. - - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - # print("--------------------------") - # testEntry() - # print(request.type) - location = request.POST.get('Location', '') - current_user = get_object_or_404(User, username=request.user.username) - y = ExtraInfo.objects.all().select_related('user','department').filter(user=current_user).first() - comp_id = y.id - if request.method == 'POST' : + def get(self, request, complaint_id): + """ + Returns the complaint details for which feedback is to be submitted. + """ try: - y = ExtraInfo.objects.all().select_related('user','department').get(id=y.id) - a = Supervisor.objects.select_related('sup_id','sup_id__user','sup_id__department').get(sup_id=y) - except Exception as e: - a = None - y = None - all_caretaker = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(area=location).order_by('-id') - area = all_caretaker[0].area - # ExtraInfo.objects.get(id=sup_id) - all_complaint = [] - numtemp = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(location = area).filter(status = 0).count() - num = int(numtemp/2+0.5) - - - - - + complaint = StudentComplain.objects.select_related('complainer', 'complainer_user', 'complainer_department').get(id=complaint_id) + serializer = StudentComplainSerializer(complaint) + return Response(serializer.data) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) +# views.py + +# Import DRF classes +from rest_framework.views import APIView +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from rest_framework import status + +# Import necessary models and serializers +from .serializers import ( + StudentComplainSerializer, + CaretakerSerializer, + FeedbackSerializer, + ResolvePendingSerializer, +) +# Other imports remain the same +import datetime +from datetime import datetime, timedelta +from django.contrib import messages +from django.contrib.auth import authenticate, login +from django.shortcuts import get_object_or_404, render +from applications.globals.models import User, ExtraInfo, HoldsDesignation +from notifications.models import Notification +from .models import Caretaker, StudentComplain, Supervisor +from notification.views import complaint_system_notif +from applications.filetracking.sdk.methods import * +from applications.filetracking.models import * +from operator import attrgetter + +# Converted to DRF APIView +class SupervisorLodgeView(APIView): + permission_classes = [IsAuthenticated] + + def post(self, request): + """ + Allows the supervisor to lodge a new complaint. + """ + # Get the current user + a = request.user + y = ExtraInfo.objects.select_related('user', 'department').filter(user=a).first() + + data = request.data.copy() + data['complainer'] = y.id + data['status'] = 0 - comp_type = request.POST.get('complaint_type', '') - location = request.POST.get('Location', '') - specific_location = request.POST.get('specific_location', '') - comp_file = request.FILES.get('myfile') - - details = request.POST.get('details', '') - status = 0 - # finish time is according to complaint type + comp_type = data.get('complaint_type', '') + # Finish time is according to complaint type complaint_finish = datetime.now() + timedelta(days=2) if comp_type == 'Electricity': complaint_finish = datetime.now() + timedelta(days=2) @@ -1044,841 +508,408 @@ def supervisor(request): complaint_finish = datetime.now() + timedelta(days=4) elif comp_type == 'other': complaint_finish = datetime.now() + timedelta(days=3) - y = ExtraInfo.objects.all().select_related('user','department').get(id=comp_id) - #check if location given - if location!="": - # x = StudentComplain(complainer=y, - # complaint_type=comp_type, - # location=location, - # specific_location=specific_location, - # details=details, - # status=status, - # complaint_finish=complaint_finish, - # upload_complaint=comp_file) - - - # x.save() - obj1, created = StudentComplain.objects.get_or_create(complainer=y, - complaint_type=comp_type, - location=location, - specific_location=specific_location, - details=details, - status=status, - complaint_finish=complaint_finish, - upload_complaint=comp_file) - - - - if location == "hall-1": - dsgn ="hall1caretaker" - elif location =="hall-3": - dsgn ="hall3caretaker" - elif location =="hall-4": - dsgn ="hall4caretaker" - elif location =="CC1": - dsgn ="cc1convener" - elif location =="CC2": - dsgn ="CC2 convener" - elif location == "core_lab": - dsgn = "corelabcaretaker" - elif location =="LHTC": - dsgn ="lhtccaretaker" - elif location =="NR2": - dsgn ="nr2caretaker" - elif location =="Maa Saraswati Hostel": - dsgn ="mshcaretaker" - elif location =="Nagarjun Hostel": - dsgn ="nhcaretaker" - elif location =="Panini Hostel": - dsgn ="phcaretaker" + data['complaint_finish'] = complaint_finish.date() + + serializer = StudentComplainSerializer(data=data) + if serializer.is_valid(): + complaint = serializer.save() + + # Notification logic (if any) + location = data.get('location', '') + if location == "hall-1": + dsgn = "hall1caretaker" + elif location == "hall-3": + dsgn = "hall3caretaker" + elif location == "hall-4": + dsgn = "hall4caretaker" + elif location == "CC1": + dsgn = "cc1convener" + elif location == "CC2": + dsgn = "CC2 convener" + elif location == "core_lab": + dsgn = "corelabcaretaker" + elif location == "LHTC": + dsgn = "lhtccaretaker" + elif location == "NR2": + dsgn = "nr2caretaker" + elif location == "Maa Saraswati Hostel": + dsgn = "mshcaretaker" + elif location == "Nagarjun Hostel": + dsgn = "nhcaretaker" + elif location == "Panini Hostel": + dsgn = "phcaretaker" + else: + dsgn = "rewacaretaker" + caretaker_name = HoldsDesignation.objects.select_related('user', 'working', 'designation').get(designation__name=dsgn) + + # Send notification + student = 1 + message = "A New Complaint has been lodged" + complaint_system_notif(request.user, caretaker_name.user, 'lodge_comp_alert', complaint.id, student, message) + + return Response(serializer.data, status=status.HTTP_201_CREATED) else: - dsgn = "rewacaretaker" - caretaker_name = HoldsDesignation.objects.select_related('user','working','designation').get(designation__name = dsgn) - user_details=User.objects.get(id=y.user_id) - # c2=Supervisor.objects.all().filter(area=location) - print(caretaker_name.user.username) - print(user_details.username) - print(caretaker_name.designation) - - # sup = HoldsDesignation.objects.select_related('user','working','designation').get(user = y.id) - # print(sup.designation) - - user_details=User.objects.get(id=y.user_id) - des=HoldsDesignation.objects.filter(user=user_details).all() - + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def get(self, request): + """ + Returns the history of complaints lodged by the supervisor. + """ + a = request.user + y = ExtraInfo.objects.select_related('user', 'department').filter(user=a).first() + complaints = StudentComplain.objects.filter(complainer=y).order_by('-id') + serializer = StudentComplainSerializer(complaints, many=True) + return Response(serializer.data) + +# Converted to DRF APIView +class SupervisorView(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request): + """ + Returns the list of complaints assigned to the supervisor's area. + """ + current_user = request.user + y = ExtraInfo.objects.select_related('user', 'department').filter(user=current_user).first() + try: + supervisor = Supervisor.objects.select_related('sup_id').get(sup_id=y) + type = supervisor.type + complaints = StudentComplain.objects.filter(complaint_type=type, status=1).order_by('-id') + serializer = StudentComplainSerializer(complaints, many=True) + return Response(serializer.data) + except Supervisor.DoesNotExist: + return Response({'error': 'Supervisor does not exist'}, status=status.HTTP_404_NOT_FOUND) + +# Converted to DRF APIView +class FeedbackSuperView(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request, feedcomp_id): + """ + Returns the feedback details for a specific complaint for the supervisor. + """ + try: + complaint = StudentComplain.objects.select_related('complainer', 'complainer_user', 'complainer_department').get(id=feedcomp_id) + caretaker = Caretaker.objects.select_related('staff_id', 'staff_id_user', 'staff_id_department').filter(area=complaint.location).first() + complaint_data = StudentComplainSerializer(complaint).data + caretaker_data = CaretakerSerializer(caretaker).data if caretaker else None + return Response({'complaint': complaint_data, 'caretaker': caretaker_data}) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) - file_id = create_file(uploader=user_details.username, - uploader_designation=des[0].designation, - receiver=caretaker_name.user.username, - receiver_designation=str(caretaker_name.designation), - src_module="complaint", - src_object_id= str(obj1.id), - file_extra_JSON= {}, - attached_file = None) +# Converted to DRF APIView +class CaretakerIdKnowMoreView(APIView): + permission_classes = [IsAuthenticated] + def get(self, request, caretaker_id): + """ + Returns the details of a caretaker and the list of pending complaints in their area. + """ + try: + caretaker = Caretaker.objects.select_related('staff_id', 'staff_id_user', 'staff_id_department').get(id=caretaker_id) + area = caretaker.area + pending_complaints = StudentComplain.objects.filter(location=area, status=0) + caretaker_data = CaretakerSerializer(caretaker).data + complaints_data = StudentComplainSerializer(pending_complaints, many=True).data + return Response({'caretaker': caretaker_data, 'pending_complaints': complaints_data}) + except Caretaker.DoesNotExist: + return Response({'error': 'Caretaker not found'}, status=status.HTTP_404_NOT_FOUND) + +# Converted to DRF APIView +class SupervisorComplaintDetailView(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request, detailcomp_id1): + """ + Returns the details of a complaint for the supervisor, including caretaker info. + """ + try: + complaint = StudentComplain.objects.select_related('complainer', 'complainer_user', 'complainer_department').get(id=detailcomp_id1) + caretaker = Caretaker.objects.select_related('staff_id', 'staff_id_user', 'staff_id_department').filter(area=complaint.location).first() + complaint_data = StudentComplainSerializer(complaint).data + caretaker_data = CaretakerSerializer(caretaker).data if caretaker else None + return Response({'complaint': complaint_data, 'caretaker': caretaker_data}) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) + +# Converted to DRF APIView +class SupervisorResolvePendingView(APIView): + permission_classes = [IsAuthenticated] + + def post(self, request, cid): + """ + Allows the supervisor to resolve a pending complaint. + """ + serializer = ResolvePendingSerializer(data=request.data) + if serializer.is_valid(): + newstatus = serializer.validated_data['yesorno'] + comment = serializer.validated_data.get('comment', '') + intstatus = 2 if newstatus == 'Yes' else 3 + StudentComplain.objects.filter(id=cid).update(status=intstatus, comment=comment) + + # Send notification to the complainer + try: + complainer_details = StudentComplain.objects.select_related('complainer').get(id=cid) + student = 0 + message = "Congrats! Your complaint has been resolved" + complaint_system_notif(request.user, complainer_details.complainer.user, 'comp_resolved_alert', complainer_details.id, student, message) + return Response({'success': 'Complaint status updated'}) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - # This is to allow the student - student = 1 - message = "A New Complaint has been lodged" - complaint_system_notif(request.user, caretaker_name.user,'lodge_comp_alert',obj1.id,student,message) + def get(self, request, cid): + """ + Returns the details of the complaint to be resolved. + """ + try: + complaint = StudentComplain.objects.select_related('complainer').get(id=cid) + serializer = StudentComplainSerializer(complaint) + return Response(serializer.data) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) + +# Converted to DRF APIView +class SupervisorSubmitFeedbackView(APIView): + permission_classes = [IsAuthenticated] + + def post(self, request, complaint_id): + """ + Allows the supervisor to submit feedback for a complaint. + """ + serializer = FeedbackSerializer(data=request.data) + if serializer.is_valid(): + feedback = serializer.validated_data['feedback'] + rating = serializer.validated_data['rating'] + try: + rating = int(rating) + except ValueError: + return Response({'error': 'Invalid rating'}, status=status.HTTP_400_BAD_REQUEST) + StudentComplain.objects.filter(id=complaint_id).update(feedback=feedback, flag=rating) + + # Update caretaker's rating + try: + complaint = StudentComplain.objects.select_related('complainer', 'complainer_user', 'complainer_department').get(id=complaint_id) + care = Caretaker.objects.filter(area=complaint.location).first() + rate = care.rating + newrate = int((rating + rate) / 2) if rate != 0 else rating + care.rating = newrate + care.save() + return Response({'success': 'Feedback submitted'}) + except Caretaker.DoesNotExist: + return Response({'error': 'Caretaker not found'}, status=status.HTTP_404_NOT_FOUND) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - # return render(request, "complaintModule/complaint_user.html", - # {'history': history, 'comp_id': comp_id }) - # next = request.POST.get('next', '/') + def get(self, request, complaint_id): + """ + Returns the complaint details for which feedback is to be submitted. + """ + try: + complaint = StudentComplain.objects.select_related('complainer', 'complainer_user', 'complainer_department').get(id=complaint_id) + serializer = StudentComplainSerializer(complaint) + return Response(serializer.data) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) +# views.py - messages.success(request,message) - # return HttpResponseRedirect('/complaint/user') - - return HttpResponseRedirect('/complaint/supervisor') +# Import DRF classes +from rest_framework.views import APIView +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from rest_framework import status - else: - - - all_caretaker = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').order_by('-id') - area = all_caretaker[0].area - - numtemp = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(location = area).filter(status = 0).count() - num = int(numtemp/2+0.5) - all_complaint = [] - user_details=User.objects.get(id=y.user_id) - +# Import necessary models and serializers +from .models import Caretaker, StudentComplain, Supervisor, Workers, SectionIncharge +from .serializers import StudentComplainSerializer, WorkersSerializer # Added WorkersSerializer +from applications.globals.models import User, ExtraInfo, HoldsDesignation - +# Converted 'removew' function to DRF APIView 'RemoveWorkerView' +class RemoveWorkerView(APIView): + permission_classes = [IsAuthenticated] - - current_user = get_object_or_404(User, username=request.user.username) - y = ExtraInfo.objects.all().select_related('user','department').filter(user=current_user).first() - user_details=User.objects.get(id=y.user_id) - des=HoldsDesignation.objects.filter(user=user_details).all() - # print(y.user_id) - # print(user_details.username) - # print(des[0].user) - outbox_files = view_outbox( - username=user_details.username, - designation=des[0].designation, - src_module="complaint" - ) + def post(self, request, work_id): + """ + Allows the caretaker to remove a worker if not assigned to any complaints. + """ + try: + worker = Workers.objects.get(id=work_id) + assigned_complaints = StudentComplain.objects.filter(worker_id=worker).count() + if assigned_complaints == 0: + worker.delete() + return Response({'success': 'Worker removed successfully'}, status=status.HTTP_200_OK) + else: + return Response({'error': 'Worker is assigned to some complaints'}, status=status.HTTP_400_BAD_REQUEST) + except Workers.DoesNotExist: + return Response({'error': 'Worker not found'}, status=status.HTTP_404_NOT_FOUND) + + # Optionally, accept DELETE method + def delete(self, request, work_id): + return self.post(request, work_id) + +# Converted 'assign_worker' function to DRF APIView 'AssignWorkerView' +class ForwardCompaintView(APIView): + permission_classes = [IsAuthenticated] + + def post(self, request, comp_id1): + """ + Assigns a complaint to a supervisor. + """ + current_user = request.user + y = ExtraInfo.objects.filter(user=current_user).first() + complaint_id = comp_id1 - outbox=[] - comp_list=set() - for i in outbox_files: - # print(i) - outbox.append(i) - - for i in outbox: - file_history = view_history(file_id=i['id']) - print(i['id']) - comp=File.objects.filter(id=i['id']) - print(comp[0].src_object_id) - complaint=StudentComplain.objects.all().filter(id=comp[0].src_object_id) - print(complaint) - comp_list.add(complaint) - # file_history = view_history(file_id=i['id']) - - # comp=File.objects.filter(uploader=file_history[0]['current_id']) - # for j in comp: - # c=StudentComplain.objects.all().filter(id=j.src_object_id) - # comp_list.add(c) - # print(c[0]) - - # break - complaint_final_list=[] - for i in comp_list: - complaint_final_list.append(i[0]) - sorted_history_out = sorted(complaint_final_list, key=attrgetter('complaint_date'), reverse=True) - - inbox_files = view_inbox( - username=user_details.username, - designation=des[0].designation, - src_module="complaint" + try: + complaint = StudentComplain.objects.get(id=complaint_id) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) + + complaint_type = complaint.complaint_type + + supervisors = Supervisor.objects.filter(type=complaint_type) + if not supervisors.exists(): + return Response({'error': 'Supervisor does not exist for this complaint type'}, status=status.HTTP_404_NOT_FOUND) + + supervisor = supervisors.first() + supervisor_details = ExtraInfo.objects.get(id=supervisor.sup_id.id) + + # Update complaint status + complaint.status = 1 + complaint.save() + + # Forward file to supervisor + sup_designations = HoldsDesignation.objects.filter(user=supervisor_details.user_id) + + files = File.objects.filter(src_object_id=complaint_id) + + if not files.exists(): + return Response({'error': 'No files associated with this complaint'}, status=status.HTTP_206_PARTIAL_CONTENT) + + supervisor_username = User.objects.get(id=supervisor_details.user_id).username + + file = forward_file( + file_id=files.first().id, + receiver=supervisor_username, + receiver_designation=sup_designations.first().designation, + file_extra_JSON={}, + remarks="", + file_attachment=None ) - inbox=[] - comp_list_in=set() - for i in inbox_files: - inbox.append(i) - # print(inbox[0]['id']) - - for i in inbox: - file_history = view_history(file_id=i['id']) - print(i['id']) - comp=File.objects.filter(id=i['id']) - print(comp[0].src_object_id) - complaint=StudentComplain.objects.all().filter(id=comp[0].src_object_id) - print(complaint) - comp_list_in.add(complaint) - # print(complaint[0]) - # for j in comp: - # c=StudentComplain.objects.all().filter(id=j.src_object_id) - # comp_list_in.add(c) - # print(c[0]) - - # break - complaint_final_list_in=[] - for i in comp_list_in: - complaint_final_list_in.append(i[0]) - - sorted_history = sorted(complaint_final_list_in, key=attrgetter('complaint_date'), reverse=True) - print(complaint_final_list_in) - return render(request, "complaintModule/supervisor1.html", - - {'history':sorted_history,'all_caretaker': all_caretaker, 'all_complaint': all_complaint,'outbox':sorted_history_out}) - -@login_required -def caretaker_id_know_more(request,caretaker_id): - this_caretaker = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').get(id = caretaker_id) - this_caretaker_area = this_caretaker.area - list_pending_complaints = [] - list_pending_complaintstemp = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(location = this_caretaker_area).filter(status = 0) - j = 1 - for i in list_pending_complaintstemp: - list_pending_complaints.append(i) - - num = len(list_pending_complaints) - return render(request, "complaintModule/caretaker_id_know_more.html",{'this_caretaker':this_caretaker , 'list_pending_complaints':list_pending_complaints, 'num':num}) + return Response({'success': 'Complaint assigned to supervisor'}, status=status.HTTP_200_OK) + def get(self, request, comp_id1): + """ + Retrieves complaint details. + """ + try: + complaint = StudentComplain.objects.get(id=comp_id1) + serializer = StudentComplainSerializer(complaint) + return Response(serializer.data, status=status.HTTP_200_OK) + except StudentComplain.DoesNotExist: + return Response({'error': 'Not a valid complaint'}, status=status.HTTP_404_NOT_FOUND) -def search_complaint(request): - return HttpResponseRedirect('/login/') +# Converted 'deletecomplaint' function to DRF APIView 'DeleteComplaintView' +class DeleteComplaintView(APIView): + permission_classes = [IsAuthenticated] -@login_required -def resolvepending(request, cid): - a = get_object_or_404(User, username=request.user.username) - y = ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() - thiscomplaint = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=cid) - if request.method == 'POST': - newstatus = request.POST.get('yesorno','') - comment = request.POST.get('comment') - intstatus = 0 - if newstatus == 'Yes': - intstatus = 2 - else: - intstatus = 3 - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=cid).\ - update(status=intstatus) - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=cid).\ - update(comment=comment) - complainer_details = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=cid) - student=0 - message = "Congrats! Your complaint has been resolved" - complaint_system_notif(request.user, complainer_details.complainer.user ,'comp_resolved_alert',complainer_details.id,student,message) - return HttpResponseRedirect("/complaint/caretaker/") - else: - # complainer_details = StudentComplain.objects.get(id=cid) - # complaint_system_notif(request.user, complainer_details.complainer.user ,'comp_resolved_alert') - return render(request,"complaintModule/resolve_pending.html",{"a" : a,"thiscomplaint" : thiscomplaint}) - - - - -@login_required -def resolvependingsuper(request, cid): - a = get_object_or_404(User, username=request.user.username) - y = ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() - thiscomplaint = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').get(id=cid) - if request.method == 'POST': - newstatus = request.POST.get('yesorno','') - comment = request.POST.get('comment') - intstatus = 0 - if newstatus == 'Yes': - intstatus = 2 - else: - intstatus = 3 - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(id=cid).\ - update(status=intstatus) - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(id=cid).\ - update(comment=comment) - complainer_details = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').get(id=cid) - student=0 - message = "Congrats! Your complaint has been resolved" - complaint_system_notif(request.user, complainer_details.complainer.user ,'comp_resolved_alert',complainer_details.id,student,message) - return HttpResponseRedirect("/complaint/supervisor/") - else: - # complainer_details = StudentComplain.objects.get(id=cid) - # complaint_system_notif(request.user, complainer_details.complainer.user ,'comp_resolved_alert') - return render(request,"complaintModule/resolve_pending.html",{"a" : a,"thiscomplaint" : thiscomplaint}) - - - - -@login_required -def resolvependingsuper(request, cid): - a = get_object_or_404(User, username=request.user.username) - y = ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() - thiscomplaint = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=cid) - if request.method == 'POST': - newstatus = request.POST.get('yesorno','') - comment = request.POST.get('comment') - intstatus = 0 - if newstatus == 'Yes': - intstatus = 2 - else: - intstatus = 3 - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=cid).\ - update(status=intstatus) - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=cid).\ - update(comment=comment) - complainer_details = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=cid) - student=0 - message = "Congrats! Your complaint has been resolved" - complaint_system_notif(request.user, complainer_details.complainer.user ,'comp_resolved_alert',complainer_details.id,student,message) - return HttpResponseRedirect("/complaint/supervisor/") - else: - # complainer_details = StudentComplain.objects.get(id=cid) - # complaint_system_notif(request.user, complainer_details.complainer.user ,'comp_resolved_alert') - return render(request,"complaintModule/resolve_pending.html",{"a" : a,"thiscomplaint" : thiscomplaint}) - - - - -def login1(request): - if request.method == 'POST': - u = request.POST.get('username', '') - p = request.POST.get('password', '') - user = authenticate(username=u, password=p) - if user is not None: - if user.is_active: - login(request, user) - a = User.objects.get(username=u) - b = ExtraInfo.objects.all().select_related('user','department').get(user=a) - return HttpResponseRedirect('/complaint/') - else: - return HttpResponse("

wrong user credentials

") - else: - return HttpResponseRedirect('/login/') - -@login_required -def feedback_super(request, feedcomp_id): - detail3 = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=feedcomp_id) - a=User.objects.get(username=detail3.complainer.user.username) - y=ExtraInfo.objects.all().select_related('user','department').get(user=a) - temp=StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(complainer=y).first() - comp_id=temp.id - loc = detail3.location - care = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(area=loc).first() - return render(request, "complaintModule/feedback_super.html", {"detail3": detail3,"comp_id":comp_id,"care":care}) - - -@login_required -def feedback_care(request, feedcomp_id): - detail2 = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=feedcomp_id) - a=User.objects.get(username=detail2.complainer.user.username) - y=ExtraInfo.objects.all().select_related('user','department').get(user=a) - temp=StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(complainer=y).first() - comp_id=temp.id - return render(request, "complaintModule/feedback_care.html", {"detail2": detail2,"comp_id":comp_id}) - - -#for complainaint and caretaker -@login_required -def detail(request, detailcomp_id1): - """ - function that shows detail about complaint - """ - detail = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=detailcomp_id1) - if(detail.worker_id is None): - worker_name = None - worker_id = detail.worker_id - else: - worker_id = detail.worker_id.id - worker = Workers.objects.select_related('secincharge_id','secincharge_id__staff_id','secincharge_id__staff_id__user','secincharge_id__staff_id__department').get(id=worker_id) - worker_name = worker.name - a=User.objects.get(username=detail.complainer.user.username) - y=ExtraInfo.objects.all().select_related('user','department').get(user=a) - num=0 - if detail.upload_complaint != "": - num = 1 - temp=StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(complainer=y).first() - comp_id=temp.id - return render(request, "complaintModule/complaint_user_detail.html", {"detail": detail, "comp_id":detail.id,"num":num,"worker_name":worker_name}) - - - -#for SectionIncharge -@login_required -def detail2(request, detailcomp_id1): - detail2 = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=detailcomp_id1) - if(detail2.worker_id is None): - worker_name = None - worker_id = detail2.worker_id - else: - worker_id = detail2.worker_id.id - worker = Workers.objects.select_related('secincharge_id','secincharge_id__staff_id','secincharge_id__staff_id__user','secincharge_id__staff_id__department').get(id=worker_id) - worker_name = worker.name - a=User.objects.get(username=detail2.complainer.user.username) - y=ExtraInfo.objects.all().select_related('user','department').get(user=a) - num=0 - - if detail2.upload_complaint != "": - num = 1 - temp=StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(complainer=y).first() - comp_id=temp.id - return render(request, "complaintModule/complaint_secincharge_detail.html", {"detail2": detail2, "comp_id":detail2.id,"num":num,"worker_name":worker_name,"wid":worker_id}) - - -@login_required -def detail3(request, detailcomp_id1): - detail3 = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=detailcomp_id1) - a=User.objects.get(username=detail3.complainer.user.username) - y=ExtraInfo.objects.all().select_related('user','department').get(user=a) - num=0 - if detail3.upload_complaint != "": - num = 1 - temp=StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(complainer=y).first() - comp_id=temp.id - loc = detail3.location - care = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(area=loc).first() - return render(request, "complaintModule/complaint_supervisor_detail.html", {"detail3": detail3,"comp_id":comp_id,"care":care,"num":num}) - - - - -@login_required - -def supervisorlodge(request): - """ - The function is used to register a complaint - @param: - request - trivial. - - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - 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': - comp_type = request.POST.get('complaint_type', '') - location = request.POST.get('Location', '') - specific_location = request.POST.get('specific_location', '') - comp_file = request.FILES.get('myfile') - - details = request.POST.get('details', '') - status = 0 - # finish time is according to complaint type - complaint_finish = datetime.now() + timedelta(days=2) - if comp_type == 'Electricity': - complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'carpenter': - complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'plumber': - complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'garbage': - complaint_finish = datetime.now() + timedelta(days=1) - elif comp_type == 'dustbin': - complaint_finish = datetime.now() + timedelta(days=1) - elif comp_type == 'internet': - complaint_finish = datetime.now() + timedelta(days=4) - elif comp_type == 'other': - complaint_finish = datetime.now() + timedelta(days=3) - y = ExtraInfo.objects.all().select_related('user','department').get(id=comp_id) - #check if location given - if location!="": - # x = StudentComplain(complainer=y, - # complaint_type=comp_type, - # location=location, - # specific_location=specific_location, - # details=details, - # status=status, - # complaint_finish=complaint_finish, - # upload_complaint=comp_file) - - - # x.save() - obj1, created = StudentComplain.objects.get_or_create(complainer=y, - complaint_type=comp_type, - location=location, - specific_location=specific_location, - details=details, - status=status, - complaint_finish=complaint_finish, - upload_complaint=comp_file) - - - historytemp = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(complainer=y).order_by('-id') - history = [] - j = 1 - k = 1 - for i in historytemp: - history.append(i) - # if j%2 != 0: - # history.append(i) - # j = j+1 - - - for h in history: - h.serial_no = k - k = k+1 - # if location == "hall1": - # dsgn = "hall1caretaker" - # elif location == "hall3": - # dsgn = "hall3caretaker" - # else : - # dsgn = "hall4caretaker" - if location == "hall-1": - dsgn ="hall1caretaker" - elif location =="hall-3": - dsgn ="hall3caretaker" - elif location =="hall-4": - dsgn ="hall4caretaker" - elif location =="CC1": - dsgn ="cc1convener" - elif location =="CC2": - dsgn ="CC2 convener" - elif location == "core_lab": - dsgn = "corelabcaretaker" - elif location =="LHTC": - dsgn ="lhtccaretaker" - elif location =="NR2": - dsgn ="nr2caretaker" - elif location =="Maa Saraswati Hostel": - dsgn ="mshcaretaker" - elif location =="Nagarjun Hostel": - dsgn ="nhcaretaker" - elif location =="Panini Hostel": - dsgn ="phcaretaker" - else: - dsgn = "rewacaretaker" - caretaker_name = HoldsDesignation.objects.select_related('user','working','designation').get(designation__name = dsgn) - - - # This is to allow the student - student = 1 - message = "A New Complaint has been lodged" - complaint_system_notif(request.user, caretaker_name.user,'lodge_comp_alert',obj1.id,student,message) - - # return render(request, "complaintModule/complaint_user.html", - # {'history': history, 'comp_id': comp_id }) - # next = request.POST.get('next', '/') - - messages.success(request,message) - return HttpResponseRedirect('/complaint/supervisor') - - else: - a = get_object_or_404(User, username=request.user.username) - y = ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() - historytemp = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(complainer=y).order_by('-id') - history=[] - - notification = Notification.objects.filter(recipient=a.id) - notification = notification.filter(data__exact={'url':'complaint:detail','module':'Complaint System'}) - # notification_message = [] - # for notification in x: - # to = User.objects.get(id=notification.actor_object_id).username - # from django.utils.timesince import timesince as timesince_ - # duration = timesince_(notification.timestamp,None) - # notification_message.append(notification.verb+' by '+ to + ' ' + duration + ' ago ') - + def post(self, request, comp_id1): + """ + Deletes a complaint. + """ + try: + complaint = StudentComplain.objects.get(id=comp_id1) + complaint.delete() + return Response({'success': 'Complaint deleted successfully'}, status=status.HTTP_200_OK) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) + def delete(self, request, comp_id1): + return self.post(request, comp_id1) +# Converted 'changestatus' function to DRF APIView 'ChangeStatusView' +class ChangeStatusView(APIView): + permission_classes = [IsAuthenticated] - j = 1 - for i in historytemp: - history.append(i) - # if j%2 != 0: - # history.append(i) - # j = j+1 - - for i in history: - i.serial_no = j - j = j+1 - - # if location == "hall-1": - # dsgn ="hall1caretaker" - # elif location =="hall-3": - # dsgn ="hall3caretaker" - # elif location =="hall-4": - # dsgn ="hall4caretaker" - # elif location =="CC1": - # dsgn ="CC convenor" - # elif location =="CC2": - # dsgn ="CC2 convener" - # elif location == "core_lab": - # dsgn = "corelabcaretaker" - # elif location =="LHTC": - # dsgn ="lhtccaretaker" - # elif location =="NR2": - # dsgn ="nr2caretaker" - # else: - # dsgn = "rewacaretaker" - # caretaker_name = HoldsDesignation.objects.get(designation__name = dsgn) - - # complaint_system_notif(request.user, caretaker_name.user,'lodge_comp_alert') - return render(request, "complaintModule/supervisor1.html", - {'history': history,'notification':notification, 'comp_id': y.id}) - - return render(request, "complaintModule/complaint_user.html", - {'history': history, 'comp_id': comp_id }) - - - - -@login_required -def submitfeedbacksuper(request, complaint_id): - """ - The function is used by the complainant to enter feedback after the complaint has been resolved - @param: - request - trivial. - complaint_id - id of the registerd complaint. - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - - if request.method == 'POST': - feedback = request.POST.get('feedback', '') - rating = request.POST.get('rating', '') - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=complaint_id).\ - update(feedback=feedback, flag=rating) - a = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=complaint_id).first() - care = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(area=a.location).first() - rate = care.rating - newrate = 0 - if rate == 0: - newrate = rating - else: - a1 = int(rating) - b1 = int(rate) - c1 = int((a1+b1)/2) - newrate = c1 - - Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(area=a.location).update(rating=newrate) - return HttpResponseRedirect('/complaint/supervisor/') - return render(request,"complaintModule/feedback.html",{'a' : a}) - - else: - a = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=complaint_id) - return render(request, "complaintModule/submit_feedback.html", {'a': a}) - - - -@login_required - -def caretakerlodge(request): - """ - The function is used to register a complaint - @param: - request - trivial. - - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - 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': - comp_type = request.POST.get('complaint_type', '') - location = request.POST.get('Location', '') - specific_location = request.POST.get('specific_location', '') - comp_file = request.FILES.get('myfile') - - details = request.POST.get('details', '') - status = 0 - # finish time is according to complaint type - complaint_finish = datetime.now() + timedelta(days=2) - if comp_type == 'Electricity': - complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'carpenter': - complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'plumber': - complaint_finish = datetime.now() + timedelta(days=2) - elif comp_type == 'garbage': - complaint_finish = datetime.now() + timedelta(days=1) - elif comp_type == 'dustbin': - complaint_finish = datetime.now() + timedelta(days=1) - elif comp_type == 'internet': - complaint_finish = datetime.now() + timedelta(days=4) - elif comp_type == 'other': - complaint_finish = datetime.now() + timedelta(days=3) - y = ExtraInfo.objects.all().select_related('user','department').get(id=comp_id) - #check if location given - if location!="": - # x = StudentComplain(complainer=y, - # complaint_type=comp_type, - # location=location, - # specific_location=specific_location, - # details=details, - # status=status, - # complaint_finish=complaint_finish, - # upload_complaint=comp_file) - - - # x.save() - obj1, created = StudentComplain.objects.get_or_create(complainer=y, - complaint_type=comp_type, - location=location, - specific_location=specific_location, - details=details, - status=status, - complaint_finish=complaint_finish, - upload_complaint=comp_file) - - - historytemp = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(complainer=y).order_by('-id') - history = [] - j = 1 - k = 1 - for i in historytemp: - history.append(i) - # if j%2 != 0: - # history.append(i) - # j = j+1 - - - for h in history: - h.serial_no = k - k = k+1 - # if location == "hall1": - # dsgn = "hall1caretaker" - # elif location == "hall3": - # dsgn = "hall3caretaker" - # else : - # dsgn = "hall4caretaker" - if location == "hall-1": - dsgn ="hall1caretaker" - elif location =="hall-3": - dsgn ="hall3caretaker" - elif location =="hall-4": - dsgn ="hall4caretaker" - elif location =="CC1": - dsgn ="cc1convener" - elif location =="CC2": - dsgn ="CC2 convener" - elif location == "core_lab": - dsgn = "corelabcaretaker" - elif location =="LHTC": - dsgn ="lhtccaretaker" - elif location =="NR2": - dsgn ="nr2caretaker" - elif location =="Maa Saraswati Hostel": - dsgn ="mshcaretaker" - elif location =="Nagarjun Hostel": - dsgn ="nhcaretaker" - elif location =="Panini Hostel": - dsgn ="phcaretaker" - else: - dsgn = "rewacaretaker" - caretaker_name = HoldsDesignation.objects.select_related('user','working','designation').get(designation__name = dsgn) - - - # This is to allow the student - student = 1 - message = "A New Complaint has been lodged" - complaint_system_notif(request.user, caretaker_name.user,'lodge_comp_alert',obj1.id,student,message) - - # return render(request, "complaintModule/complaint_user.html", - # {'history': history, 'comp_id': comp_id }) - # next = request.POST.get('next', '/') - - messages.success(request,message) - return HttpResponseRedirect('/complaint/caretaker') - - else: - a = get_object_or_404(User, username=request.user.username) - y = ExtraInfo.objects.all().select_related('user','department').filter(user=a).first() - historytemp = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department','worker_id','worker_id__caretaker_id__staff_id','worker_id__caretaker_id__staff_id__user','worker_id__caretaker_id__staff_id__department').filter(complainer=y).order_by('-id') - history=[] - - notification = Notification.objects.filter(recipient=a.id) - notification = notification.filter(data__exact={'url':'complaint:detail','module':'Complaint System'}) - # notification_message = [] - # for notification in x: - # to = User.objects.get(id=notification.actor_object_id).username - # from django.utils.timesince import timesince as timesince_ - # duration = timesince_(notification.timestamp,None) - # notification_message.append(notification.verb+' by '+ to + ' ' + duration + ' ago ') + def post(self, request, complaint_id, status): + """ + Allows the caretaker to change the status of a complaint. + """ + try: + complaint = StudentComplain.objects.get(id=complaint_id) + if status == '3' or status == '2': + complaint.status = status + complaint.worker_id = None + else: + complaint.status = status + complaint.save() + return Response({'success': 'Complaint status updated'}, status=status.HTTP_200_OK) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) + +# Converted 'changestatussuper' function to DRF APIView 'ChangeStatusSuperView' +class ChangeStatusSuperView(APIView): + permission_classes = [IsAuthenticated] + + def post(self, request, complaint_id, status): + """ + Allows the supervisor to change the status of a complaint. + """ + try: + complaint = StudentComplain.objects.get(id=complaint_id) + if status == '3' or status == '2': + complaint.status = status + complaint.worker_id = None + else: + complaint.status = status + complaint.save() + return Response({'success': 'Complaint status updated'}, status=status.HTTP_200_OK) + except StudentComplain.DoesNotExist: + return Response({'error': 'Complaint not found'}, status=status.HTTP_404_NOT_FOUND) +class GenerateReportView(APIView): + permission_classes = [IsAuthenticated] + def get(self, request): + """ + Generates a report of complaints for the caretaker's area, warden's area, or supervisor's type. + """ + user = request.user + is_caretaker = hasattr(user, 'caretaker') + is_supervisor = False + is_warden = hasattr(user, 'warden') - j = 1 - for i in historytemp: - history.append(i) - # if j%2 != 0: - # history.append(i) - # j = j+1 - - for i in history: - i.serial_no = j - j = j+1 - - # if location == "hall-1": - # dsgn ="hall1caretaker" - # elif location =="hall-3": - # dsgn ="hall3caretaker" - # elif location =="hall-4": - # dsgn ="hall4caretaker" - # elif location =="CC1": - # dsgn ="CC convenor" - # elif location =="CC2": - # dsgn ="CC2 convener" - # elif location == "core_lab": - # dsgn = "corelabcaretaker" - # elif location =="LHTC": - # dsgn ="lhtccaretaker" - # elif location =="NR2": - # dsgn ="nr2caretaker" - # else: - # dsgn = "rewacaretaker" - # caretaker_name = HoldsDesignation.objects.get(designation__name = dsgn) - - # complaint_system_notif(request.user, caretaker_name.user,'lodge_comp_alert') - return render(request, "complaintModule/complaint_caretaker.html", - {'history': history,'notification':notification, 'comp_id': y.id}) - - return render(request, "complaintModule/complaint_user.html", - {'history': history, 'comp_id': comp_id }) - - -@login_required -def submitfeedbackcaretaker(request, complaint_id): - """ - The function is used by the complainant to enter feedback after the complaint has been resolved - @param: - request - trivial. - complaint_id - id of the registerd complaint. - - @variables: - issue - The issue object. - supported - True if the user's intention is to support the issue. - support_count - Total supporters of the above issue. - context - Holds data needed to make necessary changes in the template. - """ - - if request.method == 'POST': - feedback = request.POST.get('feedback', '') - rating = request.POST.get('rating', '') - StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=complaint_id).\ - update(feedback=feedback, flag=rating) - a = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').filter(id=complaint_id).first() - care = Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(area=a.location).first() - rate = care.rating - newrate = 0 - if rate == 0: - newrate = rating - else: - a1 = int(rating) - b1 = int(rate) - c1 = int((a1+b1)/2) - newrate = c1 - - Caretaker.objects.select_related('staff_id','staff_id__user','staff_id__department').filter(area=a.location).update(rating=newrate) - return HttpResponseRedirect('/complaint/caretaker/') - return render(request,"complaintModule/feedback.html",{'a' : a}) - - else: - a = StudentComplain.objects.select_related('complainer','complainer__user','complainer__department').get(id=complaint_id) - return render(request, "complaintModule/submit_feedback.html", {'a': a}) \ No newline at end of file + # Check if user is a supervisor + try: + supervisor = Supervisor.objects.get(sup_id=user.extrainfo) + is_supervisor = True + except Supervisor.DoesNotExist: + is_supervisor = False + + if not is_caretaker and not is_supervisor and not is_warden: + return Response({"detail": "Not authorized to generate report."}, status=403) + + complaints = None + + # Generate report for supervisor + if is_supervisor: + print(f"Generating report for Supervisor {supervisor}") + complaints = StudentComplain.objects.filter(complaint_type=supervisor.type) + + # Generate report for caretaker + if is_caretaker and not is_supervisor: + caretaker = get_object_or_404(Caretaker, staff_id=user.extrainfo) + complaints = StudentComplain.objects.filter(location=caretaker.area) + + # if is_warden: + # warden = get_object_or_404(Warden, staff_id=user.extrainfo) + # if complaints: + # complaints = complaints.filter(location=warden.area) + # else: + # complaints = StudentComplain.objects.filter(location=warden.area) + + # Serialize and return the complaints + serializer = StudentComplainSerializer(complaints, many=True) + return Response(serializer.data) diff --git a/FusionIIIT/applications/counselling_cell/migrations/0001_initial.py b/FusionIIIT/applications/counselling_cell/migrations/0001_initial.py index f0214910c..7cd42f1b2 100644 --- a/FusionIIIT/applications/counselling_cell/migrations/0001_initial.py +++ b/FusionIIIT/applications/counselling_cell/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-07-16 15:44 import datetime from django.db import migrations, models @@ -10,8 +10,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('globals', '0001_initial'), ('academic_information', '0001_initial'), + ('globals', '0001_initial'), ] operations = [ diff --git a/FusionIIIT/applications/department/api/permissions.py b/FusionIIIT/applications/department/api/permissions.py new file mode 100644 index 000000000..2b870575b --- /dev/null +++ b/FusionIIIT/applications/department/api/permissions.py @@ -0,0 +1,18 @@ +from rest_framework import permissions +from django.shortcuts import get_object_or_404 +from applications.academic_information.models import ExtraInfo +from applications.globals.models import User + + +class IsFacultyStaffOrReadOnly(permissions.BasePermission): + """ + Custom permission to only allow faculty and staff to edit it. + """ + + def has_permission(self, request, view): + # Read permissions are allowed to any request, + # so we'll always allow GET, HEAD or OPTIONS requests. + if request.method in permissions.SAFE_METHODS: + return True + #only faculty and staff are able to make post request + return not request.user.holds_designations.filter(designation__name='student').exists() diff --git a/FusionIIIT/applications/department/api/serializers.py b/FusionIIIT/applications/department/api/serializers.py new file mode 100644 index 000000000..0dad5fe3f --- /dev/null +++ b/FusionIIIT/applications/department/api/serializers.py @@ -0,0 +1,80 @@ +from rest_framework import serializers +from applications.department.models import Announcements +from applications.academic_information.models import Spi, Student +from applications.globals.models import (Designation, ExtraInfo, + HoldsDesignation,Faculty) +from applications.eis.models import (faculty_about, emp_research_projects) +from applications.department.models import Information +from applications.department.models import Lab +from applications.department.models import Feedback +class AnnouncementSerializer(serializers.ModelSerializer): + class Meta: + model = Announcements + fields = ('__all__') + + extra_kwargs = { + 'maker_id': {'required': False} + } + + def create(self, validated_data): + user = self.context['request'].user + user_info = ExtraInfo.objects.all().select_related('user','department').filter(user=user).first() + validated_data['maker_id'] = user_info + return Announcements.objects.create(**validated_data) + +class ExtraInfoSerializer(serializers.ModelSerializer): + class Meta: + model = ExtraInfo + fields = ('__all__') + +class SpiSerializer(serializers.ModelSerializer): + class Meta: + model = Spi + fields = ('__all__') + +class StudentSerializer(serializers.ModelSerializer): + class Meta: + model = Student + fields = ('__all__') + +class DesignationSerializer(serializers.ModelSerializer): + class Meta: + model = Designation + fields = ('__all__') + +class HoldsDesignationSerializer(serializers.ModelSerializer): + class Meta: + model = HoldsDesignation + fields = ('__all__') + +class FacultySerializer(serializers.ModelSerializer): + class Meta: + model = Faculty + fields = ('__all__') + +class faculty_aboutSerializer(serializers.ModelSerializer): + class Meta: + model = faculty_about + fields = ('__all__') + +class emp_research_projectsSerializer(serializers.ModelSerializer): + class Meta: + model = emp_research_projects + fields = ('__all__') + +class InformationSerializer(serializers.ModelSerializer): + class Meta: + model = Information + fields = '__all__' # or specify fields as needed + +# serializers.py +class LabSerializer(serializers.ModelSerializer): + class Meta: + model = Lab + fields = '__all__' + + +class FeedbackSerializer(serializers.ModelSerializer): + class Meta: + model = Feedback + fields = ['id', 'department', 'rating', 'remark'] \ No newline at end of file diff --git a/FusionIIIT/applications/department/api/urls.py b/FusionIIIT/applications/department/api/urls.py new file mode 100644 index 000000000..5a58bebb3 --- /dev/null +++ b/FusionIIIT/applications/department/api/urls.py @@ -0,0 +1,22 @@ +from django.conf.urls import url + +from . import views + +urlpatterns = [ + url(r'announcements/$', views.ListCreateAnnouncementView.as_view(),name='announcements'), + url(r'dep-main/$', views.DepMainAPIView.as_view(), name='depmain'), + url(r'fac-view/$', views.FacAPIView.as_view(), name='facapi'), + url(r'staff-view/$',views.StaffAPIView.as_view(),name='staffapi'), + url(r'all-students/(?P\w+)/$', views.AllStudentsAPIView.as_view(), name='all_students'), + url(r'faculty-data/(?P\w+)/$', views.FacultyDataAPIView.as_view(), name='faculty_data'), + url(r'ann-data/(?P\w+)/$', views.AnnouncementsDataAPIView.as_view(), name='ann_data'), + + # url(r'all-students/(?P[0-9]+)/$', views.AllStudentsAPIView.as_view() ,name='all_students'), + url(r'information/$', views.InformationAPIView.as_view(), name='information'), # New endpoint + url(r'information/update-create/$', views.InformationUpdateAPIView.as_view(), name='update_create_information'), # New endpoint + url(r'^labs/$', views.LabListView.as_view(), name='lab-list'), + url(r'labsadd/$', views.LabAPIView.as_view(), name='add_lab'), # Add Lab endpoint + url(r'labs/delete/$', views.LabDeleteAPIView.as_view(), name='delete_lab'), + url(r'feedback/create/$', views.FeedbackCreateAPIView.as_view(), name='feedback_create'), + url(r'feedback/$', views.FeedbackListView.as_view(), name='getfeedback'), +] diff --git a/FusionIIIT/applications/department/api/views.py b/FusionIIIT/applications/department/api/views.py new file mode 100644 index 000000000..4e7d12304 --- /dev/null +++ b/FusionIIIT/applications/department/api/views.py @@ -0,0 +1,336 @@ +from rest_framework import generics +from rest_framework.views import APIView +from applications.department.models import Announcements +from applications.academic_information.models import Spi, Student +from applications.globals.models import (Designation, ExtraInfo, + HoldsDesignation,Faculty) +from applications.eis.models import (faculty_about, emp_research_projects) +from .serializers import (AnnouncementSerializer,ExtraInfoSerializer,SpiSerializer,StudentSerializer,DesignationSerializer + ,HoldsDesignationSerializer,FacultySerializer,faculty_aboutSerializer,emp_research_projectsSerializer) +from rest_framework.permissions import IsAuthenticated +from .permissions import IsFacultyStaffOrReadOnly +from django.http import JsonResponse +from django.shortcuts import get_object_or_404, render, redirect +from django.contrib.auth.models import User +from rest_framework.response import Response +from rest_framework import status +from django.contrib.auth.decorators import login_required +from django.urls import reverse +from datetime import date +from notification.views import department_notif +from collections import defaultdict +import re + +from applications.department.models import Information +from .serializers import InformationSerializer +from .serializers import LabSerializer +from applications.globals.models import DepartmentInfo +from applications.department.models import Lab +from .serializers import FeedbackSerializer +from applications.department.models import Feedback +from datetime import datetime + +current_year = datetime.now().year +current_month = datetime.now().month +yearset = current_year if current_month > 8 else current_year - 1 +class ListCreateAnnouncementView(generics.ListCreateAPIView): + def post(self, request): + # Get the current user from the request + user = request.user + usrnm = get_object_or_404(User, username=user.username) + user_info = ExtraInfo.objects.select_related('user', 'department').filter(user=usrnm).first() + + if not user_info: + return Response({'error': 'User information not found'}, status=status.HTTP_404_NOT_FOUND) + + ann_maker_id = user_info.id + department = user_info.department.name # Get department name + + # Get the data from the request + data = request.data.copy() # Copy request data to modify + + # Add the department and announcement maker to the data + data['ann_maker'] = ann_maker_id + + # Instantiate the serializer with the modified data + serializer = AnnouncementSerializer(data=data, context={'request': request}) + + # Validate and save if the data is valid + if serializer.is_valid(): + # Save the data to the Announcement model + serializer.save() # This automatically saves the data in the Announcements table + + return Response(serializer.data, status=status.HTTP_201_CREATED) + + # If invalid, return the errors + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + +class DepMainAPIView(APIView): + def get(self, request): + user = request.user + usrnm = get_object_or_404(User, username=user.username) + user_info = ExtraInfo.objects.all().select_related('user', 'department').filter(user=usrnm).first() + ann_maker_id = user_info.id + user_info = ExtraInfo.objects.all().select_related('user', 'department').get(id=ann_maker_id) + department_name = user_info.department.name if user_info.department else "Unknown" + + fac_view = user.holds_designations.filter(designation__name='faculty').exists() + student = user.holds_designations.filter(designation__name='student').exists() + staff = user.holds_designations.filter(designation__name='staff').exists() + + # context = browse_announcements() + # context_f = faculty() + user_designation = "" + + if fac_view: + user_designation = "faculty" + elif student: + user_designation = "student" + else: + user_designation = "staff" + + # serailizing the data + # announcements_serailizer = AnnouncementSerializer(context, many=True) + + + response_data = { + "user_designation": user_designation, + "department": department_name, + # "announcements": context, + # "fac_list": context_f + } + + + return Response(data = response_data, status=status.HTTP_200_OK) + # return Response(data = response_data, status=status.HTTP_200_OK) + +class FacAPIView(APIView): + def get(self,request): + usrnm = get_object_or_404(User, username=request.user.username) + user_info = ExtraInfo.objects.all().select_related('user','department').filter(user=usrnm).first() + + + # context = browse_announcements() + + + # Serialize the data into JSON formats + data = { + "user_designation": user_info.user_type, + # "announcements": list(context.values()), # Assuming 'context' is a dictionary + } + + return Response(data) + +class StaffAPIView(APIView): + def get(self,request): + usrnm = get_object_or_404(User, username=request.user.username) + user_info = ExtraInfo.objects.all().select_related('user','department').filter(user=usrnm).first() + + + # context = browse_announcements() + + + # Serialize the data into JSON formats + data = { + "user_designation": user_info.user_type, + # "announcements": list(context.values()), # Assuming 'context' is a dictionary + } + + return Response(data) + +class AnnouncementsDataAPIView(APIView): + def get(self,request,bid): + filter_branch = decode_branch(bid) + if not filter_branch: + return Response({'detail': 'Invalid bid value'}, status=status.HTTP_400_BAD_REQUEST) + + ann = Announcements.objects.filter(department=filter_branch) + ann_serialized = AnnouncementSerializer(ann, many=True).data + return Response(ann_serialized, status=status.HTTP_200_OK) + +class FacultyDataAPIView(APIView): + def get(self, request, bid): + filter_branch = decode_branch(bid) + if not filter_branch: + return Response({'detail': 'Invalid bid value'}, status=status.HTTP_400_BAD_REQUEST) + + fac=ExtraInfo.objects.filter(department__name=filter_branch,user_type='faculty') + response_data = ExtraInfoSerializer(fac, many=True).data + return Response(response_data, status=status.HTTP_200_OK) + +def decode_branch(bid): + try: + branch = bid.replace('_', ' ') + match = re.match(r"^([a-zA-Z]+)", branch) + if match: + return branch # Return the branch name + + except (IndexError, KeyError): + return None # Handle malformed bid values + +class AllStudentsAPIView(APIView): + def get(self, request, bid): + # Decode bid to filter criteria + filter_criteria = decode_bid(bid) + if not filter_criteria: + return Response({'detail': 'Invalid bid value'}, status=status.HTTP_400_BAD_REQUEST) + + # Query the student list based on filter criteria + student_list = Student.objects.filter( + id__user_type='student', + **filter_criteria + ).select_related('id') + + # Create a nested dictionary with programme, year, and specialization + response_data = defaultdict(lambda: defaultdict(lambda: defaultdict(list))) + + # Populate the dictionary by programme, year, and department + for student in student_list: + programme = student.programme # E.g., 'B.Tech' + year = student.batch # E.g., '2022' + department = student.specialization # E.g., 'CSE' + serializer = StudentSerializer(student) + response_data[programme][year][department].append(serializer.data) + + # Convert defaultdict to a regular dict for JSON response + response_data = {prog: {yr: dict(depts) for yr, depts in years.items()} for prog, years in response_data.items()} + + return Response(response_data, status=status.HTTP_200_OK) + +def decode_bid(bid): + """Decode bid into filter criteria.""" + try: + match = re.match(r"([a-zA-Z]+)(\d+)([a-zA-Z]+)", bid) + if match: + level = match.group(1) # e.g., 'btech' + year = match.group(2) # e.g., '1' + specialization = match.group(3) # e.g., 'CSE' + + # Map the level to program name and process year + programme = { + 'btech': 'B.Tech', + 'bdes': 'B.Des', + 'mtech': 'M.Tech', + 'phd': 'PhD', + }.get(level.lower(), None) + + if programme: + return { + 'programme': programme, + 'batch': int(yearset) - int(year) + 1, # Example: calculate batch based on year + 'specialization': specialization.upper() # Normalize specialization to uppercase + } + except (IndexError, KeyError): + return None # Handle malformed bid values + +class InformationAPIView(generics.ListAPIView): + queryset = Information.objects.all() + serializer_class = InformationSerializer + permission_classes = (IsFacultyStaffOrReadOnly,) +class InformationUpdateAPIView(APIView): + def put(self, request): + # Ensure the data only contains phone_number, email, and facilities + data = request.data + fields_to_update = {key: data[key] for key in ["phone_number", "email", "facilites"] if key in data} + + # Get the department string from the request + department_name = data.get("department") + + # Get the department info using the department name string + department_info = DepartmentInfo.objects.filter(name=department_name).first() + + if not department_info: + return Response({"detail": "Department not found."}, status=status.HTTP_404_NOT_FOUND) + + # Update or create the Information entry for the department + information_instance, created = Information.objects.update_or_create( + department=department_info, + defaults=fields_to_update + ) + + serializer = InformationSerializer(information_instance) + if created: + message = "Information created successfully." + else: + message = "Information updated successfully." + + return Response({"message": message, "data": serializer.data}, status=status.HTTP_200_OK) +# class UpdateOrCreateInformationAPIView(APIView): +# """ +# This view will handle POST requests to either update or create +# an Information entry for a department. +# """ +# def post(self, request): +# department_name = request.data.get('department') +# phone_number = request.data.get('phone_number') +# email = request.data.get('email') +# facilities = request.data.get('facilities') + +# # Retrieve the department +# department = DepartmentInfo.objects.filter(name=department_name).first() +# if not department: +# return Response({"error": "Department not found."}, status=status.HTTP_400_BAD_REQUEST) + +# # Check if an entry exists for the department +# information_entry, created = Information.objects.update_or_create( +# department=department, +# defaults={ +# 'phone_number': phone_number, +# 'email': email, +# 'facilities': facilities +# } +# ) + +# serializer = InformationSerializer(information_entry) +# if created: +# return Response({"message": "Information created successfully.", "data": serializer.data}, status=status.HTTP_201_CREATED) +# else: +# return Response({"message": "Information updated successfully.", "data": serializer.data}, status=status.HTTP_200_OK) + +class LabListView(generics.ListAPIView): + queryset = Lab.objects.all() # Fetch all lab entries + serializer_class = LabSerializer + + +class LabAPIView(APIView): + def post(self, request): + data = request.data + + # Ensure all required fields are in the data + if not all(key in data for key in ["department", "location", "name", "capacity"]): + return Response({"detail": "Missing required fields."}, status=status.HTTP_400_BAD_REQUEST) + + # Create the Lab instance directly with the data provided + serializer = LabSerializer(data=data) + if serializer.is_valid(): + lab = serializer.save() # No need to set a department object + return Response(LabSerializer(lab).data, status=status.HTTP_201_CREATED) + + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +class LabDeleteAPIView(APIView): + def delete(self, request): + lab_ids = request.data.get('lab_ids', []) + + if not lab_ids: + return Response({"detail": "No lab IDs provided."}, status=status.HTTP_400_BAD_REQUEST) + + deleted_count = 0 + for lab_id in lab_ids: + try: + lab = Lab.objects.get(id=lab_id) + lab.delete() + deleted_count += 1 + except Lab.DoesNotExist: + return Response({"detail": f"Lab with id {lab_id} does not exist."}, status=status.HTTP_404_NOT_FOUND) + + return Response({"detail": f"Successfully deleted {deleted_count} labs."}, status=status.HTTP_204_NO_CONTENT) + +class FeedbackCreateAPIView(generics.CreateAPIView): + queryset = Feedback.objects.all() + serializer_class = FeedbackSerializer + +class FeedbackListView(generics.ListAPIView): + queryset = Feedback.objects.all() + serializer_class = FeedbackSerializer diff --git a/FusionIIIT/applications/department/migrations/0001_initial.py b/FusionIIIT/applications/department/migrations/0001_initial.py index cb016ad8b..2138e601b 100644 --- a/FusionIIIT/applications/department/migrations/0001_initial.py +++ b/FusionIIIT/applications/department/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-07-16 15:44 import datetime from django.db import migrations, models @@ -28,11 +28,22 @@ class Migration(migrations.Migration): ('request_maker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), ], ), + migrations.CreateModel( + name='Information', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('phone_number', models.BigIntegerField()), + ('email', models.CharField(max_length=200)), + ('facilites', models.TextField()), + ('labs', models.TextField()), + ('department', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='globals.departmentinfo')), + ], + ), migrations.CreateModel( name='Announcements', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('ann_date', models.DateTimeField(default='04-04-2021')), + ('ann_date', models.DateTimeField(auto_now_add=True)), ('message', models.CharField(max_length=200)), ('batch', models.CharField(default='Year-1', max_length=40)), ('department', models.CharField(default='ALL', max_length=40)), @@ -41,4 +52,4 @@ class Migration(migrations.Migration): ('maker_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), ], ), - ] + ] \ No newline at end of file diff --git a/FusionIIIT/applications/department/migrations/0002_auto_20250217_1742.py b/FusionIIIT/applications/department/migrations/0002_auto_20250217_1742.py new file mode 100644 index 000000000..5b39f6b3d --- /dev/null +++ b/FusionIIIT/applications/department/migrations/0002_auto_20250217_1742.py @@ -0,0 +1,37 @@ +# Generated by Django 3.1.5 on 2025-02-17 17:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('department', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Feedback', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('department', models.CharField(max_length=50)), + ('rating', models.CharField(max_length=20)), + ('remark', models.TextField()), + ], + ), + migrations.CreateModel( + name='Lab', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('department', models.CharField(max_length=50)), + ('location', models.CharField(max_length=200)), + ('name', models.CharField(max_length=100)), + ('capacity', models.IntegerField()), + ], + ), + migrations.AlterField( + model_name='announcements', + name='upload_announcement', + field=models.FileField(default=None, null=True, upload_to='department/upload_announcement'), + ), + ] diff --git a/FusionIIIT/applications/department/models.py b/FusionIIIT/applications/department/models.py index f8e1392db..dcbb8f4a2 100644 --- a/FusionIIIT/applications/department/models.py +++ b/FusionIIIT/applications/department/models.py @@ -3,15 +3,16 @@ from datetime import date # Create your models here. -from applications.globals.models import ExtraInfo +from applications.globals.models import ExtraInfo , DepartmentInfo + class SpecialRequest(models.Model): request_maker = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) request_date = models.DateTimeField(default=date.today) 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="--") @@ -21,13 +22,40 @@ def __str__(self): class Announcements(models.Model): maker_id = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) - ann_date = models.DateTimeField(default="04-04-2021") + ann_date = models.DateTimeField(auto_now_add=True) 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=None) def __str__(self): return str(self.maker_id.user.username) + +class Information(models.Model): + department = models.OneToOneField( + DepartmentInfo, + on_delete=models.CASCADE, + ) + + phone_number = models.BigIntegerField() + email = models.CharField(max_length=200) + facilites = models.TextField() + labs = models.TextField() + + +class Lab(models.Model): + department = models.CharField(max_length=50) # Store department as a string field instead of a foreign key + location = models.CharField(max_length=200) + name = models.CharField(max_length=100) + capacity = models.IntegerField() + + def __str__(self): + return f"{self.name} ({self.department})" + +class Feedback(models.Model): + department = models.CharField(max_length=50) # no need to validate department name + rating = models.CharField(max_length=20) + remark = models.TextField() + + def __str__(self): + return f"{self.department} - {self.rating}" \ No newline at end of file diff --git a/FusionIIIT/applications/department/serializers.py b/FusionIIIT/applications/department/serializers.py deleted file mode 100644 index eb65119c9..000000000 --- a/FusionIIIT/applications/department/serializers.py +++ /dev/null @@ -1,12 +0,0 @@ -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 bdf859afd..0a64c2c95 100644 --- a/FusionIIIT/applications/department/static/department/js/function.js +++ b/FusionIIIT/applications/department/static/department/js/function.js @@ -5,46 +5,79 @@ $(document).ready(function(){ function announce(event) - { - var message= $('input[name="announcement"]').val(); - var batch = $('input[name="batch"]').val(); - var programme = $('input[name="programme"]').val(); - var department = $('input[name="department"]').val(); - var upload_announcement =$('input[name="upload_announcement"]').val(); - if(message=="" || batch=="" || programme =="" || department=="") - { - alert("Please fill all the details!"); - return; - } - else - { - event.preventDefault(); - $.ajax({ - type : 'POST', - url : '.', - data : { - 'message' : message, - 'batch' : batch, - 'programme' : programme, - 'upload_announcement' : upload_announcement, - 'department' : department, - }, - success : function (data){ + { + var message= $('input[name="announcement"]').val(); + var batch = $('input[name="batch"]').val(); + var programme = $('input[name="programme"]').val(); + var department = $('input[name="department"]').val(); + var upload_announcement =$('input[name="upload_announcement"]').val(); + if(message=="" || batch=="" || programme =="" || department=="") + { + alert("Please fill all the details!"); + return; + } + else + { + event.preventDefault(); + $.ajax({ + type : 'POST', + url : '.', + data : { + 'message' : message, + 'batch' : batch, + 'programme' : programme, + 'upload_announcement' : upload_announcement, + 'department' : department, + }, + success : function (data){ + + alert("Announcement successfully made!!"); + setTimeout(function() { + window.location.reload(); + }, 1500); + + + }, + error : function (data,err){ + alert('Announcement successfully made ... '); - alert("Announcement successfully made!!"); - setTimeout(function() { - window.location.reload(); - }, 1500); + } + }); + } +}; - - }, - error : function (data,err){ - alert('Announcement successfully made ... '); +function updateDepartment(event) { + var email = $('input[name="email"]').val(); + var contactNumber = $('input[name="contact_number"]').val(); + var facilities = $('textarea[name="facilities"]').val(); + var labs = $('textarea[name="labs"]').val(); - } - }); - } - }; + if (email === "" || contactNumber === "" || facilities === "" || labs === "" || departmentId === "") { + alert("Please fill all the details!"); + return; + } else { + event.preventDefault(); + $.ajax({ + type: 'POST', + url: '.', // Specify the URL to your view for updating department information + data: { + 'email': email, + 'contact_number': contactNumber, + 'facilities': facilities, + 'labs': labs, + }, + success: function(data) { + alert("Department information updated successfully!"); + setTimeout(function() { + window.location.reload(); + }, 1500); + }, + error: function(data, err) { + alert('Failed to update department information.'); + } + }); + } +} function request(event) { @@ -52,7 +85,6 @@ 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!"); @@ -60,8 +92,7 @@ function request(event) } else { - // event.preventDefault(); - alert("please wait we are processing your request."); + event.preventDefault(); $.ajax({ type : 'POST', url : '.', @@ -75,11 +106,11 @@ function request(event) alert("Request successfully made!!"); setTimeout(function() { window.location.reload(); - }, 0); + }, 1500); }, error : function (data,err){ - alert('Request not created'); + alert('Request successfully made ... '); } }); diff --git a/FusionIIIT/applications/department/urls.py b/FusionIIIT/applications/department/urls.py index 30a4adfd4..094e1e90d 100644 --- a/FusionIIIT/applications/department/urls.py +++ b/FusionIIIT/applications/department/urls.py @@ -1,4 +1,5 @@ from django.conf.urls import url +from django.urls import include from . import views @@ -9,14 +10,11 @@ url(r'^$', views.dep_main, name='dep'), url(r'^facView/$', views.faculty_view, name='faculty_view'), url(r'^staffView/$', views.staff_view, name='staff_view'), - url(r'^All_Students/(?P[0-9]+)/$', views.all_students,name='all_students'), + url(r'All_Students/(?P[0-9]+)/$', views.all_students,name='all_students'), + url(r'alumni/$', views.alumni, name='alumni'), url(r'^approved/$', views.approved, name='approved'), 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 + + url(r'^api/', include("applications.department.api.urls")) + +] \ No newline at end of file diff --git a/FusionIIIT/applications/department/views.py b/FusionIIIT/applications/department/views.py index 3bd39ea80..249f4875c 100644 --- a/FusionIIIT/applications/department/views.py +++ b/FusionIIIT/applications/department/views.py @@ -5,7 +5,7 @@ from django.contrib import messages from django.contrib.auth.decorators import login_required -from django.http import HttpResponse, HttpResponseRedirect +from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest # Create your views here. from django.db.models import Q from django.shortcuts import get_object_or_404, render, redirect @@ -13,135 +13,31 @@ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from applications.academic_information.models import Spi, Student from applications.globals.models import (Designation, ExtraInfo, - HoldsDesignation,Faculty) + HoldsDesignation,Faculty,DepartmentInfo) from applications.eis.models import (faculty_about, emp_research_projects) - +from .models import Information from notification.views import department_notif -from .models import SpecialRequest, Announcements +from .models import SpecialRequest, Announcements , Information from jsonschema import validate from jsonschema.exceptions import ValidationError +from notification.views import create_announcement -# 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. +def department_information(request): + cse_info = Information.objects.filter(department_id=51).first() + ece_info = Information.objects.filter(department_id=30).first() + me_info = Information.objects.filter(department_id=37).first() + sm_info = Information.objects.filter(department_id=28).first() + department_context = { + "cse_info" : cse_info, + "ece_info" : ece_info, + "me_info" : me_info, + "sm_info" : sm_info + } + # print(department_context) + # print(me_info.phone_number,me_info.email,me_info.department_id) + return department_context def browse_announcements(): """ @@ -170,7 +66,7 @@ def browse_announcements(): "sm" : sm_ann, "all" : all_ann } - + # print(context) return context def get_make_request(user_id): @@ -216,7 +112,8 @@ def dep_main(request): user_info = ExtraInfo.objects.all().select_related('user','department').filter(user=usrnm).first() ann_maker_id = user_info.id user_info = ExtraInfo.objects.all().select_related('user','department').get(id=ann_maker_id) - + user_departmentid = ExtraInfo.objects.all().select_related('user','department').get(id=ann_maker_id).department_id + requests_made = get_make_request(user_info) fac_view = request.user.holds_designations.filter(designation__name='faculty').exists() @@ -226,7 +123,10 @@ def dep_main(request): context = browse_announcements() context_f = faculty() user_designation = "" - + + + department_context = department_information(request) + if fac_view: user_designation = "faculty" elif student: @@ -239,25 +139,37 @@ def dep_main(request): request_to = request.POST.get('request_to', '') request_details = request.POST.get('request_details', '') request_date = date.today() - - 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 - ) + + 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, - "fac_list" : context_f, - "requests_made" : requests_made - }) - # elif(str(user.extrainfo.user_type)=="faculty"): + department_templates = { + 51: 'department/cse_index.html', + 30: 'department/ece_index.html', + 37: 'department/me_index.html', + 53: 'department/sm_index.html' + } + default_template = 'department/cse_index.html' + template_name = department_templates.get(user_departmentid, default_template) + + return render(request, template_name, { + "announcements": context, + "fac_list": context_f, + "requests_made": requests_made, + "department_info": department_context + + }) + elif user_designation=="faculty": return HttpResponseRedirect("facView") + elif user_designation=="staff": return HttpResponseRedirect("staffView") @@ -275,11 +187,15 @@ def faculty_view(request): department, ann_date, user_info - Gets and store data from FORM used for Announcements. """ + context_f = faculty() usrnm = get_object_or_404(User, username=request.user.username) user_info = ExtraInfo.objects.all().select_related('user','department').filter(user=usrnm).first() num = 1 ann_maker_id = user_info.id requests_received = get_to_request(usrnm) + user_departmentid = ExtraInfo.objects.all().select_related('user','department').get(id=ann_maker_id).department_id + department_context = department_information(request) + if request.method == 'POST': batch = request.POST.get('batch', '') programme = request.POST.get('programme', '') @@ -298,13 +214,29 @@ def faculty_view(request): upload_announcement=upload_announcement, department = department, ann_date=ann_date) + department_notif(usrnm, recipients , message) context = browse_announcements() - return render(request, 'department/dep_request.html', {"user_designation":user_info.user_type, - "announcements":context, - "request_to":requests_received - }) + + department_templates = { + 51: 'department/csedep_request.html', + 30: 'department/ecedep_request.html', + 37: 'department/medep_request.html', + 53: 'department/smdep_request.html' + } + default_template = 'department/dep_request.html' + + template_name = department_templates.get(user_departmentid, default_template) + + return render(request, template_name, { + "user_designation": user_info.user_type, + "announcements": context, + "request_to": requests_received, + "fac_list": context_f, + "department_info": department_context + }) + def staff_view(request): """ @@ -320,39 +252,144 @@ def staff_view(request): department, ann_date, user_info - Gets and store data from FORM used for Announcements for Students. """ + context_f = faculty() usrnm = get_object_or_404(User, username=request.user.username) user_info = ExtraInfo.objects.all().select_related('user','department').filter(user=usrnm).first() num = 1 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() - user_info = ExtraInfo.objects.all().select_related('user','department').get(id=ann_maker_id) - getstudents = ExtraInfo.objects.select_related('user') - recipients = User.objects.filter(extrainfo__in=getstudents) + user_departmentid = ExtraInfo.objects.all().select_related('user','department').get(id=ann_maker_id).department_id - 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) - department_notif(usrnm, recipients , message) + department_context = department_information(request) + + requests_received = get_to_request(usrnm) + # if request.method == 'POST': + # form_type = request.POST.get('form_type', '') + # if form_type == 'form1' : + + # 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() + # user_info = ExtraInfo.objects.all().select_related('user','department').get(id=ann_maker_id) + # getstudents = ExtraInfo.objects.select_related('user') + # recipients = User.objects.filter(extrainfo__in=getstudents) + + # 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) + # department_notif(usrnm, recipients , message) + + # elif form_type == 'form2' : + + # email = request.POST.get('email', '') + # phone_number = request.POST.get('contact_number', '') + # facilites = request.POST.get('facilities', '') + # labs = request.POST.get('labs', '') + # department_id = user_departmentid + + # # Check if a row with the specified department_id already exists + # try: + # department_info = Information.objects.get(department_id=department_id) + # # If row exists, update the values + # department_info.email = email + # department_info.phone_number_number = phone_number + # department_info.facilites = facilites + # department_info.labs = labs + # department_info.save() + # except Information.DoesNotExist: + # # If row does not exist, create a new one + # department_info = Information.objects.create( + # department_id=department_id, + # email=email, + # phone_number=phone_number, + # facilites=facilites, + # labs=labs + # ) + - context = browse_announcements() - return render(request, 'department/dep_request.html', {"user_designation":user_info.user_type, - "announcements":context, - "request_to":requests_received - }) + # context = browse_announcements() + + + # department_templates = { + # 51: 'department/csedep_request.html', + # 30: 'department/ecedep_request.html', + # 37: 'department/medep_request.html', + # 53: 'department/smdep_request.html', + + # } + # default_template = 'department/dep_request.html' + + # desig=request.session.get('currentDesignationSelected', 'default_value') + # if desig=='deptadmin_cse': + # template_name = 'department/admin_cse.html' + + # return render(request, template_name, { + # "user_designation": user_info.user_type, + # "announcements": context, + # "request_to": requests_received, + # "fac_list": context_f, + # "department_info": department_context + # }) + # elif desig=='deptadmin_ece': + # template_name = 'department/admin_ece.html' + # return render(request, template_name, { + # "user_designation": user_info.user_type, + # "announcements": context, + # "request_to": requests_received, + # "fac_list": context_f, + # "department_info": department_context + # }) + # elif desig=='deptadmin_me': + # template_name = 'department/admin_me.html' + # return render(request, template_name, { + # "user_designation": user_info.user_type, + # "announcements": context, + # "request_to": requests_received, + # "fac_list": context_f, + # "department_info": department_context + # }) + # elif desig=='deptadmin_sm': + # template_name = 'department/admin_sm.html' + # return render(request, template_name, { + # "user_designation": user_info.user_type, + # "announcements": context, + # "request_to": requests_received, + # "fac_list": context_f, + # "department_info": department_context + # }) + + # # if desig == 'deptadmin_cse': + # # return render(request, 'admin_cse.html') + # # elif desig == 'deptadmin_ece': + # # return render(request, 'admin_ece.html') + # # elif desig == 'deptadmin_sm': + # # return render(request, 'admin_sm.html') + # # elif desig == 'deptadmin_me': + # # return render(request, 'admin_me.html') + # # else: + # # return render(request, 'default.html') + + # template_name = department_templates.get(user_departmentid, default_template) + # return render(request, template_name, { + # "user_designation": user_info.user_type, + # "announcements": context, + # "request_to": requests_received, + # "fac_list": context_f, + # "department_info": department_context + # }) + return create_announcement(request, 'department/dep_request.html', 'Department', {"user_designation": user_info.user_type}) + + @login_required(login_url='/accounts/login') -def all_students(request,bid): + +def all_students(request, bid): """ This function is used to Return data of Faculties Department-Wise. @@ -365,284 +402,62 @@ def all_students(request,bid): student_list - Stores data pagewise """ - if int(bid)==1: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2021, - id__user_type='student', - id__department__name='CSE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==11: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2020, - id__user_type='student', - id__department__name='CSE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==111: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2019, - id__user_type='student', - id__department__name='CSE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==1111: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2018, - id__user_type='student', - id__department__name='CSE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==11111: - student_list1=Student.objects.order_by('id').filter(programme='M.Tech', - batch=2021, - id__user_type='student', - id__department__name='CSE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==111111: - student_list1=Student.objects.order_by('id').filter(programme='M.Tech', - batch=2020, - id__user_type='student', - id__department__name='CSE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==1111111: - student_list1=Student.objects.order_by('id').filter(programme='PhD', - id__user_type='student', - id__department__name='CSE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==2: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2021, - id__user_type='student', - id__department__name='ECE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==21: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2020, - id__user_type='student', - id__department__name='ECE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==211: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2019, - id__user_type='student', - id__department__name='ECE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==2111: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2018, - id__user_type='student', - id__department__name='ECE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==21111: - student_list1=Student.objects.order_by('id').filter(programme='M.Tech', - batch=2021, - id__user_type='student', - id__department__name='ECE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==211111: - student_list1=Student.objects.order_by('id').filter(programme='M.Tech', - batch=2020, - id__user_type='student', - id__department__name='ECE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==2111111: - student_list1=Student.objects.order_by('id').filter(programme='PhD', - id__user_type='student', - id__department__name='ECE').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==3: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2021, - id__user_type='student', - id__department__name='ME').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==31: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2020, - id__user_type='student', - id__department__name='ME').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==311: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2019, - id__user_type='student', - id__department__name='ME').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==3111: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2018, - id__user_type='student', - id__department__name='ME').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==31111: - student_list1=Student.objects.order_by('id').filter(programme='M.Tech', - batch=2021, - id__user_type='student', - id__department__name='ME').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==311111: - student_list1=Student.objects.order_by('id').filter(programme='M.Tech', - batch=2020, - id__user_type='student', - id__department__name='ME').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==3111111: - student_list1=Student.objects.order_by('id').filter(programme='PhD', - id__user_type='student', - id__department__name='ME').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==4: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2021, - id__user_type='student', - id__department__name='SM').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==41: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2020, - id__user_type='student', - id__department__name='SM').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==411: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2019, - id__user_type='student', - id__department__name='SM').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==4111: - student_list1=Student.objects.order_by('id').filter(programme='B.Tech', - batch=2018, - id__user_type='student', - id__department__name='SM').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==41111: - student_list1=Student.objects.order_by('id').filter(programme='M.Tech', - batch=2021, - id__user_type='student', - id__department__name='SM').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==411111: - student_list1=Student.objects.order_by('id').filter(programme='M.Tech', - batch=2020, - id__user_type='student', - id__department__name='SM').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - elif int(bid)==4111111: - student_list1=Student.objects.order_by('id').filter(programme='PhD', - id__user_type='student', - id__department__name='SM').select_related('id') - paginator=Paginator(student_list1,25,orphans=5) - page_number=request.GET.get('page') - student_list=paginator.get_page(page_number) - id_dict={'student_list':student_list,} - return render(request, 'department/AllStudents.html',context=id_dict) - + def decode_bid(bid): + """Decodes the bid structure into programme, batch, and department (if applicable).""" + + try: + department_code = bid[0] + programme = { + '1': 'B.Tech', + '2': 'M.Tech', + '3': 'PhD', + + }[department_code] + batch = 2021 - len(bid) + 1 + return {'programme': programme, 'batch': batch} + except (IndexError, KeyError): + return None # Handle malformed bid values + # Get sort parameter from the request + sort_by = request.GET.get('sort_by', None) # No default sort + last_sort = request.session.get('last_sort', None) + + # Decode bid into filter criteria + filter_criteria = decode_bid(bid) + if not filter_criteria: + return HttpResponseBadRequest("Invalid bid value") + + # Apply additional department filter since it seems fixed + filter_criteria['id__department__name'] = 'CSE' + + # Apply sort parameter to the queryset + if sort_by: + if last_sort == sort_by: + sort_by = '-' + sort_by # Reverse the order + try: + student_list1 = Student.objects.order_by(sort_by).filter( + id__user_type='student', + **filter_criteria + ).select_related('id') + except: + # If the sort field doesn't exist or isn't sortable, ignore the sort parameter + student_list1 = Student.objects.filter( + id__user_type='student', + **filter_criteria + ).select_related('id') + request.session['last_sort'] = sort_by # Save the sort parameter for the next request + else: + student_list1 = Student.objects.filter( + id__user_type='student', + **filter_criteria + ).select_related('id') + + paginator = Paginator(student_list1, 25, orphans=5) + page_number = request.GET.get('page') + student_list = paginator.get_page(page_number) + id_dict = {'student_list': student_list} + return render(request, 'department/AllStudents.html', context=id_dict) + def faculty(): """ @@ -674,8 +489,35 @@ def faculty(): } + # print(cse_f) return context_f + +def alumni(request): + """ + This function is used to Return data of Alumni Department-Wise. + + @variables: + cse_a - Stores data of alumni from CSE Department + ece_a - Stores data of alumni from ECE Department + me_a - Stores data of alumni from ME Department + sm_a - Stores data of alumni from ME Department + context_a - Stores all above variables in Dictionary + + """ + cse_a=ExtraInfo.objects.filter(department__name='CSE',user_type='alumni') + ece_a=ExtraInfo.objects.filter(department__name='ECE',user_type='alumni') + me_a=ExtraInfo.objects.filter(department__name='ME',user_type='alumni') + sm_a=ExtraInfo.objects.filter(department__name='SM',user_type='alumni') + + context_a = { + "cse_a" : cse_a, + "ece_a" : ece_a, + "me_a" : me_a, + "sm_a" : sm_a + } + return render(request, 'department/alumni.html', context_a) + def approved(request): """ This function is used to approve requests. @@ -692,6 +534,7 @@ def approved(request): request.method = '' return redirect('/dep/facView/') + def deny(request): """ This function is used to deny requests. @@ -706,6 +549,4 @@ 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/') - - + return redirect('/dep/facView/') \ No newline at end of file diff --git a/FusionIIIT/applications/eis/admin.py b/FusionIIIT/applications/eis/admin.py index fbbd20943..40ae43cf7 100644 --- a/FusionIIIT/applications/eis/admin.py +++ b/FusionIIIT/applications/eis/admin.py @@ -29,3 +29,8 @@ class emp_research_papersAdmin(admin.ModelAdmin): admin.site.register(emp_achievement) admin.site.register(faculty_about) + +admin.site.register(emp_administrative_position) +admin.site.register(emp_honors) +admin.site.register(emp_professional_experience) +admin.site.register(emp_qualifications) diff --git a/FusionIIIT/applications/eis/api/serializers.py b/FusionIIIT/applications/eis/api/serializers.py index c164fa2ed..f3d5cd964 100644 --- a/FusionIIIT/applications/eis/api/serializers.py +++ b/FusionIIIT/applications/eis/api/serializers.py @@ -7,7 +7,7 @@ emp_consultancy_projects,emp_patents,emp_techtransfer,emp_mtechphd_thesis, emp_visits,emp_confrence_organised,emp_achievement, emp_expert_lectures,emp_session_chair,emp_keynote_address, - emp_event_organized,faculty_about) + emp_event_organized,faculty_about,AdministrativePosition,Honor,ProfessionalExperience,Qualification) from applications.globals.api.serializers import ExtraInfoSerializer, UserSerializer, HoldsDesignationSerializer User = get_user_model() @@ -101,3 +101,27 @@ class FacultyAboutSerializer(serializers.ModelSerializer): class Meta: model = faculty_about fields = ('__all__') + +class AdministrativePositionSerializer(serializers.ModelSerializer): + + class Meta: + model = AdministrativePosition + fields = ('__all__') + +class HonorSerializer(serializers.ModelSerializer): + + class Meta: + model = Honor + fields = ('__all__') + +class ProfessionalExperienceSerializer(serializers.ModelSerializer): + + class Meta: + model = ProfessionalExperience + fields = ('__all__') + +class QualificationSerializer(serializers.ModelSerializer): + + class Meta: + model = Qualification + fields = ('__all__') diff --git a/FusionIIIT/applications/eis/api/urls.py b/FusionIIIT/applications/eis/api/urls.py index 6e9117aaa..f1be56d57 100644 --- a/FusionIIIT/applications/eis/api/urls.py +++ b/FusionIIIT/applications/eis/api/urls.py @@ -1,10 +1,126 @@ -from django.conf.urls import url +from django.conf.urls import url, re_path from . import views urlpatterns = [ - # generic profile endpoint - url(r'^profile/(?P\w+)/', views.profile, name='profile-api'), - # current user profile - url(r'^profile/', views.profile, name='profile-api'), -] + # url used to add data + # url(r'uploadcsv/$', views.upload_file), + re_path(r'^$', views.index, name='index'), + # url(r'^profile/(?P\w+)/$', views.profile, name='profile'), + re_path(r'^profile/$', views.profile, name='profile'), + + re_path(r'^rspc_profile/$', views.rspc_profile, name='rspc_profile'), + + # delete + re_path(r'^achv/$', views.achievementDelete, name='achievement_delete'), + re_path(r'^emp_confrence_organisedDelete/$', views.emp_confrence_organisedDelete, name='emp_confrence_organisedDelete'), + re_path(r'^emp_consultancy_projectsDelete/$', views.emp_consultancy_projectsDelete, name='emp_consultancy_projectsDelete'), + + re_path(r'^emp_confrence_organisedDelete/$', views.emp_confrence_organisedDelete, name='emp_confrence_organisedDelete'), + re_path(r'^emp_event_organizedDelete/$', views.emp_event_organizedDelete, name='emp_event_organizedDelete'), + re_path(r'^emp_expert_lecturesDelete/$', views.emp_expert_lecturesDelete, name='emp_expert_lecturesDelete'), + re_path(r'^emp_keynote_addressDelete/$', views.emp_keynote_addressDelete, name='emp_keynote_addressDelete'), + re_path(r'^emp_mtechphd_thesisDelete/$', views.emp_mtechphd_thesisDelete, name='emp_mtechphd_thesisDelete'), + re_path(r'^emp_patentsDelete/$', views.emp_patentsDelete, name='emp_patentsDelete'), + re_path(r'^emp_published_booksDelete/$', views.emp_published_booksDelete, name='emp_published_booksDelete'), + re_path(r'^emp_research_papersDelete/$', views.emp_research_papersDelete, name='emp_research_papersDelete'), + re_path(r'^emp_research_projectsDelete/$', views.emp_research_projectsDelete, name='emp_research_projectsDelete'), + re_path(r'^emp_session_chairDelete/$', views.emp_session_chairDelete, name='emp_session_chairDelete'), + + re_path(r'^emp_techtransferDelete/$', views.emp_techtransferDelete, name='emp_techtransferDelete'), + re_path(r'^emp_visitsDelete/$', views.emp_visitsDelete, name='emp_visitsDelete'), + re_path(r'^emp_consymDelete/$', views.emp_consymDelete, name='emp_consymDelete'), + + + # edit personal information + re_path(r'^extra/$', views.view_all_extra_infos, name='extra'), + re_path(r'^persinfo/$', views.persinfo, name='persinfo'), + re_path(r'^journal/edit$', views.editjournal, name='editjournal'), + re_path(r'^foreignvisit/edit$', views.editforeignvisit, name='editforeignvisit'), + re_path(r'^indianvisit/edit$', views.editindianvisit, name='editindianvisit'), + re_path(r'^consym/edit$', views.editconsym, name='editconsym'), + re_path(r'^event/edit$', views.editevent, name='editevent'), + re_path(r'^conference/edit$', views.editconference, name='editconference'), + re_path(r'^books/edit$', views.editbooks, name='editbooks'), + + re_path(r'^update_personal_info/$', views.update_personal_info, name='update_personal_info'), + + # insert + re_path(r'^pg/$', views.pg_insert, name='pg_insert'), + re_path(r'^phd/$', views.phd_insert, name='phd_insert'), + re_path(r'^fvisit/$', views.fvisit_insert, name='fvisit_insert'), + re_path(r'^ivisit/$', views.ivisit_insert, name='ivisit_insert'), + re_path(r'^journal/$', views.journal_insert, name='journal_insert'), + re_path(r'^conference/$', views.conference_insert, name='conference_insert'), + re_path(r'^book/$', views.book_insert, name='book_insert'), + re_path(r'^consym/$', views.consym_insert, name='consym_insert'), + re_path(r'^event/$', views.event_insert, name='event_insert'), + re_path(r'^award/$', views.award_insert, name='award_insert'), + re_path(r'^talk/$', views.talk_insert, name='talk_insert'), + re_path(r'^chaired/$', views.chaired_insert, name='chaired_insert'), + re_path(r'^keynote/$', views.keynote_insert, name='keynote_insert'), + re_path(r'^project/$', views.project_insert, name='project_insert'), + re_path(r'^consult_insert/$', views.consult_insert, name='consult_insert'), + re_path(r'^patent_insert/$', views.patent_insert, name='patent_insert'), + re_path(r'^transfer_insert/$', views.transfer_insert, name='transfer_insert'), + + # generate report + url(r'^report/$', views.generate_report, name='generate_report'), + + + # Fetch Details from Database + re_path(r'^get_personal_info/$', views.get_personal_info, name='get_personal_info'), + re_path(r'^projects/pf_no/$', views.get_research_projects, name='projects_by_pf_no'), + re_path(r'^projects/all/$', views.get_all_research_projects, name='projects_all'), + re_path(r'^consultancy_projects/pf_no/$', views.get_consultancy_projects, name='consultancy_projects_by_pf_no'), + re_path(r'^patents/pf_no/$', views.get_patents, name='patents_by_pf_no'), + re_path(r'^pg_thesis/pf_no/$', views.get_pg_thesis, name='pg_thesis_by_pf_no'), + re_path(r'^phd_thesis/pf_no/$', views.get_phd_thesis, name='phd_thesis_by_pf_no'), + re_path(r'^event/pf_no/$', views.get_event, name='event_by_pf_no'), + re_path(r'^fvisits/pf_no/$', views.get_fvisits, name='fvisits_by_pf_no'), + re_path(r'^ivisits/pf_no/$', views.get_ivisits, name='ivisits_by_pf_no'), + re_path(r'^consym/pf_no/$', views.get_consym, name='consym_by_pf_no'), + re_path(r'^fetch_book/$', views.get_books, name="get_books_of_prof"), + re_path(r'^fetch_journal/$', views.get_journals, name="get_journals_of_prof"), + re_path(r'^fetch_conference/$', views.get_conference, name="get_conference_of_prof"), + re_path(r'^award/pf_no/$', views.get_achievements, name="get_achievements_of_prof"), + re_path(r'^talk/pf_no/$', views.get_talks, name="get_talks_of_prof"), + + # Filter and Fetch + re_path(r'^projects/filter/$', views.filter_research_projects, name='projects_by_filter'), + re_path(r'^consultancy_projects/filter/$', views.filter_consultancy_projects, name='consultancy_projects_by_filter'), + re_path(r'^patents/filter/$', views.filter_patents, name='patents_by_filter'), + re_path(r'^pg_phd_thesis/filter/$', views.filter_mtechphd_thesis, name='pg_thesis_by_filter'), + re_path(r'^event/filter/$', views.filter_events, name='event_by_filter'), + re_path(r'^visits/filter/$', views.filter_visits, name='visits_by_filter'), + re_path(r'^consym/filter/$', views.filter_consym, name='consym_by_filter'), + re_path(r'^fetch_book/filter/$', views.filter_books, name="get_books_of_prof_filter"), + re_path(r'^fetch_journal_or_conference/filter/$', views.filter_journal_or_conference, name="get_journals_or_conference_of_prof_filter"), + re_path(r'^award/filter/$', views.filter_achievements, name="get_achievements_of_prof_filter"), + re_path(r'^talk/filter/$', views.filter_talks, name="get_talks_of_prof_filter"), + + # special + + re_path(r'^get_id/$', views.get_all_faculty_ids, name='get_all_faculty_ids'), + + # 4 forms + + re_path(r'^add_administrative_position/$', views.add_administrative_position, name='add_administrative_position'), + re_path(r'^get_administrative_positions/$', views.get_administrative_position, name='get_administrative_positions'), + re_path(r'^delete_administrative_position/$', views.delete_administrative_position, name='delete_administrative_position'), + + re_path(r'^add_qualification/$', views.add_qualification, name='add_qualification'), + re_path(r'^get_qualifications/$', views.get_qualifications, name='get_qualifications'), + re_path(r'^delete_qualification/$', views.delete_qualification, name='delete_qualification'), + + re_path(r'^add_honor/$', views.add_honor, name='add_honor'), + re_path(r'^get_honors/$', views.get_honors, name='get_honors'), + re_path(r'^delete_honor/$', views.delete_honor, name='delete_honor'), + + re_path(r'^add_professional_experience/$', views.add_professional_experience, name='add_professional_experience'), + re_path(r'^get_professional_experiences/$', views.get_professional_experiences, name='get_professional_experiences'), + re_path(r'^delete_professional_experience/$', views.delete_professional_experience, name='delete_professional_experience'), + + # csrf + re_path(r'^csrf/$', views.get_csrf_token, name='csrf'), +] \ No newline at end of file diff --git a/FusionIIIT/applications/eis/api/views.py b/FusionIIIT/applications/eis/api/views.py index d05033da0..f9ace3cef 100644 --- a/FusionIIIT/applications/eis/api/views.py +++ b/FusionIIIT/applications/eis/api/views.py @@ -1,89 +1,3817 @@ -from django.contrib.auth import get_user_model -from django.shortcuts import get_object_or_404 - -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 django.contrib.auth import get_user_model +# from django.shortcuts import get_object_or_404 + +# 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.eis.models import * +# from applications.eis.views import countries +# from applications.globals.models import HoldsDesignation + +# from . import serializers + + +# User = get_user_model() + +# @api_view(['GET']) +# def profile(request, username=None): +# user = get_object_or_404(User, username=username) if username else request.user +# user_detail = serializers.UserSerializer(user).data +# extra_info = serializers.ExtraInfoSerializer(user.extrainfo).data +# if extra_info['user_type'] != 'faculty': +# return Response(data={'message':'Not faculty'}, status=status.HTTP_400_BAD_REQUEST) + +# pf = extra_info['id'] +# journal = serializers.EmpResearchPapersSerializer(emp_research_papers.objects.filter(pf_no=pf, rtype='Journal').order_by('-year'),many=True).data +# conference = serializers.EmpResearchPapersSerializer(emp_research_papers.objects.filter(pf_no=pf, rtype='Conference').order_by('-year'),many=True).data +# books = serializers.EmpPublishedBooksSerializer(emp_published_books.objects.filter(pf_no=pf).order_by('-pyear'),many=True).data +# projects = serializers.EmpResearchProjectsSerializer(emp_research_projects.objects.filter(pf_no=pf).order_by('-start_date'),many=True).data +# consultancy = serializers.EmpConsultancyProjectsSerializer(emp_consultancy_projects.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data +# patents = serializers.EmpPatentsSerializer(emp_patents.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data +# techtransfers = serializers.EmpTechTransferSerializer(emp_techtransfer.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data +# mtechs = serializers.EmpMtechPhdThesisSerializer(emp_mtechphd_thesis.objects.filter(pf_no=pf, degree_type=1).order_by('-date_entry'),many=True).data +# phds = serializers.EmpMtechPhdThesisSerializer(emp_mtechphd_thesis.objects.filter(pf_no=pf, degree_type=2).order_by('-date_entry'),many=True).data +# fvisits = serializers.EmpVisitsSerializer(emp_visits.objects.filter(pf_no=pf, v_type=2).order_by('-entry_date'),many=True).data +# ivisits = serializers.EmpVisitsSerializer(emp_visits.objects.filter(pf_no=pf, v_type=1).order_by('-entry_date'),many=True).data +# for fvisit in fvisits: +# fvisit['countryfull'] = countries[fvisit['country']] +# consymps = serializers.EmpConfrenceOrganisedSerializer(emp_confrence_organised.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data +# awards = serializers.EmpAchievementSerializer(emp_achievement.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data +# talks = serializers.EmpExpertLecturesSerializer(emp_expert_lectures.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data +# chairs = serializers.EmpSessionChairSerializer(emp_session_chair.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data +# keynotes = serializers.EmpKeynoteAddressSerializer(emp_keynote_address.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data +# events = serializers.EmpEventOrganizedSerializer(emp_event_organized.objects.filter(pf_no=pf).order_by('-start_date'),many=True).data +# year_range = [] +# for r in range(1995, (datetime.datetime.now().year + 1)): +# year_range.append(r) +# try: +# faculty_about = serializers.FacultyAboutSerializer(user.faculty_about).data +# except: +# faculty_about = None + +# holds_desig = user.current_designation.all() +# flag_rspc = 0 +# for i in holds_desig: +# if(str(i.designation)=='Dean (RSPC)'): +# flag_rspc = 1 + +# designation = serializers.HoldsDesignationSerializer(holds_desig,many=True).data + +# resp = {'user' : user_detail, +# 'profile' : extra_info, +# 'designation' : designation, +# 'pf' : pf, +# 'flag_rspc' : flag_rspc, +# 'journal' : journal, +# 'conference' : conference, +# 'books' : books, +# 'projects' : projects, +# 'consultancy' : consultancy, +# 'patents' : patents, +# 'techtransfers' : techtransfers, +# 'mtechs' : mtechs, +# 'phds' : phds, +# 'fvisits' : fvisits, +# 'ivisits' : ivisits, +# 'consymps' : consymps, +# 'awards' : awards, +# 'talks' : talks, +# 'chairs' : chairs, +# 'keynotes' : keynotes, +# 'events' : events, +# 'year_range' : year_range, +# 'faculty_about' : faculty_about +# } +# return Response(data=resp, status=status.HTTP_200_OK) + + +import csv +from html import escape +from io import BytesIO + +from django.contrib.auth.models import User +from django.http import FileResponse, HttpResponse, HttpResponseRedirect +from django.shortcuts import (get_object_or_404, redirect, render, + render) +from django.template import loader +from django.template.loader import get_template +from django.urls import reverse_lazy +from django.views import generic +from django.views.generic.edit import CreateView, DeleteView, UpdateView +from xhtml2pdf import pisa + +from .. import admin +from django.http import JsonResponse +from django.core.serializers import serialize +from ..forms import * +from ..models import * +from django.core.files.storage import FileSystemStorage +import logging +import json +from django.views.decorators.csrf import csrf_exempt +# import google.generativeai as genai +import os +# import pdfkit +import tempfile + +from reportlab.lib.pagesizes import letter +from reportlab.platypus import SimpleDocTemplate, Paragraph, Table, TableStyle, Spacer +from reportlab.lib.styles import getSampleStyleSheet +from reportlab.lib import colors +import os +import tempfile +from django.http import FileResponse, JsonResponse +from django.db.models import Q +import datetime -from applications.eis.models import * -from applications.eis.views import countries -from applications.globals.models import HoldsDesignation +countries = { + 'AF': 'Afghanistan', + 'AX': 'Aland Islands', + 'AL': 'Albania', + 'DZ': 'Algeria', + 'AS': 'American Samoa', + 'AD': 'Andorra', + 'AO': 'Angola', + 'AI': 'Anguilla', + 'AQ': 'Antarctica', + 'AG': 'Antigua And Barbuda', + 'AR': 'Argentina', + 'AM': 'Armenia', + 'AW': 'Aruba', + 'AU': 'Australia', + 'AT': 'Austria', + 'AZ': 'Azerbaijan', + 'BS': 'Bahamas', + 'BH': 'Bahrain', + 'BD': 'Bangladesh', + 'BB': 'Barbados', + 'BY': 'Belarus', + 'BE': 'Belgium', + 'BZ': 'Belize', + 'BJ': 'Benin', + 'BM': 'Bermuda', + 'BT': 'Bhutan', + 'BO': 'Bolivia', + 'BA': 'Bosnia And Herzegovina', + 'BW': 'Botswana', + 'BV': 'Bouvet Island', + 'BR': 'Brazil', + 'IO': 'British Indian Ocean Territory', + 'BN': 'Brunei Darussalam', + 'BG': 'Bulgaria', + 'BF': 'Burkina Faso', + 'BI': 'Burundi', + 'KH': 'Cambodia', + 'CM': 'Cameroon', + 'CA': 'Canada', + 'CV': 'Cape Verde', + 'KY': 'Cayman Islands', + 'CF': 'Central African Republic', + 'TD': 'Chad', + 'CL': 'Chile', + 'CN': 'China', + 'CX': 'Christmas Island', + 'CC': 'Cocos (Keeling) Islands', + 'CO': 'Colombia', + 'KM': 'Comoros', + 'CG': 'Congo', + 'CD': 'Congo, Democratic Republic', + 'CK': 'Cook Islands', + 'CR': 'Costa Rica', + 'CI': 'Cote D\'Ivoire', + 'HR': 'Croatia', + 'CU': 'Cuba', + 'CY': 'Cyprus', + 'CZ': 'Czech Republic', + 'DK': 'Denmark', + 'DJ': 'Djibouti', + 'DM': 'Dominica', + 'DO': 'Dominican Republic', + 'EC': 'Ecuador', + 'EG': 'Egypt', + 'SV': 'El Salvador', + 'GQ': 'Equatorial Guinea', + 'ER': 'Eritrea', + 'EE': 'Estonia', + 'ET': 'Ethiopia', + 'FK': 'Falkland Islands (Malvinas)', + 'FO': 'Faroe Islands', + 'FJ': 'Fiji', + 'FI': 'Finland', + 'FR': 'France', + 'GF': 'French Guiana', + 'PF': 'French Polynesia', + 'TF': 'French Southern Territories', + 'GA': 'Gabon', + 'GM': 'Gambia', + 'GE': 'Georgia', + 'DE': 'Germany', + 'GH': 'Ghana', + 'GI': 'Gibraltar', + 'GR': 'Greece', + 'GL': 'Greenland', + 'GD': 'Grenada', + 'GP': 'Guadeloupe', + 'GU': 'Guam', + 'GT': 'Guatemala', + 'GG': 'Guernsey', + 'GN': 'Guinea', + 'GW': 'Guinea-Bissau', + 'GY': 'Guyana', + 'HT': 'Haiti', + 'HM': 'Heard Island & Mcdonald Islands', + 'VA': 'Holy See (Vatican City State)', + 'HN': 'Honduras', + 'HK': 'Hong Kong', + 'HU': 'Hungary', + 'IS': 'Iceland', + 'IN': 'India', + 'ID': 'Indonesia', + 'IR': 'Iran, Islamic Republic Of', + 'IQ': 'Iraq', + 'IE': 'Ireland', + 'IM': 'Isle Of Man', + 'IL': 'Israel', + 'IT': 'Italy', + 'JM': 'Jamaica', + 'JP': 'Japan', + 'JE': 'Jersey', + 'JO': 'Jordan', + 'KZ': 'Kazakhstan', + 'KE': 'Kenya', + 'KI': 'Kiribati', + 'KR': 'Korea', + 'KW': 'Kuwait', + 'KG': 'Kyrgyzstan', + 'LA': 'Lao People\'s Democratic Republic', + 'LV': 'Latvia', + 'LB': 'Lebanon', + 'LS': 'Lesotho', + 'LR': 'Liberia', + 'LY': 'Libyan Arab Jamahiriya', + 'LI': 'Liechtenstein', + 'LT': 'Lithuania', + 'LU': 'Luxembourg', + 'MO': 'Macao', + 'MK': 'Macedonia', + 'MG': 'Madagascar', + 'MW': 'Malawi', + 'MY': 'Malaysia', + 'MV': 'Maldives', + 'ML': 'Mali', + 'MT': 'Malta', + 'MH': 'Marshall Islands', + 'MQ': 'Martinique', + 'MR': 'Mauritania', + 'MU': 'Mauritius', + 'YT': 'Mayotte', + 'MX': 'Mexico', + 'FM': 'Micronesia, Federated States Of', + 'MD': 'Moldova', + 'MC': 'Monaco', + 'MN': 'Mongolia', + 'ME': 'Montenegro', + 'MS': 'Montserrat', + 'MA': 'Morocco', + 'MZ': 'Mozambique', + 'MM': 'Myanmar', + 'NA': 'Namibia', + 'NR': 'Nauru', + 'NP': 'Nepal', + 'NL': 'Netherlands', + 'AN': 'Netherlands Antilles', + 'NC': 'New Caledonia', + 'NZ': 'New Zealand', + 'NI': 'Nicaragua', + 'NE': 'Niger', + 'NG': 'Nigeria', + 'NU': 'Niue', + 'NF': 'Norfolk Island', + 'MP': 'Northern Mariana Islands', + 'NO': 'Norway', + 'OM': 'Oman', + 'PK': 'Pakistan', + 'PW': 'Palau', + 'PS': 'Palestinian Territory, Occupied', + 'PA': 'Panama', + 'PG': 'Papua New Guinea', + 'PY': 'Paraguay', + 'PE': 'Peru', + 'PH': 'Philippines', + 'PN': 'Pitcairn', + 'PL': 'Poland', + 'PT': 'Portugal', + 'PR': 'Puerto Rico', + 'QA': 'Qatar', + 'RE': 'Reunion', + 'RO': 'Romania', + 'RU': 'Russian Federation', + 'RW': 'Rwanda', + 'BL': 'Saint Barthelemy', + 'SH': 'Saint Helena', + 'KN': 'Saint Kitts And Nevis', + 'LC': 'Saint Lucia', + 'MF': 'Saint Martin', + 'PM': 'Saint Pierre And Miquelon', + 'VC': 'Saint Vincent And Grenadines', + 'WS': 'Samoa', + 'SM': 'San Marino', + 'ST': 'Sao Tome And Principe', + 'SA': 'Saudi Arabia', + 'SN': 'Senegal', + 'RS': 'Serbia', + 'SC': 'Seychelles', + 'SL': 'Sierra Leone', + 'SG': 'Singapore', + 'SK': 'Slovakia', + 'SI': 'Slovenia', + 'SB': 'Solomon Islands', + 'SO': 'Somalia', + 'ZA': 'South Africa', + 'GS': 'South Georgia And Sandwich Isl.', + 'ES': 'Spain', + 'LK': 'Sri Lanka', + 'SD': 'Sudan', + 'SR': 'Suriname', + 'SJ': 'Svalbard And Jan Mayen', + 'SZ': 'Swaziland', + 'SE': 'Sweden', + 'CH': 'Switzerland', + 'SY': 'Syrian Arab Republic', + 'TW': 'Taiwan', + 'TJ': 'Tajikistan', + 'TZ': 'Tanzania', + 'TH': 'Thailand', + 'TL': 'Timor-Leste', + 'TG': 'Togo', + 'TK': 'Tokelau', + 'TO': 'Tonga', + 'TT': 'Trinidad And Tobago', + 'TN': 'Tunisia', + 'TR': 'Turkey', + 'TM': 'Turkmenistan', + 'TC': 'Turks And Caicos Islands', + 'TV': 'Tuvalu', + 'UG': 'Uganda', + 'UA': 'Ukraine', + 'AE': 'United Arab Emirates', + 'GB': 'United Kingdom', + 'US': 'United States', + 'UM': 'United States Outlying Islands', + 'UY': 'Uruguay', + 'UZ': 'Uzbekistan', + 'VU': 'Vanuatu', + 'VE': 'Venezuela', + 'VN': 'Viet Nam', + 'VG': 'Virgin Islands, British', + 'VI': 'Virgin Islands, U.S.', + 'WF': 'Wallis And Futuna', + 'EH': 'Western Sahara', + 'YE': 'Yemen', + 'ZM': 'Zambia', + 'ZW': 'Zimbabwe', + 'KP': 'Korea (Democratic Peoples Republic of)', + } + +# Create your views here + +def index(request): + return HttpResponse("Hello, world. You're at the FPF index.") + +def view_all_extra_infos(request): + + # Retrieve all ExtraInfo objects + """ + View to retrieve all ExtraInfo objects, and return them as a JSON response. -from . import serializers + The response will contain a list of dictionaries, each containing the following + information about an ExtraInfo object: + - id: The ID of the ExtraInfo object + - user: The username of the User object associated with the ExtraInfo + - title: The title of the ExtraInfo object + - sex: The sex of the ExtraInfo object + - date_of_birth: The date of birth of the ExtraInfo object as a string + - user_status: The status of the ExtraInfo object + - address: The address of the ExtraInfo object + - phone_no: The phone number of the ExtraInfo object + - user_type: The type of the ExtraInfo object + - department: The name of the DepartmentInfo object associated with the ExtraInfo + - profile_picture: The URL of the profile picture of the ExtraInfo object + - about_me: The about me of the ExtraInfo object + - date_modified: The date modified of the ExtraInfo object as a string + - age: The age of the ExtraInfo object -User = get_user_model() + The response will be a JSON object with a single key, 'extra_info_list', which + contains the list of dictionaries. + """ -@api_view(['GET']) + extra_infos = ExtraInfo.objects.all() + + # Serialize the queryset into a list of dictionaries + extra_info_list = [ + { + 'id': info.id, + 'user': info.user.username, + 'title': info.title, + 'sex': info.sex, + 'date_of_birth': info.date_of_birth.isoformat(), # Convert date to string + 'user_status': info.user_status, + 'address': info.address, + 'phone_no': info.phone_no, + 'user_type': info.user_type, + 'department': info.department.name if info.department else None, # Assuming DepartmentInfo has a name field + 'profile_picture': info.profile_picture.url if info.profile_picture else None, + 'about_me': info.about_me, + 'date_modified': info.date_modified.isoformat() if info.date_modified else None, + 'age': info.age # Custom property to get the user's age + } + for info in extra_infos + ] + + # Return the data as a JSON response + return JsonResponse(extra_info_list, safe=False) + +# Main profile landing view +@csrf_exempt def profile(request, username=None): - user = get_object_or_404(User, username=username) if username else request.user - user_detail = serializers.UserSerializer(user).data - extra_info = serializers.ExtraInfoSerializer(user.extrainfo).data - if extra_info['user_type'] != 'faculty': - return Response(data={'message':'Not faculty'}, status=status.HTTP_400_BAD_REQUEST) - - pf = extra_info['id'] - journal = serializers.EmpResearchPapersSerializer(emp_research_papers.objects.filter(pf_no=pf, rtype='Journal').order_by('-year'),many=True).data - conference = serializers.EmpResearchPapersSerializer(emp_research_papers.objects.filter(pf_no=pf, rtype='Conference').order_by('-year'),many=True).data - books = serializers.EmpPublishedBooksSerializer(emp_published_books.objects.filter(pf_no=pf).order_by('-pyear'),many=True).data - projects = serializers.EmpResearchProjectsSerializer(emp_research_projects.objects.filter(pf_no=pf).order_by('-start_date'),many=True).data - consultancy = serializers.EmpConsultancyProjectsSerializer(emp_consultancy_projects.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data - patents = serializers.EmpPatentsSerializer(emp_patents.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data - techtransfers = serializers.EmpTechTransferSerializer(emp_techtransfer.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data - mtechs = serializers.EmpMtechPhdThesisSerializer(emp_mtechphd_thesis.objects.filter(pf_no=pf, degree_type=1).order_by('-date_entry'),many=True).data - phds = serializers.EmpMtechPhdThesisSerializer(emp_mtechphd_thesis.objects.filter(pf_no=pf, degree_type=2).order_by('-date_entry'),many=True).data - fvisits = serializers.EmpVisitsSerializer(emp_visits.objects.filter(pf_no=pf, v_type=2).order_by('-entry_date'),many=True).data - ivisits = serializers.EmpVisitsSerializer(emp_visits.objects.filter(pf_no=pf, v_type=1).order_by('-entry_date'),many=True).data - for fvisit in fvisits: - fvisit['countryfull'] = countries[fvisit['country']] - consymps = serializers.EmpConfrenceOrganisedSerializer(emp_confrence_organised.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data - awards = serializers.EmpAchievementSerializer(emp_achievement.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data - talks = serializers.EmpExpertLecturesSerializer(emp_expert_lectures.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data - chairs = serializers.EmpSessionChairSerializer(emp_session_chair.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data - keynotes = serializers.EmpKeynoteAddressSerializer(emp_keynote_address.objects.filter(pf_no=pf).order_by('-date_entry'),many=True).data - events = serializers.EmpEventOrganizedSerializer(emp_event_organized.objects.filter(pf_no=pf).order_by('-start_date'),many=True).data - year_range = [] - for r in range(1995, (datetime.datetime.now().year + 1)): - year_range.append(r) + + """ + Main profile landing view that retrieves and returns detailed information + about a faculty member based on their username. The information includes + personal data, research activities, project management records, and designation + details. + + Args: + request (HttpRequest): The request object. + username (str, optional): The username of the faculty member. Defaults to None. + + Returns: + JsonResponse: A JSON response containing user information, research data, + project details, personal information, and designations. + """ + + if request.method == 'POST': + user = get_object_or_404(User, username=request.POST.get('username')) + else: + if username: + pass + else: + user = get_object_or_404(User, username=request.GET.get('username')) + + extra_info = get_object_or_404(ExtraInfo, user=user) + + pf = extra_info.user_id + + # Forms and project management data + project_r = Project_Registration.objects.filter(PI_id=pf).order_by('PI_id__user') + project_ext = Project_Extension.objects.filter(project_id__PI_id=pf).order_by('project_id__PI_id__user') + project_closure = Project_Closure.objects.filter(project_id__PI_id=pf).order_by('project_id__PI_id__user') + project_reall = Project_Reallocation.objects.filter(project_id__PI_id=pf).order_by('project_id__PI_id__user') + + # Research data + journal = emp_research_papers.objects.filter(pf_no=pf, rtype='Journal').order_by('-year') + conference = emp_research_papers.objects.filter(pf_no=pf, rtype='Conference').order_by('-year') + books = emp_published_books.objects.filter(pf_no=pf).order_by('-pyear') + projects = emp_research_projects.objects.filter(pf_no=pf).order_by('-start_date') + consultancy = emp_consultancy_projects.objects.filter(pf_no=pf).order_by('-date_entry') + patents = emp_patents.objects.filter(pf_no=pf).order_by('-date_entry') + techtransfers = emp_techtransfer.objects.filter(pf_no=pf).order_by('-date_entry') + mtechs = emp_mtechphd_thesis.objects.filter(pf_no=pf, degree_type=1).order_by('-date_entry') + phds = emp_mtechphd_thesis.objects.filter(pf_no=pf, degree_type=2).order_by('-date_entry') + fvisits = emp_visits.objects.filter(pf_no=pf, v_type=2).order_by('-entry_date') + ivisits = emp_visits.objects.filter(pf_no=pf, v_type=1).order_by('-entry_date') + consymps = emp_confrence_organised.objects.filter(pf_no=pf).order_by('-date_entry') + awards = emp_achievement.objects.filter(pf_no=pf).order_by('-date_entry') + talks = emp_expert_lectures.objects.filter(pf_no=pf).order_by('-date_entry') + chairs = emp_session_chair.objects.filter(pf_no=pf).order_by('-date_entry') + keynotes = emp_keynote_address.objects.filter(pf_no=pf).order_by('-date_entry') + events = emp_event_organized.objects.filter(pf_no=pf).order_by('-start_date') + + # Get year range + y = list(range(1995, datetime.datetime.now().year + 1)) + + # Personal information try: - faculty_about = serializers.FacultyAboutSerializer(user.faculty_about).data + pers = get_object_or_404(faculty_about, user_id=pf) except: - faculty_about = None + pers = None - holds_desig = user.current_designation.all() + # Designations + a1 = HoldsDesignation.objects.select_related('user', 'working', 'designation').filter(working=user) flag_rspc = 0 - for i in holds_desig: - if(str(i.designation)=='Dean (RSPC)'): + for i in a1: + if str(i.designation) == 'Dean (RSPC)': flag_rspc = 1 - designation = serializers.HoldsDesignationSerializer(holds_desig,many=True).data - - resp = {'user' : user_detail, - 'profile' : extra_info, - 'designation' : designation, - 'pf' : pf, - 'flag_rspc' : flag_rspc, - 'journal' : journal, - 'conference' : conference, - 'books' : books, - 'projects' : projects, - 'consultancy' : consultancy, - 'patents' : patents, - 'techtransfers' : techtransfers, - 'mtechs' : mtechs, - 'phds' : phds, - 'fvisits' : fvisits, - 'ivisits' : ivisits, - 'consymps' : consymps, - 'awards' : awards, - 'talks' : talks, - 'chairs' : chairs, - 'keynotes' : keynotes, - 'events' : events, - 'year_range' : year_range, - 'faculty_about' : faculty_about + designations = [str(i.designation) for i in a1] + + # Prepare data to be returned in JSON format + data = { + 'user': { + 'username': user.username, + 'email': user.email, + }, + 'designations': designations, + 'pf': pf, + 'flag_rspc': flag_rspc, + 'research': { + 'journal': list(journal.values()), # Convert queryset to list of dictionaries + 'conference': list(conference.values()), + 'books': list(books.values()), + 'projects': list(projects.values()), + 'consultancy': list(consultancy.values()), + 'patents': list(patents.values()), + 'techtransfers': list(techtransfers.values()), + 'mtechs': list(mtechs.values()), + 'phds': list(phds.values()), + 'fvisits': list(fvisits.values()), + 'ivisits': list(ivisits.values()), + 'consymps': list(consymps.values()), + 'awards': list(awards.values()), + 'talks': list(talks.values()), + 'chairs': list(chairs.values()), + 'keynotes': list(keynotes.values()), + 'events': list(events.values()), + }, + 'year_range': y, + 'personal_info': { + 'faculty_about': pers.about if pers else None, + 'date_of_joining': pers.doj if pers else None, + 'contact': pers.contact if pers else None, + 'interest': pers.interest if pers else None, + 'education': pers.education if pers else None, + 'linkedin': pers.linkedin if pers else None, + 'github': pers.github if pers else None + }, + 'projects': { + 'registrations': list(project_r.values()), + 'extensions': list(project_ext.values()), + 'closures': list(project_closure.values()), + 'reallocations': list(project_reall.values()), + }, + } + + # Return data as JSON response + return JsonResponse(data, safe=False) + +# @csrf_exempt +# def generate_report(request, username=None): + +# """Generate a PDF report for a given faculty member based on their research data and personal information. + +# Args: +# request (HttpRequest): The request object. +# username (str): The username of the faculty member. + +# Returns: +# HttpResponse: The PDF report as a response.""" + +# if request.method == 'POST': +# user = get_object_or_404(User, username=request.POST.get('username')) +# else: +# return JsonResponse({'error': 'Only POST method is allowed.'}, status=405) + +# extra_info = get_object_or_404(ExtraInfo, user=user) + +# pf = extra_info.user_id + +# # Forms and project management data +# project_r = Project_Registration.objects.filter(PI_id=pf).order_by('PI_id__user') +# project_ext = Project_Extension.objects.filter(project_id__PI_id=pf).order_by('project_id__PI_id__user') +# project_closure = Project_Closure.objects.filter(project_id__PI_id=pf).order_by('project_id__PI_id__user') +# project_reall = Project_Reallocation.objects.filter(project_id__PI_id=pf).order_by('project_id__PI_id__user') + +# # Research data +# journal = emp_research_papers.objects.filter(pf_no=pf, rtype='Journal').order_by('-year') +# conference = emp_research_papers.objects.filter(pf_no=pf, rtype='Conference').order_by('-year') +# books = emp_published_books.objects.filter(pf_no=pf).order_by('-pyear') +# projects = emp_research_projects.objects.filter(pf_no=pf).order_by('-start_date') +# consultancy = emp_consultancy_projects.objects.filter(pf_no=pf).order_by('-date_entry') +# patents = emp_patents.objects.filter(pf_no=pf).order_by('-date_entry') +# techtransfers = emp_techtransfer.objects.filter(pf_no=pf).order_by('-date_entry') +# mtechs = emp_mtechphd_thesis.objects.filter(pf_no=pf, degree_type=1).order_by('-date_entry') +# phds = emp_mtechphd_thesis.objects.filter(pf_no=pf, degree_type=2).order_by('-date_entry') +# fvisits = emp_visits.objects.filter(pf_no=pf, v_type=2).order_by('-entry_date') +# ivisits = emp_visits.objects.filter(pf_no=pf, v_type=1).order_by('-entry_date') +# consymps = emp_confrence_organised.objects.filter(pf_no=pf).order_by('-date_entry') +# awards = emp_achievement.objects.filter(pf_no=pf).order_by('-date_entry') +# talks = emp_expert_lectures.objects.filter(pf_no=pf).order_by('-date_entry') +# chairs = emp_session_chair.objects.filter(pf_no=pf).order_by('-date_entry') +# keynotes = emp_keynote_address.objects.filter(pf_no=pf).order_by('-date_entry') +# events = emp_event_organized.objects.filter(pf_no=pf).order_by('-start_date') + +# # Get year range +# y = list(range(1995, datetime.datetime.now().year + 1)) + +# # Personal information +# try: +# pers = get_object_or_404(faculty_about, user_id=pf) +# except: +# pers = None + +# # Designations +# a1 = HoldsDesignation.objects.select_related('user', 'working', 'designation').filter(working=user) +# flag_rspc = 0 +# for i in a1: +# if str(i.designation) == 'Dean (RSPC)': +# flag_rspc = 1 + +# designations = [str(i.designation) for i in a1] + +# data = { +# 'user': { +# 'username': user.username, +# 'email': user.email, +# }, +# 'designations': designations, +# 'pf': pf, +# 'flag_rspc': flag_rspc, +# 'research': { +# 'journal': list(journal.values()), # Convert queryset to list of dictionaries +# 'conference': list(conference.values()), +# 'books': list(books.values()), +# 'projects': list(projects.values()), +# 'consultancy': list(consultancy.values()), +# 'patents': list(patents.values()), +# 'techtransfers': list(techtransfers.values()), +# 'mtechs': list(mtechs.values()), +# 'phds': list(phds.values()), +# 'fvisits': list(fvisits.values()), +# 'ivisits': list(ivisits.values()), +# 'consymps': list(consymps.values()), +# 'awards': list(awards.values()), +# 'talks': list(talks.values()), +# 'chairs': list(chairs.values()), +# 'keynotes': list(keynotes.values()), +# 'events': list(events.values()), +# }, +# 'year_range': y, +# 'personal_info': { +# 'faculty_about': pers.about if pers else None, +# 'date_of_joining': pers.doj if pers else None, +# 'contact': pers.contact if pers else None, +# 'interest': pers.interest if pers else None, +# 'education': pers.education if pers else None, +# 'linkedin': pers.linkedin if pers else None, +# 'github': pers.github if pers else None +# }, +# 'projects': { +# 'registrations': list(project_r.values()), +# 'extensions': list(project_ext.values()), +# 'closures': list(project_closure.values()), +# 'reallocations': list(project_reall.values()), +# }, +# } + +# # Generate HTML content using Gemini API +# model = genai.GenerativeModel("gemini-1.5-flash") +# json_input = f"Generate an HTML report for the following data: {data}" +# response = model.generate_content(json_input) +# html_content = response.text.strip("```html").strip("```") + +# # Convert HTML to PDF +# with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp_pdf: +# pdfkit.from_string(html_content, temp_pdf.name) +# temp_pdf.seek(0) +# pdf_file_path = temp_pdf.name + +# # Send the PDF as a response +# return FileResponse(open(pdf_file_path, 'rb'), content_type='application/pdf', as_attachment=True, filename="report.pdf") + + + +@csrf_exempt +def generate_report(request, username=None): + """Generate a PDF report for a given faculty member based on their research data and personal information. + + Args: + request (HttpRequest): The request object. + username (str): The username of the faculty member. + + Returns: + HttpResponse: The PDF report as a response. + """ + if request.method != 'POST': + return JsonResponse({'error': 'Only POST method is allowed.'}, status=405) + + user = get_object_or_404(User, username=request.POST.get('username')) + extra_info = get_object_or_404(ExtraInfo, user=user) + pf = extra_info.user_id + extra_info = get_object_or_404(faculty_about, user_id=pf) + + # Fetch data + research_data = { + 'Journal Publications': emp_research_papers.objects.filter(pf_no=pf, rtype='Journal').order_by('-year'), + 'Conference Publications': emp_research_papers.objects.filter(pf_no=pf, rtype='Conference').order_by('-year'), + 'Books Published': emp_published_books.objects.filter(pf_no=pf).order_by('-pyear'), + 'Research Projects': emp_research_projects.objects.filter(pf_no=pf).order_by('-start_date'), + 'Consultancy Projects': emp_consultancy_projects.objects.filter(pf_no=pf).order_by('-date_entry'), + 'Patents': emp_patents.objects.filter(pf_no=pf).order_by('-date_entry'), + 'Technical Transfers': emp_techtransfer.objects.filter(pf_no=pf).order_by('-date_entry'), + 'Awards': emp_achievement.objects.filter(pf_no=pf).order_by('-date_entry'), + } + + personal_info = { + 'About': extra_info.about if hasattr(extra_info, 'about') else "N/A", + 'Date of Joining': extra_info.doj if hasattr(extra_info, 'doj') else "N/A", + 'Contact': extra_info.contact if hasattr(extra_info, 'contact') else "N/A", } - return Response(data=resp, status=status.HTTP_200_OK) + + # Create PDF using ReportLab + with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp_pdf: + pdf_file_path = temp_pdf.name + + doc = SimpleDocTemplate(pdf_file_path, pagesize=letter) + styles = getSampleStyleSheet() + elements = [] + + # Title + title = Paragraph(f"Report for {user.username}", styles['Title']) + elements.append(title) + elements.append(Spacer(1, 12)) + + # Personal Information + elements.append(Paragraph("Personal Information", styles['Heading2'])) + for key, value in personal_info.items(): + elements.append(Paragraph(f"{key}: {value}", styles['Normal'])) + elements.append(Spacer(1, 12)) + + # Research Data + elements.append(Paragraph("Research Information", styles['Heading2'])) + for section, items in research_data.items(): + elements.append(Paragraph(f"{section}", styles['Heading3'])) + if items.exists(): + data = [[f"{field.name}" for field in items.model._meta.fields]] # Add table headers + for item in items: + data.append([getattr(item, field.name, '') for field in items.model._meta.fields]) + table = Table(data, repeatRows=1) + table.setStyle(TableStyle([ + ('BACKGROUND', (0, 0), (-1, 0), colors.grey), + ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), + ('ALIGN', (0, 0), (-1, -1), 'LEFT'), + ('GRID', (0, 0), (-1, -1), 0.5, colors.black) + ])) + elements.append(table) + else: + elements.append(Paragraph("No data available.", styles['Normal'])) + elements.append(Spacer(1, 12)) + + # Build PDF + doc.build(elements) + + # Serve the file + return FileResponse(open(pdf_file_path, 'rb'), content_type='application/pdf', as_attachment=True, filename="report.pdf") + + +# Dean RSPC Profile +@csrf_exempt +def rspc_profile(request): + """ + Return a JSON response with the research data and personal information of the + Dean RSPC profile. + + The research data includes the following elements: + + - Journal and conference papers + - Books + - Projects + - Consultancy projects + - Patents + - Technology transfers + - M.Tech and Ph.D theses supervised + - Foreign and Indian visits + - Conferences organized + - Awards received + - Talks given + - Sessions chaired + - Keynote addresses given + - Events organized + + The personal information includes the following: + + - Faculty about + - Date of joining + - Contact information + - Interests + - Education + - LinkedIn profile + - GitHub profile + + The year range is also included in the response. + + The response is sent as a JSON object with the following keys: + + - user: a dictionary with the username and email of the user + - desig: a list of strings representing the designations of the user + - pf: the pf number of the user + - research: a dictionary with the research data + - year_range: a list of integers representing the year range + - personal_info: a dictionary with the personal information of the user + + The research data is organized as follows: + + - Journal and conference papers are organized by year and month + - Books are organized by year and authors + - Projects are organized by start date + - Consultancy projects are organized by start date + - Patents are organized by year and month + - Technology transfers are organized by date entry + - M.Tech and Ph.D theses are organized by year and month + - Foreign and Indian visits are organized by start date + - Conferences organized are organized by start date + - Awards are organized by year and month + - Talks are organized by year and month + - Sessions chaired are organized by start date + - Keynote addresses are organized by start date + - Events organized are organized by start date + + The personal information is organized as follows: + + - Faculty about is a string + - Date of joining is a date + - Contact information is a string + - Interests is a string + - Education is a string + - LinkedIn profile is a string + - GitHub profile is a string + + The year range is a list of integers representing the year range. + """ + + if request.method == 'POST': + user = get_object_or_404(faculty_about, user=request.user) + pf = user.user + + # Retrieve data for various research elements + journal = emp_research_papers.objects.filter(rtype='Journal').order_by('-year', '-a_month') + conference = emp_research_papers.objects.filter(rtype='Conference').order_by('-year', '-a_month') + books = emp_published_books.objects.all().order_by('-pyear', '-authors') + projects = emp_research_projects.objects.all().order_by('-start_date') + consultancy = emp_consultancy_projects.objects.all().order_by('-start_date') + patents = emp_patents.objects.all().order_by('-p_year', '-a_month') + techtransfers = emp_techtransfer.objects.all().order_by('-date_entry') + mtechs = emp_mtechphd_thesis.objects.filter(degree_type=1).order_by('-s_year', '-a_month') + phds = emp_mtechphd_thesis.objects.filter(degree_type=2).order_by('-s_year', '-a_month') + fvisits = emp_visits.objects.filter(v_type=2).order_by('-start_date') + ivisits = emp_visits.objects.filter(v_type=1).order_by('-start_date') + + # Add countryfull to foreign visits + for fvisit in fvisits: + fvisit.countryfull = countries[fvisit.country] # assuming `countries` is a valid dictionary + + consymps = emp_confrence_organised.objects.all().order_by('-start_date') + awards = emp_achievement.objects.all().order_by('-a_year', '-a_month') + talks = emp_expert_lectures.objects.all().order_by('-l_year', '-a_month') + chairs = emp_session_chair.objects.all().order_by('-start_date') + keynotes = emp_keynote_address.objects.all().order_by('-start_date') + events = emp_event_organized.objects.all().order_by('-start_date') + + # Get year range + y = list(range(1995, datetime.datetime.now().year + 1)) + + # Get personal info + pers = get_object_or_404(faculty_about, user=request.user) + + # Designation + design = HoldsDesignation.objects.select_related('user', 'working', 'designation').filter(working=request.user) + desig = [str(i.designation) for i in design] + + # Prepare data to be returned in JSON format + data = { + 'user': { + 'username': user.username, # Assuming `user` has a `username` attribute + 'email': user.email, # Assuming `user` has an `email` attribute + }, + 'desig': desig, + 'pf': pf, + 'research': { + 'journal': list(journal.values()), # Converting QuerySets to a list of dictionaries + 'conference': list(conference.values()), + 'books': list(books.values()), + 'projects': list(projects.values()), + 'consultancy': list(consultancy.values()), + 'patents': list(patents.values()), + 'techtransfers': list(techtransfers.values()), + 'mtechs': list(mtechs.values()), + 'phds': list(phds.values()), + 'fvisits': list(fvisits.values('country', 'countryfull', 'start_date')), # Example fields + 'ivisits': list(ivisits.values('country', 'start_date')), + 'consymps': list(consymps.values()), + 'awards': list(awards.values()), + 'talks': list(talks.values()), + 'chairs': list(chairs.values()), + 'keynotes': list(keynotes.values()), + 'events': list(events.values()), + }, + 'year_range': y, + 'personal_info': { + 'faculty_about': pers.details if pers else None # Assuming `details` field exists + } + } + + # Return data as JSON response + return JsonResponse(data, safe=False) + else: + return JsonResponse({"x" : "You are not authorized to hit this URL", "status" : 400}) + +# View for editing persnal Information +@csrf_exempt +def persinfo(request): + """ + Update the personal information of a faculty member. + + This view handles POST requests to update various fields of the faculty + member's profile, including contact information, about section, interests, + education, and social media links. + + Args: + request (HttpRequest): The request object containing user data. + + Returns: + JsonResponse: A JSON response indicating the success or failure of the + update operation. A successful update returns a message confirming the + data update, while an unauthorized attempt returns an error message. + """ + if request.method == 'POST': + try: + faculty = get_object_or_404(faculty_about, user_id = request.POST.get('user_id')) + contact = request.POST['contact'] + faculty.contact = contact + faculty.about = request.POST['about'] + faculty.interest = request.POST['interest'] + faculty.education = request.POST['education'] + + faculty.linkedin = request.POST['linkedin'] + faculty.github = request.POST['github'] + + faculty.save() + return JsonResponse({'x' : 'Your data is updated '}) + except: + return JsonResponse({'x' : 'You are not authorized to update '}) + + +@csrf_exempt +def update_personal_info(request): + if request.method == "POST": + try: + data = json.loads(request.body) + user_id = data.get("user_id") + + # Fetch the faculty_about entry + faculty = faculty_about.objects.get(user_id=user_id) + + # Update fields + faculty.about = data.get("aboutMe", faculty.about) + faculty.doj = data.get("dateOfJoining", faculty.doj) + faculty.education = data.get("education", faculty.education) + faculty.interest = data.get("interestAreas", faculty.interest) + faculty.contact = data.get("contact", faculty.contact) + faculty.github = data.get("github", faculty.github) + faculty.linkedin = data.get("linkedIn", faculty.linkedin) + + faculty.save() + + return JsonResponse({"message": "Details updated successfully."}, status=200) + except faculty_about.DoesNotExist: + return JsonResponse({"error": "Faculty not found."}, status=404) + except Exception as e: + return JsonResponse({"error": str(e)}, status=400) + return JsonResponse({"error": "Invalid request method."}, status=405) + + +# Views for deleting the EIS fields +@csrf_exempt +def achievementDelete(request): + """ + Delete an achievement entry from the database. + + This view handles POST requests to delete a specific achievement + identified by its primary key ('pk') sent in the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the achievement to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success or failure of + the delete operation. If successful, returns a success message. If the + achievement is not found, returns an error message. If the request + method is not POST, returns an invalid request method error. + """ + if request.method == 'POST': + try: + instance = emp_achievement.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}, status=200) + except emp_achievement.DoesNotExist: + return JsonResponse({'success': False, 'error': 'Achievement not found.'}, status=404) + else: + return JsonResponse({'success': False, 'error': 'Invalid request method.'}, status=400) + +@csrf_exempt +def emp_confrence_organisedDelete(request): + """ + Delete an emp_confrence_organised entry from the database. + + This view handles POST requests to delete a specific + emp_confrence_organised identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_confrence_organised to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_confrence_organised is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_confrence_organised.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_consymDelete(request): + """ + Delete an emp_consym entry from the database. + + This view handles POST requests to delete a specific + emp_consym identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_consym to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_consym is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_confrence_organised.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_consultancy_projectsDelete(request): + """ + Delete an emp_consultancy_projects entry from the database. + + This view handles POST requests to delete a specific + emp_consultancy_projects identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_consultancy_projects to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_consultancy_projects is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_consultancy_projects.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_event_organizedDelete(request): + """ + Delete an emp_event_organized entry from the database. + + This view handles POST requests to delete a specific + emp_event_organized identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_event_organized to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_event_organized is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_event_organized.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_expert_lecturesDelete(request): + """ + Delete an emp_expert_lectures entry from the database. + + This view handles POST requests to delete a specific + emp_expert_lectures identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_expert_lectures to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_expert_lectures is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_expert_lectures.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_keynote_addressDelete(request): + """ + Delete an emp_keynote_address entry from the database. + + This view handles POST requests to delete a specific + emp_keynote_address identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_keynote_address to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_keynote_address is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_keynote_address.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_mtechphd_thesisDelete(request): + """ + Delete an emp_mtechphd_thesis entry from the database. + + This view handles POST requests to delete a specific + emp_mtechphd_thesis identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_mtechphd_thesis to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_mtechphd_thesis is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_mtechphd_thesis.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_patentsDelete(request): + """ + Delete an emp_patents entry from the database. + + This view handles POST requests to delete a specific + emp_patents identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_patents to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_patents is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_patents.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_published_booksDelete(request): + """ + Delete an emp_published_books entry from the database. + + This view handles POST requests to delete a specific + emp_published_books identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_published_books to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_published_books is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_published_books.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_research_papersDelete(request): + """ + Delete an emp_research_papers entry from the database. + + This view handles POST requests to delete a specific + emp_research_papers identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_research_papers to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_research_papers is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_research_papers.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_research_projectsDelete(request): + """ + Delete an emp_research_projects entry from the database. + + This view handles POST requests to delete a specific + emp_research_projects identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_research_projects to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_research_projects is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_research_projects.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_session_chairDelete(request): + """ + Delete an emp_session_chair entry from the database. + + This view handles POST requests to delete a specific + emp_session_chair identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_session_chair to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_session_chair is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_session_chair.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_journal_delete(request): + instance = emp_research_papers.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_techtransferDelete(request): + """ + Delete an emp_techtransfer entry from the database. + + This view handles POST requests to delete a specific + emp_techtransfer identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_techtransfer to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_techtransfer is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_techtransfer.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + +@csrf_exempt +def emp_visitsDelete(request): + """ + Delete an emp_visits entry from the database. + + This view handles POST requests to delete a specific + emp_visits identified by its primary key ('pk') sent in + the request data. + + Args: + request (HttpRequest): The request object containing the primary key + of the emp_visits to be deleted. + + Returns: + JsonResponse: A JSON response indicating the success of the delete + operation. If successful, returns a success message. If the + emp_visits is not found, returns an error message. If the + request method is not POST, returns an invalid request method error. + """ + instance = emp_visits.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + + +# Views for inserting fields in EIS +@csrf_exempt +def pg_insert(request): + """ + Insert a new or update an existing Post Graduate student entry in the emp_mtechphd_thesis table. + + This view handles POST requests to insert a new or update an existing + Post Graduate student entry in the emp_mtechphd_thesis table. The + request data should contain the primary key ('user_id') of the faculty + about, the primary key ('pg_id') of the emp_mtechphd_thesis entry to be + updated, the title of the thesis, the starting year, the month of + completion, the supervisors, the roll number and the name of the student. + + If the 'pg_id' is not provided, a new emp_mtechphd_thesis entry is + created. Otherwise, the existing entry is updated. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty about and the details of the Post Graduate student entry + to be inserted or updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or + update operation. If successful, returns a success message. If the + request method is not POST, returns an invalid request method error. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + + if (request.POST.get('pg_id')==None or request.POST.get('pg_id')==""): + eis = emp_mtechphd_thesis() + else: + eis = get_object_or_404(emp_mtechphd_thesis, id=request.POST.get('pg_id')) + + eis.pf_no = pf + eis.title = request.POST.get('title') + eis.s_year = request.POST.get('s_year') + eis.a_month = request.POST.get('month') + eis.supervisors = request.POST.get('supervisors') + eis.rollno = request.POST.get('roll') + eis.s_name = request.POST.get('name') + + eis.save() + return JsonResponse({'success': True}) + +@csrf_exempt +def phd_insert(request): + """ + Insert a new or update an existing PhD student entry in the emp_mtechphd_thesis table. + + This view handles POST requests to insert a new or update an existing + PhD student entry in the emp_mtechphd_thesis table. The request data + should contain the primary key ('user_id') of the faculty about, the + primary key ('phd_id') of the emp_mtechphd_thesis entry to be updated, + the title of the thesis, the starting year, the month of completion, + the supervisors, the roll number, and the name of the student. + + If the 'phd_id' is not provided, a new emp_mtechphd_thesis entry is + created. Otherwise, the existing entry is updated. The 'degree_type' is + set to 2 for PhD entries. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty about and the details of the PhD student entry to be + inserted or updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or + update operation. If successful, returns a success message. If the + request method is not POST, returns an invalid request method error. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + + if (request.POST.get('phd_id')==None or request.POST.get('phd_id')==""): + eis = emp_mtechphd_thesis() + else: + eis = get_object_or_404(emp_mtechphd_thesis, id=request.POST.get('phd_id')) + + eis.pf_no = pf + eis.degree_type = 2 + eis.title = request.POST.get('title') + eis.s_year = request.POST.get('s_year') + eis.a_month = request.POST.get('month') + eis.supervisors = request.POST.get('supervisors') + eis.rollno = request.POST.get('roll') + eis.s_name = request.POST.get('name') + + eis.save() + return JsonResponse({'success': True}) + +@csrf_exempt +def fvisit_insert(request): + """ + Insert a new or update an existing foreign visit entry in the emp_visits table. + + This view handles POST requests to insert a new or update an existing + foreign visit entry in the emp_visits table. The request data + should contain the primary key ('user_id') of the faculty about, the + primary key ('fvisit_id') of the emp_visits entry to be updated, the + country of visit, the place of visit, the purpose of visit, the + start date and end date of visit. + + If the 'fvisit_id' is not provided, a new emp_visits entry is + created. Otherwise, the existing entry is updated. The 'v_type' is + set to 2 for foreign visit entries. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty about and the details of the foreign visit entry to be + inserted or updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or + update operation. If successful, returns a success message. If the + request method is not POST, returns an invalid request method error. + """ + if request.method=='POST': + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + + if (request.POST.get('fvisit_id')==None or request.POST.get('fvisit_id')==""): + eis = emp_visits() + else: + eis = get_object_or_404(emp_visits, id=request.POST.get('fvisit_id')) + + eis.pf_no = pf + eis.v_type = 2 + eis.country = request.POST.get('country').upper() + eis.place = request.POST.get('place') + eis.purpose = request.POST.get('purpose') + + # x = request.POST.get('start_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.start_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.start_date = request.POST.get('start_date') + + # x = request.POST.get('end_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.end_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.end_date = request.POST.get('end_date') + + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + +@csrf_exempt +def ivisit_insert(request): + """ + API endpoint to insert or update a research data entry of type 'International Visit' in the database. + + Parameters: + request (HttpRequest): The POST request containing the data to be inserted or updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or update operation. If successful, returns a success message. If the request method is not POST, returns an invalid request method error. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + + if (request.POST.get('ivisit_id')==None or request.POST.get('ivisit_id')==""): + eis = emp_visits() + else: + eis = get_object_or_404(emp_visits, id=request.POST.get('ivisit_id')) + + eis.pf_no = pf + eis.v_type = 1 + eis.country = "India" + eis.place = request.POST.get('place') + eis.purpose = request.POST.get('purpose') + + # x = request.POST.get('start_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.start_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.start_date = request.POST.get('start_date') + + # x = request.POST.get('end_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.end_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.end_date = request.POST.get('end_date') + + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + + +#Function to save journal of employee +@csrf_exempt +def journal_insert(request): + """ + This function is used to create a journal for an employee. + + @param: + request (HttpRequest): The POST request containing the data to be inserted or updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or update operation. If successful, returns a success message. If the request method is not POST, returns an invalid request method error. + """ + if request.method=="POST": + user = get_object_or_404(faculty_about, user_id=request.POST['user_id']) + eis = emp_research_papers.objects.create(pf_no = user.user_id) + eis.rtype = 'Journal' + eis.authors = request.POST.get('authors') + eis.title_paper = request.POST.get('title') + try: + myfile = request.FILES['journal'] + fs = FileSystemStorage() + filename = fs.save(myfile.name, myfile) + uploaded_file_url = fs.url(filename) + eis.paper=uploaded_file_url + except: + eis.paper = None + + eis.co_authors = request.POST.get('co_author') + eis.name = request.POST.get('name') + eis.doc_id = request.POST.get('doc_id') + eis.doc_description = request.POST.get('doc_description') + eis.status = request.POST.get('status') + eis.reference_number = request.POST.get('ref') + eis.is_sci = request.POST.get('sci') + volume_no = request.POST.get('volume') + page_no = request.POST.get('page') + year = request.POST.get('year') + if volume_no != '': + eis.volume_no=volume_no + if page_no != '': + eis.page_no=page_no + if year != '': + eis.year = year + if(request.POST.get('doi') != None and request.POST.get('doi') != '' and request.POST.get('doi') != 'None'): + try: + eis.doi = datetime.datetime.strptime( + request.POST.get('doi'), "%B %d, %Y") + except: + try: + eis.doi = datetime.datetime.strptime( + request.POST.get('doi'), "%b. %d, %Y") + except: + eis.doi = request.POST.get('doi') + if (request.POST.get('doa') != None and request.POST.get('doa') != '' and request.POST.get('doa') != 'None'): + try: + eis.date_acceptance = datetime.datetime.strptime( + request.POST.get('doa'), "%B %d, %Y") + except: + eis.date_acceptance = datetime.datetime.strptime( + request.POST.get('doa'), "%b. %d, %Y") + if (request.POST.get('dop') != None and request.POST.get('dop') != '' and request.POST.get('dop') != 'None'): + try: + eis.date_publication = datetime.datetime.strptime( + request.POST.get('dop'), "%B %d, %Y") + except: + eis.date_publication = datetime.datetime.strptime( + request.POST.get('dop'), "%b. %d, %Y") + if (request.POST.get('dos') != None and request.POST.get('dos') != '' and request.POST.get('dos') != 'None'): + try: + eis.date_submission = datetime.datetime.strptime( + request.POST.get('dos'), "%B %d, %Y") + except: + eis.date_submission = datetime.datetime.strptime( + request.POST.get('dos'), "%b. %d, %Y") + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + +@csrf_exempt +def editjournal(request): + """ + Update the details of an existing journal entry in the database with the provided data. + + The function retrieves a specific journal entry based on a primary key passed in the request, + updates its fields with the new data from the request, and saves the changes to the database. + If a new journal file is uploaded, it is saved and its URL is updated in the entry. + + Args: + request (HttpRequest): The request object containing POST data with journal details and files. + + Returns: + JsonResponse: A JSON response indicating the success of the update operation. + """ + eis = emp_research_papers.objects.get(pk=request.POST.get('journalpk')) + eis.authors = request.POST.get('authors') + eis.title_paper = request.POST.get('title') + try: + myfile = request.FILES['journal'] + fs = FileSystemStorage() + filename = fs.save(myfile.name, myfile) + uploaded_file_url = fs.url(filename) + eis.paper=uploaded_file_url + except: + logging.warning('No New Journal Found for Update, Older one will be kept.') + eis.co_authors = request.POST.get('co_author') + eis.name = request.POST.get('name') + eis.doc_id = request.POST.get('doc_id') + eis.doc_description = request.POST.get('doc_description') + eis.status = request.POST.get('status') + eis.reference_number = request.POST.get('ref') + eis.is_sci = request.POST.get('sci') + eis.volume_no = request.POST.get('volume') + eis.page_no = request.POST.get('page') + eis.year = request.POST.get('year') + + if(request.POST.get('doi') != None and request.POST.get('doi') != '' and request.POST.get('doi') != 'None'): + x = request.POST.get('doi') + + + + if x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.doi = datetime.datetime.strptime( + x, "%B %d, %Y") + except: + try: + eis.doi = datetime.datetime.strptime( + x, "%b. %d, %Y") + except: + eis.doi = x + if (request.POST.get('doa') != None and request.POST.get('doa') != '' and request.POST.get('doa') != 'None'): + x = request.POST.get('doa') + if x[:-10] == ', midnight': + x = x[0:-10] + + if x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.date_acceptance = datetime.datetime.strptime( + x, "%B %d, %Y") + except: + eis.date_acceptance = datetime.datetime.strptime( + x, "%b. %d, %Y") + + if (request.POST.get('dop') != None and request.POST.get('dop') != '' and request.POST.get('dop') != 'None'): + x = request.POST.get('dop') + if x[:-10] == ', midnight': + x = x[0:-10] + if x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.date_publication = datetime.datetime.strptime( + x, "%B %d, %Y") + except: + eis.date_publication = datetime.datetime.strptime( + x, "%b. %d, %Y") + if (request.POST.get('dos') != None and request.POST.get('dos') != '' and request.POST.get('dos') != 'None'): + x = request.POST.get('dos') + if x[-10:] == ', midnight': + x = x[0:-10] + if x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.date_submission = datetime.datetime.strptime( + x, "%B %d, %Y") + except: + eis.date_submission = datetime.datetime.strptime( + x, "%b. %d, %Y") + eis.save() + return JsonResponse({'message' : 'Your data is updated '}) + +@csrf_exempt +def editforeignvisit(request): + """ + Edit a foreign visit entry in the emp_visits table. + + This view handles POST requests to edit a foreign visit entry in the + emp_visits table. The request data should contain the primary key + ('foreignvisitpk') of the emp_visits entry to be updated, the + country of visit, the place of visit, the purpose of visit, the + start date and end date of visit. + + If the 'foreignvisitpk' is not provided, a new emp_visits entry is + created. Otherwise, the existing entry is updated. The 'v_type' is + set to 2 for foreign visit entries. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty about and the details of the foreign visit entry to be + inserted or updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or + update operation. If successful, returns a success message. If the + request method is not POST, returns an invalid request method error. + """ + eis = emp_visits.objects.get(pk=request.POST.get('foreignvisitpk')) + eis.country = request.POST.get('country') + eis.place = request.POST.get('place') + eis.purpose = request.POST.get('purpose') + x = request.POST.get('start_date') + if x and x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.start_date = datetime.datetime.strptime(x, "%B %d, %Y") if x else None + except: + eis.start_date = datetime.datetime.strptime(x, "%b. %d, %Y") if x else None + x = request.POST.get('end_date') + if x and x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.end_date = datetime.datetime.strptime(x, "%B %d, %Y") if x else None + except: + eis.end_date = datetime.datetime.strptime(x, "%b. %d, %Y") if x else None + eis.save() + return JsonResponse({'message' : 'Your data is updated '}) + +@csrf_exempt +def editindianvisit(request): + """ + Edit an Indian visit entry in the emp_visits table. + + This view handles POST requests to edit an Indian visit entry in the + emp_visits table. The request data should contain the primary key + ('indianvisitpk') of the emp_visits entry to be updated, the + country of visit, the place of visit, the purpose of visit, the + start date and end date of visit. + + If the 'indianvisitpk' is not provided, a new emp_visits entry is + created. Otherwise, the existing entry is updated. The 'v_type' is + set to 1 for Indian visit entries. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty about and the details of the Indian visit entry to be + inserted or updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or + update operation. If successful, returns a success message. If the + request method is not POST, returns an invalid request method error. + """ + eis = emp_visits.objects.get(pk=request.POST.get('indianvisitpk')) + eis.country = request.POST.get('country') + eis.place = request.POST.get('place') + eis.purpose = request.POST.get('purpose') + x = request.POST.get('start_date') + if x and x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.start_date = datetime.datetime.strptime(x, "%B %d, %Y") if x else None + except: + eis.start_date = datetime.datetime.strptime(x, "%b. %d, %Y") if x else None + x = request.POST.get('end_date') + if x and x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.end_date = datetime.datetime.strptime(x, "%B %d, %Y") if x else None + except: + eis.end_date = datetime.datetime.strptime(x, "%b. %d, %Y") if x else None + eis.save() + return JsonResponse({'success': True}) + + +@csrf_exempt +def conference_insert(request): + """ + Insert a conference paper entry in the emp_research_papers table. + + This view handles POST requests to insert a conference paper entry in the + emp_research_papers table. The request data should contain the primary key + ('user_id') of the faculty about, the authors, the co-authors, the title of + the paper, the journal name, the venue, the page number, the isbn number, + the year, the status, the date of acceptance, the date of publication, and + the date of submission. + + The 'rtype' is set to 'Conference' for conference paper entries. + + Args: + request (HttpRequest): The request object containing the primary key of + the faculty about and the details of the conference paper entry to be + inserted. + + Returns: + JsonResponse: A JSON response indicating the success of the insert + operation. If successful, returns a success message. If the request + method is not POST, returns an invalid request method error. + """ + if request.method == 'POST': + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + eis = emp_research_papers() + eis.pf_no = pf + eis.rtype = 'Conference' + eis.authors = request.POST.get('author') + eis.co_authors = request.POST.get('co_authors') + eis.title_paper = request.POST.get('title') + try: + myfile = request.FILES['journal'] + fs = FileSystemStorage() + filename = fs.save(myfile.name, myfile) + uploaded_file_url = fs.url(filename) + eis.paper=uploaded_file_url + except: + logging.warning('Journal file not Uploaded') + eis.name = request.POST.get('name') + eis.venue = request.POST.get('venue') + if request.POST.get('page_no') != '': + eis.page_no = request.POST.get('page_no') + if request.POST.get('isbn_no') != '': + eis.isbn_no = request.POST.get('isbn_no') + if request.POST.get('year') != '': + eis.year = request.POST.get('year') + eis.status = request.POST.get('status') + if(request.POST.get('doi') != None and request.POST.get('doi') != '' and request.POST.get('doi') != 'None'): + x = request.POST.get('doi') + x = x.split() + x = x[1:4] + x = ' '.join(x) + eis.doi = datetime.datetime.strptime(x, "%b %d %Y") + + if (request.POST.get('doa') != None and request.POST.get('doa') != '' and request.POST.get('doa') != 'None'): + x = request.POST.get('doa') + x = x.split() + x = x[1:4] + x = ' '.join(x) + eis.date_acceptance = datetime.datetime.strptime(x, "%b %d %Y") + + if (request.POST.get('dop') != None and request.POST.get('dop') != '' and request.POST.get('dop') != 'None'): + x = request.POST.get('dop') + x = x.split() + x = x[1:4] + x = ' '.join(x) + eis.date_publication = datetime.datetime.strptime(x, "%b %d %Y") + + if (request.POST.get('dos') != None and request.POST.get('dos') != '' and request.POST.get('dos') != 'None'): + x = request.POST.get('dos') + x = x.split() + x = x[1:4] + x = ' '.join(x) + eis.date_submission = datetime.datetime.strptime(x, "%b %d %Y") + + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + +@csrf_exempt +def editconference(request): + """ + This function is used to update a conference for an employee. + + @param: + request (HttpRequest): The POST request containing the data to be updated. + + Returns: + JsonResponse: A JSON response indicating the success of the update operation. If successful, returns a success message. If the request method is not POST, returns an invalid request method error. + """ + eis = emp_research_papers.objects.get(pk=request.POST.get('conferencepk')) + eis.authors = request.POST.get('author') + eis.co_authors = request.POST.get('co_authors') + eis.title_paper = request.POST.get('title') + try: + myfile = request.FILES['journal'] + fs = FileSystemStorage() + filename = fs.save(myfile.name, myfile) + uploaded_file_url = fs.url(filename) + eis.paper=uploaded_file_url + except: + logging.warning('Journal File not Uploaded.') + + eis.name = request.POST.get('name') + eis.venue = request.POST.get('venue') + isbn = request.POST.get('isbn_no') + + eis.page_no = request.POST.get('page_no') + + eis.year = request.POST.get('year') + eis.status = request.POST.get('status') + if(request.POST.get('doi') != None and request.POST.get('doi') != '' and request.POST.get('doi') != 'None'): + x = request.POST.get('doi') + if x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.doi = datetime.datetime.strptime( + x, "%B %d, %Y") + except: + try: + eis.doi = datetime.datetime.strptime( + x, "%b. %d, %Y") + except: + eis.doi = x + if (request.POST.get('doa') != None and request.POST.get('doa') != '' and request.POST.get('doa') != 'None'): + x = request.POST.get('doa') + if x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.date_acceptance = datetime.datetime.strptime( + x, "%B %d, %Y") + except: + eis.date_acceptance = datetime.datetime.strptime( + x, "%b. %d, %Y") + + if (request.POST.get('dop') != None and request.POST.get('dop') != '' and request.POST.get('dop') != 'None'): + x = request.POST.get('dop') + if x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.date_publication = datetime.datetime.strptime( + x, "%B %d, %Y") + except: + eis.date_publication = datetime.datetime.strptime( + x, "%b. %d, %Y") + if (request.POST.get('dos') != None and request.POST.get('dos') != '' and request.POST.get('dos') != 'None'): + x = request.POST.get('dos') + if x[-10:] == ', midnight': + x = x[0:-10] + if x[:5] == "Sept." : + x = "Sep." + x[5:] + try: + eis.date_submission = datetime.datetime.strptime( + x, "%B %d, %Y") + except: + eis.date_submission = datetime.datetime.strptime( + x, "%b. %d, %Y") + eis.save() + return JsonResponse({'success': True}) + + +@csrf_exempt +def book_insert(request): + """ + Insert a book entry in the emp_published_books table. + + This view handles POST requests to insert a book entry in the + emp_published_books table. The request data should contain the primary key + ('user_id') of the faculty about, the type of publication, the title of + the publication, the publisher of the publication, the year of publication, + and the authors of the publication. + + Returns: + JsonResponse: A JSON response indicating the success of the insert + operation. If successful, returns a success message. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + eis = emp_published_books() + eis.pf_no = pf + eis.p_type = request.POST.get('book_p_type') + eis.title = request.POST.get('book_title') + eis.publisher = request.POST.get('book_publisher') + eis.pyear = request.POST.get('book_year') + eis.authors = request.POST.get('book_author') + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + + +@csrf_exempt +def editbooks(request): + """ + Edit a book entry in the emp_published_books table. + + This view handles POST requests to edit a book entry in the + emp_published_books table. The request data should contain the primary key + ('pk') of the book entry, the type of publication, the title of the + publication, the publisher of the publication, the year of publication, + and the authors of the publication. + + Returns: + JsonResponse: A JSON response indicating the success of the edit + operation. If successful, returns a success message. + """ + eis = emp_published_books.objects.get(pk=request.POST.get('bookspk')) + eis.p_type = request.POST.get('book_p_type') + eis.title = request.POST.get('book_title') + eis.publisher = request.POST.get('book_publisher') + eis.pyear = request.POST.get('book_year') + eis.authors = request.POST.get('book_author') + eis.save() + return JsonResponse({'message' : 'Your data is updated '}) + +@csrf_exempt +def consym_insert(request): + """ + Insert a new conference entry in the emp_confrence_organised table. + + This view handles POST requests to insert a new conference entry. The request + data should include the primary key ('user_id') of the faculty about, the + conference name, venue, role, and the start and end dates of the conference. + + The 'role1' is set based on the provided conference role and can be further + specified with 'role2' if applicable. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty about and the details of the conference entry to be + inserted. + + Returns: + JsonResponse: A JSON response indicating the success of the insert + operation. If successful, returns a success message. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + eis = emp_confrence_organised() + eis.pf_no = pf + eis.name = request.POST.get('conference_name') + eis.venue = request.POST.get('conference_venue') + eis.role1 = request.POST.get('conference_role') + if(eis.role1 == 'Any Other'): + eis.role2 = request.POST.get('conference_organised') + if(eis.role1 == 'Organised'): + if(request.POST.get('conference_organised') == 'Any Other'): + eis.role2 = request.POST.get('myDIV1') + else: + eis.role2 = request.POST.get('conference_organised') + if (eis.role1 == "" or eis.role1==None): + eis.role1 = "Any Other" + eis.role2 = "Any Other" + + # x = request.POST.get('conference_start_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.start_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.start_date = request.POST.get('conference_start_date') + + # x = request.POST.get('conference_end_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.end_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.end_date = request.POST.get('conference_end_date') + + eis.save() + return JsonResponse({ "success": True}) + +@csrf_exempt +def editconsym(request): + """ + Edit a conference organised entry for a faculty member. + + Args: + request (HttpRequest): The request object. + + Returns: + JsonResponse: A JSON response indicating the success of the edit + operation. If successful, returns a success message. + """ + eis = emp_confrence_organised.objects.get(pk=request.POST.get('conferencepk2')) + eis.name = request.POST.get('conference_name') + eis.venue = request.POST.get('conference_venue') + eis.role1 = request.POST.get('conference_role') + if(eis.role1 == 'Any Other'): + eis.role2 = request.POST.get('conference_organised') + if(eis.role1 == 'Organised'): + if(request.POST.get('conference_organised') == 'Any Other'): + eis.role2 = request.POST.get('myDIV1') + else: + eis.role2 = request.POST.get('conference_organised') + if (eis.role1 == "" or eis.role1==None): + eis.role1 = "Any Other" + eis.role2 = "Any Other" + + # x = request.POST.get('conference_start_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.start_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.start_date = request.POST.get('conference_start_date') + + # x = request.POST.get('conference_end_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.end_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.end_date = request.POST.get('conference_end_date') + + eis.save() + return JsonResponse({'success': True}) + +@csrf_exempt +def event_insert(request): + """ + Insert a new event organized entry for a faculty member. + + Args: + request (HttpRequest): The request object. + + Returns: + JsonResponse: A JSON response indicating the success of the insert + operation. If successful, returns a success message. + """ + + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + eis = emp_event_organized() + + eis.pf_no = pf + eis.type = request.POST.get('event_type') + if(eis.type == 'Any Other'): + if(request.POST.get('myDIV')!= None or request.POST.get('myDIV') != ""): + eis.type = request.POST.get('myDIV') + eis.sponsoring_agency = request.POST.get('sponsoring_agency') + eis.name = request.POST.get('event_name') + eis.venue = request.POST.get('event_venue') + eis.role = request.POST.get('event_role') + + # x = request.POST.get('event_start_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.start_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.start_date = request.POST.get('event_start_date') + + # x = request.POST.get('event_end_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.end_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.end_date = request.POST.get('event_end_date') + + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + +@csrf_exempt +def editevent(request): + """ + Edit an event organized entry for a faculty member. + + Args: + request (HttpRequest): The request object. + + Returns: + JsonResponse: A JSON response indicating the success of the edit + operation. If successful, returns a success message. + """ + + eis = emp_event_organized.objects.get(pk=request.POST.get('eventpk')) + + eis.type = request.POST.get('event_type') + if(eis.type == 'Any Other'): + if(request.POST.get('myDIV')!= None or request.POST.get('myDIV') != ""): + eis.type = request.POST.get('myDIV') + eis.sponsoring_agency = request.POST.get('sponsoring_agency') + eis.name = request.POST.get('event_name') + eis.venue = request.POST.get('event_venue') + eis.role = request.POST.get('event_role') + + # x = request.POST.get('event_start_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.start_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.start_date = request.POST.get('event_start_date') + + # x = request.POST.get('event_end_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.end_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.end_date = request.POST.get('event_end_date') + + eis.save() + return JsonResponse({'success': True}) + +@csrf_exempt +def award_insert(request): + """ + Insert or update an award entry in the emp_achievement table. + + This view handles POST requests to insert a new or update an existing + award entry in the emp_achievement table. The request data should + contain the primary key ('user_id') of the faculty about, the award type, + and other optional details such as the day, month, and year of the award. + + If the 'ach_id' is not provided, a new emp_achievement entry is created. + Otherwise, the existing entry is updated. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty about and the details of the award entry to be + inserted or updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or + update operation. If successful, returns a success message. If the + request method is not POST, returns an invalid request method error. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + + if (request.POST.get('ach_id')==None or request.POST.get('ach_id')==""): + eis = emp_achievement() + else: + eis = get_object_or_404(emp_achievement, id=request.POST.get('ach_id')) + + eis.pf_no = pf + eis.a_type = request.POST.get('type') + if(request.POST.get('a_day') != None and request.POST.get('a_day') != ""): + eis.a_day = request.POST.get('a_day') + if(request.POST.get('a_month') != None and request.POST.get('a_month') != ""): + eis.a_month = request.POST.get('a_month') + if(request.POST.get('a_year') != None and request.POST.get('a_year') != ""): + eis.a_year = request.POST.get('a_year') + eis.details = request.POST.get('details') + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + +@csrf_exempt +def talk_insert(request): + """ + This view handles POST requests to insert a new or update an existing + expert lecture entry in the emp_expert_lectures table. The request data + should contain the primary key ('user_id') of the faculty about, the + lecture type, the place, title, and date of the lecture. + + If the 'lec_id' is not provided, a new emp_expert_lectures entry is + created. Otherwise, the existing entry is updated. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty about and the details of the lecture entry to be + inserted or updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or + update operation. If successful, returns a success message. If the + request method is not POST, returns an invalid request method error. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + if (request.POST.get('lec_id')==None or request.POST.get('lec_id')=="" or request.POST.get('lec_id')==0): + eis = emp_expert_lectures() + else: + eis = get_object_or_404(emp_expert_lectures, id=request.POST.get('lec_id')) + + eis.pf_no = pf + eis.l_type = request.POST.get('type') + eis.place = request.POST.get('place') + eis.title = request.POST.get('title') + + # x = request.POST.get('l_date') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.l_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.l_date = request.POST.get('l_date') + + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + +@csrf_exempt +def chaired_insert(request): + """ + Insert a session chair entry in the emp_session_chair table. + + The request data should contain the primary key ('user_id') of the faculty about, the + event name, the name of the session, and the start and end dates of the session. + + Args: + request (HttpRequest): The request object containing the primary key of the + faculty about and the details of the session chair entry to be inserted. + + Returns: + JsonResponse: A JSON response indicating the success of the insert operation. + If successful, returns a success message. If the request method is not POST, + returns an invalid request method error. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + + eis = emp_session_chair() + eis.pf_no = pf + eis.event = request.POST.get('event') + eis.name = request.POST.get('name') + eis.s_year = request.POST.get('s_year') + try: + eis.start_date = datetime.datetime.strptime(request.POST.get('start'), "%B %d, %Y") if request.POST.get('start') else None + except: + eis.start_date = datetime.datetime.strptime(request.POST.get('start'), "%b. %d, %Y") if request.POST.get('start') else None + try: + eis.end_date = datetime.datetime.strptime(request.POST.get('end'), "%B %d, %Y") if request.POST.get('end') else None + except: + eis.end_date = datetime.datetime.strptime(request.POST.get('end'), "%b. %d, %Y") if request.POST.get('end') else None + + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + +@csrf_exempt +def keynote_insert(request): + """ + Insert a keynote address entry in the emp_keynote_address table. + + The request data should contain the primary key ('user_id') of the faculty about, the + type of the address, the name of the event, the title of the address, the venue, the + page number and isbn number of the address, and the year of the address. + + Args: + request (HttpRequest): The request object containing the primary key of the + faculty about and the details of the address entry to be inserted. + + Returns: + JsonResponse: A JSON response indicating the success of the insert operation. + If successful, returns a success message. If the request method is not POST, + returns an invalid request method error. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + + eis = emp_keynote_address() + eis.pf_no = pf + eis.type = request.POST.get('type') + eis.name = request.POST.get('name') + eis.title = request.POST.get('title') + eis.venue = request.POST.get('venue') + eis.page_no = request.POST.get('page_no') + eis.isbn_no = request.POST.get('isbn_no') + eis.k_year = request.POST.get('k_year') + try: + eis.start_date = datetime.datetime.strptime(request.POST.get('start'), "%B %d, %Y") if request.POST.get('start') else None + except: + eis.start_date = datetime.datetime.strptime(request.POST.get('start'), "%b. %d, %Y") if request.POST.get('start') else None + + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + +@csrf_exempt +def project_insert(request): + """ + Insert a research project entry in the emp_research_projects table. + + The request data should contain the primary key ('user_id') of the faculty about, the + primary key ('project_id') of the emp_research_projects entry to be updated, the + principal investigator, the co-investigator, the title of the project, the financial + outlay, the funding agency, the status of the project, the start date and end date of + the project. + + If the 'project_id' is not provided, a new emp_research_projects entry is + created. Otherwise, the existing entry is updated. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty about and the details of the research project entry to be + inserted or updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or + update operation. If successful, returns a success message. If the + request method is not POST, returns an invalid request method error. + """ + + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + + if (request.POST.get('project_id')==None or request.POST.get('project_id')==""): + eis = emp_research_projects() + else: + eis = get_object_or_404(emp_research_projects, id=request.POST.get('project_id')) + eis.pf_no = pf + eis.pi = request.POST.get('pi') + eis.co_pi = request.POST.get('co_pi') + eis.title = request.POST.get('title') + eis.financial_outlay = request.POST.get('financial_outlay') + eis.funding_agency = request.POST.get('funding_agency') + eis.status = request.POST.get('status') + + # x = request.POST.get('start') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.start_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.start_date = request.POST.get('start') + + # x = request.POST.get('end') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.finish_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.finish_date = request.POST.get('end') + + # x = request.POST.get('sub') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.date_submission = datetime.datetime.strptime(x, "%b %d %Y") + + eis.date_submission = request.POST.get('sub') + + eis.save() + return JsonResponse({'success': True}) + +@csrf_exempt +def consult_insert(request): + """ + Insert a new consultancy project entry in the emp_consultancy_projects table. + + This view handles POST requests to insert a new consultancy project entry in the + emp_consultancy_projects table. The request data should contain the primary key + ('user_id') of the faculty about, the consultants, the client, the title of the + project, the financial outlay, the start date and the end date of the project. + + If the 'consultancy_id' is not provided, a new emp_consultancy_projects entry is + created. Otherwise, the existing entry is updated. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty about and the details of the consultancy project entry to be + inserted or updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or + update operation. If successful, returns a success message. If the + request method is not POST, returns an invalid request method error. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + + if (request.POST.get('consultancy_id')==None or request.POST.get('consultancy_id')==""): + eis = emp_consultancy_projects() + else: + eis = get_object_or_404(emp_consultancy_projects, id=request.POST.get('consultancy_id')) + eis.pf_no = pf + eis.consultants = request.POST.get('consultants') + eis.client = request.POST.get('client') + eis.title = request.POST.get('title') + eis.financial_outlay = request.POST.get('financial_outlay') + + # x = request.POST.get('start') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.start_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.start_date = request.POST.get('start') + + # x = request.POST.get('end') + # x = x.split() + # x = x[1:4] + # x = ' '.join(x) + + # eis.end_date = datetime.datetime.strptime(x, "%b %d %Y") + + eis.end_date = request.POST.get('end') + + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + +@csrf_exempt +def patent_insert(request): + """ + Insert or update a patent entry in the emp_patents table. + + This view handles POST requests to insert a new patent entry or update an + existing one in the emp_patents table. The request data should include the + primary key ('user_id') of the faculty, the patent number, earnings, title, + year, status, and application month. + + If the 'patent_id' is not provided, a new emp_patents entry is created. + Otherwise, the existing entry is updated. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty and the details of the patent entry to be inserted or + updated. + + Returns: + JsonResponse: A JSON response indicating the success of the insert or + update operation. If successful, returns a success message. If the + request method is not POST, returns an invalid request method error. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + + if (request.POST.get('patent_id')==None or request.POST.get('patent_id')==""): + eis = emp_patents() + else: + eis = get_object_or_404(emp_patents, id=request.POST.get('patent_id')) + + eis.pf_no = pf + eis.p_no = request.POST.get('p_no') + eis.earnings = request.POST.get('earnings') + eis.title = request.POST.get('title') + eis.p_year = request.POST.get('year') + eis.status = request.POST.get('status') + eis.a_month = request.POST.get('month') + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + +@csrf_exempt +def transfer_insert(request): + """ + Insert a new technology transfer entry in the emp_techtransfer table. + + This view handles POST requests to insert a new technology transfer entry in the + emp_techtransfer table. The request data should contain the primary key + ('user_id') of the faculty about and the details of the technology transfer. + + Args: + request (HttpRequest): The request object containing the primary key + of the faculty about and the details of the technology transfer entry to be + inserted. + + Returns: + JsonResponse: A JSON response indicating the success of the insert + operation. If successful, returns a success message. If the + request method is not POST, returns an invalid request method error. + """ + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + eis = emp_techtransfer() + eis.pf_no = pf + eis.details = request.POST.get('details') + eis.save() + return JsonResponse({'message' : 'Your data is saved '}) + +# def get_personal_info(request): +# # Fetch all entries where pf_no is '5318' +# projects = faculty_about.objects.filter(user_id='5318').values() + +# return JsonResponse(list(projects), safe=False) + +def get_personal_info(request): + # Fetch all entries where pf_no is '5318' + + projects = faculty_about.objects.filter(user_id=request.GET.get("pfNo")).values() + + return JsonResponse(list(projects), safe=False) + + +def get_research_projects(request): + # Fetch all entries where pf_no is '5318' + projects = emp_research_projects.objects.filter(pf_no=request.GET.get("pfNo")).values() + + return JsonResponse(list(projects), safe=False) + +def get_consultancy_projects(request): + # Fetch all entries where pf_no is '5318' + projects = emp_consultancy_projects.objects.filter(pf_no=request.GET.get("pfNo")).values() + + return JsonResponse(list(projects), safe=False) + +def get_patents(request): + # Fetch all entries where pf_no is '5318' + projects = emp_patents.objects.filter(pf_no=request.GET.get("pfNo")).values() + + return JsonResponse(list(projects), safe=False) + +def get_pg_thesis(request): + # Fetch all entries where pf_no is '5318' + projects = emp_mtechphd_thesis.objects.filter(pf_no=request.GET.get("pfNo"), degree_type='1').values() + + return JsonResponse(list(projects), safe=False) + +def get_phd_thesis(request): + # Fetch all entries where pf_no is '5318' + projects = emp_mtechphd_thesis.objects.filter(pf_no=request.GET.get("pfNo"), degree_type='2').values() + + return JsonResponse(list(projects), safe=False) + +def get_event(request): + # Fetch all entries where pf_no is '5318' + + projects = emp_event_organized.objects.filter(pf_no=request.GET.get("pfNo")).values() + + return JsonResponse(list(projects), safe=False) + +def get_fvisits(request): + # Fetch all entries where pf_no is '5318' + projects = emp_visits.objects.filter(pf_no=request.GET.get("pfNo"), v_type='2').values() + + return JsonResponse(list(projects), safe=False) + +def get_ivisits(request): + # Fetch all entries where pf_no is '5318' + projects = emp_visits.objects.filter(pf_no=request.GET.get("pfNo"), v_type='1').values() + + return JsonResponse(list(projects), safe=False) + +def get_consym(request): + # Fetch all entries where pf_no is '5318' + projects = emp_confrence_organised.objects.filter(pf_no=request.GET.get("pfNo")).values() + + return JsonResponse(list(projects), safe=False) + +def get_all_research_projects(request): + # Fetch all entries where pf_no is '5318' + projects = emp_research_projects.objects.values() + + return JsonResponse(list(projects), safe=False) + + +# def get_books(request): +# # Fetch all entries where pf_no is '5318' +# books = emp_published_books.objects.filter(pf_no="5318").order_by('-pyear').values() + +# return JsonResponse(list(books), safe=False) + +def get_books(request): + # Fetch all entries where pf_no is '5318' + books = emp_published_books.objects.filter(pf_no=request.GET.get("pfNo")).order_by('-pyear').values() + return JsonResponse(list(books), safe=False) + + +def get_journals(request): + journals = emp_research_papers.objects.filter(pf_no=request.GET.get("pfNo"), rtype='Journal').order_by('-date_entry').values() + return JsonResponse(list(journals), safe=False) + +def get_conference(request): + conference = emp_research_papers.objects.filter(pf_no=request.GET.get("pfNo")).order_by('-year').values() + return JsonResponse(list(conference), safe=False) + +def get_achievements(request): + # Fetch all entries where pf_no is '5318' + achievements = emp_achievement.objects.filter(pf_no=request.GET.get("pfNo")).order_by('-a_year').values() + + return JsonResponse(list(achievements), safe=False) + +def get_talks(request): + # Fetch all entries where pf_no is '5318' + talks = emp_expert_lectures.objects.filter(pf_no=request.GET.get("pfNo")).values() + + return JsonResponse(list(talks), safe=False) + + +def edit_research_project(request, pk): + """ + Edit an existing research project entry in the emp_research_projects table. + + This view handles the editing of a research project based on the provided + primary key (pk). The project details are updated using the data from a + POST request. If the request method is not POST, an error response is returned. + + Args: + request (HttpRequest): The request object containing POST data for the + project to be updated. + pk (int): The primary key of the research project to be edited. + + Returns: + JsonResponse: A response indicating the success or failure of the update + operation. On success, returns a success message with status 200. + On failure, returns the form errors with status 400. + If the request method is invalid, returns an error message with status 400. + """ + project = get_object_or_404(emp_research_projects, pk=pk) + + if request.method == 'POST': + form = emp_research_projects(request.POST, instance=project) + if form.is_valid(): + form.save() + return JsonResponse({'message': 'Project updated successfully.'}, status=200) + else: + return JsonResponse({'errors': form.errors}, status=400) + + return JsonResponse({'error': 'Invalid request method.'}, status=400) +# Filter and Fetch +@csrf_exempt +def filter_research_projects(request): + filters = {} + interval_filters = {} + sorting = request.POST.get("sort_by", None) + fields_of_interest = request.POST.get("fields", None) + + # Extracting filter fields + pf_no = request.POST.get("pf_no") + if pf_no: + filters['pf_no__icontains'] = pf_no + + ptype = request.POST.get("ptype") + if ptype: + filters['ptype__icontains'] = ptype + + pi = request.POST.get("pi") + if pi: + filters['pi__icontains'] = pi + + co_pi = request.POST.get("co_pi") + if co_pi: + filters['co_pi__icontains'] = co_pi + + funding_agency = request.POST.get("funding_agency") + if funding_agency: + filters['funding_agency__icontains'] = funding_agency + + status = request.POST.get("status") + if status: + filters['status'] = status + + # Interval filtering for date fields + start_date = request.POST.get("start_date") + end_date = request.POST.get("end_date") + if start_date and end_date: + try: + interval_filters['start_date__gte'] = datetime.strptime(start_date, '%Y-%m-%d') + interval_filters['finish_date__lte'] = datetime.strptime(end_date, '%Y-%m-%d') + except ValueError: + return JsonResponse({"error": "Invalid date format. Use YYYY-MM-DD."}, status=400) + + # Apply filters + projects = emp_research_projects.objects.filter( + Q(**filters) & Q(**interval_filters) + ) + + # Apply sorting + if sorting: + projects = projects.order_by(sorting) + + # Select specific fields + if fields_of_interest: + fields_of_interest = fields_of_interest.split(', ') + projects = projects.values(*fields_of_interest) + else: + projects = projects.values() + + return JsonResponse(list(projects), safe=False) + +# Sample Filter Input JSON: +# { +# "pf_no": "12345", +# "ptype": "Research", +# "pi": "Dr. Smith", +# "start_date": "2023-01-01", +# "end_date": "2024-01-01", +# "sort_by": "-start_date", +# "fields": ["pf_no", "pi", "title", "status"] +# } +@csrf_exempt +def filter_consultancy_projects(request): + filters = {} + interval_filters = {} + sorting = request.POST.get("sort_by", None) + fields_of_interest = request.POST.get("fields", None) + + # Extracting filter fields + pf_no = request.POST.get("pf_no") + if pf_no: + filters['pf_no__icontains'] = pf_no + + consultants = request.POST.get("consultants") + if consultants: + filters['consultants__icontains'] = consultants + + title = request.POST.get("title") + if title: + filters['title__icontains'] = title + + client = request.POST.get("client") + if client: + filters['client__icontains'] = client + + status = request.POST.get("status") + if status: + filters['status'] = status + + remarks = request.POST.get("remarks") + if remarks: + filters['remarks__icontains'] = remarks + + # Interval filtering for date fields + start_date = request.POST.get("start_date") + end_date = request.POST.get("end_date") + if start_date and end_date: + try: + interval_filters['start_date__gte'] = datetime.strptime(start_date, '%Y-%m-%d') + interval_filters['end_date__lte'] = datetime.strptime(end_date, '%Y-%m-%d') + except ValueError: + return JsonResponse({"error": "Invalid date format. Use YYYY-MM-DD."}, status=400) + + # Financial outlay filtering (range-based) + min_financial_outlay = request.POST.get("min_financial_outlay") + max_financial_outlay = request.POST.get("max_financial_outlay") + if min_financial_outlay and max_financial_outlay: + try: + interval_filters['financial_outlay__gte'] = int(min_financial_outlay) + interval_filters['financial_outlay__lte'] = int(max_financial_outlay) + except ValueError: + return JsonResponse({"error": "Invalid financial outlay range."}, status=400) + + # Apply filters + projects = emp_consultancy_projects.objects.filter( + Q(**filters) & Q(**interval_filters) + ) + + # Apply sorting + if sorting: + projects = projects.order_by(sorting) + + # Select specific fields + if fields_of_interest: + fields_of_interest = fields_of_interest.split(', ') + projects = projects.values(*fields_of_interest) + else: + projects = projects.values() + + return JsonResponse(list(projects), safe=False) + +# Sample Filter Input JSON: +# { +# "pf_no": "12345", +# "consultants": "Dr. John Doe", +# "title": "AI Consultancy", +# "client": "TechCorp", +# "status": "Ongoing", +# "start_date": "2023-01-01", +# "end_date": "2024-01-01", +# "min_financial_outlay": "100000", +# "max_financial_outlay": "500000", +# "sort_by": "-financial_outlay", +# "fields": ["pf_no", "consultants", "title", "financial_outlay", "status"] +# } +@csrf_exempt +def filter_patents(request): + filters = {} + interval_filters = {} + sorting = request.POST.get("sort_by", None) + fields_of_interest = request.POST.get("fields", None) + + # Extracting filter fields + pf_no = request.POST.get("pf_no") + if pf_no: + filters['pf_no__icontains'] = pf_no + + p_no = request.POST.get("p_no") + if p_no: + filters['p_no__icontains'] = p_no + + title = request.POST.get("title") + if title: + filters['title__icontains'] = title + + status = request.POST.get("status") + if status: + filters['status'] = status + + p_year = request.POST.get("p_year") + if p_year: + try: + filters['p_year'] = int(p_year) + except ValueError: + return JsonResponse({"error": "Invalid year format."}, status=400) + + a_month = request.POST.get("a_month") + if a_month: + try: + filters['a_month'] = int(a_month) + except ValueError: + return JsonResponse({"error": "Invalid month format."}, status=400) + + # Interval filtering for date fields + start_date = request.POST.get("start_date") + end_date = request.POST.get("end_date") + if start_date and end_date: + try: + interval_filters['start_date__gte'] = datetime.strptime(start_date, '%Y-%m-%d') + interval_filters['end_date__lte'] = datetime.strptime(end_date, '%Y-%m-%d') + except ValueError: + return JsonResponse({"error": "Invalid date format. Use YYYY-MM-DD."}, status=400) + + # Earnings filtering (range-based) + min_earnings = request.POST.get("min_earnings") + max_earnings = request.POST.get("max_earnings") + if min_earnings and max_earnings: + try: + interval_filters['earnings__gte'] = int(min_earnings) + interval_filters['earnings__lte'] = int(max_earnings) + except ValueError: + return JsonResponse({"error": "Invalid earnings range."}, status=400) + + # Apply filters + patents = emp_patents.objects.filter( + Q(**filters) & Q(**interval_filters) + ) + all_patents = emp_patents.objects.all() + + # Apply sorting + if sorting: + patents = patents.order_by(sorting) + + # Select specific fields + if fields_of_interest: + fields_of_interest = fields_of_interest.split(', ') + patents = patents.values(*fields_of_interest) + else: + patents = patents.values() + + return JsonResponse(list(patents), safe=False) + +# Sample Filter Input JSON: +# { +# "pf_no": "12345", +# "p_no": "P-56789", +# "title": "AI Patent", +# "status": "Granted", +# "p_year": "2023", +# "a_month": "5", +# "start_date": "2022-01-01", +# "end_date": "2023-12-31", +# "min_earnings": "10000", +# "max_earnings": "50000", +# "sort_by": "-earnings", +# "fields": ["pf_no", "p_no", "title", "status", "earnings"] +# } +@csrf_exempt +def filter_mtechphd_thesis(request): + filters = {} + interval_filters = {} + sorting = request.POST.get("sort_by", None) + fields_of_interest = request.POST.get("fields", None) + + # Extracting filter fields + pf_no = request.POST.get("pf_no") + if pf_no: + filters['pf_no__icontains'] = pf_no + + degree_type = request.POST.get("degree_type") + if degree_type: + try: + filters['degree_type'] = int(degree_type) + except ValueError: + return JsonResponse({"error": "Invalid degree type."}, status=400) + + title = request.POST.get("title") + if title: + filters['title__icontains'] = title + + supervisors = request.POST.get("supervisors") + if supervisors: + filters['supervisors__icontains'] = supervisors + + co_supervisors = request.POST.get("co_supervisors") + if co_supervisors: + filters['co_supervisors__icontains'] = co_supervisors + + rollno = request.POST.get("rollno") + if rollno: + filters['rollno__icontains'] = rollno + + s_name = request.POST.get("s_name") + if s_name: + filters['s_name__icontains'] = s_name + + status = request.POST.get("status") + if status: + filters['status'] = status + + s_year = request.POST.get("s_year") + if s_year: + try: + filters['s_year'] = int(s_year) + except ValueError: + return JsonResponse({"error": "Invalid year format."}, status=400) + + a_month = request.POST.get("a_month") + if a_month: + try: + filters['a_month'] = int(a_month) + except ValueError: + return JsonResponse({"error": "Invalid month format."}, status=400) + + semester = request.POST.get("semester") + if semester: + try: + filters['semester'] = int(semester) + except ValueError: + return JsonResponse({"error": "Invalid semester format."}, status=400) + + # Interval filtering for date fields + start_date = request.POST.get("start_date") + end_date = request.POST.get("end_date") + if start_date and end_date: + try: + interval_filters['start_date__gte'] = datetime.strptime(start_date, '%Y-%m-%d') + interval_filters['end_date__lte'] = datetime.strptime(end_date, '%Y-%m-%d') + except ValueError: + return JsonResponse({"error": "Invalid date format. Use YYYY-MM-DD."}, status=400) + + # Apply filters + thesis = emp_mtechphd_thesis.objects.filter( + Q(**filters) & Q(**interval_filters) + ) + + # Apply sorting + if sorting: + thesis = thesis.order_by(sorting) + + # Select specific fields + if fields_of_interest: + fields_of_interest = fields_of_interest.split(', ') + thesis = thesis.values(*fields_of_interest) + else: + thesis = thesis.values() + + return JsonResponse(list(thesis), safe=False) + +# Sample Filter Input JSON: +# { +# "pf_no": "12345", +# "degree_type": "1", 1 for M.Tech and 2 for Ph.D +# "title": "Deep Learning Thesis", +# "supervisors": "Dr. John", +# "co_supervisors": "Dr. Jane", +# "rollno": "MT2023001", +# "s_name": "Alice", +# "status": "Ongoing", +# "s_year": "2023", +# "a_month": "7", +# "semester": "2", +# "start_date": "2023-01-01", +# "end_date": "2023-12-31", +# "sort_by": "start_date", +# "fields": ["pf_no", "degree_type", "title", "supervisors", "s_name"] +# } +@csrf_exempt +def filter_events(request): + filters = {} + interval_filters = {} + sorting = request.POST.get("sort_by", None) + fields_of_interest = request.POST.get("fields", None) + + # Extracting filter fields + pf_no = request.POST.get("pf_no") + if pf_no: + filters['pf_no__icontains'] = pf_no + + type = request.POST.get("type") + if type: + filters['type'] = type + + name = request.POST.get("name") + if name: + filters['name__icontains'] = name + + sponsoring_agency = request.POST.get("sponsoring_agency") + if sponsoring_agency: + filters['sponsoring_agency__icontains'] = sponsoring_agency + + venue = request.POST.get("venue") + if venue: + filters['venue__icontains'] = venue + + role = request.POST.get("role") + if role: + filters['role'] = role + + # Interval filtering for date fields + start_date = request.POST.get("start_date") + end_date = request.POST.get("end_date") + if start_date and end_date: + try: + interval_filters['start_date__gte'] = datetime.strptime(start_date, '%Y-%m-%d') + interval_filters['end_date__lte'] = datetime.strptime(end_date, '%Y-%m-%d') + except ValueError: + return JsonResponse({"error": "Invalid date format. Use YYYY-MM-DD."}, status=400) + + # Apply filters + events = emp_event_organized.objects.filter( + Q(**filters) & Q(**interval_filters) + ) + + # Apply sorting + if sorting: + events = events.order_by(sorting) + + # Select specific fields + if fields_of_interest: + fields_of_interest = fields_of_interest.split(', ') + events = events.values(*fields_of_interest) + else: + events = events.values() + + return JsonResponse(list(events), safe=False) + +# Sample Filter Input JSON: +# { +# "pf_no": "12345", +# "type": "Workshop", +# "name": "AI Workshop", +# "sponsoring_agency": "DST", +# "venue": "IIIT Campus", +# "role": "Coordinator", +# "start_date": "2023-01-01", +# "end_date": "2023-12-31", +# "sort_by": "start_date", +# "fields": ["pf_no", "type", "name", "sponsoring_agency", "venue", "start_date"] +# } +@csrf_exempt +def filter_visits(request): + filters = {} + interval_filters = {} + sorting = request.POST.get("sort_by", None) + fields_of_interest = request.POST.get("fields", None) + + # Extracting filter fields + pf_no = request.POST.get("pf_no") + if pf_no: + filters['pf_no__icontains'] = pf_no + + v_type = request.POST.get("v_type") + if v_type: + try: + filters['v_type'] = int(v_type) + except ValueError: + return JsonResponse({"error": "v_type must be an integer."}, status=400) + + country = request.POST.get("country") + if country: + filters['country__icontains'] = country + + place = request.POST.get("place") + if place: + filters['place__icontains'] = place + + purpose = request.POST.get("purpose") + if purpose: + filters['purpose__icontains'] = purpose + + # Interval filtering for date fields + v_date = request.POST.get("v_date") + if v_date: + try: + interval_filters['v_date'] = datetime.strptime(v_date, '%Y-%m-%d') + except ValueError: + return JsonResponse({"error": "Invalid v_date format. Use YYYY-MM-DD."}, status=400) + + start_date = request.POST.get("start_date") + end_date = request.POST.get("end_date") + if start_date and end_date: + try: + interval_filters['start_date__gte'] = datetime.strptime(start_date, '%Y-%m-%d') + interval_filters['end_date__lte'] = datetime.strptime(end_date, '%Y-%m-%d') + except ValueError: + return JsonResponse({"error": "Invalid date format for start_date or end_date. Use YYYY-MM-DD."}, status=400) + + # Apply filters + visits = emp_visits.objects.filter( + Q(**filters) & Q(**interval_filters) + ) + + # Apply sorting + if sorting: + visits = visits.order_by(sorting) + + # Select specific fields + if fields_of_interest: + fields_of_interest = fields_of_interest.split(', ') + visits = visits.values(*fields_of_interest) + else: + visits = visits.values() + + return JsonResponse(list(visits), safe=False) + +# Sample Filter Input JSON: +# { +# "pf_no": "12345", +# "v_type": "2", +# "country": "India", +# "place": "Delhi", +# "purpose": "Conference", +# "v_date": "2023-05-01", +# "start_date": "2023-04-01", +# "end_date": "2023-04-30", +# "sort_by": "-start_date", +# "fields": ["pf_no", "country", "place", "purpose", "v_date", "start_date", "end_date"] +# } +@csrf_exempt +def filter_consym(request): + filters = {} + interval_filters = {} + sorting = request.POST.get("sort_by", None) + fields_of_interest = request.POST.get("fields", None) + + # Extracting filter fields + pf_no = request.POST.get("pf_no") + if pf_no: + filters['pf_no__icontains'] = pf_no + + name = request.POST.get("name") + if name: + filters['name__icontains'] = name + + venue = request.POST.get("venue") + if venue: + filters['venue__icontains'] = venue + + k_year = request.POST.get("k_year") + if k_year: + try: + filters['k_year'] = int(k_year) + except ValueError: + return JsonResponse({"error": "k_year must be an integer."}, status=400) + + a_month = request.POST.get("a_month") + if a_month: + try: + filters['a_month'] = int(a_month) + except ValueError: + return JsonResponse({"error": "a_month must be an integer."}, status=400) + + role1 = request.POST.get("role1") + if role1: + filters['role1__iexact'] = role1 + + role2 = request.POST.get("role2") + if role2: + filters['role2__icontains'] = role2 + + # Interval filtering for date fields + start_date = request.POST.get("start_date") + end_date = request.POST.get("end_date") + if start_date and end_date: + try: + interval_filters['start_date__gte'] = datetime.strptime(start_date, '%Y-%m-%d') + interval_filters['end_date__lte'] = datetime.strptime(end_date, '%Y-%m-%d') + except ValueError: + return JsonResponse({"error": "Invalid date format for start_date or end_date. Use YYYY-MM-DD."}, status=400) + + # Apply filters + conferences = emp_confrence_organised.objects.filter( + Q(**filters) & Q(**interval_filters) + ) + + # Apply sorting + if sorting: + conferences = conferences.order_by(sorting) + + # Select specific fields + if fields_of_interest: + fields_of_interest = fields_of_interest.split(', ') + conferences = conferences.values(*fields_of_interest) + else: + conferences = conferences.values() + + return JsonResponse(list(conferences), safe=False) + +# Sample Filter Input JSON: +# { +# "pf_no": "12345", +# "name": "AI Conference", +# "venue": "New Delhi", +# "k_year": "2023", +# "a_month": "5", +# "role1": "Organised", +# "role2": "Keynote Speaker", +# "start_date": "2023-04-01", +# "end_date": "2023-04-30", +# "sort_by": "-start_date", +# "fields": ["pf_no", "name", "venue", "k_year", "a_month", "start_date", "end_date", "role1", "role2"] +# } +@csrf_exempt +def filter_books(request): + filters = {} + sorting = request.POST.get("sort_by", None) + fields_of_interest = request.POST.get("fields", None) + + # Extracting filter fields + pf_no = request.POST.get("pf_no") + if pf_no: + filters['pf_no__icontains'] = pf_no + + p_type = request.POST.get("p_type") + if p_type: + filters['p_type__iexact'] = p_type + + title = request.POST.get("title") + if title: + filters['title__icontains'] = title + + publisher = request.POST.get("publisher") + if publisher: + filters['publisher__icontains'] = publisher + + authors = request.POST.get("authors") + if authors: + filters['authors__icontains'] = authors + + pyear = request.POST.get("pyear") + if pyear: + try: + filters['pyear'] = int(pyear) + except ValueError: + return JsonResponse({"error": "pyear must be an integer."}, status=400) + + # Interval filtering for date fields + start_date = request.POST.get("start_date") + end_date = request.POST.get("end_date") + if start_date and end_date: + try: + filters['publication_date__range'] = ( + datetime.strptime(start_date, '%Y-%m-%d'), + datetime.strptime(end_date, '%Y-%m-%d'), + ) + except ValueError: + return JsonResponse({"error": "Invalid date format for start_date or end_date. Use YYYY-MM-DD."}, status=400) + + # Apply filters + books = emp_published_books.objects.filter(Q(**filters)) + + # Apply sorting + if sorting: + books = books.order_by(sorting) + + # Select specific fields + if fields_of_interest: + fields_of_interest = fields_of_interest.split(', ') + books = books.values(*fields_of_interest) + else: + books = books.values() + + return JsonResponse(list(books), safe=False) + +# Sample Filter Input JSON: +# { +# "pf_no": "12345", +# "p_type": "Book", +# "title": "Artificial Intelligence", +# "publisher": "Tech Publishers", +# "authors": "John Doe", +# "pyear": "2023", +# "start_date": "2023-01-01", +# "end_date": "2023-12-31", +# "sort_by": "-publication_date", +# "fields": ["pf_no", "p_type", "title", "publisher", "authors", "pyear", "publication_date"] +# } +@csrf_exempt +def filter_journal_or_conference(request): + filters = {} + sorting = request.POST.get("sort_by", None) + fields_of_interest = request.POST.get("fields", None) + + # Extracting filter fields + pf_no = request.POST.get("pf_no") + if pf_no: + filters['pf_no__icontains'] = pf_no + + rtype = request.POST.get("rtype") + if rtype: + filters['rtype__iexact'] = rtype + + authors = request.POST.get("authors") + if authors: + filters['authors__icontains'] = authors + + co_authors = request.POST.get("co_authors") + if co_authors: + filters['co_authors__icontains'] = co_authors + + title_paper = request.POST.get("title_paper") + if title_paper: + filters['title_paper__icontains'] = title_paper + + venue = request.POST.get("venue") + if venue: + filters['venue__icontains'] = venue + + is_sci = request.POST.get("is_sci") + if is_sci: + filters['is_sci__iexact'] = is_sci + + status = request.POST.get("status") + if status: + filters['status__iexact'] = status + + year = request.POST.get("year") + if year: + filters['year__iexact'] = year + + # Interval filtering for date fields + start_date = request.POST.get("start_date") + end_date = request.POST.get("end_date") + if start_date and end_date: + try: + filters['date_publication__range'] = ( + datetime.strptime(start_date, '%Y-%m-%d'), + datetime.strptime(end_date, '%Y-%m-%d'), + ) + except ValueError: + return JsonResponse({"error": "Invalid date format for start_date or end_date. Use YYYY-MM-DD."}, status=400) + + # Apply filters + papers = emp_research_papers.objects.filter(Q(**filters)) + + # Apply sorting + if sorting: + papers = papers.order_by(sorting) + + # Select specific fields + if fields_of_interest: + fields_of_interest = fields_of_interest.split(', ') + papers = papers.values(*fields_of_interest) + else: + papers = papers.values() + + return JsonResponse(list(papers), safe=False) + +# Sample Filter Input JSON: +# { +# "pf_no": "12345", +# "rtype": "Journal", +# "authors": "John Doe", +# "co_authors": "Jane Smith", +# "title_paper": "AI Research", +# "venue": "Tech Conference", +# "is_sci": "SCI", +# "status": "Published", +# "year": "2023", +# "start_date": "2023-01-01", +# "end_date": "2023-12-31", +# "sort_by": "-date_publication", +# "fields": ["pf_no", "rtype", "authors", "title_paper", "venue", "date_publication"] +# } +@csrf_exempt +def filter_achievements(request): + filters = {} + sorting = request.POST.get("sort_by", None) + fields_of_interest = request.POST.get("fields", None) + + # Extracting filter fields + pf_no = request.POST.get("pf_no") + if pf_no: + filters['pf_no__icontains'] = pf_no + + a_type = request.POST.get("a_type") + if a_type: + filters['a_type__iexact'] = a_type + + details = request.POST.get("details") + if details: + filters['details__icontains'] = details + + a_day = request.POST.get("a_day") + if a_day: + filters['a_day'] = int(a_day) + + a_month = request.POST.get("a_month") + if a_month: + filters['a_month'] = int(a_month) + + a_year = request.POST.get("a_year") + if a_year: + filters['a_year'] = int(a_year) + + # Interval filtering for achievement_date + start_date = request.POST.get("start_date") + end_date = request.POST.get("end_date") + if start_date and end_date: + try: + filters['achievment_date__range'] = ( + datetime.strptime(start_date, '%Y-%m-%d'), + datetime.strptime(end_date, '%Y-%m-%d'), + ) + except ValueError: + return JsonResponse({"error": "Invalid date format for start_date or end_date. Use YYYY-MM-DD."}, status=400) + + # Apply filters + achievements = emp_achievement.objects.filter(Q(**filters)) + + # Apply sorting + if sorting: + achievements = achievements.order_by(sorting) + + # Select specific fields + if fields_of_interest: + fields_of_interest = fields_of_interest.split(', ') + achievements = achievements.values(*fields_of_interest) + else: + achievements = achievements.values() + + return JsonResponse(list(achievements), safe=False) + +# Sample Filter Input JSON: +{ + "pf_no": "12345", + "a_type": "Award", + "details": "Best Researcher", + "a_day": "15", + "a_month": "8", + "a_year": "2023", + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "sort_by": "-achievment_date", + "fields": ["pf_no", "a_type", "details", "achievment_date"] +} +@csrf_exempt +def filter_talks(request): + filters = {} + sorting = request.POST.get("sort_by", None) + fields_of_interest = request.POST.get("fields", None) + + # Extracting filter fields + pf_no = request.POST.get("pf_no") + if pf_no: + filters['pf_no__icontains'] = pf_no + + l_type = request.POST.get("l_type") + if l_type: + filters['l_type__iexact'] = l_type + + title = request.POST.get("title") + if title: + filters['title__icontains'] = title + + place = request.POST.get("place") + if place: + filters['place__icontains'] = place + + l_year = request.POST.get("l_year") + if l_year: + filters['l_year'] = int(l_year) + + a_month = request.POST.get("a_month") + if a_month: + filters['a_month'] = int(a_month) + + # Interval filtering for lecture date + start_date = request.POST.get("start_date") + end_date = request.POST.get("end_date") + if start_date and end_date: + try: + filters['l_date__range'] = ( + datetime.strptime(start_date, '%Y-%m-%d'), + datetime.strptime(end_date, '%Y-%m-%d'), + ) + except ValueError: + return JsonResponse({"error": "Invalid date format for start_date or end_date. Use YYYY-MM-DD."}, status=400) + + # Apply filters + expert_lectures = emp_expert_lectures.objects.filter(Q(**filters)) + + # Apply sorting + if sorting: + expert_lectures = expert_lectures.order_by(sorting) + + # Select specific fields + if fields_of_interest: + fields_of_interest = fields_of_interest.split(', ') + expert_lectures = expert_lectures.values(*fields_of_interest) + else: + expert_lectures = expert_lectures.values() + + return JsonResponse(list(expert_lectures), safe=False) + +# Sample Filter Input JSON: +# { +# "pf_no": "56789", +# "l_type": "Invited Talk", +# "title": "Machine Learning", +# "place": "New York", +# "l_year": "2023", +# "a_month": "12", +# "start_date": "2023-01-01", +# "end_date": "2023-12-31", +# "sort_by": "-l_date", +# "fields": ["pf_no", "l_type", "title", "place", "l_date"] +# } + + + + + + + + + + + + + + + + +from django.db import connection +from rest_framework.response import Response +from rest_framework.decorators import api_view + +# @csrf_exempt +# @api_view(['GET']) +def get_all_faculty_ids(request): + """ + Fetch all unique id and user_id from the globals_extra_info table where user_type is 'faculty'. + Returns a list of id and user_id combinations. + """ + # try: + # Fetch data using Django ORM + faculty_data = ExtraInfo.objects.filter(user_type='faculty').values('id', 'user_id').order_by('user_id') + + # Convert the QuerySet to a list + response_data = list(faculty_data) + + return JsonResponse(response_data, safe=False) + + # except Exception as e: + # return JsonResponse( + # {"error": f"Failed to fetch faculty IDs: {str(e)}"}, + # status=500 + # ) + +@csrf_exempt +def add_administrative_position(request): + # Get user based on user_id + user = get_object_or_404(faculty_about, user_id=request.POST.get('user_id')) + pf = user.user_id + + # Create new instance or get existing one + if (request.POST.get('position_id')==None or request.POST.get('position_id') == ""): + position = emp_administrative_position() + else: + position = get_object_or_404(emp_administrative_position, id=request.POST.get('position_id')) + + # Update fields + position.pf_no = pf + position.title = request.POST.get('title') + position.description = request.POST.get('description') + position.from_date = request.POST.get('from_date') + position.to_date = request.POST.get('to_date') + position.save() + + return JsonResponse({'success': True}) + +def get_administrative_position(request): + positions = emp_administrative_position.objects.filter(pf_no=request.GET.get("pfNo")).values() + return JsonResponse(list(positions), safe=False) + +@csrf_exempt +def delete_administrative_position(request): + instance = emp_administrative_position.objects.get(pk=request.POST['pk']) + instance.delete() + return JsonResponse({'success': True}) + + + + + + +@csrf_exempt +def add_qualification(request): + """Create or update a qualification entry.""" + # Get user based on user_id + user = get_object_or_404(User, id=request.POST.get('user_id')) + pf = request.POST.get('user_id') + + # Create a new qualification or update an existing one + if request.POST.get('qualification_id') is None or request.POST.get('qualification_id') == "": + qualification = emp_qualifications() + else: + qualification = get_object_or_404(emp_qualifications, id=request.POST.get('qualification_id')) + + # Update fields + qualification.pf_no = pf + qualification.degree = request.POST.get('degree') + qualification.college = request.POST.get('college') + qualification.description = request.POST.get('description') + qualification.save() + + return JsonResponse({'success': True}) + +def get_qualifications(request): + """Fetch all qualifications for a given user (based on pf_no).""" + qualifications = emp_qualifications.objects.filter(pf_no=request.GET.get("pfNo")).values() + return JsonResponse(list(qualifications), safe=False) + +@csrf_exempt +def delete_qualification(request): + """Delete a qualification entry by primary key.""" + instance = get_object_or_404(emp_qualifications, pk=request.POST.get('pk')) + instance.delete() + return JsonResponse({'success': True}) + + + + + + + +@csrf_exempt +def add_honor(request): + """Create or update an honor entry.""" + # Get user based on user_id + user = get_object_or_404(User, id=request.POST.get('user_id')) + pf = request.POST.get('user_id') + + # Create a new honor or update an existing one + if request.POST.get('honor_id') is None or request.POST.get('honor_id') == "": + honor = emp_honors() + else: + honor = get_object_or_404(emp_honors, id=request.POST.get('honor_id')) + + # Update fields + honor.pf_no = pf + honor.title = request.POST.get('title') + honor.period = request.POST.get('period') + honor.description = request.POST.get('description') + honor.save() + + return JsonResponse({'success': True}) + +def get_honors(request): + """Fetch all honors for a given user (based on pf_no).""" + honors = emp_honors.objects.filter(pf_no=request.GET.get("pfNo")).values() + return JsonResponse(list(honors), safe=False) + +@csrf_exempt +def delete_honor(request): + """Delete an honor entry by primary key.""" + instance = get_object_or_404(emp_honors, pk=request.POST.get('pk')) + instance.delete() + return JsonResponse({'success': True}) + + + + + +@csrf_exempt +def add_professional_experience(request): + """Create or update a professional experience entry.""" + # Get user based on user_id + user = get_object_or_404(User, id=request.POST.get('user_id')) + pf = request.POST.get('user_id') + + # Create a new experience or update an existing one + if request.POST.get('experience_id') is None or request.POST.get('experience_id') == "": + experience = emp_professional_experience() + else: + experience = get_object_or_404(emp_professional_experience, id=request.POST.get('experience_id')) + + # Update fields + experience.pf_no = pf + experience.title = request.POST.get('title') + experience.description = request.POST.get('description') + experience.from_date = request.POST.get('from_date') + experience.to_date = request.POST.get('to_date') + experience.save() + + return JsonResponse({'success': True}) + +def get_professional_experiences(request): + """Fetch all professional experiences for a given user (based on pf_no).""" + experiences = emp_professional_experience.objects.filter(pf_no=request.GET.get("pfNo")).values() + return JsonResponse(list(experiences), safe=False) + +@csrf_exempt +def delete_professional_experience(request): + """Delete a professional experience entry by primary key.""" + instance = get_object_or_404(emp_professional_experience, pk=request.POST.get('pk')) + instance.delete() + return JsonResponse({'success': True}) + +from django.middleware.csrf import get_token + +def get_csrf_token(request): + print("here") + return JsonResponse({'csrfToken': get_token(request)}) \ No newline at end of file diff --git a/FusionIIIT/applications/eis/migrations/0001_initial.py b/FusionIIIT/applications/eis/migrations/0001_initial.py index f3dbd4bf3..1f0d14598 100644 --- a/FusionIIIT/applications/eis/migrations/0001_initial.py +++ b/FusionIIIT/applications/eis/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 2025-02-04 20:22 import datetime from django.conf import settings @@ -113,7 +113,7 @@ class Migration(migrations.Migration): ('end_date', models.DateField(blank=True, null=True)), ('date_acceptance', models.DateField(blank=True, null=True)), ('date_publication', models.DateField(blank=True, null=True)), - ('year', models.CharField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], max_length=10, null=True)), + ('year', models.CharField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024), (2025, 2025)], max_length=10, null=True)), ('a_month', models.CharField(blank=True, choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12)], default=1, max_length=500, null=True)), ('doc_id', models.CharField(blank=True, max_length=50, null=True)), ('doc_description', models.CharField(blank=True, max_length=1000, null=True)), @@ -132,7 +132,7 @@ class Migration(migrations.Migration): ('p_type', models.CharField(choices=[('Book', 'Book'), ('Monograph', 'Monograph'), ('Book Chapter', 'Book Chapter'), ('Handbook', 'Handbook'), ('Technical Report', 'Technical Report')], max_length=16)), ('title', models.CharField(default=' ', max_length=2500)), ('publisher', models.CharField(default=' ', max_length=2500)), - ('pyear', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year')), + ('pyear', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024), (2025, 2025)], null=True, verbose_name='year')), ('authors', models.CharField(default=' ', max_length=250)), ('date_entry', models.DateField(blank=True, default=datetime.datetime.now, null=True)), ('publication_date', models.DateField(blank=True, null=True)), @@ -148,7 +148,7 @@ class Migration(migrations.Migration): ('title', models.CharField(max_length=1500)), ('earnings', models.IntegerField(default=0)), ('status', models.CharField(choices=[('Filed', 'Filed'), ('Granted', 'Granted'), ('Published', 'Published'), ('Owned', 'Owned')], max_length=15)), - ('p_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year')), + ('p_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024), (2025, 2025)], null=True, verbose_name='year')), ('a_month', models.IntegerField(blank=True, choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12)], default=1, null=True, verbose_name='Month')), ('date_entry', models.DateField(blank=True, default=datetime.datetime.now, null=True)), ('start_date', models.DateField(blank=True, null=True)), @@ -167,7 +167,7 @@ class Migration(migrations.Migration): ('co_supervisors', models.CharField(blank=True, max_length=250, null=True)), ('rollno', models.CharField(max_length=200)), ('s_name', models.CharField(max_length=5000)), - ('s_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year')), + ('s_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024), (2025, 2025)], null=True, verbose_name='year')), ('a_month', models.IntegerField(blank=True, choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12)], default=1, null=True, verbose_name='Month')), ('date_entry', models.DateField(blank=True, default=datetime.datetime.now, null=True)), ('start_date', models.DateField(blank=True, null=True)), @@ -188,7 +188,7 @@ class Migration(migrations.Migration): ('venue', models.CharField(max_length=1000)), ('page_no', models.CharField(max_length=100)), ('isbn_no', models.CharField(max_length=200)), - ('k_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year')), + ('k_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024), (2025, 2025)], null=True, verbose_name='year')), ('a_month', models.IntegerField(blank=True, choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12)], default=1, null=True, verbose_name='Month')), ('start_date', models.DateField(blank=True, null=True)), ('end_date', models.DateField(blank=True, null=True)), @@ -205,7 +205,7 @@ class Migration(migrations.Migration): ('title', models.CharField(max_length=1000)), ('place', models.CharField(max_length=1000)), ('l_date', models.DateField(blank=True, null=True)), - ('l_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year')), + ('l_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024), (2025, 2025)], null=True, verbose_name='year')), ('a_month', models.IntegerField(blank=True, choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12)], default=1, null=True, verbose_name='Month')), ('date_entry', models.DateField(blank=True, default=datetime.datetime.now, null=True)), ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), @@ -252,7 +252,7 @@ class Migration(migrations.Migration): ('pf_no', models.CharField(max_length=20)), ('name', models.CharField(max_length=500)), ('venue', models.CharField(max_length=500)), - ('k_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year')), + ('k_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024), (2025, 2025)], null=True, verbose_name='year')), ('a_month', models.IntegerField(blank=True, choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12)], default=1, null=True, verbose_name='Month')), ('start_date', models.DateField(blank=True, null=True)), ('end_date', models.DateField(blank=True, null=True)), @@ -271,10 +271,76 @@ class Migration(migrations.Migration): ('details', models.TextField(default=' ', max_length=1550)), ('a_day', models.IntegerField(blank=True, choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15), (16, 16), (17, 17), (18, 18), (19, 19), (20, 20), (21, 21), (22, 22), (23, 23), (24, 24), (25, 25), (26, 26), (27, 27), (28, 28), (29, 29), (30, 30), (31, 31)], null=True, verbose_name='Day')), ('a_month', models.IntegerField(blank=True, choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12)], null=True, verbose_name='Month')), - ('a_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024)], null=True, verbose_name='year')), + ('a_year', models.IntegerField(blank=True, choices=[(1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024), (2025, 2025)], null=True, verbose_name='year')), ('date_entry', models.DateField(default=datetime.datetime.now)), ('achievment_date', models.DateField(blank=True, null=True)), ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), + migrations.CreateModel( + name='emp_qualifications', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('pf_no', models.CharField(max_length=20)), + ('degree', models.CharField(max_length=255)), + ('college', models.CharField(max_length=255)), + ('description', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True, null=True)), + ('updated_at', models.DateTimeField(auto_now=True, null=True)), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'unique_together': {('user', 'degree')}, + }, + ), + migrations.CreateModel( + name='emp_professional_experience', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('pf_no', models.CharField(max_length=20)), + ('title', models.CharField(blank=True, max_length=255, null=True)), + ('description', models.TextField(blank=True, null=True)), + ('from_date', models.DateField(blank=True, null=True)), + ('to_date', models.DateField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True, null=True)), + ('updated_at', models.DateTimeField(auto_now=True, null=True)), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'unique_together': {('user', 'title')}, + }, + ), + migrations.CreateModel( + name='emp_honors', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('pf_no', models.CharField(max_length=20)), + ('title', models.CharField(max_length=255)), + ('period', models.CharField(blank=True, max_length=255, null=True)), + ('description', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True, null=True)), + ('updated_at', models.DateTimeField(auto_now=True, null=True)), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'unique_together': {('user', 'title')}, + }, + ), + migrations.CreateModel( + name='emp_administrative_position', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('pf_no', models.CharField(max_length=20)), + ('title', models.CharField(blank=True, max_length=255, null=True)), + ('description', models.TextField(blank=True, null=True)), + ('from_date', models.DateField(blank=True, null=True)), + ('to_date', models.DateField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True, null=True)), + ('updated_at', models.DateTimeField(auto_now=True, null=True)), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'unique_together': {('user', 'title')}, + }, + ), ] diff --git a/FusionIIIT/applications/eis/models.py b/FusionIIIT/applications/eis/models.py index b43ae974e..20bca8b66 100644 --- a/FusionIIIT/applications/eis/models.py +++ b/FusionIIIT/applications/eis/models.py @@ -3,7 +3,8 @@ from django.contrib.auth.models import User from django.urls import reverse from django.db import models -from applications.globals.models import ExtraInfo +from applications.globals.models import ExtraInfo, Designation, DepartmentInfo, HoldsDesignation, Staff, Faculty, Feedback, Issue_image_directory, IssueImage, Issue, ModuleAccess +from applications.office_module.models import Project_Registration, Project_Extension, Project_Closure, Project_Reallocation class emp_visits(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True,null=True) @@ -396,4 +397,66 @@ class faculty_about(models.Model): linkedin = models.CharField(max_length=100,null=True, blank=True) def __str__(self): - return str(self.user) \ No newline at end of file + return str(self.user) + +class emp_administrative_position(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) + pf_no = models.CharField(max_length=20) + title = models.CharField(max_length=255, null=True, blank=True) + description = models.TextField(null=True, blank=True) + from_date = models.DateField(null=True, blank=True) + to_date = models.DateField(null=True, blank=True) + created_at = models.DateTimeField(null=True, blank=True, auto_now_add=True) + updated_at = models.DateTimeField(null=True, blank=True, auto_now=True) + + class Meta: + unique_together = ('user', 'title') + + def __str__(self): + return f"{self.user.username} - {self.title}" + +class emp_honors(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) + pf_no = models.CharField(max_length=20) + title = models.CharField(max_length=255) # NOT NULL constraint + period = models.CharField(max_length=255, null=True, blank=True) + description = models.TextField(null=True, blank=True) + created_at = models.DateTimeField(null=True, blank=True, auto_now_add=True) + updated_at = models.DateTimeField(null=True, blank=True, auto_now=True) + + class Meta: + unique_together = ('user', 'title') + + def __str__(self): + return f"{self.user.username} - {self.title}" + +class emp_professional_experience(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) + pf_no = models.CharField(max_length=20) + title = models.CharField(max_length=255, null=True, blank=True) + description = models.TextField(null=True, blank=True) + from_date = models.DateField(null=True, blank=True) + to_date = models.DateField(null=True, blank=True) + created_at = models.DateTimeField(null=True, blank=True, auto_now_add=True) + updated_at = models.DateTimeField(null=True, blank=True, auto_now=True) + + class Meta: + unique_together = ('user', 'title') + + def __str__(self): + return f"{self.user.username} - {self.title}" + +class emp_qualifications(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) + pf_no = models.CharField(max_length=20) + degree = models.CharField(max_length=255) + college = models.CharField(max_length=255) + description = models.TextField(null=True, blank=True) + created_at = models.DateTimeField(null=True, blank=True, auto_now_add=True) + updated_at = models.DateTimeField(null=True, blank=True, auto_now=True) + + class Meta: + unique_together = ('user', 'degree') + + def __str__(self): + return f"{self.user.username} - {self.degree} from {self.college}" \ No newline at end of file diff --git a/FusionIIIT/applications/establishment/migrations/0001_initial.py b/FusionIIIT/applications/establishment/migrations/0001_initial.py index d85fe198d..51caaf80b 100644 --- a/FusionIIIT/applications/establishment/migrations/0001_initial.py +++ b/FusionIIIT/applications/establishment/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-07-16 15:44 from django.conf import settings from django.db import migrations, models @@ -10,9 +10,9 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('globals', '0001_initial'), ('auth', '0012_alter_user_first_name_max_length'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ diff --git a/FusionIIIT/applications/estate_module/migrations/0001_initial.py b/FusionIIIT/applications/estate_module/migrations/0001_initial.py index 899dbfccc..7d80b342e 100644 --- a/FusionIIIT/applications/estate_module/migrations/0001_initial.py +++ b/FusionIIIT/applications/estate_module/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-07-16 15:44 from django.conf import settings from django.db import migrations, models diff --git a/FusionIIIT/applications/examination/migrations/0001_initial.py b/FusionIIIT/applications/examination/migrations/0001_initial.py index 9cbd0f6ac..4bc165c9d 100644 --- a/FusionIIIT/applications/examination/migrations/0001_initial.py +++ b/FusionIIIT/applications/examination/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1.5 on 2024-04-18 13:13 +# Generated by Django 3.1.5 on 2024-07-16 15:44 from django.db import migrations, models import django.db.models.deletion @@ -9,7 +9,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('academic_information', '0001_initial'), + ('programme_curriculum', '0001_initial'), ] operations = [ @@ -42,7 +42,7 @@ class Migration(migrations.Migration): ('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')), + ('course_id', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), ], ), ] diff --git a/FusionIIIT/applications/examination/views.py b/FusionIIIT/applications/examination/views.py index 6e7bb47a6..e65f34b3e 100644 --- a/FusionIIIT/applications/examination/views.py +++ b/FusionIIIT/applications/examination/views.py @@ -61,10 +61,10 @@ def exam(request): 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() + 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": + elif request.session.get("currentDesignationSelected") == "acadadmin": return HttpResponseRedirect('/examination/updateGrades/') return HttpResponseRedirect('/dashboard/') diff --git a/FusionIIIT/applications/feeds/migrations/0001_initial.py b/FusionIIIT/applications/feeds/migrations/0001_initial.py index e989d0101..7b794eac6 100644 --- a/FusionIIIT/applications/feeds/migrations/0001_initial.py +++ b/FusionIIIT/applications/feeds/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-07-16 15:44 from django.conf import settings from django.db import migrations, models diff --git a/FusionIIIT/applications/filetracking/admin.py b/FusionIIIT/applications/filetracking/admin.py index 144ac4e2a..af7ed0d4b 100644 --- a/FusionIIIT/applications/filetracking/admin.py +++ b/FusionIIIT/applications/filetracking/admin.py @@ -3,7 +3,7 @@ class FileAdmin(admin.ModelAdmin): - list_display = ('uploader', 'designation', + list_display = ('id', 'uploader', 'designation', 'subject', 'upload_date', 'is_read') search_fields = ('uploader__user__username', 'subject', 'description') list_filter = ('is_read',) diff --git a/FusionIIIT/applications/filetracking/api/urls.py b/FusionIIIT/applications/filetracking/api/urls.py index 139f965ff..720e89b42 100644 --- a/FusionIIIT/applications/filetracking/api/urls.py +++ b/FusionIIIT/applications/filetracking/api/urls.py @@ -1,4 +1,6 @@ -from django.conf.urls import url +from django.urls import path +from django.conf import settings +from django.conf.urls.static import static from .views import ( CreateFileView, ViewFileView, @@ -9,16 +11,24 @@ DraftFileView, CreateDraftFile, GetDesignationsView, + CreateArchiveFile, + ArchiveFileView, + UnArchiveFile, + AjaxDropdownView ) urlpatterns = [ - url(r'^file/$', CreateFileView.as_view(), name='create_file'), - url(r'^file/(?P\d+)/$', ViewFileView.as_view(), name='view_file'), - url(r'^inbox/$', ViewInboxView.as_view(), name='view_inbox'), - url(r'^outbox/$', ViewOutboxView.as_view(), name='view_outbox'), - url(r'^history/(?P\d+)/$', ViewHistoryView.as_view(), name='view_history'), - url(r'^forwardfile/(?P\d+)/$', ForwardFileView.as_view(), name='forward_file'), - url(r'^draft/$', DraftFileView.as_view(), name='view_drafts'), - url(r'^createdraft/$', CreateDraftFile.as_view(), name='create_draft'), - url(r'^designations/(?P\w+)/$', GetDesignationsView.as_view(), name='get_designations'), -] + path('file/', CreateFileView.as_view(), name='create_file'), + path('file//', ViewFileView.as_view(), name='view_file'), + path('inbox/', ViewInboxView.as_view(), name='view_inbox'), + path('outbox/', ViewOutboxView.as_view(), name='view_outbox'), + path('history//', ViewHistoryView.as_view(), name='view_history'), + path('forwardfile//', ForwardFileView.as_view(), name='forward_file'), + path('draft/', DraftFileView.as_view(), name='view_drafts'), + path('createdraft/', CreateDraftFile.as_view(), name='create_draft'), + path('createarchive/', CreateArchiveFile.as_view(), name='archive_file'), + path('unarchive/', UnArchiveFile.as_view(), name='un_archive'), + path('archive/', ArchiveFileView.as_view(), name='view_archived'), + path('designations//', GetDesignationsView.as_view(), name='get_designations'), + path('dropdown/', AjaxDropdownView.as_view(), name='get_dropdown'), +]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/FusionIIIT/applications/filetracking/api/views.py b/FusionIIIT/applications/filetracking/api/views.py index 5f395ab41..1463c18a7 100644 --- a/FusionIIIT/applications/filetracking/api/views.py +++ b/FusionIIIT/applications/filetracking/api/views.py @@ -1,12 +1,16 @@ import logging from venv import logger +from django.core import serializers from django.forms import ValidationError +from django.contrib.auth.models import User from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status, permissions from rest_framework.authentication import TokenAuthentication from ..models import File, Tracking -from ..sdk.methods import create_draft, create_file, view_drafts, view_file, delete_file, view_inbox, view_outbox, view_history, forward_file, get_designations +from applications.globals.models import Designation +from ..sdk.methods import create_draft, create_file, view_drafts, view_file, delete_file, view_inbox, view_outbox, view_history, forward_file, get_designations, archive_file, view_archived, unarchive_file + class CreateFileView(APIView): authentication_classes = [TokenAuthentication] @@ -14,20 +18,40 @@ class CreateFileView(APIView): def post(self, request): try: - current_user = request.user.username + current_user = request.user current_designation = request.data.get('designation') receiver_username = request.data.get('receiver_username') receiver_designation = request.data.get('receiver_designation') subject = request.data.get('subject') description = request.data.get('description') + src_module = request.data.get('src_module') + uploaded_files = request.FILES.getlist('files') # Retrieve the list of files - if None in [current_designation, receiver_username, receiver_designation, subject, description]: + # Check for missing required fields + if None in [current_designation, receiver_username, receiver_designation, subject, description, src_module]: return Response({'error': 'One or more required fields are missing.'}, status=status.HTTP_400_BAD_REQUEST) - file_id = create_file(uploader=current_user, uploader_designation=current_designation, - receiver=receiver_username, receiver_designation=receiver_designation, subject=subject, description=description) + # Process each file in the list + file_ids = [] + for file in uploaded_files: + # Debugging log for each file + print("Processing file: ", file.name) + + # Call your `create_file` function for each file + file_id = create_file( + uploader=current_user, + uploader_designation=current_designation, + receiver=receiver_username, + receiver_designation=receiver_designation, + subject=subject, + description=description, + attached_file=file, # Pass individual file here + src_module=src_module + ) + file_ids.append(file_id) # Store the IDs of the created files + + return Response({'file_ids': file_ids}, status=status.HTTP_201_CREATED) - return Response({'file_id': file_id}, status=status.HTTP_201_CREATED) except Exception as e: return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST) @@ -39,7 +63,7 @@ class ViewFileView(APIView): def get(self, request, file_id): try: file_details = view_file(int(file_id)) - # print(file_details) + print("File: ",file_details) return Response(file_details, status=status.HTTP_200_OK) except ValueError: return Response({'error': 'Invalid file ID format.'}, status=status.HTTP_400_BAD_REQUEST) @@ -47,7 +71,7 @@ def get(self, request, file_id): return Response({'error': 'File not found.'}, status=status.HTTP_404_NOT_FOUND) except Exception as e: return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST) - + def delete(self, request, file_id): try: # file_details = view_file(int(file_id)) @@ -96,8 +120,8 @@ def get(self, request): # if not username or not src_module: # return Response({'error': 'Missing required query parameters: username and src_module.'}, status=400) - inbox_files = view_inbox(username, designation, src_module) + print("inbox viewed", inbox_files) return Response(inbox_files) class ViewOutboxView(APIView): @@ -145,15 +169,21 @@ def get(self, request, file_id): Returns: rest_framework.response.Response: JSON response containing serialized tracking history. """ - try: - history = view_history(file_id) - return Response(history) + tracking_array = [] + histories = view_history(file_id) + for history in histories: + temp_obj_action = history; + temp_obj_action['receiver_id'] = User.objects.get(id=history['receiver_id']).username + temp_obj_action['receive_design'] = Designation.objects.get(id=history['receive_design']).name + tracking_array.append(temp_obj_action) + + return Response(tracking_array) except Tracking.DoesNotExist: - return Response({'error': f'File with ID {file_id} not found.'}, status=404) + return Response({'error': f'File with ID {file_id} not found.'}, status=404) except Exception as e: - logger.error(f"An unexpected error occurred: {e}") - return Response({'error': 'Internal server error.'}, status=500) + logger.error(f"An unexpected error occurred: {e}") + return Response({'error': 'Internal server error.'}, status=500) class ForwardFileView(APIView): # # # Authentication and permission classes (adjust based on your needs) @@ -166,13 +196,15 @@ def post(self, request, file_id): receiver_designation = request.data.get('receiver_designation') file_extra_JSON = request.data.get('file_extra_JSON', {}) remarks = request.data.get('remarks', "") - + print(receiver) + print(receiver_designation) # Validate data if not receiver or not receiver_designation: raise ValidationError("Missing required fields: receiver and receiver_designation") # # Extract and validate file attachment (if present) file_attachment = request.FILES.get('file_attachment') + print(file_attachment) if file_attachment: if file_attachment.size > 10 * 1024 * 1024: # Adjust size limit as needed raise ValidationError("File size exceeds limit (10 MB)") @@ -194,29 +226,39 @@ def post(self, request, file_id): # Return response return Response({'tracking_id': new_tracking_id}, status=status.HTTP_201_CREATED) - + class CreateDraftFile(APIView): authentication_classes = [TokenAuthentication] permission_classes = [permissions.IsAuthenticated] def post(self, request): - uploader = request.data.get('uploader') - uploader_designation = request.data.get('uploader_designation') - src_module = request.data.get('src_module', 'filetracking') + uploader = request.user + uploader_designation = request.data.get('designation') + src_module = request.data.get('src_module') src_object_id = request.data.get('src_object_id', '') - file_extra_JSON = request.data.get('file_extra_JSON', {}) - attached_file = request.FILES.get('attached_file', None) + uploaded_files = request.FILES.getlist('files') # Retrieve multiple files + print(uploader_designation, src_module) + # Validate required fields + if None in [uploader_designation, src_module] or not uploaded_files: + return Response({'error': 'One or more required fields are missing.'}, status=status.HTTP_400_BAD_REQUEST) + draft_file_ids = [] try: - file_id = create_draft( - uploader=uploader, - uploader_designation=uploader_designation, - src_module=src_module, - src_object_id=src_object_id, - file_extra_JSON=file_extra_JSON, - attached_file=attached_file - ) - return Response({'file_id': file_id}, status=status.HTTP_201_CREATED) + for file in uploaded_files: + # Debugging log for each file + print("Processing draft file:", file.name) + + file_id = create_draft( + uploader=uploader, + uploader_designation=uploader_designation, + src_module=src_module, + src_object_id=src_object_id, + attached_file=file # Pass individual file + ) + draft_file_ids.append(file_id) # Collect created draft file IDs + print(draft_file_ids) + return Response({'file_ids': draft_file_ids}, status=status.HTTP_201_CREATED) + except Exception as e: return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) @@ -235,13 +277,80 @@ def get(self, request): return Response(draft_files, status=status.HTTP_200_OK) except Exception as e: return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + +class ArchiveFileView(APIView): + authentication_classes = [TokenAuthentication] + permission_classes = [permissions.IsAuthenticated] + def get(self, request): + username = request.query_params.get('username') + designation = request.query_params.get('designation', '') + src_module = request.query_params.get('src_module') + try: + archived_files = view_archived(username, designation, src_module) + return Response(archived_files, status=status.HTTP_200_OK) + except Exception as e: + return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + +class CreateArchiveFile(APIView): + authentication_classes = [TokenAuthentication] + permission_classes = [permissions.IsAuthenticated] + + def post(self, request): + file_id = request.data.get('file_id', None) + + if file_id is None: + return Response({'error': 'Missing file_id'}, status=status.HTTP_400_BAD_REQUEST) + + try: + success = archive_file(file_id) + if success: + return Response({'success': True}) + else: + return Response({'error': 'File does not exist'}, status=status.HTTP_404_NOT_FOUND) + + except Exception as e: + return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + +class UnArchiveFile(APIView): + authentication_classes = [TokenAuthentication] + permission_classes = [permissions.IsAuthenticated] + + def post(self, request): + file_id = request.data.get('file_id', None) + + if file_id is None: + return Response({'error': 'Missing file_id'}, status=status.HTTP_400_BAD_REQUEST) + + try: + success = unarchive_file(file_id) + if success: + return Response({'success': True}) + else: + return Response({'error': 'File does not exist'}, status=status.HTTP_404_NOT_FOUND) + + except Exception as e: + return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) class GetDesignationsView(APIView): - #authentication_classes = [TokenAuthentication] - #permission_classes = [permissions.IsAuthenticated] + authentication_classes = [TokenAuthentication] + permission_classes = [permissions.IsAuthenticated] def get(self, request, username, *args, **kwargs): user_designations = get_designations(username) return Response({'designations': user_designations}) + +class AjaxDropdownView(APIView): + authentication_classes = [TokenAuthentication] + permission_classes = [permissions.IsAuthenticated] + """ + Returns usernames of receivers that match the search input. + """ + + def post(self, request): + value = request.data.get('value', '') # Default to empty string if missing + users = User.objects.filter(username__startswith=value) + users_json = serializers.serialize('json', users) + return Response({"users": users_json}) diff --git a/FusionIIIT/applications/filetracking/migrations/0001_initial.py b/FusionIIIT/applications/filetracking/migrations/0001_initial.py index 3375630f7..56a210012 100644 --- a/FusionIIIT/applications/filetracking/migrations/0001_initial.py +++ b/FusionIIIT/applications/filetracking/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-07-16 15:44 from django.conf import settings from django.db import migrations, models @@ -10,8 +10,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('globals', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ diff --git a/FusionIIIT/applications/filetracking/models.py b/FusionIIIT/applications/filetracking/models.py index 87f91ced8..6dbfd04eb 100644 --- a/FusionIIIT/applications/filetracking/models.py +++ b/FusionIIIT/applications/filetracking/models.py @@ -12,7 +12,7 @@ class File(models.Model): subject = models.CharField(max_length=100, null=True, blank=True) description = models.CharField(max_length=400, null=True, blank=True) upload_date = models.DateTimeField(auto_now_add=True) - upload_file = models.FileField(blank=True) + upload_file = models.FileField(blank=True) # if you want to access the attachment, use this field, not attached_file or uploaded_file. is_read = models.BooleanField(default = False) diff --git a/FusionIIIT/applications/filetracking/sdk/methods.py b/FusionIIIT/applications/filetracking/sdk/methods.py index b01a7a77e..0d97f8db5 100644 --- a/FusionIIIT/applications/filetracking/sdk/methods.py +++ b/FusionIIIT/applications/filetracking/sdk/methods.py @@ -8,15 +8,15 @@ def create_file( - uploader: str, uploader_designation: str, receiver: str, receiver_designation: str, - subject: str = "", - description: str = "", - src_module: str = "filetracking", - src_object_id: str = "", + src_module: str = "", file_extra_JSON: dict = {}, + uploader: str = "", + subject: str = "", + description: str = "", + src_object_id: str = "", attached_file: Any = None) -> int: ''' This function is used to create a file object corresponding to any object of a module that needs to be tracked @@ -29,7 +29,7 @@ def create_file( if both complete then return id of file else raise error - also, delete file object if tracking isnt created + also, delete file object if tracking isn't created ''' uploader_user_obj = get_user_object_from_username(uploader) uploader_extrainfo_obj = get_ExtraInfo_object_from_username(uploader) @@ -48,7 +48,6 @@ def create_file( src_object_id=src_object_id, file_extra_JSON=file_extra_JSON, ) - if attached_file is not None: new_file.upload_file.save(attached_file.name, attached_file, save=True) @@ -108,7 +107,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) @@ -142,8 +141,12 @@ def view_outbox(username: str, designation: str, src_module: str) -> list: # remove duplicate file ids (from sending back and forth) sent_files_unique = uniqueList(sent_files) - sent_files_serialized = FileHeaderSerializer(sent_files_unique, many=True) - return sent_files_serialized.data + sent_files_serialized = list(FileHeaderSerializer( + sent_files_unique, many=True).data) + # for file in sent_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 sent_files_serialized @@ -167,7 +170,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] @@ -205,7 +208,7 @@ def unarchive_file(file_id: int) -> bool: def create_draft( uploader: str, uploader_designation: str, - src_module: str = "filetracking", + src_module: str = "", src_object_id: str = "", file_extra_JSON: dict = {}, attached_file: Any = None) -> int: @@ -214,10 +217,15 @@ def create_draft( It is similar to create_file but is not sent to anyone Later this file can be sent to someone by forward_file by using draft file_id ''' + uploader_user_obj = get_user_object_from_username(uploader) uploader_extrainfo_obj = get_ExtraInfo_object_from_username(uploader) uploader_designation_obj = Designation.objects.get( name=uploader_designation) - + print(uploader) + print(uploader_designation) + print(src_module) + if file_extra_JSON is None: + file_extra_JSON = {} new_file = File.objects.create( uploader=uploader_extrainfo_obj, designation=uploader_designation_obj, @@ -236,7 +244,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 b1e4b19ba..7b56041a6 100644 --- a/FusionIIIT/applications/filetracking/urls.py +++ b/FusionIIIT/applications/filetracking/urls.py @@ -11,9 +11,9 @@ url(r'^draftdesign/$', views.draft_design, name='draft_design'), url(r'^drafts/(?P\d+)$', views.drafts_view, name='drafts_view'), url(r'^outbox/(?P\d+)$', views.outbox_view, name='outbox_view'), - url(r'^inbox/(?P\d+)$', views.inbox_view, name='inbox_view'), - url(r'^outward/$', views.outward, name='outward'), - url(r'^inward/$', views.inward, name='inward'), + url(r'^inbox/$', views.inbox_view, name='inbox_view'), + url(r'^outward/$', views.outbox_view, name='outward'), + url(r'^inward/$', views.inbox_view, name='inward'), url(r'^confirmdelete/(?P\d+)$', views.confirmdelete, name='confirm_delete'), url(r'^archive/(?P\d+)/$', views.archive_view, name='archive_view'), @@ -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,6 +38,7 @@ 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 31c166e5e..0bba0d9a1 100644 --- a/FusionIIIT/applications/filetracking/views.py +++ b/FusionIIIT/applications/filetracking/views.py @@ -1,21 +1,33 @@ -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 django.core.paginator import Paginator + +from .models import File, Tracking +from applications.globals.models import ExtraInfo, HoldsDesignation, Designation +from .utils import * from .sdk.methods import * from .decorators import * +from datetime import datetime; + +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 +55,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 +70,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 +123,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 +139,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 +167,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 +193,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 +207,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,31 +228,33 @@ 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") -def outbox_view(request, id): +@user_is_student +@dropdown_designation_valid +def outbox_view(request): """ - The function is used to get all the files sent by user(employee) to other employees - which are filtered from Tracking(table) objects by current user i.e. current_id. - It displays files sent by user to other employees of a Tracking(table) of filetracking(model) - in the 'Outbox' tab of template. - - @param: - request - trivial. - id - user id - - @variables: - outward_files - File objects filtered by current_id i.e, present working user. - context - Holds data needed to make necessary changes in the template. + The function is used to get all the files sent by user(employee) to other employees + which are filtered from Tracking(table) objects by current user i.e. current_id. + It displays files sent by user to other employees of a Tracking(table) of filetracking(model) + in the 'Outbox' tab of template. + @param: + request - trivial. + id - user id + @variables: + outward_files - File objects filtered by current_id i.e, present working user. + context - Holds data needed to make necessary changes in the template. """ - user_HoldsDesignation_obj = HoldsDesignation.objects.select_related( - 'user', 'working', 'designation').get(pk=id) + dropdown_design = request.session.get('currentDesignationSelected', 'default_value') + username = request.user + user_HoldsDesignation_obj = get_HoldsDesignation_obj(username, dropdown_design) s = str(user_HoldsDesignation_obj).split(" - ") designation = s[1] @@ -255,26 +269,41 @@ def outbox_view(request, id): f['sent_to_user'] = last_forw_tracking.receiver_id f['sent_to_design'] = last_forw_tracking.receive_design f['last_sent_date'] = last_forw_tracking.forward_date - f['upload_date'] = parse_datetime(f['upload_date']) f['uploader'] = get_extra_info_object_from_id(f['uploader']) - outward_files = add_uploader_department_to_files_list(outward_files) - user_HoldsDesignation_obj = HoldsDesignation.objects.select_related( - 'user', 'working', 'designation').get(pk=id) - s = str(user_HoldsDesignation_obj).split(" - ") - designation = s[1] + subject_query = request.GET.get('subject', '') + sent_to_query = request.GET.get('sent_to', '') + date_query = request.GET.get('date', '') + + if subject_query: + outward_files = [f for f in outward_files if subject_query.lower() in f['subject'].lower()] + if sent_to_query: + outward_files = [f for f in outward_files if sent_to_query.lower() in f['sent_to_user'].username.lower()] + if date_query: + try: + search_date = datetime.strptime(date_query, '%Y-%m-%d') + outward_files = [f for f in outward_files if f['last_sent_date'].date() == search_date.date()] + except ValueError: + outward_files = [] # Invalid date format + + paginator = Paginator(outward_files, 10) + page_number = request.GET.get('page') + page_obj = paginator.get_page(page_number) context = { - 'out_files': outward_files, + 'page_obj': page_obj, '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") -def inbox_view(request, id): +@user_is_student +@dropdown_designation_valid +def inbox_view(request): """ The function is used to fetch the files received by the user form other employees. These files are filtered by receiver id and ordered by receive date. @@ -288,9 +317,11 @@ def inbox_view(request, id): context - Holds data needed to make necessary changes in the template. """ - - user_HoldsDesignation_obj = HoldsDesignation.objects.select_related( - 'user', 'working', 'designation').get(pk=id) + dropdown_design = request.session.get( + 'currentDesignationSelected', 'default_value') + username = request.user + user_HoldsDesignation_obj = get_HoldsDesignation_obj( + username, dropdown_design) s = str(user_HoldsDesignation_obj).split(" - ") designation = s[1] inward_files = view_inbox( @@ -308,18 +339,42 @@ def inbox_view(request, id): designation=user_HoldsDesignation_obj.designation) f['receive_date'] = last_recv_tracking.receive_date f['uploader'] = get_extra_info_object_from_id(f['uploader']) + f['is_forwarded'] = (False if (str(get_current_file_owner(f['id']).username) == str(user_HoldsDesignation_obj.user)) else True) + inward_files = add_uploader_department_to_files_list(inward_files) + subject_query = request.GET.get('subject', '') + sent_to_query = request.GET.get('sent_to', '') + date_query = request.GET.get('date', '') + + if subject_query: + inward_files = [f for f in inward_files if subject_query.lower() in f['subject'].lower()] + if sent_to_query: + inward_files = [f for f in inward_files if sent_to_query.lower() in f['sent_to_user'].username.lower()] + if date_query: + try: + search_date = datetime.strptime(date_query, '%Y-%m-%d') + inward_files = [f for f in inward_files if f['last_sent_date'].date() == search_date.date()] + except ValueError: + inward_files = [] # Invalid date format + + paginator = Paginator(inward_files, 10) + page_number = request.GET.get('page') + page_obj = paginator.get_page(page_number) + context = { - 'in_file': inward_files, + 'page_obj': page_obj, '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 +394,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 +413,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 +435,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. @@ -411,30 +472,35 @@ def view_file(request, id): current_owner = get_current_file_owner(file.id) file_uploader = get_user_object_from_username(file.uploader.user.username) + last_receiver_designation = get_current_file_owner_designation(file.id).name if current_owner == request.user and file.is_read is False: forward_enable = True - if current_owner == request.user and file_uploader == request.user and file.is_read is False: + if current_owner == request.user and last_receiver_designation == file.designation.name 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 +513,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 +545,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 +577,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 +595,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 +617,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 +627,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 +654,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 +692,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 +710,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 +725,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 +745,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 +758,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 +793,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 +813,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 +831,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 +881,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 +939,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 +954,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 +975,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 +1011,63 @@ def edit_draft_view(request, id, *args, **kwargs): return render(request, 'filetracking/editdraft.html', context) - \ No newline at end of file +@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/finance_accounts/migrations/0001_initial.py b/FusionIIIT/applications/finance_accounts/migrations/0001_initial.py index 8d45f1fc1..7bcb45aba 100644 --- a/FusionIIIT/applications/finance_accounts/migrations/0001_initial.py +++ b/FusionIIIT/applications/finance_accounts/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-07-16 15:44 from django.db import migrations, models diff --git a/FusionIIIT/applications/globals/admin.py b/FusionIIIT/applications/globals/admin.py index 8ee73973e..ba595e235 100644 --- a/FusionIIIT/applications/globals/admin.py +++ b/FusionIIIT/applications/globals/admin.py @@ -1,7 +1,7 @@ from django.contrib import admin from .models import (DepartmentInfo, Designation, ExtraInfo, Faculty, Feedback, - HoldsDesignation, Issue, IssueImage, Staff) + HoldsDesignation, Issue, IssueImage, Staff,ModuleAccess) # Register your models here. @@ -22,4 +22,5 @@ class HoldsDesignationAdmin(admin.ModelAdmin): admin.site.register(Faculty) admin.site.register(DepartmentInfo) admin.site.register(Designation) +admin.site.register(ModuleAccess) admin.site.register(HoldsDesignation, HoldsDesignationAdmin) diff --git a/FusionIIIT/applications/globals/api/urls.py b/FusionIIIT/applications/globals/api/urls.py index e6683eac7..f25b901b9 100644 --- a/FusionIIIT/applications/globals/api/urls.py +++ b/FusionIIIT/applications/globals/api/urls.py @@ -1,4 +1,6 @@ from django.conf.urls import url +from django.urls import path +from .views import department_info from . import views @@ -6,6 +8,8 @@ url(r'^auth/login/', views.login, name='login-api'), url(r'^auth/logout/', views.logout, name='logout-api'), + url(r'^auth/me', views.auth_view, name='auth-api'), + url(r'^update-role/', views.update_last_selected_role, name='update_last_selected_role'), # generic profile endpoint #code of corresponding view is modifiedtemporary because of mismatched designations url(r'^profile/(?P.+)/', views.profile, name='profile-api'), @@ -14,9 +18,12 @@ url(r'^profile_update/', views.profile_update, name='update-profile-api'), url(r'^profile_delete/(?P[0-9]+)/', views.profile_delete, name='delete-profile-api'), - url(r'^dashboard/',views.dashboard,name='dashboard-api'), url(r'^notification/',views.notification,name='notification'), - url(r'^notification/read',views.NotificationRead,name='notifications-read') - + url(r'^notificationread',views.NotificationRead,name='notifications-read'), + url(r'^notificationdelete',views.delete_notification,name='notifications-delete'), + url(r'^notificationunread',views.NotificationUnread,name='notifications-unread'), + url(r'^search-users/', views.search_users, name='search_users'), + # url(r'^department-info/', views.department_info, name='department_info'), + path('department-info/', department_info, name='department-info'), ] diff --git a/FusionIIIT/applications/globals/api/views.py b/FusionIIIT/applications/globals/api/views.py index c8fd9f5b1..048cb47b5 100644 --- a/FusionIIIT/applications/globals/api/views.py +++ b/FusionIIIT/applications/globals/api/views.py @@ -14,11 +14,12 @@ from rest_framework.decorators import api_view, permission_classes,authentication_classes from rest_framework.permissions import AllowAny from rest_framework.response import Response +from django.http import JsonResponse from . import serializers from applications.globals.models import (ExtraInfo, Feedback, HoldsDesignation, - Issue, IssueImage, DepartmentInfo) + Issue, IssueImage, DepartmentInfo, ModuleAccess) from .utils import get_and_authenticate_user from notifications.models import Notification @@ -71,13 +72,15 @@ def logout(request): return Response(data=resp, status=status.HTTP_200_OK) @api_view(['GET']) -@permission_classes([IsAuthenticated]) -@authentication_classes([TokenAuthentication]) -def dashboard(request): +@permission_classes([AllowAny]) +def auth_view(request): user=request.user - name = request.user.first_name +"_"+ request.user.last_name + roll_no = request.user.username + extra_info = get_object_or_404(ExtraInfo, user=user) + last_selected_role = extra_info.last_selected_role + designation_list = list(HoldsDesignation.objects.all().filter(working = request.user).values_list('designation')) designation_id = [designation for designations in designation_list for designation in designations] designation_info = [] @@ -85,26 +88,36 @@ def dashboard(request): name_ = get_object_or_404(Designation, id = id) designation_info.append(str(name_.name)) - notifications=serializers.NotificationSerializer(request.user.notifications.all(),many=True).data - club_details= coordinator_club(request) + print(designation_info) + accessible_modules = {} + + for designation in designation_info: + module_access = ModuleAccess.objects.filter(designation__iexact=designation).first() + if module_access: + filtered_modules = {} + field_names = [field.name for field in ModuleAccess._meta.get_fields() if field.name not in ['id', 'designation']] + + for field_name in field_names: + filtered_modules[field_name] = getattr(module_access, field_name) + + accessible_modules[designation] = filtered_modules + resp={ - 'notifications':notifications, - 'desgination_info' : designation_info, - 'club_details' : club_details + 'designation_info' : designation_info, + 'name': name, + 'roll_no': roll_no, + 'accessible_modules': accessible_modules, + 'last_selected_role': last_selected_role } - + return Response(data=resp,status=status.HTTP_200_OK) @api_view(['GET']) @permission_classes([IsAuthenticated]) @authentication_classes([TokenAuthentication]) def notification(request): - - print(request) notifications=serializers.NotificationSerializer(request.user.notifications.all(),many=True).data - print("get") - print(notifications) resp={ 'notifications':notifications, @@ -112,17 +125,39 @@ def notification(request): return Response(data=resp,status=status.HTTP_200_OK) +@api_view(['PATCH']) +@permission_classes([IsAuthenticated]) +def update_last_selected_role(request): + new_role = request.data.get('last_selected_role') + + if new_role is None: + return Response({'error': 'last_selected_role is required'}, status=status.HTTP_400_BAD_REQUEST) + + extra_info = get_object_or_404(ExtraInfo, user=request.user) + + extra_info.last_selected_role = new_role + extra_info.save() + + return Response({'message': 'last_selected_role updated successfully'}, status=status.HTTP_200_OK) + +# This API is only for student profile. For faculty profile, use eis_profile views @api_view(['GET']) 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 + std_sem = Student.objects.get(id=student.id).curr_semester_no + skills = list( + Has.objects.filter(unique_id_id=student) + .select_related("skill_id") + .values("skill_id__skill", "skill_rating") + ) + formatted_skills = [ + {"skill_name": skill["skill_id__skill"], "skill_rating": skill["skill_rating"]} + for skill in skills + ] education = serializers.EducationSerializer(student.education_set.all(), many=True).data course = serializers.CourseSerializer(student.course_set.all(), many=True).data experience = serializers.ExperienceSerializer(student.experience_set.all(), many=True).data @@ -132,9 +167,9 @@ def profile(request, username=None): patent = serializers.PatentSerializer(student.patent_set.all(), many=True).data current = serializers.HoldsDesignationSerializer(user.current_designation.all(), many=True).data resp = { - 'user' : user_detail, 'profile' : profile, - 'skills' : skills, + 'semester_no' : std_sem, + 'skills' : formatted_skills, 'education' : education, 'course' : course, 'experience' : experience, @@ -145,15 +180,8 @@ def profile(request, username=None): 'current' : current } 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 = { - 'user' : user_detail, - 'profile' : profile, - } - return Response(data=resp, status=status.HTTP_200_OK) + else: + return Response(data={'error': 'User is not a student'}, status=status.HTTP_400_BAD_REQUEST) @api_view(['PUT']) def profile_update(request): @@ -177,11 +205,26 @@ def profile_update(request): return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) elif 'skillsubmit' in request.data: - serializer = serializers.HasSerializer(data=request.data['skillsubmit']) - if serializer.is_valid(): - serializer.save(unique_id=student) - return Response(serializer.data, status=status.HTTP_200_OK) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + try: + skill_data = request.data['skillsubmit'] + skill_id = skill_data['skill_id'] + skill_name = skill_id['skill_name'] + skill_rating = skill_data['skill_rating'] + + if not skill_name or skill_rating is None: + return Response({"error": "Missing skill_name or skill_rating"}, status=status.HTTP_400_BAD_REQUEST) + + skill, created = Skill.objects.get_or_create(skill=skill_name) + has_obj, created = Has.objects.get_or_create(skill_id=skill, unique_id=student, defaults={"skill_rating": skill_rating}) + if not created: + has_obj.skill_rating = skill_rating + has_obj.save() + + return Response({"message": "Skill added successfully"}, status=status.HTTP_200_OK) + + except Exception as e: + return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + elif 'achievementsubmit' in request.data: request.data['achievementsubmit']['unique_id'] = profile serializer = serializers.AchievementSerializer(data=request.data['achievementsubmit']) @@ -306,4 +349,74 @@ def NotificationRead(request): response ={ 'error':'Failed, notification is not marked as seen.' } - return Response(response,status=status.HTTP_404_NOT_FOUND) \ No newline at end of file + return Response(response,status=status.HTTP_404_NOT_FOUND) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def NotificationUnread(request): + try: + notifId = int(request.data['id']) + user = request.user + notification = get_object_or_404(Notification, recipient=user, id=notifId) + if not notification.unread: + notification.unread = True + notification.save() + response = { + 'message': 'Notification successfully marked as unread.' + } + return Response(response, status=status.HTTP_200_OK) + except: + response = { + 'error': 'Failed to mark the notification as unread.' + } + return Response(response, status=status.HTTP_404_NOT_FOUND) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def delete_notification(request): + try: + notifId = int(request.data['id']) + notification = get_object_or_404(Notification, recipient=request.user, id=notifId) + + notification.deleted = True + notification.save() + + response = { + 'message': 'Notification marked as deleted.' + } + return Response(response, status=status.HTTP_200_OK) + except Exception as e: + response = { + 'error': 'Failed to mark the notification as deleted.', + 'details': str(e) + } + return Response(response, status=status.HTTP_400_BAD_REQUEST) + + +def search_users(request): + query = request.GET.get('q', '') + if query: + users = ExtraInfo.objects.filter(user__username__icontains=query).values('id', 'user__username') + else: + users = ExtraInfo.objects.none() + + results = [ + {'id': user['id'], 'text': user['user__username']} for user in users + ] + return JsonResponse({'results': results}) + +@api_view(['GET']) # Declare that this view handles GET requests +@permission_classes([]) # No permissions required +@authentication_classes([]) # No authentication required +def department_info(request): + """ + Retrieve department information and return as JSON. + """ + try: + departments = DepartmentInfo.objects.all() # Fetch all department objects + serializer = serializers.DepartmentInfoSerializer(departments, many=True) # Serialize the data + return Response(serializer.data, status=status.HTTP_200_OK) # Return serialized data as JSON + except Exception as e: + return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) diff --git a/FusionIIIT/applications/globals/migrations/0001_initial.py b/FusionIIIT/applications/globals/migrations/0001_initial.py index 7fc43ccef..f67ff0834 100644 --- a/FusionIIIT/applications/globals/migrations/0001_initial.py +++ b/FusionIIIT/applications/globals/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-07-16 15:44 import applications.globals.models import datetime @@ -106,7 +106,7 @@ class Migration(migrations.Migration): ('working', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='current_designation', to=settings.AUTH_USER_MODEL)), ], options={ - 'unique_together': {('working', 'designation'), ('user', 'designation')}, + 'unique_together': {('user', 'designation'), ('working', 'designation')}, }, ), - ] + ] \ No newline at end of file diff --git a/FusionIIIT/applications/globals/migrations/0002_auto_20241007_2302.py b/FusionIIIT/applications/globals/migrations/0002_auto_20241007_2302.py new file mode 100644 index 000000000..9c732169d --- /dev/null +++ b/FusionIIIT/applications/globals/migrations/0002_auto_20241007_2302.py @@ -0,0 +1,44 @@ +# Generated by Django 3.1.5 on 2024-10-07 23:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('globals', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='ModuleAccess', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('designation', models.CharField(max_length=155)), + ('program_and_curriculum', models.BooleanField(default=False)), + ('course_registration', models.BooleanField(default=False)), + ('course_management', models.BooleanField(default=False)), + ('other_academics', models.BooleanField(default=False)), + ('spacs', models.BooleanField(default=False)), + ('department', models.BooleanField(default=False)), + ('examinations', models.BooleanField(default=False)), + ('hr', models.BooleanField(default=False)), + ('iwd', models.BooleanField(default=False)), + ('complaint_management', models.BooleanField(default=False)), + ('fts', models.BooleanField(default=False)), + ('purchase_and_store', models.BooleanField(default=False)), + ('rspc', models.BooleanField(default=False)), + ('hostel_management', models.BooleanField(default=False)), + ('mess_management', models.BooleanField(default=False)), + ('gymkhana', models.BooleanField(default=False)), + ('placement_cell', models.BooleanField(default=False)), + ('visitor_hostel', models.BooleanField(default=False)), + ('phc', models.BooleanField(default=False)), + ], + ), + migrations.AddField( + model_name='extrainfo', + name='last_selected_role', + field=models.CharField(blank=True, max_length=20, null=True), + ), + ] \ No newline at end of file diff --git a/FusionIIIT/applications/globals/models.py b/FusionIIIT/applications/globals/models.py index d51fbcb69..6a924ceff 100644 --- a/FusionIIIT/applications/globals/models.py +++ b/FusionIIIT/applications/globals/models.py @@ -65,10 +65,10 @@ class Constants: ('academic', 'Academic Designation'), ('administrative', 'Administrative Designation'), ) - USER_STATUS = { + USER_STATUS = ( ("NEW", "NEW"), ("PRESENT", "PRESENT"), - } + ) class Designation(models.Model): @@ -152,6 +152,7 @@ class ExtraInfo(models.Model): null=True, blank=True, upload_to='globals/profile_pictures') about_me = models.TextField(default='NA', max_length=1000, blank=True) date_modified = models.DateTimeField('date_updated', blank=True, null=True) + last_selected_role = models.CharField(max_length=20, null=True, blank=True) @property def age(self): @@ -310,3 +311,30 @@ class Issue(models.Model): """ End of feedback and bug report models""" + + + +class ModuleAccess(models.Model): + designation = models.CharField(max_length=155) + program_and_curriculum = models.BooleanField(default=False) + course_registration = models.BooleanField(default=False) + course_management = models.BooleanField(default=False) + other_academics = models.BooleanField(default=False) + spacs = models.BooleanField(default=False) + department = models.BooleanField(default=False) + examinations = models.BooleanField(default=False) + hr = models.BooleanField(default=False) + iwd = models.BooleanField(default=False) + complaint_management = models.BooleanField(default=False) + fts = models.BooleanField(default=False) + purchase_and_store = models.BooleanField(default=False) + rspc = models.BooleanField(default=False) + hostel_management = models.BooleanField(default=False) + mess_management = models.BooleanField(default=False) + gymkhana = models.BooleanField(default=False) + placement_cell = models.BooleanField(default=False) + visitor_hostel = models.BooleanField(default=False) + phc = models.BooleanField(default=False) + + def __str__(self): + return self.designation diff --git a/FusionIIIT/applications/globals/static/globals/css/package.json b/FusionIIIT/applications/globals/static/globals/css/package.json index f595cc60a..2d78ac5f3 100644 --- a/FusionIIIT/applications/globals/static/globals/css/package.json +++ b/FusionIIIT/applications/globals/static/globals/css/package.json @@ -15,6 +15,7 @@ "url": "https://github.com/Semantic-Org/Semantic-UI/issues" }, "dependencies": { - "jquery": "x.*" + "jquery": "x.*", + "semantic-ui-css": "file:" } -} \ No newline at end of file +} diff --git a/FusionIIIT/applications/globals/static/globals/img/Designer.jpg b/FusionIIIT/applications/globals/static/globals/img/Designer.jpg new file mode 100644 index 000000000..ee8305b77 Binary files /dev/null and b/FusionIIIT/applications/globals/static/globals/img/Designer.jpg differ diff --git a/FusionIIIT/applications/globals/static/globals/img/Designer.png b/FusionIIIT/applications/globals/static/globals/img/Designer.png new file mode 100644 index 000000000..c8c2bdf00 Binary files /dev/null and b/FusionIIIT/applications/globals/static/globals/img/Designer.png differ diff --git a/FusionIIIT/applications/globals/static/globals/img/LHTC.jpg b/FusionIIIT/applications/globals/static/globals/img/LHTC.jpg new file mode 100644 index 000000000..7cc2a7731 Binary files /dev/null and b/FusionIIIT/applications/globals/static/globals/img/LHTC.jpg differ diff --git a/FusionIIIT/applications/globals/static/globals/img/fusion.png b/FusionIIIT/applications/globals/static/globals/img/fusion.png new file mode 100644 index 000000000..3de95db63 Binary files /dev/null and b/FusionIIIT/applications/globals/static/globals/img/fusion.png differ diff --git a/FusionIIIT/applications/globals/static/globals/img/fusion_icon.png b/FusionIIIT/applications/globals/static/globals/img/fusion_icon.png new file mode 100644 index 000000000..195e9ded8 Binary files /dev/null and b/FusionIIIT/applications/globals/static/globals/img/fusion_icon.png differ diff --git a/FusionIIIT/applications/globals/static/semantic/tasks/config/admin/templates/package.json b/FusionIIIT/applications/globals/static/semantic/tasks/config/admin/templates/package.json index 5d967850d..9063404bc 100644 --- a/FusionIIIT/applications/globals/static/semantic/tasks/config/admin/templates/package.json +++ b/FusionIIIT/applications/globals/static/semantic/tasks/config/admin/templates/package.json @@ -13,5 +13,7 @@ "bugs": { "url": "https://github.com/Semantic-Org/Semantic-UI/issues" }, - "devDependencies": {} + "dependencies": { + "semantic": "file:" + } } diff --git a/FusionIIIT/applications/globals/views.py b/FusionIIIT/applications/globals/views.py index 9b0303c36..f982ba075 100644 --- a/FusionIIIT/applications/globals/views.py +++ b/FusionIIIT/applications/globals/views.py @@ -16,7 +16,7 @@ from applications.academic_information.models import Student from applications.globals.forms import IssueForm, WebFeedbackForm from applications.globals.models import (ExtraInfo, Feedback, HoldsDesignation, - Issue, IssueImage, DepartmentInfo) + Issue, IssueImage, DepartmentInfo,ModuleAccess) from applications.gymkhana.views import coordinator_club from applications.placement_cell.forms import (AddAchievement, AddCourse, AddEducation, AddExperience, @@ -30,6 +30,7 @@ from notifications.models import Notification from .models import * from applications.hostel_management.models import (HallCaretaker,HallWarden) +from notification.views import announcement_list def index(request): context = {} @@ -745,7 +746,8 @@ def dashboard(request): hall_warden_user = [] for warden in hall_wardens: hall_warden_user.append(warden.faculty.id.user) - + print("modules are") + print(request.session.get('moduleAccessRights')) context={ 'notifications':notifs, 'Curr_desig' : roll_, @@ -753,11 +755,13 @@ def dashboard(request): 'designation' : designation, 'hall_caretaker': hall_caretaker_user, 'hall_warden': hall_warden_user, + 'announcements': announcement_list(request)['announcements'] } # a=HoldsDesignation.objects.select_related('user','working','designation').filter(designation = user) print(context) print(type(user.extrainfo.user_type)) + print(announcement_list(request)) if(request.user.get_username() == 'director'): return render(request, "dashboard/director_dashboard2.html", {}) elif( "dean_rspc" in designation): @@ -1267,8 +1271,19 @@ def update_global_variable(request): if request.method == 'POST': selected_option = request.POST.get('dropdown') request.session['currentDesignationSelected'] = selected_option + module_access = ModuleAccess.objects.filter(designation=selected_option).first() + if module_access: + access_rights = {} + + field_names = [field.name for field in ModuleAccess._meta.get_fields() if field.name not in ['id', 'designation']] + + for field_name in field_names: + access_rights[field_name] = getattr(module_access, field_name) + + request.session['moduleAccessRights'] = access_rights + print(selected_option) print(request.session['currentDesignationSelected']) - return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) + return HttpResponseRedirect('/dashboard') # Redirect to home if not a POST request or some issue occurs - return HttpResponseRedirect(reverse('home')) + return HttpResponseRedirect(reverse('home')) \ No newline at end of file diff --git a/FusionIIIT/applications/gymkhana/admin.py b/FusionIIIT/applications/gymkhana/admin.py index 11a213def..10dd3b792 100644 --- a/FusionIIIT/applications/gymkhana/admin.py +++ b/FusionIIIT/applications/gymkhana/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from .models import (Club_budget,Club_info,Club_member,Club_report,Core_team,Fest_budget,Other_report,Session_info,Voting_choices,Voting_polls,Voting_voters,Event_info,Registration_form,Form_available) +from .models import (Club_budget,Club_info,Club_member,Club_report,Core_team,Fest_budget,Other_report,Session_info,Voting_choices,Voting_polls,Voting_voters,Event_info,Registration_form,Form_available,Inventory) # Register your models here. @@ -27,3 +27,4 @@ class ClubMemberAdmin(admin.ModelAdmin): admin.site.register(Voting_voters) admin.site.register(Registration_form) admin.site.register(Form_available) +admin.site.register(Inventory) diff --git a/FusionIIIT/applications/gymkhana/api/serializers.py b/FusionIIIT/applications/gymkhana/api/serializers.py index 57a7434f8..77a92726c 100644 --- a/FusionIIIT/applications/gymkhana/api/serializers.py +++ b/FusionIIIT/applications/gymkhana/api/serializers.py @@ -2,14 +2,21 @@ from django.contrib.auth import get_user_model from rest_framework.authtoken.models import Token from rest_framework import serializers -from applications.gymkhana.models import Club_info,Session_info,Event_info +from applications.gymkhana.models import Club_info,Session_info,Event_info, Voting_choices from applications.gymkhana.models import Club_member,Core_team,Club_budget,Club_report,Fest_budget,Registration_form,Voting_polls +class Voting_choicesSerializer(serializers.ModelSerializer): + class Meta: + model = Voting_choices + fields = ['poll_event', 'title', 'description', 'votes'] + + class Club_infoSerializer(serializers.ModelSerializer): class Meta: - model=Club_info - fields=['club_name'] + model = Club_info + fields = ['club_name', 'category', 'co_ordinator', 'co_coordinator', 'faculty_incharge', 'club_file', 'activity_calender', 'description', 'alloted_budget', 'spent_budget', 'avail_budget', 'status', 'head_changed_on', 'created_on'] + class EmptySerializer(serializers.Serializer): @@ -18,36 +25,38 @@ class EmptySerializer(serializers.Serializer): class Club_memberSerializer(serializers.ModelSerializer): class Meta: model = Club_member - fields = ['member','club'] + fields = ['member','club','description', 'status','remarks','id'] class Core_teamSerializer(serializers.ModelSerializer): class Meta: model=Core_team - fields=('_all_') + fields=('all') class Club_DetailsSerializer(serializers.ModelSerializer): class Meta: model=Club_info - fields=['club_name',"co_ordinator","co_coordinator","activity_calender"] + fields=['club_name',"co_ordinator","co_coordinator","activity_calender","category",'faculty_incharge',"club_file", "status"] class Session_infoSerializer(serializers.ModelSerializer): class Meta: model = Session_info - fields= ['venue','date','start_time','details'] + fields = [ 'venue', 'date', 'start_time', 'end_time', 'details','status','session_poster','id', 'club'] + + class event_infoserializer(serializers.ModelSerializer): class Meta: model=Event_info - fields=['club','event_name','incharge','date'] + fields=['club','event_name','incharge','date','venue','start_time','id','details','status'] class club_budgetserializer(serializers.ModelSerializer): class Meta: model=Club_budget - fields=['club','budget_for','budget_amt','budget_file'] + fields=['club','budget_for','budget_amt','budget_file','status','id','description'] class Club_reportSerializers(serializers.ModelSerializer): class Meta: @@ -65,6 +74,7 @@ class Meta: fields=['roll','user_name','branch','cpi','programme'] class Voting_pollSerializer(serializers.ModelSerializer): + class Meta: model=Voting_polls - fields=['title','pub_date','exp_date','created_by','groups'] + fields=['title','pub_date','exp_date','created_by','groups','id','description'] \ No newline at end of file diff --git a/FusionIIIT/applications/gymkhana/api/views.py b/FusionIIIT/applications/gymkhana/api/views.py index 194d7c503..0ec4b524e 100644 --- a/FusionIIIT/applications/gymkhana/api/views.py +++ b/FusionIIIT/applications/gymkhana/api/views.py @@ -1,3 +1,8 @@ +import genericpath +import json +import tempfile +from datetime import datetime +from venv import logger from rest_framework.permissions import IsAuthenticated from rest_framework.authentication import TokenAuthentication from rest_framework import status @@ -6,18 +11,276 @@ from rest_framework.permissions import AllowAny from rest_framework.response import Response from django.shortcuts import render -from applications.gymkhana.models import Club_info,Club_member,Core_team,Session_info,Event_info,Club_budget,Club_report,Fest_budget,Registration_form,Voting_polls -from .serializers import Club_memberSerializer,Core_teamSerializer,Club_infoSerializer,Club_DetailsSerializer,Session_infoSerializer,event_infoserializer,club_budgetserializer,Club_reportSerializers,Fest_budgerSerializer,Registration_formSerializer,Voting_pollSerializer +from applications.gymkhana.models import Voting_choices, Registration_form, Student ,Club_info,Club_member,Core_team,Session_info,Event_info,Club_budget,Club_report,Fest_budget,Registration_form,Voting_polls +from .serializers import Club_memberSerializer,Core_teamSerializer,Club_DetailsSerializer,Session_infoSerializer, Voting_choicesSerializer,event_infoserializer,club_budgetserializer,Club_reportSerializers,Fest_budgerSerializer,Registration_formSerializer,Voting_pollSerializer, Club_infoSerializer + from django.contrib.auth.models import User +from applications.gymkhana.views import * +from rest_framework import generics +from django.core.files.base import ContentFile +import base64 + +from rest_framework.parsers import MultiPartParser + +class UploadActivityCalendarAPIView(APIView): + parser_classes = [MultiPartParser] + + def post(self, request, format=None): + # Get the club name from the request data + club_name = request.data.get('club_name') + + # Retrieve the club object from the database + try: + club = Club_info.objects.get(club_name=club_name) + except Club_info.DoesNotExist: + return Response({'error': f'Club with name {club_name} does not exist'}, status=status.HTTP_404_NOT_FOUND) + + # Update the activity calendar file + club.activity_calender = request.data.get('activity_calender') + + # Save the updated club object + club.save() + + return Response({'message': 'Activity calendar updated successfully'}, status=status.HTTP_200_OK) + + +class VoteIncrementAPIView(APIView): + def post(self, request): + serializer = Voting_choicesSerializer(data=request.data, many=True) + if not serializer.is_valid(): + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + data = serializer.validated_data + for choice_data in data: + poll_event_id = choice_data.get('poll_event') + title = choice_data.get('title') + try: + choice_instance = Voting_choices.objects.get(poll_event_id=poll_event_id, title=title) + choice_instance.votes += 1 + choice_instance.save() + except Voting_choices.DoesNotExist: + pass # Do nothing if the choice with the given poll_event and title doesn't exist + + return Response({'message': 'Votes incremented successfully'}, status=status.HTTP_200_OK) + + +class VotingPollsDeleteAPIView(APIView): + def post(self, request): + Voting_poll_id = request.data.get('id') # Assuming the ID is sent in the request body + try: + Voting_poll = Voting_polls.objects.get(id=Voting_poll_id) + except Voting_polls.DoesNotExist: + return Response({"error": "Voting Poll not found."}, status=status.HTTP_404_NOT_FOUND) + + # Delete the club member object + Voting_poll.delete() + + return Response({"message": "POll deleted successfully."}, status=status.HTTP_204_NO_CONTENT) + + +class ShowVotingChoicesAPIView(APIView): + def get(self, request): + voting_choices = Voting_choices.objects.all() + serializer = Voting_choicesSerializer(voting_choices, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + +class ClubMemberApproveView(generics.UpdateAPIView): + def post(self, request): + club_member_id = request.data.get('id') # Assuming the ID is sent in the request body + try: + club_member = Club_member.objects.get(id=club_member_id) + except Club_member.DoesNotExist: + return Response({"error": "Club member not found."}, status=status.HTTP_404_NOT_FOUND) + + # Update the status of the club member + club_member.status = 'confirmed' # Assuming 'confirmed' is the status for approval + club_member.save() + + return Response({"message": "Status updated successfully."}, status=status.HTTP_200_OK) + + +class ClubMemberDeleteAPIView(APIView): + def post(self, request): + club_member_id = request.data.get('id') # Assuming the ID is sent in the request body + try: + club_member = Club_member.objects.get(id=club_member_id) + except Club_member.DoesNotExist: + return Response({"error": "Club member not found."}, status=status.HTTP_404_NOT_FOUND) + + # Delete the club member object + club_member.delete() + + return Response({"message": "Club member deleted successfully."}, status=status.HTTP_204_NO_CONTENT) + +# class UpdateClubDetailsAPIView(APIView): +# def post(self, request, *args, **kwargs): +# club_name = request.data.get('club_name') +# co_coordinator = request.data.get('co_coordinator') +# co_ordinator = request.data.get('co_ordinator') + +# print(f"Received request data: club_name={club_name}, co_coordinator={co_coordinator}, co_ordinator={co_ordinator}") + +# # Retrieve the Club_info object by club_name +# try: +# club_info = Club_info.objects.get(club_name=club_name) +# except Club_info.DoesNotExist: +# return Response({"message": "Club not found"}, status=status.HTTP_404_NOT_FOUND) + +# print(f"Found Club_info object: {club_info}") + +# # Update the details provided in the request +# serializer = Club_infoSerializer(instance=club_info, data={'co_coordinator': co_coordinator, 'co_ordinator': co_ordinator}, partial=True) +# if serializer.is_valid(): +# print("Serializer is valid. Saving...") +# serializer.save() +# print("Data saved successfully.") +# return Response(serializer.data) +# else: +# print(f"Serializer errors: {serializer.errors}") +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +class ChangeHeadAPIView(APIView): + def post(self, request): + club = request.data.get("club_name") + co_ordinator = request.data.get('co_ordinator') + co_coordinator = request.data.get('co_coordinator') + + if not club or (not co_ordinator and not co_coordinator): + return JsonResponse({'status': 'error', 'message': 'Invalid request parameters'}) + + try: + club_info = Club_info.objects.get(club_name=club) + except Club_info.DoesNotExist: + return JsonResponse({'status': 'error', 'message': 'Club not found'}) + + message = "" + + if co_ordinator: + if not Club_member.objects.filter(club_id=club, member_id=co_ordinator).exists(): + return JsonResponse({'status': 'error', 'message': 'Selected student is not a member of the club'}) + + try: + co_ordinator_student = Student.objects.get(id_id=co_ordinator) + old_co_ordinator = club_info.co_ordinator_id + club_info.co_ordinator_id = co_ordinator_student + + new_co_ordinator = HoldsDesignation( + user=User.objects.get(username=co_ordinator), + working=User.objects.get(username=co_ordinator), + designation=Designation.objects.get(name="co-ordinator") + ) + new_co_ordinator.save() + + HoldsDesignation.objects.filter( + user__username=old_co_ordinator, + designation=Designation.objects.get(name="co-ordinator") + ).delete() + + message += "Successfully changed co-ordinator !!!" + except Student.DoesNotExist: + return JsonResponse({'status': 'error', 'message': 'Selected student not found'}) + + if co_coordinator: + if not Club_member.objects.filter(club_id=club, member_id=co_coordinator).exists(): + return JsonResponse({'status': 'error', 'message': 'Selected student is not a member of the club'}) + + try: + co_coordinator_student = Student.objects.get(id_id=co_coordinator) + old_co_coordinator = club_info.co_coordinator_id + club_info.co_coordinator_id = co_coordinator_student + + new_co_coordinator = HoldsDesignation( + user=User.objects.get(username=co_coordinator), + working=User.objects.get(username=co_coordinator), + designation=Designation.objects.get(name="co co-ordinator") + ) + new_co_coordinator.save() + + HoldsDesignation.objects.filter( + user__username=old_co_coordinator, + designation=Designation.objects.get(name="co co-ordinator") + ).delete() + + message += "Successfully changed co-coordinator !!!" + except Student.DoesNotExist: + return JsonResponse({'status': 'error', 'message': 'Selected student not found'}) + + club_info.head_changed_on = timezone.now() + club_info.save() + + return JsonResponse({'status': "success", 'message': message}) +class AddMemberToClub(APIView): + def post(self, request): + serializer = Club_memberSerializer(data=request.data) + if serializer.is_valid(): + club_id = request.data.get('club') # Assuming 'club_id' is passed in the request data + try: + club_member = serializer.save() + # Implement logic to add member to the club here + # For example, you can retrieve the club instance and add the member to it + # club = Club.objects.get(pk=club_id) + # club.members.add(club_member) + return Response(serializer.data, status=status.HTTP_201_CREATED) + except Exception as e: + return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +class ClubMemberAPIView(APIView): + def get(self, request): + club_members = Club_member.objects.all() + serializer = Club_memberSerializer(club_members, many=True) + return Response(serializer.data) + +class RegistrationFormAPIView(APIView): + """ + API endpoint to handle registration form submissions. + """ + + def post(self, request): + """ + Handles POST requests to save registration form data. + """ + try: + # Getting form data + user_name = request.data.get("user_name") + print(user_name) + roll = request.data.get("roll") + cpi = request.data.get("cpi") + branch = request.data.get("branch") + programme = request.data.get("programme") + print(programme) + + # Check if the user has already submitted the form + if Registration_form.objects.filter(user_name=user_name).exists(): + raise Exception("User has already filled the form.") + + # Saving data to the database + registration = Registration_form(user_name=user_name, branch=branch, roll=roll, cpi=cpi, programme=programme) + try: + registration.save() + # If no exception occurred, the save operation was successful + print("Save operation successful") + serializer = Registration_formSerializer(registration) + return Response(serializer.data, status=status.HTTP_201_CREATED) + except Exception as e: + # If an exception occurred, print the error message or log it + print(f"Error occurred while saving registration: {e}") + + print(registration.user_name) + + # Serialize the response + + except Exception as e: + error_message = "Some error occurred" + logger.error(f"Error in registration form submission: {e}") + return Response({"status": "error", "message": error_message}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + def coordinator_club(request): club_info = [] - for i in Club_info.objects.all(): - co = (str(i.co_ordinator)).split(" ") - co_co=(str(i.co_coordinator)).split(" ") - if co[0]==str(request.user) or co_co[0] == str(request.user): - club_info.append(serializers.ClubInfoSerializer(i).data) - + for club in Club_info.objects.all(): + if str(request.user) in [club.co_ordinator, club.co_coordinator]: + serialized_club = Club_infoSerializer(club).data + club_info.append(serialized_club) return club_info class core(APIView): @@ -87,3 +350,502 @@ def get(self,respect): votingpolls=Voting_polls.objects.all() serializer=Voting_pollSerializer(votingpolls, many=True) return Response(serializer.data) + +##logger = logging.getLogger(_NamedFuncPointer) +class NewSessionAPIView(APIView): + def get(self, request): + sessions = Session_info.objects.all() + serializer = Session_infoSerializer(sessions, many=True) + return Response(serializer.data) + + def post(self, request): + serializer =Session_infoSerializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + +class NewEventAPIView(APIView): + def get(self, request): + events = Event_info.objects.all() + serializer = event_infoserializer(events, many=True) + return Response(serializer.data) + + def post(self, request): + serializer = event_infoserializer(data=request.data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + + + +# class DeleteEventsView(APIView): +# """ +# API endpoint to delete events. +# """ + +# def post(self, request): +# """ +# Handle POST requests to delete events. +# """ +# try: +# events_deleted = [] +# events_not_found = [] + +# # Ensure that request.data is a dictionary +# event_data_list = request.data if isinstance(request.data, list) else [] + +# for event_data in event_data_list: +# name = event_data.get('event_name') +# venue = event_data.get('venue') +# incharge = event_data.get('incharge') +# date = event_data.get('date') +# event_id = event_data.get('id') + +# # Query Event_info based on the provided parameters +# event = Event_info.objects.filter( +# event_name=name, +# venue=venue, +# incharge=incharge, +# date=date, +# event_id=id, +# ).first() + +# if event: +# event.delete() +# events_deleted.append(event_data) +# else: +# events_not_found.append(event_data) + +# response_data = { +# "events_deleted": events_deleted, +# "events_not_found": events_not_found +# } + +# return Response(response_data, status=status.HTTP_200_OK) +# except Exception as e: +# return Response(str(e), status=status.HTTP_500_INTERNAL_SERVER_ERROR) + +class EventDeleteAPIView(APIView): + def post(self, request, *args, **kwargs): + # Retrieve data from request + event_data = request.data + + # Check if 'id' parameter is provided + if 'id' not in event_data: + return Response({'error': 'The "id" parameter is required'}, status=status.HTTP_400_BAD_REQUEST) + + # Get the event by id + event_id = event_data['id'] + try: + event = Event_info.objects.get(id=event_id) + except Event_info.DoesNotExist: + return Response({'error': 'Event not found with the provided id'}, status=status.HTTP_404_NOT_FOUND) + + # Delete the event + event.delete() + + return Response({'message': 'Event deleted successfully'}, status=status.HTTP_200_OK) + + +class SessionUpdateAPIView(APIView): + def post(self, request): + session_id = request.data.get('id') + if session_id is None: + return Response({'error': 'Session ID not provided'}, status=status.HTTP_400_BAD_REQUEST) + + try: + session_instance = Session_info.objects.get(id=session_id) + except Session_info.DoesNotExist: + return Response({'error': 'Session not found'}, status=status.HTTP_404_NOT_FOUND) + + serializer = Session_infoSerializer(instance=session_instance, 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) + + +class EventUpdateAPIView(APIView): + def post(self, request): + event_id = request.data.get('id') + if event_id is None: + return Response({'error': 'Event ID not provided'}, status=status.HTTP_400_BAD_REQUEST) + + try: + event_instance = Event_info.objects.get(id=event_id) + except Event_info.DoesNotExist: + return Response({'error': 'Event not found'}, status=status.HTTP_404_NOT_FOUND) + + serializer = event_infoserializer(instance=event_instance, 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) + + +class DeleteSessionsView(APIView): + """ + API endpoint to delete sessions. + """ + + def post(self, request): + """ + Handle POST requests to delete sessions. + """ + try: + # Get the list of session data from the request + session_data_list = json.loads(request.body) + + sessions_deleted = [] + sessions_not_found = [] + + # Iterate over each session data + for session_data in session_data_list: + venue = session_data.get('venue') + date = session_data.get('date') + start_time = session_data.get('start_time') + end_time = session_data.get('end_time') + + # Query Session_info based on the provided parameters + session = Session_info.objects.filter( + venue=venue, + date=date, + start_time=start_time, + end_time=end_time, + ).first() + + if session: + session.delete() + sessions_deleted.append(session_data) + else: + sessions_not_found.append(session_data) + + response_data = { + "sessions_deleted": sessions_deleted, + "sessions_not_found": sessions_not_found + } + + return JsonResponse(response_data, status=200) + except Exception as e: + return JsonResponse({"error": str(e)}, status=500) + + +class CreateVotingPollAPIView(APIView): + def post(self, request): + voting_poll_serializer = Voting_pollSerializer(data=request.data) + if voting_poll_serializer.is_valid(): + voting_poll_instance = voting_poll_serializer.save() + + # Extract ID of the created Voting_poll instance + voting_poll_id = voting_poll_instance.id + + # Modify the request data to include poll_event ID for each choice + choices_data = request.data.get('choices', []) + for choice_data in choices_data: + choice_data['poll_event'] = voting_poll_id + + voting_choices_serializer = Voting_choicesSerializer(data=choices_data, many=True) + if voting_choices_serializer.is_valid(): + voting_choices_serializer.save() + return Response({'message': 'Voting poll created successfully'}, status=status.HTTP_201_CREATED) + else: + return Response({'voting_choices_errors': voting_choices_serializer.errors}, status=status.HTTP_400_BAD_REQUEST) + else: + return Response({'voting_poll_errors': voting_poll_serializer.errors}, status=status.HTTP_400_BAD_REQUEST) + +class UpdateClubBudgetAPIView(APIView): + def post(self, request): + budget_id = request.data.get('id') + if budget_id is None: + return Response({'error': 'Club budget ID not provided'}, status=status.HTTP_400_BAD_REQUEST) + + try: + budget_instance = Club_budget.objects.get(pk=budget_id) + except Club_budget.DoesNotExist: + return Response({'error': 'Club budget not found'}, status=status.HTTP_404_NOT_FOUND) + + serializer = club_budgetserializer(instance=budget_instance, data=request.data, partial = True) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_200_OK) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +class AddClub_BudgetAPIView(APIView): + def post(self, request): + # Get the string representation of the file content + budget_file_content = request.data.get('budget_file') + + # Convert the string to a file object + file_obj = None + if budget_file_content: + # Create a ContentFile object + file_obj = ContentFile(budget_file_content.encode(), name='temp_file.txt') + +# Update the request data with the File object + request.data['budget_file'] = file_obj + + # Update the request data with the file object + request.data['budget_file'] = file_obj + + # Initialize the serializer with the modified request data + serializer = club_budgetserializer(data=request.data) + + # Validate and save the serializer data + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + +class DeleteClubBudgetAPIView(APIView): + def post(self, request): + budget_id = request.data.get('id') + if budget_id is None: + return Response({'error': 'Club budget ID not provided'}, status=status.HTTP_400_BAD_REQUEST) + + try: + budget_instance = Club_budget.objects.get(pk=budget_id) + except Club_budget.DoesNotExist: + return Response({'error': 'Club budget not found'}, status=status.HTTP_404_NOT_FOUND) + + budget_instance.delete() + return Response({'message': 'Club budget deleted successfully'}, status=status.HTTP_200_OK) + + +class DeleteClubAPIView(APIView): + def post(self, request): + # Retrieve data from request + club_data = request.data + + # Extract fields for filtering + club_name = club_data.get('club_name') + category = club_data.get('category') + co_ordinator = club_data.get('co_ordinator') + co_coordinator = club_data.get('co_coordinator') + faculty_incharge = club_data.get('faculty_incharge') + + # Check if all required fields are provided + if not all([club_name, category, co_ordinator, co_coordinator, faculty_incharge]): + return Response({"error": "Missing required fields"}, status=status.HTTP_400_BAD_REQUEST) + + # Try to find the club based on provided fields + try: + club = Club_info.objects.get( + club_name=club_name, + category=category, + co_ordinator=co_ordinator, + co_coordinator=co_coordinator, + faculty_incharge=faculty_incharge + ) + except Club_info.DoesNotExist: + return Response({"error": "Club not found"}, status=status.HTTP_404_NOT_FOUND) + + # Delete the club from the database + club.delete() + + return Response({"message": "Club deleted successfully"}, status=status.HTTP_200_OK) + + +# class ClubCreateAPIView(APIView): +# def post(self, request, format=None): +# data = { +# 'club_name': request.data.get('club_name'), +# 'category': request.data.get('category'), +# 'co_ordinator': request.data.get('co_ordinator'), +# 'co_coordinator': request.data.get('co_coordinator'), +# 'faculty_incharge': request.data.get('faculty_incharge'), +# 'club_file': request.data.get('club_file'), +# 'activity_calender': request.data.get('activity_calender'), +# 'description': request.data.get('description'), +# 'status': request.data.get('status'), +# 'head_changed_on': request.data.get('head_changed_on'), +# 'created_on': request.data.get('created_on'), +# } +# serializer = Club_infoSerializer(data=data,partial=True) +# if serializer.is_valid(): +# serializer.save() +# return Response(serializer.data, status=status.HTTP_201_CREATED) +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + +class CreateClubAPIView(APIView): + def post(self, request): + # Get the string representation of the file content for club_file + club_file_content = request.data.get('club_file') + + # Convert the string to a file object for club_file + club_file_obj = None + if club_file_content: + club_file_obj = ContentFile(club_file_content.encode(), name='club_file.txt') + + # Update the request data with the file object for club_file + request.data['club_file'] = club_file_obj + + # Get the string representation of the file content for activity_calendar + description = request.data.get('description') + + # Initialize the serializer with the modified request data + serializer = Club_infoSerializer(data=request.data) + + # Validate and save the serializer data + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + + +class UpdateClubStatusAPIView(APIView): + def post(self, request): + # Retrieve data from request + club_data = request.data + + # Extract fields for filtering + club_name = club_data.get('club_name') + co_ordinator = club_data.get('co_ordinator') + co_coordinator = club_data.get('co_coordinator') + faculty_incharge = club_data.get('faculty_incharge') + + # Check if all required fields are provided + if not all([club_name, co_ordinator, co_coordinator, faculty_incharge]): + return Response({"error": "Missing required fields"}, status=status.HTTP_400_BAD_REQUEST) + + # Try to find the club based on provided fields + try: + club = Club_info.objects.get( + club_name=club_name, + co_ordinator=co_ordinator, + co_coordinator=co_coordinator, + faculty_incharge=faculty_incharge + ) + except Club_info.DoesNotExist: + return Response({"error": "Club not found"}, status=status.HTTP_404_NOT_FOUND) + + # Update the status of the club + club.status = 'confirmed' + club.save() + + return Response({"message": "Club status updated to 'confirmed' successfully"}, status=status.HTTP_200_OK) + + + + + + +# class UpdateClubNameAPIView(APIView): +# def post(self, request): +# # Retrieve data from request +# club_data = request.data + +# # Extract fields for filtering +# club_name = club_data.get('club_name') +# co_ordinator = club_data.get('co_ordinator') +# co_coordinator = club_data.get('co_coordinator') +# faculty_incharge = club_data.get('faculty_incharge') +# new_club = club_data.get('new_club') + +# # Check if all required fields are provided +# if not all([club_name, co_ordinator, co_coordinator, faculty_incharge]): +# return Response({"error": "Missing required fields"}, status=status.HTTP_400_BAD_REQUEST) + +# # Try to find the club based on provided fields +# try: +# club = Club_info.objects.get( +# club_name=club_name, +# co_ordinator=co_ordinator, +# co_coordinator=co_coordinator, +# faculty_incharge=faculty_incharge +# ) +# except Club_info.DoesNotExist: +# return Response({"error": "Club not found"}, status=status.HTTP_404_NOT_FOUND) + +# # Update the status of the club +# club.club_name = new_club +# club.save() + +# return Response({"message": "Club name updated successfully"}, status=status.HTTP_200_OK) + + + +class UpdateClubNameAPIView(APIView): + def post(self, request): + # Retrieve data from request + club_data = request.data + + # Extract fields for filtering + club_name = club_data.get('club_name') + co_ordinator = club_data.get('co_ordinator') + co_coordinator = club_data.get('co_coordinator') + faculty_incharge = club_data.get('faculty_incharge') + new_club = club_data.get('new_club') + + # Check if all required fields are provided + if not all([club_name, co_ordinator, co_coordinator, faculty_incharge, new_club]): + return Response({"error": "Missing required fields"}, status=status.HTTP_400_BAD_REQUEST) + + # Try to find the club based on provided fields + try: + club = Club_info.objects.get( + club_name=club_name, + co_ordinator=co_ordinator, + co_coordinator=co_coordinator, + faculty_incharge=faculty_incharge + ) + except Club_info.DoesNotExist: + return Response({"error": "Club not found"}, status=status.HTTP_404_NOT_FOUND) + + # Check if a club with the new name already exists + if Club_info.objects.filter(club_name=new_club).exists(): + return Response({"error": f"A club with the name '{new_club}' already exists"}, status=status.HTTP_400_BAD_REQUEST) + + # Update the status of the club + club.club_name = new_club + club.save() + + # Delete the original club entry + Club_info.objects.filter(club_name=club_name).delete() + + return Response({"message": "Club name updated successfully"}, status=status.HTTP_200_OK) + + + +class ApproveEvent(APIView): + def post(self, request): + # Retrieve data from request + event_data = request.data + + # Extract fields for filtering + event_name = event_data.get('event_name') + incharge = event_data.get('incharge') + date = event_data.get('date') + venue = event_data.get('venue') + event_id = event_data.get('id') + # status = event_data.get('status') + + # Check if all required fields are provided + if not all([event_name, incharge, date, venue, event_id]): + return Response({"error": "Missing required fields"}, status=status.HTTP_400_BAD_REQUEST) + + # Try to find the event based on provided fields + try: + event = Event_info.objects.get( + event_name=event_name, + incharge=incharge, + date=date, + venue=venue, + id=event_id + ) + except Event_info.DoesNotExist: + return Response({"error": "Event not found"}, status=status.HTTP_404_NOT_FOUND) + + # Update the status of the event + event.status = 'confirmed' + event.save() + + return Response({"message": "event status updated successfully"}, status=status.HTTP_200_OK) \ No newline at end of file diff --git a/FusionIIIT/applications/gymkhana/migrations/0001_initial.py b/FusionIIIT/applications/gymkhana/migrations/0001_initial.py index 546d7fb81..0869064d5 100644 --- a/FusionIIIT/applications/gymkhana/migrations/0001_initial.py +++ b/FusionIIIT/applications/gymkhana/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-07-16 15:44 from django.conf import settings from django.db import migrations, models @@ -11,9 +11,9 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('globals', '0001_initial'), ('academic_information', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ @@ -30,6 +30,8 @@ class Migration(migrations.Migration): ('spent_budget', models.IntegerField(default=0, null=True)), ('avail_budget', models.IntegerField(default=0, null=True)), ('status', models.CharField(choices=[('open', 'Open'), ('confirmed', 'Confirmed'), ('rejected', 'Rejected')], default='open', max_length=50)), + ('head_changed_on', models.DateField(default=django.utils.timezone.now, null=True)), + ('created_on', models.DateField(default=django.utils.timezone.now, null=True)), ('co_coordinator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='coco_of', to='academic_information.student')), ('co_ordinator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='co_of', to='academic_information.student')), ('faculty_incharge', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='faculty_incharge_of', to='globals.faculty')), @@ -68,7 +70,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Registration_form', fields=[ - ('roll', models.CharField(default='2016001', max_length=7, primary_key=True, serialize=False)), + ('roll', models.CharField(default='20160017', max_length=8, primary_key=True, serialize=False)), ('user_name', models.CharField(default='Student', max_length=40)), ('branch', models.CharField(default='open', max_length=20)), ('cpi', models.FloatField(default=6.0, max_length=3)), @@ -93,6 +95,16 @@ class Migration(migrations.Migration): 'ordering': ['-pub_date'], }, ), + migrations.CreateModel( + name='Inventory', + fields=[ + ('club_name', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='club_inventory', serialize=False, to='gymkhana.club_info')), + ('inventory', models.FileField(upload_to='gymkhana/inventory')), + ], + options={ + 'db_table': 'Inventory', + }, + ), migrations.CreateModel( name='Voting_voters', fields=[ @@ -121,7 +133,7 @@ class Migration(migrations.Migration): ('venue', models.CharField(choices=[('Classroom', (('CR101', 'CR101'), ('CR102', 'CR102'))), ('Lecturehall', (('L101', 'L101'), ('L102', 'L102')))], max_length=50)), ('date', models.DateField(default=None)), ('start_time', models.TimeField(default=None)), - ('end_time', models.TimeField(default=None, null=True)), + ('end_time', models.TimeField(default=None)), ('session_poster', models.ImageField(null=True, upload_to='gymkhana/session_poster')), ('details', models.TextField(max_length=256, null=True)), ('status', models.CharField(choices=[('open', 'Open'), ('confirmed', 'Confirmed'), ('rejected', 'Rejected')], default='open', max_length=50)), diff --git a/FusionIIIT/applications/gymkhana/models.py b/FusionIIIT/applications/gymkhana/models.py index c4513b236..3544f2f3b 100644 --- a/FusionIIIT/applications/gymkhana/models.py +++ b/FusionIIIT/applications/gymkhana/models.py @@ -19,34 +19,31 @@ # # Class for various choices on the enumerations class Constants: available = ( - ('On', 'On'), - ('Off', 'Off'), + ("On", "On"), + ("Off", "Off"), ) categoryCh = ( - ('Technical', 'Technical'), - ('Sports', 'Sports'), - ('Cultural', 'Cultural') - ) - status = ( - ('open', 'Open'), - ('confirmed', 'Confirmed'), - ('rejected', 'Rejected') - ) - fest = ( - ('Abhikalpan', 'Abhikalpan'), - ('Gusto', 'Gusto'), - ('Tarang', 'Tarang') + ("Technical", "Technical"), + ("Sports", "Sports"), + ("Cultural", "Cultural"), ) + status = (("open", "Open"), ("confirmed", "Confirmed"), ("rejected", "Rejected")) + fest = (("Abhikalpan", "Abhikalpan"), ("Gusto", "Gusto"), ("Tarang", "Tarang")) venue = ( - ('Classroom', ( - ('CR101', 'CR101'), - ('CR102', 'CR102'), - )), - ('Lecturehall', ( - ('L101', 'L101'), - ('L102', 'L102'), - )), - + ( + "Classroom", + ( + ("CR101", "CR101"), + ("CR102", "CR102"), + ), + ), + ( + "Lecturehall", + ( + ("L101", "L101"), + ("L102", "L102"), + ), + ), ) @@ -58,7 +55,7 @@ class Club_info(models.Model): club_name - name of the club club_website - url of the club website - category - to which category it belongs to + category - to which category it belongs to co_ordinator - refers to the id of co_ordinator of the club co_coordinator - refers to the id of co_coordinator of the club faculty_incharge - the lecturer/proffesor who is incharge of this club. @@ -66,41 +63,50 @@ class Club_info(models.Model): activity_calender - it is the url of club logo description - refers to brief explanation about the club alloted_budget - the amount alloted to the club - spent_budget - the amount spent by the club + spent_budget - the amount spent by the club avail_budget - the amount available at the club status - status of club wheather it is confirmed or not """ + club_name = models.CharField(max_length=50, null=False, primary_key=True) club_website = models.CharField(max_length=150, null=True, default="hello") - category = models.CharField( - max_length=50, null=False, choices=Constants.categoryCh) - co_ordinator = models.ForeignKey(Student, on_delete=models.CASCADE, null=False, related_name='co_of') + category = models.CharField(max_length=50, null=False, choices=Constants.categoryCh) + co_ordinator = models.ForeignKey( + Student, on_delete=models.CASCADE, null=False, related_name="co_of" + ) co_coordinator = models.ForeignKey( - Student, on_delete=models.CASCADE, null=False, related_name='coco_of') + Student, on_delete=models.CASCADE, null=False, related_name="coco_of" + ) faculty_incharge = models.ForeignKey( - Faculty, on_delete=models.CASCADE, null=False, related_name='faculty_incharge_of') - club_file = models.FileField(upload_to='gymkhana/club_poster', null=True) + Faculty, + on_delete=models.CASCADE, + null=False, + related_name="faculty_incharge_of", + ) + club_file = models.FileField(upload_to="gymkhana/club_poster", null=True) activity_calender = models.FileField( - upload_to='gymkhana/activity_calender', null=True, default=" ") + upload_to="gymkhana/activity_calender", null=True, default=" " + ) description = models.TextField(max_length=256, null=True) alloted_budget = models.IntegerField(null=True, default=0) spent_budget = models.IntegerField(null=True, default=0) avail_budget = models.IntegerField(null=True, default=0) - status = models.CharField( - max_length=50, choices=Constants.status, default='open') + status = models.CharField(max_length=50, choices=Constants.status, default="open") + head_changed_on = models.DateField(default=timezone.now, auto_now=False, null=True) + created_on = models.DateField(default=timezone.now, auto_now=False, null=True) def __str__(self): return str(self.club_name) class Meta: - db_table = 'Club_info' + db_table = "Club_info" class Form_available(models.Model): """ It stores registered form name , roll number and status. - + roll - roll number of the student status - it is a boolean value wheather the form is available or not form_name - name of the form @@ -109,13 +115,14 @@ class Form_available(models.Model): roll = models.CharField(default=2016001, max_length=7, primary_key=True) status = models.BooleanField(default=True, max_length=5) - form_name = models.CharField(default='senate_registration', max_length=30) + form_name = models.CharField(default="senate_registration", max_length=30) def __str__(self): return str(self.roll) class Meta: - db_table = 'Form_available' + db_table = "Form_available" + class Registration_form(models.Model): """ @@ -129,17 +136,17 @@ class Registration_form(models.Model): """ - roll = models.CharField(max_length=7, default="2016001", primary_key=True) + roll = models.CharField(max_length=8, default="20160017", primary_key=True) user_name = models.CharField(max_length=40, default="Student") - branch = models.CharField(max_length=20, default='open') + branch = models.CharField(max_length=20, default="open") cpi = models.FloatField(max_length=3, default=6.0) - programme = models.CharField(max_length=20, default='B.tech') + programme = models.CharField(max_length=20, default="B.tech") def __str__(self): return str(self.roll) class Meta: - db_table = 'Registration_form' + db_table = "Registration_form" class Club_member(models.Model): @@ -154,22 +161,23 @@ class Club_member(models.Model): remarks - remarks of the student by the club if any. """ + id = models.AutoField(primary_key=True) member = models.ForeignKey( - Student, on_delete=models.CASCADE, related_name='member_of') - club = models.ForeignKey(Club_info, on_delete=models.CASCADE, related_name='this_club', null=False) + Student, on_delete=models.CASCADE, related_name="member_of" + ) + club = models.ForeignKey( + Club_info, on_delete=models.CASCADE, related_name="this_club", null=False + ) description = models.TextField(max_length=256, null=True) - status = models.CharField( - max_length=50, choices=Constants.status, default='open') + status = models.CharField(max_length=50, choices=Constants.status, default="open") remarks = models.CharField(max_length=256, null=True) def __str__(self): return str(self.member.id) class Meta: - db_table = 'Club_member' - - + db_table = "Club_member" class Core_team(models.Model): @@ -186,13 +194,14 @@ class Core_team(models.Model): remarks - remarks(if there are any) in the fest """ + id = models.AutoField(primary_key=True) student_id = models.ForeignKey( - Student, on_delete=models.CASCADE, related_name='applied_for') + Student, on_delete=models.CASCADE, related_name="applied_for" + ) team = models.CharField(max_length=50, null=False) year = models.DateTimeField(max_length=6, null=True) - fest_name = models.CharField( - max_length=256, null=False, choices=Constants.fest) + fest_name = models.CharField(max_length=256, null=False, choices=Constants.fest) pda = models.TextField(max_length=256, null=False) remarks = models.CharField(max_length=256, null=True) @@ -200,38 +209,36 @@ def __str__(self): return str(self.student_id) class Meta: - db_table = 'Core_team' + db_table = "Core_team" class Club_budget(models.Model): - """ Records the budget details of the clubs. - id - serial number club - name of the club budget_for - the purpose of the budget,like for equipment or for event etc.., budget_amt - the amount required for the club budget_file - it is file which contains complete details regarding the amount they want to spend descrion - description about the budget if any - """ id = models.AutoField(primary_key=True) - club = models.ForeignKey(Club_info,on_delete=models.CASCADE, max_length=50, null=False) + club = models.ForeignKey( + Club_info, on_delete=models.CASCADE, max_length=50, null=False + ) budget_for = models.CharField(max_length=256, null=False) budget_amt = models.IntegerField(default=0, null=False) - budget_file = models.FileField(upload_to='uploads/', null=False) + budget_file = models.FileField(upload_to="uploads/", null=False) description = models.TextField(max_length=256, null=False) - status = models.CharField( - max_length=50, choices=Constants.status, default='open') + status = models.CharField(max_length=50, choices=Constants.status, default="open") remarks = models.CharField(max_length=256, null=True) def __str__(self): return str(self.id) class Meta: - db_table = 'Club_budget' + db_table = "Club_budget" class Session_info(models.Model): @@ -241,31 +248,32 @@ class Session_info(models.Model): id - serial number club - name of the club venue - the place at which they conducting the session - date - date of the session + date - date of the session start_time - the time at which session starts end_time - the time at which session ends session_poster - the logo/poster for the session(image) details - for which purpose they are taking the session status - wheather it is approved/rejected. - """ + id = models.AutoField(primary_key=True) - club = models.ForeignKey(Club_info, on_delete=models.CASCADE,max_length=50, null=True) - venue = models.CharField(max_length=50, null=False, - choices=Constants.venue) + club = models.ForeignKey( + Club_info, on_delete=models.CASCADE, max_length=50, null=True + ) + venue = models.CharField(max_length=50, null=False, choices=Constants.venue) date = models.DateField(default=None, auto_now=False, null=False) start_time = models.TimeField(default=None, auto_now=False, null=False) - end_time = models.TimeField(default=None, auto_now=False, null=True) - session_poster = models.ImageField(upload_to='gymkhana/session_poster', null=True) + end_time = models.TimeField(default=None, auto_now=False, null=False) + session_poster = models.ImageField(upload_to="gymkhana/session_poster", null=True) details = models.TextField(max_length=256, null=True) - status = models.CharField( - max_length=50, choices=Constants.status, default='open') + status = models.CharField(max_length=50, choices=Constants.status, default="open") def __str__(self): return str(self.id) class Meta: - db_table = 'Session_info' + db_table = "Session_info" + class Event_info(models.Model): """ @@ -286,24 +294,24 @@ class Event_info(models.Model): """ id = models.AutoField(primary_key=True) - club = models.ForeignKey(Club_info, on_delete=models.CASCADE,max_length=50, null=True) - event_name= models.CharField(max_length=256, null=False) - venue = models.CharField(max_length=50, null=False, - choices=Constants.venue) - incharge=models.CharField(max_length=256, null=False) + club = models.ForeignKey( + Club_info, on_delete=models.CASCADE, max_length=50, null=True + ) + event_name = models.CharField(max_length=256, null=False) + venue = models.CharField(max_length=50, null=False, choices=Constants.venue) + incharge = models.CharField(max_length=256, null=False) date = models.DateField(default=None, auto_now=False, null=False) start_time = models.TimeField(default=None, auto_now=False, null=False) end_time = models.TimeField(default=None, auto_now=False, null=True) - event_poster = models.FileField(upload_to='gymkhana/event_poster', blank=True) + event_poster = models.FileField(upload_to="gymkhana/event_poster", blank=True) details = models.TextField(max_length=256, null=True) - status = models.CharField( - max_length=50, choices=Constants.status, default='open') + status = models.CharField(max_length=50, choices=Constants.status, default="open") def __str__(self): return str(self.id) class Meta: - db_table = 'Event_info' + db_table = "Event_info" class Club_report(models.Model): @@ -322,19 +330,22 @@ class Club_report(models.Model): """ id = models.AutoField(primary_key=True) - club = models.ForeignKey(Club_info, on_delete=models.CASCADE,max_length=50, null=False) - incharge = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE,max_length=256, null=False) + club = models.ForeignKey( + Club_info, on_delete=models.CASCADE, max_length=50, null=False + ) + incharge = models.ForeignKey( + ExtraInfo, on_delete=models.CASCADE, max_length=256, null=False + ) event_name = models.CharField(max_length=50, null=False) - date = models.DateTimeField( - max_length=50, default=timezone.now, blank=True) - event_details = models.FileField(upload_to='uploads/', null=False) + date = models.DateTimeField(max_length=50, default=timezone.now, blank=True) + event_details = models.FileField(upload_to="uploads/", null=False) description = models.TextField(max_length=256, null=True) def __str__(self): return str(self.id) class Meta: - db_table = 'Club_report' + db_table = "Club_report" class Fest_budget(models.Model): @@ -349,56 +360,57 @@ class Fest_budget(models.Model): description - brief explanation regarding budget if any status - wheather budget is approved or rejected remarks - negative things regarding budget - + """ id = models.AutoField(primary_key=True) fest = models.CharField(max_length=50, null=False, choices=Constants.fest) budget_amt = models.IntegerField(default=0, null=False) - budget_file = models.FileField(upload_to='uploads/', null=False) + budget_file = models.FileField(upload_to="uploads/", null=False) year = models.CharField(max_length=10, null=True) description = models.TextField(max_length=256, null=False) - status = models.CharField( - max_length=50, choices=Constants.status, default='open') + status = models.CharField(max_length=50, choices=Constants.status, default="open") remarks = models.CharField(max_length=256, null=True) def __str__(self): return str(self.id) class Meta: - db_table = 'Fest_budget' + db_table = "Fest_budget" class Other_report(models.Model): """ This model also stores details of the events conducting by all clubs irrespective of the clubs. - + id - serial number incharge - name of faculty who is incharge for the event date - date of the event event_details - for which purpose they are conducting the event - description - brief explanation about event if needed + description - brief explanation about event if needed """ + id = models.AutoField(primary_key=True) - incharge = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE,max_length=256, null=False) + incharge = models.ForeignKey( + ExtraInfo, on_delete=models.CASCADE, max_length=256, null=False + ) event_name = models.CharField(max_length=50, null=False) - date = models.DateTimeField( - max_length=50, default=timezone.now, blank=True) - event_details = models.FileField(upload_to='uploads/', null=False) + date = models.DateTimeField(max_length=50, default=timezone.now, blank=True) + event_details = models.FileField(upload_to="uploads/", null=False) description = models.TextField(max_length=256, null=True) def __str__(self): return str(self.id) class Meta: - db_table = 'Other_report' + db_table = "Other_report" class Change_office(models.Model): """ - + id - serial number club - name of the club @@ -410,15 +422,19 @@ class Change_office(models.Model): remarks - remarks if there are any. """ + id = models.AutoField(primary_key=True) - club = models.ForeignKey(Club_info, on_delete=models.CASCADE,max_length=50, null=False) - co_ordinator = models.ForeignKey(User, on_delete=models.CASCADE,null=False, related_name='co_of') + club = models.ForeignKey( + Club_info, on_delete=models.CASCADE, max_length=50, null=False + ) + co_ordinator = models.ForeignKey( + User, on_delete=models.CASCADE, null=False, related_name="co_of" + ) co_coordinator = models.ForeignKey( - User, on_delete=models.CASCADE, null=False, related_name='coco_of') - status = models.CharField( - max_length=50, choices=Constants.status, default='open') - date_request = models.DateTimeField( - max_length=50, default=timezone.now, blank=True) + User, on_delete=models.CASCADE, null=False, related_name="coco_of" + ) + status = models.CharField(max_length=50, choices=Constants.status, default="open") + date_request = models.DateTimeField(max_length=50, default=timezone.now, blank=True) date_approve = models.DateTimeField(max_length=50, blank=True) remarks = models.CharField(max_length=256, null=True) @@ -426,7 +442,7 @@ def __str__(self): return self.id class Meta: - db_table = 'Change_office' + db_table = "Change_office" class Voting_polls(models.Model): @@ -441,21 +457,23 @@ class Voting_polls(models.Model): groups - the groups that are participating in the voting """ - - title = models.CharField(max_length=200,null=False) - description = models.CharField(max_length=5000,null=False) + + title = models.CharField(max_length=200, null=False) + description = models.CharField(max_length=5000, null=False) pub_date = models.DateTimeField(default=timezone.now) exp_date = models.DateTimeField(default=timezone.now) - created_by = models.CharField(max_length=100,null=True) - groups = models.CharField(max_length=500,default='{}') - + created_by = models.CharField(max_length=100, null=True) + groups = models.CharField(max_length=500, default="{}") + def groups_data(self): return self.groups def __str__(self): return self.title + class Meta: - ordering = ['-pub_date'] + ordering = ["-pub_date"] + class Voting_choices(models.Model): """ @@ -467,15 +485,16 @@ class Voting_choices(models.Model): """ poll_event = models.ForeignKey(Voting_polls, on_delete=models.CASCADE) - title = models.CharField(max_length=200,null=False) - description = models.CharField(max_length=500,default='') + title = models.CharField(max_length=200, null=False) + description = models.CharField(max_length=500, default="") votes = models.IntegerField(default=0) def __str__(self): return self.title - + class Meta: - get_latest_by = 'votes' + get_latest_by = "votes" + class Voting_voters(models.Model): """ @@ -485,11 +504,26 @@ class Voting_voters(models.Model): student_id - roll number of student """ - + poll_event = models.ForeignKey(Voting_polls, on_delete=models.CASCADE) student_id = models.CharField(max_length=50, null=False) - - + def __str__(self): return self.student_id + +class Inventory(models.Model): + club_name = models.OneToOneField( + Club_info, + primary_key=True, + on_delete=models.CASCADE, + related_name="club_inventory", + unique=True, + ) + inventory = models.FileField(upload_to="gymkhana/inventory") + + def __str__(self): + return str(self.club_name) + + class Meta: + db_table = "Inventory" \ No newline at end of file diff --git a/FusionIIIT/applications/gymkhana/templatetags/voters_tag.py b/FusionIIIT/applications/gymkhana/templatetags/voters_tag.py index 408e7b643..3cb86ce50 100644 --- a/FusionIIIT/applications/gymkhana/templatetags/voters_tag.py +++ b/FusionIIIT/applications/gymkhana/templatetags/voters_tag.py @@ -4,23 +4,15 @@ toggel = False -## A tag function to find whether to show the poll to the user or not @register.simple_tag def validate(user, groups): - - roll = user.username[:4] + roll = user.username[:5] branch = user.extrainfo.department.name - print(groups) - if roll in groups.keys(): - if groups[roll][0] == 'All': + if roll in groups: + allowed_branches = groups[roll] + if 'All' in allowed_branches or branch in allowed_branches: return True - else: - if branch in groups[roll]: - return True - else: - return False - else: - return False + return False @register.simple_tag def result(): diff --git a/FusionIIIT/applications/gymkhana/urls.py b/FusionIIIT/applications/gymkhana/urls.py index 308ce4d7b..3c8c20de1 100644 --- a/FusionIIIT/applications/gymkhana/urls.py +++ b/FusionIIIT/applications/gymkhana/urls.py @@ -1,79 +1,127 @@ from django.conf.urls import url +from django.urls import path from rest_framework.urlpatterns import format_suffix_patterns -from applications.gymkhana.api.views import Voting_Polls +from applications.gymkhana.api.views import AddClub_BudgetAPIView, AddMemberToClub, ApproveEvent, ChangeHeadAPIView, ClubMemberAPIView, ClubMemberApproveView, ClubMemberDeleteAPIView, CreateClubAPIView, DeleteClubAPIView, DeleteClubBudgetAPIView, EventDeleteAPIView, EventUpdateAPIView, SessionUpdateAPIView, UpdateClubBudgetAPIView, UpdateClubNameAPIView, UpdateClubStatusAPIView, UploadActivityCalendarAPIView from applications.gymkhana.api.views import clubname,Club_Details,club_events,club_budgetinfo,Fest_Budget,club_report,Registraion_form from applications.gymkhana.api.views import session_details +from applications.gymkhana.api.views import DeleteSessionsView, NewEventAPIView, NewSessionAPIView, ShowVotingChoicesAPIView, VoteIncrementAPIView, VotingPollsDeleteAPIView from . import views from rest_framework.authtoken.views import obtain_auth_token app_name = 'gymkhana' urlpatterns = [ - url(r'^session_details/$',session_details.as_view()), - url(r'^event_info/$',club_events.as_view()), - url(r'^club_budgetinfo/$',club_budgetinfo.as_view()), - #academic administration - url(r'^club_approve/$', views.club_approve, name='club_approve'), - url(r'^club_reject/$', views.club_reject, name='club_reject'), + url(r"^session_details/$", session_details.as_view()), + url(r"^event_info/$", club_events.as_view()), + url(r"^club_budgetinfo/$", club_budgetinfo.as_view()), + # academic administration + url(r"^club_approve/$", views.club_approve, name="club_approve"), + url(r"^del_mem/$", views.del_mem, name="del_mem"), + url(r"^club_reject/$", views.club_reject, name="club_reject"), + url(r"^budget_approve/$", views.budget_approve, name="budget_approve"), + url(r"^budget_reject/$", views.budget_reject, name="budget_reject"), # This is post method which takes username and password to generates/return Token - url(r'^login/$', obtain_auth_token, name='login'), + url(r"^login/$", obtain_auth_token, name="login"), # api for "clubdetails" method="get" with TokenAuthentication - url(r'^clubdetails/$', Club_Details.as_view()), + url(r"^clubdetails/$", Club_Details.as_view()), # api for "clubname" method="get" with TokenAuthentication - url(r'^Fest_budget/$',Fest_Budget.as_view(),name='Fest_budget'), + url(r"^Fest_budget/$", Fest_Budget.as_view(), name="Fest_budget"), # api for "festbudget" method="get" with TokenAuthentication - url(r'^club_report/$',club_report.as_view()), + url(r"^club_report/$", club_report.as_view()), # api for "club_report" method="get" with TokenAuthentication - url(r'^registration_form/$',Registraion_form.as_view()), + url(r"^registration_form/$", Registraion_form.as_view()), # api for "registration_form" method="get" with TokenAuthentication - url(r'^voting_polls/$',Voting_Polls.as_view()), + # url(r'^voting_polls/$',Voting_Polls.as_view()), # api for "voting_polls" method="get" with TokenAuthentication - - - - url(r'^clubname/$', clubname.as_view()), - url(r'^$', views.gymkhana, name='gymkhana'), - url(r'^delete_requests/$', views.delete_requests, name='delete_requests'), - url(r'^form_avail/$', views.form_avail, name='form_avail'), - url(r'^registration_form/$', views.registration_form, name='registration_form'), - url(r'^new_club/$', views.new_club, name='new_club'), - - #club_head - url(r'^approve/$', views.approve, name='approve'), - url(r'^reject/$', views.reject, name='reject'), - url(r'^cancel/$', views.cancel, name='cancel'), - url(r'^new_event/$', views.new_event, name='new_event'), - url(r'^new_session/$', views.new_session, name='new_session'), - url(r'^event_report/$', views.event_report, name='event_report'), - url(r'^club_event_report/$', views.club_report, name='club_report'), - url(r'^change_head/$', views.change_head, name='change_head'), - url(r'^club_budget/$', views.club_budget, name='club_budget'), - url(r'^act_calender/$', views.act_calender, name='act_calender'), - url(r'^date_sessions/$', views.date_sessions, name='date_sessions'), - url(r'^date_events/$', views.date_events, name='date_events'), - url(r'^delete_sessions/$', views.delete_sessions, name='delete_sessions'), - url(r'^delete_events/$', views.delete_events, name='delete_events'), - url(r'^(?P\d+)/edit_event/$', views.edit_event, name='edit_event'), - url(r'^(?P\d+)/editsession/$', views.editsession, name='editsession'), - url(r'^delete_memberform/$', views.delete_memberform, name='delete_memberform'), - url(r'^voting_poll/$', views.voting_poll, name='voting_poll'), - url(r'^delete_poll/(?P\d+)/$', views.delete_poll, name='delete_poll'), - - #student - url(r'^registration_form/$', views.registration_form, name='registration_form'), - url(r'^delete_requests/$', views.delete_requests, name='delete_requests'), - url(r'^club_membership/$', views.club_membership, name='membership'), - url(r'^(?P\d+)/$', views.vote, name='vote'), - url(r'^$', views.gymkhana, name='gymkhana'), - - #data recieving - url(r'^form_avail/$', views.form_avail, name='form_avail'), - url(r'^faculty_data/$', views.facultyData, name='faculty_data'), - url(r'^students_data/$', views.studentsData, name='students_data'), - url(r'^get_venue/$', views.getVenue, name='get_venue'), - - #core_team - url(r'^core_team/$', views.core_team, name='core_team'), - url(r'^festbudget/$', views.fest_budget, name='fest_budget'), + # url(r"^api/new_event/$", NewEventAPIView.as_view(), name="new_event_api"), + # url(r"^api/club_membership/$", AddMemberToClub.as_view(), name="new_club_member"), + # url(r"^api/delete_event/$", DeleteEventsView.as_view(), name="delete_events_api"), + # url( + # r"^api/delete_sessions/$", + # DeleteSessionsView.as_view(), + # name="delete_sessions_api", + # ), + # url(r"^api/new_session/$", NewSessionAPIView.as_view(), name="new_session_api"), + url(r"^clubname/$", clubname.as_view()), + url(r"^$", views.gymkhana, name="gymkhana"), + url(r"^delete_requests/$", views.delete_requests, name="delete_requests"), + url(r"^form_avail/$", views.form_avail, name="form_avail"), + url(r"^registration_form/$", views.registration_form, name="registration_form"), + url(r"^new_club/$", views.new_club, name="new_club"), + # url(r"^api/members_records/$", ClubMemberAPIView.as_view(), name="club_members"), + # club_head + url(r"^approve/$", views.approve, name="approve"), + url(r"^reject/$", views.reject, name="reject"), + url(r"^cancel/$", views.cancel, name="cancel"), + url(r"^new_event/$", views.new_event, name="new_event"), + url(r"^new_session/$", views.new_session, name="new_session"), + url(r"^event_report/$", views.event_report, name="event_report"), + url(r"^club_event_report/$", views.club_report, name="club_report"), + url(r"^change_head/$", views.change_head, name="change_head"), + url(r"^club_budget/$", views.club_budget, name="club_budget"), + url(r"^act_calender/$", views.act_calender, name="act_calender"), + url(r"^date_sessions/$", views.date_sessions, name="date_sessions"), + url(r"^date_events/$", views.date_events, name="date_events"), + url(r"^delete_sessions/$", views.delete_sessions, name="delete_sessions"), + url(r"^delete_events/$", views.delete_events, name="delete_events"), + url(r"^(?P\d+)/edit_event/$", + views.edit_event, name="edit_event"), + url(r"^(?P\d+)/editsession/$", + views.editsession, name="editsession"), + url(r"^delete_memberform/$", views.delete_memberform, name="delete_memberform"), + # url(r'^voting_poll/$', views.voting_poll, name='voting_poll'), + # url(r'^delete_poll/(?P\d+)/$', views.delete_poll, name='delete_poll'), + # student + url(r"^registration_form/$", views.registration_form, name="registration_form"), + url(r"^delete_requests/$", views.delete_requests, name="delete_requests"), + url(r"^club_membership/$", views.club_membership, name="membership"), + # url(r'^(?P\d+)/$', views.vote, name='vote'), + url(r"^$", views.gymkhana, name="gymkhana"), + # data recieving + url(r"^form_avail/$", views.form_avail, name="form_avail"), + url(r"^faculty_data/$", views.facultyData, name="faculty_data"), + url(r"^students_data/$", views.studentsData, name="students_data"), + url(r"^students_club_members/$", + views.studentsClubMembers, name="students_data"), + url(r"^get_venue/$", views.getVenue, name="get_venue"), + # core_team + url(r"^core_team/$", views.core_team, name="core_team"), + url(r"^festbudget/$", views.fest_budget, name="fest_budget"), + # fic + url(r"^Inventory_update/$", views.core_team, name="Inventory_update"), + url(r"^del_club/$", views.del_club, name="del_club"), + url(r"^approve_events/$", views.approve_events, name="approve_events"), + url(r"^update-club-name/$", views.update_club_name, name='update-club-name'), + url(r"^update-budget-amount/$", views.update_budget_amount, name='update_budget_amount'), + # url(r"^update-spent-amount/$", views.update_spent_amount, name='update_spent_amount'), + + + + #app + + url(r'^api/update_clubBudget/$', UpdateClubBudgetAPIView.as_view(), name='update budget'), + url(r'^api/add_clubBudget/$', AddClub_BudgetAPIView.as_view(), name='edit event'), + url(r'^api/update_coordinator/$', ChangeHeadAPIView.as_view(), name = 'update coordinator'), + url(r'^api/activity_calender/$', UploadActivityCalendarAPIView.as_view(), name='update activity calendder'), + url(r'^api/delete_event/$', EventDeleteAPIView.as_view(), name='delete_events_api'), + url(r'^api/delete_sessions/$', DeleteSessionsView.as_view(), name='delete_sessions_api'), + url(r'^api/new_session/$',NewSessionAPIView.as_view(), name='new_session_api'), + url(r'^api/new_event/$',NewEventAPIView.as_view(), name='new_event_api'), + url(r'^api/delete_club/$',DeleteClubAPIView.as_view(), name='delete_club'), + url(r'^api/members_records/$', ClubMemberAPIView.as_view(), name='club_members'), + url(r'^api/member_approve/$', ClubMemberApproveView.as_view(), name='approval'), + url(r'^api/member_reject/$', ClubMemberDeleteAPIView.as_view(), name='reject'), + url(r'^api/club_membership/$', AddMemberToClub.as_view(), name='new_club_member'), + url(r'^api/show_voting_choices/$', ShowVotingChoicesAPIView.as_view(), name='voting_choices'), + url(r'^api/delete_poll/$', VotingPollsDeleteAPIView.as_view(), name='delete poll'), + url(r'^api/vote/$', VoteIncrementAPIView.as_view(), name='give vote'), + url(r'^api/edit_session/$', SessionUpdateAPIView.as_view(), name='edit session'), + url(r'^api/edit_event/$', EventUpdateAPIView.as_view(), name='edit event'), + url(r'^api/delete_budget/$',DeleteClubBudgetAPIView.as_view(), name='delete budget'), + url(r'^api/upload_activitycalender/$', UploadActivityCalendarAPIView.as_view(), name='calender'), + url(r'^api/create_club/$', CreateClubAPIView.as_view(), name='new club'), + url(r'^api/update_clubStatus/$', UpdateClubStatusAPIView.as_view(),name = 'update club status' ), + url(r'^api/updateClubName/$', UpdateClubNameAPIView.as_view(), name = 'update club name'), + url(r'^api/approve_event/$', ApproveEvent.as_view(), name = 'approve event'), ] diff --git a/FusionIIIT/applications/gymkhana/views.py b/FusionIIIT/applications/gymkhana/views.py index 7f54215bb..393d26986 100644 --- a/FusionIIIT/applications/gymkhana/views.py +++ b/FusionIIIT/applications/gymkhana/views.py @@ -1,3 +1,4 @@ +from django.db import transaction from django.contrib import messages from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User @@ -8,7 +9,7 @@ from bisect import bisect from django.contrib import messages from django.shortcuts import * -from applications.filetracking.models import File, Tracking +from applications.filetracking.models import File, Tracking from django.template.defaulttags import csrf_token from django.http import HttpResponse, HttpResponseRedirect, JsonResponse from django.contrib.auth.decorators import login_required @@ -16,7 +17,14 @@ from django.core import serializers from django.contrib.auth.models import User from timeit import default_timer as time -from notification.views import gymkhana_voting, office_module_notif, gymkhana_session, gymkhana_event +from django.core.exceptions import ObjectDoesNotExist +from notification.views import ( + gymkhana_voting, + office_module_notif, + gymkhana_session, + gymkhana_event, +) +from applications.globals.models import HoldsDesignation from django.views.decorators.csrf import ensure_csrf_cookie from applications.academic_information.models import Student from applications.globals.models import * @@ -29,1846 +37,2630 @@ import logging logger = logging.getLogger(__name__) + + def coordinator_club(request): - """ - coordinator_club: - this function is used to return the details of the Club_info of the requested user - if the user is either the coordinator or the cocoordinator of the club - @param: - request - trivial - @variables: - details - contains the Club_info - co_ordinator - contains the details of the Club co_ordinator - co_coordinator - contains the details of the Club co_coordinator - """ - for details in Club_info.objects.select_related('co_ordinator','co_ordinator__id','co_ordinator__id__user','co_ordinator__id__department','co_coordinator','co_coordinator__id','co_coordinator__id__user','co_coordinator__id__department','faculty_incharge','faculty_incharge__id','faculty_incharge__id__user','faculty_incharge__id__department').all(): - co_ordinator= (str(details.co_ordinator)).split(" ") - co_coordinator= (str(details.co_coordinator)).split(" ") - if co_ordinator[0] == str(request.user) or co_coordinator[0] == str(request.user) : - return(details) + """ + coordinator_club: + this function is used to return the details of the Club_info of the requested user + if the user is either the coordinator or the cocoordinator of the club + @param: + request - trivial + @variables: + details - contains the Club_info + co_ordinator - contains the details of the Club co_ordinator + co_coordinator - contains the details of the Club co_coordinator + """ + for details in Club_info.objects.select_related( + "co_ordinator", + "co_ordinator__id", + "co_ordinator__id__user", + "co_ordinator__id__department", + "co_coordinator", + "co_coordinator__id", + "co_coordinator__id__user", + "co_coordinator__id__department", + "faculty_incharge", + "faculty_incharge__id", + "faculty_incharge__id__user", + "faculty_incharge__id__department", + ).all(): + co_ordinator = (str(details.co_ordinator)).split(" ") + co_coordinator = (str(details.co_coordinator)).split(" ") + if co_ordinator[0] == str(request.user) or co_coordinator[0] == str( + request.user + ): + return details + @csrf_exempt def delete_sessions(request): - """ - delete_sessions: - This view deletes the session based on the request_id in Session_info - if it runs without exception then it deletes and return the result : success - if not then it just returns the result : error - @param: - request - trivial - @variables: - selectedIds - contains the id of the request - delSession - this contains the details of Session which needs to be deleted based on the SelectedIds from Session_info - - """ - selectedIds = request.POST['ids'] - selectedIds = json.loads(selectedIds) - try: - for ids in selectedIds: - delSession = Session_info.objects.get(id=ids) - delSession.delete() - return HttpResponse("success") - except Exception as e: - logger.error("An error was encountered") - return HttpResponse("error") + """ + delete_sessions: + This view deletes the session based on the request_id in Session_info + if it runs without exception then it deletes and return the result : success + if not then it just returns the result : error + @param: + request - trivial + @variables: + selectedIds - contains the id of the request + delSession - this contains the details of Session which needs to be deleted based on the SelectedIds from Session_info + + """ + selectedIds = request.POST["ids"] + selectedIds = json.loads(selectedIds) + try: + for ids in selectedIds: + delSession = Session_info.objects.get(id=ids) + delSession.delete() + return HttpResponse("success") + except Exception as e: + logger.error("An error was encountered") + return HttpResponse("error") def editsession(request, session_id): - """ - editsession: - This function is used to edit the club_sessions for clubs by their users. - By using this the club user can edit the session. - If the given date and time and venue clasheswith already booked session it doesn't edit the session. - And it displays success if there is no exception and displays error if there is an exception. - - @param: - request - trivial - - @variables: - venue - the place/room at which the session is going to happen - session_poster - it is a file that has to be uploaded which contains the poster for session - date - the date at which session is going to happen - start_time - the time at which session is going to start - end_time - the time at which session is going to end - desc - brief explanation about session if any - club_name - requests the coordinator_club and it returns - result - checks wheather the date,time,venue clashes with other session using conflict_algorithm_session view - session - if result is success then the session books successfully - - - """ - if request.method == 'POST': - try: - body = request.POST - venue = body.get('venue_type') - session_poster = request.FILES.get('session_poster') - date = body.get('date') - start_time = body.get('start_time') - end_time = body.get('end_time') - desc = body.get('d_d') - club_name = coordinator_club(request) - result = conflict_algorithm_session(date, start_time, end_time, venue) - message = "" - if (result == 'success'): - event = Session_info.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').get(id=session_id) - event.club = club_name - event.venue = venue - event.date = date - event.start_time = start_time - event.end_time = end_time - event.session_poster = session_poster - event.details = desc - event.save() - # e = Session_info.objects.filter(id=session_id).update(club=club_name,venue=venue, date=date,start_time=start_time, end_time=end_time, session_poster=session_poster, details=desc) - message += "Your form has been dispatched for further process" - return redirect('/gymkhana/') - else: - message += "The selected time slot for the given date and venue conflicts with already booked session" - except Exception as e: - result = "error" - message = "Some error occurred" - logger.info(message,e) - - ##Get Request - # Session_info.objects(club=club_name,venue=venue,date=date,start_time=start_time,end_time=end_time,session_poster=session_poster, details=desc) - venue = [] - event = Session_info.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').get(pk=session_id) - - for rooms in Constants.venue: - for venues in rooms[1]: - venue.append(venues[0]) - context = { - 'form': { - "venue": event.venue, - "session_poster": event.session_poster, - "date": datetime.datetime.strftime(event.date, '%Y-%m-%d'), - "start_time": event.start_time, - "end_time": event.end_time, - "desc": event.details, - "club_name": event.club, - "Venue": venue, - "id": session_id - } - } - # res = conflict_algorithm_event(date, start_time, end_time, venue) - template = 'gymkhanaModule/editsession.html' - - return render(request, template, context) + """ + editsession: + This function is used to edit the club_sessions for clubs by their users. + By using this the club user can edit the session. + If the given date and time and venue clasheswith already booked session it doesn't edit the session. + And it displays success if there is no exception and displays error if there is an exception. + + @param: + request - trivial + + @variables: + venue - the place/room at which the session is going to happen + session_poster - it is a file that has to be uploaded which contains the poster for session + date - the date at which session is going to happen + start_time - the time at which session is going to start + end_time - the time at which session is going to end + desc - brief explanation about session if any + club_name - requests the coordinator_club and it returns + result - checks wheather the date,time,venue clashes with other session using conflict_algorithm_session view + session - if result is success then the session books successfully + + + """ + if request.method == "POST": + try: + body = request.POST + venue = body.get("venue_type") + session_poster = request.FILES.get("session_poster") + date = body.get("date") + start_time = body.get("start_time") + end_time = body.get("end_time") + desc = body.get("d_d") + club_name = coordinator_club(request) + result = conflict_algorithm_session( + date, start_time, end_time, venue) + message = "" + if result == "success": + event = Session_info.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ).get(id=session_id) + event.club = club_name + event.venue = venue + event.date = date + event.start_time = start_time + event.end_time = end_time + event.session_poster = session_poster + event.details = desc + event.save() + # e = Session_info.objects.filter(id=session_id).update(club=club_name,venue=venue, date=date,start_time=start_time, end_time=end_time, session_poster=session_poster, details=desc) + message += "Your form has been dispatched for further process" + return redirect("/gymkhana/") + else: + message += "The selected time slot for the given date and venue conflicts with already booked session" + except Exception as e: + result = "error" + message = "Some error occurred" + logger.info(message, e) + + # Get Request + # Session_info.objects(club=club_name,venue=venue,date=date,start_time=start_time,end_time=end_time,session_poster=session_poster, details=desc) + venue = [] + event = Session_info.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ).get(pk=session_id) + + for rooms in Constants.venue: + for venues in rooms[1]: + venue.append(venues[0]) + context = { + "form": { + "venue": event.venue, + "session_poster": event.session_poster, + "date": datetime.datetime.strftime(event.date, "%Y-%m-%d"), + "start_time": event.start_time, + "end_time": event.end_time, + "desc": event.details, + "club_name": event.club, + "Venue": venue, + "id": session_id, + } + } + # res = conflict_algorithm_event(date, start_time, end_time, venue) + template = "gymkhanaModule/editsession.html" + + return render(request, template, context) @csrf_exempt def delete_events(request): - """ - delete_events: - This view deletes the event based on the request_id in Event_info - if it runs without exception then it deletes and return the result : success - if not then it just returns the result : error - @param: - request - trivial - @variables: - selectedIds - contains the id of the request - delEvent - this contains the details of Event which needs to be deleted based on the SelectedIds from Event_info - - """ - selectedIds = request.POST['ids'] - selectedIds = json.loads(selectedIds) - message = "" - try: - for ids in selectedIds: - delEvent = Event_info.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').get(id=ids) - delEvent.delete() - return HttpResponse("success") - except Exception as e: - logger.error("An error was encountered") - return HttpResponse("error") - -def edit_event(request,event_id): - # event = Event_info.objects.get(pk=event_id) - """ - edit_event: - This function is used to edit the club_event for clubs by their users. - By using this the club user can edit the event. - If the given date and time and venue clasheswith already booked session it doesn't edit the event. - And it displays success if there is no exception and displays error if there is an exception. - - @param: - request - trivial - - @variables: - venue - the place/room at which the event is going to happen - event_name - it has the name of the event - date - the date at which event is going to happen - start_time - the time at which event is going to start - end_time - the time at which event is going to end - desc - brief explanation about event if any - club_name - requests the coordinator_club and it returns - result - checks wheather the date,time,venue clashes with other event using conflict_algorithm_session view - event - if result is success then the event books successfully - - """ - if request.method == 'POST': - try: - body = request.POST - event_name = body.get('event_name') - incharge=body.get('incharge') - venue = body.get('venue_type') - event_poster = request.FILES.get('event_poster') - date = body.get('date') - start_time = body.get('start_time') - end_time = body.get('end_time') - desc = body.get('d_d') - club_name = coordinator_club(request) - result = conflict_algorithm_event(date, start_time, end_time, venue) - message = "" - if(result == 'success'): - event = Event_info.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').get(id=event_id) - event.club = club_name - event.event_name = event_name - event.incharge = incharge - event.venue = venue - event.date = date - event.start_time = start_time - event.end_time = end_time - event.event_poster = event_poster - event.details = desc - event.save() - # e = Event_info.objects.filter(id=event_id).update(club = club_name, event_name=event_name, incharge=incharge, venue = venue, date =date, start_time=start_time , end_time = end_time ,event_poster = event_poster , details = desc) - message += "Your form has been dispatched for further process" - return redirect('/gymkhana/') - else: - message += "The selected time slot for the given date and venue conflicts with already booked session" - except Exception as e: - result = "error" - message = "Some error occurred" - logger.info(message,e) - - - ##Get Request - # Event_info(club = club_name, event_name=event_name, incharge=incharge, venue = venue, date =date, start_time=start_time , end_time = end_time ,event_poster = event_poster , details = desc) - venue = [] - event = Event_info.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').get(pk=event_id) - - for rooms in Constants.venue: - for venues in rooms[1]: - venue.append(venues[0]) - context = { - 'form':{ - "event_name":event.event_name, - "incharge":event.incharge, - "venue" : event.venue, - "event_poster" : event.event_poster, - "date":datetime.datetime.strftime(event.date,'%Y-%m-%d'), - "start_time": event.start_time, - "end_time" : event.end_time, - "desc" : event.details, - "club_name" : event.club, - "Venue": venue, - "id":event_id - } - } - # res = conflict_algorithm_event(date, start_time, end_time, venue) - template='gymkhanaModule/editevent.html' - - return render(request,template,context) + """ + delete_events: + This view deletes the event based on the request_id in Event_info + if it runs without exception then it deletes and return the result : success + if not then it just returns the result : error + @param: + request - trivial + @variables: + selectedIds - contains the id of the request + delEvent - this contains the details of Event which needs to be deleted based on the SelectedIds from Event_info + + """ + selectedIds = request.POST["ids"] + selectedIds = json.loads(selectedIds) + message = "" + try: + for ids in selectedIds: + delEvent = Event_info.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ).get(id=ids) + delEvent.delete() + return HttpResponse("success") + except Exception as e: + logger.error("An error was encountered") + return HttpResponse("error") + + +def edit_event(request, event_id): + # event = Event_info.objects.get(pk=event_id) + """ + edit_event: + This function is used to edit the club_event for clubs by their users. + By using this the club user can edit the event. + If the given date and time and venue clasheswith already booked session it doesn't edit the event. + And it displays success if there is no exception and displays error if there is an exception. + + @param: + request - trivial + + @variables: + venue - the place/room at which the event is going to happen + event_name - it has the name of the event + date - the date at which event is going to happen + start_time - the time at which event is going to start + end_time - the time at which event is going to end + desc - brief explanation about event if any + club_name - requests the coordinator_club and it returns + result - checks wheather the date,time,venue clashes with other event using conflict_algorithm_session view + event - if result is success then the event books successfully + + """ + if request.method == "POST": + try: + body = request.POST + event_name = body.get("event_name") + incharge = body.get("incharge") + venue = body.get("venue_type") + event_poster = request.FILES.get("event_poster") + date = body.get("date") + start_time = body.get("start_time") + end_time = body.get("end_time") + desc = body.get("d_d") + club_name = coordinator_club(request) + result = conflict_algorithm_event( + date, start_time, end_time, venue) + message = "" + if result == "success": + event = Event_info.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ).get(id=event_id) + event.club = club_name + event.event_name = event_name + event.incharge = incharge + event.venue = venue + event.date = date + event.start_time = start_time + event.end_time = end_time + event.event_poster = event_poster + event.details = desc + event.status = 'confirmed' + event.save() + # e = Event_info.objects.filter(id=event_id).update(club = club_name, event_name=event_name, incharge=incharge, venue = venue, date =date, start_time=start_time , end_time = end_time ,event_poster = event_poster , details = desc) + message += "Your form has been dispatched for further process" + return redirect("/gymkhana/") + else: + message += "The selected time slot for the given date and venue conflicts with already booked session" + except Exception as e: + result = "error" + message = "Some error occurred" + logger.info(message, e) + + # Get Request + # Event_info(club = club_name, event_name=event_name, incharge=incharge, venue = venue, date =date, start_time=start_time , end_time = end_time ,event_poster = event_poster , details = desc) + venue = [] + event = Event_info.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ).get(pk=event_id) + + for rooms in Constants.venue: + for venues in rooms[1]: + venue.append(venues[0]) + context = { + "form": { + "event_name": event.event_name, + "incharge": event.incharge, + "venue": event.venue, + "event_poster": event.event_poster, + "date": datetime.datetime.strftime(event.date, "%Y-%m-%d"), + "start_time": event.start_time, + "end_time": event.end_time, + "desc": event.details, + "club_name": event.club, + "Venue": venue, + "id": event_id, + } + } + # res = conflict_algorithm_event(date, start_time, end_time, venue) + template = "gymkhanaModule/editevent.html" + + return render(request, template, context) + def delete_memberform(request): - """ - delete_memberform: - This view deletes the memberform based on the request_id in Club_member - if it runs without exception then it deletes and return the result : success - if not then it just returns the result : error - @param: - request - trivial - @variables: - selectedIds - contains the id of the request - delMemberform - this contains the details of member which needs to be deleted based on the SelectedIds from Club_member - - """ - selectedIds = request.POST['ids'] - selectedIds = json.loads(selectedIds) - try: - for ids in selectedIds: - delMemberform = Club_member.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department','member','member__id','member__id__user','member__id__department').get(id=ids) - delMemberform.delete() - return HttpResponse("success") - except Exception as e: - logger.error("An error was encountered") - return HttpResponse("error") + """ + delete_memberform: + This view deletes the memberform based on the request_id in Club_member + if it runs without exception then it deletes and return the result : success + if not then it just returns the result : error + @param: + request - trivial + @variables: + selectedIds - contains the id of the request + delMemberform - this contains the details of member which needs to be deleted based on the SelectedIds from Club_member + + """ + selectedIds = request.POST["ids"] + selectedIds = json.loads(selectedIds) + try: + for ids in selectedIds: + delMemberform = Club_member.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + "member", + "member__id", + "member__id__user", + "member__id__department", + ).get(id=ids) + delMemberform.delete() + return HttpResponse("success") + except Exception as e: + logger.error("An error was encountered") + return HttpResponse("error") + def facultyData(request): - """ - facultyData: - this function is used to return the facultyNames from the ExtraInfo of the requested value which are not present in the current value - @param: - request - trivial - @variables: - faculty - contains the Extrainfo of the faculty - facultyName - contains the list of faculties firstname and lastname - name - contains the lecturers first name and the last name - """ - current_value = request.POST['current_value'] - try: - # students =ExtraInfo.objects.all().filter(user_type = "student") - faculty = ExtraInfo.objects.select_related('user','department').all().filter(user_type = "faculty") - facultyNames = [] - for lecturer in faculty: - name = lecturer.user.first_name + " " +lecturer.user.last_name - if current_value != "": - Lowname = name.lower() - Lowcurrent_value = current_value.lower() - if Lowcurrent_value in Lowname: - facultyNames.append(name) - else: - facultyNames.append(name) - faculty = json.dumps(facultyNames) - return HttpResponse(faculty) - except Exception as e: - return HttpResponse("error") + """ + facultyData: + this function is used to return the facultyNames from the ExtraInfo of the requested value which are not present in the current value + @param: + request - trivial + @variables: + faculty - contains the Extrainfo of the faculty + facultyName - contains the list of faculties firstname and lastname + name - contains the lecturers first name and the last name + """ + current_value = request.POST["current_value"] + try: + # students =ExtraInfo.objects.all().filter(user_type = "student") + faculty = ( + ExtraInfo.objects.select_related("user", "department") + .all() + .filter(user_type="faculty") + ) + facultyNames = [] + for lecturer in faculty: + name = lecturer.user.first_name + " " + lecturer.user.last_name + if current_value != "": + Lowname = name.lower() + Lowcurrent_value = current_value.lower() + if Lowcurrent_value in Lowname: + facultyNames.append(name) + else: + facultyNames.append(name) + faculty = json.dumps(facultyNames) + return HttpResponse(faculty) + except Exception as e: + return HttpResponse("error") def studentsData(request): - """ - studentsData: - this function is used to return the students data from the ExtraInfo of the requested value - @param: - request - trivial - @variables: - students- contains the Extrainfo of the faculty for the required current value - - """ - current_value = request.POST['current_value'] - try: - # students = ExtraInfo.objects.all().filter(user_type="student").filter(id__startswith=current_value) - students = ExtraInfo.objects.select_related('user','department').all().filter(user_type="student").filter(id__startswith=current_value) - students = serializers.serialize('json', students) - return HttpResponse(students) - except Exception as e: - return HttpResponse("error") + """ + studentsData: + this function is used to return the students data from the ExtraInfo of the requested value + @param: + request - trivial + @variables: + students- contains the Extrainfo of the faculty for the required current value + + """ + current_value = request.POST["current_value"] + try: + # students = ExtraInfo.objects.all().filter(user_type="student").filter(id__startswith=current_value) + students = ( + ExtraInfo.objects.select_related("user", "department") + .all() + .filter(user_type="student") + .filter(id__startswith=current_value) + ) + students = serializers.serialize("json", students) + return HttpResponse(students) + except Exception as e: + return HttpResponse("error") + + +def studentsClubMembers(request): + """ + studentsData: + this function is used to return the students data from the ExtraInfo of the requested value + @param: + request - trivial + @variables: + students- contains the Extrainfo of the faculty for the required current value + + """ + club_filter = request.POST["club_name"] + print(club_filter) + try: + # students = ExtraInfo.objects.all().filter(user_type="student").filter(id__startswith=current_value) + students = ( + Club_member.objects.select_related() + .all() + .filter(club=club_filter) + ) + students = serializers.serialize("json", students) + return HttpResponse(students) + except Exception as e: + return HttpResponse("error") @login_required def new_club(request): - """ - new_club: - this function is used to create a new club with the given data and to check whether - the given info of the co_ordinator , co-coordinator and faculty is true or not from the Student_info and Extra_info , - And if the data is true then dump the json content or else return the error that these data doesn't exit - - @param: - request - trivial - @variables: - club_name - contains the club_name from the request - category - contains the category to which the club belongs - co_ordinator - contains the id of the new_club's co_ordinator - co_coordinator - contains the id of the new_club's co_coordinator - faculty - contains the details of the faculty for the new_club - d_d = contains the descriptons of the - """ - if request.method == 'POST': - result = None - message = None - try: - club_name = request.POST.get("club_name") - category = request.POST.get("category") - print(category) - co_ordinator = request.POST.get("co") - co_coordinator = request.POST.get("coco") - faculty = request.POST.get("faculty") - print("faculty",faculty) - # club_file = request.FILES.get("file") - d_d = request.POST.get("d_d") - - result = "error" - message = "" - co_ordinator = co_ordinator.strip() - co_coordinator = co_coordinator.strip() - faculty = faculty.strip() - #checking if the form data is authentic - #checking for coordinator field - students = ExtraInfo.objects.select_related('user','department').all().filter(user_type = "student") - CO = None - for student_info in students: - if co_ordinator == student_info.id: - result = "success" - CO = student_info - break - print("result",result) - if (result == "error"): - message = message + "The entered roll number of the co_ordinator does not exist" - content = { - 'status' : result, - 'message' : message - } - content = json.dumps(content) - return HttpResponse(content) - - #checking for co-coordinator field - COCO = None - result = "error" - for student_info in students: - if co_coordinator == student_info.id: - result = "success" - COCO = student_info - break - print("cocoordinator",result) - if(result == "error"): - message = message + "The entered roll number of the co_coordinator does not exist" - content = { - 'status' : result, - 'message' : message - } - content = json.dumps(content) - return HttpResponse(content) - - #checking for faculty field - FACUL = None - faculties = ExtraInfo.objects.select_related('user','department').all().filter(user_type = "faculty") - result = "error" - for lecturer in faculties: - checkName = lecturer.user.first_name + " " + lecturer.user.last_name - # print() - if faculty == checkName: - result = "success" - FACUL = lecturer - break - print("faculty",result) - print(CO,COCO) - if (result == "error"): - message = message + "The entered faculty incharge does not exist" - content = { - 'status' : result, - 'message' : message - } - content = json.dumps(content) - return HttpResponse(content) - #getting queryset class objects - co_student = get_object_or_404(Student, id = CO) - print(co_student) - #getting queryset class objects - coco_student = get_object_or_404(Student, id = COCO) - print(coco_student) - #getting queryset class objects - # faculty = faculty.split(" - ") - # user_name = get_object_or_404(User, username = faculty[1]) - # faculty = get_object_or_404(ExtraInfo, id = faculty[0], user = user_name) - faculty_inc = get_object_or_404(Faculty, id = FACUL) - print(faculty_inc) - # club_file.name = club_name+"_club_file" - - club_info = Club_info(club_name = club_name, category = category, co_ordinator = co_student, co_coordinator = coco_student, faculty_incharge = faculty_inc, description = d_d) - print(club_info) - club_info.save() - print("saved successfully") - message = message + "The form has been successfully dispatched for further process" - except Exception as e: - result = "error" - message = "Some error occurred" - - content = { - 'status' : result, - 'message' : message - } - content = json.dumps(content) - HttpResponse(content) - return redirect('/gymkhana/') - + """ + new_club: + this function is used to create a new club with the given data and to check whether + the given info of the co_ordinator , co-coordinator and faculty is true or not from the Student_info and Extra_info , + And if the data is true then dump the json content or else return the error that these data doesn't exit + + @param: + request - trivial + @variables: + club_name - contains the club_name from the request + category - contains the category to which the club belongs + co_ordinator - contains the id of the new_club's co_ordinator + co_coordinator - contains the id of the new_club's co_coordinator + faculty - contains the details of the faculty for the new_club + d_d = contains the descriptons of the + """ + if request.method == "POST": + result = None + message = None + try: + club_name = request.POST.get("club_name") + category = request.POST.get("category") + print(category) + co_ordinator = request.POST.get("co") + co_coordinator = request.POST.get("coco") + faculty = request.POST.get("faculty") + print("faculty", faculty) + # club_file = request.FILES.get("file") + d_d = request.POST.get("d_d") + + result = "error" + message = "" + co_ordinator = co_ordinator.strip() + co_coordinator = co_coordinator.strip() + faculty = faculty.strip() + # checking if the form data is authentic + # checking for coordinator field + students = ( + ExtraInfo.objects.select_related("user", "department") + .all() + .filter(user_type="student") + ) + CO = None + for student_info in students: + if co_ordinator == student_info.id: + result = "success" + CO = student_info + break + print("result", result) + if result == "error": + message = ( + message + + "The entered roll number of the co_ordinator does not exist" + ) + content = {"status": result, "message": message} + content = json.dumps(content) + return HttpResponse(content) + + # checking for co-coordinator field + COCO = None + result = "error" + for student_info in students: + if co_coordinator == student_info.id: + result = "success" + COCO = student_info + break + print("cocoordinator", result) + if result == "error": + message = ( + message + + "The entered roll number of the co_coordinator does not exist" + ) + content = {"status": result, "message": message} + content = json.dumps(content) + return HttpResponse(content) + + # checking for faculty field + FACUL = None + faculties = ( + ExtraInfo.objects.select_related("user", "department") + .all() + .filter(user_type="faculty") + ) + result = "error" + for lecturer in faculties: + checkName = lecturer.user.first_name + " " + lecturer.user.last_name + # print() + if faculty == checkName: + result = "success" + FACUL = lecturer + break + print("faculty", result) + print(CO, COCO) + if result == "error": + message = message + "The entered faculty incharge does not exist" + content = {"status": result, "message": message} + content = json.dumps(content) + return HttpResponse(content) + # getting queryset class objects + co_student = get_object_or_404(Student, id=CO) + print(co_student) + # getting queryset class objects + coco_student = get_object_or_404(Student, id=COCO) + print(coco_student) + # getting queryset class objects + # faculty = faculty.split(" - ") + # user_name = get_object_or_404(User, username = faculty[1]) + # faculty = get_object_or_404(ExtraInfo, id = faculty[0], user = user_name) + faculty_inc = get_object_or_404(Faculty, id=FACUL) + print(faculty_inc) + # club_file.name = club_name+"_club_file" + + club_info = Club_info( + club_name=club_name, + category=category, + co_ordinator=co_student, + co_coordinator=coco_student, + faculty_incharge=faculty_inc, + description=d_d, + status="open", + ) + print(club_info) + club_info.save() + print("saved successfully") + message = ( + message + + "The form has been successfully dispatched for further process" + ) + except Exception as e: + result = "error" + message = "Some error occurred" + + content = {"status": result, "message": message} + content = json.dumps(content) + HttpResponse(content) + return redirect("/gymkhana/") @login_required() def form_avail(request): - """ - form_avail: - this function is used to fill the form if available and then save the data - if there is an exception return an error - - @param: - request - trivial - @variables: - form_name - it is used to send the data for the registration - status - it is availablity of form - """ - if request.method == 'POST': - result = "success" - message = "Form available?" - try: - #getting form data - form_name = request.POST["registration"] - status = request.POST["available"] - - if(status == "On"): - status = True - else: - status = False - roll = request.user.username - rev = Form_available.objects.get(roll=roll).form_name - if rev != form_name: - delete_requests(request) - #saving data to the database - rob = Form_available.objects.get(roll=roll) - rob.form_name = form_name - rob.status = status - rob.save() - - except Exception as e: - logger.info(e) - result = "error" - message = "You've already filled the form." - - content = { - 'status': result, - 'message': message, - } - content = json.dumps(content) - # messages.success(request, "Form available?") - return HttpResponse(content) - # redirect("/gymkhana/") + """ + form_avail: + this function is used to fill the form if available and then save the data + if there is an exception return an error + + @param: + request - trivial + @variables: + form_name - it is used to send the data for the registration + status - it is availablity of form + """ + if request.method == "POST": + result = "success" + message = "Form available?" + try: + # getting form data + form_name = request.POST["registration"] + status = request.POST["available"] + + if status == "On": + status = True + else: + status = False + roll = request.user.username + rev = Form_available.objects.get(roll=roll).form_name + if rev != form_name: + delete_requests(request) + # saving data to the database + rob = Form_available.objects.get(roll=roll) + rob.form_name = form_name + rob.status = status + rob.save() + + except Exception as e: + logger.info(e) + result = "error" + message = "You've already filled the form." + + content = { + "status": result, + "message": message, + } + content = json.dumps(content) + # messages.success(request, "Form available?") + return HttpResponse(content) + # redirect("/gymkhana/") + @login_required def delete_requests(request): - """ - delete_requests: - This view deletes all objects in Registration_form table - if it runs without exception then it deletes and return the result : success - if not then it just returns the result : error in json object - Only this can be when the method is POST - @param: - request : trivial - @variables: - register_objects : all objects of records in Registration_form - """ - if request.method == 'POST': - result = "success" - message = "Data is Deleted." - try: - register_objects = Registration_form.objects.all() - register_objects.delete() - - except Exception as e: - result = "error" - message = "Some error occured." - content = { - 'status': result, - 'message': message, - } - content = json.dumps(content) - return HttpResponse(content) + """ + delete_requests: + This view deletes all objects in Registration_form table + if it runs without exception then it deletes and return the result : success + if not then it just returns the result : error in json object + Only this can be when the method is POST + @param: + request : trivial + @variables: + register_objects : all objects of records in Registration_form + """ + if request.method == "POST": + result = "success" + message = "Data is Deleted." + try: + register_objects = Registration_form.objects.all() + register_objects.delete() + + except Exception as e: + result = "error" + message = "Some error occured." + content = { + "status": result, + "message": message, + } + content = json.dumps(content) + return HttpResponse(content) @login_required() def registration_form(request): - """ - registration_form - This view recieves the data from Front-end side and saves into the Registration_form database - if it runs without exception then it deletes and return the result : success - if not then it just returns the result : error in json object - Only this can be when the method is POST - @params: - request : trivial - @variables: - user_name : name of the user - roll : Roll number of student - cpi : cpi of the student - branch : branch name of the student - programme : Programme of the student - """ - if request.method == 'POST': - result = "success" - message = "The form has been dispatched for further process" - try: - #getting form data - info = Student.objects.select_related('id','id__user','id__department').get(id__user=request.user).cpi - user_name = request.POST.get("user_name") - roll = request.POST.get("roll") - cpi = request.POST.get("cpi") - branch = request.POST.get("branch") - programme = request.POST.get("programme") - - #saving data to the database - register = Registration_form(user_name=user_name, branch=branch, roll=roll, cpi=cpi, programme=programme) - register.save() - # club_member = Club_member(member = student, club = club_name, description = pda) - # club_member.save() - except Exception as e: - logger.info(f"{e}DSANKJDVBJBDAKSCBASKFBasjcbaskjvbaskvaslvbna") - result = "error" - message = "You've already filled the form." - - content = { - 'status':result, - 'message':message - } - content = json.dumps(content) - return HttpResponse(content) - # messages.success(request,"Successfully sent the application !!!") - - # return redirect('/gymkhana/') - -def retrun_content(request, roll, name, desig , club__ ): - """ - retrun_content - This view returns all data regarding the parameters that sent through function - The returned data contains all information regarding all clubs , polling system , status of clubs , - students info who are in the designation, which was sent through parameters of this function - @param: - request : trivial - roll : Roll number of the student - name : name of the user - desig : Designition of the user - club__ : club name of the user - @variables: - student : All info of the student passes through the function - faculty : All info of the faculty - club_name : All club names - club_member : All info of the Club_member - fest_budget : All info of the fest_budget - club_budget : All info of the Club_budget - club_session : All info of the Session_info - club_event : All info of the Event_info - club_event_report : All info of the Club_report - - """ - students =ExtraInfo.objects.select_related('user','department').filter(user_type = "student") - faculty = ExtraInfo.objects.select_related('user','department').filter(user_type = "faculty") - club_name = Club_info.objects.select_related('co_ordinator','co_ordinator__id','co_ordinator__id__user','co_ordinator__id__department','co_coordinator','co_coordinator__id','co_coordinator__id__user','co_coordinator__id__department','faculty_incharge','faculty_incharge__id','faculty_incharge__id__user','faculty_incharge__id__department').all() - club_member = Club_member.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department','member','member__id','member__id__user','member__id__department').all() - fest_budget = Fest_budget.objects.all() - club_budget = Club_budget.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').all() - club_session = Session_info.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').all() - club_event = Event_info.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').all() - club_event_report = Club_report.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department','incharge','incharge__user','incharge__department').all() - if 'student' in desig or 'Convenor' in desig: - registration_form = Registration_form.objects.all() - cpi = Student.objects.select_related('id','id__user','id__department').get(id__user=request.user).cpi - programme = Student.objects.select_related('id','id__user','id__department').get(id__user=request.user).programme - - try: - form_name = Form_available.objects.get(roll=request.user.username).form_name - logger.info(f'{form_name} MKNCjncknisncs') - status = Form_available.objects.get(roll=request.user.username).status - except Exception as e: - forms = Form_available.objects.all() - for form in forms: - form_name = form.form_name - status = form.status - break - - venue_type = [] - id =0 - venue = [] - - - for rooms in Constants.venue: - for room in rooms[1]: - venue.append(room[0]) - curr_club=[] - if 'student' in desig: - user_name = get_object_or_404(User, username = str(roll)) - extra = get_object_or_404(ExtraInfo, id = roll, user = user_name) - student = get_object_or_404(Student, id = extra) - else : - curr_club = [] - - # creating the data for the active voting polls - voting_polls = [] - for poll in Voting_polls.objects.all(): - event = {} - choices = [] - event["id"] = poll.id - event["title"] = poll.title - event["desc"] = poll.description - event['exp_date'] = (poll.exp_date- datetime.datetime.now()).days if (datetime.datetime.now() - poll.exp_date).days <= 0 else 'expire' - event['pub_date'] = poll.exp_date.strftime("%d/%m/%Y") - event["created_by"] = poll.created_by.split(":") - for choice in poll.voting_choices_set.all(): - choices.append({'title':choice.title,'id':choice.id,'votes':choice.votes}) - - event['choices'] = choices - event['max'] = poll.voting_choices_set.latest() - event['voters'] = poll.voting_voters_set.values_list('student_id', flat=True) - event['groups'] = json.loads(poll.groups) - - voting_polls.append(event) - - content = { - 'Students' : students, - 'Club_name' : club_name, - 'Faculty' : faculty, - 'Club_member' : club_member, - 'Fest_budget' : fest_budget, - 'Club_budget' : club_budget, - 'Club_session': club_session, - 'Club_event' : club_event, - 'Club_event_report' : club_event_report, - 'Curr_club' : curr_club, - 'venue' : venue, - 'Curr_desig' : desig, - 'club_details':club__, - 'voting_polls': voting_polls, - 'roll' : str(roll), - - } - if 'student' in desig or 'Convenor' in desig: - content1 = { - 'registration_form': registration_form, - 'cpi': cpi, - 'programme': programme, - 'form_name': form_name, - 'status': status, - } - content.update(content1) - return content + """ + registration_form + This view recieves the data from Front-end side and saves into the Registration_form database + if it runs without exception then it deletes and return the result : success + if not then it just returns the result : error in json object + Only this can be when the method is POST + @params: + request : trivial + @variables: + user_name : name of the user + roll : Roll number of student + cpi : cpi of the student + branch : branch name of the student + programme : Programme of the student + """ + if request.method == "POST": + result = "success" + message = "The form has been dispatched for further process" + try: + # getting form data + info = ( + Student.objects.select_related( + "id", "id__user", "id__department") + .get(id__user=request.user) + .cpi + ) + user_name = request.POST.get("user_name") + roll = request.POST.get("roll") + cpi = request.POST.get("cpi") + branch = request.POST.get("branch") + programme = request.POST.get("programme") + + # saving data to the database + register = Registration_form( + user_name=user_name, + branch=branch, + roll=roll, + cpi=cpi, + programme=programme, + ) + register.save() + # club_member = Club_member(member = student, club = club_name, description = pda) + # club_member.save() + except Exception as e: + logger.info(f"{e}DSANKJDVBJBDAKSCBASKFBasjcbaskjvbaskvaslvbna") + result = "error" + message = "You've already filled the form." + + content = {"status": result, "message": message} + content = json.dumps(content) + return HttpResponse(content) + # messages.success(request,"Successfully sent the application !!!") + + # return redirect('/gymkhana/') + + +def return_content(request, roll, name, desig, club__, student_clubs, notifications): + """ + return_content + This view returns all data regarding the parameters that sent through function + The returned data contains all information regarding all clubs , polling system , status of clubs , + students info who are in the designation, which was sent through parameters of this function + @param: + request : trivial + roll : Roll number of the student + name : name of the user + desig : Designition of the user + club__ : club name of the user + @variables: + student : All info of the student passes through the function + faculty : All info of the faculty + club_name : All club names + club_member : All info of the Club_member + fest_budget : All info of the fest_budget + club_budget : All info of the Club_budget + club_session : All info of the Session_info + club_event : All info of the Event_info + club_event_report : All info of the Club_report + + """ + students = ExtraInfo.objects.select_related("user", "department").filter( + user_type="student" + ) + faculty = ExtraInfo.objects.select_related("user", "department").filter( + user_type="faculty" + ) + club_name = Club_info.objects.select_related( + "co_ordinator", + "co_ordinator__id", + "co_ordinator__id__user", + "co_ordinator__id__department", + "co_coordinator", + "co_coordinator__id", + "co_coordinator__id__user", + "co_coordinator__id__department", + "faculty_incharge", + "faculty_incharge__id", + "faculty_incharge__id__user", + "faculty_incharge__id__department", + ).all() + club_member = Club_member.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + "member", + "member__id", + "member__id__user", + "member__id__department", + ).all() + fest_budget = Fest_budget.objects.all() + club_budget = Club_budget.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ).all() + club_session = Session_info.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ).all() + club_event = Event_info.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ).all() + club_event_report = Club_report.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + "incharge", + "incharge__user", + "incharge__department", + ).all() + # inventory1 = Inventory.objects.all() + if "student" in desig or "Convenor" in desig: + registration_form = Registration_form.objects.all() + cpi = ( + Student.objects.select_related("id", "id__user", "id__department") + .get(id__user=request.user) + .cpi + ) + programme = ( + Student.objects.select_related("id", "id__user", "id__department") + .get(id__user=request.user) + .programme + ) + + try: + form_name = Form_available.objects.get( + roll=request.user.username).form_name + logger.info(f"{form_name} MKNCjncknisncs") + status = Form_available.objects.get( + roll=request.user.username).status + except Exception as e: + forms = Form_available.objects.all() + for form in forms: + form_name = form.form_name + status = form.status + break + + venue_type = [] + id = 0 + venue = [] + + for rooms in Constants.venue: + for room in rooms[1]: + venue.append(room[0]) + curr_club = [] + if "student" in desig: + user_name = get_object_or_404(User, username=str(roll)) + extra = get_object_or_404(ExtraInfo, id=roll, user=user_name) + student = get_object_or_404(Student, id=extra) + else: + curr_club = [] + + # creating the data for the active voting polls + voting_polls = [] + # for poll in Voting_polls.objects.all(): + # event = {} + # choices = [] + # event["id"] = poll.id + # event["title"] = poll.title + # event["desc"] = poll.description + # event["exp_date"] = ( + # (poll.exp_date - datetime.datetime.now()).days + # if (datetime.datetime.now() - poll.exp_date).days <= 0 + # else "expire" + # ) + # event["pub_date"] = poll.exp_date.strftime("%d/%m/%Y") + # event["created_by"] = poll.created_by.split(":") + # for choice in poll.voting_choices_set.all(): + # choices.append( + # {"title": choice.title, "id": choice.id, "votes": choice.votes} + # ) + + # event["choices"] = choices + # event["max"] = poll.voting_choices_set.latest() + # event["voters"] = poll.voting_voters_set.values_list("student_id", flat=True) + # event["groups"] = json.loads(poll.groups) + + # voting_polls.append(event) + + content = { + "Students": students, + "Club_name": club_name, + "Faculty": faculty, + "Club_member": club_member, + "Fest_budget": fest_budget, + "Club_budget": club_budget, + "Club_session": club_session, + "Club_event": club_event, + "Club_event_report": club_event_report, + "Curr_club": curr_club, + "venue": venue, + "Curr_desig": desig, + "club_details": club__, + "voting_polls": voting_polls, + "roll": str(roll), + # "Inventory": inventory1, + "student_clubs": student_clubs, + "notifications": notifications, + } + # print(club__) + if "student" in desig or "Convenor" in desig: + content1 = { + "registration_form": registration_form, + "cpi": cpi, + "programme": programme, + "form_name": form_name, + "status": status, + } + content.update(content1) + return content + @login_required def getVenue(request): - """ - getVenue - This view takes the venue type from Front-end and returns the list of venues which of type - provided by User - @param: - request : trivial - @variables: - selected : Type of the venue selected by the user - """ - selected = request.POST.get('venueType') - selected = selected.strip() - venue_type = [] - venue_details = {} - idd = 0 - for rooms in Constants.venue: - for room in rooms: - if(idd % 2 == 0): - venue_type.append(room) - else: - venue_list = [venue[0] for venue in room] - venue_details[venue_type[int(idd/2)]] = venue_list - idd = idd+1 - content = [] - for key, value in venue_details.items(): - if key == selected: - for val in value: - val = val.strip() - content.append(val) - content = json.dumps(content) - return HttpResponse(content) + """ + getVenue + This view takes the venue type from Front-end and returns the list of venues which of type + provided by User + @param: + request : trivial + @variables: + selected : Type of the venue selected by the user + """ + selected = request.POST.get("venueType") + selected = selected.strip() + venue_type = [] + venue_details = {} + idd = 0 + for rooms in Constants.venue: + for room in rooms: + if idd % 2 == 0: + venue_type.append(room) + else: + venue_list = [venue[0] for venue in room] + venue_details[venue_type[int(idd / 2)]] = venue_list + idd = idd + 1 + content = [] + for key, value in venue_details.items(): + if key == selected: + for val in value: + val = val.strip() + content.append(val) + content = json.dumps(content) + return HttpResponse(content) + + +def sc(request): + # Assuming Club_member is a model representing the club memberships + clubs = Club_member.objects.filter(member=request.user.username) + + # Initialize an empty list to store club names + clubinfo = [] + + # Iterate over the clubs associated with the user + for club in clubs: + + clubinfo.append(club.club) + + return clubinfo + @login_required def gymkhana(request): - """ - gymkhana - This view gives us the complete information regarding various clubs and it - contains the records of the coordinator and co-coordinator of all the clubs and users can join any - club and cancel his/her membership from any club that he/she wishes to. And it also contains the - details of the sessions and events conducted by various clubs and club heads can also conduct - surveys by conducting polls and by taking the permission from the academic office students can - also create the clubs for a purpose. - @param: - request : trivial - @variables: - roll : Roll number of the User - name : full name of the user - designations : List contains all info of the user logged in - - """ - roll = request.user - name = request.user.first_name +"_"+ request.user.last_name - designations = list(HoldsDesignation.objects.select_related('user','working','designation').all().filter(working = request.user).values_list('designation')) - designation_data = [element for designation in designations for element in designation] - roll_ = [] - for designation in designation_data : - name_ = get_object_or_404(Designation, id = designation) - # # # print name_ - roll_.append(str(name_.name)) - for club_data in Club_info.objects.select_related('co_ordinator','co_ordinator__id','co_ordinator__id__user','co_ordinator__id__department','co_coordinator','co_coordinator__id','co_coordinator__id__user','co_coordinator__id__department','faculty_incharge','faculty_incharge__id','faculty_incharge__id__user','faculty_incharge__id__department').all(): - lines =str("") - Types = lines.split(" ") - club__ = coordinator_club(request) - return render(request, "gymkhanaModule/gymkhana.html", retrun_content(request, roll, name, roll_ , club__ )) + notifications = request.user.notifications.all() + """ + gymkhana + This view gives us the complete information regarding various clubs and it + contains the records of the coordinator and co-coordinator of all the clubs and users can join any + club and cancel his/her membership from any club that he/she wishes to. And it also contains the + details of the sessions and events conducted by various clubs and club heads can also conduct + surveys by conducting polls and by taking the permission from the academic office students can + also create the clubs for a purpose. + @param: + request : trivial + @variables: + roll : Roll number of the User + name : full name of the user + designations : List contains all info of the user logged in + + """ + roll = request.user + name = request.user.first_name + "_" + request.user.last_name + designations = list( + HoldsDesignation.objects.select_related( + "user", "working", "designation") + .all() + .filter(working=request.user) + .values_list("designation") + ) + designation_data = [ + element for designation in designations for element in designation + ] + roll_ = [] + for designation in designation_data: + name_ = get_object_or_404(Designation, id=designation) + # # # print name_ + roll_.append(str(name_.name)) + for club_data in Club_info.objects.select_related( + "co_ordinator", + "co_ordinator__id", + "co_ordinator__id__user", + "co_ordinator__id__department", + "co_coordinator", + "co_coordinator__id", + "co_coordinator__id__user", + "co_coordinator__id__department", + "faculty_incharge", + "faculty_incharge__id", + "faculty_incharge__id__user", + "faculty_incharge__id__department", + ).all(): + lines = str("") + Types = lines.split(" ") + club__ = coordinator_club(request) + print(club__) + student_clubs = sc(request) + return render( + request, + "gymkhanaModule/gymkhana.html", + return_content(request, roll, name, roll_, club__, student_clubs, notifications), + ) + @login_required def club_membership(request): - """ - club_membership: - This view takes the user_name, club name, achievements of that student and saves it to - club_memder database. Finally displays success if there are no Exceptions and errors and if there - is some Exception, then by using json.dump() which converts python objects to json string. - @param: - request : trivial - @variables: - user_name : Name of the user - club : Name of the club - achievements : Achievements of the user - """ - if request.method == 'POST': - result = "success" - message = "The form has been dispatched for further process" - try: - # getting form data - user_name = request.POST.get("user_name") - club = request.POST.get("club") - achievements = request.POST.get("achievements") - - # getting queryset class objects - #user_name = User.objects.get(username = user[-7:]) - USER = user_name.split(' - ') - user_name = get_object_or_404(User, username=USER[1]) - extra = get_object_or_404(ExtraInfo, id=USER[0], user=user_name) - student = get_object_or_404(Student, id=extra) - #extra = ExtraInfo.objects.get(id = user[:-10], user = user_name) - #student = Student.objects.get(id = extra) - - club_name = get_object_or_404(Club_info, club_name=club) - - # saving data to the database - club_member = Club_member( - member=student, club=club_name, description=achievements) - club_member.save() - except Exception as e: - result = "error" - message = "Some error occurred" - - content = { - 'status': result, - 'message': message - } - content = json.dumps(content) - return HttpResponse(content) - # messages.success(request,"Successfully sent the application !!!") - - # return redirect('/gymkhana/') + """ + club_membership: + This view takes the user_name, club name, achievements of that student and saves it to + club_memder database. Finally displays success if there are no Exceptions and errors and if there + is some Exception, then by using json.dump() which converts python objects to json string. + @param: + request : trivial + @variables: + user_name : Name of the user + club : Name of the club + achievements : Achievements of the user + """ + if request.method == "POST": + result = "success" + message = "The form has been dispatched for further process" + try: + # getting form data + user_name = request.POST.get("user_name") + club = request.POST.get("club") + achievements = request.POST.get("achievements") + + # getting queryset class objects + # user_name = User.objects.get(username = user[-7:]) + USER = user_name.split(" - ") + user_name = get_object_or_404(User, username=USER[1]) + extra = get_object_or_404(ExtraInfo, id=USER[0], user=user_name) + student = get_object_or_404(Student, id=extra) + # extra = ExtraInfo.objects.get(id = user[:-10], user = user_name) + # student = Student.objects.get(id = extra) + + club_name = get_object_or_404(Club_info, club_name=club) + + # saving data to the database + club_member = Club_member( + member=student, club=club_name, description=achievements + ) + club_member.save() + except Exception as e: + result = "error" + message = "Some error occurred" + + content = {"status": result, "message": message} + content = json.dumps(content) + return HttpResponse(content) + # messages.success(request,"Successfully sent the application !!!") + + # return redirect('/gymkhana/') @login_required def core_team(request): - """ - core_team: - This view takes the data of students. Data like, their name, fest name, team, pda and - year. And finally saving this data to the database of the core team. - This will done only when the method is POST and at the end it will redirect to '/gymkhana/' - @params: - request : trivial - @variables: - user : Name of the user - fest : Name of the fest - team : Name of the team - achievements : Achievements of the user - year : Acedamic year of the core team - - """ - if request.method == 'POST': - # getting form data - user = request.POST.get("user_name") - fest = request.POST.get("fest") - team = request.POST.get("team") - achievements = request.POST.get("pda") - year = request.POST.get("year") - - # getting queryset class objects - USER = user.split(' - ') - user_name = get_object_or_404(User, username=USER[1]) - extra = get_object_or_404(ExtraInfo, id=USER[00], user=user_name) - student = get_object_or_404(Student, id=extra) - - # saving data to the database - core_team = Core_team(student_id=student, - fest_name=fest, team=team, pda=achievements, year=year) - core_team.save() - messages.success(request, "Successfully applied for the post !!!") - - return redirect('/gymkhana/') + """ + core_team: + This view takes the data of students. Data like, their name, fest name, team, pda and + year. And finally saving this data to the database of the core team. + This will done only when the method is POST and at the end it will redirect to '/gymkhana/' + @params: + request : trivial + @variables: + user : Name of the user + fest : Name of the fest + team : Name of the team + achievements : Achievements of the user + year : Acedamic year of the core team + + """ + if request.method == "POST": + # getting form data + user = request.POST.get("user_name") + fest = request.POST.get("fest") + team = request.POST.get("team") + achievements = request.POST.get("pda") + year = request.POST.get("year") + + # getting queryset class objects + USER = user.split(" - ") + user_name = get_object_or_404(User, username=USER[1]) + extra = get_object_or_404(ExtraInfo, id=USER[00], user=user_name) + student = get_object_or_404(Student, id=extra) + + # saving data to the database + core_team = Core_team( + student_id=student, fest_name=fest, team=team, pda=achievements, year=year + ) + core_team.save() + messages.success(request, "Successfully applied for the post !!!") + + return redirect("/gymkhana/") + @login_required def event_report(request): - """ - event_report: - This view takes mainly the event, date, time, report and description of that - certain event. And then it appends that particular event`s report to other_report and - saves it to the database. Finally it redirects to the gymkhana homepage. - @param: - request : trivial - @variables: - user : Name of the user - event : Name of the event - description : Event`s description - date : Date of the event - time : Time of the event schedule - report : This is a file of details of the event - - """ - if request.method == 'POST': - # getting form data - user = request.POST.get("st_inc") - event = request.POST.get("event") - description = request.POST.get("d_d") - date = request.POST.get("date") - time = request.POST.get("time") - report = request.FILES["report"] - report.name = event+"_report" - - # getting queryset class objects - USER = user.split(' - ') - user_name = get_object_or_404(User, username=USER[1]) - extra = get_object_or_404(ExtraInfo, id=USER[0], user=user_name) - - # saving data to the database - other_report = Other_report(incharge=extra, event_name=event, - date=date+" "+time, event_details=report, description=description) - other_report.save() - messages.success(request, "Successfully saved the report !!!") - - return redirect('/gymkhana/') + """ + event_report: + This view takes mainly the event, date, time, report and description of that + certain event. And then it appends that particular event`s report to other_report and + saves it to the database. Finally it redirects to the gymkhana homepage. + @param: + request : trivial + @variables: + user : Name of the user + event : Name of the event + description : Event`s description + date : Date of the event + time : Time of the event schedule + report : This is a file of details of the event + + """ + if request.method == "POST": + # getting form data + user = request.POST.get("st_inc") + event = request.POST.get("event") + description = request.POST.get("d_d") + date = request.POST.get("date") + time = request.POST.get("time") + report = request.FILES["report"] + report.name = event + "_report" + + # getting queryset class objects + USER = user.split(" - ") + user_name = get_object_or_404(User, username=USER[1]) + extra = get_object_or_404(ExtraInfo, id=USER[0], user=user_name) + + # saving data to the database + other_report = Other_report( + incharge=extra, + event_name=event, + date=date + " " + time, + event_details=report, + description=description, + ) + other_report.save() + messages.success(request, "Successfully saved the report !!!") + + return redirect("/gymkhana/") @login_required def club_budget(request): - """ - club_budget: - This view takes details of club name, reason for the event and the amount - required for the event of the club.if the club name doesn't match with the clubs in database it - shows errors,else it the uploads to database and a message displays successfully uploaded the - budget.And then it redirects to gymkhana homepage. - @param: - request : trivial - @variables: - club : Name of the club - budget_for : Reason for the budget - budget_amount : Amount of the budget - budget_file : File that contains the budget details - description : Brief note of the whole budget view. - - - """ - if request.method == 'POST' and request.FILES['budget_file']: - club = request.POST.get("club") - budget_for = request.POST.get("budget_for") - budget_amount = request.POST.get('amount') - budget_file = request.FILES['budget_file'] - description = request.POST.get('d_d') - budget_file.name = club+"_budget" - club_name = get_object_or_404(Club_info, club_name=club) - - club_budget = Club_budget(club=club_name, budget_amt=budget_amount, - budget_file=budget_file, budget_for=budget_for, description=description) - club_budget.save() - messages.success(request, "Successfully requested for the budget !!!") - - return redirect('/gymkhana/') + """ + club_budget: + This view takes details of club name, reason for the event and the amount + required for the event of the club.if the club name doesn't match with the clubs in database it + shows errors,else it the uploads to database and a message displays successfully uploaded the + budget.And then it redirects to gymkhana homepage. + @param: + request : trivial + @variables: + club : Name of the club + budget_for : Reason for the budget + budget_amount : Amount of the budget + budget_file : File that contains the budget details + description : Brief note of the whole budget view. + + + """ + print("function called") + if request.method == "POST" and request.FILES["budget_file"]: + club = request.POST.get("club") + budget_for = request.POST.get("budget_for") + budget_amount = request.POST.get("amount") + budget_file = request.FILES["budget_file"] + description = request.POST.get("d_d") + budget_file.name = club + "_budget" + club_name = get_object_or_404(Club_info, club_name=club) + + club_budget = Club_budget( + club_id=club_name, + budget_amt=budget_amount, + budget_file=budget_file, + budget_for=budget_for, + description=description, + status="open", + ) + club_budget.save() + messages.success(request, "Successfully requested for the budget !!!") + + return redirect("/gymkhana/") @login_required def act_calender(request): - """ - act_calender: - This view gets the date from the club if there is any wrong info it shows the error - otherwise it shows Successfully uploaded the calendar in the form of Json object - and adds to the calendar - @params: - request : trivial - @variables: - club : Name of the club - act_calender : File that contains the active calender of the club - """ - if request.method == "POST": - message = "" - club = request.POST.get("club") - act_calender = request.FILES['act_file'] - act_calender.name = club+"_act_calender.pdf" - - #club_name = get_object_or_404(Club_info, club_name = club) - - club_info = get_object_or_404(Club_info, club_name=club) - club_info.activity_calender = act_calender - club_info.save() - message += "Successfully uploaded the calender !!!" - - content = { - 'status':"success", - 'message':message, - } - content = json.dumps(content) - return HttpResponse(content) - - + """ + act_calender: + This view gets the date from the club if there is any wrong info it shows the error + otherwise it shows Successfully uploaded the calendar in the form of Json object + and adds to the calendar + @params: + request : trivial + @variables: + club : Name of the club + act_calender : File that contains the active calender of the club + """ + if request.method == "POST": + message = "" + club = request.POST.get("club") + act_calender = request.FILES["act_file"] + act_calender.name = club + "_act_calender.pdf" + + # club_name = get_object_or_404(Club_info, club_name = club) + + club_info = get_object_or_404(Club_info, club_name=club) + club_info.activity_calender = act_calender + club_info.save() + message += "Successfully uploaded the calender !!!" + + content = { + "status": "success", + "message": message, + } + content = json.dumps(content) + return HttpResponse(content) @login_required def club_report(request): - """ - This function is used to add the details of the club event along with a report. - It adds the club event details to the database. - And also uploads report file. - - @param: - request - trivial - - @variable: - club - name of the club - user - the id of user who adds this club event details - event - name of the event - d_d - description of the event - date - date in which the event going to happen/happened - time - time in which the event going to happen/happened - report - the club_report file on the event uploads by the user who adds data - - """ - if request.method == 'POST' and request.FILES['report']: - # getting form data - club = request.POST.get('club') - user = request.POST.get("s_inc") - event = request.POST.get("event") - d_d = request.POST.get("d_d") - date = request.POST.get("date") - time = request.POST.get("time") - report = request.FILES["report"] - report.name = club+"_"+event+"_report" - - # getting queryset class objects - USER = user.split(' - ') - user_name = get_object_or_404(User, username=USER[1]) - extra = get_object_or_404(ExtraInfo, id=USER[0], user=user_name) - - club_name = get_object_or_404(Club_info, club_name=club) - - # saving data to the database - club_report = Club_report(club=club_name, incharge=extra, event_name=event, - date=date+" "+time, event_details=report, description=d_d) - club_report.save() - messages.success(request, "Successfully updated the report !!!") - - return redirect('/gymkhana/') + """ + This function is used to add the details of the club event along with a report. + It adds the club event details to the database. + And also uploads report file. + + @param: + request - trivial + + @variable: + club - name of the club + user - the id of user who adds this club event details + event - name of the event + d_d - description of the event + date - date in which the event going to happen/happened + time - time in which the event going to happen/happened + report - the club_report file on the event uploads by the user who adds data + + """ + if request.method == "POST" and request.FILES["report"]: + # getting form data + club = request.POST.get("club") + user = request.POST.get("s_inc") + event = request.POST.get("event") + d_d = request.POST.get("d_d") + date = request.POST.get("date") + time = request.POST.get("time") + report = request.FILES["report"] + report.name = club + "_" + event + "_report" + + # getting queryset class objects + USER = user.split(" - ") + user_name = get_object_or_404(User, username=USER[1]) + extra = get_object_or_404(ExtraInfo, id=USER[0], user=user_name) + + club_name = get_object_or_404(Club_info, club_name=club) + + # saving data to the database + club_report = Club_report( + club=club_name, + incharge=extra, + event_name=event, + date=date + " " + time, + event_details=report, + description=d_d, + ) + club_report.save() + messages.success(request, "Successfully updated the report !!!") + + return redirect("/gymkhana/") + @login_required def change_head(request): - """ - This used to change the heads of club. - It gets the old co_ordinator and co_cordinator and replaces them with new co and co_co. - And adds to the database. - - @param: - request - trivial - - @variables: - - club - name of the club - co_ordinator - new co_ordinator of the club - co_coordinator - new co_cordinator of the club - date - date at which the heads of the clubs changes - time - time at which the heads changes - desc - description on change of heads - old_co_ordinator - HoldsDesignation object and after deletes this co_ordinator - old_co_coordinator - HoldsDesignation object and after deletes this co_coordinator - new_co_ordinator - HoldsDesignation object and after saves this object as co_ordinator - new_co_coordinator - HoldsDesignation object and after saves this object as co_coordinator - """ - - if request.method == "POST": - club = request.POST.get("club") - co_ordinator = request.POST.get('co') - co_coordinator = request.POST.get('coco') - date = request.POST.get("date") - time = request.POST.get("time") - desc = "co-ordinator and co co-ordinator changed on "+date+" at "+time - message = "" - - # club_name = get_object_or_404(Club_info, club_name=club) - - co_ordinator_student = get_object_or_404(Student, id__user__username=co_ordinator) - - co_coordinator_student = get_object_or_404(Student, id__user__username=co_coordinator) - - club_info = get_object_or_404(Club_info, club_name=club) - - old_co_ordinator = club_info.co_ordinator - old_co_coordinator = club_info.co_coordinator - club_info.co_ordinator = co_ordinator_student - club_info.co_coordinator = co_coordinator_student - club_info.save() - - message += "Successfully changed !!!" - - new_co_ordinator = HoldsDesignation(user=User.objects.get(username=co_ordinator), working=User.objects.get(username=co_ordinator), designation=Designation.objects.get(name="co-ordinator")) - new_co_ordinator.save() - new_co_coordinator = HoldsDesignation(user=User.objects.get(username=co_coordinator), working=User.objects.get(username=co_coordinator), designation=Designation.objects.get(name="co co-ordinator")) - new_co_coordinator.save() - - old_co_ordinator = HoldsDesignation.objects.select_related('user','working','designation').filter(user__username=old_co_ordinator, designation__name="co-ordinator") - old_co_ordinator.delete() - old_co_coordinator = HoldsDesignation.objects.select_related('user','working','designation').filter(user__username=old_co_coordinator, designation__name="co co-ordinator") - old_co_coordinator.delete() - - content = { - 'status':"success", - 'message':message, - } - - content = json.dumps(content) - return HttpResponse(content) - - # return redirect('/gymkhana/') - + if request.method == "POST": + club = request.POST.get("club") + co_ordinator = request.POST.get('co') + co_coordinator = request.POST.get('coco') + + desc = "co-ordinator and co co-ordinator changed on " + \ + str(timezone.now()) + message = "" + + club_info = Club_info.objects.get(club_name=club) + + if co_ordinator: + check = Club_member.objects.filter( + club_id=club, member_id=co_ordinator).exists() + if check == False: + return HttpResponse(json.dumps({'status': 'error', 'message': 'Selected student is not a member of the club'})) + co_ordinator_student = Student.objects.get(id_id=co_ordinator) + old_co_ordinator = club_info.co_ordinator_id + club_info.co_ordinator_id = co_ordinator_student + new_co_ordinator = HoldsDesignation(user=User.objects.get(username=co_ordinator), working=User.objects.get( + username=co_ordinator), designation=Designation.objects.get(name="co-ordinator")) + new_co_ordinator.save() + old_co_ordinator_obj = HoldsDesignation.objects.select_related('user', 'working', 'designation').filter( + user__username=old_co_ordinator, designation=Designation.objects.get(name="co-ordinator")) + old_co_ordinator_obj.delete() + message += "Successfully changed co-ordinator !!!" + + if co_coordinator: + check = Club_member.objects.filter( + club_id=club, member_id=co_coordinator).exists() + if check == False: + return HttpResponse(json.dumps({'status': 'error', 'message': 'Selected student is not a member of the club'})) + co_coordinator_student = Student.objects.get(id_id=co_coordinator) + old_co_coordinator = club_info.co_coordinator_id + club_info.co_coordinator_id = co_coordinator_student + new_co_coordinator = HoldsDesignation(user=User.objects.get(username=co_coordinator), working=User.objects.get( + username=co_coordinator), designation=Designation.objects.get(name="co co-ordinator")) + new_co_coordinator.save() + old_co_coordinator_obj = HoldsDesignation.objects.select_related('user', 'working', 'designation').filter( + user__username=old_co_coordinator, designation=Designation.objects.get(name="co co-ordinator")) + old_co_coordinator_obj.delete() + message += " Successfully changed co-coordinator !!!" + + club_info.head_changed_on = timezone.now() + club_info.save() + + content = { + 'status': "success", + 'message': message, + } + + content = json.dumps(content) + return HttpResponse(content) @login_required def new_session(request): - """ + """ This function is used to add/create new sessions for clubs by their users. - By using this the club user can add new session. - If the given date and time and venue clasheswith already booked session it doesn't add the session. - And it displays success if there is no exception and displays error if there is an exception. - - @param: - request - trivial - - @variables: - venue - the place/room at which the session is going to happen - session_poster - it is a file that has to be uploaded which contains the poster for session - date - the date at which session is going to happen - start_time - the time at which session is going to start - end_time - the time at which session is going to end - desc - brief explanation about session if any - club_name - requests the coordinator_club and it returns - result - checks wheather the date,time,venue clashes with other session using conflict_algorithm_session view - getstudents - extrainfo object - session - if result is success then the session books successfully - - """ - if request.method == "POST": - club_name = None - result =None - message = None - try: - venue = request.POST.get("venue_type") - session_poster = request.FILES.get("session_poster") - date = request.POST.get("date") - start_time = request.POST.get("start_time") - end_time = request.POST.get("end_time") - desc = request.POST.get("d_d") - club_name = coordinator_club(request) - result = conflict_algorithm_session(date, start_time, end_time, venue) - message = "" - getstudents = ExtraInfo.objects.select_related('user','department').filter(user_type = 'student') - recipients = User.objects.filter(extrainfo__in=getstudents) - if(result == "success"): - session = Session_info(club = club_name, venue = venue, date =date, start_time=start_time , end_time = end_time , session_poster=session_poster, details = desc) - session.save() - message += "Session booked Successfully" - gymkhana_session(request.user, recipients, 'new_session', club_name, desc, venue) - - else: - message += "The selected time slot for the given date and venue conflicts with already booked session" - except Exception as e: - logger.info(e) - result = "error" - message = "Some error occurred" - - content = { - 'status':result, - 'message':message - } - - content = json.dumps(content) - return HttpResponse(content) + By using this the club user can add new session. + If the given date and time and venue clasheswith already booked session it doesn't add the session. + And it displays success if there is no exception and displays error if there is an exception. + + @param: + request - trivial + + @variables: + venue - the place/room at which the session is going to happen + session_poster - it is a file that has to be uploaded which contains the poster for session + date - the date at which session is going to happen + start_time - the time at which session is going to start + end_time - the time at which session is going to end + desc - brief explanation about session if any + club_name - requests the coordinator_club and it returns + result - checks wheather the date,time,venue clashes with other session using conflict_algorithm_session view + getstudents - extrainfo object + session - if result is success then the session books successfully + + """ + if request.method == "POST": + club_name = None + result = None + message = None + try: + venue = request.POST.get("venue_type") + session_poster = request.FILES.get("session_poster") + date = request.POST.get("date") + start_time = request.POST.get("start_time") + end_time = request.POST.get("end_time") + desc = request.POST.get("d_d") + club_name = coordinator_club(request) + result = conflict_algorithm_session( + date, start_time, end_time, venue) + message = "" + getstudents = ExtraInfo.objects.select_related("user", "department").filter( + user_type="student" + ) + recipients = User.objects.filter(extrainfo__in=getstudents) + if result == "success": + session = Session_info( + club=club_name, + venue=venue, + date=date, + start_time=start_time, + end_time=end_time, + session_poster=session_poster, + details=desc, + ) + session.save() + message += "Session booked Successfully" + gymkhana_session( + request.user, recipients, "new_session", club_name, desc, venue + ) + + else: + message += "The selected time slot for the given date and venue conflicts with already booked session" + except Exception as e: + logger.info(e) + result = "error" + message = "Some error occurred" + + content = {"status": result, "message": message} + + content = json.dumps(content) + return HttpResponse(content) + @login_required def new_event(request): - """ + """ This function is used to add/create new event by clubs by their users. - By using this the club user can add new event. - If the given date and time and venue clasheswith already booked events/sessions it doesn't move to further process. - And it displays your form has been moved for further process if there is no exception and displays error if there is an exception. - - @param: - request - trivial - - @variables: + By using this the club user can add new event. + If the given date and time and venue clasheswith already booked events/sessions it doesn't move to further process. + And it displays your form has been moved for further process if there is no exception and displays error if there is an exception. + + @param: + request - trivial + + @variables: event_name - we have to give name of the event - incharge - the faculty staff name who is going to incharge the event - venue - the place/room at which the event is going to happen - event_poster - it is a file that has to be uploaded which contains the poster for event - date - the date at which event is going to happen - start_time - the time at which event is going to start - end_time - the time at which event is going to end - desc - brief explanation about event - club_name - requests the coordinator_club and it returns - result - checks wheather the date,time,venue clashes with other event using conflict_algorithm_event view - getstudents - Extrainfo object - session - if result is success then the event has been saved - - """ - if request.method == "POST": - club_name = None - result =None - message = None - try: - event_name=request.POST.get("event_name") - incharge=request.POST.get("incharge") - venue = request.POST.get("venue_type") - event_poster = request.FILES.get("event_poster") - date = request.POST.get("date") - start_time = request.POST.get("start_time") - end_time = request.POST.get("end_time") - desc = request.POST.get("d_d") - club_name = coordinator_club(request) - result = conflict_algorithm_event(date, start_time, end_time, venue) - message = "" - getstudents = ExtraInfo.objects.select_related('user','department').filter(user_type = 'student') - recipients = User.objects.filter(extrainfo__in=getstudents) - if(result == "success"): - event = Event_info(club = club_name, event_name=event_name, incharge=incharge, venue = venue, date =date, start_time=start_time , end_time = end_time ,event_poster = event_poster , details = desc) - event.save() - message += "Your form has been dispatched for further process" - gymkhana_event(request.user, recipients, 'new_event', club_name, event_name, desc, venue) - else: - message += "The selected time slot for the given date and venue conflicts with already booked session" - except Exception as e: - result = "error" - message = "Some error occurred" - - content = { - 'status':result, - 'message':message - } - content = json.dumps(content) - return HttpResponse(content) + incharge - the faculty staff name who is going to incharge the event + venue - the place/room at which the event is going to happen + event_poster - it is a file that has to be uploaded which contains the poster for event + date - the date at which event is going to happen + start_time - the time at which event is going to start + end_time - the time at which event is going to end + desc - brief explanation about event + club_name - requests the coordinator_club and it returns + result - checks wheather the date,time,venue clashes with other event using conflict_algorithm_event view + getstudents - Extrainfo object + session - if result is success then the event has been saved + + """ + if request.method == "POST": + club_name = None + result = None + message = None + try: + event_name = request.POST.get("event_name") + incharge = request.POST.get("incharge") + venue = request.POST.get("venue_type") + event_poster = request.FILES.get("event_poster") + date = request.POST.get("date") + start_time = request.POST.get("start_time") + end_time = request.POST.get("end_time") + desc = request.POST.get("d_d") + club_name = coordinator_club(request) + result = conflict_algorithm_event( + date, start_time, end_time, venue) + message = "" + getstudents = ExtraInfo.objects.select_related("user", "department").filter( + user_type="student" + ) + recipients = User.objects.filter(extrainfo__in=getstudents) + if result == "success": + event = Event_info( + club=club_name, + event_name=event_name, + incharge=incharge, + venue=venue, + date=date, + start_time=start_time, + end_time=end_time, + event_poster=event_poster, + details=desc, + ) + event.save() + message += "Your form has been dispatched for further process" + gymkhana_event( + request.user, + recipients, + "new_event", + club_name, + event_name, + desc, + venue, + ) + else: + message += "The selected time slot for the given date and venue conflicts with already booked session" + except Exception as e: + result = "error" + message = "Some error occurred" + + content = {"status": result, "message": message} + content = json.dumps(content) + return HttpResponse(content) + @login_required def fest_budget(request): - """ - This view uploads the budget details for the fest to the database. - Then the academic management can check the budget and accordingly allot the budget. - - @param: - fest - takes the name of the fest - budget_amt - the amount that is needed for the club - budget_file - have to upload the file that contails all details about the budget for fest - descrition - anything that we want write about fest - year - year fest is happening - fest_budget - the given details saved to the database - - """ - if request.method == 'POST' and request.FILES['file']: - fest = request.POST.get("fest") - budget_amt = request.POST.get('amount') - budget_file = request.FILES['file'] - desc = request.POST.get('d_d') - year = request.POST.get('year') - budget_file.name = fest+"_budget_"+year - - fest_budget = Fest_budget(fest=fest, budget_amt=budget_amt, - budget_file=budget_file, description=desc, year=year) - fest_budget.save() - messages.success(request, "Successfully uploaded the budget !!!") - - return redirect('/gymkhana/') + """ + This view uploads the budget details for the fest to the database. + Then the academic management can check the budget and accordingly allot the budget. + + @param: + fest - takes the name of the fest + budget_amt - the amount that is needed for the club + budget_file - have to upload the file that contails all details about the budget for fest + descrition - anything that we want write about fest + year - year fest is happening + fest_budget - the given details saved to the database + + """ + if request.method == "POST" and request.FILES["file"]: + fest = request.POST.get("fest") + budget_amt = request.POST.get("amount") + budget_file = request.FILES["file"] + desc = request.POST.get("d_d") + year = request.POST.get("year") + budget_file.name = fest + "_budget_" + year + + fest_budget = Fest_budget( + fest=fest, + budget_amt=budget_amt, + budget_file=budget_file, + description=desc, + year=year, + ) + fest_budget.save() + messages.success(request, "Successfully uploaded the budget !!!") + + return redirect("/gymkhana/") @login_required def approve(request): - """ - This view is used by the clubs to approve the students who wants to join the club and changes status of student to confirmed. - It gets a list of students who has to be approved and checks them and approves accordingly. - - @variables: - approve_list - list of students who has to be checked and approved. - remarks - gets remarks list if any remarks present - club_member - gets the object(club and student) and the confirms the status of student in the club. - """ - approve_list = list(request.POST.getlist('check')) - for user in approve_list: - # pos = lis.index(user) - remark = "remarks" + user - remarks = request.POST.getlist(remark) - user = user.split(',') - info = user[0].split(' - ') - - # getting queryset class objects - user_name = get_object_or_404(User, username=info[1]) - extra1 = get_object_or_404(ExtraInfo, id=info[0], user=user_name) - student = get_object_or_404(Student, id=extra1) - - club_member = get_object_or_404(Club_member, club=user[1], member=student) - club_member.status = "confirmed" - club_member.remarks = remarks[0] - club_member.save() - messages.success(request, "Successfully Approved !!!") - - return redirect('/gymkhana/') + """ + This view is used by the clubs to approve the students who want to join the club and changes the status of the student to 'confirmed'. + It gets a list of students who have to be approved and approves them accordingly. + """ + approve_list = list(request.POST.getlist("check")) + + for user in approve_list: + remark = "remarks" + user + remarks = request.POST.getlist(remark) + user = user.split(",") + info = user[0].split(" - ") + + # Retrieve User, ExtraInfo, and Student objects + user_name = get_object_or_404(User, username=info[1]) + extra1 = get_object_or_404(ExtraInfo, id=info[0], user=user_name) + student = get_object_or_404(Student, id=extra1) + + # Check if the user is already a member of the club + existing_club_member = Club_member.objects.filter( + club=user[1], member=student + ).first() + + if existing_club_member: + # If the user is already a member, update the existing entry and delete past entry + existing_club_member.status = "confirmed" + existing_club_member.remarks = remarks[0] + existing_club_member.save() + + # Delete past entries + Club_member.objects.filter(club=user[1], member=student).exclude( + id=existing_club_member.id + ).delete() + + else: + # If the user is not already a member, create a new entry + new_club_member = Club_member.objects.create( + club=user[1], member=student, status="confirmed", remarks=remarks[0] + ) + new_club_member.save() + + messages.success(request, "Successfully Approved !!!") + + return redirect("/gymkhana/") + @login_required def club_approve(request): - """ - This view is used by the administration to approve the clubs. - It gets a list of clubs and then approves if they want to. - - @variables: - club_approve_list - list of clubs which has to be approved - club_name - gets the object and then confirms the club - - """ - club_approve_list = list(request.POST.getlist('check')) - for club in club_approve_list: - club_name = get_object_or_404(Club_info, club_name=club) - club_name.status = "confirmed" - club_name.save() - messages.success(request, "Successfully Approved !!!") - - return redirect('/gymkhana/') + if request.method == "POST": + club_approve_list = request.POST.getlist("check") + for club in club_approve_list: + club_info = get_object_or_404(Club_info, club_name=club) + club_info.status = "confirmed" + club_info.created_on = timezone.now() + club_info.save() + + user_name1 = get_object_or_404( + User, username=club_info.co_ordinator) + extra1 = get_object_or_404( + ExtraInfo, id=club_info.co_ordinator, user=user_name1 + ) + student1 = get_object_or_404(Student, id=extra1) + + user_name2 = get_object_or_404( + User, username=club_info.co_coordinator) + extra2 = get_object_or_404( + ExtraInfo, id=club_info.co_coordinator, user=user_name2 + ) + student2 = get_object_or_404(Student, id=extra2) + + co_user = User.objects.get(username=club_info.co_ordinator) + co_co_user = User.objects.get(username=club_info.co_coordinator) + + HoldsDesignation.objects.create( + designation_id=56, user_id=co_user.id, working_id=co_user.id + ) + HoldsDesignation.objects.create( + designation_id=57, user_id=co_co_user.id, working_id=co_co_user.id + ) + + Club_member.objects.create( + club_id=club_info.club_name, member=student1, status="confirmed" + ) + Club_member.objects.create( + club_id=club_info.club_name, member=student2, status="confirmed" + ) + messages.success( + request, f"Successfully approved {club_info.club_name} club." + ) + + return redirect("/gymkhana/") @login_required def club_reject(request): - """ + """ This view is used by the administration to reject the clubs. - It gets a list of clubs and then rejects if they want to. - - @variables: - club_reject_list - list of clubs which has to be checked and rejected - club_name - gets the object and then rejects the club - - """ - club_reject_list = list(request.POST.getlist('check')) - for club in club_reject_list: - club_name = get_object_or_404(Club_info, club_name=club) - club_name.status = "rejected" - club_name.save() - messages.success(request, "Successfully Rejected !!!") - - return redirect('/gymkhana/') + It gets a list of clubs and then rejects if they want to. + + @variables: + club_reject_list - list of clubs which has to be checked and rejected + club_name - gets the object and then rejects the club + + """ + club_reject_list = request.POST.getlist("check") + for club in club_reject_list: + club_name = get_object_or_404(Club_info, club_name=club) + club_name.status = "rejected" + club_name.save() + messages.success(request, "Successfully Rejected !!!") + + return redirect("/gymkhana/") + @login_required def reject(request): - """ - This view is used by the clubs to approve the students who wants to join the club. - It gets a list of students who has to be approved and checks them and approves accordingly. - - @variables: - approve_list - list of students who has to be checked and approved. - remarks - gets remarks list if any remarks present - - """ - reject_list = list(request.POST.getlist('check')) - - for user in reject_list: - # pos = lis.index(user) - remark = "remarks" + user - remarks = request.POST.getlist(remark) - user = user.split(',') - info = user[0].split(' - ') - - # getting queryset class objects - user_name = get_object_or_404(User, username=info[1]) - extra1 = get_object_or_404(ExtraInfo, id=info[0], user=user_name) - student = get_object_or_404(Student, id=extra1) - - club_member = get_object_or_404(Club_member, club=user[1], member=student) - club_member.status = "rejected" - club_member.remarks = remarks[0] - club_member.save() - messages.success(request, "Successfully Rejected !!!") - - return redirect('/gymkhana/') - - return redirect('/gymkhana/') + """ + This view is used by the clubs to approve the students who wants to join the club. + It gets a list of students who has to be approved and checks them and approves accordingly. + + @variables: + approve_list - list of students who has to be checked and approved. + remarks - gets remarks list if any remarks present + + """ + reject_list = list(request.POST.getlist("check")) + + for user in reject_list: + # pos = lis.index(user) + remark = "remarks" + user + remarks = request.POST.getlist(remark) + user = user.split(",") + info = user[0].split(" - ") + + # getting queryset class objects + user_name = get_object_or_404(User, username=info[1]) + extra1 = get_object_or_404(ExtraInfo, id=info[0], user=user_name) + student = get_object_or_404(Student, id=extra1) + + club_member = get_object_or_404(Club_member, club=user[1], member=student) + club_member.status = "rejected" + club_member.remarks = remarks[0] + club_member.save() + messages.success(request, "Successfully Deleted !!!") + + return redirect("/gymkhana/") + + return redirect("/gymkhana/") + @login_required def cancel(request): - """ + """ This function is used to cancel/remove the member from a club. It gets the list of student and checks in their club and the deletes the student from that club. - Finally gets the message successfully deleted. + Finally gets the message successfully deleted. - @variables: - cancel_list - list of students who are to be removed/delted from club. - club_member - checks the object and then deletes the member from club. - """ + @variables: + cancel_list - list of students who are to be removed/delted from club. + club_member - checks the object and then deletes the member from club. + """ - cancel_list = list(request.POST.getlist('check')) + cancel_list = list(request.POST.getlist("check")) - for user in cancel_list: - #pos = lis.index(user) - user = user.split(',') - info = user[0].split(' - ') + for user in cancel_list: + # pos = lis.index(user) + user = user.split(",") + info = user[0].split(" - ") - # getting queryset class objects - user_name = get_object_or_404(User, username=info[1]) - extra1 = get_object_or_404(ExtraInfo, id=info[0], user=user_name) - student = get_object_or_404(Student, id=extra1) + # getting queryset class objects + user_name = get_object_or_404(User, username=info[1]) + extra1 = get_object_or_404(ExtraInfo, id=info[0], user=user_name) + student = get_object_or_404(Student, id=extra1) - club_member = get_object_or_404( - Club_member, club=user[1], member=student) + club_member = get_object_or_404( + Club_member, club=user[1], member=student) - club_member.delete() - messages.success(request, "Successfully deleted !!!") + club_member.delete() + messages.success(request, "Successfully deleted !!!") - return redirect('/gymkhana/') + return redirect("/gymkhana/") @login_required @csrf_exempt def date_sessions(request): - """ - date_sessions: - this function is used to return the details of the Session_info for the requested date - and sends the serialized data - @param: - request - trivial - @variables: - value - contains the requested date - get_sessions - contains the details of the Club's from the Session_info which are having sessions on the requested date - dates - it's a list which contains the data present in the get_sessions - - """ - if(request.is_ajax()): - value = request.POST.get('date') - get_sessions = Session_info.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').filter(date=value).order_by('start_time') - dates = [] - for session_info in get_sessions: - dates.append(session_info) - dates = serializers.serialize('json', dates) - return HttpResponse(dates) + """ + date_sessions: + this function is used to return the details of the Session_info for the requested date + and sends the serialized data + @param: + request - trivial + @variables: + value - contains the requested date + get_sessions - contains the details of the Club's from the Session_info which are having sessions on the requested date + dates - it's a list which contains the data present in the get_sessions + + """ + if request.is_ajax(): + value = request.POST.get("date") + get_sessions = ( + Session_info.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ) + .filter(date=value) + .order_by("start_time") + ) + dates = [] + for session_info in get_sessions: + dates.append(session_info) + dates = serializers.serialize("json", dates) + return HttpResponse(dates) + @login_required @csrf_exempt def date_events(request): - """ - date_sessions: - this function is used to return the details of the Event_info for the requested date and sends the serialized data - @param: - request - trivial - @variables: - value - contains the requested date - get_events - contains the details of the Club's from the Event_info which are having events on the requested date - dates - it's a list which contains the data present in the get_events - - """ - if(request.method=='POST'): - value = request.POST.get('date') - get_events = Event_info.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').filter(date=value).order_by('start_time') - dates = [] - for event_info in get_events: - dates.append(event_info) - dates = serializers.serialize('json', dates) - return HttpResponse(dates) - return HttpResponse("Hurray") - -#this algorithm checks if the passed slot time coflicts with any of already booked sessions + """ + date_sessions: + this function is used to return the details of the Event_info for the requested date and sends the serialized data + @param: + request - trivial + @variables: + value - contains the requested date + get_events - contains the details of the Club's from the Event_info which are having events on the requested date + dates - it's a list which contains the data present in the get_events + + """ + if request.method == "POST": + value = request.POST.get("date") + get_events = ( + Event_info.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ) + .filter(date=value) + .order_by("start_time") + ) + dates = [] + for event_info in get_events: + dates.append(event_info) + dates = serializers.serialize("json", dates) + return HttpResponse(dates) + return HttpResponse("Hurray") + + +# this algorithm checks if the passed slot time coflicts with any of already booked sessions def conflict_algorithm_session(date, start_time, end_time, venue): - #converting string to datetime type variable - """ - conflict_algorithm_session: - this algorithm is used to find if there any avaiable slot for the given date , stat_time ,end_time and venue - from the session_info to book the slot else it returns error. - @param: - date - date of the slot - start_time - starting time for the slot - end_time - ending time for the slot - venue - venue for the slot - @variables: - - booked_session - contains the session_info of all previously alloted slots - """ - start_time = datetime.datetime.strptime(start_time, '%H:%M').time() - end_time = datetime.datetime.strptime(end_time, '%H:%M').time() - booked_Sessions = Session_info.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').filter(date=date, venue=venue) - - #placing start time and end time in tuple fashion inside this list - slots = [(start_time, end_time)] - for value in booked_Sessions: - slots.append((value.start_time, value.end_time)) - slots.sort() - #if there isn't any slot present for the selected day just book the session - if (len(slots) == 1): - return "success" - else: - #this whole logic checks if the end time of any slot is less than the start time of next slot - counter = slots[0][1] - flag = 0 - i=1 - while i < len(slots): - if (slots[i][0] < counter): - flag = 1 - break - counter = slots[i][1] - i = i + 1 - if (flag == 0): - return "success" - else: - return "error" - -##helper function to get the target user for the voting poll + # converting string to datetime type variable + """ + conflict_algorithm_session: + this algorithm is used to find if there any avaiable slot for the given date , stat_time ,end_time and venue + from the session_info to book the slot else it returns error. + @param: + date - date of the slot + start_time - starting time for the slot + end_time - ending time for the slot + venue - venue for the slot + @variables: + + booked_session - contains the session_info of all previously alloted slots + """ + start_time = datetime.datetime.strptime(start_time, "%H:%M").time() + end_time = datetime.datetime.strptime(end_time, "%H:%M").time() + booked_Sessions = Session_info.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ).filter(date=date, venue=venue) + + # placing start time and end time in tuple fashion inside this list + slots = [(start_time, end_time)] + for value in booked_Sessions: + slots.append((value.start_time, value.end_time)) + slots.sort() + # if there isn't any slot present for the selected day just book the session + if len(slots) == 1: + return "success" + else: + # this whole logic checks if the end time of any slot is less than the start time of next slot + counter = slots[0][1] + flag = 0 + i = 1 + while i < len(slots): + if slots[i][0] < counter: + flag = 1 + break + counter = slots[i][1] + i = i + 1 + if flag == 0: + return "success" + else: + return "error" + + +# helper function to get the target user for the voting poll def get_target_user(groups): - """ - get_target_user: - This function helps to fetch the passed list to Dictionary of Key unique batches(years) and - values of braches and remove the redundancy and returns the "dic" through Json string - @param: - groups : This takes the info of which brach and batch can access(voting) this poll - """ - dic = {} - for i in range(len(groups)): - value = groups[i].split(":") - batch = value[0] - branch = value[1] - if dic.get(batch): - if dic[batch][0] != 'All': - dic[batch].append(branch) - else: - dic[batch] = [branch] - return json.dumps(dic) - -## Voting Polls + """ + get_target_user: + This function helps to fetch the passed list to Dictionary of Key unique batches(years) and + values of braches and remove the redundancy and returns the "dic" through Json string + @param: + groups : This takes the info of which brach and batch can access(voting) this poll + """ + dic = {} + for i in range(len(groups)): + value = groups[i].split(":") + batch = value[0] + branch = value[1] + if dic.get(batch): + if dic[batch][0] != "All": + dic[batch].append(branch) + else: + dic[batch] = [branch] + return json.dumps(dic) + + +# Voting Polls +# @login_required +# def voting_poll(request): +# """ +# voting_poll: +# This view creates new voting poll by taking the values from Front-end and add this poll details +# to "Voting_polls" database and also it create and add object of "Voting_choices" contains +# poll_event and title>. Finally it calls gymkhana_voting as per the data given to "groups" +# @param: +# request : trivial +# @variables: +# title : Title of the voting poll +# description : It describes that what this poll is for +# choices : Choices of the voting poll +# exp_data : Expire date of the voting poll +# groups : This takes the info of which brach and batch can access(voting) this poll +# """ +# if request.POST: +# try: +# body = request.POST +# title = body.get("title") +# description = body.get("desc") +# choices = body.getlist("choices") +# exp_date = body.get("expire_date") +# groups = body.getlist("groups") +# target_groups = get_target_user(groups) +# name = request.user.first_name + " " + request.user.last_name +# roll = request.user +# created_by = str(name) + ":" + str(roll) +# new_poll = Voting_polls( +# title=title, +# description=description, +# exp_date=exp_date, +# created_by=str(created_by), +# groups=target_groups, +# ) +# new_poll.save() +# for choice in choices: +# new_choice = Voting_choices(poll_event=new_poll, title=choice) +# new_choice.save() +# for i in range(len(groups)): +# value = groups[i].split(":") +# batch = value[0] +# branch = value[1] +# allbatch = User.objects.filter(username__contains=batch) +# selbranch = ExtraInfo.objects.select_related( +# "user", "department" +# ).filter(department__name=branch) +# batchbranch = User.objects.filter( +# username__contains=batch, extrainfo__in=selbranch +# ) +# if branch == "All": +# gymkhana_voting( +# request.user, allbatch, "voting_open", title, description +# ) +# else: +# gymkhana_voting( +# request.user, batchbranch, "voting_open", title, description +# ) +# return redirect("/gymkhana/") +# except Exception as e: +# res = "error" +# message = "Some error occurred" +# logger.info(e) +# content = {"status": res, "message": message} +# content = json.dumps(content) +# return HttpResponse(content) + +# return redirect("/gymkhana/") + + +# @login_required +# def vote(request, poll_id): +# """ +# vote: +# This view will update(increase) votes by 1 for particular 'submitted_choice' then it adds the +# voter(student)ID and poll_event for which he/she votes. Finally it saves to the database +# redirect to '/gymkhana/'. In case of any exception it return "error" +# @param: +# poll_id : ID of the poll +# request : trivial +# @variables: +# submitted_choice : Choice of the user selected for poll_event +# choice : It is a object contains all data of "submitted_choice" from Voting_choices +# new_voter : creating object of Voting_voter to save the voter info +# """ +# poll = Voting_polls.objects.get(pk=poll_id) +# if request.POST: +# try: +# body = request.POST +# submitted_choice = body.get("choice") +# choice = Voting_choices.objects.select_related("poll_event").get( +# pk=submitted_choice +# ) +# choice.votes += 1 +# choice.save() +# new_voter = Voting_voters(poll_event=poll, student_id=str(request.user)) +# new_voter.save() +# return redirect("/gymkhana/") +# except Exception as e: +# logger.info(e) +# return HttpResponse("error") +# data = serializers.serialize( +# "json", Voting_choices.objects.select_related("poll_event").all() +# ) +# return redirect("/gymkhana/") + + +# @login_required +# def delete_poll(request, poll_id): +# """ +# delete_poll: +# This view delete the particular voting poll which is passed through function and redirect +# to "/gymkhana/" if there is an exception then it return the HttpResponse of "error" +# @param: +# request : trivial +# poll_id : id of the poll in Voting_polls +# @variables: +# poll : It is an object stores the all data of poll_id from Voting_poll +# """ +# try: +# poll = Voting_polls.objects.filter(pk=poll_id) +# poll.delete() +# return redirect("/gymkhana/") +# except Exception as e: +# logger.info(e) +# return HttpResponse("error") + +# return redirect("/gymkhana/") + + +# this algorithm checks if the passed slot time coflicts with any of already booked events @login_required -def voting_poll(request): - """ - voting_poll: - This view creates new voting poll by taking the values from Front-end and add this poll details - to "Voting_polls" database and also it create and add object of "Voting_choices" contains - poll_event and title>. Finally it calls gymkhana_voting as per the data given to "groups" - @param: - request : trivial - @variables: - title : Title of the voting poll - description : It describes that what this poll is for - choices : Choices of the voting poll - exp_data : Expire date of the voting poll - groups : This takes the info of which brach and batch can access(voting) this poll - """ - if request.POST: - try: - body = request.POST - title = body.get('title') - description = body.get('desc') - choices = body.getlist('choices') - exp_date = body.get('expire_date') - groups = body.getlist('groups') - target_groups = get_target_user(groups) - name = request.user.first_name + " " + request.user.last_name - roll = request.user - created_by = str(name) +":"+ str(roll) - new_poll = Voting_polls(title=title, description=description, exp_date=exp_date, created_by = str(created_by),groups=target_groups) - new_poll.save() - for choice in choices: - new_choice = Voting_choices(poll_event=new_poll,title=choice) - new_choice.save() - for i in range(len(groups)): - value = groups[i].split(":") - batch = value[0] - branch = value[1] - allbatch = User.objects.filter(username__contains = batch) - selbranch = ExtraInfo.objects.select_related('user','department').filter(department__name = branch) - batchbranch = User.objects.filter(username__contains = batch, extrainfo__in=selbranch) - if branch == 'All': - gymkhana_voting(request.user, allbatch, 'voting_open', title, description) - else: - gymkhana_voting(request.user, batchbranch, 'voting_open', title, description) - return redirect('/gymkhana/') - except Exception as e: - res = "error" - message = "Some error occurred" - logger.info(e) - content = { - 'status':res, - 'message':message - } - content = json.dumps(content) - return HttpResponse(content) - - return redirect('/gymkhana/') +def budget_approve(request): + """ + This view is used by the administration to approve the clubs_budget. + It gets a list of clubs and then approves_budget if they want to. + + @variables: + club_approve_list - list of clubs which has to be approved + club_name - gets the object and then confirms the club + """ + if request.method == "POST": + budget_approve_list = list(request.POST.getlist("check")) + first_words = [] + for item in budget_approve_list: + first_word = item.split()[0] + first_words.append(first_word) + + for club in first_words: + print(club) + club_budget_list = Club_budget.objects.filter( + club_id=club, status="open") # Ensure status is open + print(club_budget) + for single_club in club_budget_list: + single_club.status = "confirmed" + # single_club = get_object_or_404(Club_info, club_name=club) + # single_club.alloted_budget = single_club.alloted_budget + single_club.budget_amt + single_club.save() + # club_budget.save() + messages.success( + request, f"Successfully budget approved for club." + ) + return redirect("/gymkhana/") -@login_required -def vote(request,poll_id): - """ - vote: - This view will update(increase) votes by 1 for particular 'submitted_choice' then it adds the - voter(student)ID and poll_event for which he/she votes. Finally it saves to the database - redirect to '/gymkhana/'. In case of any exception it return "error" - @param: - poll_id : ID of the poll - request : trivial - @variables: - submitted_choice : Choice of the user selected for poll_event - choice : It is a object contains all data of "submitted_choice" from Voting_choices - new_voter : creating object of Voting_voter to save the voter info - """ - poll = Voting_polls.objects.get(pk=poll_id) - if request.POST: - try: - body = request.POST - submitted_choice = body.get('choice') - choice = Voting_choices.objects.select_related('poll_event').get(pk=submitted_choice) - choice.votes += 1 - choice.save() - new_voter = Voting_voters(poll_event=poll, student_id=str(request.user)) - new_voter.save() - return redirect('/gymkhana/') - except Exception as e: - logger.info(e) - return HttpResponse('error') - data = serializers.serialize('json',Voting_choices.objects.select_related('poll_event').all()) - return redirect('/gymkhana/') @login_required -def delete_poll(request, poll_id): - """ - delete_poll: - This view delete the particular voting poll which is passed through function and redirect - to "/gymkhana/" if there is an exception then it return the HttpResponse of "error" - @param: - request : trivial - poll_id : id of the poll in Voting_polls - @variables: - poll : It is an object stores the all data of poll_id from Voting_poll - """ - try: - poll = Voting_polls.objects.filter(pk=poll_id) - poll.delete() - return redirect('/gymkhana/') - except Exception as e: - logger.info(e) - return HttpResponse('error') - - return redirect('/gymkhana/') - -#this algorithm checks if the passed slot time coflicts with any of already booked events +def budget_reject(request): + """ + This view is used by the administration to reject the clubs. + It gets a list of clubs and then rejects if they want to. + + @variables: + club_reject_list - list of clubs which has to be checked and rejected + club_name - gets the object and then rejects the club + + """ + if request.method == "POST": + budget_approve_list = list(request.POST.getlist("check")) + first_words = [] + for item in budget_approve_list: + first_word = item.split()[0] + first_words.append(first_word) + + for club in first_words: + print(club) + club_budget = Club_budget.objects.get( + club_id=club, status="open" + ) + club_budget.status = "rejected" + club_budget.save() + messages.success( + request, f"Successfully budget rejected for club.") + return redirect("/gymkhana/") + def conflict_algorithm_event(date, start_time, end_time, venue): - """ - conflict_algorithm_event: - This view takes the date, start_time , end_time , Venue which is passed by function and - checks with data in database then it returns "success" if there is no time slot is clashng - with passed data and returns "error" if there is some time slot is clashing with passed - data - @param: - date : date of the event - start_time : Event's starting time - end_time : Event's ending time - venue : Venue of the event - @variables: - booked_Events : This is an object contains all data of Event_info for which date - and venue is equal to passed date and venue - """ - #converting string to datetime type variable - start_time = datetime.datetime.strptime(start_time, '%H:%M').time() - end_time = datetime.datetime.strptime(end_time, '%H:%M').time() - booked_Events = Event_info.objects.select_related('club','club__co_ordinator','club__co_ordinator__id','club__co_ordinator__id__user','club__co_ordinator__id__department','club__co_coordinator','club__co_coordinator__id','club__co_coordinator__id__user','club__co_coordinator__id__department','club__faculty_incharge','club__faculty_incharge__id','club__faculty_incharge__id__user','club__faculty_incharge__id__department').filter(date=date, venue=venue) - - #placing start time and end time in tuple fashion inside this list - slots = [(start_time, end_time)] - for value in booked_Events: - slots.append((value.start_time, value.end_time)) - slots.sort() - #if there isn't any slot present for the selected day just book the event - if (len(slots) == 1): - return "success" - else: - #this whole logic checks if the end time of any slot is less than the start time of next slot - counter = slots[0][1] - flag = 0 - i=1 - while i < len(slots): - if (slots[i][0] < counter): - flag = 1 - break - counter = slots[i][1] - i = i + 1 - if (flag == 0): - return "success" - else: - return "error" - -@login_required(login_url = "/accounts/login/") + """ + conflict_algorithm_event: + This view takes the date, start_time , end_time , Venue which is passed by function and + checks with data in database then it returns "success" if there is no time slot is clashng + with passed data and returns "error" if there is some time slot is clashing with passed + data + @param: + date : date of the event + start_time : Event's starting time + end_time : Event's ending time + venue : Venue of the event + @variables: + booked_Events : This is an object contains all data of Event_info for which date + and venue is equal to passed date and venue + """ + # converting string to datetime type variable + start_time = datetime.datetime.strptime(start_time, "%H:%M").time() + end_time = datetime.datetime.strptime(end_time, "%H:%M").time() + booked_Events = Event_info.objects.select_related( + "club", + "club__co_ordinator", + "club__co_ordinator__id", + "club__co_ordinator__id__user", + "club__co_ordinator__id__department", + "club__co_coordinator", + "club__co_coordinator__id", + "club__co_coordinator__id__user", + "club__co_coordinator__id__department", + "club__faculty_incharge", + "club__faculty_incharge__id", + "club__faculty_incharge__id__user", + "club__faculty_incharge__id__department", + ).filter(date=date, venue=venue) + + # placing start time and end time in tuple fashion inside this list + slots = [(start_time, end_time)] + for value in booked_Events: + slots.append((value.start_time, value.end_time)) + slots.sort() + # if there isn't any slot present for the selected day just book the event + if len(slots) == 1: + return "success" + else: + # this whole logic checks if the end time of any slot is less than the start time of next slot + counter = slots[0][1] + flag = 0 + i = 1 + while i < len(slots): + if slots[i][0] < counter: + flag = 1 + break + counter = slots[i][1] + i = i + 1 + if flag == 0: + return "success" + else: + return "error" + + +@login_required(login_url="/accounts/login/") def filetracking(request): - """ - The function is used to create files by current user(employee). - It adds the employee(uploader) and file datails to a file(table) of filetracking(model) - if he intends to create file. - - @param: - request - trivial. - - @variables: - - - uploader - Employee who creates file. - subject - Title of the file. - description - Description of the file. - upload_file - Attachment uploaded while creating file. - file - The file object. - exations - The HoldsDesignation object. - context - Hotrainfo - The Extrainfo object. - holdsdesignlds data needed to make necessary changes in the template. - """ - if request.method =="POST": - try: - if 'save' in request.POST: - uploader = request.user.extrainfo - logger.info(uploader) - #ref_id = request.POST.get('fileid') - subject = request.POST.get('title') - description = request.POST.get('desc') - design = request.POST.get('design') - designation = Designation.objects.get(id=design) - upload_file = request.FILES.get('myfile') - - File.objects.create( - uploader=uploader, - #ref_id=ref_id, - description=description, - subject=subject, - designation=designation, - upload_file=upload_file - ) - - if 'send' in request.POST: - - - uploader = request.user.extrainfo - logger.info(uploader) - #ref_id = request.POST.get('fileid') - subject = request.POST.get('title') - description = request.POST.get('desc') - design = request.POST.get('design') - logger.info("designation is ", design) - designation = Designation.objects.get(id = HoldsDesignation.objects.select_related('user','working','designation').get(id = design).designation_id) - - upload_file = request.FILES.get('myfile') - - file = File.objects.create( - uploader=uploader, - #ref_id=ref_id, - description=description, - subject=subject, - designation=designation, - upload_file=upload_file - ) - - - 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') - receiver_id = User.objects.get(username=receiver) - logger.info("Receiver_id = ") - logger.info(receiver_id) - receive = request.POST.get('recieve') - logger.info("recieve = ") - logger.info(receive) - receive_designation = Designation.objects.filter(name=receive) - logger.info("receive_designation = ") - logger.info(receive_designation) - receive_design = receive_designation[0] - 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, - remarks=remarks, - upload_file=upload_file, - ) - office_module_notif(request.user, receiver_id) - messages.success(request,'File sent successfully') - - except IntegrityError: - message = "FileID Already Taken.!!" - return HttpResponse(message) - - - - file = File.objects.select_related('uploader','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, 'filetracking/composefile.html', context) - -@login_required(login_url = "/accounts/login") + """ + The function is used to create files by current user(employee). + It adds the employee(uploader) and file datails to a file(table) of filetracking(model) + if he intends to create file. + + @param: + request - trivial. + + @variables: + + + uploader - Employee who creates file. + subject - Title of the file. + description - Description of the file. + upload_file - Attachment uploaded while creating file. + file - The file object. + exations - The HoldsDesignation object. + context - Hotrainfo - The Extrainfo object. + holdsdesignlds data needed to make necessary changes in the template. + """ + if request.method == "POST": + try: + if "save" in request.POST: + uploader = request.user.extrainfo + logger.info(uploader) + # ref_id = request.POST.get('fileid') + subject = request.POST.get("title") + description = request.POST.get("desc") + design = request.POST.get("design") + designation = Designation.objects.get(id=design) + upload_file = request.FILES.get("myfile") + + File.objects.create( + uploader=uploader, + # ref_id=ref_id, + description=description, + subject=subject, + designation=designation, + upload_file=upload_file, + ) + + if "send" in request.POST: + uploader = request.user.extrainfo + logger.info(uploader) + # ref_id = request.POST.get('fileid') + subject = request.POST.get("title") + description = request.POST.get("desc") + design = request.POST.get("design") + logger.info("designation is ", design) + designation = Designation.objects.get( + id=HoldsDesignation.objects.select_related( + "user", "working", "designation" + ) + .get(id=design) + .designation_id + ) + + upload_file = request.FILES.get("myfile") + + file = File.objects.create( + uploader=uploader, + # ref_id=ref_id, + description=description, + subject=subject, + designation=designation, + upload_file=upload_file, + ) + 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") + receiver_id = User.objects.get(username=receiver) + logger.info("Receiver_id = ") + logger.info(receiver_id) + receive = request.POST.get("recieve") + logger.info("recieve = ") + logger.info(receive) + receive_designation = Designation.objects.filter(name=receive) + logger.info("receive_designation = ") + logger.info(receive_designation) + receive_design = receive_designation[0] + 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, + remarks=remarks, + upload_file=upload_file, + ) + office_module_notif(request.user, receiver_id) + messages.success(request, "File sent successfully") + except IntegrityError: + message = "FileID Already Taken.!!" + return HttpResponse(message) + + file = File.objects.select_related( + "uploader", "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, "filetracking/composefile.html", context) + + +@login_required(login_url="/accounts/login") def forward(request, id): - """ - The function is used to forward files received by user(employee) from other - employees which are filtered from Tracking(table) objects by current user - i.e. receiver_id to other employees. - It also gets track of file created by uploader through all users involved in file - along with their remarks and attachments - It displays details file of a File(table) and remarks and attachments of user involved - in file of Tracking(table) of filetracking(model) in the template. - - @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. - """ - # start = timer() - file = get_object_or_404(File, id=id) - # end = timer() - - # start = timer() - track = Tracking.objects.select_related('file_id','file_id__uploader','file_id__uploader__user','file_id__uploader__department','file_id__designation','current_id','current_id__user','current_id__department','current_design','current_design__user','current_design__working','current_design__designation','receiver_id','receive_design').filter(file_id=file) - # end = timer() - - if request.method == "POST": - if 'finish' in request.POST: - file.complete_flag = True - file.save() - - if 'send' in request.POST: - current_id = request.user.extrainfo - remarks = request.POST.get('remarks') - - sender = request.POST.get('sender') - current_design = HoldsDesignation.objects.select_related('user','working','designation').get(id=sender) - - receiver = request.POST.get('receiver') - receiver_id = User.objects.get(username=receiver) - receive = request.POST.get('recieve') - receive_designation = Designation.objects.filter(name=receive) - receive_design = receive_designation[0] - 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, - remarks=remarks, - upload_file=upload_file, - ) - # start = timer() - - 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 = { - # 'extrainfo': extrainfo, - # 'holdsdesignations': holdsdesignations, - 'designations':designations, - 'file': file, - 'track': track, - } - - return render(request, 'filetracking/forward.html', context) - - - + """ + The function is used to forward files received by user(employee) from other + employees which are filtered from Tracking(table) objects by current user + i.e. receiver_id to other employees. + It also gets track of file created by uploader through all users involved in file + along with their remarks and attachments + It displays details file of a File(table) and remarks and attachments of user involved + in file of Tracking(table) of filetracking(model) in the template. + + @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. + """ + # start = timer() + file = get_object_or_404(File, id=id) + # end = timer() + + # start = timer() + track = Tracking.objects.select_related( + "file_id", + "file_id__uploader", + "file_id__uploader__user", + "file_id__uploader__department", + "file_id__designation", + "current_id", + "current_id__user", + "current_id__department", + "current_design", + "current_design__user", + "current_design__working", + "current_design__designation", + "receiver_id", + "receive_design", + ).filter(file_id=file) + # end = timer() + + if request.method == "POST": + if "finish" in request.POST: + file.complete_flag = True + file.save() + + if "send" in request.POST: + current_id = request.user.extrainfo + remarks = request.POST.get("remarks") + + sender = request.POST.get("sender") + current_design = HoldsDesignation.objects.select_related( + "user", "working", "designation" + ).get(id=sender) + + receiver = request.POST.get("receiver") + receiver_id = User.objects.get(username=receiver) + receive = request.POST.get("recieve") + receive_designation = Designation.objects.filter(name=receive) + receive_design = receive_designation[0] + 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, + remarks=remarks, + upload_file=upload_file, + ) + # start = timer() + + 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 = { + # 'extrainfo': extrainfo, + # 'holdsdesignations': holdsdesignations, + "designations": designations, + "file": file, + "track": track, + } + + return render(request, "filetracking/forward.html", context) + + +@login_required +def inventory_update(request): + """ + act_calender: + This view gets the date from the club if there is any wrong info it shows the error + otherwise it shows Successfully uploaded the calendar in the form of Json object + and adds to the calendar + @params: + request : trivial + @variables: + club : Name of the club + act_calender : File that contains the active calender of the club + """ + if request.method == "POST": + message = "" + club = request.POST.get("club") + act_calender = request.FILES["act_file"] + act_calender.name = club + "_act_calender.pdf" + + # club_name = get_object_or_404(Club_info, club_name = club) + + club_info = get_object_or_404(Club_info, club_name=club) + club_info.activity_calender = act_calender + club_info.save() + message += "Successfully uploaded the calender !!!" + + content = { + "status": "success", + "message": message, + } + content = json.dumps(content) + return HttpResponse(content) + + +def del_mem(request): + reject_list = list(request.POST.getlist("check")) + for club in reject_list: + club_info = get_object_or_404(Club_member, member_id=club) + club_info.status = "rejected" + club_info.save() + + return redirect("/gymkhana/") + + +def del_club(request): + print("hi") + reject_list = request.POST.getlist("check") # No need to convert to list + for club in reject_list: + # Get the club info object + club_info = Club_info.objects.get(club_name=club) + + # Update budget status to "rejected" + try: + budgets = Club_budget.objects.filter(club_id=club) + for budget in budgets: + budget.status = "rejected" + budget.save() + except Club_budget.DoesNotExist: + pass + + # Update club info status to "rejected" + club_info.status = "rejected" + + # Delete coordinator and co-coordinator + co_user = User.objects.get(username=club_info.co_ordinator_id) + co_co_user = User.objects.get(username=club_info.co_coordinator_id) + + # Delete old coordinator designation + old_co_ordinator = HoldsDesignation.objects.filter( + user_id=co_user, working_id=co_user, designation_id=56 + ) + old_co_ordinator.delete() + + # Delete old co-coordinator designation + old_co_coordinator = HoldsDesignation.objects.filter( + user_id=co_co_user, working_id=co_co_user, designation_id=57 + ) + old_co_coordinator.delete() + club_info.delete() + + return redirect("/gymkhana/") + +def approve_events(request): + selected_ids = request.POST.get("ids") + + if not selected_ids: + return JsonResponse({"status": "error", "message": "No event IDs provided"}) + + try: + selected_ids = json.loads(selected_ids) + for event_id in selected_ids: + try: + event = Event_info.objects.get(pk=event_id) + event.status = "confirmed" + event.save() + except ObjectDoesNotExist: + return JsonResponse({"status": "error", "message": f"Event with ID {event_id} does not exist"}) + + return JsonResponse({"status": "success"}) + except Exception as e: + return JsonResponse({"status": "error", "message": str(e)}) + + +def update_club_name(request): + club_id = request.POST.get('club_id') + new_name = request.POST.get('new_name') + + if club_id and new_name: + try: + with transaction.atomic(): + + club = Club_info.objects.get(club_name=club_id) + + co_ordinator_id = club.co_ordinator_id + co_coordinator_id = club.co_coordinator_id + faculty_incharge_id = club.faculty_incharge_id + status = club.status + description = club.description + activity_calender = club.activity_calender + category = club.category + + club.delete() + + new_club = Club_info( + club_name=new_name, + co_ordinator_id=co_ordinator_id, + co_coordinator_id=co_coordinator_id, + faculty_incharge_id=faculty_incharge_id, + status="open", + description=description, + activity_calender=activity_calender, + category=category + + + ) + new_club.save() + + return JsonResponse({'status': 'success'}) + except Club_info.DoesNotExist: + return JsonResponse({'status': 'error', 'message': 'Club not found'}) + + + +@csrf_exempt +def update_budget_amount(request): + print("inside function") + if request.method == 'POST': + budget_id = request.POST.get('budget_id') + req_id=request.POST.get('req_id') + + print(budget_id) + print(req_id) + # Fetch the budget object + + budget = Club_budget.objects.get(id=budget_id) + if req_id=="spent": + new_budget = float(request.POST.get('new_budget')) # convert new_budget to float + + # Fetch the budget object + budget = Club_budget.objects.get(id=budget_id) + + # Update the budget amount + if new_budget > budget.budget_amt: + return JsonResponse({'status': 'error', 'message': 'Spent amount cannot be greater than available amount!'}) + budget.budget_amt = budget.budget_amt - new_budget + budget.save() + + else: + # Update the budget amount + new_budget = request.POST.get('new_budget') + budget.budget_amt = new_budget + budget.save() + + # Return a success response + return JsonResponse({'status': 'success', 'message': 'Budget amount updated successfully'}) + + # Return an error response if not a POST request + return JsonResponse({'status': 'error', 'message': 'Invalid request'}) + + + +@csrf_exempt +def update_spent_amount(request): + if request.method == 'POST': + budget_id = request.POST.get('budget_id') + new_budget = float(request.POST.get('new_budget')) # convert new_budget to float + + # Fetch the budget object + budget = Club_budget.objects.get(id=budget_id) + + # Update the budget amount + if new_budget > budget.budget_amt: + return JsonResponse({'status': 'error', 'message': 'Spent amount cannot be greater than available amount!'}) + budget.budget_amt = budget.budget_amt - new_budget + budget.save() + + # Return a success response + return redirect('/gymkhana/') + + # Return an error response if not a POST request + return JsonResponse({'status': 'error', 'message': 'Invalid request'}) \ No newline at end of file diff --git a/FusionIIIT/applications/health_center/admin.py b/FusionIIIT/applications/health_center/admin.py index 7299eff00..a988d7b5f 100644 --- a/FusionIIIT/applications/health_center/admin.py +++ b/FusionIIIT/applications/health_center/admin.py @@ -3,19 +3,19 @@ from .models import * admin.site.register(Doctor) -admin.site.register(Appointment) -admin.site.register(Ambulance_request) -admin.site.register(Hospital_admit) -admin.site.register(Complaint) -admin.site.register(Stock) -admin.site.register(Counter) -admin.site.register(Expiry) -admin.site.register(Hospital) -admin.site.register(Prescription) -admin.site.register(Medicine) -admin.site.register(Prescribed_medicine) +# admin.site.register(Appointment) +# admin.site.register(Ambulance_request) +# admin.site.register(Hospital_admit) +# admin.site.register(Complaint) +admin.site.register(Present_Stock) +# admin.site.register(Counter) +# admin.site.register(Expiry) +# admin.site.register(Hospital) +admin.site.register(All_Prescription) +admin.site.register(All_Medicine) +admin.site.register(All_Prescribed_medicine) admin.site.register(Doctors_Schedule) admin.site.register(Pathologist_Schedule) -admin.site.register(Announcements) -admin.site.register(SpecialRequest) -admin.site.register(Pathologist) \ No newline at end of file +# admin.site.register(Announcements) +# admin.site.register(SpecialRequest) +admin.site.register(Pathologist) \ No newline at end of file diff --git a/FusionIIIT/applications/health_center/api/serializers.py b/FusionIIIT/applications/health_center/api/serializers.py index 5eb2740b2..edfaa6dc7 100644 --- a/FusionIIIT/applications/health_center/api/serializers.py +++ b/FusionIIIT/applications/health_center/api/serializers.py @@ -1,114 +1,114 @@ -from django.contrib.auth import get_user_model -from rest_framework.authtoken.models import Token -from rest_framework import serializers -from applications.health_center.models import * +# from django.contrib.auth import get_user_model +# from rest_framework.authtoken.models import Token +# from rest_framework import serializers +# from applications.health_center.models import * -class DoctorSerializer(serializers.ModelSerializer): +# class DoctorSerializer(serializers.ModelSerializer): - class Meta: - model=Doctor - fields=('__all__') +# class Meta: +# model=Doctor +# fields=('__all__') -class PathologistSerializer(serializers.ModelSerializer): +# class PathologistSerializer(serializers.ModelSerializer): - class Meta: - model=Pathologist - fields=('__all__') +# class Meta: +# model=Pathologist +# fields=('__all__') -class ComplaintSerializer(serializers.ModelSerializer): +# class ComplaintSerializer(serializers.ModelSerializer): - class Meta: - model=Complaint - fields=('__all__') +# class Meta: +# model=Complaint +# fields=('__all__') -class StockSerializer(serializers.ModelSerializer): +# class StockSerializer(serializers.ModelSerializer): - class Meta: - model=Stock - fields=('__all__') +# class Meta: +# model=Stock +# fields=('__all__') -class MedicineSerializer(serializers.ModelSerializer): +# class MedicineSerializer(serializers.ModelSerializer): - class Meta: - model=Medicine - fields=('__all__') +# class Meta: +# model=Medicine +# fields=('__all__') -class HospitalSerializer(serializers.ModelSerializer): +# class HospitalSerializer(serializers.ModelSerializer): - class Meta: - model=Hospital - fields=('__all__') +# class Meta: +# model=Hospital +# fields=('__all__') -class ExpirySerializer(serializers.ModelSerializer): +# class ExpirySerializer(serializers.ModelSerializer): - class Meta: - model=Expiry - fields=('__all__') +# class Meta: +# model=Expiry +# fields=('__all__') -class DoctorsScheduleSerializer(serializers.ModelSerializer): +# class DoctorsScheduleSerializer(serializers.ModelSerializer): - class Meta: - model=Doctors_Schedule - fields=('__all__') -class PathologistScheduleSerializer(serializers.ModelSerializer): +# class Meta: +# model=Doctors_Schedule +# fields=('__all__') +# class PathologistScheduleSerializer(serializers.ModelSerializer): - class Meta: - model=Pathologist_Schedule - fields=('__all__') +# class Meta: +# model=Pathologist_Schedule +# fields=('__all__') -class AnnouncementSerializer(serializers.ModelSerializer): +# class AnnouncementSerializer(serializers.ModelSerializer): - class Meta: - model=Announcements - fields=('__all__') +# class Meta: +# model=Announcements +# fields=('__all__') -class CounterSerializer(serializers.ModelSerializer): +# class CounterSerializer(serializers.ModelSerializer): - class Meta: - model=Counter - fields=('__all__') +# class Meta: +# model=Counter +# fields=('__all__') -class AppointmentSerializer(serializers.ModelSerializer): +# class AppointmentSerializer(serializers.ModelSerializer): - class Meta: - model=Appointment - fields=('__all__') +# class Meta: +# model=Appointment +# fields=('__all__') -class PrescriptionSerializer(serializers.ModelSerializer): +# class PrescriptionSerializer(serializers.ModelSerializer): - class Meta: - model=Prescription - fields=('__all__') +# class Meta: +# model=Prescription +# fields=('__all__') -class PrescribedMedicineSerializer(serializers.ModelSerializer): +# class PrescribedMedicineSerializer(serializers.ModelSerializer): - class Meta: - model=Prescribed_medicine - fields=('__all__') +# class Meta: +# model=Prescribed_medicine +# fields=('__all__') -class AmbulanceRequestSerializer(serializers.ModelSerializer): +# class AmbulanceRequestSerializer(serializers.ModelSerializer): - class Meta: - model=Ambulance_request - fields=('__all__') +# class Meta: +# model=Ambulance_request +# fields=('__all__') -class HospitalAdmitSerializer(serializers.ModelSerializer): +# class HospitalAdmitSerializer(serializers.ModelSerializer): - class Meta: - model=Hospital_admit - fields=('__all__') +# class Meta: +# model=Hospital_admit +# fields=('__all__') -class MedicalReliefSerializer(serializers.ModelSerializer): +# class MedicalReliefSerializer(serializers.ModelSerializer): - class Meta: - model=medical_relief - fields=('__all__') \ No newline at end of file +# class Meta: +# model=medical_relief +# fields=('__all__') \ No newline at end of file diff --git a/FusionIIIT/applications/health_center/api/urls.py b/FusionIIIT/applications/health_center/api/urls.py index 49fee2d6e..30e998166 100644 --- a/FusionIIIT/applications/health_center/api/urls.py +++ b/FusionIIIT/applications/health_center/api/urls.py @@ -4,8 +4,8 @@ urlpatterns = [ - url(r'^compounder/$', views.compounder_view_api, name='compounder_view_api'), - url(r'^compounder/request$', views.compounder_request_api , name='compounder_request_api'), - url(r'^student/$', views.student_view_api, name='student_view'), - url(r'^student/request$', views.student_request_api, name='student_request_api') + # url(r'^compounder/$', views.compounder_view_api, name='compounder_view_api'), + # url(r'^compounder/request$', views.compounder_request_api , name='compounder_request_api'), + # url(r'^student/$', views.student_view_api, name='student_view'), + # url(r'^student/request$', views.student_request_api, name='student_request_api') ] \ No newline at end of file diff --git a/FusionIIIT/applications/health_center/api/views.py b/FusionIIIT/applications/health_center/api/views.py index a3f8b1c67..d900c1461 100644 --- a/FusionIIIT/applications/health_center/api/views.py +++ b/FusionIIIT/applications/health_center/api/views.py @@ -1,407 +1,407 @@ -from django.contrib.auth import get_user_model -from django.shortcuts import get_object_or_404, redirect -from applications.globals.models import ExtraInfo, HoldsDesignation, Designation, DepartmentInfo -from applications.health_center.models import * -from datetime import datetime, timedelta, time,date -from django.db import transaction -from notification.views import healthcare_center_notif -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 django.contrib.auth import get_user_model +# from django.shortcuts import get_object_or_404, redirect +# from applications.globals.models import ExtraInfo, HoldsDesignation, Designation, DepartmentInfo +# from applications.health_center.models import * +# from datetime import datetime, timedelta, time,date +# from django.db import transaction +# from notification.views import healthcare_center_notif +# 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 . import serializers +# from . import serializers -from notifications.models import Notification +# from notifications.models import Notification -User = get_user_model() +# User = get_user_model() -def getDesignation(request): - user = request.user - design = HoldsDesignation.objects.select_related('user','designation').filter(working=user) +# def getDesignation(request): +# user = request.user +# design = HoldsDesignation.objects.select_related('user','designation').filter(working=user) - designation=[] +# designation=[] - if str(user.extrainfo.user_type) == "student": - designation.append(str(user.extrainfo.user_type)) +# if str(user.extrainfo.user_type) == "student": +# designation.append(str(user.extrainfo.user_type)) - for i in design: - if str(i.designation) != str(user.extrainfo.user_type): - # print('-------') - # print(i.designation) - # print(user.extrainfo.user_type) - # print('') - designation.append(str(i.designation)) - # for i in designation: - # print(i) - return designation +# for i in design: +# if str(i.designation) != str(user.extrainfo.user_type): +# # print('-------') +# # print(i.designation) +# # print(user.extrainfo.user_type) +# # print('') +# designation.append(str(i.designation)) +# # for i in designation: +# # print(i) +# return designation -@api_view(['POST','DELETE']) -def student_request_api(request): - # design=request.session['currentDesignationSelected'] - usertype = ExtraInfo.objects.get(user=request.user).user_type - design = getDesignation(request) - if 'student' in design or 'Compounder' not in design: - # if design == 'student' or usertype == 'faculty' or usertype == 'staff': - # if 'ambulancerequest' in request.data and request.method=='POST': - # comp_id = ExtraInfo.objects.filter(user_type='compounder') - # request.data['user_id'] = get_object_or_404(User,username=request.user.username) - # request.data['date_request']=datetime.now() - # serializer = serializers.AmbulanceRequestSerializer(data=request.data) - # if serializer.is_valid(): - # serializer.save() - # healthcare_center_notif(request.user, request.user, 'amb_request') - # for cmp in comp_id: - # healthcare_center_notif(request.user, cmp.user, 'amb_req') - # return Response(serializer.data, status=status.HTTP_201_CREATED) - # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# @api_view(['POST','DELETE']) +# def student_request_api(request): +# # design=request.session['currentDesignationSelected'] +# usertype = ExtraInfo.objects.get(user=request.user).user_type +# design = getDesignation(request) +# if 'student' in design or 'Compounder' not in design: +# # if design == 'student' or usertype == 'faculty' or usertype == 'staff': +# # if 'ambulancerequest' in request.data and request.method=='POST': +# # comp_id = ExtraInfo.objects.filter(user_type='compounder') +# # request.data['user_id'] = get_object_or_404(User,username=request.user.username) +# # request.data['date_request']=datetime.now() +# # serializer = serializers.AmbulanceRequestSerializer(data=request.data) +# # if serializer.is_valid(): +# # serializer.save() +# # healthcare_center_notif(request.user, request.user, 'amb_request') +# # for cmp in comp_id: +# # healthcare_center_notif(request.user, cmp.user, 'amb_req') +# # return Response(serializer.data, status=status.HTTP_201_CREATED) +# # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - # elif 'ambulancecancel' in request.data and request.method == 'DELETE': - # try: - # amb_id=int(request.data['amb_id']) - # except: - # return Response({'message': 'Please enter ambulance id'}, status=status.HTTP_404_NOT_FOUND) - # ambulance = get_object_or_404(Ambulance_request,pk=amb_id) - # ambulance.delete() - # resp = {'message': 'ambulance request is cancelled'} - # return Response(data=resp,status=status.HTTP_200_OK) +# # elif 'ambulancecancel' in request.data and request.method == 'DELETE': +# # try: +# # amb_id=int(request.data['amb_id']) +# # except: +# # return Response({'message': 'Please enter ambulance id'}, status=status.HTTP_404_NOT_FOUND) +# # ambulance = get_object_or_404(Ambulance_request,pk=amb_id) +# # ambulance.delete() +# # resp = {'message': 'ambulance request is cancelled'} +# # return Response(data=resp,status=status.HTTP_200_OK) - # elif 'appointmentadd' in request.data and request.method == 'POST': - # request.data['user_id'] = get_object_or_404(User,username=request.user.username) - # try: - # day = datetime.strptime(request.data['date'], "%Y-%m-%d").weekday() - # except: - # return Response({'message': 'Please enter valid date'}, status=status.HTTP_404_NOT_FOUND) - # try: - # doctor_id = request.data['doctor_id'] - # except: - # return Response({'message': 'Please enter doctor id'}, status=status.HTTP_404_NOT_FOUND) - # request.data['schedule'] =get_object_or_404(Doctors_Schedule,doctor_id=request.data['doctor_id'],day=day).id - # comp_id = ExtraInfo.objects.filter(user_type='compounder') - # serializer = serializers.AppointmentSerializer(data=request.data) - # if serializer.is_valid(): - # serializer.save() - # healthcare_center_notif(request.user, request.user, 'appoint') - # for cmp in comp_id: - # healthcare_center_notif(request.user, cmp.user, 'appoint_req') - # return Response(serializer.data, status=status.HTTP_201_CREATED) - # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# # elif 'appointmentadd' in request.data and request.method == 'POST': +# # request.data['user_id'] = get_object_or_404(User,username=request.user.username) +# # try: +# # day = datetime.strptime(request.data['date'], "%Y-%m-%d").weekday() +# # except: +# # return Response({'message': 'Please enter valid date'}, status=status.HTTP_404_NOT_FOUND) +# # try: +# # doctor_id = request.data['doctor_id'] +# # except: +# # return Response({'message': 'Please enter doctor id'}, status=status.HTTP_404_NOT_FOUND) +# # request.data['schedule'] =get_object_or_404(Doctors_Schedule,doctor_id=request.data['doctor_id'],day=day).id +# # comp_id = ExtraInfo.objects.filter(user_type='compounder') +# # serializer = serializers.AppointmentSerializer(data=request.data) +# # if serializer.is_valid(): +# # serializer.save() +# # healthcare_center_notif(request.user, request.user, 'appoint') +# # for cmp in comp_id: +# # healthcare_center_notif(request.user, cmp.user, 'appoint_req') +# # return Response(serializer.data, status=status.HTTP_201_CREATED) +# # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - # elif 'appointmentdelete' in request.data and request.method == 'DELETE': - # try: - # app_id = request.data['app_id'] - # except: - # return Response({'message': 'Please enter valid appointment id'}, status=status.HTTP_404_NOT_FOUND) - # appointment=get_object_or_404(Appointment,pk=app_id) - # appointment.delete() - # resp = {'message': 'Your appointment is cancelled'} - # return Response(data=resp,status=status.HTTP_200_OK) +# # elif 'appointmentdelete' in request.data and request.method == 'DELETE': +# # try: +# # app_id = request.data['app_id'] +# # except: +# # return Response({'message': 'Please enter valid appointment id'}, status=status.HTTP_404_NOT_FOUND) +# # appointment=get_object_or_404(Appointment,pk=app_id) +# # appointment.delete() +# # resp = {'message': 'Your appointment is cancelled'} +# # return Response(data=resp,status=status.HTTP_200_OK) - if 'complaintadd' in request.data and request.method == 'POST': - request.data['user_id'] = get_object_or_404(User,username=request.user.username) - serializer = serializers.ComplaintSerializer(data=request.data) - if serializer.is_valid(): - serializer.save() - return Response(serializer.data, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - else: - resp = {'message': 'invalid request'} - return Response(data=resp,status=status.HTTP_404_NOT_FOUND) +# if 'complaintadd' in request.data and request.method == 'POST': +# request.data['user_id'] = get_object_or_404(User,username=request.user.username) +# serializer = serializers.ComplaintSerializer(data=request.data) +# if serializer.is_valid(): +# serializer.save() +# return Response(serializer.data, status=status.HTTP_201_CREATED) +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# else: +# resp = {'message': 'invalid request'} +# return Response(data=resp,status=status.HTTP_404_NOT_FOUND) - elif 'Compounder' in design: - return redirect('/healthcenter/api/compounder/request/') - else: - resp = {'message': 'invalid request'} - return Response(data=resp,status=status.HTTP_404_NOT_FOUND) +# elif 'Compounder' in design: +# return redirect('/healthcenter/api/compounder/request/') +# else: +# resp = {'message': 'invalid request'} +# return Response(data=resp,status=status.HTTP_404_NOT_FOUND) -@api_view(['GET']) -@permission_classes([IsAuthenticated]) -@authentication_classes([TokenAuthentication]) -def student_view_api(request): - # student view starts here - # design=request.session['currentDesignationSelected'] - # usertype = ExtraInfo.objects.get(user=request.user).user_type - design = getDesignation(request) - if 'student' in design or 'Compounder' not in design: - # users = ExtraInfo.objects.all() - user_id = ExtraInfo.objects.get(user=request.user) - # hospitals = serializers.HospitalAdmitSerializer(Hospital_admit.objects.filter(user_id=user_id).order_by('-admission_date'),many=True).data - # appointments = serializers.AppointmentSerializer(Appointment.objects.filter(user_id=user_id).order_by('-date'),many=True).data - # ambulances = serializers.AmbulanceRequestSerializer(Ambulance_request.objects.filter(user_id=user_id).order_by('-date_request'),many=True).data - prescription = serializers.PrescriptionSerializer(Prescription.objects.filter(user_id=user_id).order_by('-date'),many=True).data - medicines_presc = serializers.PrescribedMedicineSerializer(Prescribed_medicine.objects.all(),many=True).data - complaints = serializers.ComplaintSerializer(Complaint.objects.filter(user_id=user_id).order_by('-date'),many=True).data - days = Constants.DAYS_OF_WEEK - # schedule=serializers.ScheduleSerializer(Doctors_Schedule.objects.all().order_by('doctor_id'),many=True).data - doctor_schedule=serializers.DoctorsScheduleSerializer(Doctors_Schedule.objects.all().order_by('doctor_id'),many=True).data - pathologist_schedule=serializers.PathologistScheduleSerializer(Pathologist_Schedule.objects.all().order_by('pathologist_id'), many=True).data - doctors=serializers.DoctorSerializer(Doctor.objects.filter(active=True),many=True).data - pathologists=serializers.PathologistSerializer(Pathologist.objects.filter(active=True),many=True).data - count=Counter.objects.all() - if count: - Counter.objects.all().delete() - Counter.objects.create(count=0,fine=0) - count= serializers.CounterSerializer(Counter.objects.get()).data - resp={ - 'complaints': complaints, - 'medicines_presc': medicines_presc, - # 'ambulances': ambulances, - 'doctors': doctors, - 'pathologists': pathologists, - 'days': days, - 'count':count, - # 'hospitals': hospitals, - # 'appointments': appointments, - 'prescription': prescription, - # 'schedule': schedule - 'doctor_schedule': doctor_schedule, - 'pathologist_schedule': pathologist_schedule, - } - return Response(data=resp,status=status.HTTP_200_OK) - elif 'Compounder' in design: - return redirect('/healthcenter/api/compounder/') - else: - resp = {'message': 'invalid request'} - return Response(data=resp,status=status.HTTP_404_NOT_FOUND) +# @api_view(['GET']) +# @permission_classes([IsAuthenticated]) +# @authentication_classes([TokenAuthentication]) +# def student_view_api(request): +# # student view starts here +# # design=request.session['currentDesignationSelected'] +# # usertype = ExtraInfo.objects.get(user=request.user).user_type +# design = getDesignation(request) +# if 'student' in design or 'Compounder' not in design: +# # users = ExtraInfo.objects.all() +# user_id = ExtraInfo.objects.get(user=request.user) +# # hospitals = serializers.HospitalAdmitSerializer(Hospital_admit.objects.filter(user_id=user_id).order_by('-admission_date'),many=True).data +# # appointments = serializers.AppointmentSerializer(Appointment.objects.filter(user_id=user_id).order_by('-date'),many=True).data +# # ambulances = serializers.AmbulanceRequestSerializer(Ambulance_request.objects.filter(user_id=user_id).order_by('-date_request'),many=True).data +# prescription = serializers.PrescriptionSerializer(Prescription.objects.filter(user_id=user_id).order_by('-date'),many=True).data +# medicines_presc = serializers.PrescribedMedicineSerializer(Prescribed_medicine.objects.all(),many=True).data +# complaints = serializers.ComplaintSerializer(Complaint.objects.filter(user_id=user_id).order_by('-date'),many=True).data +# days = Constants.DAYS_OF_WEEK +# # schedule=serializers.ScheduleSerializer(Doctors_Schedule.objects.all().order_by('doctor_id'),many=True).data +# doctor_schedule=serializers.DoctorsScheduleSerializer(Doctors_Schedule.objects.all().order_by('doctor_id'),many=True).data +# pathologist_schedule=serializers.PathologistScheduleSerializer(Pathologist_Schedule.objects.all().order_by('pathologist_id'), many=True).data +# doctors=serializers.DoctorSerializer(Doctor.objects.filter(active=True),many=True).data +# pathologists=serializers.PathologistSerializer(Pathologist.objects.filter(active=True),many=True).data +# count=Counter.objects.all() +# if count: +# Counter.objects.all().delete() +# Counter.objects.create(count=0,fine=0) +# count= serializers.CounterSerializer(Counter.objects.get()).data +# resp={ +# 'complaints': complaints, +# 'medicines_presc': medicines_presc, +# # 'ambulances': ambulances, +# 'doctors': doctors, +# 'pathologists': pathologists, +# 'days': days, +# 'count':count, +# # 'hospitals': hospitals, +# # 'appointments': appointments, +# 'prescription': prescription, +# # 'schedule': schedule +# 'doctor_schedule': doctor_schedule, +# 'pathologist_schedule': pathologist_schedule, +# } +# return Response(data=resp,status=status.HTTP_200_OK) +# elif 'Compounder' in design: +# return redirect('/healthcenter/api/compounder/') +# else: +# resp = {'message': 'invalid request'} +# return Response(data=resp,status=status.HTTP_404_NOT_FOUND) -@api_view(['POST','PATCH','DELETE']) -@permission_classes([IsAuthenticated]) -@authentication_classes([TokenAuthentication]) -def compounder_request_api(request): - design = getDesignation(request) - if 'Compounder' in design: - if 'doctoradd' in request.data and request.method == 'POST': - request.data['active']=True - serializer = serializers.DoctorSerializer(data=request.data) - if serializer.is_valid(): - serializer.save() - return Response(serializer.data, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# @api_view(['POST','PATCH','DELETE']) +# @permission_classes([IsAuthenticated]) +# @authentication_classes([TokenAuthentication]) +# def compounder_request_api(request): +# design = getDesignation(request) +# if 'Compounder' in design: +# if 'doctoradd' in request.data and request.method == 'POST': +# request.data['active']=True +# serializer = serializers.DoctorSerializer(data=request.data) +# if serializer.is_valid(): +# serializer.save() +# return Response(serializer.data, status=status.HTTP_201_CREATED) +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - elif 'doctorremove' in request.data and request.method == 'PATCH': - try: - doctor=request.data['id'] - except: - return Response({'message': 'Please enter valid doctor id'}, status=status.HTTP_404_NOT_FOUND) - request.data['active']=False - doctor= get_object_or_404(Doctor,id=doctor) - serializer = serializers.DoctorSerializer(doctor,data=request.data,partial=True) - if serializer.is_valid(): - serializer.save() - return Response(serializer.data, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# elif 'doctorremove' in request.data and request.method == 'PATCH': +# try: +# doctor=request.data['id'] +# except: +# return Response({'message': 'Please enter valid doctor id'}, status=status.HTTP_404_NOT_FOUND) +# request.data['active']=False +# doctor= get_object_or_404(Doctor,id=doctor) +# serializer = serializers.DoctorSerializer(doctor,data=request.data,partial=True) +# if serializer.is_valid(): +# serializer.save() +# return Response(serializer.data, status=status.HTTP_201_CREATED) +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - elif 'doctorscheduleadd' in request.data and request.method == 'POST': - try: - doctor_id = int(request.data['doctor_id']) - except: - return Response({'message': 'Please enter valid doctor id'}, status=status.HTTP_404_NOT_FOUND) - try: - day = request.data['day'] - except: - return Response({'message': 'Please enter valid day'}, status=status.HTTP_404_NOT_FOUND) - sc = Doctor.objects.filter(doctor_id=doctor_id, day=day) - if sc.count() == 0: - serializer = serializers.DoctorsScheduleSerializer(data=request.data) - else: - sc = get_object_or_404(Doctors_Schedule,doctor_id=doctor_id,day=day) - serializer = serializers.DoctorsScheduleSerializer(sc,data=request.data,partial=True) - if serializer.is_valid(): - serializer.save() - return Response(serializer.data, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# elif 'doctorscheduleadd' in request.data and request.method == 'POST': +# try: +# doctor_id = int(request.data['doctor_id']) +# except: +# return Response({'message': 'Please enter valid doctor id'}, status=status.HTTP_404_NOT_FOUND) +# try: +# day = request.data['day'] +# except: +# return Response({'message': 'Please enter valid day'}, status=status.HTTP_404_NOT_FOUND) +# sc = Doctor.objects.filter(doctor_id=doctor_id, day=day) +# if sc.count() == 0: +# serializer = serializers.DoctorsScheduleSerializer(data=request.data) +# else: +# sc = get_object_or_404(Doctors_Schedule,doctor_id=doctor_id,day=day) +# serializer = serializers.DoctorsScheduleSerializer(sc,data=request.data,partial=True) +# if serializer.is_valid(): +# serializer.save() +# return Response(serializer.data, status=status.HTTP_201_CREATED) +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - elif 'doctorscheduleremove' in request.data and request.method == 'DELETE': - try: - doctor_id = request.data['doctor_id'] - except: - return Response({'message': 'Please enter valid doctor id'}, status=status.HTTP_404_NOT_FOUND) - try: - day = request.data['day'] - except: - return Response({'message': 'Please enter valid day'}, status=status.HTTP_404_NOT_FOUND) - sc = get_object_or_404(Doctors_Schedule,doctor_id=doctor_id,day=day) - sc.delete() - resp={'message':'Schedule Deleted successfully'} - return Response(data=resp,status=status.HTTP_200_OK) +# elif 'doctorscheduleremove' in request.data and request.method == 'DELETE': +# try: +# doctor_id = request.data['doctor_id'] +# except: +# return Response({'message': 'Please enter valid doctor id'}, status=status.HTTP_404_NOT_FOUND) +# try: +# day = request.data['day'] +# except: +# return Response({'message': 'Please enter valid day'}, status=status.HTTP_404_NOT_FOUND) +# sc = get_object_or_404(Doctors_Schedule,doctor_id=doctor_id,day=day) +# sc.delete() +# resp={'message':'Schedule Deleted successfully'} +# return Response(data=resp,status=status.HTTP_200_OK) - # elif 'hospitaladmit' in request.data and request.method == 'POST': - # serializer = serializers.HospitalAdmitSerializer(data=request.data) - # if serializer.is_valid(): - # serializer.save() - # return Response(serializer.data, status=status.HTTP_201_CREATED) - # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# # elif 'hospitaladmit' in request.data and request.method == 'POST': +# # serializer = serializers.HospitalAdmitSerializer(data=request.data) +# # if serializer.is_valid(): +# # serializer.save() +# # return Response(serializer.data, status=status.HTTP_201_CREATED) +# # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - # elif 'hospitaldischarge' in request.data and request.method == 'PATCH': - # try: - # pk = request.data['id'] - # except: - # return Response({'message': 'Please enter valid id'}, status=status.HTTP_404_NOT_FOUND) - # request.data['discharge_date']=date.today() - # Ha = get_object_or_404(Hospital_admit,id=pk) - # serializer = serializers.HospitalAdmitSerializer(Ha,data=request.data,partial=True) - # if serializer.is_valid(): - # serializer.save() - # return Response(serializer.data, status=status.HTTP_201_CREATED) - # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# # elif 'hospitaldischarge' in request.data and request.method == 'PATCH': +# # try: +# # pk = request.data['id'] +# # except: +# # return Response({'message': 'Please enter valid id'}, status=status.HTTP_404_NOT_FOUND) +# # request.data['discharge_date']=date.today() +# # Ha = get_object_or_404(Hospital_admit,id=pk) +# # serializer = serializers.HospitalAdmitSerializer(Ha,data=request.data,partial=True) +# # if serializer.is_valid(): +# # serializer.save() +# # return Response(serializer.data, status=status.HTTP_201_CREATED) +# # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - elif 'medicineadd' in request.data and request.method =='POST': - stock = serializers.StockSerializer(data=request.data) - if stock.is_valid(): - stock.save() - else: - return Response(stock.errors,status=status.HTTP_400_BAD_REQUEST) - request.data['medicine_id'] = (Stock.objects.get(medicine_name=request.data['medicine_name'])).id - expiry = serializers.ExpirySerializer(data=request.data) - if expiry.is_valid(): - expiry.save() - else: - return Response(expiry.errors,status=status.HTTP_400_BAD_REQUEST) - return Response(stock.data,status=status.HTTP_201_CREATED) +# elif 'medicineadd' in request.data and request.method =='POST': +# stock = serializers.StockSerializer(data=request.data) +# if stock.is_valid(): +# stock.save() +# else: +# return Response(stock.errors,status=status.HTTP_400_BAD_REQUEST) +# request.data['medicine_id'] = (Stock.objects.get(medicine_name=request.data['medicine_name'])).id +# expiry = serializers.ExpirySerializer(data=request.data) +# if expiry.is_valid(): +# expiry.save() +# else: +# return Response(expiry.errors,status=status.HTTP_400_BAD_REQUEST) +# return Response(stock.data,status=status.HTTP_201_CREATED) - elif 'stockadd' in request.data and request.method == 'POST': - serializer = serializers.ExpirySerializer(data=request.data) - if serializer.is_valid(): - serializer.save() - else: - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - quantity = (Stock.objects.get(id=request.data['medicine_id'])).quantity - quantity = quantity + int(request.data['quantity']) - stock = get_object_or_404(Stock,id=request.data['medicine_id']) - serializer = serializers.StockSerializer(stock,data={'quantity': quantity,'threshold':request.data['threshold']},partial=True) - if serializer.is_valid(): - serializer.save() - else: - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - resp = {'message': 'stock added successfully'} - return Response(data=resp,status=status.HTTP_200_OK) +# elif 'stockadd' in request.data and request.method == 'POST': +# serializer = serializers.ExpirySerializer(data=request.data) +# if serializer.is_valid(): +# serializer.save() +# else: +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# quantity = (Stock.objects.get(id=request.data['medicine_id'])).quantity +# quantity = quantity + int(request.data['quantity']) +# stock = get_object_or_404(Stock,id=request.data['medicine_id']) +# serializer = serializers.StockSerializer(stock,data={'quantity': quantity,'threshold':request.data['threshold']},partial=True) +# if serializer.is_valid(): +# serializer.save() +# else: +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# resp = {'message': 'stock added successfully'} +# return Response(data=resp,status=status.HTTP_200_OK) - elif 'prescriptionsubmit' in request.data and request.method == 'POST': - serializer = serializers.PrescriptionSerializer(data=request.data) - user = ExtraInfo.objects.get(id=request.data['user_id']) - if serializer.is_valid(): - serializer.save() - healthcare_center_notif(request.user, user.user, 'Presc') - return Response(serializer.data, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# elif 'prescriptionsubmit' in request.data and request.method == 'POST': +# serializer = serializers.PrescriptionSerializer(data=request.data) +# user = ExtraInfo.objects.get(id=request.data['user_id']) +# if serializer.is_valid(): +# serializer.save() +# healthcare_center_notif(request.user, user.user, 'Presc') +# return Response(serializer.data, status=status.HTTP_201_CREATED) +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - elif 'prescripmedicineadd' in request.data and request.method == 'POST': - with transaction.atomic(): - medicine_id=request.data['medicine_id'] - quantity = int(request.data['quantity']) - expiry=Expiry.objects.filter(medicine_id=medicine_id,quantity__gt=0,returned=False,expiry_date__gte=date.today()).order_by('expiry_date') - stock=(Stock.objects.get(id=medicine_id)).quantity - if stock>quantity: - for e in expiry: - q=e.quantity - em=e.id - if q>quantity: - q=q-quantity - Expiry.objects.filter(id=em).update(quantity=q) - qty = Stock.objects.get(id=medicine_id).quantity - qty = qty-quantity - Stock.objects.filter(id=medicine_id).update(quantity=qty) - break - else: - quan=Expiry.objects.get(id=em).quantity - Expiry.objects.filter(id=em).update(quantity=0) - qty = Stock.objects.get(id=medicine_id).quantity - qty = qty-quan - Stock.objects.filter(id=medicine_id).update(quantity=qty) - quantity=quantity-quan - serializer = serializers.PrescribedMedicineSerializer(data=request.data) - if serializer.is_valid(): - serializer.save() - return Response(serializer.data,status=status.HTTP_200_OK) - else: - transaction.set_rollback(True) - return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST) - else: - resp= {'message': 'Required Medicines is not available'} - return Response(data=resp,status=status.HTTP_400_BAD_REQUEST) +# elif 'prescripmedicineadd' in request.data and request.method == 'POST': +# with transaction.atomic(): +# medicine_id=request.data['medicine_id'] +# quantity = int(request.data['quantity']) +# expiry=Expiry.objects.filter(medicine_id=medicine_id,quantity__gt=0,returned=False,expiry_date__gte=date.today()).order_by('expiry_date') +# stock=(Stock.objects.get(id=medicine_id)).quantity +# if stock>quantity: +# for e in expiry: +# q=e.quantity +# em=e.id +# if q>quantity: +# q=q-quantity +# Expiry.objects.filter(id=em).update(quantity=q) +# qty = Stock.objects.get(id=medicine_id).quantity +# qty = qty-quantity +# Stock.objects.filter(id=medicine_id).update(quantity=qty) +# break +# else: +# quan=Expiry.objects.get(id=em).quantity +# Expiry.objects.filter(id=em).update(quantity=0) +# qty = Stock.objects.get(id=medicine_id).quantity +# qty = qty-quan +# Stock.objects.filter(id=medicine_id).update(quantity=qty) +# quantity=quantity-quan +# serializer = serializers.PrescribedMedicineSerializer(data=request.data) +# if serializer.is_valid(): +# serializer.save() +# return Response(serializer.data,status=status.HTTP_200_OK) +# else: +# transaction.set_rollback(True) +# return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST) +# else: +# resp= {'message': 'Required Medicines is not available'} +# return Response(data=resp,status=status.HTTP_400_BAD_REQUEST) - elif 'complaintresponse' in request.data and request.method == 'PATCH': - try: - pk = request.data['complaint_id'] - except: - return Response({'message': 'Please enter valid complaint id'}, status=status.HTTP_404_NOT_FOUND) - try: - complain = Complaint.objects.get(id = pk) - except Complaint.DoesNotExist: - return Response({'message': 'Complaint does not exist'}, status=status.HTTP_404_NOT_FOUND) - serializer = serializers.ComplaintSerializer(complain,data=request.data,partial=True) - if serializer.is_valid(): - serializer.save() - return Response(serializer.data, status=status.HTTP_201_CREATED) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - else: - resp = {'message': 'invalid request'} - return Response(data=resp,status=status.HTTP_404_NOT_FOUND) +# elif 'complaintresponse' in request.data and request.method == 'PATCH': +# try: +# pk = request.data['complaint_id'] +# except: +# return Response({'message': 'Please enter valid complaint id'}, status=status.HTTP_404_NOT_FOUND) +# try: +# complain = Complaint.objects.get(id = pk) +# except Complaint.DoesNotExist: +# return Response({'message': 'Complaint does not exist'}, status=status.HTTP_404_NOT_FOUND) +# serializer = serializers.ComplaintSerializer(complain,data=request.data,partial=True) +# if serializer.is_valid(): +# serializer.save() +# return Response(serializer.data, status=status.HTTP_201_CREATED) +# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +# else: +# resp = {'message': 'invalid request'} +# return Response(data=resp,status=status.HTTP_404_NOT_FOUND) - else: - resp = {'message': 'invalid request'} - return Response(data=resp,status=status.HTTP_404_NOT_FOUND) +# else: +# resp = {'message': 'invalid request'} +# return Response(data=resp,status=status.HTTP_404_NOT_FOUND) -@api_view(['GET']) -@permission_classes([IsAuthenticated]) -@authentication_classes([TokenAuthentication]) -def compounder_view_api(request): # compounder view starts here - # usertype = ExtraInfo.objects.get(user=request.user).user_type - design = getDesignation(request) - if 'Compounder' in design: - all_complaints = serializers.ComplaintSerializer(Complaint.objects.all(),many=True).data - # all_hospitals = serializers.HospitalAdmitSerializer(Hospital_admit.objects.all().order_by('-admission_date'),many=True).data - # hospitals_list = serializers.HospitalSerializer(Hospital.objects.all().order_by('hospital_name'),many=True).data - # all_ambulances = serializers.AmbulanceRequestSerializer(Ambulance_request.objects.all().order_by('-date_request'),many=True).data - # appointments_today = serializers.AppointmentSerializer(Appointment.objects.filter(date=datetime.now()).order_by('date'),many=True).data - # appointments_future= serializers.AppointmentSerializer(Appointment.objects.filter(date__gt=datetime.now()).order_by('date'),many=True).data - stocks = serializers.StockSerializer(Stock.objects.all(),many=True).data - days = Constants.DAYS_OF_WEEK - # schedule= serializers.ScheduleSerializer(Doctors_Schedule.objects.all().order_by('doctor_id'),many=True).data - expired= serializers.ExpirySerializer(Expiry.objects.filter(expiry_date__lt=datetime.now(),returned=False).order_by('expiry_date'),many=True).data - live_meds= serializers.ExpirySerializer(Expiry.objects.filter(returned=False).order_by('quantity'),many=True).data - count= Counter.objects.all() - presc_hist= serializers.PrescriptionSerializer(Prescription.objects.all().order_by('-date'),many=True).data - medicines_presc= serializers.PrescribedMedicineSerializer(Prescribed_medicine.objects.all(),many=True).data +# @api_view(['GET']) +# @permission_classes([IsAuthenticated]) +# @authentication_classes([TokenAuthentication]) +# def compounder_view_api(request): # compounder view starts here +# # usertype = ExtraInfo.objects.get(user=request.user).user_type +# design = getDesignation(request) +# if 'Compounder' in design: +# all_complaints = serializers.ComplaintSerializer(Complaint.objects.all(),many=True).data +# # all_hospitals = serializers.HospitalAdmitSerializer(Hospital_admit.objects.all().order_by('-admission_date'),many=True).data +# # hospitals_list = serializers.HospitalSerializer(Hospital.objects.all().order_by('hospital_name'),many=True).data +# # all_ambulances = serializers.AmbulanceRequestSerializer(Ambulance_request.objects.all().order_by('-date_request'),many=True).data +# # appointments_today = serializers.AppointmentSerializer(Appointment.objects.filter(date=datetime.now()).order_by('date'),many=True).data +# # appointments_future= serializers.AppointmentSerializer(Appointment.objects.filter(date__gt=datetime.now()).order_by('date'),many=True).data +# stocks = serializers.StockSerializer(Stock.objects.all(),many=True).data +# days = Constants.DAYS_OF_WEEK +# # schedule= serializers.ScheduleSerializer(Doctors_Schedule.objects.all().order_by('doctor_id'),many=True).data +# expired= serializers.ExpirySerializer(Expiry.objects.filter(expiry_date__lt=datetime.now(),returned=False).order_by('expiry_date'),many=True).data +# live_meds= serializers.ExpirySerializer(Expiry.objects.filter(returned=False).order_by('quantity'),many=True).data +# count= Counter.objects.all() +# presc_hist= serializers.PrescriptionSerializer(Prescription.objects.all().order_by('-date'),many=True).data +# medicines_presc= serializers.PrescribedMedicineSerializer(Prescribed_medicine.objects.all(),many=True).data - if count: - Counter.objects.all().delete() - Counter.objects.create(count=0,fine=0) - count= serializers.CounterSerializer(Counter.objects.get()).data - # hospitals=serializers.HospitalSerializer(Hospital.objects.all(),many=True).data - doctor_schedule=serializers.DoctorsScheduleSerializer(Doctors_Schedule.objects.all().order_by('doctor_id'),many=True).data - pathologist_schedule=serializers.PathologistScheduleSerializer(Pathologist_Schedule.objects.all().order_by('pathologist_id'), many=True).data - doctors=serializers.DoctorSerializer(Doctor.objects.filter(active=True),many=True).data - pathologists=serializers.PathologistSerializer(Pathologist.objects.filter(active=True),many=True).data +# if count: +# Counter.objects.all().delete() +# Counter.objects.create(count=0,fine=0) +# count= serializers.CounterSerializer(Counter.objects.get()).data +# # hospitals=serializers.HospitalSerializer(Hospital.objects.all(),many=True).data +# doctor_schedule=serializers.DoctorsScheduleSerializer(Doctors_Schedule.objects.all().order_by('doctor_id'),many=True).data +# pathologist_schedule=serializers.PathologistScheduleSerializer(Pathologist_Schedule.objects.all().order_by('pathologist_id'), many=True).data +# doctors=serializers.DoctorSerializer(Doctor.objects.filter(active=True),many=True).data +# pathologists=serializers.PathologistSerializer(Pathologist.objects.filter(active=True),many=True).data - resp= { - 'days': days, - 'count': count, - 'expired':expired, - 'stocks': stocks, - 'all_complaints': all_complaints, - # 'all_hospitals': all_hospitals, - # 'hospitals':hospitals, - # 'all_ambulances': all_ambulances, - # 'appointments_today': appointments_today, - 'doctors': doctors, - # 'appointments_future': appointments_future, - # 'schedule': schedule, - 'doctor_schedule': doctor_schedule, - 'pathologist_schedule': pathologist_schedule, - 'pathologists': pathologists, - 'live_meds': live_meds, - 'presc_hist': presc_hist, - 'medicines_presc': medicines_presc, - # 'hospitals_list': hospitals_list - } - return Response(data=resp,status=status.HTTP_200_OK) +# resp= { +# 'days': days, +# 'count': count, +# 'expired':expired, +# 'stocks': stocks, +# 'all_complaints': all_complaints, +# # 'all_hospitals': all_hospitals, +# # 'hospitals':hospitals, +# # 'all_ambulances': all_ambulances, +# # 'appointments_today': appointments_today, +# 'doctors': doctors, +# # 'appointments_future': appointments_future, +# # 'schedule': schedule, +# 'doctor_schedule': doctor_schedule, +# 'pathologist_schedule': pathologist_schedule, +# 'pathologists': pathologists, +# 'live_meds': live_meds, +# 'presc_hist': presc_hist, +# 'medicines_presc': medicines_presc, +# # 'hospitals_list': hospitals_list +# } +# return Response(data=resp,status=status.HTTP_200_OK) - else: - resp = {'message': 'invalid request'} - return Response(data=resp,status=status.HTTP_404_NOT_FOUND) # compounder view ends \ No newline at end of file +# else: +# resp = {'message': 'invalid request'} +# return Response(data=resp,status=status.HTTP_404_NOT_FOUND) # compounder view ends \ No newline at end of file diff --git a/FusionIIIT/applications/health_center/migrations/0001_initial.py b/FusionIIIT/applications/health_center/migrations/0001_initial.py index 072d80def..887666ff8 100644 --- a/FusionIIIT/applications/health_center/migrations/0001_initial.py +++ b/FusionIIIT/applications/health_center/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-27 23:48 import datetime from django.db import migrations, models @@ -28,7 +28,7 @@ class Migration(migrations.Migration): name='Doctor', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('doctor_name', models.CharField(choices=[(0, 'Dr.Sharma'), (1, 'Dr.Vinay')], max_length=50)), + ('doctor_name', models.CharField(max_length=50)), ('doctor_phone', models.CharField(max_length=15)), ('specialization', models.CharField(max_length=100)), ('active', models.BooleanField(default=True)), @@ -57,7 +57,7 @@ class Migration(migrations.Migration): name='Pathologist', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('pathologist_name', models.CharField(choices=[(0, 'Dr.Ajay'), (1, 'Dr.Rahul')], max_length=50)), + ('pathologist_name', models.CharField(max_length=50)), ('pathologist_phone', models.CharField(max_length=15)), ('specialization', models.CharField(max_length=100)), ('active', models.BooleanField(default=True)), @@ -132,6 +132,18 @@ class Migration(migrations.Migration): ('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), ], ), + migrations.CreateModel( + name='MedicalProfile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date_of_birth', models.DateField()), + ('gender', models.CharField(choices=[('M', 'Male'), ('F', 'Female'), ('O', 'Other')], max_length=1)), + ('blood_type', models.CharField(choices=[('A+', 'A+'), ('A-', 'A-'), ('B+', 'B+'), ('B-', 'B-'), ('AB+', 'AB+'), ('AB-', 'AB-'), ('O+', 'O+'), ('O-', 'O-')], max_length=3)), + ('height', models.DecimalField(decimal_places=2, max_digits=5)), + ('weight', models.DecimalField(decimal_places=2, max_digits=5)), + ('user_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), + ], + ), migrations.CreateModel( name='Hospital_admit', fields=[ @@ -197,9 +209,6 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('ann_date', models.DateTimeField(default='04-04-2021')), ('message', models.CharField(max_length=200)), - ('batch', models.CharField(default='Year-1', max_length=40)), - ('department', models.CharField(default='ALL', max_length=40)), - ('programme', models.CharField(max_length=10)), ('upload_announcement', models.FileField(default=' ', null=True, upload_to='health_center/upload_announcement')), ('anno_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='announcements_made', to='globals.extrainfo')), ], diff --git a/FusionIIIT/applications/health_center/migrations/0002_auto_20240710_2356.py b/FusionIIIT/applications/health_center/migrations/0002_auto_20240710_2356.py new file mode 100644 index 000000000..9a50335f6 --- /dev/null +++ b/FusionIIIT/applications/health_center/migrations/0002_auto_20240710_2356.py @@ -0,0 +1,201 @@ +# Generated by Django 3.1.5 on 2024-07-10 23:56 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('health_center', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='All_Medicine', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('medicine_name', models.CharField(default='NOT_SET', max_length=50)), + ('brand_name', models.CharField(default='NOT_SET', max_length=50)), + ('constituents', models.TextField(default='NOT_SET')), + ('manufacturer_name', models.CharField(default='NOT_SET', max_length=50)), + ('pack_size_label', models.CharField(default='NOT_SET', max_length=50)), + ], + ), + migrations.CreateModel( + name='All_Prescribed_medicine', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('quantity', models.IntegerField(default=0)), + ('days', models.IntegerField(default=0)), + ('times', models.IntegerField(default=0)), + ('revoked', models.BooleanField(default=False)), + ('revoked_date', models.DateField(null=True)), + ('medicine_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='health_center.all_medicine')), + ], + ), + migrations.CreateModel( + name='All_Prescription', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('user_id', models.CharField(max_length=15)), + ('details', models.TextField(null=True)), + ('date', models.DateField()), + ('suggestions', models.TextField(null=True)), + ('test', models.CharField(blank=True, max_length=200, null=True)), + ('file_id', models.IntegerField(default=0)), + ('is_dependent', models.BooleanField(default=False)), + ('dependent_name', models.CharField(default='SELF', max_length=30)), + ('dependent_relation', models.CharField(default='SELF', max_length=20)), + ('doctor_id', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='health_center.doctor')), + ], + ), + migrations.CreateModel( + name='Prescription_followup', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('details', models.TextField(null=True)), + ('date', models.DateField()), + ('test', models.CharField(blank=True, max_length=200, null=True)), + ('suggestions', models.TextField(null=True)), + ('file_id', models.IntegerField(default=0)), + ('Doctor_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='health_center.doctor')), + ('prescription_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='health_center.all_prescription')), + ], + ), + migrations.CreateModel( + name='Present_Stock', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('quantity', models.IntegerField(default=0)), + ], + ), + migrations.CreateModel( + name='Stock_entry', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('quantity', models.IntegerField(default=0)), + ('supplier', models.CharField(default='NOT_SET', max_length=50)), + ('Expiry_date', models.DateField()), + ('date', models.DateField(auto_now=True)), + ('medicine_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='health_center.all_medicine')), + ], + ), + migrations.RemoveField( + model_name='ambulance_request', + name='user_id', + ), + migrations.RemoveField( + model_name='announcements', + name='anno_id', + ), + migrations.RemoveField( + model_name='appointment', + name='doctor_id', + ), + migrations.RemoveField( + model_name='appointment', + name='schedule', + ), + migrations.RemoveField( + model_name='appointment', + name='user_id', + ), + migrations.RemoveField( + model_name='complaint', + name='user_id', + ), + migrations.DeleteModel( + name='Counter', + ), + migrations.RemoveField( + model_name='expiry', + name='medicine_id', + ), + migrations.RemoveField( + model_name='hospital_admit', + name='doctor_id', + ), + migrations.RemoveField( + model_name='hospital_admit', + name='hospital_name', + ), + migrations.RemoveField( + model_name='hospital_admit', + name='user_id', + ), + migrations.RemoveField( + model_name='medicine', + name='medicine_id', + ), + migrations.RemoveField( + model_name='medicine', + name='patient', + ), + migrations.RemoveField( + model_name='prescribed_medicine', + name='medicine_id', + ), + migrations.RemoveField( + model_name='prescribed_medicine', + name='prescription_id', + ), + migrations.RemoveField( + model_name='prescription', + name='doctor_id', + ), + migrations.RemoveField( + model_name='prescription', + name='user_id', + ), + migrations.RemoveField( + model_name='specialrequest', + name='request_ann_maker', + ), + migrations.DeleteModel( + name='Ambulance_request', + ), + migrations.DeleteModel( + name='Announcements', + ), + migrations.DeleteModel( + name='Appointment', + ), + migrations.DeleteModel( + name='Complaint', + ), + migrations.DeleteModel( + name='Expiry', + ), + migrations.DeleteModel( + name='Hospital', + ), + migrations.DeleteModel( + name='Hospital_admit', + ), + migrations.DeleteModel( + name='Medicine', + ), + migrations.DeleteModel( + name='Prescribed_medicine', + ), + migrations.DeleteModel( + name='Prescription', + ), + migrations.DeleteModel( + name='SpecialRequest', + ), + migrations.DeleteModel( + name='Stock', + ), + migrations.AddField( + model_name='present_stock', + name='stock_id', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='health_center.stock_entry'), + ), + migrations.AddField( + model_name='all_prescribed_medicine', + name='prescription_id', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='health_center.all_prescription'), + ), + ] diff --git a/FusionIIIT/applications/health_center/migrations/0003_all_medicine_threshold.py b/FusionIIIT/applications/health_center/migrations/0003_all_medicine_threshold.py new file mode 100644 index 000000000..bfc404d98 --- /dev/null +++ b/FusionIIIT/applications/health_center/migrations/0003_all_medicine_threshold.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.5 on 2024-07-11 15:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('health_center', '0002_auto_20240710_2356'), + ] + + operations = [ + migrations.AddField( + model_name='all_medicine', + name='threshold', + field=models.IntegerField(default=100), + ), + ] diff --git a/FusionIIIT/applications/health_center/migrations/0004_auto_20240713_1159.py b/FusionIIIT/applications/health_center/migrations/0004_auto_20240713_1159.py new file mode 100644 index 000000000..bed6b2da1 --- /dev/null +++ b/FusionIIIT/applications/health_center/migrations/0004_auto_20240713_1159.py @@ -0,0 +1,32 @@ +# Generated by Django 3.1.5 on 2024-07-13 11:59 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('health_center', '0003_all_medicine_threshold'), + ] + + operations = [ + migrations.AddField( + model_name='all_prescribed_medicine', + name='stock', + field=models.ForeignKey(default='1', on_delete=django.db.models.deletion.CASCADE, to='health_center.present_stock'), + preserve_default=False, + ), + migrations.AddField( + model_name='present_stock', + name='Expiry_date', + field=models.DateField(default='2024-04-12'), + preserve_default=False, + ), + migrations.AddField( + model_name='present_stock', + name='medicine_id', + field=models.ForeignKey(default='1', on_delete=django.db.models.deletion.CASCADE, to='health_center.all_medicine'), + preserve_default=False, + ), + ] diff --git a/FusionIIIT/applications/health_center/migrations/0005_all_prescribed_medicine_prescription_followup_id.py b/FusionIIIT/applications/health_center/migrations/0005_all_prescribed_medicine_prescription_followup_id.py new file mode 100644 index 000000000..2619ec86a --- /dev/null +++ b/FusionIIIT/applications/health_center/migrations/0005_all_prescribed_medicine_prescription_followup_id.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1.5 on 2024-07-15 00:19 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('health_center', '0004_auto_20240713_1159'), + ] + + operations = [ + migrations.AddField( + model_name='all_prescribed_medicine', + name='prescription_followup_id', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='health_center.prescription_followup'), + ), + ] diff --git a/FusionIIIT/applications/health_center/migrations/0006_auto_20240717_1943.py b/FusionIIIT/applications/health_center/migrations/0006_auto_20240717_1943.py new file mode 100644 index 000000000..42e9f1974 --- /dev/null +++ b/FusionIIIT/applications/health_center/migrations/0006_auto_20240717_1943.py @@ -0,0 +1,49 @@ +# Generated by Django 3.1.5 on 2024-07-17 19:43 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('health_center', '0005_all_prescribed_medicine_prescription_followup_id'), + ] + + operations = [ + migrations.AlterField( + model_name='all_medicine', + name='brand_name', + field=models.CharField(default='NOT_SET', max_length=1000, null=True), + ), + migrations.AlterField( + model_name='all_medicine', + name='constituents', + field=models.TextField(default='NOT_SET', null=True), + ), + migrations.AlterField( + model_name='all_medicine', + name='manufacturer_name', + field=models.CharField(default='NOT_SET', max_length=1000, null=True), + ), + migrations.AlterField( + model_name='all_medicine', + name='medicine_name', + field=models.CharField(default='NOT_SET', max_length=1000, null=True), + ), + migrations.AlterField( + model_name='all_medicine', + name='pack_size_label', + field=models.CharField(default='NOT_SET', max_length=1000, null=True), + ), + migrations.AlterField( + model_name='all_medicine', + name='threshold', + field=models.IntegerField(default=0, null=True), + ), + migrations.AlterField( + model_name='prescription_followup', + name='Doctor_id', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='health_center.doctor'), + ), + ] diff --git a/FusionIIIT/applications/health_center/migrations/0007_auto_20240719_0031.py b/FusionIIIT/applications/health_center/migrations/0007_auto_20240719_0031.py new file mode 100644 index 000000000..cbc2ab6fa --- /dev/null +++ b/FusionIIIT/applications/health_center/migrations/0007_auto_20240719_0031.py @@ -0,0 +1,26 @@ +# Generated by Django 3.1.5 on 2024-07-19 00:31 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('health_center', '0006_auto_20240717_1943'), + ] + + operations = [ + migrations.CreateModel( + name='files', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('file_data', models.BinaryField()), + ], + ), + migrations.AddField( + model_name='all_prescribed_medicine', + name='revoked_priscription', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='revoked_priscription', to='health_center.prescription_followup'), + ), + ] diff --git a/FusionIIIT/applications/health_center/migrations/0008_required_medicine.py b/FusionIIIT/applications/health_center/migrations/0008_required_medicine.py new file mode 100644 index 000000000..a21ca45da --- /dev/null +++ b/FusionIIIT/applications/health_center/migrations/0008_required_medicine.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.5 on 2024-07-21 11:09 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('health_center', '0007_auto_20240719_0031'), + ] + + operations = [ + migrations.CreateModel( + name='Required_medicine', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('quantity', models.IntegerField()), + ('threshold', models.IntegerField()), + ('medicine_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='health_center.all_medicine')), + ], + ), + ] diff --git a/FusionIIIT/applications/health_center/migrations/0009_auto_20240721_2316.py b/FusionIIIT/applications/health_center/migrations/0009_auto_20240721_2316.py new file mode 100644 index 000000000..1c604c5c3 --- /dev/null +++ b/FusionIIIT/applications/health_center/migrations/0009_auto_20240721_2316.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.5 on 2024-07-21 23:16 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('health_center', '0008_required_medicine'), + ] + + operations = [ + migrations.RenameField( + model_name='all_prescribed_medicine', + old_name='revoked_priscription', + new_name='revoked_prescription', + ), + ] diff --git a/FusionIIIT/applications/health_center/migrations/0010_auto_20240727_2352.py b/FusionIIIT/applications/health_center/migrations/0010_auto_20240727_2352.py new file mode 100644 index 000000000..ad10be188 --- /dev/null +++ b/FusionIIIT/applications/health_center/migrations/0010_auto_20240727_2352.py @@ -0,0 +1,26 @@ +# Generated by Django 3.1.5 on 2024-07-27 23:52 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('health_center', '0009_auto_20240721_2316'), + ] + + operations = [ + migrations.CreateModel( + name='Required_tabel_last_updated', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ], + ), + migrations.AlterField( + model_name='all_prescribed_medicine', + name='stock', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='health_center.present_stock'), + ), + ] diff --git a/FusionIIIT/applications/health_center/models.py b/FusionIIIT/applications/health_center/models.py index 534abb438..7f46307f0 100644 --- a/FusionIIIT/applications/health_center/models.py +++ b/FusionIIIT/applications/health_center/models.py @@ -4,11 +4,10 @@ from django.contrib.auth.models import User from applications.globals.models import ExtraInfo - +from applications.hr2.models import EmpDependents # Create your models here. - class Constants: DAYS_OF_WEEK = ( (0, 'Monday'), @@ -50,52 +49,51 @@ class Pathologist(models.Model): def __str__(self): return self.pathologist_name +# class Complaint(models.Model): +# user_id = models.ForeignKey(ExtraInfo,on_delete=models.CASCADE) +# feedback = models.CharField(max_length=100, null=True, blank=False) #This is the feedback given by the compounder +# complaint = models.CharField(max_length=100, null=True, blank=False) #Here Complaint given by user cannot be NULL! +# date = models.DateField(auto_now=True) -class Complaint(models.Model): - user_id = models.ForeignKey(ExtraInfo,on_delete=models.CASCADE) - feedback = models.CharField(max_length=100, null=True, blank=False) #This is the feedback given by the compounder - complaint = models.CharField(max_length=100, null=True, blank=False) #Here Complaint given by user cannot be NULL! - date = models.DateField(auto_now=True) - +class All_Medicine(models.Model): + medicine_name = models.CharField(max_length=1000,default="NOT_SET", null=True) + brand_name = models.CharField(max_length=1000,default="NOT_SET", null=True) + constituents = models.TextField(default="NOT_SET", null=True) + manufacturer_name = models.CharField(max_length=1000,default="NOT_SET", null=True) + threshold = models.IntegerField(default=0, null=True) + pack_size_label = models.CharField(max_length=1000,default="NOT_SET", null=True) -class Stock(models.Model): - medicine_name = models.CharField(max_length=100) + def __str__(self): + return self.brand_name + +class Stock_entry(models.Model): + medicine_id = models.ForeignKey(All_Medicine, on_delete=models.CASCADE) quantity = models.IntegerField(default=0) - threshold = models.IntegerField(default=10) + supplier = models.CharField(max_length=50,default="NOT_SET") + Expiry_date = models.DateField() + date = models.DateField(auto_now=True) # generic_name = models.CharField(max_length=80) - def __str__(self): - return self.medicine_name + return self.medicine_id.medicine_name + +class Required_medicine(models.Model): + medicine_id = models.ForeignKey(All_Medicine,on_delete = models.CASCADE) + quantity = models.IntegerField() + threshold = models.IntegerField() -class Medicine(models.Model): - patient = models.ForeignKey(ExtraInfo,on_delete=models.CASCADE) - medicine_id = models.ForeignKey(Stock,on_delete=models.CASCADE) +class Present_Stock(models.Model): quantity = models.IntegerField(default=0) - days = models.IntegerField(default=0) - times = models.IntegerField(default=0) + stock_id = models.ForeignKey(Stock_entry,on_delete=models.CASCADE) + medicine_id = models.ForeignKey(All_Medicine, on_delete=models.CASCADE) + Expiry_date =models.DateField() - def __str__(self): - return self.medicine_id - -class Hospital(models.Model): - hospital_name=models.CharField(max_length=100) - phone=models.CharField(max_length=10) - def __str__(self): - return self.hospital_name + # generic_name = models.CharField(max_length=80) -class Expiry(models.Model): - medicine_id=models.ForeignKey(Stock,on_delete=models.CASCADE) - quantity = models.IntegerField(default=0) - supplier=models.CharField(max_length=50) - expiry_date=models.DateField() - returned=models.BooleanField(default=False) - return_date=models.DateField(null=True,blank=True) - date=models.DateField(auto_now=True) def __str__(self): - return self.medicine_id.medicine_name + return str(self.Expiry_date) class Doctors_Schedule(models.Model): doctor_id = models.ForeignKey(Doctor,on_delete=models.CASCADE) @@ -115,117 +113,48 @@ class Pathologist_Schedule(models.Model): room = models.IntegerField() date = models.DateField(auto_now=True) - -class Counter(models.Model): - count=models.IntegerField(default=0) - fine=models.IntegerField(default=0) - doc_count=models.IntegerField(default=0) - patho_count=models.IntegerField(default=0) - - def doctor_count(self): - self.doc_count+=1 - return "" - def pathologist_count(self): - self.doc_count+=1 - return "" - def increment(self): - self.count+=1 - return "" - def increment_fine(self): - self.fine+=1 - return "" - def range_count(self): - if self.count==0: - dif=0 - elif self.count<=4: - dif=self.doc_count-self.count - elif self.count<=4: - dif=self.count-self.doc_count - elif self.count<=4: - dif=self.patho_count-self.count - else: - dif=self.count-self.patho_count - return range(dif) - def empty_fine(self): - self.count=0 - self.fine=0 - return "" - def empty_count(self): - self.count=0 - return "" - -class Appointment(models.Model): - user_id = models.ForeignKey(ExtraInfo,on_delete=models.CASCADE) - doctor_id = models.ForeignKey(Doctor,on_delete=models.CASCADE) - description = models.CharField(max_length=50) - schedule = models.ForeignKey(Doctors_Schedule, on_delete=models.CASCADE,null=True, blank=True) - date = models.DateField() - - def __str__(self): - return self.description - - -class Prescription(models.Model): - user_id = models.ForeignKey(ExtraInfo,on_delete=models.CASCADE) +class All_Prescription(models.Model): + user_id = models.CharField(max_length=15) doctor_id = models.ForeignKey(Doctor, on_delete=models.CASCADE,null=True, blank=True) - details = models.CharField(max_length=100) + details = models.TextField(null=True) date = models.DateField() + suggestions = models.TextField(null=True) test = models.CharField(max_length=200, null=True, blank=True) file_id=models.IntegerField(default=0) + is_dependent = models.BooleanField(default=False) + dependent_name = models.CharField(max_length=30,default="SELF") + dependent_relation = models.CharField(max_length=20,default="SELF") # appointment = models.ForeignKey(Appointment, on_delete=models.CASCADE,null=True, blank=True) def __str__(self): - return self.details + return self.user_id - -class Prescribed_medicine(models.Model): - prescription_id = models.ForeignKey(Prescription,on_delete=models.CASCADE) - medicine_id = models.ForeignKey(Stock,on_delete=models.CASCADE) +class Prescription_followup(models.Model): + prescription_id=models.ForeignKey(All_Prescription,on_delete=models.CASCADE) + details = models.TextField(null=True) + date = models.DateField() + test = models.CharField(max_length=200, null=True, blank=True) + suggestions = models.TextField(null=True) + Doctor_id = models.ForeignKey(Doctor,on_delete=models.CASCADE, null=True, blank=True) + file_id=models.IntegerField(default=0) +class All_Prescribed_medicine(models.Model): + prescription_id = models.ForeignKey(All_Prescription,on_delete=models.CASCADE) + medicine_id = models.ForeignKey(All_Medicine,on_delete=models.CASCADE) + stock = models.ForeignKey(Present_Stock,on_delete=models.CASCADE,null=True) + prescription_followup_id = models.ForeignKey(Prescription_followup,on_delete=models.CASCADE,null=True) quantity = models.IntegerField(default=0) days = models.IntegerField(default=0) times = models.IntegerField(default=0) + revoked = models.BooleanField(default=False) + revoked_date = models.DateField(null=True) + revoked_prescription = models.ForeignKey(Prescription_followup,on_delete=models.CASCADE,null=True,related_name="revoked_priscription") def __str__(self): return self.medicine_id.medicine_name - - -class Ambulance_request(models.Model): - user_id = models.ForeignKey(ExtraInfo,on_delete=models.CASCADE) - date_request = models.DateTimeField() - start_date = models.DateField() - end_date = models.DateField(null=True, blank=True) - reason = models.CharField(max_length=50) - -class Hospital_admit(models.Model): - user_id = models.ForeignKey(ExtraInfo,on_delete=models.CASCADE) - doctor_id = models.ForeignKey(Doctor, on_delete=models.CASCADE,null=True, blank=True) - hospital_doctor = models.CharField(max_length=100) - hospital_name = models.ForeignKey(Hospital,on_delete=models.CASCADE) - admission_date = models.DateField() - discharge_date = models.DateField(null=True, blank=True) - reason = models.CharField(max_length=50) - -class Announcements(models.Model): - anno_id = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE, related_name='announcements_made') - ann_date = models.DateTimeField(default="04-04-2021") - message = models.CharField(max_length=200) - upload_announcement = models.FileField(upload_to='health_center/upload_announcement', null=True, default=" ") - def __str__(self): - return str(self.anno_id.user.username) - - -class SpecialRequest(models.Model): - request_ann_maker = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE, related_name='special_requests_made') - request_date = models.DateTimeField(default=date.today) - 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') - remarks = models.CharField(max_length=300, default="--") - request_receiver = models.CharField(max_length=30, default="--") - - def __str__(self): - return str(self.request_ann_maker.user.username) +class Required_tabel_last_updated(models.Model): + date=models.DateField() +class files(models.Model): + file_data = models.BinaryField() class medical_relief(models.Model): description = models.CharField(max_length=200) @@ -256,4 +185,5 @@ class MedicalProfile(models.Model): ] blood_type = models.CharField(max_length=3, choices=blood_type_choices) height = models.DecimalField(max_digits=5, decimal_places=2) - weight = models.DecimalField(max_digits=5, decimal_places=2) \ No newline at end of file + weight = models.DecimalField(max_digits=5, decimal_places=2) + diff --git a/FusionIIIT/applications/health_center/static/health_center/add_medicine_example.xlsx b/FusionIIIT/applications/health_center/static/health_center/add_medicine_example.xlsx new file mode 100644 index 000000000..a1a53eae2 Binary files /dev/null and b/FusionIIIT/applications/health_center/static/health_center/add_medicine_example.xlsx differ diff --git a/FusionIIIT/applications/health_center/static/health_center/add_stock_example.xlsx b/FusionIIIT/applications/health_center/static/health_center/add_stock_example.xlsx new file mode 100644 index 000000000..09db7915e Binary files /dev/null and b/FusionIIIT/applications/health_center/static/health_center/add_stock_example.xlsx differ diff --git a/FusionIIIT/media/logo2.jpg b/FusionIIIT/applications/health_center/static/health_center/institute_logo.jpg similarity index 100% rename from FusionIIIT/media/logo2.jpg rename to FusionIIIT/applications/health_center/static/health_center/institute_logo.jpg diff --git a/FusionIIIT/applications/health_center/urls.py b/FusionIIIT/applications/health_center/urls.py index 2580313f9..982564fa2 100644 --- a/FusionIIIT/applications/health_center/urls.py +++ b/FusionIIIT/applications/health_center/urls.py @@ -7,10 +7,12 @@ urlpatterns = [ - #health_center home page + # health_center home page url(r'^$', healthcenter, name='healthcenter'), #views + url(r'^compounder/view_prescription/(?P[0-9]+)/$',compounder_view_prescription,name='view_prescription'), + url(r'^compounder/view_file/(?P[\w-]+)/$',view_file, name='view_file'), url(r'^compounder/$', compounder_view, name='compounder_view'), url(r'^student/$', student_view, name='student_view'), url(r'announcement/', announcement, name='announcement'), @@ -21,6 +23,6 @@ url(r'^doctor_entry', doctor_entry, name='doctor_entry'), url(r'^compounder_entry', compounder_entry, name='compounder_entry'), - #api - url(r'^api/',include('applications.health_center.api.urls')) + # #api + # url(r'^api/',include('applications.health_center.api.urls')) ] \ No newline at end of file diff --git a/FusionIIIT/applications/health_center/utils.py b/FusionIIIT/applications/health_center/utils.py index 9940ff024..220efea76 100644 --- a/FusionIIIT/applications/health_center/utils.py +++ b/FusionIIIT/applications/health_center/utils.py @@ -1,4 +1,7 @@ import json +import os +import pandas as pd +from django.db import transaction from datetime import datetime, timedelta,date from applications.globals.models import ExtraInfo from django.core import serializers @@ -6,13 +9,16 @@ from applications.globals.models import ExtraInfo, HoldsDesignation, Designation, DepartmentInfo from django.http import HttpResponse, JsonResponse from notification.views import healthcare_center_notif -from .models import (Ambulance_request, Appointment, Complaint, Doctor, - Expiry, Hospital, Hospital_admit, Medicine, - Prescribed_medicine, Prescription, Doctors_Schedule,Pathologist_Schedule, - Stock, Announcements, SpecialRequest, Pathologist, medical_relief, MedicalProfile) +from .models import ( Doctor, Stock_entry,Present_Stock,All_Medicine, + Doctors_Schedule,Pathologist_Schedule, + Pathologist, medical_relief, MedicalProfile,All_Prescription,All_Prescribed_medicine, + Prescription_followup,files,Required_medicine) from applications.filetracking.sdk.methods import * from django.core.exceptions import ObjectDoesNotExist from django.shortcuts import get_object_or_404 +from django.db.models import Q +from applications.globals.models import ExtraInfo +from applications.hr2.models import EmpDependents def datetime_handler(date): ''' @@ -27,16 +33,15 @@ def compounder_view_handler(request): ''' handles rendering of pages for compounder view ''' - # compounder response to patients feedback - if 'feed_com' in request.POST: + if 'feed_com' in request.POST: pk = request.POST.get('com_id') feedback = request.POST.get('feed') comp_id = ExtraInfo.objects.select_related('user','department').filter(user_type='compounder') Complaint.objects.select_related('user_id','user_id__user','user_id__department').filter(id=pk).update(feedback=feedback) data = {'feedback': feedback} for cmp in comp_id: - healthcare_center_notif(request.user, cmp.user, 'feedback_res') + healthcare_center_notif(request.user, cmp.user, 'feedback_res','') return JsonResponse(data) elif 'end' in request.POST: @@ -117,26 +122,75 @@ def compounder_view_handler(request): return JsonResponse(data) elif 'add_stock' in request.POST: - medicine = request.POST.get('medicine_id') - threshold_a = request.POST.get('threshold_a') - medicine_name = Stock.objects.get(id=medicine) - qty = int(request.POST.get('quantity')) - supplier=request.POST.get('supplier') - expiry=request.POST.get('expiry_date') - Expiry.objects.create( - medicine_id=medicine_name, - quantity=qty, - supplier=supplier, - expiry_date=expiry, - date=datetime.now(), - ) - quantity = (Stock.objects.get(id=medicine)).quantity - quantity = quantity + qty - Stock.objects.filter(id=medicine).update(quantity=quantity) - Stock.objects.filter(id=medicine).update(threshold=threshold_a) - data = {'status': 1} - return JsonResponse(data) - + try: + medicine = request.POST.get('medicine_id') + # threshold_a = request.POST.get('threshold_a') + med_brand_name = medicine.split(',')[0] + id = medicine.split(',')[1] + medicine_id = All_Medicine.objects.get(id = id) + qty = int(request.POST.get('quantity')) + supplier=request.POST.get('supplier') + expiry=request.POST.get('expiry_date') + tot_rows = Stock_entry.objects.all().count() + tot_rows1 = Present_Stock.objects.all().count() + stk=Stock_entry.objects.create( + id = tot_rows+1, + quantity=qty, + medicine_id=medicine_id, + supplier=supplier, + Expiry_date=expiry, + date=date.today() + ) + Present_Stock.objects.create( + id = tot_rows1+1, + quantity=qty, + stock_id=stk, + medicine_id=medicine_id, + Expiry_date=expiry + ) + if Required_medicine.objects.filter(medicine_id = medicine_id).exists(): + req=Required_medicine.objects.get(medicine_id = medicine_id) + req.quantity+=qty + if(req.quantity Req.threshold : + Req.delete() + else : Req.save() + else : + medicine_stock = Present_Stock.objects.filter(Q(medicine_id = threshold_med) & Q(Expiry_date__gt = date.today())) + qty=0 + for med in medicine_stock: + qty+=med.quantity + if qty < threshold_med.threshold : + Required_medicine.objects.create( + medicine_id = threshold_med, + quantity = qty, + threshold = threshold_med.threshold + ) + status=1 + except: + status=0 + finally: + data={'status':status} + return JsonResponse(data) # edit schedule for doctors elif 'edit_1' in request.POST: doctor = request.POST.get('doctor') @@ -199,27 +253,40 @@ def compounder_view_handler(request): elif 'add_medicine' in request.POST: medicine = request.POST.get('new_medicine') - quantity = request.POST.get('new_quantity') + # quantity = request.POST.get('new_quantity') threshold = request.POST.get('threshold') - new_supplier = request.POST.get('new_supplier') - new_expiry_date = request.POST.get('new_expiry_date') - Stock.objects.create( + brand_name = request.POST.get('brand_name') + constituents = request.POST.get('constituents') + manufacture_name = request.POST.get('manufacture_name') + packsize = request.POST.get('packsize') + # new_supplier = request.POST.get('new_supplier') + # new_expiry_date = request.POST.get('new_expiry_date') + tot_rows = All_Medicine.objects.all().count() + All_Medicine.objects.create( + id = tot_rows+1, medicine_name=medicine, - quantity=quantity, - threshold=threshold + brand_name=brand_name, + constituents=constituents, + threshold=threshold, + manufacturer_name=manufacture_name, + pack_size_label=packsize ) - medicine_id = Stock.objects.get(medicine_name=medicine) - Expiry.objects.create( - medicine_id=medicine_id, - quantity=quantity, - supplier=new_supplier, - expiry_date=new_expiry_date, - returned=False, - return_date=None, - date=datetime.now() - ) - data = {'medicine': medicine, 'quantity': quantity, 'threshold': threshold, - 'new_supplier': new_supplier, 'new_expiry_date': new_expiry_date } + # Stock.objects.create( + # medicine_name=medicine, + # quantity=quantity, + # threshold=threshold + # ) + # medicine_id = Stock.objects.get(medicine_name=medicine) + # Expiry.objects.create( + # medicine_id=medicine_id, + # quantity=quantity, + # supplier=new_supplier, + # expiry_date=new_expiry_date, + # returned=False, + # return_date=None, + # date=datetime.now() + # ) + data = {'medicine': medicine, 'threshold': threshold,} return JsonResponse(data) elif 'admission' in request.POST: @@ -245,63 +312,97 @@ def compounder_view_handler(request): data={'status':1} return JsonResponse(data) - elif 'medicine_name' in request.POST: - app = request.POST.get('user') - user = Appointment.objects.select_related('user_id','user_id__user','user_id__department','doctor_id','schedule','schedule__doctor_id').get(id=app).user_id - quantity = int(request.POST.get('quantity')) - days = int(request.POST.get('days')) - times = int(request.POST.get('times')) - medicine_id = request.POST.get('medicine_name') - medicine = Stock.objects.get(id=medicine_id) - Medicine.objects.create( - patient=user, - medicine_id=medicine, - quantity=quantity, - days=days, - times=times - ) - user_medicine = Medicine.objects.filter(patient=user) - list = [] - for med in user_medicine: - list.append({'medicine': med.medicine_id.medicine_name, 'quantity': med.quantity, - 'days': med.days, 'times': med.times}) - sches = json.dumps(list, default=datetime_handler) - return HttpResponse(sches, content_type='json') - + # elif 'medicine_name' in request.POST: + # app = request.POST.get('user') + # user = Appointment.objects.select_related('user_id','user_id__user','user_id__department','doctor_id','schedule','schedule__doctor_id').get(id=app).user_id + # quantity = int(request.POST.get('quantity')) + # days = int(request.POST.get('days')) + # times = int(request.POST.get('times')) + # medicine_id = request.POST.get('medicine_name') + # medicine = Stock.objects.get(id=medicine_id) + # Medicine.objects.create( + # patient=user, + # medicine_id=medicine, + # quantity=quantity, + # days=days, + # times=times + # ) + # user_medicine = Medicine.objects.filter(patient=user) + # list = [] + # for med in user_medicine: + # list.append({'medicine': med.medicine_id.medicine_name, 'quantity': med.quantity, + # 'days': med.days, 'times': med.times}) + # sches = json.dumps(list, default=datetime_handler) + # return HttpResponse(sches, content_type='json') + elif 'get_stock' in request.POST: + try: + medicine_name_and_id = request.POST.get('medicine_name_for_stock') + medicine_name = medicine_name_and_id.split(",")[0] + id=0 + if(len(medicine_name_and_id.split(",")) > 1) : + id=medicine_name_and_id.split(",")[1] + if id == 0: + status=1 + similar_name_qs = All_Medicine.objects.filter(brand_name__istartswith=medicine_name)[:10] + else : + status=2 + similar_name_qs = All_Medicine.objects.filter(id=id) + similar_name = list(similar_name_qs.values('id', 'medicine_name','constituents','manufacturer_name','pack_size_label','brand_name','threshold')) + val_to_return = [] + + try: + med = All_Medicine.objects.get(id = id) + stk = Stock_entry.objects.filter(medicine_id=med).order_by('Expiry_date') + for s in stk: + if s.Expiry_date > date.today(): + obj = {} + obj['brand_name'] = s.medicine_id.brand_name + obj['supplier'] = s.supplier + obj['expiry'] = s.Expiry_date + p_s = Present_Stock.objects.get(stock_id=s) + if p_s.quantity > 0: + obj['quantity'] = p_s.quantity + obj['id'] = p_s.id + val_to_return.append(obj) + except All_Medicine.DoesNotExist: + val_to_return = [] + except Present_Stock.DoesNotExist: + val_to_return = [] + except Exception as e: + val_to_return = [] + finally: + return JsonResponse({"val": val_to_return, "sim": similar_name, "status": status}) elif 'medicine_name_b' in request.POST: user_id = request.POST.get('user') - user = ExtraInfo.objects.select_related('user','department').get(id=user_id) + if not User.objects.filter(username__iexact = user_id).exists(): + return JsonResponse({"status":-2}) quantity = int(request.POST.get('quantity')) days = int(request.POST.get('days')) times = int(request.POST.get('times')) medicine_id = request.POST.get('medicine_name_b') - medicine = Stock.objects.get(id=medicine_id) - Medicine.objects.create( - patient=user, - medicine_id=medicine, - quantity=quantity, - days=days, - times=times - ) - schs = Medicine.objects.filter(patient=user) - list = [] - for s in schs: - list.append({'medicine': s.medicine_id.medicine_name, 'quantity': s.quantity, - 'days': s.days, 'times': s.times}) - sches = json.dumps(list, default=datetime_handler) - return HttpResponse(sches, content_type='json') + stock = request.POST.get('stock') + medicine_brand_name = medicine_id.split(",")[0] + id= medicine_id.split(",")[1] + med_name = All_Medicine.objects.get(id=id).brand_name + if(stock == "" or stock == "N/A at moment") : + return JsonResponse({"status":1,"med_name":med_name,"id":id}) + stk=stock.split(",") + qty = int(stk[2]) + status=1 + if quantity>qty : status=0 + return JsonResponse({"status":status,"med_name":med_name,"id":id}) - elif 'doct' in request.POST: - doctor_id = request.POST.get('doct') - schedule = Schedule.objects.select_related('doctor_id').filter(doctor_id=doctor_id) - list = [] - for s in schedule: - list.append({'room': s.room, 'id': s.id, 'doctor': s.doctor_id.doctor_name, - 'day': s.get_day_display(), 'from_time': s.from_time, - 'to_time': s.to_time}) - - sches = json.dumps(list, default=datetime_handler) - return HttpResponse(sches, content_type='json') + # elif 'doct' in request.POST: + # doctor_id = request.POST.get('doct') + # schedule = Schedule.objects.select_related('doctor_id').filter(doctor_id=doctor_id) + # list = [] + # for s in schedule: + # list.append({'room': s.room, 'id': s.id, 'doctor': s.doctor_id.doctor_name, + # 'day': s.get_day_display(), 'from_time': s.from_time, + # 'to_time': s.to_time}) + + # sches = json.dumps(list, default=datetime_handler) + # return HttpResponse(sches, content_type='json') elif 'prescribe' in request.POST: app_id = request.POST.get('user') @@ -358,95 +459,357 @@ def compounder_view_handler(request): status = 0 Medicine.objects.select_related('patient','patient__user','patient__department').all().delete() - healthcare_center_notif(request.user, user.user, 'presc') + healthcare_center_notif(request.user, user.user, 'presc','') data = {'status': status, 'stock': stock} return JsonResponse(data) + elif 'user_for_dependents' in request.POST: + user = request.POST.get('user_for_dependents') + if not User.objects.filter(username__iexact = user).exists(): + return JsonResponse({"status":-1}) + user_id = User.objects.get(username__iexact = user) + info = ExtraInfo.objects.get(user = user_id) + dep_info = EmpDependents.objects.filter(extra_info = info) + dep=[] + for d in dep_info: + obj={} + obj['name'] = d.name + obj['relation'] = d.relationship + dep.append(obj) + if(len(dep) == 0) : + return JsonResponse({'status':-2}) + return JsonResponse({'status':1,'dep':dep}) elif 'prescribe_b' in request.POST: user_id = request.POST.get('user') - user = ExtraInfo.objects.select_related('user','department').get(id=user_id) doctor_id = request.POST.get('doctor') - if doctor_id == "": + if not User.objects.filter(username__iexact = user_id).exists(): + return JsonResponse({"status":-1}) + if doctor_id == 'null' : doctor = None else: doctor = Doctor.objects.get(id=doctor_id) - details = request.POST.get('details') - tests = request.POST.get('tests') - # app = Appointment.objects.select_related('user_id','user_id__user','user_id__department','doctor_id','schedule','schedule__doctor_id').filter(user_id=user_id,date=datetime.now()) - # if app: - # appointment = Appointment.objects.select_related('user_id','user_id__user','user_id__department','doctor_id','schedule','schedule__doctor_id').get(user_id=user_id,date=datetime.now()) - # else: - # appointment = None - designation=request.POST.get('user') - uploaded_file = request.FILES.get('file') - d = HoldsDesignation.objects.get(user__username=designation) - form_object=Prescription( - user_id=user, - doctor_id=doctor, - details=details, - date=datetime.now(), - test=tests, - # appointment=appointment - ) - form_object.save() - request_object = Prescription.objects.get(pk=form_object.pk) - send_file_id = create_file( - uploader=request.user.username, - uploader_designation=request.session['currentDesignationSelected'], - receiver=designation, - receiver_designation=d.designation, - src_module="health_center", - src_object_id=str(request_object.id), - file_extra_JSON={"value": 2}, - attached_file=uploaded_file - ) - request_object.file_id=send_file_id - request_object.save() + - query = Medicine.objects.select_related('patient','patient__user','patient__department').filter(patient=user) - prescribe = Prescription.objects.select_related('user_id','user_id__user','user_id__department','doctor_id').all().last() - for medicine in query: - medicine_id = medicine.medicine_id - quantity = medicine.quantity - days = medicine.days - times = medicine.times - Prescribed_medicine.objects.create( - prescription_id=prescribe, - medicine_id=medicine_id, - quantity=quantity, - days=days, - times=times + is_dependent=request.POST.get('is_dependent') + fid=0 + uploaded_file = request.FILES.get('file') + if uploaded_file != None : + f=uploaded_file.read() + new_file=files.objects.create( + file_data=f ) - today=datetime.now() - expiry=Expiry.objects.select_related('medicine_id').filter(medicine_id=medicine_id,quantity__gt=0,returned=False,expiry_date__gte=today).order_by('expiry_date') - stock=Stock.objects.get(medicine_name=medicine_id).quantity - if stock>quantity: - for e in expiry: - q=e.quantity - em=e.id - if q>quantity: - q=q-quantity - Expiry.objects.select_related('medicine_id').filter(id=em).update(quantity=q) - qty = Stock.objects.get(medicine_name=medicine_id).quantity - qty = qty-quantity - Stock.objects.filter(medicine_name=medicine_id).update(quantity=qty) - break - else: - quan=Expiry.objects.select_related('medicine_id').get(id=em).quantity - Expiry.objects.select_related('medicine_id').filter(id=em).update(quantity=0) - qty = Stock.objects.get(medicine_name=medicine_id).quantity - qty = qty-quan - Stock.objects.filter(medicine_name=medicine_id).update(quantity=qty) - quantity=quantity-quan - status = 1 + fid=new_file.id + # with open(uploaded_file.name, 'wb+') as destination: + # destination.write(f) + if is_dependent == "self": + pres=All_Prescription.objects.create( + user_id = user_id, + doctor_id=doctor, + details = request.POST.get('details'), + date=date.today(), + test=request.POST.get('tests'), + file_id=fid + ) + else : + pres=All_Prescription.objects.create( + user_id = user_id, + doctor_id=doctor, + details = request.POST.get('details'), + date=date.today(), + test=request.POST.get('tests'), + is_dependent = True, + dependent_name = request.POST.get('dependent_name'), + dependent_relation = request.POST.get('dependent_relation'), + file_id=fid + ) + # designation=request.POST.get('user') + # d = HoldsDesignation.objects.get(user__username=designation) + # send_file_id = create_file( + # uploader=request.user.username, + # uploader_designation=request.session['currentDesignationSelected'], + # receiver=designation, + # receiver_designation=d.designation, + # src_module="health_center", + # src_object_id=str(pres.id), + # file_extra_JSON={"value": 2}, + # attached_file=uploaded_file + # ) + # pres.file_id=send_file_id + # pres.save() - else: - status = 0 - Medicine.objects.select_related('patient','patient__user','patient__department').all().delete() + pre_medicine = request.POST.get('pre_medicine') + + medicine=eval('('+pre_medicine+')') + + for med in medicine: + med_name = med["brand_name"] + id=med_name.split(",")[1] + quant = int(med['quantity']) + days = med['Days'] + times = med['Times'] + stock = med['stock'] + med_id = All_Medicine.objects.get(id=id) + if(stock == "," or stock == 'N/A at moment,') : + All_Prescribed_medicine.objects.create( + prescription_id = pres, + medicine_id = med_id, + quantity = quant, + days = days, + times=times + ) + else : + stk = stock.split(",") + p_stock = Present_Stock.objects.get(id=int(stk[2])) + All_Prescribed_medicine.objects.create( + prescription_id = pres, + medicine_id = med_id, + stock = p_stock, + quantity = quant, + days = days, + times=times + ) + p_stock.quantity -= quant + p_stock.save() + stock_of_medicine = Present_Stock.objects.filter(Q(medicine_id = med_id) & Q( Expiry_date__gt = date.today())) + qty=0 + for stk in stock_of_medicine : + qty+=stk.quantity + + if qtyquantity: + # for e in expiry: + # q=e.quantity + # em=e.id + # if q>quantity: + # q=q-quantity + # Expiry.objects.select_related('medicine_id').filter(id=em).update(quantity=q) + # qty = Stock.objects.get(medicine_name=medicine_id).quantity + # qty = qty-quantity + # Stock.objects.filter(medicine_name=medicine_id).update(quantity=qty) + # break + # else: + # quan=Expiry.objects.select_related('medicine_id').get(id=em).quantity + # Expiry.objects.select_related('medicine_id').filter(id=em).update(quantity=0) + # qty = Stock.objects.get(medicine_name=medicine_id).quantity + # qty = qty-quan + # Stock.objects.filter(medicine_name=medicine_id).update(quantity=qty) + # quantity=quantity-quan + # status = 1 + + # else: + # status = 0 + # Medicine.objects.select_related('patient','patient__user','patient__department').all().delete() - healthcare_center_notif(request.user, user.user, 'presc') - data = {'status': status} - return JsonResponse(data) + # healthcare_center_notif(request.user, user.user, 'presc','') + # data = {'status': status} + # return JsonResponse(data) + return JsonResponse({"status":1}) + + elif 'presc_followup' in request.POST: + pre_id=request.POST.get("pre_id") + presc = All_Prescription.objects.get(id=int(pre_id)) + + doctor_id = request.POST.get('doctor') + if doctor_id == "null": + doctor = None + else: + doctor = Doctor.objects.get(id=doctor_id) + + fid=0 + uploaded_file = request.FILES.get('file') + if uploaded_file != None : + f=uploaded_file.read() + new_file=files.objects.create( + file_data=f + ) + fid=new_file.id + + followup = Prescription_followup.objects.create( + prescription_id=presc, + Doctor_id=doctor, + details = request.POST.get('details'), + test = request.POST.get('tests'), + date = date.today(), + file_id = fid + ) + + pre_medicine = request.POST.get('pre_medicine') + + medicine=eval('('+pre_medicine+')') + for med in medicine: + med_name = med["med_name"] + id = med_name.split(',')[1] + quant = int(med['quantity']) + days = med['Days'] + times = med['Times'] + stock = med['stock'] + med_id = All_Medicine.objects.get(id = id) + if(stock == ',' or stock == "N/A at moment,"): + All_Prescribed_medicine.objects.create( + prescription_id = presc, + medicine_id = med_id, + quantity = quant, + days = days, + times=times, + prescription_followup_id = followup + ) + else : + stk = stock.split(",") + p_stock = Present_Stock.objects.get(id=int(stk[2])) + All_Prescribed_medicine.objects.create( + prescription_id = presc, + medicine_id = med_id, + stock = p_stock, + quantity = quant, + days = days, + times=times, + prescription_followup_id = followup + ) + p_stock.quantity -= quant + p_stock.save() + stock_of_medicine = Present_Stock.objects.filter(Q(medicine_id = med_id) & Q(Expiry_date__gt = date.today())) + qty=0 + for stk in stock_of_medicine : + qty+=stk.quantity + + if qty 1, + 'has_next': new_current_page < total_pages, + 'previous_page_number': new_current_page - 1 if new_current_page > 1 else None, + 'next_page_number': new_current_page + 1 if new_current_page < total_pages else None, + }) + elif 'datatype' in request.POST and request.POST['datatype'] == 'manage_stock_view': + search = request.POST.get('search_view_stock') + page_size_stock = 2 + new_current_page_stock = int(request.POST.get('page_stock_view')) + new_offset_stock = (new_current_page_stock - 1) * page_size_stock + new_live_meds = [] + new_live =Stock_entry.objects.filter(Q(Expiry_date__gte=date.today()) & Q( Q(medicine_id__brand_name__icontains = search) | Q(supplier__icontains = search))).order_by('Expiry_date')[new_offset_stock:new_offset_stock + page_size_stock] + total_pages_stock = ( Stock_entry.objects.filter(Q(Expiry_date__gte=date.today()) & Q( Q(medicine_id__brand_name__icontains = search) | Q(supplier__icontains = search))).count() + page_size_stock - 1) // page_size_stock + for e in new_live: + obj={} + obj['id']=e.id + obj['medicine_id']=e.medicine_id.brand_name + obj['Expiry_date']=e.Expiry_date + obj['supplier']=e.supplier + try: + qty=Present_Stock.objects.get(stock_id=e).quantity + except: + qty=0 + obj['quantity']=qty + new_live_meds.append(obj) + return JsonResponse({ + 'report_stock_view': new_live_meds, + 'page_stock_view': new_current_page_stock, + 'total_pages_stock_view': total_pages_stock, + 'has_previous': new_current_page_stock > 1, + 'has_next': new_current_page_stock < total_pages_stock, + 'previous_page_number': new_current_page_stock - 1 if new_current_page_stock > 1 else None, + 'next_page_number': new_current_page_stock + 1 if new_current_page_stock < total_pages_stock else None, + }) + elif 'datatype' in request.POST and request.POST['datatype'] == 'manage_stock_expired': + search = request.POST.get('search_view_expired') + new_page_size_stock_expired = 2 + new_current_page_stock_expired = int(request.POST.get('page_stock_expired')) + new_offset_stock_expired = (new_current_page_stock_expired - 1 )* new_page_size_stock_expired + new_expired=[] + new_expiredData=Stock_entry.objects.filter(Q(Expiry_date__lt=date.today())&Q( Q(medicine_id__brand_name__icontains = search) | Q(supplier__icontains = search))).order_by('Expiry_date')[new_offset_stock_expired:new_offset_stock_expired + new_page_size_stock_expired] + new_total_pages_stock_expired = ( Stock_entry.objects.filter(Q(Expiry_date__lt=date.today())&Q( Q(medicine_id__brand_name__icontains = search) | Q(supplier__icontains = search))).count() + new_page_size_stock_expired - 1) // new_page_size_stock_expired + for e in new_expiredData: + obj={} + obj['medicine_id']=e.medicine_id.brand_name + obj['Expiry_date']=e.Expiry_date + obj['supplier']=e.supplier + try: + qty=Present_Stock.objects.get(stock_id=e).quantity + except: + qty=0 + obj['quantity']=qty + new_expired.append(obj) + return JsonResponse({ + 'report_stock_expired': new_expired, + 'page_stock_expired': new_current_page_stock_expired, + 'total_pages_stock_view': new_total_pages_stock_expired, + 'has_previous': new_current_page_stock_expired > 1, + 'has_next': new_current_page_stock_expired < new_total_pages_stock_expired, + 'previous_page_number': new_current_page_stock_expired - 1 if new_current_page_stock_expired > 1 else None, + 'next_page_number': new_current_page_stock_expired + 1 if new_current_page_stock_expired < new_total_pages_stock_expired else None, + }) + elif 'datatype' in request.POST and request.POST['datatype'] == 'manage_stock_required': + search = request.POST.get('search_view_required') + new_page_size_stock_required = 2 + new_current_page_stock_required = int(request.POST.get('page_stock_required')) + new_offset_stock_required = (new_current_page_stock_required - 1 )* new_page_size_stock_required + new_required=[] + new_requiredData=Required_medicine.objects.filter( Q(medicine_id__brand_name__icontains = search))[new_offset_stock_required:new_offset_stock_required + new_page_size_stock_required] + new_total_pages_stock_required = (Required_medicine.objects.filter( Q(medicine_id__brand_name__icontains = search)).count() + new_page_size_stock_required - 1) // new_page_size_stock_required + for e in new_requiredData: + obj={} + obj['medicine_id']=e.medicine_id.brand_name + obj['quantity']=e.quantity + obj['threshold']=e.threshold + new_required.append(obj) + return JsonResponse({ + 'report_stock_required': new_required, + 'page_stock_required': new_current_page_stock_required, + 'total_pages_stock_required': new_total_pages_stock_required, + 'has_previous': new_current_page_stock_required > 1, + 'has_next': new_current_page_stock_required < new_total_pages_stock_required, + 'previous_page_number': new_current_page_stock_required - 1 if new_current_page_stock_required > 1 else None, + 'next_page_number': new_current_page_stock_required + 1 if new_current_page_stock_required < new_total_pages_stock_required else None, + }) + + elif 'search_patientlog' in request.POST: + search = request.POST.get('search_patientlog') + current_page = 1 + page_size_prescription = 2 # Default to 2 if not specified + offset = (current_page - 1) * page_size_prescription + prescriptions = All_Prescription.objects.filter(Q(user_id__icontains = search) | Q(details__icontains = search)).order_by('-date', '-id')[offset:offset + page_size_prescription] + + report = [] + for pre in prescriptions: + doc = None + if pre.doctor_id != None : doc=pre.doctor_id.doctor_name + dic = { + 'id': pre.pk, + 'user_id': pre.user_id, + 'doctor_id': doc, + 'date': pre.date, + 'details': pre.details, + 'test': pre.test, + 'file_id': pre.file_id, + # 'file': view_file(file_id=pre.file_id)['upload_file'] if pre.file_id else None + } + report.append(dic) + # Handle total count for pagination context + total_count = All_Prescription.objects.filter(Q(user_id__icontains = search) | Q(details__icontains = search)).count() + # Calculate total number of pages + total_pages = (total_count + page_size_prescription - 1) // page_size_prescription # This ensures rounding up + prescContext = { + 'count': total_pages, + 'page': { + 'object_list': report, + 'number': current_page, + 'has_previous': current_page > 1, + 'has_next': current_page < total_pages, + 'previous_page_number': current_page - 1 if current_page > 1 else None, + 'next_page_number': current_page + 1 if current_page < total_pages else None, + } + } + return JsonResponse({'status':1,"presc_context":prescContext}) + elif 'search_view_stock' in request.POST: + search = request.POST.get('search_view_stock') + current_page_stock = 1 + page_size_stock = 2 + offset_stock = (current_page_stock - 1 )* page_size_stock + live_meds=[] + live=Stock_entry.objects.filter(Q(Expiry_date__gte=date.today()) & Q( Q(medicine_id__brand_name__icontains = search) | Q(supplier__icontains = search))).order_by('Expiry_date')[offset_stock:offset_stock + page_size_stock] + total_pages_stock = ( Stock_entry.objects.filter(Q(Expiry_date__gte=date.today()) & Q(Q(medicine_id__brand_name__icontains = search) | Q(supplier__icontains = search))).count() + page_size_stock - 1) // page_size_stock + for e in live: + obj={} + obj['id']=e.id + obj['medicine_id']=e.medicine_id.brand_name + obj['Expiry_date']=e.Expiry_date + obj['supplier']=e.supplier + try: + qty=Present_Stock.objects.get(stock_id=e).quantity + except: + qty=0 + obj['quantity']=qty + live_meds.append(obj) + stockContext = { + 'count_stock_view':total_pages_stock, + 'page_stock_view':{ + 'object_list': live_meds, + 'number': current_page_stock, + 'has_previous': current_page_stock > 1, + 'has_next': current_page_stock < total_pages_stock, + 'previous_page_number': current_page_stock - 1 if current_page_stock > 1 else None, + 'next_page_number': current_page_stock + 1 if current_page_stock < total_pages_stock else None, + } + } + return JsonResponse({'status':1,'stock_context':stockContext}) + elif 'search_view_expired' in request.POST: + search = request.POST.get('search_view_expired') + current_page_stock_expired = 1 + page_size_stock_expired = 2 + offset_stock_expired = (current_page_stock_expired - 1 )* page_size_stock_expired + expired=[] + expiredData=Stock_entry.objects.filter(Q(Expiry_date__lt=date.today())&Q( Q(medicine_id__brand_name__icontains = search) | Q(supplier__icontains = search))).order_by('Expiry_date')[offset_stock_expired:offset_stock_expired + page_size_stock_expired] + total_pages_stock_expired = ( Stock_entry.objects.filter(Q(Expiry_date__lt=date.today())&Q( Q(medicine_id__brand_name__icontains = search) | Q(supplier__icontains = search))).count() + page_size_stock_expired - 1) // page_size_stock_expired + for e in expiredData: + obj={} + obj['medicine_id']=e.medicine_id.brand_name + obj['Expiry_date']=e.Expiry_date + obj['supplier']=e.supplier + try: + qty=Present_Stock.objects.get(stock_id=e).quantity + except: + qty=0 + obj['quantity']=qty + expired.append(obj) + ExpiredstockContext = { + 'count_stock_expired':total_pages_stock_expired, + 'page_stock_expired':{ + 'object_list': expired, + 'number': current_page_stock_expired, + 'has_previous': current_page_stock_expired > 1, + 'has_next': current_page_stock_expired < total_pages_stock_expired, + 'previous_page_number': current_page_stock_expired - 1 if current_page_stock_expired > 1 else None, + 'next_page_number': current_page_stock_expired + 1 if current_page_stock_expired < total_pages_stock_expired else None, + } + } + return JsonResponse({'status':1,'expired_context':ExpiredstockContext}) + elif 'search_view_required' in request.POST: + search = request.POST.get('search_view_required') + current_required_page = 1 + page_size_required = 2 + offset_stock_required = (current_required_page - 1 )* page_size_required + required_data = Required_medicine.objects.filter( Q(medicine_id__brand_name__icontains = search) )[offset_stock_required:offset_stock_required + page_size_required] + total_pages_stock_required = (Required_medicine.objects.filter( Q(medicine_id__brand_name__icontains = search) ).count() + page_size_required -1) // page_size_required + required=[] + for e in required_data: + obj={} + obj['medicine_id']=e.medicine_id.brand_name + obj['quantity']=e.quantity + obj['threshold'] = e.threshold + required.append(obj) + stocks = { + "count_stock_required" : total_pages_stock_required, + "page_stock_required":{ + "object_list":required, + 'number' : current_required_page, + 'has_previous' : current_required_page > 1 , + 'has_next': current_required_page < total_pages_stock_required, + 'previous_page_number' : current_required_page - 1 if current_required_page > 1 else None, + 'next_page_number' : current_required_page + 1 if current_required_page < total_pages_stock_required else None, + } + } + return JsonResponse({'status':1,'stocks':stocks}) def student_view_handler(request): if 'amb_submit' in request.POST: @@ -523,9 +1122,9 @@ def student_view_handler(request): reason=reason ) data = {'status': 1} - healthcare_center_notif(request.user, request.user, 'amb_request') + healthcare_center_notif(request.user, request.user, 'amb_request','') for cmp in comp_id: - healthcare_center_notif(request.user, cmp.user, 'amb_req') + healthcare_center_notif(request.user, cmp.user, 'amb_req','') return JsonResponse(data) elif "amb_submit1" in request.POST: @@ -548,9 +1147,9 @@ def student_view_handler(request): data = { 'app_time': app_time, 'dt': datei , 'status' : 1 } - healthcare_center_notif(request.user, request.user, 'appoint') + healthcare_center_notif(request.user, request.user, 'appoint','') for cmp in comp_id: - healthcare_center_notif(request.user, cmp.user, 'appoint_req') + healthcare_center_notif(request.user, cmp.user, 'appoint_req','') return JsonResponse(data) @@ -586,7 +1185,7 @@ def student_view_handler(request): date=datetime.now() ) data = {'status': 1} - healthcare_center_notif(request.user, request.user,'feedback_submitted') + healthcare_center_notif(request.user, request.user,'feedback_submitted','') return JsonResponse(data) @@ -637,7 +1236,7 @@ def student_view_handler(request): file_extra_JSON={"value": 2}, attached_file=uploaded_file ) - healthcare_center_notif(request.user,user.user,'rel_forward') + healthcare_center_notif(request.user,user.user,'rel_forward','') request_object.file_id = send_file_id request_object.save() @@ -663,7 +1262,7 @@ def student_view_handler(request): medical_relief_instance.acc_admin_forward_flag = True medical_relief_instance.save() - healthcare_center_notif(request.user,user.user,'rel_approved') + healthcare_center_notif(request.user,user.user,'rel_approved','') return JsonResponse({'status':1}) @@ -671,7 +1270,7 @@ def student_view_handler(request): anno_id = request.POST.get('anno_id') Announcements.objects.select_related('user_id','user_id__user','user_id__department', 'message', 'upload_announcement').filter(pk=anno_id).delete() data = {'status': 1} - healthcare_center_notif(request.user,user.user,'new_announce') + healthcare_center_notif(request.user,user.user,'new_announce','') return JsonResponse({'status':1}) elif 'medical_profile' in request.POST: diff --git a/FusionIIIT/applications/health_center/views.py b/FusionIIIT/applications/health_center/views.py index 4d8881496..a178a9d68 100644 --- a/FusionIIIT/applications/health_center/views.py +++ b/FusionIIIT/applications/health_center/views.py @@ -1,4 +1,6 @@ import json +import pandas as pd +from django.http import FileResponse,Http404 from datetime import date, datetime, timedelta, time import xlrd import os @@ -7,17 +9,18 @@ from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from django.core import serializers -from django.core.paginator import Paginator +from django.core.paginator import EmptyPage from django.http import HttpResponse, HttpResponseRedirect, JsonResponse from django.shortcuts import get_object_or_404, render, redirect from notification.views import healthcare_center_notif -from applications.health_center.api.serializers import MedicalReliefSerializer -from .models import (Ambulance_request, Appointment, Complaint, Constants, - Counter, Doctor,Pathologist, Expiry, Hospital, Hospital_admit, - Medicine, Prescribed_medicine, Prescription, Doctors_Schedule,Pathologist_Schedule, - Stock,SpecialRequest,Announcements,medical_relief,MedicalProfile) +# from applications.health_center.api.serializers import MedicalReliefSerializer +from .models import ( Constants,All_Medicine,All_Prescribed_medicine,All_Prescription,Prescription_followup, + Present_Stock,Doctor,Pathologist, + Doctors_Schedule,Pathologist_Schedule,Stock_entry, + medical_relief,MedicalProfile,Required_medicine,files,Required_tabel_last_updated) from .utils import datetime_handler, compounder_view_handler, student_view_handler from applications.filetracking.sdk.methods import * +from django.db.models import Q @@ -75,52 +78,190 @@ def compounder_view(request): else: notifs = request.user.notifications.all() - all_complaints = Complaint.objects.select_related('user_id','user_id__user','user_id__department').all() - all_hospitals = Hospital_admit.objects.select_related('user_id','user_id__user','user_id__department','doctor_id').all().order_by('-admission_date') - hospitals_list = Hospital.objects.all().order_by('hospital_name') - all_ambulances = Ambulance_request.objects.select_related('user_id','user_id__user','user_id__department').all().order_by('-date_request') - appointments_today =Appointment.objects.select_related('user_id','user_id__user','user_id__department','doctor_id','schedule','schedule__doctor_id').filter(date=datetime.now()).order_by('date') - appointments_future=Appointment.objects.select_related('user_id','user_id__user','user_id__department','doctor_id','schedule','schedule__doctor_id').filter(date__gt=datetime.now()).order_by('date') + # all_complaints = Complaint.objects.select_related('user_id','user_id__user','user_id__department').all() + # all_hospitals = Hospital_admit.objects.select_related('user_id','user_id__user','user_id__department','doctor_id').all().order_by('-admission_date') + # hospitals_list = Hospital.objects.all().order_by('hospital_name') + # all_ambulances = Ambulance_request.objects.select_related('user_id','user_id__user','user_id__department').all().order_by('-date_request') + # appointments_today =Appointment.objects.select_related('user_id','user_id__user','user_id__department','doctor_id','schedule','schedule__doctor_id').filter(date=datetime.now()).order_by('date') + # appointments_future=Appointment.objects.select_related('user_id','user_id__user','user_id__department','doctor_id','schedule','schedule__doctor_id').filter(date__gt=datetime.now()).order_by('date') users = ExtraInfo.objects.select_related('user','department').filter(user_type='student') - stocks = Stock.objects.all() - days = Constants.DAYS_OF_WEEK schedule=Doctors_Schedule.objects.select_related('doctor_id').all().order_by('doctor_id') schedule1=Pathologist_Schedule.objects.select_related('pathologist_id').all().order_by('pathologist_id') - expired=Expiry.objects.select_related('medicine_id').filter(expiry_date__lt=datetime.now(),returned=False).order_by('expiry_date') - live_meds=Expiry.objects.select_related('medicine_id').filter(returned=False).order_by('quantity') - count=Counter.objects.all() - announcements_data=Announcements.objects.all().values() + # expired=Expiry.objects.select_related('medicine_id').filter(expiry_date__lt=datetime.now(),returned=False).order_by('expiry_date') + # live_meds=Expiry.objects.select_related('medicine_id').filter(returned=False).order_by('quantity') + page_size=2 + fir=Required_tabel_last_updated.objects.first() + if fir == None: + exp = Stock_entry.objects.filter(Expiry_date__lt = date.today()) + for e in exp: + med=e.medicine_id + p_s = Present_Stock.objects.filter(Q(medicine_id = med) & Q(Expiry_date__gte = date.today())) + qty=0 + for ps in p_s: + qty+=ps.quantity + if Required_medicine.objects.filter(medicine_id=med).exists() : + req=Required_medicine.objects.get(medicine_id=med) + if qty>=med.threshold : req.delete() + else : + req.quantity = qty + req.save() + else : + if qtymed.threshold) : req.delete() + else : + req.quantity = qty + req.save() + else : + if qty 1 , + 'has_next': current_required_page < total_pages_stock_required, + 'previous_page_number' : current_required_page - 1 if current_required_page > 1 else None, + 'next_page_number' : current_required_page + 1 if current_required_page < total_pages_stock_required else None, + } + } + + current_page_stock_expired = 1 + page_size_stock_expired = page_size + offset_stock_expired = (current_page_stock_expired - 1 )* page_size_stock_expired + expired=[] + expiredData=Stock_entry.objects.filter(Expiry_date__lt=date.today()).order_by('Expiry_date')[offset_stock_expired:offset_stock_expired + page_size_stock_expired] + total_pages_stock_expired = ( Stock_entry.objects.filter(Expiry_date__lt=date.today()).count() + page_size_stock_expired - 1) // page_size_stock_expired + for e in expiredData: + obj={} + obj['medicine_id']=e.medicine_id.brand_name + obj['Expiry_date']=e.Expiry_date + obj['supplier']=e.supplier + try: + qty=Present_Stock.objects.get(stock_id=e).quantity + except: + qty=0 + obj['quantity']=qty + expired.append(obj) + ExpiredstockContext = { + 'count_stock_expired':total_pages_stock_expired, + 'page_stock_expired':{ + 'object_list': expired, + 'number': current_page_stock_expired, + 'has_previous': current_page_stock_expired > 1, + 'has_next': current_page_stock_expired < total_pages_stock_expired, + 'previous_page_number': current_page_stock_expired - 1 if current_page_stock_expired > 1 else None, + 'next_page_number': current_page_stock_expired + 1 if current_page_stock_expired < total_pages_stock_expired else None, + } + } + + + current_page_stock = 1 + page_size_stock = page_size + offset_stock = (current_page_stock - 1 )* page_size_stock + live_meds=[] + live=Stock_entry.objects.filter(Expiry_date__gte=date.today()).order_by('Expiry_date')[offset_stock:offset_stock + page_size_stock] + total_pages_stock = ( Stock_entry.objects.filter(Expiry_date__gte=date.today()).count() + page_size_stock - 1) // page_size_stock + for e in live: + obj={} + obj['id']=e.id + obj['medicine_id']=e.medicine_id.brand_name + obj['Expiry_date']=e.Expiry_date + obj['supplier']=e.supplier + try: + qty=Present_Stock.objects.get(stock_id=e).quantity + except: + qty=0 + obj['quantity']=qty + live_meds.append(obj) + stockContext = { + 'count_stock_view':total_pages_stock, + 'page_stock_view':{ + 'object_list': live_meds, + 'number': current_page_stock, + 'has_previous': current_page_stock > 1, + 'has_next': current_page_stock < total_pages_stock, + 'previous_page_number': current_page_stock - 1 if current_page_stock > 1 else None, + 'next_page_number': current_page_stock + 1 if current_page_stock < total_pages_stock else None, + } + } + - medicines_presc=Prescribed_medicine.objects.select_related('prescription_id','prescription_id__user_id','prescription_id__user_id__user','prescription_id__user_id__department','prescription_id__doctor_id').all() - print(medicines_presc) - if count: - Counter.objects.all().delete() - Counter.objects.create(count=0,fine=0) - count=Counter.objects.get() - hospitals=Hospital.objects.all() schedule=Doctors_Schedule.objects.select_related('doctor_id').all().order_by('day','doctor_id') schedule1=Pathologist_Schedule.objects.select_related('pathologist_id').all().order_by('day','pathologist_id') doctors=Doctor.objects.filter(active=True).order_by('id') pathologists=Pathologist.objects.filter(active=True).order_by('id') - prescription= Prescription.objects.all() - report=[] - for pre in prescription: - dic={} - dic['id']=pre.pk - dic['user_id']=pre.user_id_id - dic['doctor_id'] = pre.doctor_id # Use dot notation - dic['date'] = pre.date # Use dot notation - dic['details'] = pre.details # Use dot notation - dic['test'] = pre.test # Use dot notation - if pre.file_id: - dic['file'] = view_file(file_id=pre.file_id)['upload_file'] - else: - dic['file']=None + medicine_presc = All_Prescribed_medicine.objects.all() + + #Logic for the padination and view prescriptions is below , used ajax for pagination + current_page = 1 + page_size_prescription = page_size # Default to 2 if not specified + offset = (current_page - 1) * page_size_prescription + # Fetch the prescriptions with limit and offset + prescriptions = All_Prescription.objects.all().order_by('-date', '-id')[offset:offset + page_size_prescription] + + report = [] + for pre in prescriptions: + dic = { + 'id': pre.pk, + 'user_id': pre.user_id, + 'doctor_id': pre.doctor_id, + 'date': pre.date, + 'details': pre.details, + 'test': pre.test, + 'file_id': pre.file_id, + # 'file': view_file(file_id=pre.file_id)['upload_file'] if pre.file_id else None + } report.append(dic) - + # Handle total count for pagination context + total_count = All_Prescription.objects.count() + # Calculate total number of pages + total_pages = (total_count + page_size_prescription - 1) // page_size_prescription # This ensures rounding up + prescContext = { + 'count': total_pages, + 'page': { + 'object_list': report, + 'number': current_page, + 'has_previous': current_page > 1, + 'has_next': current_page < total_pages, + 'previous_page_number': current_page - 1 if current_page > 1 else None, + 'next_page_number': current_page + 1 if current_page < total_pages else None, + } + } + #adding file tracking inbox part for compounder @@ -136,20 +277,18 @@ def compounder_view(request): dic['uploader']=ib['uploader'] dic['upload_date']=datetime.fromisoformat(ib['upload_date']).date() dic['desc']=mr.description - dic['file']=view_file(file_id=ib['id'])['upload_file'] + # dic['file']=view_file(file_id=ib['id'])['upload_file'] dic['status']=mr.compounder_forward_flag dic['status1']=mr.acc_admin_forward_flag inbox.append(dic) # print(inbox_files) - return render(request, 'phcModule/phc_compounder.html', - {'days': days, 'users': users, 'count': count,'expired':expired, - 'stocks': stocks, 'all_complaints': all_complaints, - 'all_hospitals': all_hospitals, 'hospitals':hospitals, 'all_ambulances': all_ambulances, - 'appointments_today': appointments_today, 'doctors': doctors, 'pathologists':pathologists, - 'appointments_future': appointments_future, 'schedule': schedule, 'schedule1': schedule1, 'live_meds': live_meds, 'presc_hist': report, 'medicines_presc': medicines_presc, 'hospitals_list': hospitals_list,'inbox_files':inbox,'announcements':announcements_data,}) + {'days': days, 'users': users,'expired':ExpiredstockContext, + 'stocks': stocks, + 'doctors': doctors, 'pathologists':pathologists, + 'schedule': schedule, 'schedule1': schedule1, 'live_meds': stockContext, 'presc_hist': prescContext,'inbox_files':inbox,'medicines_presc':medicine_presc}) else: return HttpResponseRedirect("/healthcenter/student") # compounder view ends @@ -632,4 +771,37 @@ def medical_profile(request): return render(request, 'health_center/medical_profile.html', {"user_designation":user_info.user_type, 'medical_profile':medical_profile, "request_to":requests_received - }) \ No newline at end of file + }) + +@login_required +def compounder_view_prescription(request,prescription_id): + prescription = All_Prescription.objects.get(id=prescription_id) + pre_medicine = All_Prescribed_medicine.objects.filter(prescription_id=prescription) + doctors=Doctor.objects.filter(active=True).order_by('id') + follow_presc =Prescription_followup.objects.filter(prescription_id=prescription).order_by('-id') + if request.method == "POST": + print("post") + return render(request, 'phcModule/phc_compounder_view_prescription.html',{'prescription':prescription, + 'pre_medicine':pre_medicine,'doctors':doctors, + "follow_presc":follow_presc}) + +@login_required +def view_file(request,file_id): + file_id_int = int(file_id) + if(file_id_int == -2): + return FileResponse(open('static/health_center/add_stock_example.xlsx', 'rb'), as_attachment=True, filename="example_add_stock.xlsx") + if(file_id_int == -1): + return FileResponse(open('static/health_center/add_medicine_example.xlsx', 'rb'), as_attachment=True, filename="example_add_medicine.xlsx") + filepath = "applications/health_center/static/health_center/generated.pdf" + + file=files.objects.get(id=file_id) + f=file.file_data + + with open("applications/health_center/static/health_center/generated.pdf", 'wb+') as destination: + destination.write(f) + + pdf = open(filepath, 'rb') + response = FileResponse(pdf, content_type="application/pdf") + response['Content-Disposition'] = 'inline; filename="generated.pdf"' + + return response diff --git a/FusionIIIT/applications/hostel_management/migrations/0001_initial.py b/FusionIIIT/applications/hostel_management/migrations/0001_initial.py index 8659d1649..cc7cb2598 100644 --- a/FusionIIIT/applications/hostel_management/migrations/0001_initial.py +++ b/FusionIIIT/applications/hostel_management/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-07-16 15:44 from django.conf import settings from django.db import migrations, models @@ -12,9 +12,9 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('globals', '0001_initial'), ('academic_information', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ @@ -26,6 +26,50 @@ class Migration(migrations.Migration): ('hall_name', models.CharField(max_length=50)), ('max_accomodation', models.IntegerField(default=0)), ('number_students', models.PositiveIntegerField(default=0)), + ('assigned_batch', models.CharField(blank=True, max_length=50, null=True)), + ('type_of_seater', models.CharField(choices=[('single', 'Single Seater'), ('double', 'Double Seater'), ('triple', 'Triple Seater')], default='single', max_length=50)), + ], + ), + migrations.CreateModel( + name='HostelComplaint', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('hall_name', models.CharField(max_length=100)), + ('student_name', models.CharField(max_length=100)), + ('roll_number', models.CharField(max_length=20)), + ('description', models.TextField()), + ('contact_number', models.CharField(max_length=15)), + ], + ), + migrations.CreateModel( + name='HostelLeave', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('student_name', models.CharField(max_length=100)), + ('roll_num', models.CharField(max_length=20)), + ('reason', models.TextField()), + ('phone_number', models.CharField(blank=True, max_length=20, null=True)), + ('start_date', models.DateField(default=django.utils.timezone.now)), + ('end_date', models.DateField()), + ('status', models.CharField(default='pending', max_length=20)), + ('remark', models.TextField(blank=True, null=True)), + ('file_upload', models.FileField(blank=True, null=True, upload_to='hostel_management/')), + ], + ), + migrations.CreateModel( + name='StudentDetails', + fields=[ + ('id', models.CharField(max_length=20, primary_key=True, serialize=False)), + ('first_name', models.CharField(blank=True, max_length=100, null=True)), + ('last_name', models.CharField(blank=True, max_length=100, null=True)), + ('programme', models.CharField(blank=True, max_length=100, null=True)), + ('batch', models.CharField(blank=True, max_length=100, null=True)), + ('room_num', models.CharField(blank=True, max_length=20, null=True)), + ('hall_no', models.CharField(blank=True, max_length=20, null=True)), + ('hall_id', models.CharField(blank=True, max_length=20, null=True)), + ('specialization', models.CharField(blank=True, max_length=100, null=True)), + ('parent_contact', models.CharField(blank=True, max_length=20, null=True)), + ('address', models.CharField(blank=True, max_length=255, null=True)), ], ), migrations.CreateModel( @@ -51,7 +95,18 @@ class Migration(migrations.Migration): ('start_time', models.TimeField(blank=True, null=True)), ('end_time', models.TimeField(blank=True, null=True)), ('hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hostel_management.hall')), - ('staff_id', models.ForeignKey(on_delete=django.db.models.fields.related.ForeignKey, to='globals.staff')), + ('staff_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.staff')), + ], + ), + migrations.CreateModel( + name='HostelTransactionHistory', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('change_type', models.CharField(max_length=100)), + ('previous_value', models.CharField(max_length=255)), + ('new_value', models.CharField(max_length=255)), + ('timestamp', models.DateTimeField(auto_now_add=True)), + ('hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hostel_management.hall')), ], ), migrations.CreateModel( @@ -75,6 +130,49 @@ class Migration(migrations.Migration): ('posted_by', models.ForeignKey(on_delete=django.db.models.fields.related.ForeignKey, to='globals.extrainfo')), ], ), + migrations.CreateModel( + name='HostelInventory', + fields=[ + ('inventory_id', models.AutoField(primary_key=True, serialize=False)), + ('inventory_name', models.CharField(max_length=100)), + ('cost', models.DecimalField(decimal_places=2, max_digits=10)), + ('quantity', models.PositiveIntegerField(default=0)), + ('hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hostel_management.hall')), + ], + ), + migrations.CreateModel( + name='HostelHistory', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), + ('batch', models.CharField(max_length=50, null=True)), + ('caretaker', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='caretaker_history', to='globals.staff')), + ('hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hostel_management.hall')), + ('warden', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='warden_history', to='globals.faculty')), + ], + ), + migrations.CreateModel( + name='HostelFine', + fields=[ + ('fine_id', models.AutoField(primary_key=True, serialize=False)), + ('student_name', models.CharField(max_length=100)), + ('amount', models.DecimalField(decimal_places=2, max_digits=10)), + ('status', models.CharField(choices=[('Pending', 'Pending'), ('Paid', 'Paid')], default='Pending', max_length=50)), + ('reason', models.TextField()), + ('hall', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='hostel_management.hall')), + ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), + ], + ), + migrations.CreateModel( + name='HostelAllotment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('assignedBatch', models.CharField(max_length=50)), + ('assignedCaretaker', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='globals.staff')), + ('assignedWarden', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='globals.faculty')), + ('hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hostel_management.hall')), + ], + ), migrations.CreateModel( name='HallWarden', fields=[ @@ -102,36 +200,39 @@ class Migration(migrations.Migration): ('staff', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.staff')), ], ), - migrations.CreateModel( - name='GuestRoomDetail', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('room_no', models.CharField(max_length=4, unique=True)), - ('room_status', models.CharField(choices=[('Booked', 'Booked'), ('CheckedIn', 'Checked In'), ('Available', 'Available'), ('UnderMaintenance', 'Under Maintenance')], default='Available', max_length=20)), - ('hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hostel_management.hall')), - ], - ), migrations.CreateModel( name='GuestRoomBooking', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('guest_name', models.CharField(max_length=100)), - ('guest_phone', models.CharField(max_length=15)), - ('guest_email', models.CharField(blank=True, max_length=40)), + ('guest_name', models.CharField(max_length=255)), + ('guest_phone', models.CharField(max_length=255)), + ('guest_email', models.CharField(blank=True, max_length=255)), ('guest_address', models.TextField(blank=True)), ('rooms_required', models.IntegerField(blank=True, default=1, null=True)), + ('guest_room_id', models.CharField(blank=True, max_length=255)), ('total_guest', models.IntegerField(default=1)), ('purpose', models.TextField()), ('arrival_date', models.DateField()), ('arrival_time', models.TimeField()), ('departure_date', models.DateField()), ('departure_time', models.TimeField()), - ('status', models.CharField(choices=[('Confirmed', 'Confirmed'), ('Pending', 'Pending'), ('Rejected', 'Rejected'), ('Canceled', 'Canceled'), ('CancelRequested', 'Cancel Requested'), ('CheckedIn', 'Checked In'), ('Complete', 'Complete'), ('Forward', 'Forward')], default='Pending', max_length=15)), + ('status', models.CharField(choices=[('Confirmed', 'Confirmed'), ('Pending', 'Pending'), ('Rejected', 'Rejected'), ('Canceled', 'Canceled'), ('CancelRequested', 'Cancel Requested'), ('CheckedIn', 'Checked In'), ('Complete', 'Complete'), ('Forward', 'Forward')], default='Pending', max_length=255)), ('booking_date', models.DateField(default=django.utils.timezone.now)), - ('nationality', models.CharField(blank=True, max_length=20)), - ('guest_room_id', models.ManyToManyField(to='hostel_management.GuestRoomDetail')), + ('nationality', models.CharField(blank=True, max_length=255)), + ('room_type', models.CharField(choices=[('single', 'Single'), ('double', 'Double'), ('triple', 'Triple')], default='single', max_length=10)), ('hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hostel_management.hall')), ('intender', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), + migrations.CreateModel( + name='GuestRoom', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('room', models.CharField(max_length=255)), + ('occupied_till', models.DateField(blank=True, null=True)), + ('vacant', models.BooleanField(default=True)), + ('room_type', models.CharField(choices=[('single', 'Single'), ('double', 'Double'), ('triple', 'Triple')], default='single', max_length=10)), + ('hall', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hostel_management.hall')), + ], + ), ] diff --git a/FusionIIIT/applications/hostel_management/urls.py b/FusionIIIT/applications/hostel_management/urls.py index 95fcdeeb8..28c1915c2 100644 --- a/FusionIIIT/applications/hostel_management/urls.py +++ b/FusionIIIT/applications/hostel_management/urls.py @@ -12,7 +12,7 @@ path('admin/', admin.site.urls), #Home path('', views.hostel_view, name="hostel_view"), - path('/hello', views.hostel_view, name="hello"), + path('hello', views.hostel_view, name="hello"), #Notice Board path('notice_form/', views.notice_board, name="notice_board"), diff --git a/FusionIIIT/applications/hr2/api/form_views.py b/FusionIIIT/applications/hr2/api/form_views.py index 66d4de382..984e1fbaf 100644 --- a/FusionIIIT/applications/hr2/api/form_views.py +++ b/FusionIIIT/applications/hr2/api/form_views.py @@ -3,23 +3,24 @@ 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 rest_framework.permissions import IsAuthenticated 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.globals.models import Designation, HoldsDesignation, ExtraInfo from applications.filetracking.models import * # from django.contrib.auth.models import User class LTC(APIView): serializer_class = LTC_serializer - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) def post(self, request): + print("hello") user_info = request.data[1] - print(request.data) + print(request.data[1]) serializer = self.serializer_class(data=request.data[0]) if serializer.is_valid(): serializer.save() @@ -71,7 +72,7 @@ def delete(self, request, *args, **kwargs): class FormManagement(APIView): - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) def get(self, request, *args, **kwargs): username = request.query_params.get("username") @@ -95,7 +96,7 @@ def post(self, request, *args, **kwargs): class CPDAAdvance(APIView): serializer_class = CPDAAdvance_serializer - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) def post(self, request): print(request.data[0]) @@ -130,6 +131,7 @@ def get(self, request, *args, **kwargs): def put(self, request, *args, **kwargs): pk = request.query_params.get("id") receiver = request.data[0] + print(request.data) send_to = receiver['receiver'] print(send_to) receiver_value = User.objects.get(username=send_to) @@ -159,7 +161,7 @@ def delete(self, request, *args, **kwargs): class CPDAReimbursement(APIView): serializer_class = CPDAReimbursement_serializer - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) def post(self, request): user_info = request.data[1] @@ -217,7 +219,7 @@ def delete(self, request, *args, **kwargs): class Leave(APIView): serializer_class = Leave_serializer - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) def post(self, request): user_info = request.data[1] @@ -273,7 +275,7 @@ def delete(self, request, *args, **kwargs): class Appraisal(APIView): serializer_class = Appraisal_serializer - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) def post(self, request): user_info = request.data[1] @@ -313,9 +315,9 @@ def put(self, request, *args, **kwargs): 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']) + serializer.save() return Response(serializer.data, status=status.HTTP_200_OK) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -335,22 +337,22 @@ def delete(self, request, *args, **kwargs): class GetFormHistory(APIView): - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) 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 + print(type(person)) + id = person 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) + forms = LTCform.objects.filter(created_by=id) serializer = LTC_serializer(forms, many=True) return Response(serializer.data, status=status.HTTP_200_OK) except LTCform.DoesNotExist: @@ -402,7 +404,7 @@ def get(self, request, *args, **kwargs): class TrackProgress(APIView): - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) def get(self, request, *args, **kwargs): file_id = request.query_params.get("id") @@ -411,22 +413,22 @@ def get(self, request, *args, **kwargs): class FormFetch(APIView): - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) def get(self, request, *args, **kwargs): fileId = request.query_params.get("file_id") + print(fileId) 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 + current_owner = current_owner.username elif form_type == "CPDAReimbursement": forms = CPDAReimbursementform.objects.get(id=form_id) serializer = CPDAReimbursement_serializer(forms, many=False) @@ -435,7 +437,7 @@ def get(self, request, *args, **kwargs): owner = Tracking.objects.filter(file_id=fileId) current_owner = owner.last() current_owner = current_owner.receiver_id - current_owner = current_owner.user + current_owner = current_owner.username elif form_type == "CPDAAdvance": forms = CPDAAdvanceform.objects.get(id=form_id) serializer = CPDAAdvance_serializer(forms, many=False) @@ -445,7 +447,6 @@ def get(self, request, *args, **kwargs): 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) @@ -454,7 +455,7 @@ def get(self, request, *args, **kwargs): owner = Tracking.objects.filter(file_id=fileId) current_owner = owner.last() current_owner = current_owner.receiver_id - current_owner = current_owner.user + current_owner = current_owner.username elif form_type == "Leave": forms = LeaveForm.objects.get(id=form_id) serializer = Leave_serializer(forms, many=False) @@ -463,52 +464,59 @@ def get(self, request, *args, **kwargs): owner = Tracking.objects.filter(file_id=fileId) current_owner = owner.last() current_owner = current_owner.receiver_id - current_owner = current_owner.user + current_owner = current_owner.username return Response({"form": serializer.data, "creator": user.username, "current_owner": current_owner}, status=status.HTTP_200_OK) class CheckLeaveBalance(APIView): - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) 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) + extrainfo = ExtraInfo.objects.get(user=person) + leave_balance = LeaveBalance.objects.get(employeeId=extrainfo) + serializer = self.serializer_class(leave_balance, many=False) return Response(serializer.data, status=status.HTTP_200_OK) + # return Response([], status=status.HTTP_200_OK) def put(self, request, *args, **kwargs): name = request.query_params.get("name") + # print(request.data) 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) + extrainfo = ExtraInfo.objects.get(user=person) + leave_balance = LeaveBalance.objects.get(employeeId=extrainfo) + data1 = request.data + data1['employeeId'] = extrainfo.id + serializer = self.serializer_class(leave_balance, data=data1) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_200_OK) else: + print(serializer.error_messages) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class DropDown(APIView): - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) 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) + # print(designation_list) return Response(designation_list, status=status.HTTP_200_OK) class UserById(APIView): - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) def get(self, request, *args, **kwargs): user_id = request.query_params.get("id") @@ -517,7 +525,7 @@ def get(self, request, *args, **kwargs): class ViewArchived(APIView): - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) def get(self, request, *args, **kwargs): user_name = request.query_params.get("username") @@ -528,11 +536,11 @@ def get(self, request, *args, **kwargs): class GetOutbox(APIView): - permission_classes = (AllowAny, ) + permission_classes = (IsAuthenticated, ) 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 + return Response(outbox, status=status.HTTP_200_OK) diff --git a/FusionIIIT/applications/hr2/api/serializers.py b/FusionIIIT/applications/hr2/api/serializers.py index f10854eea..63efc27cc 100644 --- a/FusionIIIT/applications/hr2/api/serializers.py +++ b/FusionIIIT/applications/hr2/api/serializers.py @@ -53,4 +53,13 @@ class Meta: fields = '__all__' def create(self, validated_data): - return LeaveBalance.objects.create(**validated_data) \ No newline at end of file + return LeaveBalance.objects.create(**validated_data) + + +# class Deignations(serializers.ModelSerializer): +# class Meta: +# model = Deignations +# fields = '__all__' + +# def create(self,validated_data): +# return diff --git a/FusionIIIT/applications/hr2/api/urls.py b/FusionIIIT/applications/hr2/api/urls.py index 51396e8ef..835434b76 100644 --- a/FusionIIIT/applications/hr2/api/urls.py +++ b/FusionIIIT/applications/hr2/api/urls.py @@ -24,7 +24,10 @@ # create for GetForms url('getForms/', form_views.GetFormHistory.as_view(), name='getForms'), url('leaveBalance/', form_views.CheckLeaveBalance.as_view(), name='leaveBalance'), - + url('getDesignations/', form_views.DropDown.as_view(), name="designations"), + url('getOutbox/', form_views.GetOutbox.as_view(), name='outbox'), + url('getArchive/', form_views.ViewArchived.as_view(), name='archive'), + url('getuserbyid/', form_views.UserById.as_view(), name='userById'), # url(r'^$', views.service_book, name='hr2'), # url(r'^hradmin/$', views.hr_admin, name='hradmin'), # url(r'^edit/(?P\d+)/$', views.edit_employee_details, diff --git a/FusionIIIT/applications/hr2/migrations/0001_initial.py b/FusionIIIT/applications/hr2/migrations/0001_initial.py index 733f5b0bb..78ce3a457 100644 --- a/FusionIIIT/applications/hr2/migrations/0001_initial.py +++ b/FusionIIIT/applications/hr2/migrations/0001_initial.py @@ -1,5 +1,6 @@ -# Generated by Django 3.1.5 on 2024-04-15 23:58 +# Generated by Django 3.1.5 on 2024-07-16 15:44 +from django.conf import settings import django.core.validators from django.db import migrations, models import django.db.models.deletion @@ -11,6 +12,7 @@ class Migration(migrations.Migration): dependencies = [ ('globals', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ @@ -25,6 +27,79 @@ class Migration(migrations.Migration): ('extra_info', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), ], ), + migrations.CreateModel( + name='LTCform', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('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(blank=True, null=True)), + ('leaveEndDate', models.DateField(blank=True, null=True)), + ('dateOfDepartureForFamily', models.DateField(blank=True, null=True)), + ('natureOfLeave', models.TextField(blank=True, null=True)), + ('purposeOfLeave', models.TextField(blank=True, null=True)), + ('hometownOrNot', models.BooleanField(default=False)), + ('placeOfVisit', models.TextField(blank=True, max_length=100, null=True)), + ('addressDuringLeave', models.TextField(null=True)), + ('modeofTravel', models.TextField(blank=True, max_length=10, null=True)), + ('detailsOfFamilyMembersAlreadyDone', models.JSONField(blank=True, null=True)), + ('detailsOfFamilyMembersAboutToAvail', models.JSONField(blank=True, max_length=100, null=True)), + ('detailsOfDependents', models.JSONField(blank=True, null=True)), + ('amountOfAdvanceRequired', models.IntegerField(blank=True, null=True)), + ('certifiedThatFamilyDependents', models.BooleanField(blank=True, null=True)), + ('certifiedThatAdvanceTakenOn', models.DateField(blank=True, null=True)), + ('adjustedMonth', models.TextField(blank=True, max_length=50, null=True)), + ('submissionDate', models.DateField(null=True)), + ('phoneNumberForContact', models.BigIntegerField()), + ('approved', models.BooleanField(null=True)), + ('approvedDate', models.DateField(auto_now_add=True, null=True)), + ('approved_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='LTC_approved_by', to=settings.AUTH_USER_MODEL)), + ('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='LTC_created_by', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='LeaveForm', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('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(blank=True, max_length=40, null=True)), + ('academicResponsibility', models.TextField(blank=True, max_length=40, null=True)), + ('addministrativeResponsibiltyAssigned', models.TextField(max_length=40, null=True)), + ('approved', models.BooleanField(null=True)), + ('approvedDate', models.DateField(auto_now_add=True, null=True)), + ('approved_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='Leave_approved_by', to=settings.AUTH_USER_MODEL)), + ('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='Leave_created_by', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='LeaveBalance', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('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)), + ('employeeId', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), + ], + ), migrations.CreateModel( name='ForeignService', fields=[ @@ -88,4 +163,84 @@ class Migration(migrations.Migration): ('extra_info', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), ], ), + migrations.CreateModel( + name='CPDAReimbursementform', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('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(blank=True, decimal_places=2, max_digits=10, null=True)), + ('balanceAvailable', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), + ('advanceDueAdjustment', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), + ('advanceAmountPDA', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), + ('amountCheckedInPDA', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), + ('submissionDate', models.DateField(auto_now_add=True)), + ('approved', models.BooleanField(null=True)), + ('approvedDate', models.DateField(auto_now_add=True, null=True)), + ('approved_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='CPDAR_approved_by', to=settings.AUTH_USER_MODEL)), + ('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='CPDAR_created_by', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='CPDAAdvanceform', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('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(blank=True, decimal_places=2, max_digits=10, null=True)), + ('submissionDate', models.DateField(blank=True, null=True)), + ('balanceAvailable', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), + ('advanceAmountPDA', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), + ('amountCheckedInPDA', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), + ('approved', models.BooleanField(null=True)), + ('approvedDate', models.DateField(auto_now_add=True, null=True)), + ('approved_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='CPDA_approved_by', to=settings.AUTH_USER_MODEL)), + ('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='CPDA_created_by', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Appraisalform', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('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)), + ('approved_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='Appraisal_approved_by', to=settings.AUTH_USER_MODEL)), + ('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='Appraisal_created_by', to=settings.AUTH_USER_MODEL)), + ], + ), ] diff --git a/FusionIIIT/applications/hr2/migrations/0002_auto_20241012_1459.py b/FusionIIIT/applications/hr2/migrations/0002_auto_20241012_1459.py new file mode 100644 index 000000000..be4738fe2 --- /dev/null +++ b/FusionIIIT/applications/hr2/migrations/0002_auto_20241012_1459.py @@ -0,0 +1,64 @@ +# Generated by Django 3.1.5 on 2024-10-12 14:59 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('hr2', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='appraisalform', + name='employeeId', + field=models.IntegerField(null=True), + ), + migrations.AlterField( + model_name='cpdaadvanceform', + name='amountRequired', + field=models.IntegerField(null=True), + ), + migrations.AlterField( + model_name='cpdaadvanceform', + name='employeeId', + field=models.IntegerField(null=True), + ), + migrations.AlterField( + model_name='cpdaadvanceform', + name='pfNo', + field=models.IntegerField(null=True), + ), + migrations.AlterField( + model_name='cpdareimbursementform', + name='employeeId', + field=models.IntegerField(null=True), + ), + migrations.AlterField( + model_name='cpdareimbursementform', + name='pfNo', + field=models.IntegerField(), + ), + migrations.AlterField( + model_name='empconfidentialdetails', + name='aadhar_no', + field=models.BigIntegerField(default=0, validators=[django.core.validators.MaxValueValidator(999999999999), django.core.validators.MinValueValidator(99999999999)]), + ), + migrations.AlterField( + model_name='leaveform', + name='employeeId', + field=models.IntegerField(null=True), + ), + migrations.AlterField( + model_name='leaveform', + name='pfNo', + field=models.IntegerField(null=True), + ), + migrations.AlterField( + model_name='ltcform', + name='pfNo', + field=models.IntegerField(), + ), + ] diff --git a/FusionIIIT/applications/hr2/models.py b/FusionIIIT/applications/hr2/models.py index 01ca223c7..e225ca076 100644 --- a/FusionIIIT/applications/hr2/models.py +++ b/FusionIIIT/applications/hr2/models.py @@ -78,7 +78,7 @@ class EmpConfidentialDetails(models.Model): table for employee confidential details """ extra_info = models.OneToOneField(ExtraInfo, on_delete=models.CASCADE) - aadhar_no = models.BigIntegerField(default=0, max_length=12, + aadhar_no = models.BigIntegerField(default=0, validators=[MaxValueValidator(999999999999),MinValueValidator(99999999999)]) maritial_status = models.CharField( @@ -149,7 +149,7 @@ class LTCform(models.Model): employeeId = models.IntegerField() name = models.CharField(max_length=100, null=True) blockYear = models.TextField() # - pfNo = models.IntegerField(max_length=50) + pfNo = models.IntegerField() basicPaySalary = models.IntegerField(null=True) designation = models.CharField(max_length=50) departmentInfo = models.CharField(max_length=50) @@ -181,12 +181,12 @@ class LTCform(models.Model): class CPDAAdvanceform(models.Model): id = models.AutoField(primary_key=True) - employeeId = models.IntegerField(max_length=22, null=True) + employeeId = models.IntegerField(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) + pfNo = models.IntegerField(null=True) purpose = models.TextField(max_length=40, null=True) - amountRequired = models.IntegerField(max_length=30,null=True) + amountRequired = models.IntegerField(null=True) advanceDueAdjustment = models.DecimalField(max_digits=10, decimal_places=2, null=True,blank=True) submissionDate = models.DateField(blank=True, null=True) @@ -202,11 +202,11 @@ class CPDAAdvanceform(models.Model): class LeaveForm(models.Model): id = models.AutoField(primary_key=True) - employeeId = models.IntegerField(max_length=22,null=True) + employeeId = models.IntegerField(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) + pfNo = models.IntegerField(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) @@ -237,7 +237,7 @@ class LeaveBalance(models.Model): class Appraisalform(models.Model): id = models.AutoField(primary_key=True) - employeeId = models.IntegerField(max_length=22,null=True) + employeeId = models.IntegerField(null=True) name = models.CharField(max_length=22) designation = models.CharField(max_length=50) disciplineInfo = models.CharField(max_length=22, null=True) @@ -273,10 +273,10 @@ class Appraisalform(models.Model): class CPDAReimbursementform(models.Model): id = models.AutoField(primary_key=True) - employeeId = models.IntegerField(max_length=22,null=True) + employeeId = models.IntegerField(null=True) name = models.CharField(max_length=50) designation = models.CharField(max_length=50) - pfNo = models.IntegerField(max_length=20) + pfNo = models.IntegerField() advanceTaken = models.IntegerField() purpose = models.TextField() adjustmentSubmitted = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) diff --git a/FusionIIIT/applications/income_expenditure/migrations/0001_initial.py b/FusionIIIT/applications/income_expenditure/migrations/0001_initial.py index e772edafa..953bfcf22 100644 --- a/FusionIIIT/applications/income_expenditure/migrations/0001_initial.py +++ b/FusionIIIT/applications/income_expenditure/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-07-16 15:44 from django.db import migrations, models import django.db.models.deletion diff --git a/FusionIIIT/applications/iwdModuleV2/api/serializers.py b/FusionIIIT/applications/iwdModuleV2/api/serializers.py new file mode 100644 index 000000000..1b4e04b4a --- /dev/null +++ b/FusionIIIT/applications/iwdModuleV2/api/serializers.py @@ -0,0 +1,140 @@ +from rest_framework import serializers +from applications.globals.models import * +from applications.iwdModuleV2.models import * +from applications.ps1.models import * + +class WorkOrderFormSerializer(serializers.ModelSerializer): + class Meta: + model = WorkOrder + fields = '__all__' + +class AgreementSerializer(serializers.ModelSerializer): + class Meta: + model = Agreement + fields = '__all__' + +class MilestonesSerializer(serializers.ModelSerializer): + class Meta: + model = Milestones + fields = '__all__' + +class ExtensionOfTimeDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = ExtensionOfTimeDetails + fields = '__all__' + +class ProjectsSerializer(serializers.ModelSerializer): + class Meta: + model = Projects + fields = '__all__' + +class DesignationSerializer(serializers.ModelSerializer): + class Meta: + model = Designation + fields = ['id', 'name'] + +class HoldsDesignationSerializer(serializers.ModelSerializer): + designation = DesignationSerializer() + username = serializers.CharField(source='user.username') + + class Meta: + model = HoldsDesignation + fields = ['id', 'designation', 'username'] + +class CreateRequestsSerializer(serializers.ModelSerializer): + class Meta: + model = Requests + fields = ['id', 'name', 'area', 'description', 'requestCreatedBy'] + + def create(self, validated_data): + validated_data['engineerProcessed'] = 0 + validated_data['directorApproval'] = 0 + validated_data['deanProcessed'] = 0 + validated_data['status'] = "Pending" + validated_data['issuedWorkOrder'] = 0 + validated_data['workCompleted'] = 0 + validated_data['billGenerated'] = 0 + validated_data['billProcessed'] = 0 + validated_data['billSettled'] = 0 + return super().create(validated_data) + +class DirectorApprovedRequestsSerializer(serializers.ModelSerializer): + class Meta: + model = Requests + fields = ['id', 'name', 'area', 'description', 'requestCreatedBy'] + +class WorkUnderProgressSerializer(serializers.ModelSerializer): + class Meta: + model = Requests + fields = ['id', 'name', 'area', 'description', 'requestCreatedBy', 'issuedWorkOrder', 'workCompleted'] + + +class RequestsInProgressSerializer(serializers.ModelSerializer): + class Meta: + model = Requests + fields = ['id', 'name', 'area', 'description', 'requestCreatedBy', 'issuedWorkOrder', 'workCompleted'] + +class PageOneDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = PageOneDetails + fields = '__all__' + +class PageTwoDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = PageTwoDetails + fields = '__all__' + +class PageThreeDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = PageThreeDetails + fields = '__all__' + +class AESDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = AESDetails + fields = '__all__' + +class CorrigendumTableSerializer(serializers.ModelSerializer): + class Meta: + model = CorrigendumTable + fields = '__all__' + +class AddendumSerializer(serializers.ModelSerializer): + class Meta: + model = Addendum + fields = '__all__' + +class PreBidDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = PreBidDetails + fields = '__all__' + +class NoOfTechnicalBidTimesSerializer(serializers.ModelSerializer): + class Meta: + model = NoOfTechnicalBidTimes + fields = '__all__' + +class TechnicalBidDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = TechnicalBidDetails + fields = '__all__' + +class TechnicalBidContractorDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = TechnicalBidContractorDetails + fields = '__all__' + +class FinancialBidDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = FinancialBidDetails + fields = '__all__' + +class FinancialContractorDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = FinancialContractorDetails + fields = '__all__' + +class LetterOfIntentDetailsSerializer(serializers.ModelSerializer): + class Meta: + model = LetterOfIntentDetails + fields = '__all__' \ No newline at end of file diff --git a/FusionIIIT/applications/iwdModuleV2/api/urls.py b/FusionIIIT/applications/iwdModuleV2/api/urls.py new file mode 100644 index 000000000..5b0bd02a8 --- /dev/null +++ b/FusionIIIT/applications/iwdModuleV2/api/urls.py @@ -0,0 +1,70 @@ +from django.urls import path +from . import views +urlpatterns = [ + + # fully implemented + + path('fetch-designations/', views.fetch_designations, name='fetch_designations'), + path('fetch-designations/', views.fetch_designations, name='fetch_designations'), + path('create-request/', views.create_request, name='create_request'), + path('created-requests/', views.created_requests, name='created_requests'), + path('view-file/', views.view_file, name='view_file'), + path('dean-processed-requests/', views.dean_processed_requests, name='dean_processed_requests'), + path('handle-director-approval/', views.handle_director_approval, name='handle_director_approval'), + path('handle-engineer-process/', views.handle_engineer_process_requests, name='handle_engineer_process_requests'), + path('handle-dean-process-request/', views.handle_dean_process_request, name='handleDeanProcessRequests'), + path('rejected-requests-view/', views.rejected_requests, name='rejectedRequests'), + path('handle-update-requests/', views.handle_update_requests, name='handleUpdateRequests'), + path('director-approved-requests/', views.director_approved_requests, name='issueWorkOrder'), + path('issue-work-order/', views.issue_work_order, name='workOrder'), + path('requests-in-progress/', views.requests_in_progress, name='requestsInProgress'), + path('work-under-progress/', views.work_under_progress, name='workUnderProgress'), + path('work-completed/', views.work_completed, name='workCompleted'), + path('view-budget/', views.view_budget, name='viewBudget'), + path('add-budget/', views.add_budget, name='addBudget'), + path('edit-budget/', views.edit_budget, name='editBudget'), + path('requests-status/', views.requests_status, name='requestsStatus'), + path('audit-document-view/', views.audit_document_view, name='auditDocumentView'), + path('audit-document/', views.handle_audit_document, name='auditDocument'), + + # partially integrated on frontend + path('handle-process-bills/', views.handle_process_bills, name='handleProcessedBills'), + + path('engineer-processed-requests/', views.engineer_processed_requests, name='engineerProcessedRequests'), + path('generate-final-bill/', views.generateFinalBill, name='generateFinalBill'), + path('handle-bill-generated-requests/', views.handleBillGeneratedRequests, name='handleBillGeneratedRequests'), + path('generated-bills-view/', views.generatedBillsView, name='generatedBillsView'), + path('settle-bills-view/', views.settle_bills_view, name='settleBillsView'), + path('handle-settle-bill-request/', views.handle_settle_bill_requests, name='handleSettleBillRequest'), + + # Unsure about use or depricated + + # path('page1-1/', views.page1_1, name='page1_1'), + # path('aes-form/', views.AESForm, name='AESForm'), + # path('page2-1/', views.page2_1, name='page2_1'), + # path('corrigendum-input/', views.corrigendumInput, name='corrigendumInput'), + # path('addendum-input/', views.addendumInput, name='addendumInput'), + # path('pre-bid-form/', views.PreBidForm, name='PreBidForm'), + # path('no-of-entries-technical-bid/', views.noOfEntriesTechnicalBid, name='noOfEntriesTechnicalBid'), + # path('technical-bid-form/', views.TechnicalBidForm, name='TechnicalBidForm'), + # path('no-of-entries-financial-bid/', views.noOfEntriesFinancialBid, name='noOfEntriesFinancialBid'), + # path('letter-of-intent/', views.letterOfIntent, name='letterOfIntent'), + # path('agreement-input/', views.AgreementInput, name='AgreementInput'), + # path('milestones-form/', views.milestonesForm, name='milestonesForm'), + # path('page3-1/', views.page3_1, name='page3_1'), + # path('extension-of-time-form/', views.ExtensionOfTimeForm, name='ExtensionOfTimeForm'), + # path('page1-view/', views.page1View, name='page1View'), + # path('page2-view/', views.page2View, name='page2View'), + # path('aes-view/', views.AESView, name='AESView'), + # path('financial-bid-view/', views.financialBidView, name='financialBidView'), + # path('technical-bid-view/', views.technicalBidView, name='technicalBidView'), + # path('pre-bid-details-view/', views.preBidDetailsView, name='preBidDetailsView'), + # path('corrigendum-view/', views.corrigendumView, name='corrigendumView'), + # path('addendum-view/', views.addendumView, name='addendumView'), + # path('letter-of-intent-view/', views.letterOfIntentView, name='letterOfIntentView'), + # path('agreement-view/', views.agreementView, name='agreementView'), + # path('milestone-view/', views.milestoneView, name='milestoneView'), + # path('page3-view/', views.page3View, name='page3View'), + # path('extension-form-view/', views.extensionFormView, name='extensionFormView'), +] + diff --git a/FusionIIIT/applications/iwdModuleV2/api/views.py b/FusionIIIT/applications/iwdModuleV2/api/views.py new file mode 100644 index 000000000..069b3fda0 --- /dev/null +++ b/FusionIIIT/applications/iwdModuleV2/api/views.py @@ -0,0 +1,1176 @@ +from rest_framework.decorators import api_view, permission_classes +from rest_framework.response import Response +from rest_framework import status +from rest_framework.permissions import IsAuthenticated +from applications.globals.models import * +from applications.iwdModuleV2.models import * +from applications.ps1.models import * +from applications.filetracking.sdk.methods import * +from notification.views import iwd_notif +from .serializers import * +from django.shortcuts import get_object_or_404 +from django.contrib import messages +from reportlab.lib.pagesizes import letter +from reportlab.pdfgen import canvas +from reportlab.platypus import Table, TableStyle +from reportlab.lib import colors +from io import BytesIO +from django.http import HttpResponse +from django.core.exceptions import ObjectDoesNotExist + +# @api_view(['GET']) +# def dashboard(request): +# userObj = request.user +# userDesignationObjects = HoldsDesignation.objects.filter(user=userObj) +# eligible = any(p.designation.name == 'Admin IWD' for p in userDesignationObjects) +# return Response({'eligible': eligible}) + +''' + Fully Implemented +''' + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def fetch_designations(request): + ''' + to return a list of cincerned designations in the module's scope + ''' + holdsDesignations = [] + + designations = Designation.objects.filter(name__in=designations_list) + + for designation in designations: + holds = HoldsDesignation.objects.filter(designation=designation) + serializer = HoldsDesignationSerializer(holds, many=True) + holdsDesignations.extend(serializer.data) + + return Response({'holdsDesignations': holdsDesignations}, status=status.HTTP_200_OK) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def create_request(request): + + ''' + to create a new request + ''' + data = request.data + data['requestCreatedBy'] = request.user.username + data['requestCreatedBy'] = request.user.username + serializer = CreateRequestsSerializer(data=data, context={'request': request}) + + if serializer.is_valid(): + formObject = serializer.save() + print(formObject.requestCreatedBy) + request_object = Requests.objects.get(pk=formObject.pk) + receiver_desg, receiver_user = data.get('designation').split('|') + try: + receiver_user_obj = User.objects.get(username=receiver_user) + except User.DoesNotExist: + return Response({'error': 'Receiver user does not exist'}, status=status.HTTP_400_BAD_REQUEST) + create_file( + uploader=request.user.username, + uploader_designation=data.get('role'), + receiver=receiver_user, + receiver_designation=receiver_desg, + src_module="IWD", + src_object_id=str(request_object.id), + file_extra_JSON={"value": 2}, + attached_file=None + ) + + + iwd_notif(request.user, receiver_user_obj, "Request_added") + + return Response({'message': "Request Successfully Created"}, status=status.HTTP_201_CREATED) + + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def created_requests(request): + + ''' + to get a list of requests in current user's inbox + ''' + + params = request.query_params + obj = [] + inbox_files = view_inbox( + username=request.user, + designation=params.get('role'), + src_module="IWD" + ) + for result in inbox_files: + src_object_id = result['src_object_id'] + request_object = Requests.objects.filter(id=src_object_id).first() + if request_object: + file_obj = get_object_or_404(File, src_object_id=request_object.id, src_module="IWD") + element = { + 'request_id': request_object.id, + 'name': request_object.name, + 'area': request_object.area, + 'description': request_object.description, + 'requestCreatedBy': request_object.requestCreatedBy, + 'file_id': file_obj.id, + 'directorApproval': request_object.directorApproval, + 'processed_by_dean': request_object.deanProcessed, + } + obj.append(element) + + return Response(obj, status=200) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def view_file(request): + + ''' + get complete file data and track records + ''' + + params = request.query_params + id = params.get('file_id') + print(id) + file1 = get_object_or_404(File, id=id) + + tracks = Tracking.objects.filter(file_id=file1) + + file_serializer = FileSerializer(file1) + tracks_serializer = TrackingSerializer(tracks, many=True) + return Response({ + "file": file_serializer.data, + "tracks": tracks_serializer.data, + "url": "url", + }, status=200) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def dean_processed_requests(request): + + ''' + to get requests that have been processed through the dean and are ready for director's approval + ''' + + obj = [] + params = request.query_params + desg = params.get('role') + + inbox_files = view_inbox( + username=request.user.username, + designation=desg, + src_module="IWD" + ) + + for result in inbox_files: + src_object_id = result['src_object_id'] + request_object = Requests.objects.filter(id=src_object_id, directorApproval=0).first() + file_obj = File.objects.get(src_object_id=src_object_id, src_module="IWD") + if request_object: + element = { + 'request_id': request_object.id, + 'name': request_object.name, + 'area': request_object.area, + 'description': request_object.description, + 'requestCreatedBy': request_object.requestCreatedBy, + 'file_id': file_obj.id, + 'directorApproval': request_object.directorApproval, + } + obj.append(element) + + return Response(obj) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_dean_process_request(request): + + ''' + This api is made for the dean to process and forward the request + ''' + + data = request.data + fileid = data.get('fileid') + request_id = File.objects.get(id=fileid).src_object_id + + remarks = data.get('remarks') + attachment = request.FILES.get('file') + receiver_desg, receiver_user = data.get('designation').split('|') + + forward_file( + file_id=fileid, + receiver=receiver_user, + receiver_designation=receiver_desg, + file_extra_JSON={"message": "Request forwarded."}, + remarks=remarks, + file_attachment=attachment, + ) + + Requests.objects.filter(id=request_id).update(deanProcessed=1, status="Approved by the dean", directorApproval=0) + receiver_user_obj = get_object_or_404(User, username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "file_forward") + return Response({'message': 'File Forwarded'}, status=200) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_engineer_process_requests(request): + data = request.data + fileid = data.get('fileid') + request_id = File.objects.get(id=fileid).src_object_id + + remarks = data.get('remarks') + attachment = request.FILES.get('file') + receiver_desg, receiver_user = data.get('designation').split('|') + + forward_file( + file_id=fileid, + receiver=receiver_user, + receiver_designation=receiver_desg, + file_extra_JSON={"message": "Request forwarded."}, + remarks=remarks, + file_attachment=attachment, + ) + + Requests.objects.filter(id=request_id).update(engineerProcessed=1) + receiver_user_obj = get_object_or_404(User, username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "file_forward") + + return Response({ + "message": "File forwarded successfully", + }, status=status.HTTP_200_OK) + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_director_approval(request): + + ''' + This api is to approve or reject file based on director's action + ''' + + data = request.data + fileid = data.get('fileid') + request_id = File.objects.get(id=fileid).src_object_id + + remarks = data.get('remarks') + attachment = request.FILES.get('file') + receiver_desg, receiver_user = data.get('designation').split('|') + + if not fileid: + return Response({'error': 'File ID not provided'}, status=status.HTTP_400_BAD_REQUEST) + + forward_file( + file_id=fileid, + receiver=receiver_user, + receiver_designation=receiver_desg, + file_extra_JSON={"message": "Request forwarded."}, + remarks=remarks, + file_attachment=attachment, + ) + receiver_user_obj = get_object_or_404(User, username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "file_forward") + message = "" + print(data) + if data.get('action') == 'approve': + message = "Request_approved" + print(message) + Requests.objects.filter(id=request_id).update(directorApproval=1, status="Approved by the director") + else: + message = "Request_rejected" + Requests.objects.filter(id=request_id).update(directorApproval=-1, status="Rejected by the director") + + return Response({'message': message}) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_audit_document(request): + + ''' + This api is used to audit bill documents (with provided fileid) + ''' + + fileid = request.data.get('fileid') + remarks = request.data.get('remarks') + attachment = request.FILES.get('attachment') + receiver_desg, receiver_user = request.data['designation'].split('|') + + if fileid: + request_id = File.objects.get(id=fileid).src_object_id + + forward_file( + file_id=fileid, + receiver=receiver_user, + receiver_designation=receiver_desg, + file_extra_JSON={"message": "Request forwarded."}, + remarks=remarks, + file_attachment=attachment, + ) + + Requests.objects.filter(id=request_id).update(status="Bill Audited") + + return Response("Bill Audited", status=status.HTTP_200_OK) + + return Response({'error': 'File ID not provided'}, status=status.HTTP_400_BAD_REQUEST) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def rejected_requests(request): + + ''' + get requests rejected by director (-1) + ''' + + obj = [] + desg = request.query_params.get('role') + + inbox_files = view_inbox( + username=request.user, + designation=desg, + src_module="IWD" + ) + + for result in inbox_files: + src_object_id = result['src_object_id'] + if src_object_id==None: + continue + request_object = Requests.objects.filter(id=src_object_id, directorApproval=-1).first() + if request_object: + element = { + 'id': request_object.id, + 'name': request_object.name, + 'area': request_object.area, + 'description': request_object.description, + 'requestCreatedBy': request_object.requestCreatedBy + } + obj.append(element) + + return Response(obj, status=status.HTTP_200_OK) + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_update_requests(request): + + ''' + to update an old request(delete and make a new one) + ''' + data = request.data + request_id = data.get("id") + desg = data.get('role') + receiver_desg, receiver_user = data.get('designation').split('|') + + Requests.objects.filter(id=request_id).update( + name=request.data.get('name'), + description=request.data.get('description'), + area=request.data.get('area'), + engineerProcessed=0, + directorApproval=0, + deanProcessed=0, + requestCreatedBy=request.user.username, + status="Pending", + issuedWorkOrder=0, + workCompleted=0, + billGenerated=0, + billProcessed=0, + billSettled=0 + ) + + try: + file_obj = File.objects.get(src_object_id=request_id, src_module="IWD") + if file_obj: + delete_file(file_obj.id) + except: + print("file doesnt exist") + if request_id: + create_file( + uploader=request.user.username, + uploader_designation=desg, + receiver=receiver_user, + receiver_designation=receiver_desg, + src_module="IWD", + src_object_id=str(request_id), + file_extra_JSON={"value": 2}, + attached_file=None + ) + else: + print("request id is invalid") + + receiver_user_obj = User.objects.get(username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "Request_added") + + return Response({"message": "Request updated successfully"}, status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def director_approved_requests(request): + + ''' + requests approved by director and can issue work order + ''' + + requestsObject = Requests.objects.filter(directorApproval=1, issuedWorkOrder=0) + serializer = DirectorApprovedRequestsSerializer(requestsObject, many=True) + print(serializer.data) + return Response(serializer.data, status=status.HTTP_200_OK) + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def issue_work_order(request): + + ''' + issue work order + ''' + + request_id = request.data.get('request_id') + request_instance = get_object_or_404(Requests, pk=request_id) + serializer = WorkOrderFormSerializer(data=request.data) + print(serializer) + if serializer.is_valid(): + work_order = serializer.save(request_id=request_instance) + + request_instance.status = "Work Order issued" + request_instance.issuedWorkOrder = 1 + request_instance.save() + + messages.success(request, "Work Order Issued") + return Response(status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def work_under_progress(request): + + ''' + This api is used to get all requests under progress + ''' + + obj = [] + requestsObject = Requests.objects.filter(issuedWorkOrder=1, workCompleted=0) + serializer = WorkUnderProgressSerializer(requestsObject, many=True) + print(serializer.data) + for result in serializer.data: + src_object_id = result['id'] + file_obj = File.objects.get(src_object_id=src_object_id, src_module="IWD") + if file_obj: + element = { + 'id': result['id'], + 'file_id': file_obj.id, + 'name': result['name'], + 'area': result['area'], + 'description': result['description'], + 'issuedWorkOrder': result['issuedWorkOrder'], + 'workCompleted': result['workCompleted'], + 'requestCreatedBy': result['requestCreatedBy'] + } + obj.append(element) + + return Response(obj, status=status.HTTP_200_OK) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def requests_in_progress(request): + + ''' + work order issued but not completed + ''' + + requestsObject = Requests.objects.filter(issuedWorkOrder=1) + serializer = RequestsInProgressSerializer(requestsObject, many=True) + return Response(serializer.data, status=200) + + + +@api_view(['PATCH']) +@permission_classes([IsAuthenticated]) +def work_completed(request): + + ''' + to mark the work as completed + ''' + + request_id = request.data.get('id') + Requests.objects.filter(id=request_id).update(workCompleted=1, status="Work Completed") + return Response( + { + 'message': 'Work Completed', + }, + status=status.HTTP_200_OK + ) + + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def view_budget(request): + + ''' + view budget list + ''' + + budget_objects = Budget.objects.all() + obj = [] + + for x in budget_objects: + element = { + "id": x.id, + "name": x.name, + "budgetIssued": x.budgetIssued + } + obj.append(element) + + return Response({'obj': obj}, status=status.HTTP_200_OK) + + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def add_budget(request): + ''' + add new budget + ''' + name = request.data.get('name') + budget_issued = request.data.get('budget') + + if name and budget_issued: + formObject = Budget(name=name, budgetIssued=budget_issued) + formObject.save() + return Response({'message': 'Budget added successfully.'}, status=status.HTTP_201_CREATED) + else: + return Response({'error': 'Name and budget are required.'}, status=status.HTTP_400_BAD_REQUEST) + + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def edit_budget(request): + + ''' + edit an existing budget + ''' + + budget_id = request.data.get('id') + budget_name = request.data.get('name') + budget_issued = request.data.get('budget') + + if budget_id and budget_name and budget_issued: + Budget.objects.filter(id=budget_id).update(name=budget_name, budgetIssued=budget_issued) + return Response({'message': 'Budget updated successfully.'}, status=status.HTTP_200_OK) + else: + return Response({'error': 'ID, name, and budget are required.'}, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def requests_status(request): + + ''' + this api will get status of all the requests in outbox of user + ''' + + params = request.query_params + desg = params.get('role') + outbox_files = view_outbox(username=request.user, designation=desg, src_module="IWD") + obj = [] + for result in outbox_files: + src_object_id = result['src_object_id'] + request_object = Requests.objects.filter(id=src_object_id).first() + file_obj = File.objects.get(src_object_id=src_object_id, src_module="IWD") + print(request_object) + if request_object: + element = { + 'request_id': request_object.id, + 'name': request_object.name, + 'area': request_object.area, + 'description': request_object.description, + 'requestCreatedBy': request_object.requestCreatedBy, + 'file_id': file_obj.id, + 'processed_by_director': request_object.directorApproval, + 'processed_by_dean': request_object.deanProcessed, + 'status': request_object.status, + } + obj.append(element) + return Response(obj, status=200) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def audit_document_view(request): + + ''' + This api is used to get a list of all the bills those are required to be audited + ''' + + params = request.query_params + desg = params.get('role') + if not desg: + return Response({"error": "Designation not provided"}, status=status.HTTP_400_BAD_REQUEST) + + inbox_files = view_inbox(username=request.user, designation=desg, src_module="IWD") + + obj = [] + for x in inbox_files: + try: + bill = Bills.objects.get(request_id=x['src_object_id']) # Efficient single query + file_obj = File.objects.get(src_object_id=x['src_object_id'], src_module="IWD") # Ensure this object exists + obj.append({ + 'request_id': x['src_object_id'], + 'file': bill.file, + 'fileUrl': bill.file.url, + 'file_id': file_obj.id + }) + except Bills.DoesNotExist: + print('bill with request_id ', x['src_object_id'], " not found") + except File.DoesNotExist: + print('file with request_id ', x['src_object_id'], " not found") + + print(obj) + return Response(obj, status=status.HTTP_200_OK) + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_process_bills(request): + + ''' + This api is used to submit (process) a bill + ''' + + obj = request.data + + fileid = obj.get('fileid') + try: + request_id = File.objects.get(id=fileid).src_object_id + except ObjectDoesNotExist: + return Response({'error': 'File not found.'}, status=status.HTTP_404_NOT_FOUND) + + remarks = obj.get('remarks') + attachment = request.FILES.get('attachment') + receiver_desg, receiver_user = obj['designation'].split('|') + + forward_file( + file_id=fileid, + receiver=receiver_user, + receiver_designation=receiver_desg, + file_extra_JSON={"message": "Request forwarded."}, + remarks=remarks, + file_attachment=attachment, + ) + + Requests.objects.filter(id=request_id).update(billProcessed=1, status="Final Bill Processed") + + request_instance = Requests.objects.get(pk=request_id) + + formObject = Bills() + formObject.request_id = request_instance + formObject.file = attachment + formObject.save() + receiver_user_obj = User.objects.get(username=receiver_user) + iwd_notif(request.user, receiver_user_obj, "file_forward") + + return Response({'obj': obj}, status=status.HTTP_200_OK) + + +@api_view(['POST']) +def page1_1(request): + project_id = request.data.get('name') + request.session['projectId'] = project_id + project = Projects(id=project_id) + project.save() + + serializer = PageOneDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(id=project) # Assign the project instance + return Response({'message': 'Page One Details Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['POST']) +def AESForm(request): + serializer = AESDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'AES Details Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['POST']) +def page2_1(request): + request.session['projectId'] = request.data.get('id') + serializer = PageTwoDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(id=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'Page Two Details Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['POST']) +def corrigendumInput(request): + existingObject = CorrigendumTable.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() + + serializer = CorrigendumTableSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'Corrigendum Input Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['POST']) +def addendumInput(request): + existingObject = Addendum.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() + + serializer = AddendumSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'Addendum Input Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['POST']) +def PreBidForm(request): + existingObject = PreBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() + + serializer = PreBidDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'PreBid Form Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['POST']) +def noOfEntriesTechnicalBid(request): + existingObject = NoOfTechnicalBidTimes.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() + + serializer = NoOfTechnicalBidTimesSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({'message': 'Number of Entries for Technical Bid Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['POST']) +def TechnicalBidForm(request): + numberOfTechnicalBidTimes = NoOfTechnicalBidTimes.objects.get(key=Projects.objects.get(id=request.session['projectId'])).number + existingObject = TechnicalBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() + + serializer = TechnicalBidDetailsSerializer(data=request.data) + if serializer.is_valid(): + technical_bid = serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + + TechnicalBidContractorDetails.objects.filter(key=technical_bid).all().delete() + for w in range(numberOfTechnicalBidTimes): + contractor_serializer = TechnicalBidContractorDetailsSerializer(data={ + 'key': technical_bid, + 'name': request.data.get(f'{w}name'), + 'description': request.data.get(f'{w}Description'), + }) + if contractor_serializer.is_valid(): + contractor_serializer.save() + + return Response({'message': 'Technical Bid Form Saved!'}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['POST', 'GET']) +def noOfEntriesFinancialBid(request): + project_id = request.session['projectId'] + objectTechnicalBid = TechnicalBidDetails.objects.get(key=Projects.objects.get(id=project_id)) + objects = TechnicalBidContractorDetails.objects.filter(key=objectTechnicalBid) + + listOfContractors = [t.name for t in objects] + + if request.method == 'POST': + existingObject = FinancialBidDetails.objects.filter(key=Projects.objects.get(id=project_id)) + if existingObject.count() == 1: + existingObject.delete() + + serializer = FinancialBidDetailsSerializer(data=request.data) + if serializer.is_valid(): + financial_bid = serializer.save(key=Projects.objects.get(id=project_id)) + for contractor in listOfContractors: + contractor_serializer = FinancialContractorDetailsSerializer(data={ + 'key': financial_bid, + 'name': contractor, + 'totalCost': request.data[contractor + 'totalCost'], + 'estimatedCost': request.data[contractor + 'estimatedCost'], + 'percentageRelCost': request.data[contractor + 'percentageRelCost'], + 'perFigures': request.data[contractor + 'perFigures'], + }) + if contractor_serializer.is_valid(): + contractor_serializer.save() + return Response({"message": "Financial bid details saved successfully."}, status=status.HTTP_201_CREATED) + + return Response({'list': listOfContractors}, status=status.HTTP_200_OK) + +@api_view(['POST', 'GET']) +def letterOfIntent(request): + if request.method == 'POST': + existingObject = LetterOfIntentDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + if existingObject.count() == 1: + existingObject.delete() + + serializer = LetterOfIntentDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=request.session['projectId'])) + return Response({"message": "Letter of Intent saved successfully."}, status=status.HTTP_201_CREATED) + + return Response({}, status=status.HTTP_200_OK) + +@api_view(['POST', 'GET']) +def AgreementInput(request): + project_id = request.session.get('projectId') + if request.method == 'POST': + existingObject = Agreement.objects.filter(key=Projects.objects.get(id=project_id)) + if existingObject.exists(): + existingObject.delete() + + serializer = AgreementSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=project_id)) + return Response({"message": "Agreement saved successfully."}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + return Response({}, status=status.HTTP_200_OK) + +@api_view(['POST', 'GET']) +def milestonesForm(request): + project_id = request.session.get('projectId') + if request.method == 'POST': + serializer = MilestonesSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=project_id)) + return Response({"message": "Milestone saved successfully."}, status=status.HTTP_201_CREATED) + + Milestones.objects.filter(key=Projects.objects.get(id=project_id)).delete() + return Response({}, status=status.HTTP_200_OK) + + +@api_view(['POST', 'GET']) +def page3_1(request): + if request.method == 'POST': + request.session['projectId'] = request.data['id'] + serializer = PageThreeDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(id=Projects.objects.get(id=request.session['projectId'])) + return Response({"message": "Page 3 details saved successfully."}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + return Response({}, status=status.HTTP_200_OK) + +@api_view(['POST', 'GET']) +def ExtensionOfTimeForm(request): + project_id = request.session.get('projectId') + if request.method == 'POST': + serializer = ExtensionOfTimeDetailsSerializer(data=request.data) + if serializer.is_valid(): + serializer.save(key=Projects.objects.get(id=project_id)) + return Response({"message": "Extension of Time details saved successfully."}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + return Response({}, status=status.HTTP_200_OK) + +@api_view(['POST']) +def page1View(request): + request.session['projectId'] = request.data['id'] + projectPageOne = PageOneDetails.objects.get(id=Projects.objects.get(id=request.session['projectId'])) + return Response({'x': projectPageOne}, status=status.HTTP_200_OK) + +@api_view(['POST']) +def page2View(request): + projectPageTwo = PageTwoDetails.objects.get(id=Projects.objects.get(id=request.session['projectId'])) + return Response({'x': projectPageTwo}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def AESView(request): + objects = AESDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + serializer = AESDetailsSerializer(objects, many=True) + return Response({'AES': serializer.data}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def financialBidView(request): + elements = [] + objects = FinancialBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + for f in objects: + contractorObjects = FinancialContractorDetails.objects.filter(key=f) + for w in contractorObjects: + obj = [f.sNo, f.description, w.name, w.estimatedCost, w.percentageRelCost, w.perFigures, w.totalCost] + elements.append(obj) + return Response({'financial': elements}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def technicalBidView(request): + elements = [] + objects = TechnicalBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + for f in objects: + contractorObjects = TechnicalBidContractorDetails.objects.filter(key=f) + for w in contractorObjects: + obj = [f.sNo, f.requirements, w.name, w.description] + elements.append(obj) + return Response({'technical': elements}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def preBidDetailsView(request): + preBidObjects = PreBidDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + serializer = PreBidDetailsSerializer(preBidObjects, many=True) + return Response({'preBidDetails': serializer.data}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def corrigendumView(request): + try: + corrigendumObject = CorrigendumTable.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = CorrigendumTableSerializer(corrigendumObject) + return Response({'corrigendum': serializer.data}, status=status.HTTP_200_OK) + except CorrigendumTable.DoesNotExist: + return Response({'error': 'Corrigendum not found.'}, status=status.HTTP_404_NOT_FOUND) + +@api_view(['GET']) +def addendumView(request): + try: + addendumObject = Addendum.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = AddendumSerializer(addendumObject) + return Response({'addendum': serializer.data}, status=status.HTTP_200_OK) + except Addendum.DoesNotExist: + return Response({'error': 'Addendum not found.'}, status=status.HTTP_404_NOT_FOUND) + +@api_view(['GET']) +def letterOfIntentView(request): + try: + letterOfIntentObject = LetterOfIntentDetails.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = LetterOfIntentDetailsSerializer(letterOfIntentObject) + return Response({'letterOfIntent': serializer.data}, status=status.HTTP_200_OK) + except LetterOfIntentDetails.DoesNotExist: + return Response({'error': 'Letter of Intent not found.'}, status=status.HTTP_404_NOT_FOUND) + + +@api_view(['GET']) +def agreementView(request): + try: + agreementObject = Agreement.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = AgreementSerializer(agreementObject) + return Response({'agreement': serializer.data}, status=status.HTTP_200_OK) + except Agreement.DoesNotExist: + return Response({'error': 'Agreement not found.'}, status=status.HTTP_404_NOT_FOUND) + +@api_view(['GET']) +def milestoneView(request): + milestoneObjects = Milestones.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + serializer = MilestonesSerializer(milestoneObjects, many=True) + return Response({'milestones': serializer.data}, status=status.HTTP_200_OK) + +@api_view(['GET']) +def page3View(request): + try: + pageThreeDetails = PageThreeDetails.objects.get(key=Projects.objects.get(id=request.session['projectId'])) + serializer = PageThreeDetailsSerializer(pageThreeDetails) + return Response({'pageThreeDetails': serializer.data}, status=status.HTTP_200_OK) + except PageThreeDetails.DoesNotExist: + return Response({'error': 'Page Three Details not found.'}, status=status.HTTP_404_NOT_FOUND) + +@api_view(['GET']) +def extensionFormView(request): + extensionObjects = ExtensionOfTimeDetails.objects.filter(key=Projects.objects.get(id=request.session['projectId'])) + serializer = ExtensionOfTimeDetailsSerializer(extensionObjects, many=True) + return Response({'extension': serializer.data}, status=status.HTTP_200_OK) + +designations_list = ["Junior Engineer", "Executive Engineer (Civil)", "Electrical_AE", "Electrical_JE", "EE", "Civil_AE", "Civil_JE", "Dean (P&D)", "Director", "Accounts Admin", "Admin IWD", "Auditor"] + + + + + + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def engineer_processed_requests(request): + obj = [] + desg = request.session.get('currentDesignationSelected') + + inbox_files = view_inbox( + username=request.user.username, + designation=desg, + src_module="IWD" + ) + + for result in inbox_files: + src_object_id = result['src_object_id'] + request_object = Requests.objects.filter(id=src_object_id).first() + file_obj = File.objects.get(src_object_id=src_object_id, src_module="IWD") + if request_object: + element = { + 'id': request_object.id, + 'name': request_object.name, + 'area': request_object.area, + 'description': request_object.description, + 'requestCreatedBy': request_object.requestCreatedBy, + 'file_id': file_obj.id + } + obj.append(element) + + return Response(obj) + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def generateFinalBill(request): + request_id = request.data.get("id", 0) + + # Fetch the related work order + work_order = WorkOrder.objects.get(request_id=request_id) + + # Fetch IWD items + iwd_items = StockItem.objects.filter(department=34) + + items_list = [] + + # Collecting items related to the request + for x in iwd_items: + stock_entry_id = x.StockEntryId.item_id.file_info + indent_file_objects = IndentFile.objects.filter(file_info=stock_entry_id) + for item in indent_file_objects: + if item.purpose == request_id: + element = [item.item_name, item.quantity, item.estimated_cost, item.file_info.upload_date] + items_list.append(element) + + filename = f"Request_id_{request_id}_final_bill.pdf" + + buffer = BytesIO() + c = canvas.Canvas(buffer, pagesize=letter) + c.setFont("Helvetica", 12) + + y_position = 750 + rid = f"Request Id : {request_id}" + agency = f"Agency : {work_order.agency}" + + c.drawString(100, y_position, rid) + y_position -= 20 + c.drawString(100, y_position, agency) + y_position -= 20 + c.drawString(100, y_position - 40, "Items:") + + # Prepare data for the table + data = [["Item Name", "Quantity", "Cost (in Rupees)", "Date of Purchase", "Total Amount"]] + for item in items_list: + data.append([item[0], str(item[1]), "{:.2f}".format(item[2]), item[3], "{:.2f}".format(item[1] * item[2])]) + + total_amount_to_be_paid = sum(item[1] * item[2] for item in items_list) + c.drawString(100, y_position - 80, f"Total Amount (in Rupees): {total_amount_to_be_paid:.2f}") + + # Create a table for the PDF + table = Table(data) + 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)])) + + table.wrapOn(c, 400, 600) + table.drawOn(c, 100, y_position - 60) + c.save() + + buffer.seek(0) + + response = HttpResponse(content_type='application/pdf') + response['Content-Disposition'] = f'attachment; filename="{filename}"' + response.write(buffer.getvalue()) + + return response + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handleBillGeneratedRequests(request): + request_id = request.data.get("id", 0) + # if request_id: + # Requests.objects.filter(id=request_id).update(status="Bill Generated", billGenerated=1) + + # requests_object = Requests.objects.filter(issuedWorkOrder=1, billGenerated=0) + # obj = [] + # for x in requests_object: + # element = { + # "id": x.id, + # "name": x.name, + # "area": x.area, + # "description": x.description, + # "requestCreatedBy": x.requestCreatedBy, + # "workCompleted": x.workCompleted, + # } + # obj.append(element) + + # return Response({'obj': obj}, status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def generatedBillsView(request): + request_objects = Requests.objects.filter(billGenerated=1) + obj = [] + for x in request_objects: + try: + file_obj = File.objects.get(src_object_id=x.id, src_module="IWD") + element = { + "id": x.id, + "name": x.name, + "description": x.description, + "area": x.area, + "requestCreatedBy": x.requestCreatedBy, + "file_id": file_obj.id, + } + obj.append(element) + except File.DoesNotExist: + continue + + return Response({'obj': obj}, status=status.HTTP_200_OK) + + + + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +def settle_bills_view(request): + desg = request.session.get('currentDesignationSelected') + inbox_files = view_inbox(username=request.user, designation=desg, src_module="IWD") + + obj = [ + { + 'requestId': x['src_object_id'], + 'file': Bills.objects.get(request_id=x['src_object_id']).file, + 'fileUrl': Bills.objects.get(request_id=x['src_object_id']).file.url, + 'billSettled': Requests.objects.get(id=x['src_object_id']).billSettled, + 'fileId': File.objects.get(src_object_id=x['src_object_id'], src_module="IWD").id + } + for x in inbox_files + ] + + return Response({'data': obj}, status=status.HTTP_200_OK) + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +def handle_settle_bill_requests(request): + request_id = request.data.get('id') + if request_id: + Requests.objects.filter(id=request_id).update(status="Final Bill Settled", billSettled=1) + + desg = request.session.get('currentDesignationSelected') + inbox_files = view_inbox(username=request.user, designation=desg, src_module="IWD") + + obj = [ + { + 'requestId': x['src_object_id'], + 'file': Bills.objects.get(request_id=x['src_object_id']).file, + 'fileUrl': Bills.objects.get(request_id=x['src_object_id']).file.url, + 'billSettled': Requests.objects.get(id=x['src_object_id']).billSettled, + 'fileId': File.objects.get(src_object_id=x['src_object_id'], src_module="IWD").id + } + for x in inbox_files + ] + + return Response({'message': "Final Bill settled", 'data': obj}, status=status.HTTP_200_OK) + + return Response({'error': 'Request ID not provided'}, status=status.HTTP_400_BAD_REQUEST) + + + diff --git a/FusionIIIT/applications/iwdModuleV2/migrations/0001_initial.py b/FusionIIIT/applications/iwdModuleV2/migrations/0001_initial.py index b86a5c530..5e56f2f96 100644 --- a/FusionIIIT/applications/iwdModuleV2/migrations/0001_initial.py +++ b/FusionIIIT/applications/iwdModuleV2/migrations/0001_initial.py @@ -1,5 +1,6 @@ -# Generated by Django 3.1.5 on 2024-04-15 23:58 +# Generated by Django 3.1.5 on 2024-07-16 15:44 +import datetime from django.db import migrations, models import django.db.models.deletion @@ -12,6 +13,14 @@ class Migration(migrations.Migration): ] operations = [ + migrations.CreateModel( + name='Budget', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200)), + ('budgetIssued', models.IntegerField(default=0)), + ], + ), migrations.CreateModel( name='FinancialBidDetails', fields=[ @@ -26,6 +35,25 @@ class Migration(migrations.Migration): ('id', models.CharField(max_length=200, primary_key=True, serialize=False)), ], ), + migrations.CreateModel( + name='Requests', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200)), + ('description', models.CharField(max_length=200)), + ('area', models.CharField(max_length=200)), + ('requestCreatedBy', models.CharField(max_length=200)), + ('engineerProcessed', models.IntegerField(default=0)), + ('directorApproval', models.IntegerField(default=0)), + ('deanProcessed', models.IntegerField(default=0)), + ('status', models.CharField(max_length=200)), + ('issuedWorkOrder', models.IntegerField(default=0)), + ('workCompleted', models.IntegerField(default=0)), + ('billGenerated', models.IntegerField(default=0)), + ('billProcessed', models.IntegerField(default=0)), + ('billSettled', models.IntegerField(default=0)), + ], + ), migrations.CreateModel( name='PageOneDetails', fields=[ @@ -83,6 +111,21 @@ class Migration(migrations.Migration): ('key', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects', unique=True)), ], ), + migrations.CreateModel( + name='WorkOrder', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200)), + ('date', models.DateField(default=datetime.date.today)), + ('agency', models.CharField(max_length=200)), + ('amount', models.IntegerField(default=0)), + ('deposit', models.IntegerField(default=0)), + ('alloted_time', models.CharField(max_length=200)), + ('start_date', models.DateField()), + ('completion_date', models.DateField()), + ('request_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.requests')), + ], + ), migrations.CreateModel( name='TechnicalBidDetails', fields=[ @@ -187,6 +230,14 @@ class Migration(migrations.Migration): ('key', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects', unique=True)), ], ), + migrations.CreateModel( + name='Bills', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('file', models.FileField(upload_to='')), + ('request_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.requests')), + ], + ), migrations.CreateModel( name='Agreement', fields=[ diff --git a/FusionIIIT/applications/iwdModuleV2/migrations/0002_auto_20241015_1451.py b/FusionIIIT/applications/iwdModuleV2/migrations/0002_auto_20241015_1451.py new file mode 100644 index 000000000..8a5daed35 --- /dev/null +++ b/FusionIIIT/applications/iwdModuleV2/migrations/0002_auto_20241015_1451.py @@ -0,0 +1,89 @@ +# Generated by Django 3.1.5 on 2024-10-15 14:51 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('iwdModuleV2', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='pageonedetails', + name='page_id', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + migrations.AddField( + model_name='pagethreedetails', + name='page_id', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + migrations.AddField( + model_name='pagetwodetails', + name='page_id', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + migrations.AlterField( + model_name='addendum', + name='key', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + migrations.AlterField( + model_name='agreement', + name='key', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + migrations.AlterField( + model_name='corrigendumtable', + name='key', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + migrations.AlterField( + model_name='financialbiddetails', + name='key', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + migrations.AlterField( + model_name='letterofintentdetails', + name='key', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + migrations.AlterField( + model_name='nooftechnicalbidtimes', + name='key', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + migrations.AlterField( + model_name='pageonedetails', + name='id', + field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='pagethreedetails', + name='id', + field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='pagetwodetails', + name='id', + field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='prebiddetails', + name='key', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + migrations.AlterField( + model_name='technicalbiddetails', + name='key', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + migrations.AlterField( + model_name='workorderform', + name='key', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='iwdModuleV2.projects'), + ), + ] diff --git a/FusionIIIT/applications/iwdModuleV2/models.py b/FusionIIIT/applications/iwdModuleV2/models.py index 9a3337987..b78b7b3ef 100644 --- a/FusionIIIT/applications/iwdModuleV2/models.py +++ b/FusionIIIT/applications/iwdModuleV2/models.py @@ -9,7 +9,7 @@ class Projects(models.Model): class PageOneDetails(models.Model): - id = models.ForeignKey(Projects, on_delete=models.CASCADE, primary_key=True) + page_id = models.OneToOneField(Projects, on_delete=models.CASCADE, null=True) aESFile = models.FileField(null=True) dASA = models.DateField(null=True) nitNiqNo = models.IntegerField(null=True) @@ -31,7 +31,7 @@ class AESDetails(models.Model): class PageTwoDetails(models.Model): - id = models.ForeignKey(Projects, on_delete=models.CASCADE, primary_key=True) + page_id = models.OneToOneField(Projects, on_delete=models.CASCADE, null=True) corrigendum = models.FileField(null=True) addendum = models.FileField(null=True) preBidMeetingDetails = models.FileField(null=True) @@ -46,7 +46,7 @@ class PageTwoDetails(models.Model): class CorrigendumTable(models.Model): - key = models.ForeignKey(Projects, on_delete=models.CASCADE, unique=True) + key = models.OneToOneField(Projects, on_delete=models.CASCADE) issueDate = models.DateField() nitNo = models.IntegerField() name = models.CharField(max_length=200) @@ -59,7 +59,7 @@ class CorrigendumTable(models.Model): class Addendum(models.Model): - key = models.ForeignKey(Projects, on_delete=models.CASCADE, unique=True) + key = models.OneToOneField(Projects, on_delete=models.CASCADE) issueDate = models.DateField() nitNiqNo = models.IntegerField() name = models.CharField(max_length=200) @@ -68,7 +68,7 @@ class Addendum(models.Model): class PreBidDetails(models.Model): - key = models.ForeignKey(Projects, on_delete=models.CASCADE, unique=True) + key = models.OneToOneField(Projects, on_delete=models.CASCADE) sNo = models.CharField(max_length=200) nameOfParticipants = models.CharField(max_length=200) issuesRaised = models.CharField(max_length=200) @@ -76,7 +76,7 @@ class PreBidDetails(models.Model): class TechnicalBidDetails(models.Model): - key = models.ForeignKey(Projects, on_delete=models.CASCADE, unique=True) + key = models.OneToOneField(Projects, on_delete=models.CASCADE) sNo = models.CharField(max_length=200) requirements = models.CharField(max_length=200) @@ -88,7 +88,7 @@ class TechnicalBidContractorDetails(models.Model): class FinancialBidDetails(models.Model): - key = models.ForeignKey(Projects, on_delete=models.CASCADE, unique=True) + key = models.OneToOneField(Projects, on_delete=models.CASCADE) sNo = models.CharField(max_length=200) description = models.CharField(max_length=200) @@ -103,7 +103,7 @@ class FinancialContractorDetails(models.Model): class LetterOfIntentDetails(models.Model): - key = models.ForeignKey(Projects, on_delete=models.CASCADE, unique=True) + key = models.OneToOneField(Projects, on_delete=models.CASCADE) nitNiqNo = models.IntegerField() dateOfOpening = models.DateField() agency = models.CharField(max_length=200) @@ -112,7 +112,7 @@ class LetterOfIntentDetails(models.Model): class WorkOrderForm(models.Model): - key = models.ForeignKey(Projects, on_delete=models.CASCADE, unique=True) + key = models.OneToOneField(Projects, on_delete=models.CASCADE) issueDate = models.DateField() nitNiqNo = models.IntegerField() agency = models.CharField(max_length=200) @@ -127,7 +127,7 @@ class WorkOrderForm(models.Model): class Agreement(models.Model): - key = models.ForeignKey(Projects, on_delete=models.CASCADE, unique=True) + key = models.OneToOneField(Projects, on_delete=models.CASCADE) date = models.DateField() agencyName = models.CharField(max_length=200) workName = models.CharField(max_length=200) @@ -143,7 +143,7 @@ class Milestones(models.Model): class PageThreeDetails(models.Model): - id = models.ForeignKey(Projects, on_delete=models.CASCADE, primary_key=True) + page_id = models.OneToOneField(Projects, on_delete=models.CASCADE, null=True) extensionOfTime = models.FileField() actualCostOfBuilding = models.IntegerField() @@ -157,12 +157,12 @@ class ExtensionOfTimeDetails(models.Model): class NoOfTechnicalBidTimes(models.Model): - key = models.ForeignKey(Projects, on_delete=models.CASCADE, unique=True) + key = models.OneToOneField(Projects, on_delete=models.CASCADE) number = models.IntegerField() class Requests(models.Model): name = models.CharField(max_length=200) - description = models.CharField(max_length=200) + description = models.CharField(max_length=1000) area = models.CharField(max_length=200) requestCreatedBy = models.CharField(max_length=200) engineerProcessed = models.IntegerField(default=0) @@ -176,7 +176,6 @@ class Requests(models.Model): billSettled = models.IntegerField(default=0) class WorkOrder(models.Model): - # request_id = models.IntegerField() request_id = models.ForeignKey(Requests, on_delete=models.CASCADE) name = models.CharField(max_length=200) date = models.DateField(default=date.today) @@ -188,9 +187,11 @@ class WorkOrder(models.Model): completion_date = models.DateField() class Bills(models.Model): - # requestId = models.IntegerField() request_id = models.ForeignKey(Requests, on_delete=models.CASCADE) file = models.FileField() + # item = models.CharField(max_length=200) + # quantity = models.IntegerField(default=1) + class Budget(models.Model): name = models.CharField(max_length=200) diff --git a/FusionIIIT/applications/iwdModuleV2/urls.py b/FusionIIIT/applications/iwdModuleV2/urls.py index e976034d3..ea025ea14 100644 --- a/FusionIIIT/applications/iwdModuleV2/urls.py +++ b/FusionIIIT/applications/iwdModuleV2/urls.py @@ -6,7 +6,7 @@ urlpatterns = [ - + url(r'^api/', include('applications.iwdModuleV2.api.urls')), url(r'^$', views.dashboard, name='IWD Dashboard'), url(r'^page1_1/$', views.page1_1, name='IWD Page1.1'), url(r'page2_1/$', views.page2_1, name='IWD Page2.1'), diff --git a/FusionIIIT/applications/iwdModuleV2/views.py b/FusionIIIT/applications/iwdModuleV2/views.py index 1f999ebd9..be7042499 100644 --- a/FusionIIIT/applications/iwdModuleV2/views.py +++ b/FusionIIIT/applications/iwdModuleV2/views.py @@ -360,13 +360,13 @@ def page1View(request): if request.POST: request.session['projectId'] = request.POST['id'] projectPageOne = PageOneDetails.objects.get( - id=Projects.objects.get(id=request.session['projectId'])) + id=Projects.objects.get(page_id=request.session['projectId'])) return render(request, 'iwdModuleV2/Page1.html', {'x': projectPageOne}) def page2View(request): projectPageTwo = PageTwoDetails.objects.get( - id=Projects.objects.get(id=request.session['projectId'])) + id=Projects.objects.get(page_id=request.session['projectId'])) return render(request, 'iwdModuleV2/Page2.html', {'x': projectPageTwo}) @@ -445,7 +445,7 @@ def milestoneView(request): def page3View(request): pageThreeDetails = PageThreeDetails.objects.get( - id=Projects.objects.get(id=request.session['projectId'])) + id=Projects.objects.get(page_id=request.session['projectId'])) return render(request, 'iwdModuleV2/Page3.html', {'x': pageThreeDetails}) diff --git a/FusionIIIT/applications/leave/migrations/0001_initial.py b/FusionIIIT/applications/leave/migrations/0001_initial.py index b6fa10f0c..3ffab190b 100644 --- a/FusionIIIT/applications/leave/migrations/0001_initial.py +++ b/FusionIIIT/applications/leave/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-07-16 15:44 from django.conf import settings from django.db import migrations, models @@ -10,8 +10,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('globals', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ diff --git a/FusionIIIT/applications/leave/tasks.py b/FusionIIIT/applications/leave/tasks.py index d29285a92..8460273bd 100644 --- a/FusionIIIT/applications/leave/tasks.py +++ b/FusionIIIT/applications/leave/tasks.py @@ -1,6 +1,6 @@ from __future__ import absolute_import, unicode_literals -import celery +from Fusion.celery import app from django.db import transaction from django.db.models import Q from django.utils import timezone @@ -8,7 +8,7 @@ from .models import LeaveMigration -@celery.task() +@app.task() @transaction.atomic def execute_leave_migrations(): today = timezone.now().date() @@ -27,6 +27,6 @@ def execute_leave_migrations(): migrations.delete() -@celery.task() +@app.task() def testing(a, b): return a+b \ No newline at end of file diff --git a/FusionIIIT/applications/notifications_extension/api/serializers.py b/FusionIIIT/applications/notifications_extension/api/serializers.py index 899c50e57..08a7f7948 100644 --- a/FusionIIIT/applications/notifications_extension/api/serializers.py +++ b/FusionIIIT/applications/notifications_extension/api/serializers.py @@ -1,6 +1,51 @@ from rest_framework import serializers from notifications.models import Notification +from notification.models import Announcements, AnnouncementRecipients +from applications.globals.models import ExtraInfo, DepartmentInfo class NotificationSerializer(serializers.ModelSerializer): class Meta: model = Notification - fields = '__all__' \ No newline at end of file + fields = '__all__' + +class AnnouncementListSerializer(serializers.ModelSerializer): + class Meta: + model = Announcements + fields = '__all__' # Specify the fields you need + + +class AnnouncementSerializer(serializers.ModelSerializer): + specific_users = serializers.ListField( + child=serializers.IntegerField(), write_only=True, required=False + ) # List of specific user IDs for specific_users target group + + class Meta: + model = Announcements + fields = ['message', 'target_group', 'department', 'batch', 'module', 'specific_users'] + + def validate(self, data): + target_group = data.get('target_group') + + # Validate 'faculty' target group: department must be provided + if target_group == 'faculty' and not data.get('department'): + raise serializers.ValidationError("Department is required for faculty announcements.") + + # Validate 'students' target group: department and batch must be provided + if target_group == 'students': + if not data.get('department'): + raise serializers.ValidationError("Department is required for student announcements.") + if not data.get('batch'): + raise serializers.ValidationError("Batch is required for student announcements.") + + return data + + def create(self, validated_data): + specific_users = validated_data.pop('specific_users', []) + announcement = Announcements.objects.create(**validated_data) + + # Handle specific_users for AnnouncementRecipients + if validated_data['target_group'] == 'specific_users': + extra_info_users = ExtraInfo.objects.filter(id__in=specific_users) + for extra_info in extra_info_users: + AnnouncementRecipients.objects.create(announcement=announcement, user=extra_info) + + return announcement \ No newline at end of file diff --git a/FusionIIIT/applications/notifications_extension/api/urls.py b/FusionIIIT/applications/notifications_extension/api/urls.py index 62238c007..c3f42cb17 100644 --- a/FusionIIIT/applications/notifications_extension/api/urls.py +++ b/FusionIIIT/applications/notifications_extension/api/urls.py @@ -24,6 +24,9 @@ MarkAsRead, Delete, NotificationsList, + AnnouncementCreateView, + AnnouncementListView, + RSPCNotificationAPIView ) urlpatterns = [ @@ -50,4 +53,7 @@ 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'), + path('announcements/create', AnnouncementCreateView.as_view(), name='announcement_create'), + path('announcements/', AnnouncementListView.as_view(), name='announcement_list'), + path('RSPC_notif', RSPCNotificationAPIView.as_view(), name='RSPC_notification') ] diff --git a/FusionIIIT/applications/notifications_extension/api/views.py b/FusionIIIT/applications/notifications_extension/api/views.py index c5017f79f..e4c125786 100644 --- a/FusionIIIT/applications/notifications_extension/api/views.py +++ b/FusionIIIT/applications/notifications_extension/api/views.py @@ -7,7 +7,7 @@ from rest_framework.generics import ListAPIView from notifications.models import Notification from rest_framework import status -from .serializers import NotificationSerializer +from .serializers import NotificationSerializer, AnnouncementSerializer, AnnouncementListSerializer from notification.views import (leave_module_notif, placement_cell_notif, academics_module_notif, @@ -30,7 +30,9 @@ department_notif, office_module_DeanRSPC_notif, research_procedures_notif, - hostel_notifications) + hostel_notifications, + announcement_list, + RSPC_notif) @@ -368,4 +370,52 @@ class NotificationsList(ListAPIView): # queryset = Notification.objects.all(actor_object_id=) serializer_class = NotificationSerializer def get_queryset(self): - return Notification.objects.all().filter(recipient_id=self.request.user.id) \ No newline at end of file + return Notification.objects.all().filter(recipient_id=self.request.user.id) + +class AnnouncementCreateView(APIView): + def post(self, request): + # Extract module from request or default to 'Fusion' + module = request.data.get('module', 'Fusion') + request.data['module'] = module + + # Initialize serializer with the request data + serializer = AnnouncementSerializer(data=request.data) + if serializer.is_valid(): + # Save the announcement with the current user as 'created_by' + serializer.save(created_by=request.user) + return Response(serializer.data, status=status.HTTP_201_CREATED) + + # Return error response if data is invalid + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +class AnnouncementListView(APIView): + """ + API View that reuses the announcement_list function to fetch announcements for the user + and return them via an API response. + """ + + def get(self, request): + # Call the existing announcement_list function + announcement_context = announcement_list(request) + + # Get the queryset of announcements from the context + announcements = announcement_context['announcements'] + + # Serialize the queryset + serializer = AnnouncementListSerializer(announcements, many=True) + + # Return the serialized data as JSON response + return Response(serializer.data, status=status.HTTP_200_OK) + +class RSPCNotificationAPIView(APIView): + def post(self, request, *args, **kwargs): + + 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) + + RSPC_notif(sender,recipient, type) + + return Response({'message' : 'Notification sent successfully'}, status=status.HTTP_201_CREATED) \ No newline at end of file diff --git a/FusionIIIT/applications/office_module/migrations/0001_initial.py b/FusionIIIT/applications/office_module/migrations/0001_initial.py index c488a504c..2190b792d 100644 --- a/FusionIIIT/applications/office_module/migrations/0001_initial.py +++ b/FusionIIIT/applications/office_module/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-07-16 15:44 import datetime from django.db import migrations, models @@ -10,10 +10,10 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('filetracking', '0001_initial'), ('globals', '0001_initial'), ('academic_information', '0001_initial'), ('leave', '0001_initial'), + ('filetracking', '0001_initial'), ] operations = [ diff --git a/FusionIIIT/applications/online_cms/api/serializers.py b/FusionIIIT/applications/online_cms/api/serializers.py new file mode 100644 index 000000000..93f79f445 --- /dev/null +++ b/FusionIIIT/applications/online_cms/api/serializers.py @@ -0,0 +1,89 @@ +# from rest_framework.authtoken.models import Token +# from rest_framework import serializers + +# from applications.academic_procedures.models import course_registration + + +from rest_framework import serializers +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.online_cms.models import * + +class ExtraInfoSerializer(serializers.ModelSerializer): + class Meta: + model = ExtraInfo + fields = '__all__' # Include all fields + +class StudentSerializer(serializers.ModelSerializer): + class Meta: + model = Student + fields = '__all__' + +class CourseInstructorSerializer(serializers.ModelSerializer): + class Meta: + model = CourseInstructor + fields = '__all__' + +class CoursesSerializer(serializers.ModelSerializer): + class Meta: + model = Courses + fields = '__all__' + + def create(self,validated_data): + return Courses.objects.create(**validated_data) +class RegisteredCoursesSerializer(serializers.ModelSerializer): + + class Meta: + model = course_registration + fields = ('__all__') +class CourseRegistrationSerializer(serializers.ModelSerializer): + class Meta: + model = Courses + fields = ('__all__') + +class ModulesSerializer(serializers.ModelSerializer): + class Meta: + model = Modules + fields = '__all__' + +class CourseDocumentsSerializer(serializers.ModelSerializer): + class Meta: + model = CourseDocuments + fields = '__all__' + +class AssignmentSerializer(serializers.ModelSerializer): + class Meta: + model = Assignment + fields = '__all__' # Include all fields for now (adjust as needed) + +class AttendanceSerializer(serializers.ModelSerializer): + class Meta: + model = Attendance + fields = '__all__' # Include all fields for now (adjust as needed) + +class ForumSerializer(serializers.ModelSerializer): + class Meta: + model = Forum + fields = '__all__' # Include all fields for now (adjust as needed) + +class ForumReplySerializer(serializers.ModelSerializer): + class Meta: + model = ForumReply + fields = '__all__' # Include all fields for now (adjust as needed) + +class GradingSchemeSerializer(serializers.ModelSerializer): + class Meta: + model = GradingScheme + fields = '__all__' # Include all fields for now (adjust as needed) + +class GradingScheme_gradesSerializer(serializers.ModelSerializer): + class Meta: + model = GradingScheme_grades + fields = '__all__' # Include all fields for now (adjust as needed) +class TopicsSerializer(serializers.ModelSerializer): + class Meta: + model = Topics, + fields = '__all__' diff --git a/FusionIIIT/applications/online_cms/api/urls.py b/FusionIIIT/applications/online_cms/api/urls.py new file mode 100644 index 000000000..87919db4d --- /dev/null +++ b/FusionIIIT/applications/online_cms/api/urls.py @@ -0,0 +1,15 @@ +# from django.conf.urls import url + +# from . import views + +# urlpatterns = [ +# url(r'^courses', views.viewcourses_serialized, name="registered_courses") +# ] +from django.conf.urls import url +# from .views import course +from . import views +urlpatterns = [ + # url(r'^courses', CourseListView.as_view(), name='courses'), + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/$', views.course, name='course'), + url(r'^courses', views.courseview, name='courseview'), +] diff --git a/FusionIIIT/applications/online_cms/api/views.py b/FusionIIIT/applications/online_cms/api/views.py new file mode 100644 index 000000000..23df6aaf3 --- /dev/null +++ b/FusionIIIT/applications/online_cms/api/views.py @@ -0,0 +1,540 @@ +from __future__ import unicode_literals +from django.views.decorators.csrf import csrf_protect +from django.core import serializers +import collections +import json +import os +import random +import subprocess +import datetime +import requests +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, HttpResponseRedirect +from django.shortcuts import redirect, render +from django.utils import timezone +from django.core.serializers import serialize +from django.http import JsonResponse +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 * + +# from .forms import * +# from .helpers import create_thumbnail, semester +# from .models import * +# from .helpers import create_thumbnail, semester +# from notification.views import course_management_notif +# def viewcourses_serialized(request): +# user = request.user +# extrainfo = ExtraInfo.objects.select_related().get(user=user) + +# # If the user is a student +# if extrainfo.user_type == 'student': +# student = Student.objects.select_related('id').get(id=extrainfo) +# register = course_registration.objects.select_related().filter(student_id=student) + +# # Serialize registered courses +# registered_courses_data = serializers.serialize('json', register) + +# return JsonResponse({ +# 'user_type': 'student', +# 'registered_courses': registered_courses_data, +# }) + +# # If the user is faculty +# elif extrainfo.user_type == 'faculty': +# instructor = CourseInstructor.objects.select_related('curriculum_id').filter(instructor_id=extrainfo) +# curriculum_list = [Courses.objects.select_related().get(pk=x.course_id) for x in instructor] + +# # Serialize curriculum list +# curriculum_data = serializers.serialize('json', curriculum_list) + +# return JsonResponse({ +# 'user_type': 'faculty', +# 'curriculum_list': curriculum_data, +# }) + +# # If the user is an admin +# elif extrainfo.id == 'id_admin': +# # if request.session.get('currentDesignationSelected') != 'acadadmin': +# # return HttpResponseRedirect('/dashboard/') + +# calendar = Calendar.objects.all() +# timetable = Timetable.objects.all() + +# # Serialize calendar and timetable data +# calendar_data = serializers.serialize('json', calendar) +# timetable_data = serializers.serialize('json', timetable) + +# return JsonResponse({ +# 'user_type': 'admin', +# 'academic_calendar': calendar_data, +# 'timetable': timetable_data, +# }) + +# return JsonResponse({ +# 'error': 'Unknown user type' +# }) + +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework.decorators import api_view +from rest_framework import status # Import for custom status codes +from .serializers import * +# class CourseListView(APIView): +# def get(self, request): +# user = request.user + +# try: +# extrainfo = ExtraInfo.objects.select_related().get(user=user) +# except ExtraInfo.DoesNotExist: +# return Response({'message': 'ExtraInfo object not found for this user'}, status=status.HTTP_404_NOT_FOUND) + +# if extrainfo.user_type == 'student': +# try: +# student = Student.objects.select_related('id').get(id=extrainfo) +# register = course_registration.objects.select_related().filter(student_id=student) +# except (Student.DoesNotExist, course_registration.DoesNotExist): +# return Response({'message': 'No courses found for this student'}, status=status.HTTP_404_NOT_FOUND) + +# courses = collections.OrderedDict() +# for reg in register: +# # instructor = CourseInstructor.objects.select_related().get(course_id=reg.course_id).first() +# instructors = CourseInstructor.objects.select_related().filter(course_id=reg.course_id) +# instructor = instructors.first() # Get the first instructor + +# courses[reg] = instructor + +# courses_serializer = CoursesSerializer(courses, many=True) # Assuming CourseRegistrationSerializer exists +# return Response(courses_serializer.data) +# elif extrainfo.user_type == 'faculty': +# # ... similar logic for faculty courses ... + +# return Response(faculty_courses_serializer.data) # Assuming faculty_courses_serializer exists +# elif extrainfo.user_type == 'id_admin': +# # ... similar logic for admin courses ... + +# return Response(admin_courses_serializer.data) # Assuming admin_courses_serializer exists +# else: +# return Response({'message': 'Invalid user type'}, status=status.HTTP_400_BAD_REQUEST) + +@api_view(['GET']) +def courseview(request): + user = request.user + extrainfo = ExtraInfo.objects.select_related().get(user=user) + if extrainfo.user_type == 'student': + student = Student.objects.select_related('id').get(id=extrainfo) + # register = course_registration.objects.select_related().filter(student_id=student) + # courses_info = Courses.objects.select_related().filter(id=register) + + # course_serializer = CourseRegistrationSerializer(course_infos, many=True) + register = course_registration.objects.select_related().filter(student_id=student) + + courses_info = [] + for reg in register: + course = Courses.objects.select_related().get(pk=reg.course_id.id) # Optimized retrieval using primary key + courses_info.append(course) + + course_serializer = CourseRegistrationSerializer(courses_info, many=True) + print(course_serializer) + data ={ + "courses":course_serializer.data + } + return Response(data,status=status.HTTP_200_OK) + + elif extrainfo.user_type == 'faculty': + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) + courses_info=[] + for ins in instructor: + course = Courses.objects.select_related().get(pk=ins.course_id.id) + courses_info.append(course) + + course_serializer = CourseRegistrationSerializer(courses_info, many=True) + data = { + "courses":course_serializer.data + } + return Response(data, status=status.HTTP_200_OK) + else: + return Response({"error":"error occured"}) + +@api_view(['GET']) +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) + #info about courses he is registered in + course = Courses.objects.select_related().get(code=course_code, version = version) + #instructor of the course + instructor = CourseInstructor.objects.select_related().get(course_id = course, batch_id = student.batch_id) + + # Serialize course and instructor + course_serializer = CoursesSerializer(course) + instructor_serializer = CourseInstructorSerializer(instructor) + #course material uploaded by the instructor + # videos = CourseVideo.objects.filter(course_id=course) + videos = [] + if request.method == 'POST': + search_url = "https://www.googleapis.com/youtube/v3/search" + video_url = "https://www.googleapis.com/youtube/v3/videos" + search_params = { + 'part': 'snippet', + 'q': request.POST['search'], + 'key': settings.YOUTUBE_DATA_API_KEY, + 'type': 'video', + 'channelId': 'channel_id' + } + videos_ids = [] + r = requests.get(search_url, params=search_params) + # print(r) + results = r.json()['items'] + for result in results: + videos_ids.append(result['id']['videoId']) + + video_params = { + 'key': settings.YOUTUBE_DATA_API_KEY, + 'part': 'snippet,contentDetails', + 'id': ','.join(videos_ids), + 'maxResults': 9 + } + + p = requests.get(video_url, params=video_params) + results1 = p.json()['items'] + + for result in results1: + video_data = { + 'id': result['id'], + # 'url': f'https://www.youtube.com/watch?v={result["id"]}', + 'title': result['snippet']['title'], + # 'duration': int(parse_duration(result['contentDetails']['duration']).total_seconds() // 60), + # 'thumbnails': result['snippet']['thumbnails']['high']['url'] + } + + videos.append(video_data) + else: + 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) + + modules = Modules.objects.select_related().filter(course_id=course) + slides = CourseDocuments.objects.select_related().filter(course_id=course) + + 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 + # Serialize modules + modules_serializer = ModulesSerializer(modules, many=True) + slides_serializer = CourseDocumentsSerializer(slides, many=True) + + 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) + student_assignment.append(sa) + + assignment_serializer = AssignmentSerializer(assignment, many=True) + + ''' + marks to store the marks of quizes of student + 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]) + + 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 = {} + + attendance_serializer = AttendanceSerializer(a, many=True) + + lec = 0 + comments = Forum.objects.select_related().filter(course_id=course).order_by('comment_time') + answers = collections.OrderedDict() + for comment in comments: + fr = ForumReply.objects.select_related().filter(forum_reply=comment) + fr1 = ForumReply.objects.select_related().filter(forum_ques=comment) + if not fr: + answers[comment] = fr1 + # serialise forum and reply + forum_serializer = ForumSerializer(comments,many=True) + # forum_reply_serializer = ForumReplySerializer(fr,many=True) + + data = { + 'course': course_serializer.data, + 'instructor': instructor_serializer.data, + 'modules': modules_serializer.data, + 'slides': slides_serializer.data, + 'assignments': assignment_serializer.data, + 'student_assignment': student_assignment, # Include if needed + 'attendance': attendance_serializer.data, #try sending "total attendance" + 'present_attendance': present_attendance, + 'attendance_percent': attendance_percent, + 'attendance_file': attendance_file, + # 'comments': nested_comments, # Use nested comments for better structure + # 'forum_reply': forum_reply_serializer.data, # Include if not nested # Include if needed + # 'notifications': notifs.values('id', 'title', 'message', 'is_seen'), + } + print(course_serializer.data) + return Response(data,status=status.HTTP_200_OK) + + else: + # 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.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) + # 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) + #marks_id.append(x.curr_id) + #print(stored_marks) + #for x in stored_marks: + # print(x) + students_info = [] + for stu in registered_students: + s = Student.objects.select_related().get(pk=stu.student_id.id) + students_info.append(s) + + + # registered student serializer + registered_students_serialiser = StudentSerializer(students_info,many=True) + 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 + # serializer + topics_serialiser = TopicsSerializer(topics,many=True) + present_attendance = {} + 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 = [] + + # 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) + 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 = [] + modules_serializer = ModulesSerializer(modules, many=True) + slides_serializer = CourseDocumentsSerializer(slides, many=True) + + 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) + + assignment_serializer = AssignmentSerializer(assignment, many=True) + + comments = Forum.objects.select_related().filter(course_id=course).order_by('comment_time') + answers = collections.OrderedDict() + for comment in comments: + fr = ForumReply.objects.select_related().filter(forum_reply=comment) + 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) + forum_serializer = ForumSerializer(comments,many=True) + + 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 = {} + + gradingscheme_serialiser = GradingSchemeSerializer(gradingscheme,many=True) + data = { + "students":registered_students_serialiser.data, + "topics":topics_serialiser.data, + "present_att":present_attendance, + "total_att":total_attendance, + "modules":modules_serializer.data, + "slides":slides_serializer.data, + "assignment":assignment_serializer.data, + "forum":forum_serializer.data, + "grading_scheme":gradingscheme_serialiser.data, + } + return Response(data,status=status.HTTP_200_OK) + \ 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 9f3c47375..23293a797 100644 --- a/FusionIIIT/applications/online_cms/migrations/0001_initial.py +++ b/FusionIIIT/applications/online_cms/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-07-16 15:44 from django.db import migrations, models import django.db.models.deletion @@ -9,6 +9,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ + ('programme_curriculum', '0001_initial'), ('globals', '0001_initial'), ('academic_information', '0001_initial'), ] @@ -22,7 +23,7 @@ class Migration(migrations.Migration): ('submit_date', models.DateTimeField()), ('assignment_name', models.CharField(max_length=100)), ('assignment_url', models.CharField(max_length=100, null=True)), - ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.course')), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), ], ), migrations.CreateModel( @@ -32,7 +33,7 @@ class Migration(migrations.Migration): ('comment_time', models.DateTimeField(auto_now=True)), ('comment', models.TextField(max_length=2000)), ('commenter_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), - ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.course')), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), ], ), migrations.CreateModel( @@ -44,7 +45,7 @@ class Migration(migrations.Migration): ('number_of_question', models.IntegerField(default=0)), ('description', models.TextField(max_length=1000)), ('total_score', models.IntegerField(default=0)), - ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.course')), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), ], ), migrations.CreateModel( @@ -77,7 +78,7 @@ class Migration(migrations.Migration): ('description', models.TextField(max_length=1000)), ('rules', models.TextField(max_length=2000)), ('total_score', models.IntegerField(default=0)), - ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.course')), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), ], ), migrations.CreateModel( @@ -93,7 +94,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('topic_name', models.TextField(max_length=200)), - ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.course')), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), ], ), migrations.CreateModel( @@ -119,6 +120,19 @@ class Migration(migrations.Migration): ('student_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), ], ), + migrations.CreateModel( + name='Student_grades', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('semester', models.IntegerField(default=1)), + ('year', models.IntegerField(default=2016)), + ('roll_no', models.TextField(max_length=2000)), + ('total_marks', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('grade', models.TextField(max_length=2000)), + ('batch', models.IntegerField(default=2021)), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), + ], + ), migrations.CreateModel( name='QuizResult', fields=[ @@ -134,7 +148,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=100)), - ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.course')), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), ('instructor_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), ], ), @@ -163,6 +177,50 @@ class Migration(migrations.Migration): ('prac_quiz_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='online_cms.practice')), ], ), + migrations.CreateModel( + name='Modules', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('module_name', models.CharField(max_length=50)), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), + ], + ), + migrations.CreateModel( + name='GradingScheme_grades', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('O_Lower', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('O_Upper', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('A_plus_Lower', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('A_plus_Upper', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('A_Lower', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('A_Upper', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('B_plus_Lower', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('B_plus_Upper', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('B_Lower', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('B_Upper', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('C_plus_Lower', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('C_plus_Upper', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('C_Lower', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('C_Upper', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('D_plus_Lower', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('D_plus_Upper', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('D_Lower', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('D_Upper', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('F_Lower', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('F_Upper', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), + ], + ), + migrations.CreateModel( + name='GradingScheme', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type_of_evaluation', models.TextField(default=None, max_length=255)), + ('weightage', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), + ], + ), migrations.CreateModel( name='ForumReply', fields=[ @@ -179,7 +237,7 @@ class Migration(migrations.Migration): ('description', models.CharField(max_length=100)), ('video_name', models.CharField(max_length=40)), ('video_url', models.CharField(max_length=100, null=True)), - ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.course')), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), ], ), migrations.CreateModel( @@ -190,7 +248,28 @@ class Migration(migrations.Migration): ('description', models.CharField(max_length=100)), ('document_name', models.CharField(max_length=40)), ('document_url', models.CharField(max_length=100, null=True)), - ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.course')), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), + ('module_id', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='online_cms.modules')), + ], + ), + migrations.CreateModel( + name='AttendanceFiles', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('upload_time', models.DateTimeField(auto_now=True)), + ('file_name', models.CharField(max_length=40)), + ('file_url', models.CharField(max_length=100, null=True)), + ('course_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.course')), + ], + ), + migrations.CreateModel( + name='Attendance', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('present', models.BooleanField(default=False)), + ('instructor_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.courseinstructor')), + ('student_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), ], ), - ] \ No newline at end of file + ] diff --git a/FusionIIIT/applications/online_cms/migrations/0002_auto_20241012_1459.py b/FusionIIIT/applications/online_cms/migrations/0002_auto_20241012_1459.py new file mode 100644 index 000000000..94ea4b985 --- /dev/null +++ b/FusionIIIT/applications/online_cms/migrations/0002_auto_20241012_1459.py @@ -0,0 +1,40 @@ +# Generated by Django 3.1.5 on 2024-10-12 14:59 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('academic_information', '0001_initial'), + ('online_cms', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='attendance', + name='no_of_attendance', + field=models.IntegerField(default=1), + ), + migrations.AlterField( + model_name='attendance', + name='present', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='gradingscheme', + name='type_of_evaluation', + field=models.CharField(max_length=100), + ), + migrations.CreateModel( + name='StudentEvaluation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('marks', models.DecimalField(decimal_places=2, max_digits=10, null=True)), + ('total_marks', models.DecimalField(decimal_places=2, default=0, max_digits=10)), + ('evaluation_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='online_cms.gradingscheme')), + ('student_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='academic_information.student')), + ], + ), + ] \ No newline at end of file diff --git a/FusionIIIT/applications/online_cms/models.py b/FusionIIIT/applications/online_cms/models.py index 74f2a93bd..3a63aca08 100644 --- a/FusionIIIT/applications/online_cms/models.py +++ b/FusionIIIT/applications/online_cms/models.py @@ -229,7 +229,7 @@ class GradingScheme(models.Model): # 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) + type_of_evaluation = models.CharField(max_length=100) weightage = models.DecimalField(max_digits=10, decimal_places=2,default=0) def __str__(self): @@ -281,7 +281,19 @@ class Attendance(models.Model): 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) + present = models.IntegerField(default=0) + no_of_attendance = models.IntegerField(default=1) def __str__(self): - return self.course_id \ No newline at end of file + return self.course_id + +class StudentEvaluation(models.Model): + student_id = models.ForeignKey(Student, on_delete=models.CASCADE) + evaluation_id = models.ForeignKey(GradingScheme, on_delete=models.CASCADE) + marks = models.DecimalField(max_digits=10, decimal_places=2,null=True) + total_marks = models.DecimalField(max_digits=10, decimal_places=2, default=0) + + def __str__(self): + return '{} - {} - {} - {}'.format( + self.pk, self.student_id, + self.evaluation_id, self.marks) \ No newline at end of file diff --git a/FusionIIIT/applications/online_cms/templates/Sample_Attendance_Sheet.xlsx b/FusionIIIT/applications/online_cms/templates/Sample_Attendance_Sheet.xlsx new file mode 100644 index 000000000..2f2e9616b Binary files /dev/null and b/FusionIIIT/applications/online_cms/templates/Sample_Attendance_Sheet.xlsx differ diff --git a/FusionIIIT/applications/online_cms/urls.py b/FusionIIIT/applications/online_cms/urls.py index f5d3996be..c81142539 100644 --- a/FusionIIIT/applications/online_cms/urls.py +++ b/FusionIIIT/applications/online_cms/urls.py @@ -1,81 +1,82 @@ from django.conf import settings from django.conf.urls.static import static -from django.conf.urls import url +from django.conf.urls import url, include from . import views app_name = 'online_cms' urlpatterns = [ url(r'^$', views.viewcourses, name='viewcourses'), - 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, + url(r'^api/', include('applications.online_cms.api.urls'), name='api'), + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/$', views.course, name='course'), + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/edit_marks$', views.edit_marks, name='edit_marks'), + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/get_exam_data$', views.get_exam_data, name='get_exam_data'), + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/forum$', views.forum, name='forum'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/ajax_reply$', views.ajax_reply, + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/ajax_reply$', views.ajax_reply, name='ajax_reply'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/ajax_new$', views.ajax_new, + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/ajax_new$', views.ajax_new, name='ajax_new'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/ajax_remove$', views.ajax_remove, + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/ajax_remove$', views.ajax_remove, name='ajax_remove'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/upload_assignment$', views.upload_assignment, + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/upload_assignment$', views.upload_assignment, name='upload_assignment'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/add_modules$', views.add_modules, + url(r'^(?P[A-Za-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, + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/add_documents$', views.add_document, name='add_document'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/add_assignment$', + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/add_assignment$', views.add_assignment, name='add_assignment'), - # url(r'^(?P[A-Z0-9]+)/add_video$', views.add_videos, + # url(r'^(?P[A-Za-z0-9]+)/add_video$', views.add_videos, # name='add_videos'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/delete/$', views.delete, + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/delete/$', views.delete, name='delete'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/ajax_assess$', views.ajax_assess, + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/ajax_assess$', views.ajax_assess, name='ajax_assess'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/ajax_feedback$', views.ajax_feedback, + url(r'^(?P[A-Za-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-Z0-9]+)/create_quiz/$', views.create_quiz, name='create_quiz'), - url(r'^(?P[A-Z0-9]+)/edit_quiz/(?P[0-9]+)/$', + url(r'^(?P[A-Za-z0-9]+)/create_quiz/$', views.create_quiz, name='create_quiz'), + url(r'^(?P[A-Za-z0-9]+)/edit_quiz/(?P[0-9]+)/$', views.edit_quiz, name='edit_quiz'), - url(r'^(?P[A-Z0-9]+)/edit_quiz/(?P[0-9]+)/(?P[0-9]+)$', + url(r'^(?P[A-Za-z0-9]+)/edit_quiz/(?P[0-9]+)/(?P[0-9]+)$', views.edit_quiz_topic, name='edit_quiz_topic'), - url(r'^(?P[A-Z0-9]+)/(?P[0-9]+)/add_question_topic$', + url(r'^(?P[A-Za-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-Z0-9]+)/(?P[0-9]+)/(?P[0-9]+)/remove_quiz_question$', + r'^(?P[A-Za-z0-9]+)/(?P[0-9]+)/(?P[0-9]+)/remove_quiz_question$', views.remove_quiz_question, name='remove_quiz_question'), - url(r'^(?P[A-Z0-9]+)/preview_quiz/(?P[0-9]+)/$', views.preview_quiz, + url(r'^(?P[A-Za-z0-9]+)/preview_quiz/(?P[0-9]+)/$', views.preview_quiz, name='preview_quiz'), - url(r'^(?P[A-Z0-9]+)/edit_quiz_details/(?P[0-9]+)/$', + url(r'^(?P[A-Za-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-Z0-9]+)/remove_quiz$', views.remove_quiz, + url(r'^(?P[A-Za-z0-9]+)/remove_quiz$', views.remove_quiz, name='remove_quiz'), - url(r'^(?P[A-Z0-9]+)/remove_bank$', views.remove_bank, + url(r'^(?P[A-Za-z0-9]+)/remove_bank$', views.remove_bank, name='remove_bank'), - url(r'^(?P[A-Z0-9]+)/remove_topic$', views.remove_topic, + url(r'^(?P[A-Za-z0-9]+)/remove_topic$', views.remove_topic, name='remove_topic'), - url(r'^(?P[A-Z0-9]+)/create_bank$', views.create_bank, + url(r'^(?P[A-Za-z0-9]+)/create_bank$', views.create_bank, name='create_bank'), - url(r'^(?P[A-Z0-9]+)/create_topic$', views.create_topic, + url(r'^(?P[A-Za-z0-9]+)/create_topic$', views.create_topic, name='create_topic'), - url(r'^(?P[A-Z0-9]+)/(?P[0-9]+)/(?P[0-9]+)$', + url(r'^(?P[A-Za-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-Z0-9]+)/(?P[0-9]+)/(?P[0-9]+)/remove_question$', + url(r'^(?P[A-Za-z0-9]+)/(?P[0-9]+)/(?P[0-9]+)/remove_question$', views.remove_question, name='remove_question'), - url(r'^(?P[A-Z0-9]+)/edit_bank/(?P[0-9]+)$', + url(r'^(?P[A-Za-z0-9]+)/edit_bank/(?P[0-9]+)$', views.edit_bank, name='edit_bank'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/attendance$', views.submit_attendance, + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/attendance$', views.submit_attendance, name='submit_attendance'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/add_attendance$', views.add_attendance, + url(r'^(?P[A-Za-z0-9]+)/(?P[\d.]+)/add_attendance$', views.add_attendance, name='add_attendance'), - url(r'^(?P[A-Z0-9]+)/(?P[\d.]+)/create_grading_scheme$', + url(r'^(?P[A-Za-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'), diff --git a/FusionIIIT/applications/online_cms/views.py b/FusionIIIT/applications/online_cms/views.py index 415b957da..27acb4498 100644 --- a/FusionIIIT/applications/online_cms/views.py +++ b/FusionIIIT/applications/online_cms/views.py @@ -12,6 +12,7 @@ from django.contrib.auth.decorators import login_required from django.core.files.storage import FileSystemStorage from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseRedirect +from django.http import JsonResponse from django.shortcuts import redirect, render from django.utils import timezone from django.core.serializers import serialize @@ -29,6 +30,7 @@ from .helpers import create_thumbnail, semester from notification.views import course_management_notif + @login_required def viewcourses(request): ''' @@ -76,6 +78,7 @@ def viewcourses(request): + @login_required def course(request, course_code, version): ''' @@ -91,7 +94,10 @@ def course(request, course_code, version): #info about courses he is registered in course = Courses.objects.select_related().get(code=course_code, version = version) #instructor of the course - instructor = CourseInstructor.objects.select_related().get(course_id = course, batch_id = student.batch_id) + try: + instructor = CourseInstructor.objects.select_related().get(course_id = course, batch_id = student.batch_id) + except: + return HttpResponseRedirect('/academic-procedures/stu/') #course material uploaded by the instructor # videos = CourseVideo.objects.filter(course_id=course) videos = [] @@ -222,16 +228,14 @@ def course(request, course_code, version): # marks_pk.append(qs_pk[0]) present_attendance = {} - total_attendance=None + total_attendance=0 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 + total_attendance+=row.no_of_attendance + count+=row.present + present_attendance[row.date] = row.present + attendance_percent = 0 if(total_attendance): attendance_percent = count/total_attendance*100 @@ -243,7 +247,19 @@ def course(request, course_code, version): except AttendanceFiles.DoesNotExist: attendance_file = {} + quiz_marks = 0 + quiz = {} + try: + quiz = GradingScheme.objects.select_related().filter(course_id = course) + for q in quiz: + if q.type_of_evaluation == "Quiz": + m = StudentEvaluation.objects.select_related().filter(evaluation_id = q, student_id = student) + for mr in m: + quiz_marks+=mr.marks + except GradingScheme.DoesNotExist: + quiz_marks = 0 + lec = 0 comments = Forum.objects.select_related().filter(course_id=course).order_by('comment_time') answers = collections.OrderedDict() @@ -266,21 +282,27 @@ def course(request, course_code, version): 'present_attendance':present_attendance, 'attendance_percent': attendance_percent, 'Lecturer': lec, + 'quiz_marks': quiz_marks, 'attendance_file':attendance_file, 'notifications': notifs}) else: 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) + instructor = {} + try: + instructor = CourseInstructor.objects.select_related('course_id').filter(instructor_id=extrainfo) + except: + return HttpResponseRedirect('/academic-procedures/fac/') + for ins in instructor: 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) - # stored_marks = StoreMarks.objects.filter(mid = x.r_id) + students[x.student_id.id.id] = (x.student_id.id.user.first_name + " " + x.student_id.id.user.last_name) + # stored_marks = StudentEvaluation.objects.filter(mid = x.r_id) # for x in stored_marks: # test_marks[x.id] = (x.mid.r_id,x.exam_type,x.marks) #marks_id.append(x.curr_id) @@ -298,11 +320,11 @@ def course(request, course_code, version): 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) + total_attendance = 0 count =0 for row in a: - if(row.present): - count += 1 + total_attendance+=row.no_of_attendance + count+=row.present attendance_percent = 0 if(total_attendance): @@ -401,10 +423,24 @@ def course(request, course_code, version): gradingscheme_grades = {} try: - student_grades = Student_grades.objects.select_related().filter(course_id=course) + student_grades = Student_grades.objects.select_related().filter(course_id=course).order_by('roll_no') except Student_grades.DoesNotExist: student_grades = {} + marks_with_roll = collections.OrderedDict() + for eval in gradingscheme: + try: + rollist = StudentEvaluation.objects.filter(evaluation_id=eval) + except StudentEvaluation.DoesNotExist: + rollist = {} + for roll in rollist: + sid = roll.student_id.id.id + scaling_factor = eval.weightage/roll.total_marks + scaled_marks = scaling_factor*roll.marks + if sid in marks_with_roll: + marks_with_roll[sid] += round(scaled_marks,2) + else: + marks_with_roll[sid] = round(scaled_marks,2) return render(request, 'coursemanagement/viewcourse.html', {'instructor': instructor, @@ -426,7 +462,8 @@ def course(request, course_code, version): 'test_marks': test_marks, 'gradingscheme':gradingscheme, 'gradingscheme_grades': gradingscheme_grades, - 'student_grades' : student_grades + 'student_grades' : student_grades, + 'marks_with_roll': marks_with_roll }) @@ -1527,56 +1564,57 @@ def add_practice_question(request, course_code, practice_contest_code): ) return redirect('/ocms/' + course_code + '/edit_practice_contest/'+str(pq[0].id)) -# @csrf_protect -# @login_required -# def edit_marks(request, course_code): -# user = request.user -# extrainfo = ExtraInfo.objects.get(user=user) - -# if extrainfo.user_type == 'faculty': -# instructor = Curriculum_Instructor.objects.filter(instructor_id=extrainfo) - -# for ins in instructor: -# if ins.curriculum_id.course_code == course_code: -# registered_students = Register.objects.filter(curr_id = ins.curriculum_id.curriculum_id) - - -# exam = request.POST.get('examtype') -# score = request.POST.getlist('enteredmarks') +@csrf_protect +@login_required +def edit_marks(request, course_code,version): + user = request.user + extrainfo = ExtraInfo.objects.get(user=user) -# List = list() + 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): + registered_students = course_registration.objects.select_related('student_id').filter(course_id = ins.course_id) -# for i in range(len(registered_students)): -# m_id = registered_students[i] -# s = score[i] -# # rows = StoreMarks.objects.filter(mid=m_id, exam_type=exam) -# num = StoreMarks.objects.filter(mid=m_id, exam_type=exam).count() -# record = StoreMarks.objects.filter(mid=m_id, exam_type=exam).values_list('marks', flat=True) + exam = request.POST.get('examtype') + score = request.POST.getlist('enteredmarks') + total = request.POST.get('totalmarks') + e_id = GradingScheme.objects.get(pk=int(exam)) + print(e_id) + List = list() -# List.append(list(record)) + for i in range(len(registered_students)): + m_id = registered_students[i].student_id + s = score[i] -# if num==0: -# StoreMarks.objects.create( -# mid=m_id, -# exam_type=exam, -# marks=s -# ) -# else: -# StoreMarks.objects.filter(mid=m_id, exam_type=exam).update(marks=s) + # rows = StudentEvaluation.objects.filter(mid=m_id, exam_type=exam) + num = StudentEvaluation.objects.filter(student_id=m_id, evaluation_id=exam).count() + record = StudentEvaluation.objects.filter(student_id=m_id, evaluation_id=exam).values_list('marks', flat=True) -# #print(registered_students) + List.append(list(record)) + if num==0: + StudentEvaluation.objects.create( + student_id=m_id, + evaluation_id=e_id, + marks=s, + total_marks = total + ) + else: + StudentEvaluation.objects.filter(student_id=m_id, evaluation_id=e_id).update(marks=s) -# return HttpResponse("Upload successful") -# context= {'m_id':m_id,'registered_students': registered_students, 'record':List} -# return render(request, 'coursemanagement/assessment.html', context) + return JsonResponse({"message": "Upload Successful"}, status=200) + return HttpResponse("Unauthorized", status=403) + # context= {'m_id':m_id,'registered_students': registered_students, 'record':List} + # return render(request, 'coursemanagement/assessment.html', context) @csrf_protect @login_required -def get_exam_data(request,course_code): #it is store the type of exam helpful in storing the marks +def get_exam_data(request,course_code, version): #it is store the type of exam helpful in storing the marks exam_name = request.POST['exam_name'] - data = serializers.serialize('json', StoreMarks.objects.filter(exam_type=exam_name)) + e_id = GradingScheme.objects.get(pk=int(exam_name)) + data = serializers.serialize('json', StudentEvaluation.objects.filter(evaluation_id=e_id)) return HttpResponse(data, content_type='application/json') @@ -1601,31 +1639,34 @@ def submit_attendance(request, course_code, version): # print(item) try: date = request.POST['date'] + total_attendance = int(request.POST['total_attendance']) except: - return HttpResponse("Please Enter The Form Properly") + return HttpResponse("Please Enter The Form Properly",status=400) #mark the attendance according to the student roll no. all_students = request.POST.getlist('Roll') - present_students = request.POST.getlist('Present_absent') for student in all_students: s_id = Student.objects.select_related().get(id = student) - present = False - if student in present_students: - present = True - - Attendance.objects.create( - student_id = s_id, - instructor_id = instructor, - date = date, - present = present - ) + presents = int(request.POST.get(f'Present_absent_{student}', 0)) + # Ensure presents do not exceed total attendance + if presents > total_attendance: + presents = total_attendance - return HttpResponse("Feedback uploaded") + Attendance.objects.create( + student_id = s_id, + instructor_id = instructor, + date = date, + present = presents, + no_of_attendance = total_attendance + ) + + return HttpResponse("Upload Successful", status=200) + return HttpResponse("Form is not valid", status=400) #to store the grading scheme created by the faculty @login_required @@ -1639,11 +1680,10 @@ def create_grading_scheme(request, course_code, version): form_data = {} form_data = request.POST.copy() - del form_data['add_item_wtg'] - del form_data['add_eval_type'] - del form_data['csrfmiddlewaretoken'] + form_data.pop('add_item_wtg', None) + form_data.pop('add_eval_type', None) + form_data.pop('csrfmiddlewaretoken', None) - # data to be sent to the gradingscheme table key_list = list(form_data.keys()) no_of_evaluation_types = len(form_data) - 20 @@ -1661,6 +1701,21 @@ def create_grading_scheme(request, course_code, version): weightage=form_data[key_list[i]] ) grading_scheme.save() + + # for key, value in form_data.items(): + # # Check if the grading scheme already exists + # already_existing_data = GradingScheme.objects.filter(course_id=course_id, type_of_evaluation=key) + # if already_existing_data.exists(): + # grading_scheme_object = already_existing_data.first() + # grading_scheme_object.weightage = value + # grading_scheme_object.save() + # else: + # grading_scheme = GradingScheme.objects.create( + # course_id=course_id, + # type_of_evaluation=key, + # weightage=value + # ) + # grading_scheme.save() # data to be sent to gradingscheme_grades table already_existing_data2 = GradingScheme_grades.objects.filter(course_id=course_id) @@ -1734,7 +1789,7 @@ def add_academic_calendar(request): user = request.user extrainfo = ExtraInfo.objects.select_related().get(user=user) - if extrainfo.id == 'id_admin': + if request.session.get('currentDesignationSelected') == 'acadadmin': calendar = Calendar.objects.all() context= { 'academic_calendar' :calendar, @@ -1786,7 +1841,7 @@ def update_calendar(request): user = request.user extrainfo = ExtraInfo.objects.select_related().get(user=user) - if extrainfo.id == 'id_admin': + if request.session.get('currentDesignationSelected') == 'acadadmin': calendar = Calendar.objects.all() context= { 'academic_calendar' :calendar, @@ -1831,7 +1886,7 @@ def add_timetable(request): user = request.user extrainfo = ExtraInfo.objects.select_related().get(user=user) - if extrainfo.id == 'id_admin': + if request.session.get('currentDesignationSelected') == 'acadadmin': if request.method == 'POST': try: timetable = request.FILES.get('img') @@ -1879,7 +1934,7 @@ def delete_timetable(request): extrainfo = ExtraInfo.objects.select_related().get(user=user) - if extrainfo.id == 'id_admin': + if request.session.get('currentDesignationSelected') == 'acadadmin': if request.method == "POST": pk = request.POST.get('pk') t = Timetable.objects.get(pk=pk) diff --git a/FusionIIIT/applications/otheracademic/__init__.py b/FusionIIIT/applications/otheracademic/__init__.py new file mode 100644 index 000000000..e69de29bb 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..1598f71a5 --- /dev/null +++ b/FusionIIIT/applications/otheracademic/migrations/0001_initial.py @@ -0,0 +1,228 @@ +# Generated by Django 3.1.5 on 2024-07-16 15:44 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('globals', '0001_initial'), + ] + + 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)), + ('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(blank=True, upload_to='')), + ('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()), + ('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)), + ('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)), + ('remark', models.TextField(default='')), + ('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/placement_cell/migrations/0001_initial.py b/FusionIIIT/applications/placement_cell/migrations/0001_initial.py index 95f070aef..712c60a56 100644 --- a/FusionIIIT/applications/placement_cell/migrations/0001_initial.py +++ b/FusionIIIT/applications/placement_cell/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-07-16 15:44 import datetime from django.db import migrations, models diff --git a/FusionIIIT/applications/programme_curriculum/forms.py b/FusionIIIT/applications/programme_curriculum/forms.py index 8100e4f60..394828004 100644 --- a/FusionIIIT/applications/programme_curriculum/forms.py +++ b/FusionIIIT/applications/programme_curriculum/forms.py @@ -5,6 +5,10 @@ from django.forms.models import ModelChoiceField from .models import Programme, Discipline, Curriculum, Semester, Course, Batch, CourseSlot, PROGRAMME_CATEGORY_CHOICES,NewProposalFile,Proposal_Tracking from django.utils.translation import gettext_lazy as _ +from django.contrib.auth.models import User +from applications.globals.models import (DepartmentInfo, Designation,ExtraInfo, Faculty, HoldsDesignation) +from applications.filetracking.sdk.methods import * + class ProgrammeForm(ModelForm): class Meta: @@ -315,3 +319,56 @@ class Meta: 'remarks' : 'remarks', } + + def clean(self): + + r_id = self.cleaned_data.get('receive_id') + r_des = self.cleaned_data.get('receive_design') + des=HoldsDesignation.objects.filter(user=r_id) + print(des) + data2='' + msg1='' + if des: + data2 = ', '.join(str(i) for i in des) + msg1 = f'{r_id} has only these working designations: {data2}' + + else: + msg1=f'{r_id} has no working designations' + data = HoldsDesignation.objects.select_related('designation').filter(user=r_id,designation=r_des) + + if not data: + msg = 'Invalid reciever id and reciever designation' + raise ValidationError({'receive_id': [msg, msg1]}) + + name="" + name = name+str(r_des) + if "hod" in name.lower() : + pass + elif "professor" in name.lower() : + pass + elif "dean academic" in name.lower(): + pass + else: + msg3 = f"You can't send Proposal Form to the user {r_id}-{r_des}" + raise ValidationError({'receive_id': [msg3]}) + + + + + return self.cleaned_data + + + # def sed(self): + # r_id = self.cleaned_data.get('receive_id') + # return r_id + # def __init__(self, *args, **kwargs): + # super().__init__(*args, **kwargs) + # des = HoldsDesignation.objects.select_related('working','designation').filter(user=5333) + # self.fields['receive_design'].queryset = Designation.objects.filter(id=list(des.designation)) + + + # def clean(self): + # cleaned_data = super().clean() + # user_id = cleaned_data.get('receive_id') + # if user_id: + # self.fields['receive_design'].queryset = HoldsDesignation.objects.select_related('designation').filter(user_id=user_id) diff --git a/FusionIIIT/applications/programme_curriculum/migrations/0001_initial.py b/FusionIIIT/applications/programme_curriculum/migrations/0001_initial.py index ea11ebc7c..0654934c9 100644 --- a/FusionIIIT/applications/programme_curriculum/migrations/0001_initial.py +++ b/FusionIIIT/applications/programme_curriculum/migrations/0001_initial.py @@ -1,5 +1,6 @@ -# Generated by Django 3.1.5 on 2024-04-15 23:58 +# Generated by Django 3.1.5 on 2024-07-16 15:44 +from django.conf import settings import django.core.validators from django.db import migrations, models import django.db.models.deletion @@ -11,6 +12,7 @@ class Migration(migrations.Migration): dependencies = [ ('globals', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ @@ -19,10 +21,11 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=100)), - ('version', models.DecimalField(decimal_places=1, default=1.0, max_digits=2, validators=[django.core.validators.MinValueValidator(1.0), django.core.validators.DecimalValidator(decimal_places=1, max_digits=2)])), + ('version', models.DecimalField(decimal_places=1, default=1.0, max_digits=5, validators=[django.core.validators.MinValueValidator(1.0), django.core.validators.DecimalValidator(decimal_places=1, max_digits=5)])), ('working_curriculum', models.BooleanField(default=True)), ('no_of_semester', models.PositiveIntegerField(default=1)), ('min_credit', models.PositiveIntegerField(default=0)), + ('latest_version', models.BooleanField(default=True)), ], ), migrations.CreateModel( @@ -110,19 +113,42 @@ class Migration(migrations.Migration): }, ), migrations.CreateModel( - name='UpdateCourseProposal', + name='Proposal_Tracking', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('faculty_name', models.CharField(max_length=100)), - ('faculty_code', models.CharField(max_length=10)), + ('file_id', models.CharField(max_length=100)), + ('current_id', models.CharField(max_length=100)), + ('current_design', models.CharField(max_length=100)), + ('receive_date', models.DateTimeField(auto_now_add=True)), + ('forward_date', models.DateTimeField(auto_now_add=True)), + ('remarks', models.CharField(blank=True, max_length=250, null=True)), + ('is_added', models.BooleanField(default=False)), + ('is_submitted', models.BooleanField(default=False)), + ('is_rejected', models.BooleanField(default=False)), + ('sender_archive', models.BooleanField(default=False)), + ('receiver_archive', models.BooleanField(default=False)), + ('disciplines', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='programme_curriculum.discipline')), + ('receive_design', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.designation')), + ('receive_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'unique_together': {('file_id', 'current_id', 'current_design', 'disciplines')}, + }, + ), + migrations.CreateModel( + name='NewProposalFile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('uploader', models.CharField(max_length=100)), + ('designation', models.CharField(max_length=100)), ('code', models.CharField(max_length=10)), ('name', models.CharField(max_length=100)), - ('credit', models.PositiveIntegerField(default=0)), - ('lecture_hours', models.PositiveIntegerField(null=True)), - ('tutorial_hours', models.PositiveIntegerField(null=True)), - ('pratical_hours', models.PositiveIntegerField(null=True)), - ('discussion_hours', models.PositiveIntegerField(null=True)), - ('project_hours', models.PositiveIntegerField(null=True)), + ('credit', models.PositiveIntegerField(default=3)), + ('lecture_hours', models.PositiveIntegerField(default=3, null=True)), + ('tutorial_hours', models.PositiveIntegerField(default=0, null=True)), + ('pratical_hours', models.PositiveIntegerField(default=0, null=True)), + ('discussion_hours', models.PositiveIntegerField(default=0, null=True)), + ('project_hours', models.PositiveIntegerField(default=0, null=True)), ('pre_requisits', models.TextField(blank=True, null=True)), ('syllabus', models.TextField()), ('percent_quiz_1', models.PositiveIntegerField(default=10)), @@ -133,13 +159,16 @@ class Migration(migrations.Migration): ('percent_lab_evaluation', models.PositiveIntegerField(default=10)), ('percent_course_attendance', models.PositiveIntegerField(default=5)), ('ref_books', models.TextField()), - ('working_course', models.BooleanField(default=True)), - ('status', models.PositiveIntegerField(default=0)), - ('disciplines', models.ManyToManyField(blank=True, to='programme_curriculum.Discipline')), + ('subject', models.CharField(max_length=100, null=True)), + ('description', models.CharField(max_length=400, null=True)), + ('upload_date', models.DateTimeField(auto_now_add=True)), + ('is_read', models.BooleanField(default=False)), + ('is_update', models.BooleanField(default=False)), + ('is_archive', models.BooleanField(default=False)), ('pre_requisit_courses', models.ManyToManyField(blank=True, to='programme_curriculum.Course')), ], options={ - 'unique_together': {('code', 'faculty_code')}, + 'unique_together': {('code', 'uploader', 'name')}, }, ), migrations.AlterUniqueTogether( @@ -163,38 +192,6 @@ class Migration(migrations.Migration): 'unique_together': {('semester', 'name', 'type')}, }, ), - migrations.CreateModel( - name='CourseProposal', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('faculty_name', models.CharField(max_length=100)), - ('faculty_code', models.CharField(max_length=10)), - ('code', models.CharField(max_length=10)), - ('name', models.CharField(max_length=100)), - ('credit', models.PositiveIntegerField(default=3)), - ('lecture_hours', models.PositiveIntegerField(default=3, null=True)), - ('tutorial_hours', models.PositiveIntegerField(default=0, null=True)), - ('pratical_hours', models.PositiveIntegerField(default=0, null=True)), - ('discussion_hours', models.PositiveIntegerField(default=0, null=True)), - ('project_hours', models.PositiveIntegerField(default=0, null=True)), - ('pre_requisits', models.TextField(blank=True, null=True)), - ('syllabus', models.TextField()), - ('percent_quiz_1', models.PositiveIntegerField(default=10)), - ('percent_midsem', models.PositiveIntegerField(default=20)), - ('percent_quiz_2', models.PositiveIntegerField(default=10)), - ('percent_endsem', models.PositiveIntegerField(default=30)), - ('percent_project', models.PositiveIntegerField(default=15)), - ('percent_lab_evaluation', models.PositiveIntegerField(default=10)), - ('percent_course_attendance', models.PositiveIntegerField(default=5)), - ('ref_books', models.TextField()), - ('status', models.PositiveIntegerField(default=0)), - ('disciplines', models.ManyToManyField(blank=True, to='programme_curriculum.Discipline')), - ('pre_requisit_courses', models.ManyToManyField(blank=True, to='programme_curriculum.Course')), - ], - options={ - 'unique_together': {('code', 'faculty_code')}, - }, - ), migrations.CreateModel( name='CourseInstructor', fields=[ @@ -207,4 +204,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 e781af115..655994c1c 100644 --- a/FusionIIIT/applications/programme_curriculum/models.py +++ b/FusionIIIT/applications/programme_curriculum/models.py @@ -392,6 +392,7 @@ class NewProposalFile(models.Model): upload_date = models.DateTimeField(auto_now_add=True) is_read = models.BooleanField(default = False) is_update= models.BooleanField(default = False) + is_archive = models.BooleanField(default = False) class Meta: unique_together = ('code', 'uploader','name') # if code and faculty code matches to another proposal name will take care of it @@ -412,6 +413,10 @@ class Proposal_Tracking(models.Model): is_added = models.BooleanField(default = False) is_submitted = models.BooleanField(default = False) is_rejected = models.BooleanField(default = False) + sender_archive = models.BooleanField(default = False) + receiver_archive = models.BooleanField(default = False) + + class Meta: # unique_together = ('file_id', 'current_id','receive_id','receive_design') diff --git a/FusionIIIT/applications/programme_curriculum/urls.py b/FusionIIIT/applications/programme_curriculum/urls.py index c40dad9a0..4c06b2b1b 100644 --- a/FusionIIIT/applications/programme_curriculum/urls.py +++ b/FusionIIIT/applications/programme_curriculum/urls.py @@ -66,6 +66,11 @@ 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'), + path('tracking_archive//',views.tracking_archive,name='tracking_archive'), + path('tracking_unarchive//',views.tracking_unarchive,name='tracking_unarchive'), + path('file_archive//',views.file_archive,name='file_archive'), + path('file_unarchive//',views.file_unarchive,name='file_unarchive'), + # urls for api view path('api/programmes_ug/', v2.view_ug_programmes, name='view_ug_programmes_api'), diff --git a/FusionIIIT/applications/programme_curriculum/views.py b/FusionIIIT/applications/programme_curriculum/views.py index a1e40c6d1..e0fdb5a50 100644 --- a/FusionIIIT/applications/programme_curriculum/views.py +++ b/FusionIIIT/applications/programme_curriculum/views.py @@ -67,13 +67,14 @@ def view_all_programmes(request): elif 'hod' in request.session['currentDesignationSelected'].lower(): url+='faculty/' - + notifs = request.user.notifications.all() + ug = Programme.objects.filter(category='UG') pg = Programme.objects.filter(category='PG') phd = Programme.objects.filter(category='PHD') url+='view_all_programmes.html' - return render(request, url, {'ug': ug, 'pg': pg, 'phd': phd}) + return render(request, url, {'ug': ug, 'pg': pg, 'phd': phd,'notifications': notifs,}) def view_curriculums_of_a_programme(request, programme_id): @@ -100,7 +101,7 @@ def view_curriculums_of_a_programme(request, programme_id): elif 'hod' in request.session['currentDesignationSelected'].lower(): url+='faculty/' - + notifs = request.user.notifications.all() program = get_object_or_404(Programme, Q(id=programme_id)) curriculums = program.curriculums @@ -111,7 +112,7 @@ def view_curriculums_of_a_programme(request, programme_id): working_curriculums = curriculums.filter(working_curriculum=1) past_curriculums = curriculums.filter(working_curriculum=0) url+='view_curriculums_of_a_programme.html' - return render(request,url, {'program': program, 'past_curriculums': past_curriculums, 'working_curriculums': working_curriculums, 'curriculumfilter': curriculumfilter}) + return render(request,url, {'program': program, 'past_curriculums': past_curriculums, 'working_curriculums': working_curriculums, 'curriculumfilter': curriculumfilter,'notifications': notifs,}) def view_all_working_curriculums(request): @@ -130,11 +131,11 @@ def view_all_working_curriculums(request): elif 'hod' in request.session['currentDesignationSelected'].lower(): url+='faculty/' curriculums = Curriculum.objects.filter(working_curriculum=1) - + notifs = request.user.notifications.all() curriculumfilter = CurriculumFilter(request.GET, queryset=curriculums) curriculums = curriculumfilter.qs - return render(request,url+'view_all_working_curriculums.html',{'curriculums':curriculums, 'curriculumfilter': curriculumfilter}) + return render(request,url+'view_all_working_curriculums.html',{'curriculums':curriculums, 'curriculumfilter': curriculumfilter,'notifications': notifs,}) def view_semesters_of_a_curriculum(request, curriculum_id): """ @@ -160,6 +161,7 @@ def view_semesters_of_a_curriculum(request, curriculum_id): elif 'hod' in request.session['currentDesignationSelected'].lower(): url+='faculty/' curriculum = get_object_or_404(Curriculum, Q(id=curriculum_id)) + notifs = request.user.notifications.all() semesters = curriculum.semesters semester_slots = [] for sem in semesters: @@ -187,7 +189,7 @@ def view_semesters_of_a_curriculum(request, curriculum_id): transpose_semester_slots = list(zip(*semester_slots)) - return render(request, url+'view_semesters_of_a_curriculum.html', {'curriculum': curriculum, 'semesters': semesters, 'semester_slots': transpose_semester_slots, 'semester_credits': semester_credits}) + return render(request, url+'view_semesters_of_a_curriculum.html', {'curriculum': curriculum, 'semesters': semesters, 'semester_slots': transpose_semester_slots, 'semester_credits': semester_credits,'notifications': notifs,}) def view_a_semester_of_a_curriculum(request, semester_id): @@ -205,8 +207,9 @@ def view_a_semester_of_a_curriculum(request, semester_id): url+='faculty/' semester = get_object_or_404(Semester, Q(id=semester_id)) course_slots = semester.courseslots + notifs = request.user.notifications.all() - return render(request, url+'view_a_semester_of_a_curriculum.html', {'semester': semester, 'course_slots': course_slots}) + return render(request, url+'view_a_semester_of_a_curriculum.html', {'semester': semester, 'course_slots': course_slots,'notifications': notifs,}) def view_a_courseslot(request, courseslot_id): @@ -222,7 +225,8 @@ def view_a_courseslot(request, courseslot_id): elif 'hod' in request.session['currentDesignationSelected'].lower(): url+='faculty/' course_slot = get_object_or_404(CourseSlot, Q(id=courseslot_id)) - return render(request, url+'view_a_courseslot.html', {'course_slot': course_slot}) + notifs = request.user.notifications.all() + return render(request, url+'view_a_courseslot.html', {'course_slot': course_slot,'notifications': notifs,}) def view_all_courses(request): @@ -239,11 +243,12 @@ def view_all_courses(request): elif 'hod' in request.session['currentDesignationSelected'].lower(): url+='faculty/' courses = Course.objects.all() + notifs = request.user.notifications.all() coursefilter = CourseFilter(request.GET, queryset=courses) courses = coursefilter.qs - return render(request, url+'view_all_courses.html', {'courses': courses, 'coursefilter': coursefilter}) + return render(request, url+'view_all_courses.html', {'courses': courses, 'coursefilter': coursefilter,'notifications': notifs,}) def view_a_course(request, course_id): @@ -259,7 +264,8 @@ def view_a_course(request, course_id): elif 'hod' in request.session['currentDesignationSelected'].lower(): url+='faculty/' course = get_object_or_404(Course, Q(id=course_id)) - return render(request, url+'view_a_course.html', {'course': course}) + notifs = request.user.notifications.all() + return render(request, url+'view_a_course.html', {'course': course,'notifications': notifs,}) def view_all_discplines(request): @@ -276,7 +282,8 @@ def view_all_discplines(request): url+='faculty/' disciplines = Discipline.objects.all() - return render(request, url+'view_all_disciplines.html', {'disciplines': disciplines}) + notifs = request.user.notifications.all() + return render(request, url+'view_all_disciplines.html', {'disciplines': disciplines,'notifications': notifs,}) def view_all_batches(request): @@ -301,8 +308,9 @@ def view_all_batches(request): finished_batches = batches.filter(running_batch=False) batches = batches.filter(running_batch=True) + notifs = request.user.notifications.all() - return render(request, url+'view_all_batches.html', {'batches': batches, 'finished_batches': finished_batches, 'batchfilter': batchfilter}) + return render(request, url+'view_all_batches.html', {'batches': batches, 'finished_batches': finished_batches, 'batchfilter': batchfilter,'notifications': notifs,}) @@ -783,11 +791,9 @@ def add_course_form(request): return render(request,'programme_curriculum/acad_admin/course_form.html',{'form':form,'submitbutton': submitbutton}) - def update_course_form(request, course_id): - des = HoldsDesignation.objects.all().filter(user = request.user).first() - if request.session['currentDesignationSelected']== "student": # or request.session['currentDesignationSelected']== "Associate Professor" or request.session['currentDesignationSelected']== "Professor" or request.session['currentDesignationSelected']== "Assistant Professor" + if request.session['currentDesignationSelected']== "student": return HttpResponseRedirect('/programme_curriculum/programmes/') elif str(request.user) == "acadadmin" : pass @@ -808,17 +814,41 @@ def update_course_form(request, course_id): previous.save() form.latest_version=True new_course = form.save(commit=False) + add=True + ver=0 if(new_course.version>previous.version): - form.save() - course = Course.objects.last() - messages.success(request, "Added successful") - return HttpResponseRedirect("/programme_curriculum/admin_course/" + str(course.id) + "/") + # Check if a course with the same values (except version, latest_version, disciplines, and pre_requisit_courses) already exists + old_course=Course.objects.filter(code=new_course.code, name=new_course.name, credit=new_course.credit, lecture_hours=new_course.lecture_hours, tutorial_hours=new_course.tutorial_hours, pratical_hours=new_course.pratical_hours, discussion_hours=new_course.discussion_hours, project_hours=new_course.project_hours, pre_requisits=new_course.pre_requisits, syllabus=new_course.syllabus, percent_quiz_1=new_course.percent_quiz_1, percent_midsem=new_course.percent_midsem, percent_quiz_2=new_course.percent_quiz_2, percent_endsem=new_course.percent_endsem, percent_project=new_course.percent_project, percent_lab_evaluation=new_course.percent_lab_evaluation, percent_course_attendance=new_course.percent_course_attendance, ref_books=new_course.ref_books) + if old_course: + # Check if disciplines or pre_requisit_courses have been changed + for i in old_course: + if set(form.cleaned_data['disciplines']) != set(i.disciplines.all()) or set(form.cleaned_data['pre_requisit_courses']) != set(i.pre_requisit_courses.all()): + add=True + else: + add=False + ver=i.version + break + if add: + new_course.save() # Save the new course first before adding many-to-many fields + new_course.disciplines.set(form.cleaned_data['disciplines']) + new_course.pre_requisit_courses.set(form.cleaned_data['pre_requisit_courses']) + course = Course.objects.last() + messages.success(request, "Added successful") + return HttpResponseRedirect("/programme_curriculum/admin_course/" + str(course.id) + "/") + else: + form.add_error(None, 'A Course with the same values already exists at "Version Number '+' ' +str(ver)+'"') + else: + new_course.save() # Save the new course first before adding many-to-many fields + new_course.disciplines.set(form.cleaned_data['disciplines']) + new_course.pre_requisit_courses.set(form.cleaned_data['pre_requisit_courses']) + course = Course.objects.last() + messages.success(request, "Added successful") + return HttpResponseRedirect("/programme_curriculum/admin_course/" + str(course.id) + "/") else: version_error+=f'The version should be greater than {previous.version}' return render(request,'programme_curriculum/acad_admin/course_form.html',{'course':course, 'form':form, 'submitbutton': submitbutton,'version_error':version_error}) - def add_courseslot_form(request): user_details = ExtraInfo.objects.get(user = request.user) @@ -1058,14 +1088,17 @@ def view_course_proposal_forms(request): if request.session['currentDesignationSelected'] == "Associate Professor" or request.session['currentDesignationSelected'] == "Professor" or request.session['currentDesignationSelected'] == "Assistant Professor" : pass - elif request.session['currentDesignationSelected'] == "acadadmin" or request.session['currentDesignationSelected'] == "student" : + elif request.session['currentDesignationSelected'] == "student" : return HttpResponseRedirect('/programme_curriculum/programmes/') + elif request.session['currentDesignationSelected']== "acadadmin": + return render(request, 'programme_curriculum/admin_programmes/') else: data='Files Cannot be sent with current Designation Switch to "Professor or Assistant Professor or Associate Professor"' + notifs = request.user.notifications.all() courseProposal = NewProposalFile.objects.filter(uploader=des.user,designation=request.session['currentDesignationSelected'],is_update=False) updatecourseProposal = NewProposalFile.objects.filter(uploader=des.user,designation=request.session['currentDesignationSelected'],is_update=True) - return render(request, 'programme_curriculum/faculty/view_course_proposal_forms.html',{'courseProposals': courseProposal,'updateProposals':updatecourseProposal,'data':data}) + return render(request, 'programme_curriculum/faculty/view_course_proposal_forms.html',{'courseProposals': courseProposal,'updateProposals':updatecourseProposal,'data':data,'notifications': notifs,}) @login_required(login_url='/accounts/login') def faculty_view_all_courses(request): @@ -1083,12 +1116,12 @@ def faculty_view_all_courses(request): pass courses = Course.objects.all() - + notifs = request.user.notifications.all() coursefilter = CourseFilter(request.GET, queryset=courses) courses = coursefilter.qs - return render(request, 'programme_curriculum/faculty/faculty_view_all_courses.html', {'courses': courses, 'coursefilter': coursefilter}) + return render(request, 'programme_curriculum/faculty/faculty_view_all_courses.html', {'courses': courses, 'coursefilter': coursefilter,'notifications': notifs,}) def faculty_view_a_course(request, course_id): @@ -1105,7 +1138,8 @@ def faculty_view_a_course(request, course_id): elif 'hod' in request.session['currentDesignationSelected'].lower(): pass course = get_object_or_404(Course, Q(id=course_id)) - return render(request, 'programme_curriculum/faculty/faculty_view_a_course.html', {'course': course}) + notifs = request.user.notifications.all() + return render(request, 'programme_curriculum/faculty/faculty_view_a_course.html', {'course': course,'notifications': notifs,}) def view_a_course_proposal_form(request,CourseProposal_id): @@ -1124,7 +1158,8 @@ def view_a_course_proposal_form(request,CourseProposal_id): user_details = ExtraInfo.objects.get(user = request.user) des = HoldsDesignation.objects.all().filter(user = request.user).first() proposalform = get_object_or_404(NewProposalFile, Q(id=CourseProposal_id)) - return render(request, 'programme_curriculum/faculty/view_a_course_proposal.html', {'proposal': proposalform}) + notifs = request.user.notifications.all() + return render(request, 'programme_curriculum/faculty/view_a_course_proposal.html', {'proposal': proposalform,'notifications': notifs,}) def new_course_proposal_file(request): @@ -1139,7 +1174,6 @@ def new_course_proposal_file(request): uploader = request.user.extrainfo design=request.session['currentDesignationSelected'] form=NewCourseProposalFile(initial={'uploader':des.user,'designation':design}) - submitbutton= request.POST.get('Submit') if submitbutton: @@ -1179,24 +1213,28 @@ def filetracking(request,proposal_id): if request.method == 'POST': form = CourseProposalTrackingFile(request.POST) if form.is_valid(): - form.is_read=False - form.save() - receiver=request.POST.get('receive_id') - receiver_id = User.objects.get(id=receiver) - receiver_design=request.POST.get('receive_design') - receiver_des= Designation.objects.get(id=receiver_design) - uploader=request.POST.get('current_id') - uploader_design=request.POST.get('current_design') + try: + form.is_read=False + form.save() + receiver=request.POST.get('receive_id') + receiver_id = User.objects.get(id=receiver) + receiver_design=request.POST.get('receive_design') + receiver_des= Designation.objects.get(id=receiver_design) + uploader=request.POST.get('current_id') + uploader_design=request.POST.get('current_design') + data='Received as '+ str(receiver_id) +'-'+str(receiver_des) +' Course Proposal Form "'+file_data +'" By '+str(uploader)+' - '+str(uploader_design) + # data=file.subject + messages.success(request, "Submitted successful") + prog_and_curr_notif(request.user,receiver_id,data) + return HttpResponseRedirect('/programme_curriculum/outward_files/') + except IntegrityError as e: + # Handle the IntegrityError here, for example: + form.add_error(None, 'Proposal_ tracking with this File id, Current id, Current design and Disciplines already exists.') - data='Received as '+ str(receiver_id) +'-'+str(receiver_des) +' Course Proposal Form "'+file_data +'" By '+str(uploader)+' - '+str(uploader_design) - # data=file.subject - messages.success(request, "Submitted successful") - prog_and_curr_notif(request.user,receiver_id,data) - return HttpResponseRedirect('/programme_curriculum/outward_files/') - return render(request,'programme_curriculum/faculty/filetracking.html',{'form':form,'submitbutton': submitbutton,'file_info':file_data}) + return render(request,'programme_curriculum/faculty/filetracking.html',{'form':form,'submitbutton': submitbutton,'file_info':file_data,}) @@ -1206,7 +1244,7 @@ def inward_files(request): data='' if request.session['currentDesignationSelected'] == "Associate Professor" or request.session['currentDesignationSelected'] == "Professor" or request.session['currentDesignationSelected'] == "Assistant Professor" : - data='As a "Professor or Assistant Professor or Associate Professor" you cannot receive any proposal requests' + data=f'As a "{request.session["currentDesignationSelected"]}" you cannot receive any proposal requests' pass elif 'hod' in request.session['currentDesignationSelected'].lower(): pass @@ -1219,14 +1257,14 @@ def inward_files(request): id=request.user user_designation=HoldsDesignation.objects.select_related('user','working','designation').filter(user=request.user) - + notifs = request.user.notifications.all() designation = Designation.objects.get(name=request.session['currentDesignationSelected']) des_id = designation.id courseProposal = Proposal_Tracking.objects.filter(receive_design = des_id,receive_id= id) - return render(request, 'programme_curriculum/faculty/inward_course_forms.html',{'courseProposals': courseProposal,'design':request.session['currentDesignationSelected'],'data':data}) + return render(request, 'programme_curriculum/faculty/inward_course_forms.html',{'courseProposals': courseProposal,'design':request.session['currentDesignationSelected'],'data':data,'notifications': notifs,}) @@ -1235,16 +1273,19 @@ def outward_files(request): des = HoldsDesignation.objects.all().filter(user = request.user).last() data='' if request.session['currentDesignationSelected'] == "Dean Academic" : - data='As a "Dean Academic" you cannot have any out going files' + data=f'As a "{request.session["currentDesignationSelected"]}" you cannot have any out going files' pass elif request.session['currentDesignationSelected'] == "Associate Professor" or request.session['currentDesignationSelected'] == "Professor" or request.session['currentDesignationSelected'] == "Assistant Professor" : pass elif 'hod' in request.session['currentDesignationSelected'].lower(): pass - elif request.session['currentDesignationSelected'] == "acadadmin" or request.session['currentDesignationSelected'] == "student" : + elif request.session['currentDesignationSelected'] == "student" : return HttpResponseRedirect('/programme_curriculum/programmes/') + elif request.session['currentDesignationSelected']== "acadadmin": + return render(request, 'programme_curriculum/admin_programmes/') id=request.user + notifs = request.user.notifications.all() user_designation=HoldsDesignation.objects.select_related('user','working','designation').filter(user=request.user) design=request.session['currentDesignationSelected'] @@ -1255,16 +1296,16 @@ def outward_files(request): courseProposal = Proposal_Tracking.objects.filter(current_design = design,current_id= des.user) - return render(request, 'programme_curriculum/faculty/outward_course_forms.html',{'courseProposals': courseProposal,'design':request.session['currentDesignationSelected'],'data':data}) + return render(request, 'programme_curriculum/faculty/outward_course_forms.html',{'courseProposals': courseProposal,'design':request.session['currentDesignationSelected'],'data':data,'notifications': notifs,}) -def update_course_proposal_file(request,course_id): +def update_course_proposal_file(request, course_id): des = HoldsDesignation.objects.all().filter(user = request.user).first() if request.session['currentDesignationSelected'] == "Associate Professor" or request.session['currentDesignationSelected'] == "Professor" or request.session['currentDesignationSelected'] == "Assistant Professor": pass elif request.session['currentDesignationSelected'] == "acadadmin" : return HttpResponseRedirect('/programme_curriculum/admin_programmes') else: - return HttpResponseRedirect('/programme_curriculum/programmes') + return HttpResponseRedirect('/programme_curriculum/programmes/') uploader = request.user.extrainfo design=request.session['currentDesignationSelected'] @@ -1273,20 +1314,44 @@ def update_course_proposal_file(request,course_id): form = NewCourseProposalFile(initial={'uploader':des.user,'designation':design},instance=course) submitbutton= request.POST.get('Submit') - if submitbutton: if request.method == 'POST': form = NewCourseProposalFile(request.POST) if form.is_valid(): + previous = Course.objects.all().filter(code=course.code).order_by('version').last() + course.version=previous.version new_course=form.save(commit=False) new_course.is_read=False new_course.is_update=True - new_course.save() - messages.success(request, "Added successful") - return HttpResponseRedirect('/programme_curriculum/view_course_proposal_forms/') - - - return render(request,'programme_curriculum/faculty/course_proposal_form.html',{'form':form,'submitbutton': submitbutton,'file_info':file_data}) + add=True + ver=0 + # Check if a course with the same values (except version, latest_version, disciplines, and pre_requisit_courses) already exists + old_course=Course.objects.filter(code=new_course.code, name=new_course.name, credit=new_course.credit, lecture_hours=new_course.lecture_hours, tutorial_hours=new_course.tutorial_hours, pratical_hours=new_course.pratical_hours, discussion_hours=new_course.discussion_hours, project_hours=new_course.project_hours, pre_requisits=new_course.pre_requisits, syllabus=new_course.syllabus, percent_quiz_1=new_course.percent_quiz_1, percent_midsem=new_course.percent_midsem, percent_quiz_2=new_course.percent_quiz_2, percent_endsem=new_course.percent_endsem, percent_project=new_course.percent_project, percent_lab_evaluation=new_course.percent_lab_evaluation, percent_course_attendance=new_course.percent_course_attendance, ref_books=new_course.ref_books) + if old_course: + # Check if disciplines or pre_requisit_courses have been changed + for i in old_course: + if set(form.cleaned_data['pre_requisit_courses']) != set(i.pre_requisit_courses.all()): + add=True + else: + add=False + ver=i.version + break + if add: + new_course.save() # Save the new course first before adding many-to-many fields + new_course.pre_requisit_courses.set(form.cleaned_data['pre_requisit_courses']) + course = Course.objects.last() + messages.success(request, "Added successful") + return HttpResponseRedirect("/programme_curriculum/admin_course/" + str(course.id) + "/") + else: + form.add_error(None, 'A Course with the same values already exists at "Version Number '+' ' +str(ver)+'"') + else: + new_course.save() # Save the new course first before adding many-to-many fields + new_course.pre_requisit_courses.set(form.cleaned_data['pre_requisit_courses']) + course = Course.objects.last() + messages.success(request, "Added successful") + return HttpResponseRedirect("/programme_curriculum/admin_course/" + str(course.id) + "/") + + return render(request,'programme_curriculum/faculty/course_proposal_form.html',{'form':form,'submitbutton': submitbutton,'file_info':file_data,}) @@ -1314,7 +1379,7 @@ def forward_course_forms(request,ProposalId): if(course): previous = Course.objects.all().filter(code=course.code).order_by('version').last() course.version=previous.version - form = CourseForm(instance=course) + form = CourseForm(instance=file2,initial={'disciplines':file.disciplines}) submitbutton= request.POST.get('Submit') if submitbutton: if request.method == 'POST': @@ -1334,10 +1399,10 @@ def forward_course_forms(request,ProposalId): receiver=file2.uploader receiver_id = User.objects.get(username=receiver) - data='The Course "'+ file2.code+ ' - '+ file2.name + '" Updated Successfully' + data=f'The Course " {file2.code} -{file2.name}" Updated Successfully' # data=file.subject prog_and_curr_notif(request.user,receiver_id,data) - messages.success(request, data) + messages.success(request, "Updated "+ file2.code+'-'+file2.name +" successful") return HttpResponseRedirect("/programme_curriculum/course/" + str(course.id) + "/") else: version_error+=f'The version should be greater than {previous.version}' @@ -1363,7 +1428,7 @@ def forward_course_forms(request,ProposalId): # data=file.subject prog_and_curr_notif(request.user,receiver_id,data) course =Course.objects.all().filter(code=file2.code).last() - messages.success(request, "Updated "+ file2.name +" successful") + messages.success(request, "Added "+ file2.name +" successful") return HttpResponseRedirect("/programme_curriculum/course/" + str(course.id) + "/") @@ -1383,25 +1448,28 @@ def forward_course_forms(request,ProposalId): if request.method == 'POST': form = CourseProposalTrackingFile(request.POST) if form.is_valid(): - file.is_submitted=True - file.save() - form.is_read=False - form.save() - - receiver=request.POST.get('receive_id') - - uploader=request.POST.get('current_id') - uploader_design=request.POST.get('current_design') - - - receiver_design=request.POST.get('receive_design') - receiver_des= Designation.objects.get(id=receiver_design) - receiver_id = User.objects.get(id=receiver) - messages.success(request, "Added successful") - data='Received as '+ str(receiver_id) +'-'+str(receiver_des) +' Course Proposal of Course '+file_data +' By '+str(uploader)+' - '+str(uploader_design) + try: + file.is_submitted=True + file.save() + form.is_read=False + form.save() + + receiver=request.POST.get('receive_id') + + uploader=request.POST.get('current_id') + uploader_design=request.POST.get('current_design') + + + receiver_design=request.POST.get('receive_design') + receiver_des= Designation.objects.get(id=receiver_design) + receiver_id = User.objects.get(id=receiver) + messages.success(request, "Added successful") + data='Received as '+ str(receiver_id) +'-'+str(receiver_des) +' Course Proposal of Course '+file_data +' By '+str(uploader)+' - '+str(uploader_design) - prog_and_curr_notif(request.user,receiver_id,data) - return HttpResponseRedirect('/programme_curriculum/outward_files/') + prog_and_curr_notif(request.user,receiver_id,data) + return HttpResponseRedirect('/programme_curriculum/outward_files/') + except IntegrityError as e: + form.add_error(None, 'Proposal_ tracking with this File id, Current id, Current design and Disciplines already exists.') elif request.session['currentDesignationSelected'] == "acadadmin" : return HttpResponseRedirect('/programme_curriculum/admin_programmes') else: @@ -1424,8 +1492,6 @@ def view_inward_files(request,ProposalId): return HttpResponseRedirect('/programme_curriculum/programmes/') des = HoldsDesignation.objects.all().filter(user = request.user).first() - - uploader = request.user.extrainfo design=request.session['currentDesignationSelected'] file = get_object_or_404(Proposal_Tracking, Q(id=ProposalId)) @@ -1472,4 +1538,84 @@ def reject_form(request,ProposalId): else: messages.error(request, "course already forwarded or added can't be rejected") return HttpResponseRedirect('/programme_curriculum/inward_files/') - \ No newline at end of file + + +def tracking_unarchive(request,ProposalId): + if request.session['currentDesignationSelected'] == "Associate Professor" or request.session['currentDesignationSelected'] == "Professor" or request.session['currentDesignationSelected'] == "Assistant Professor" or request.session['currentDesignationSelected'] == "Dean Academic": + pass + elif 'hod' in request.session['currentDesignationSelected'].lower(): + pass + elif request.session['currentDesignationSelected'] == "acadadmin": + return HttpResponseRedirect('/programme_curriculum/admin_programmes/') + else: + return HttpResponseRedirect('/programme_curriculum/programmes/') + + track=get_object_or_404(Proposal_Tracking, Q(id=ProposalId)) + file = get_object_or_404(NewProposalFile,Q(id = track.file_id)) + print(request.user) + if str(track.current_design)==str(request.session['currentDesignationSelected']) and str(track.current_id)==str(request.user): + track.sender_archive=False + track.save() + messages.success(request, "File UnArchived") + return HttpResponseRedirect('/programme_curriculum/outward_files/') + else : + track.receiver_archive=False + track.save() + messages.success(request, "File UnArchived") + return HttpResponseRedirect('/programme_curriculum/inward_files/') + + + +def tracking_archive(request,ProposalId): + + if request.session['currentDesignationSelected'] == "Associate Professor" or request.session['currentDesignationSelected'] == "Professor" or request.session['currentDesignationSelected'] == "Assistant Professor" or request.session['currentDesignationSelected'] == "Dean Academic": + pass + elif 'hod' in request.session['currentDesignationSelected'].lower(): + pass + elif request.session['currentDesignationSelected'] == "acadadmin": + return HttpResponseRedirect('/programme_curriculum/admin_programmes/') + else: + return HttpResponseRedirect('/programme_curriculum/programmes/') + + track=get_object_or_404(Proposal_Tracking, Q(id=ProposalId)) + if str(track.current_design)==str(request.session['currentDesignationSelected']) and str(track.current_id)==str(request.user): + track.sender_archive=True + track.save() + messages.success(request, "File Archived") + return HttpResponseRedirect('/programme_curriculum/outward_files/') + + else: + track.receiver_archive=True + track.save() + messages.success(request, "File Archived") + return HttpResponseRedirect('/programme_curriculum/inward_files/') + +def file_archive(request,FileId): + if request.session['currentDesignationSelected'] == "Associate Professor" or request.session['currentDesignationSelected'] == "Professor" or request.session['currentDesignationSelected'] == "Assistant Professor" or request.session['currentDesignationSelected'] == "Dean Academic": + pass + elif 'hod' in request.session['currentDesignationSelected'].lower(): + pass + elif request.session['currentDesignationSelected'] == "acadadmin": + return HttpResponseRedirect('/programme_curriculum/admin_programmes/') + else: + return HttpResponseRedirect('/programme_curriculum/programmes/') + + file = get_object_or_404(NewProposalFile,Q(id = FileId)) + file.is_archive=True + file.save() + return HttpResponseRedirect('/programme_curriculum/view_course_proposal_forms/') + +def file_unarchive(request,FileId): + if request.session['currentDesignationSelected'] == "Associate Professor" or request.session['currentDesignationSelected'] == "Professor" or request.session['currentDesignationSelected'] == "Assistant Professor" or request.session['currentDesignationSelected'] == "Dean Academic": + pass + elif 'hod' in request.session['currentDesignationSelected'].lower(): + pass + elif request.session['currentDesignationSelected'] == "acadadmin": + return HttpResponseRedirect('/programme_curriculum/admin_programmes/') + else: + return HttpResponseRedirect('/programme_curriculum/programmes/') + + file = get_object_or_404(NewProposalFile,Q(id = FileId)) + file.is_archive=False + file.save() + return HttpResponseRedirect('/programme_curriculum/view_course_proposal_forms/') \ No newline at end of file diff --git a/FusionIIIT/applications/ps1/migrations/0001_initial.py b/FusionIIIT/applications/ps1/migrations/0001_initial.py index 4d5674c39..5b3086e09 100644 --- a/FusionIIIT/applications/ps1/migrations/0001_initial.py +++ b/FusionIIIT/applications/ps1/migrations/0001_initial.py @@ -1,7 +1,8 @@ -# Generated by Django 3.1.5 on 2024-04-15 23:58 +# Generated by Django 3.1.5 on 2024-07-16 15:44 from django.db import migrations, models import django.db.models.deletion +import django.utils.timezone class Migration(migrations.Migration): @@ -24,7 +25,8 @@ class Migration(migrations.Migration): ('estimated_cost', models.IntegerField(null=True)), ('purpose', models.CharField(max_length=250)), ('specification', models.CharField(max_length=250)), - ('indent_type', models.CharField(max_length=250)), + ('item_type', models.CharField(max_length=250)), + ('item_subtype', models.CharField(default='computers', max_length=250)), ('nature', models.BooleanField(default=False)), ('indigenous', models.BooleanField(default=False)), ('replaced', models.BooleanField(default=False)), @@ -40,19 +42,54 @@ class Migration(migrations.Migration): 'db_table': 'IndentFile', }, ), + migrations.CreateModel( + name='StockItem', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nomenclature', models.CharField(max_length=100, unique=True)), + ('inUse', models.BooleanField(default=True)), + ('location', models.CharField(choices=[('SR1', 'LHTC'), ('SR2', 'Computer Center'), ('SR3', 'Panini Hostel'), ('SR4', 'Lab complex'), ('SR5', 'Admin Block')], default='SR1', max_length=100)), + ('isTransferred', models.BooleanField(default=False)), + ('department', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='globals.departmentinfo')), + ], + options={ + 'db_table': 'StockItem', + }, + ), migrations.CreateModel( name='StockEntry', fields=[ ('item_id', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='ps1.indentfile')), ('vendor', models.CharField(max_length=250)), - ('item_name', models.CharField(max_length=250)), ('current_stock', models.IntegerField()), ('recieved_date', models.DateField()), ('bill', models.FileField(upload_to='')), + ('location', models.CharField(choices=[('SR1', 'LHTC'), ('SR2', 'Computer Center'), ('SR3', 'Panini Hostel'), ('SR4', 'Lab complex'), ('SR5', 'Admin Block')], default='SR1', max_length=100)), ('dealing_assistant_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), ], options={ 'db_table': 'StockEntry', }, ), - ] \ No newline at end of file + migrations.CreateModel( + name='StockTransfer', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('src_location', models.CharField(choices=[('SR1', 'LHTC'), ('SR2', 'Computer Center'), ('SR3', 'Panini Hostel'), ('SR4', 'Lab complex'), ('SR5', 'Admin Block')], default='SR1', max_length=100)), + ('dest_location', models.CharField(choices=[('SR1', 'LHTC'), ('SR2', 'Computer Center'), ('SR3', 'Panini Hostel'), ('SR4', 'Lab complex'), ('SR5', 'Admin Block')], default='SR2', max_length=100)), + ('dateTime', models.DateTimeField(default=django.utils.timezone.now)), + ('dest_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='dept_dest_transfers', to='globals.departmentinfo')), + ('indent_file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ps1.indentfile')), + ('src_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='dept_src_transfers', to='globals.departmentinfo')), + ('stockItem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ps1.stockitem')), + ], + options={ + 'db_table': 'StockTransfer', + }, + ), + migrations.AddField( + model_name='stockitem', + name='StockEntryId', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ps1.stockentry'), + ), + ] diff --git a/FusionIIIT/applications/ps1/models.py b/FusionIIIT/applications/ps1/models.py index ffbe50020..b34683836 100644 --- a/FusionIIIT/applications/ps1/models.py +++ b/FusionIIIT/applications/ps1/models.py @@ -16,6 +16,7 @@ class IndentFile(models.Model): purpose=models.CharField(max_length=250,blank=False ) specification=models.CharField(max_length=250) item_type=models.CharField(max_length=250) + item_subtype = models.CharField(max_length=250,blank=False,default='computers') nature=models.BooleanField(default = False) indigenous= models.BooleanField(default = False) replaced =models.BooleanField(default = False) diff --git a/FusionIIIT/applications/ps1/urls.py b/FusionIIIT/applications/ps1/urls.py index 148e0c753..dc0b33bae 100644 --- a/FusionIIIT/applications/ps1/urls.py +++ b/FusionIIIT/applications/ps1/urls.py @@ -68,7 +68,8 @@ url(r'^outboxview/$', views.outboxview, name='outboxview'), - url(r'^update_stock_item_inUse/$', views.updateStockItemInUse, name='outboxview'), + url(r'^update_stock_item_inUse/$', views.updateStockItemInUse, name='stockItemInUse'), + url(r'^item_detail/(?P\d+)/$', views.item_detail, name='item_detail'), # BASE API url(r'^api/',include('applications.ps1.api.urls')), diff --git a/FusionIIIT/applications/ps1/views.py b/FusionIIIT/applications/ps1/views.py index c07889c43..971df43b0 100644 --- a/FusionIIIT/applications/ps1/views.py +++ b/FusionIIIT/applications/ps1/views.py @@ -20,6 +20,8 @@ import json from django.db.models import Q,Count +from datetime import datetime +from datetime import datetime dept_admin_to_dept = { "deptadmin_cse": "CSE", @@ -29,9 +31,11 @@ "deptadmin_design": "Design", "deptadmin_liberalarts": "Liberal Arts", "deptadmin_ns": "Natural Science", + "Admin IWD":"IWD", + "Compounder":"Health Center" } -dept_admin_design = ["deptadmin_cse", "deptadmin_ece", "deptadmin_me","deptadmin_sm", "deptadmin_design", "deptadmin_liberalarts","deptadmin_ns" ] +dept_admin_design = ["deptadmin_cse", "deptadmin_ece", "deptadmin_me","deptadmin_sm", "deptadmin_design", "deptadmin_liberalarts","deptadmin_ns" ,"Admin IWD","Compounder"] @login_required(login_url = "/accounts/login/") @@ -118,6 +122,8 @@ def create_proposal(request): purpose=request.POST.get('purpose') specification=request.POST.get('specification') item_type=request.POST.get('item_type') + item_subtype=request.POST.get('item_subtype') + nature=request.POST.get('nature') indigenous=request.POST.get('indigenous') replaced =request.POST.get('replaced') @@ -150,6 +156,7 @@ def create_proposal(request): purpose=purpose, specification=specification, item_type=item_type, + item_subtype=item_subtype, nature=nature, indigenous=indigenous, replaced = replaced , @@ -191,6 +198,8 @@ def create_proposal(request): purpose=request.POST.get('purpose') specification=request.POST.get('specification') item_type=request.POST.get('item_type') + item_subtype=request.POST.get('item_subtype') + nature=request.POST.get('nature') indigenous=request.POST.get('indigenous') replaced =request.POST.get('replaced') @@ -249,6 +258,7 @@ def create_proposal(request): purpose=purpose, specification=specification, item_type=item_type, + item_subtype=item_subtype, nature=nature, indigenous=indigenous, replaced = replaced , @@ -751,6 +761,7 @@ def forwardindent(request, id): file_attachment=upload_file ) + # 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 @@ -768,8 +779,9 @@ def forwardindent(request, id): indent.save() - + office_module_notif(request.user, receiver_id) messages.success(request, 'Indent File Forwarded successfully') + 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) @@ -1104,11 +1116,12 @@ def current_stock_view(request): StockEntryId__item_id__item_type=type ) - grouped_items = StockItems.values('StockEntryId__item_id__item_type', 'department').annotate(total_quantity=Count('id')) + grouped_items = StockItems.values('StockEntryId__item_id__item_type','StockEntryId__item_id__item_subtype', 'department').annotate(total_quantity=Count('id')) grouped_items_list = [ { 'item_type': item['StockEntryId__item_id__item_type'], + 'item_subtype': item['StockEntryId__item_id__item_subtype'], 'department': DepartmentInfo.objects.get(id=department), 'total_quantity': item['total_quantity'] } @@ -1118,6 +1131,7 @@ def current_stock_view(request): firstStock=StockItems.first() + print(grouped_items_list) return render(request,'ps1/current_stock_view.html',{'stocks':grouped_items_list,'first_stock':firstStock, @@ -1135,9 +1149,11 @@ def current_stock_view(request): print(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) + StockItems = StockItem.objects.filter(department=deptId['id']) elif request.session['currentDesignationSelected'] == "ps_admin": departments=DepartmentInfo.objects.values('id','name').all() @@ -1147,11 +1163,12 @@ def current_stock_view(request): return redirect('/dashboard') - grouped_items = StockItems.values('StockEntryId__item_id__item_type','department').annotate(total_quantity=Count('id')) + grouped_items = StockItems.values('StockEntryId__item_id__item_type','StockEntryId__item_id__item_subtype','department').annotate(total_quantity=Count('id')) grouped_items_list = [ { 'item_type': item['StockEntryId__item_id__item_type'], + 'item_subtype': item['StockEntryId__item_id__item_subtype'], 'department': DepartmentInfo.objects.values('id','name').get(id=item['department']), 'departmentId': item['department'], 'total_quantity': item['total_quantity'] @@ -1170,14 +1187,19 @@ def stock_item_view(request): if request.session['currentDesignationSelected'] not in dept_admin_design + ["ps_admin"]: return redirect('/dashboard') + if request.method=="GET": + return HttpResponseRedirect('../current_stock_view') + if request.method=="POST": departmentId = request.POST.get('departmentId') type = request.POST.get('item_type') + subtype = request.POST.get('item_subtype') # StockEntryId__item_id__file_info_grade StockItems = StockItem.objects.filter( department=departmentId, - StockEntryId__item_id__item_type=type + StockEntryId__item_id__item_type=type, + StockEntryId__item_id__item_subtype=subtype ) return render(request,'ps1/stock_item_view.html',{'stocks':StockItems}) @@ -1339,16 +1361,57 @@ def generate_report(request): if request.session['currentDesignationSelected'] not in dept_admin_design + ["ps_admin"]: return redirect('/dashboard') + - des = HoldsDesignation.objects.all().select_related().filter(user = request.user).first() - department = request.user.extrainfo.department.name + if request.method =='GET': + if request.session['currentDesignationSelected'] in dept_admin_design: - if request.session['currentDesignationSelected'] in dept_admin_design: - sto=StockEntry.objects.filter(item_id__file_info__uploader__department__name=dept_admin_to_dept[request.session['currentDesignationSelected']]) - else: - sto=StockEntry.objects.all() + deptId = DepartmentInfo.objects.values('id', 'name').get(name=dept_admin_to_dept[request.session['currentDesignationSelected']]) + departments=[deptId] + + elif request.session['currentDesignationSelected'] == "ps_admin": + departments=DepartmentInfo.objects.values('id','name').all() + + return render(request,'ps1/generate_report_filter.html',{'departments':departments}) + + + if request.method=="POST": - return render(request,'ps1/generate_report.html',{'sto':sto}) + + departments = request.POST.getlist('departments') + start_date = request.POST.get('start_date'); + finish_date = request.POST.get('finish_date'); + + + + start_date = datetime.strptime(start_date, '%Y-%m-%d').date() + finish_date = datetime.strptime(finish_date, '%Y-%m-%d').date() + + if(departments[0]=='all'): + StockItems = StockItem.objects.filter(StockEntryId__recieved_date__range=(start_date, finish_date)) + else : + StockItems = StockItem.objects.filter(department__in=departments, StockEntryId__recieved_date__range=(start_date, finish_date)) + + + grouped_items = StockItems.values('StockEntryId__item_id__item_type','StockEntryId__item_id__item_subtype','department').annotate(total_quantity=Count('id')) + + grouped_items_list = [ + { + 'item_type': item['StockEntryId__item_id__item_type'], + 'item_subtype': item['StockEntryId__item_id__item_subtype'], + 'department': DepartmentInfo.objects.values('id','name').get(id=item['department']), + 'departmentId': item['department'], + 'total_quantity': item['total_quantity'], + 'StockItems': StockItem.objects.filter( + department=item['department'], + StockEntryId__item_id__item_type=item['StockEntryId__item_id__item_type'] + ) + } + for item in grouped_items + ] + + + return render(request,'ps1/generate_report.html',{'departments':departments,'stocks':grouped_items_list}) @login_required(login_url = "/accounts/login") @@ -1447,7 +1510,7 @@ def perform_transfer(request): dest_location=dest_location ) - messages.success(request,'Stock Transfer Done Successfully.!') + messages.success(request,'Stock Transfer Done Successfully.!') # if the quantity required for this indent file is fulfilled we should mark this indentfile as done. if(moreStocksRequired<=0): myIndent.purchased=True @@ -1458,7 +1521,7 @@ def perform_transfer(request): department = request.user.extrainfo.department.name - return HttpResponseRedirect('../view_transfer') + return JsonResponse({'success':True}) # This is to get the list of all the available stock items for transfer. @login_required(login_url = "/accounts/login") @@ -1537,8 +1600,14 @@ def outboxview(request): @login_required(login_url="/accounts/login") def updateStockItemInUse(request): + print("updatestockiteminuse"); + if request.session['currentDesignationSelected'] not in dept_admin_design + ["ps_admin"]: return redirect('/dashboard') + + if request.method=="GET": + return redirect('../current_stock_view') + if request.method == "POST": @@ -1557,4 +1626,23 @@ def updateStockItemInUse(request): stock_item.inUse = checked stock_item.save() - return redirect('/purchase-and-store/current_stock_view') \ No newline at end of file + return JsonResponse({'success': True}) + + # return HttpResponseRedirect('../current_stock_view') + + +@login_required(login_url="/accounts/login") +def item_detail(request, id): + if request.session['currentDesignationSelected'] not in dept_admin_design + ["ps_admin"]: + return redirect('/dashboard') + + stock_transfers = StockTransfer.objects.filter(stockItem=id).order_by('dateTime') + stock_item = StockItem.objects.filter(id=id).first(); + # Do something with the stock_transfers + + context = { + 'transfers': stock_transfers, + 'item': stock_item + } + + return render(request, 'ps1/stock_item_details.html', context) diff --git a/FusionIIIT/applications/recruitment/migrations/0001_initial.py b/FusionIIIT/applications/recruitment/migrations/0001_initial.py index 386d6d6fb..489d77996 100644 --- a/FusionIIIT/applications/recruitment/migrations/0001_initial.py +++ b/FusionIIIT/applications/recruitment/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-07-16 15:44 import datetime from django.conf import settings diff --git a/FusionIIIT/applications/research_procedures/api/urls.py b/FusionIIIT/applications/research_procedures/api/urls.py index 232dda90c..55c56e10b 100644 --- a/FusionIIIT/applications/research_procedures/api/urls.py +++ b/FusionIIIT/applications/research_procedures/api/urls.py @@ -23,17 +23,17 @@ # 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('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('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('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('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"), diff --git a/FusionIIIT/applications/research_procedures/api/views.py b/FusionIIIT/applications/research_procedures/api/views.py index 3addf40d4..20483cb8e 100644 --- a/FusionIIIT/applications/research_procedures/api/views.py +++ b/FusionIIIT/applications/research_procedures/api/views.py @@ -1,9 +1,11 @@ from rest_framework.viewsets import ModelViewSet from applications.research_procedures.models import * from .serializers import * +from rest_framework.decorators import api_view from rest_framework.permissions import IsAuthenticatedOrReadOnly from django.shortcuts import redirect, render, get_object_or_404 from rest_framework.response import Response +from django.http import JsonResponse from django.contrib import messages from applications.research_procedures.models import * from applications.globals.models import ExtraInfo, HoldsDesignation, Designation @@ -137,219 +139,256 @@ # 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) +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") + 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") + 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") + 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") + 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 + 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 + 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 + ) + 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") -# 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, -# ) +def add_fund_requests(request,pj_id): + data= { + "pj_id": pj_id + } + return render(request,"rs/add_fund_requests.html",context=data) -# messages.success(request,"Project added successfully") -# categories = category.objects.all() +def add_staff_requests(request,pj_id): + data= { + "pj_id": pj_id + } + return render(request,"rs/add_staff_requests.html",context=data) -# 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_projects(request): -# def add_fund_requests(request,pj_id): -# data= { -# "pj_id": pj_id -# } -# return render(request,"rs/add_fund_requests.html",context=data) + # 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") -# def add_staff_requests(request,pj_id): -# data= { -# "pj_id": pj_id -# } -# return render(request,"rs/add_staff_requests.html",context=data) + 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') -# def add_requests(request,id,pj_id): -# if request.method == 'POST': -# obj=request.POST + check = User.objects.filter(username=pid) + # print(check[0].username) -# 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= get_obj_by_username_and_designation(pid, "Professor") #checking for pid to exist -# 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") + 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") -# pi_id_instance=User.objects.get(username= request.user.username ) -# project_instance=projects.objects.get(project_id=projectid) + + + check= get_obj_by_username_and_designation(copid, "Professor") #checking for copid to exist -# 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 + 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") -# 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") + + obj= projects.objects.all() -# 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) + if len(obj)==0 : + projectid=1 + + else : + projectid= obj[0].project_id+1 -# 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") + 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, + 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") +@api_view(['GET']) def view_projects(request): queryset= projects.objects.all() - + print('---------------------------------------------------------------') rspc_admin = HoldsDesignation.objects.get(designation__name="rspc_admin") rspc_admin =rspc_admin.user.username + data = Project_serializer(queryset, many=True).data if request.user.username == rspc_admin: data= { - "projects": queryset, + "projects": data, "username": request.user.username, } - return render(request,"rs/view_projects_rspc.html", context= data) + return JsonResponse(data,safe=False) queryset= projects.objects.filter(project_investigator_id__username= request.user.username) - + data2 = Project_serializer(queryset, many=True).data data= { - "projects": queryset, + "projects": data2, "username": request.user.username, } # print(data) # print(request.user.username) - return Response(data, status=status.HTTP_200_OK) + return JsonResponse(data,safe=False) +def view_project_info(request,id): + id= int(id) + obj= projects.objects.filter(project_id=id) + data = Project_serializer(obj, many=True).data + + + # data = { + # "project": obj, + # } + data = { + "project": data, + } + + return JsonResponse(data , safe=False) # def view_requests(request,id): @@ -382,28 +421,29 @@ def view_projects(request): # return render(request,"rs/view_requests.html", context= data) -# def view_financial_outlay(request,pid): +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) + 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] = financial_outlay_serializer(table_data.filter(category=category) , many=True).data + # category_data = category_serializer(category_data , many=True).data + -# data = { -# 'table_title': 'Total Budget Outlay', -# 'table_caption': '...', # Add caption if needed -# 'project_name':project.project_name, -# 'years': list(years), -# 'category_data': category_data, -# } + 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) + # print(data) + return JsonResponse(data , safe=False) # def submit_closure_report(request,id): # id= int(id) @@ -421,32 +461,33 @@ def view_projects(request): # } # 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) +@api_view(['GET']) +def view_project_inventory(request,pj_id): + pj_id=int(pj_id) + queryset= (requests.objects.filter(project_id=pj_id,request_type="funds")) + queryset = requests_serializer(queryset , many=True).data -# data= { -# "requests": queryset, -# "username": request.user.username -# } -# return render(request,"rs/view_project_inventory.html",context=data) + # print(queryset) + + data= { + "requests": queryset, + "username": request.user.username + } + return JsonResponse(data , safe=True) -# def view_project_staff(request,pj_id): -# pj_id=int(pj_id) -# queryset= requests.objects.filter(project_id=pj_id,request_type="staff") +def view_project_staff(request,pj_id): + pj_id=int(pj_id) + queryset= requests.objects.filter(project_id=pj_id,request_type="staff") + queryset = requests_serializer(queryset , many = True).data -# # print(queryset) + # print(queryset) -# data= { -# "requests": queryset, -# "username": request.user.username -# } -# return render(request,"rs/view_project_staff.html",context=data) + data= { + "requests": queryset, + "username": request.user.username + } + return JsonResponse(data , safe = True) # def projectss(request): # return render(request,"rs/projects.html") @@ -548,36 +589,33 @@ def view_projects(request): # return render(request, "rs/add_staff_details.html", context=data) +@api_view(['GET']) +def view_staff_details(request, pid): + staff_records = staff_allocations.objects.filter(project_id=pid) + data_by_year = {} + project = projects.objects.get(project_id=pid) + # project = Project_serializer(project , many=True).data + + 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': int(record.staff_id.id), + 'staff_name': record.staff_name, + 'qualification': record.qualification, + 'stipend': record.stipend + }) + + context = { + 'data_by_year': data_by_year, + 'project_name': project.project_name + # Add other necessary fields from project here + } -# 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) + rspc_admin = HoldsDesignation.objects.get(designation__name="rspc_admin") + return JsonResponse(context, safe=True) # def add_financial_outlay(request,pid): diff --git a/FusionIIIT/applications/research_procedures/migrations/0001_initial.py b/FusionIIIT/applications/research_procedures/migrations/0001_initial.py index 4de9b80a1..592c0fd36 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-14 19:17 +# Generated by Django 3.1.5 on 2024-07-16 15:44 import datetime from django.conf import settings @@ -12,80 +12,109 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('globals', '0001_initial'), ] operations = [ migrations.CreateModel( - name='TechTransfer', + name='category', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('pf_no', models.IntegerField()), - ('details', models.CharField(default=' ', max_length=500)), - ('date_entry', models.DateField(blank=True, default=datetime.datetime.now, null=True)), - ('start_date', models.DateField(blank=True, null=True)), + ('category_id', models.IntegerField(primary_key=True, serialize=False)), + ('category_name', models.CharField(max_length=500)), + ('sub_category_name', models.CharField(max_length=500)), + ], + options={ + 'ordering': ['-category_id'], + }, + ), + migrations.CreateModel( + name='projects', + fields=[ + ('project_id', models.IntegerField(primary_key=True, serialize=False)), + ('project_name', models.CharField(max_length=600)), + ('project_type', models.CharField(max_length=500)), + ('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(blank=True, null=True, upload_to='')), + ('financial_outlay_status', models.IntegerField(default=0)), + ('co_project_investigator_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='copi_id', to=settings.AUTH_USER_MODEL)), + ('project_investigator_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pi_id', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ['-project_id'], + }, + ), + migrations.CreateModel( + name='staff_allocations', + fields=[ + ('staff_allocation_id', models.IntegerField(primary_key=True, serialize=False)), + ('staff_name', models.CharField(max_length=500)), + ('qualification', models.CharField(max_length=500)), + ('year', models.IntegerField()), + ('stipend', models.IntegerField()), + ('staff_type', models.CharField(default='research', max_length=100)), + ('start_date', models.DateField(default=datetime.date(2024, 7, 16))), ('end_date', models.DateField(blank=True, null=True)), - ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('project_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='research_procedures.projects')), + ('staff_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], + options={ + 'ordering': ['-staff_allocation_id'], + }, ), migrations.CreateModel( - name='ResearchProject', + name='requests', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('pf_no', models.IntegerField()), - ('ptype', models.CharField(default='Research', max_length=100)), - ('pi', models.CharField(default=' ', max_length=1000)), - ('co_pi', models.CharField(default=' ', max_length=1500)), - ('title', models.TextField(default=' ', max_length=5000)), - ('funding_agency', models.CharField(default=' ', max_length=250, null=True)), - ('financial_outlay', models.CharField(default=' ', max_length=150, null=True)), - ('status', models.CharField(choices=[('Awarded', 'Awarded'), ('Submitted', 'Submitted'), ('Ongoing', 'Ongoing'), ('Completed', 'Completed')], max_length=10)), - ('start_date', models.DateField(blank=True, null=True)), - ('finish_date', models.DateField(blank=True, null=True)), - ('date_submission', models.DateField(blank=True, null=True)), - ('date_entry', models.DateField(blank=True, default=datetime.datetime.now, null=True)), - ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('request_id', models.IntegerField(primary_key=True, serialize=False)), + ('request_type', models.CharField(max_length=500)), + ('approval_status', models.IntegerField(default=0)), + ('project_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='research_procedures.projects')), + ('project_investigator_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rj_pi', to=settings.AUTH_USER_MODEL)), ], + options={ + 'ordering': ['-request_id'], + }, ), migrations.CreateModel( - name='ResearchGroup', + name='financial_outlay', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=120)), - ('description', models.TextField()), - ('faculty_under_group', models.ManyToManyField(related_name='allfaculty', to=settings.AUTH_USER_MODEL)), - ('students_under_group', models.ManyToManyField(related_name='allstudents', to=settings.AUTH_USER_MODEL)), + ('financial_outlay_id', models.IntegerField(primary_key=True, serialize=False)), + ('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)), + ('project_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='research_procedures.projects')), ], + options={ + 'ordering': ['-financial_outlay_id'], + }, ), migrations.CreateModel( - name='Patent', + name='co_project_investigator', fields=[ - ('application_id', models.AutoField(primary_key=True, serialize=False)), - ('title', models.CharField(max_length=120)), - ('ipd_form', models.FileField(blank=True, null=True, upload_to='')), - ('project_details', models.FileField(blank=True, null=True, upload_to='')), - ('ipd_form_file', models.TextField(blank=True, null=True)), - ('project_details_file', models.TextField(blank=True, null=True)), - ('status', models.CharField(choices=[('Approved', 'Approved'), ('Disapproved', 'Disapproved'), ('Pending', 'Pending')], default='Pending', max_length=20)), - ('faculty_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('co_pi_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('project_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='research_procedures.projects')), ], + options={ + 'ordering': ['-co_pi_id'], + }, ), migrations.CreateModel( - name='ConsultancyProject', + name='co_pis', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('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(blank=True, null=True)), - ('end_date', models.DateField(blank=True, null=True)), - ('duration', models.CharField(blank=True, max_length=500, null=True)), - ('date_entry', models.DateField(blank=True, default=datetime.datetime.now, null=True)), - ('status', models.CharField(blank=True, choices=[('Completed', 'Completed'), ('Submitted', 'Submitted'), ('Ongoing', 'Ongoing')], default='Ongoing', max_length=10, null=True)), - ('remarks', models.CharField(blank=True, max_length=1000, null=True)), - ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('co_pi', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('project_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='research_procedures.projects')), ], + options={ + 'ordering': ['-project_id'], + }, ), ] diff --git a/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241015_1451.py b/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241015_1451.py new file mode 100644 index 000000000..a120603a6 --- /dev/null +++ b/FusionIIIT/applications/research_procedures/migrations/0002_auto_20241015_1451.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1.5 on 2024-10-12 14:59 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('research_procedures', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='staff_allocations', + name='start_date', + field=models.DateField(default=datetime.date.today), + ), + ] \ No newline at end of file diff --git a/FusionIIIT/applications/research_procedures/models.py b/FusionIIIT/applications/research_procedures/models.py index 9279939d2..3a653e374 100644 --- a/FusionIIIT/applications/research_procedures/models.py +++ b/FusionIIIT/applications/research_procedures/models.py @@ -77,7 +77,7 @@ class staff_allocations(models.Model): 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() + start_date=models.DateField(default=datetime.date.today) end_date=models.DateField(null=True, blank=True) def __str__(self): @@ -88,6 +88,15 @@ def __str__(self): class Meta: ordering = ['-staff_allocation_id'] +class co_pis(models.Model): + co_pi= models.ForeignKey(User, on_delete=models.CASCADE) + project_id= models.ForeignKey(projects, on_delete=models.CASCADE) + + class Meta: + ordering = ['-project_id'] + + + class requests(models.Model): request_id=models.IntegerField(primary_key=True) project_id= models.ForeignKey(projects, on_delete=models.CASCADE) @@ -101,34 +110,15 @@ def __str__(self): 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) +class co_project_investigator(models.Model): + co_pi_id= models.ForeignKey(User, on_delete=models.CASCADE) + project_id= models.ForeignKey(projects, on_delete=models.CASCADE) + def __str__(self): + return str(self.co_pi_id) + + class Meta: + ordering = ['-co_pi_id'] diff --git a/FusionIIIT/applications/research_procedures/views.py b/FusionIIIT/applications/research_procedures/views.py index 9c7132296..838cf0d62 100644 --- a/FusionIIIT/applications/research_procedures/views.py +++ b/FusionIIIT/applications/research_procedures/views.py @@ -153,11 +153,12 @@ 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') + copid=obj.get('co_project_investigator_id-1') sa= obj.get('sponsored_agency') startd= obj.get('start_date') subd= obj.get('finish_date') @@ -166,6 +167,8 @@ def add_projects(request): # project_description= obj.get('description') project_info_file= request.FILES.get('project_info_file') + + check = User.objects.filter(username=pid) # print(check[0].username) @@ -191,8 +194,21 @@ def add_projects(request): return render(request,"rs/projects.html") - obj= projects.objects.all() + copi_list = [] + + for key, value in obj.items(): + if key.startswith('co_project_investigator_id-' ): + if value not in copi_list: + check= HoldsDesignation.objects.filter(user__username= value, designation__name= "Professor") #checking for copid to exist + if not check.exists(): + check= HoldsDesignation.objects.filter(user__username=value , 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") + copi_list.append(value) + + obj= projects.objects.all() if len(obj)==0 : projectid=1 @@ -206,6 +222,13 @@ def add_projects(request): return render(request,"rs/projects.html") + for copi in copi_list: + if copi == pid: + messages.error(request,"Request not added, project investigator and co project investigator cannot be same") + return render(request,"rs/projects.html") + + + @@ -227,7 +250,11 @@ def add_projects(request): project_info_file=project_info_file ) - project_investigator_designation = HoldsDesignation.objects.get(user=userpi_instance).designation + pi_designation= HoldsDesignation.objects.get(user=userpi_instance , designation__name="Professor") + if not pi_designation: + pi_designation= HoldsDesignation.objects.get(user=userpi_instance , designation__name="Assistant Professor") + project_investigator_designation= pi_designation.designation + file_x= create_file( uploader=request.user.username, @@ -241,6 +268,12 @@ def add_projects(request): attached_file= project_info_file, ) + + for copi in copi_list: + co_pis.objects.create( + co_pi= User.objects.get(username=copi), + project_id= projects.objects.get(project_id=projectid) + ) research_procedures_notif(request.user, userpi_instance, "Project Added") tracking_obj = Tracking.objects.get(file_id__id=file_x) @@ -529,9 +562,10 @@ def view_project_info(request,id): obj= projects.objects.get(project_id=id) - + copis= co_pis.objects.filter(project_id__project_id=id) data = { "project": obj, + "copis": copis } return render(request,"rs/view_project_info.html", context= data) @@ -1049,6 +1083,19 @@ def change_end_date(request,id): messages.success(request,"End date changed successfully") return redirect("/research_procedures/view_staff_details/"+str(staff_allocation_instance.project_id.project_id)) +def AjaxDropdown(request): + + if request.method == 'POST': + value = request.POST.get('value') + users = User.objects.filter(username__startswith=value) + users = serializers.serialize('json', list(users)) + + context = { + 'users': users + } + return HttpResponse(JsonResponse(context), content_type='application/json') + + def getDesignation(us): user_inst = User.objects.get(username= us) diff --git a/FusionIIIT/applications/scholarships/migrations/0001_initial.py b/FusionIIIT/applications/scholarships/migrations/0001_initial.py index 13627011e..7e1962c88 100644 --- a/FusionIIIT/applications/scholarships/migrations/0001_initial.py +++ b/FusionIIIT/applications/scholarships/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-07-16 15:44 import datetime from django.db import migrations, models @@ -10,8 +10,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('globals', '0001_initial'), ('academic_information', '0001_initial'), + ('globals', '0001_initial'), ] operations = [ diff --git a/FusionIIIT/applications/scholarships/urls.py b/FusionIIIT/applications/scholarships/urls.py index 769dec040..121cdd116 100755 --- a/FusionIIIT/applications/scholarships/urls.py +++ b/FusionIIIT/applications/scholarships/urls.py @@ -17,6 +17,5 @@ url(r'^getConvocationFlag/$', views.getConvocationFlag, name='getConvocationFlag'), url(r'^getContent/$', views.getContent, name='getContent'), 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 9bffc3fb8..bbcbffb16 100755 --- a/FusionIIIT/applications/scholarships/views.py +++ b/FusionIIIT/applications/scholarships/views.py @@ -3,7 +3,6 @@ from operator import or_ from functools import reduce -from django.http import JsonResponse from django.contrib import messages from django.contrib.auth.decorators import login_required from django.http import HttpResponse, HttpResponseRedirect @@ -24,13 +23,9 @@ from .validations import MCM_list, MCM_schema, gold_list, gold_schema, silver_list, silver_schema, proficiency_list,proficiency_schema from jsonschema import validate from jsonschema.exceptions import ValidationError -from .helpers import getBatch # Create your views here. - - - @login_required(login_url='/accounts/login') def spacs(request): convener = Designation.objects.get(name='spacsconvenor') @@ -75,8 +70,6 @@ def spacs(request): @login_required(login_url='/accounts/login') def convener_view(request): - print(request) - try: convener = Designation.objects.get(name='spacsconvenor') hd = HoldsDesignation.objects.get( @@ -84,11 +77,8 @@ def convener_view(request): except: return HttpResponseRedirect('/logout') if request.method == 'POST': - print("this is a check for post request") if 'Submit' in request.POST: - print("this is a check for post xfhjgisdfkhlsjk request") award = request.POST.get('type') - print("award " + award) programme = request.POST.get('programme') batch = request.POST.get('batch') from_date = request.POST.get('From') @@ -108,17 +98,14 @@ def convener_view(request): ) # It updates the student Notification table on the spacs head sending the mcm invitation - if batch == 'All': + if batch == 'all': active_batches = range(datetime.datetime.now().year - 4 , datetime.datetime.now().year + 1) - query = reduce(or_, (Q(id__id__startswith=int(batch)-2000) for batch in active_batches)) recipient = Student.objects.filter(programme=programme).filter(query) else: recipient = Student.objects.filter(programme=programme, id__id__startswith=int(batch)-2000) - # Notification starts - print(recipient) convenor = request.user for student in recipient: scholarship_portal_notif(convenor, student.id.user, 'award_' + award) # Notification @@ -139,9 +126,9 @@ def convener_view(request): notification_convocation_flag=True, invite_convocation_accept_flag=False) for student in recipient]) # Notification ends - print(batch) + messages.success(request, - award + ' applications are invited successfully for ' + str(batch) + ' batch(es)') + award + ' applications are invited successfully for ' + batch + ' batch(es)') return HttpResponseRedirect('/spacs/convener_view') elif 'Email' in request.POST: @@ -278,7 +265,6 @@ def convener_view(request): @login_required(login_url='/accounts/login') def student_view(request): - if request.method == 'POST': if 'Submit_MCM' in request.POST: return submitMCM(request) @@ -404,52 +390,37 @@ def convenerCatalogue(request): context['result'] = 'Failure' return HttpResponse(json.dumps(context), content_type='convenerCatalogue/json') - - -#below function is refactored and changed as it is not used by the user interface -#it will be changed later for other testing and download of winners def getWinners(request): - # Extract parameters from the request award_name = request.GET.get('award_name') batch_year = int(request.GET.get('batch')) programme_name = request.GET.get('programme') - - # Get the Award_and_scholarship object based on the provided award name - try: - award = Award_and_scholarship.objects.get(award_name=award_name) - except Award_and_scholarship.DoesNotExist: - return JsonResponse({'result': 'Failure', 'message': 'Award not found'}) - - # Query for previous winners based on the provided criteria - winners = Previous_winner.objects.select_related('student__extra_info').filter( + award = Award_and_scholarship.objects.get(award_name=award_name) + winners = Previous_winner.objects.select_related('student','award_id').filter( year=batch_year, award_id=award, programme=programme_name) + context = {} + context['student_name'] = [] + context['student_program'] = [] + context['roll'] = [] - context = { - 'result': 'Success', - 'winners': [], - } - - # Process the winners if any found +# If-Else Condition for previous winner if there is or no data in the winner table if winners: for winner in winners: - # Fetch extra information for the student - extra_info = winner.student.extra_info + + extra_info = ExtraInfo.objects.get(id=winner.student_id) + student_id = Student.objects.get(id=extra_info) student_name = extra_info.user.first_name student_roll = winner.student_id - student_program = winner.student.programme - - # Append student details to the context - context['winners'].append({ - 'student_name': student_name, - 'roll': student_roll, - 'student_program': student_program, - }) + student_program = student_id.programme + context['student_name'].append(student_name) + context['roll'].append(student_roll) + context['student_program'].append(student_program) + + context['result'] = 'Success' else: context['result'] = 'Failure' - context['message'] = 'No winners found for the provided criteria' - return JsonResponse(context) + return HttpResponse(json.dumps(context), content_type='getWinners/json') def get_MCM_Flag(request): # Here we are extracting mcm_flag print("get mcm_flags here") @@ -469,7 +440,6 @@ 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 - print("get convo_flags here") x = Notification.objects.filter(student_id=request.user.extrainfo.id) for i in x: @@ -521,18 +491,6 @@ def updateEndDate(request): context['result'] = 'Failure' return HttpResponse(json.dumps(context), content_type='updateEndDate/json') -def deleteRelease(request): - print("deleteRelease") - id = request.GET.get('id') - is_deleted = Release.objects.filter(pk=id).delete() - request.session['last_clicked'] = "Release_deleted" - context = {} - if is_deleted: - context['result'] = 'Success' - else: - context['result'] = 'Failure' - return HttpResponse(json.dumps(context), content_type='deleteRelease/json') - def getAwardId(request): award = request.POST.get('award') a = Award_and_scholarship.objects.get(award_name=award).id @@ -1064,6 +1022,7 @@ def sendConvenerRenderRequest(request, additionalParams={}): source = Constants.FATHER_OCC_CHOICE time = Constants.TIME release = Release.objects.all() + notification = Notification.objects.select_related('student_id','release_id').all() spi = Spi.objects.all() context.update({ 'source': source, 'time': time, 'ch': ch, 'spi': spi, 'release': release}) context.update(additionalParams) @@ -1071,7 +1030,6 @@ def sendConvenerRenderRequest(request, additionalParams={}): def sendStudentRenderRequest(request, additionalParams={}): context = getCommonParams(request) - ch = Constants.BATCH time = Constants.TIME mother_occ = Constants.MOTHER_OCC_CHOICES @@ -1091,7 +1049,6 @@ def sendStudentRenderRequest(request, additionalParams={}): update_con_flag = False x_notif_mcm_flag = False x_notif_con_flag = False - student_batch = getBatch(request.user.extrainfo.student) for dates in release: if checkDate(dates.startdate, dates.enddate): print("sudheer's test --->") @@ -1102,11 +1059,11 @@ def sendStudentRenderRequest(request, additionalParams={}): if no_of_mcm_filled > 0: update_mcm_flag = True 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 =="20"+ str(request.user.extrainfo.student)[0:2]: try: @@ -1141,7 +1098,7 @@ def sendStudentRenderRequest(request, additionalParams={}): context.update(additionalParams) return render(request, 'scholarshipsModule/scholarships_student.html',context) -def sendStaffRenderRequest(request, additionalParams={}): +def sendStaffRenderRequest(request, additionalParams={}): context = getCommonParams(request) context.update(additionalParams) return render(request, 'scholarshipsModule/scholarships_staff.html', context) diff --git a/FusionIIIT/applications/visitor_hostel/api/serializers.py b/FusionIIIT/applications/visitor_hostel/api/serializers.py new file mode 100644 index 000000000..f5e4c1cf4 --- /dev/null +++ b/FusionIIIT/applications/visitor_hostel/api/serializers.py @@ -0,0 +1,16 @@ +from rest_framework import serializers +from applications.visitor_hostel.models import Inventory, InventoryBill + +class InventorySerializer(serializers.ModelSerializer): + class Meta: + model = Inventory + fields = ['item_name', 'quantity', 'consumable'] + +class InventoryBillSerializer(serializers.ModelSerializer): + class Meta: + model = InventoryBill + fields = ['item_name', 'bill_number', 'cost'] +class InventoryItemSerializer(serializers.ModelSerializer): + class Meta: + model = Inventory + fields = ['item_name', 'quantity'] \ No newline at end of file diff --git a/FusionIIIT/applications/visitor_hostel/api/views.py b/FusionIIIT/applications/visitor_hostel/api/views.py new file mode 100644 index 000000000..b0b658e3a --- /dev/null +++ b/FusionIIIT/applications/visitor_hostel/api/views.py @@ -0,0 +1,50 @@ +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status +from applications.visitor_hostel.models import Inventory, InventoryBill +from .serializers import InventorySerializer, InventoryBillSerializer, InventoryItemSerializer +from rest_framework.generics import ListAPIView +class AddToInventory(APIView): + def post(self, request): + # Extract data from request + item_name = request.data.get('item_name') + bill_number = request.data.get('bill_number') + quantity = request.data.get('quantity') + cost = request.data.get('cost') + consumable = request.data.get('consumable') + + # Validate and save Inventory item + inventory_data = { + 'item_name': item_name, + 'quantity': quantity, + 'consumable': consumable, + } + inventory_serializer = InventorySerializer(data=inventory_data) + + if inventory_serializer.is_valid(): + inventory_item = Inventory.objects.filter(item_name=item_name).first() + if inventory_item: + inventory_item.quantity = quantity + inventory_item.consumable = consumable + inventory_item.save() + else: + inventory_item = inventory_serializer.save() + + # Save InventoryBill + bill_data = { + 'item_name': inventory_item.id, # Link to inventory item + 'bill_number': bill_number, + 'cost': cost, + } + bill_serializer = InventoryBillSerializer(data=bill_data) + if bill_serializer.is_valid(): + bill_serializer.save() + return Response({"message": "Item added successfully!"}, status=status.HTTP_201_CREATED) + else: + return Response(bill_serializer.errors, status=status.HTTP_400_BAD_REQUEST) + else: + return Response(inventory_serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +class InventoryListView(ListAPIView): + queryset = Inventory.objects.all() + serializer_class = InventorySerializer \ No newline at end of file diff --git a/FusionIIIT/applications/visitor_hostel/apps.py b/FusionIIIT/applications/visitor_hostel/apps.py index cf256aeb7..6fdf22599 100644 --- a/FusionIIIT/applications/visitor_hostel/apps.py +++ b/FusionIIIT/applications/visitor_hostel/apps.py @@ -3,3 +3,4 @@ class VisitorHostelConfig(AppConfig): name = 'applications.visitor_hostel' + diff --git a/FusionIIIT/applications/visitor_hostel/migrations/0001_initial.py b/FusionIIIT/applications/visitor_hostel/migrations/0001_initial.py index 96df7d704..fca0cab67 100644 --- a/FusionIIIT/applications/visitor_hostel/migrations/0001_initial.py +++ b/FusionIIIT/applications/visitor_hostel/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-07-16 15:44 from django.conf import settings from django.db import migrations, models diff --git a/FusionIIIT/applications/visitor_hostel/serializers.py b/FusionIIIT/applications/visitor_hostel/serializers.py new file mode 100644 index 000000000..37ca2b64e --- /dev/null +++ b/FusionIIIT/applications/visitor_hostel/serializers.py @@ -0,0 +1,31 @@ +from rest_framework import serializers +from .models import Inventory, InventoryBill +from .models import BookingDetail, Bill + +class InventorySerializer(serializers.ModelSerializer): + class Meta: + model = Inventory + fields = '__all__' + +class InventoryBillSerializer(serializers.ModelSerializer): + class Meta: + model = InventoryBill + fields = '__all__' + +class BillSerializer(serializers.ModelSerializer): + total_bill = serializers.SerializerMethodField() + + class Meta: + model = Bill + fields = ['id', 'booking', 'meal_bill', 'room_bill', 'payment_status', 'bill_date', 'total_bill'] + + def get_total_bill(self, obj): + return obj.meal_bill + obj.room_bill + +class BookingDetailSerializer(serializers.ModelSerializer): + intender_name = serializers.CharField(source='intender.username') # Assuming User model has a username field + bill = BillSerializer() + + class Meta: + model = BookingDetail + fields = ['intender_name', 'booking_from', 'booking_to', 'bill'] diff --git a/FusionIIIT/applications/visitor_hostel/urls.py b/FusionIIIT/applications/visitor_hostel/urls.py index 1153e0d88..4f5fe6b1f 100644 --- a/FusionIIIT/applications/visitor_hostel/urls.py +++ b/FusionIIIT/applications/visitor_hostel/urls.py @@ -1,4 +1,5 @@ from django.conf.urls import url +from applications.visitor_hostel.api.views import AddToInventory, InventoryListView from . import views @@ -9,6 +10,8 @@ url(r'^$', views.visitorhostel, name='visitorhostel'), url(r'^get-booking-requests/', views.get_booking_requests, name='get_booking_requests'), url(r'^get-active-bookings/', views.get_active_bookings, name='get_active_bookings'), + url(r'^get-inactive-bookings/', views.get_inactive_bookings, name='get_inactive_bookings'), + url(r'^get-completed-bookings/', views.get_completed_bookings, name='get_completed_bookings'), url(r'^get-booking-form/', views.get_booking_form, name='get_booking_form'), url(r'^request-booking/' , views.request_booking , name ='request_booking'), url(r'^confirm-booking/' , views.confirm_booking , name ='confirm_booking'), @@ -23,9 +26,37 @@ url(r'^bill_between_date_range/', views.bill_between_dates, name = 'generate_records'), url(r'^room-availability/', views.room_availabity, name = 'room_availabity'), + url(r'^room_availabity_new/', views.room_availabity_new, name = 'room_availabity_new'), + + url(r'^check-partial-booking/', views.check_partial_booking, name='check_partial_booking'), + + url(r'^add-to-inventory/', views.add_to_inventory, name = 'add_to_inventory'), url(r'^update-inventory/', views.update_inventory, name = 'update_inventory'), url(r'^edit-room-status/', views.edit_room_status, name = 'edit_room_status'), url(r'^booking-details/', views.booking_details, name = 'booking_details'), url(r'^forward-booking/', views.forward_booking, name = 'forward_booking'), + url(r'^intenders/', views.get_intenders, name='get_intenders'), # + url(r'^user-details/', views.get_user_details, name='get_user_details'), # + url(r'^get-booking-details/(?P\d+)/$', views.get_booking_details, name='get_booking_details'), # + url(r'^forward-booking-new/$', views.forward_booking_new, name='forward_booking_new'), + + url(r'^confirm-booking-new/$', views.confirm_booking_new, name='confirm_booking_new'), # + + url(r'^inventory/$', views.get_inventory_items, name='get_inventory_items'), + url(r'^inventory/(?P\d+)/$', views.get_inventory_item, name='get_inventory_item'), + url(r'^inventory-bills/$', views.get_inventory_bills, name='get_inventory_bills'), + url(r'^inventory-bills/(?P\d+)/$', views.get_inventory_bill, name='get_inventory_bill'), + + url(r'^accounts-income/$', views.get_all_bills, name='get_all_bills'), + url(r'^accounts-income/(?P\d+)/$', views.get_bills_id, name='get_bills_id'), + + # url(r'^confirm-booking-new/$', views.confirm_booking_new, name='confirm_booking_new'), # + #api + url('api/inventory_add/', AddToInventory.as_view(), name='add-to-inventory'), + url('api/inventory_list/', InventoryListView.as_view(), name='inventory-list'), + # completed bookings + url(r'^completed-bookings/', views.completed_bookings, name='completed_bookings'), + ] + diff --git a/FusionIIIT/applications/visitor_hostel/views.py b/FusionIIIT/applications/visitor_hostel/views.py index 3419a7d14..ff371e7d4 100644 --- a/FusionIIIT/applications/visitor_hostel/views.py +++ b/FusionIIIT/applications/visitor_hostel/views.py @@ -4,7 +4,9 @@ import os import sys + from django.core.files.storage import FileSystemStorage +from django.views.decorators.csrf import csrf_exempt from Fusion import settings from applications.visitor_hostel.models import RoomDetail @@ -24,6 +26,38 @@ # from notification.views import visitor_hostel_caretaker_notif import numpy as np from django.contrib.auth.models import User +from django.http import JsonResponse +from .models import BookingDetail # Make sure to import your BookingDetail model +from django.utils import timezone +from rest_framework.permissions import IsAuthenticated +from rest_framework.authentication import TokenAuthentication +from rest_framework.decorators import api_view, permission_classes,authentication_classes +from django.http import JsonResponse +from .models import BookingDetail # Make sure to import your BookingDetail model +from django.utils import timezone +from rest_framework.permissions import IsAuthenticated +from rest_framework.authentication import TokenAuthentication +from rest_framework.decorators import api_view, permission_classes,authentication_classes + +from django.views.decorators.http import require_GET + + +#---- +#account staments +from rest_framework.decorators import api_view, permission_classes, authentication_classes +from rest_framework.permissions import IsAuthenticated +from rest_framework.authentication import TokenAuthentication +from rest_framework.response import Response +from .models import Inventory, InventoryBill +from .serializers import InventorySerializer, InventoryBillSerializer + +#income +from rest_framework import generics +from .models import BookingDetail +from .serializers import BookingDetailSerializer +#-- + + # from .forms import InventoryForm @@ -278,187 +312,522 @@ def visitorhostel(request): 'cancel_booking_requested': cancel_booking_requested, 'user_designation': user_designation}) +#### NEW +@login_required +@require_GET +def get_intenders(request): + intenders = User.objects.all().values('id', 'username') + return JsonResponse(list(intenders), safe=False) + +@login_required +def get_user_details(request): + user = request.user + user_details = { + 'id': user.id, + 'username': user.username, + 'role': 'student' if user.groups.filter(name='Students').exists() else 'other', + 'intender_id': user.id # Assuming the intender_id is the same as the user ID + } + return JsonResponse(user_details) + # Get methods for bookings -@login_required(login_url='/accounts/login/') + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) def get_booking_requests(request): - if request.method == 'POST': - pending_bookings = BookingDetail.objects.select_related( - 'intender', 'caretaker').filter(status="Pending") + print("works? in the original request") + + # intenders + intenders = User.objects.all() + user = request.user + print("Intenders: ",intenders) + vhcaretaker = request.user.holds_designations.filter( + designation__name='VhCaretaker').exists() + vhincharge = request.user.holds_designations.filter( + designation__name='VhIncharge').exists() + + # finding designation of user + user_designation = "Intender" + if vhincharge: + user_designation = "VhIncharge" + elif vhcaretaker: + user_designation = "VhCaretaker" - return render(request, "vhModule/visitorhostel.html", {'pending_bookings': pending_bookings}) + if request.method == 'GET': + print("User Designation: ", user_designation) + if user_designation in ["VhIncharge", "VhCaretaker"]: + # Fetch all bookings for VhIncharge and VhCaretaker + all_bookings = BookingDetail.objects.select_related('intender', 'caretaker').all() + else: + # Filter bookings by the authenticated user + all_bookings = BookingDetail.objects.select_related('intender', 'caretaker').filter(intender=request.user) + + # Serialize the queryset to a list of dictionaries + bookings_list = [ + { + 'id': booking.id, + 'intender': booking.intender.first_name, + 'email': booking.intender.email, + 'bookingFrom': booking.booking_from.isoformat() if booking.booking_from else None, + 'bookingTo': booking.booking_to.isoformat() if booking.booking_to else None, + 'category': booking.visitor_category, + 'modifiedCategory': booking.modified_visitor_category, + 'status': booking.status, + 'remarks': booking.remark, + 'rooms': [room.room_number for room in booking.rooms.all()] + } + for booking in all_bookings + ] + + return JsonResponse({'pending_bookings': bookings_list}) else: - return HttpResponseRedirect('/visitorhostel/') + return JsonResponse({'error': 'Invalid request method'}, status=400) -# getting active bookings +#@login_required(login_url='/accounts/login/') +# def get_booking_requests(request): +# print("works? in the original request") +# if request.method == 'GET': +# pending_bookings = BookingDetail.objects.select_related( +# 'intender', 'caretaker').filter(status="Pending") +# print(pending_bookings) -@login_required(login_url='/accounts/login/') -def get_active_bookings(request): - if request.method == 'POST': - active_bookings = BookingDetail.objects.select_related( - 'intender', 'caretaker').filter(status="Confirmed") +# return render(request, "vhModule/visitorhostel.html", {'pending_bookings': pending_bookings}) +# else: +# return HttpResponseRedirect('/visitorhostel/') - return render(request, "vhModule/visitorhostel.html", {'active_bookings': active_bookings}) - else: - return HttpResponseRedirect('/visitorhostel/') +# getting active bookings +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def get_active_bookings(request): + # intenders + intenders = User.objects.all() + user = request.user + vhcaretaker = request.user.holds_designations.filter( + designation__name='VhCaretaker').exists() + vhincharge = request.user.holds_designations.filter( + designation__name='VhIncharge').exists() -@login_required(login_url='/accounts/login/') -def get_inactive_bookings(request): - if request.method == 'POST': - inactive_bookings = BookingDetail.objects.select_related('intender', 'caretaker').filter( - Q(status="Cancelled") | Q(status="Rejected") | Q(status="Complete")) + # finding designation of user + user_designation = "Intender" + if vhincharge: + user_designation = "VhIncharge" + elif vhcaretaker: + user_designation = "VhCaretaker" - return render(request, "vhModule/visitorhostel.html", {'inactive_bookings': inactive_bookings}) + if request.method == 'GET': + print("User Designation: ", user_designation) + + if user_designation in ["VhIncharge", "VhCaretaker"]: + # Fetch all relevant bookings for VhCaretaker or VhIncharge + active_bookings = BookingDetail.objects.select_related('intender', 'caretaker').filter( + Q(status="Forward") | Q(status="CheckedIn") | Q(status="Pending")| Q(status="Confirmed"), + booking_to__gte=date.today() + ) + else: + # Fetch only the logged-in user's bookings + active_bookings = BookingDetail.objects.select_related('intender', 'caretaker').filter( + Q(status="Forward") | Q(status="CheckedIn") | Q(status="Pending")| Q(status="Confirmed"), + booking_to__gte=date.today(), + intender=user + ) + # Serialize the queryset to a list of dictionaries + bookings_list = [ + { + 'id': booking.id, + 'intender': booking.intender.first_name, + 'email': booking.intender.email, + 'bookingFrom': booking.booking_from.isoformat() if booking.booking_from else None, + 'bookingTo': booking.booking_to.isoformat() if booking.booking_to else None, + 'category': booking.visitor_category, + # 'status': booking.status, + } + for booking in active_bookings + ] + + return JsonResponse({'active_bookings': bookings_list}) else: - return HttpResponseRedirect('/visitorhostel/') + return JsonResponse({'error': 'Invalid request method'}, status=400) -# Method for making booking request -@login_required(login_url='/accounts/login/') -def get_booking_form(request): - if request.method == 'POST': - intenders = User.objects.all() - return render(request, "vhModule/visitorhostel.html", {'intenders': intenders}) - else: - return HttpResponseRedirect('/visitorhostel/') +# @login_required(login_url='/accounts/login/') +# def get_active_bookings(request): +# if request.method == 'POST': +# active_bookings = BookingDetail.objects.select_related( +# 'intender', 'caretaker').filter(status="Confirmed") -# request booking form action view starts here +# return render(request, "vhModule/visitorhostel.html", {'active_bookings': active_bookings}) +# else: +# return HttpResponseRedirect('/visitorhostel/') -@login_required(login_url='/accounts/login/') -def request_booking(request): +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def get_inactive_bookings(request): + # intenders + intenders = User.objects.all() + user = request.user + vhcaretaker = request.user.holds_designations.filter( + designation__name='VhCaretaker').exists() + vhincharge = request.user.holds_designations.filter( + designation__name='VhIncharge').exists() - if request.method == 'POST': - flag = 0 + # finding designation of user + user_designation = "Intender" + if vhincharge: + user_designation = "VhIncharge" + elif vhcaretaker: + user_designation = "VhCaretaker" - # getting details from request form - intender = request.POST.get('intender') - user = User.objects.get(id=intender) - print("jiihuhhih") - print(user) - booking_id = request.POST.get('booking-id') - category = request.POST.get('category') - person_count = request.POST.get('number-of-people') - bookingObject = [] - # if person_count and (int(person_count)<20): - # person_count = person_count + if request.method == 'GET': + print("User Designation: ", user_designation) - # else: - # flag = 1 # for error + if user_designation in ["VhIncharge", "VhCaretaker"]: + # Fetch all cancelled bookings for VhCaretaker or VhIncharge + cancelled_bookings = BookingDetail.objects.select_related('intender', 'caretaker').filter(Q(status="Canceled") | Q(status="Rejected")) + else: + # Filter cancelled bookings for the logged-in user (intender) + cancelled_bookings = BookingDetail.objects.select_related('intender', 'caretaker').filter(Q(status="Canceled") | Q(status="Rejected"), intender=request.user) + + # Serialize the queryset to a list of dictionaries + bookings_list = [ + { + 'id': booking.id, + 'intender': booking.intender.first_name, + 'email': booking.intender.email, + 'bookingFrom': booking.booking_from.isoformat() if booking.booking_from else None, + 'bookingTo': booking.booking_to.isoformat() if booking.booking_to else None, + 'category': booking.visitor_category, + # 'status': booking.status, # Optional, if you need to include it + } + for booking in cancelled_bookings + ] + + return JsonResponse({'cancelled_bookings': bookings_list}) + else: + return JsonResponse({'error': 'Invalid request method'}, status=400) - # person_count = 1 - purpose_of_visit = request.POST.get('purpose-of-visit') - booking_from = request.POST.get('booking_from') - booking_to = request.POST.get('booking_to') - booking_from_time = request.POST.get('booking_from_time') - booking_to_time = request.POST.get('booking_to_time') - remarks_during_booking_request = request.POST.get( - 'remarks_during_booking_request') - bill_to_be_settled_by = request.POST.get('bill_settlement') - number_of_rooms = request.POST.get('number-of-rooms') - caretaker = 'shailesh' - - # if (int(person_count) -# -# {{message}} -# -# {% endfor %} -# {% endif %} - - # in case of any attachment - - doc = request.FILES.get('files-during-booking-request') - remark = remarks_during_booking_request, - if doc: - print("hello") - filename, file_extenstion = os.path.splitext( - request.FILES.get('files-during-booking-request').booking_id) - filename = booking_id - full_path = settings.MEDIA_ROOT + "/VhImage/" - url = settings.MEDIA_URL + filename + file_extenstion - if not os.path.isdir(full_path): - cmd = "mkdir " + full_path - os.subprocess.call(cmd, shell=True) - fs = FileSystemStorage(full_path, url) - fs.save(filename + file_extenstion, doc) - uploaded_file_url = "/media/online_cms/" + filename - uploaded_file_url = uploaded_file_url + file_extenstion - bookingObject.image = uploaded_file_url - bookingObject.save() - - # visitor datails from place request form - visitor_name = request.POST.get('name') - visitor_phone = request.POST.get('phone') - visitor_email = request.POST.get('email') - visitor_address = request.POST.get('address') - visitor_organization = request.POST.get('organization') - visitor_nationality = request.POST.get('nationality') - # visitor_nationality="jk" - if visitor_organization == '': - visitor_organization = ' ' +# @login_required(login_url='/accounts/login/') +# def get_inactive_bookings(request): +# if request.method == 'POST': +# inactive_bookings = BookingDetail.objects.select_related('intender', 'caretaker').filter( +# Q(status="Cancelled") | Q(status="Rejected") | Q(status="Complete")) - visitor = VisitorDetail.objects.create( - visitor_phone=visitor_phone, visitor_name=visitor_name, visitor_email=visitor_email, visitor_address=visitor_address, visitor_organization=visitor_organization, nationality=visitor_nationality - ) +# return render(request, "vhModule/visitorhostel.html", {'inactive_bookings': inactive_bookings}) +# else: +# return HttpResponseRedirect('/visitorhostel/') - # try: - # bd = BookingDetail.objects.get(id=booking_id) +# Method for making booking request - bookingObject.visitor.add(visitor) - bookingObject.save() +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def get_completed_bookings(request): + # intenders + intenders = User.objects.all() + user = request.user + vhcaretaker = request.user.holds_designations.filter( + designation__name='VhCaretaker').exists() + vhincharge = request.user.holds_designations.filter( + designation__name='VhIncharge').exists() - # except: - # print("exception occured") - # return HttpResponse('/visitorhostel/') + # Determine the user's designation + user_designation = "Intender" + if vhincharge: + user_designation = "VhIncharge" + elif vhcaretaker: + user_designation = "VhCaretaker" + + if request.method == 'GET': + print("User Designation: ", user_designation) - # for sending notification of booking request to caretaker + if user_designation in ["VhIncharge", "VhCaretaker"]: + # Fetch all completed bookings for VhCaretaker or VhIncharge + completed_bookings = BookingDetail.objects.select_related( + 'intender', 'caretaker').filter(check_out__lt=datetime.datetime.today(), intender=user).order_by('booking_from').reverse() + else: + # Filter completed bookings for the logged-in user (intender) + completed_bookings = BookingDetail.objects.select_related( + 'intender', 'caretaker').filter(check_out__lt=datetime.datetime.today(), intender=user).order_by('booking_from').reverse() + + # Serialize the queryset to a list of dictionaries + bookings_list = [ + { + 'id': booking.id, + 'intender': booking.intender.first_name, + 'email': booking.intender.email, + 'bookingFrom': booking.booking_from.isoformat() if booking.booking_from else None, + 'bookingTo': booking.booking_to.isoformat() if booking.booking_to else None, + 'category': booking.visitor_category, + } + for booking in completed_bookings + ] + + return JsonResponse({'completed_bookings': bookings_list}) + else: + return JsonResponse({'error': 'Invalid request method'}, status=400) - # caretaker_name = HoldsDesignation.objects.select_related('user','working','designation').get(designation__name = "VhCaretaker") - # visitors_hostel_notif(request.user, care_taker.user, 'booking_request') - return HttpResponseRedirect('/visitorhostel/') +@login_required(login_url='/accounts/login/') +def get_booking_form(request): + if request.method == 'POST': + intenders = User.objects.all() + return render(request, "vhModule/visitorhostel.html", {'intenders': intenders}) else: return HttpResponseRedirect('/visitorhostel/') +# request booking form action view starts here +# request booking form action view +@csrf_exempt +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def request_booking(request): + if request.method == 'POST': + try: + # Getting details from request form + intenders = User.objects.all() + user = request.user + # intender = request.POST.get('intender') + # user = User.objects.get(id=intenders) + print("jiihuhhih") + print("USER is: ", user) + booking_id = request.data.get('booking_id') # Fixed field name + category = request.data.get('category') + person_count = request.data.get('number-of-people') + purpose_of_visit = request.data.get('purpose-of-visit') + booking_from = request.data.get('booking_from') + booking_to = request.data.get('booking_to') + booking_from_time = request.data.get('booking_from_time') + booking_to_time = request.data.get('booking_to_time') + remarks_during_booking_request = request.data.get('remarks_during_booking_request') + bill_to_be_settled_by = request.data.get('bill_settlement') + number_of_rooms = request.data.get('number-of-rooms') + intenders_list = list(intenders) + # print("INTENDERS :",intenders_list) + # Visitor details + visitor_name = request.data.get('visitor_name') + visitor_email = request.data.get('visitor_email') + visitor_phone = request.data.get('visitor_phone') + visitor_organization = request.data.get('visitor_organization') + visitor_address = request.data.get('visitor_address') + nationality = request.data.get('nationality') + + # Fetching caretaker + care_taker = HoldsDesignation.objects.select_related('user', 'working', 'designation') \ + .filter(designation__name="VhCaretaker").first() + care_taker_user = care_taker.user if care_taker else None + + if care_taker_user: + # Create a VisitorDetail object for the visitor + visitor = VisitorDetail.objects.create( + visitor_name=visitor_name, + visitor_email=visitor_email, + visitor_phone=visitor_phone, + visitor_organization=visitor_organization, + visitor_address=visitor_address, + nationality=nationality, + ) + + # Create a BookingDetail object + booking = BookingDetail.objects.create( + caretaker=care_taker_user, + purpose=purpose_of_visit, + intender=user, + booking_from=booking_from, + booking_to=booking_to, + visitor_category=category, + person_count=person_count, + arrival_time=booking_from_time, + departure_time=booking_to_time, + number_of_rooms=number_of_rooms, + bill_to_be_settled_by=bill_to_be_settled_by, + remark=remarks_during_booking_request, # Correct field name + ) + + # Associate visitor with the booking + booking.visitor.set([visitor]) + + return JsonResponse({'success': 'Booking successfully created', 'booking_id': booking.id}) + else: + return JsonResponse({'error': 'Caretaker not found'}, status=400) + + except Exception as e: + return JsonResponse({'error': str(e)}, status=400) + return JsonResponse({'error': 'Invalid request method'}, status=400) +# request booking form action view starts here + +# @login_required(login_url='/accounts/login/') +# def request_booking(request): + +# if request.method == 'POST': +# print("Received Data:", request) +# print("Request POST Data:", request.POST) +# print("Request FILES Data:", request.FILES) +# # print("Request Headers:", request.headers) +# # print("Request Method:", request.method) +# # print("Request User:", request.user) +# flag = 0 + +# # getting details from request form +# intender = request.POST.get('intender') +# user = User.objects.get(id=intender) +# print("jiihuhhih") +# print(user) +# booking_id = request.POST.get('booking-id') +# category = request.POST.get('category') +# person_count = request.POST.get('number-of-people') +# bookingObject = [] +# # if person_count and (int(person_count)<20): +# # person_count = person_count + +# # else: +# # flag = 1 # for error + +# # person_count = 1 +# purpose_of_visit = request.POST.get('purpose-of-visit') +# booking_from = request.POST.get('booking_from') +# booking_to = request.POST.get('booking_to') +# booking_from_time = request.POST.get('booking_from_time') +# booking_to_time = request.POST.get('booking_to_time') +# remarks_during_booking_request = request.POST.get( +# 'remarks_during_booking_request') +# bill_to_be_settled_by = request.POST.get('bill_settlement') +# number_of_rooms = request.POST.get('number-of-rooms') +# caretaker = 'shailesh' + +# # if (int(person_count) +# # +# # {{message}} +# # +# # {% endfor %} +# # {% endif %} + +# # # in case of any attachment + +# # doc = request.FILES.get('files-during-booking-request') +# # remark = remarks_during_booking_request, +# # if doc: +# # print("hello") +# # filename, file_extenstion = os.path.splitext( +# # request.FILES.get('files-during-booking-request').booking_id) +# # filename = booking_id +# # full_path = settings.MEDIA_ROOT + "/VhImage/" +# # url = settings.MEDIA_URL + filename + file_extenstion +# # if not os.path.isdir(full_path): +# # cmd = "mkdir " + full_path +# # os.subprocess.call(cmd, shell=True) +# # fs = FileSystemStorage(full_path, url) +# # fs.save(filename + file_extenstion, doc) +# # uploaded_file_url = "/media/online_cms/" + filename +# # uploaded_file_url = uploaded_file_url + file_extenstion +# # bookingObject.image = uploaded_file_url +# # bookingObject.save() + +# # # visitor datails from place request form + +# visitor_name = request.POST.get('name') +# visitor_phone = request.POST.get('phone') +# visitor_email = request.POST.get('email') +# visitor_address = request.POST.get('address') +# visitor_organization = request.POST.get('organization') +# visitor_nationality = request.POST.get('nationality') +# # visitor_nationality="jk" +# if visitor_organization == '': +# visitor_organization = ' ' + +# visitor = VisitorDetail.objects.create( +# visitor_phone=visitor_phone, visitor_name=visitor_name, visitor_email=visitor_email, visitor_address=visitor_address, visitor_organization=visitor_organization, nationality=visitor_nationality +# ) + +# # try: +# # bd = BookingDetail.objects.get(id=booking_id) + +# bookingObject.visitor.add(visitor) +# bookingObject.save() + +# # except: +# # print("exception occured") +# # return HttpResponse('/visitorhostel/') + +# # for sending notification of booking request to caretaker + +# # caretaker_name = HoldsDesignation.objects.select_related('user','working','designation').get(designation__name = "VhCaretaker") +# # visitors_hostel_notif(request.user, care_taker.user, 'booking_request') + +# return HttpResponseRedirect('/visitorhostel/') +# else: +# return HttpResponseRedirect('/visitorhostel/') + +#get booking details as Caretaker + +def get_booking_details(request, booking_id): + try: + booking = BookingDetail.objects.select_related('intender').prefetch_related('visitor', 'rooms').get(id=booking_id) + booking_data = { + 'intenderUsername': booking.intender.username, + 'intenderEmail': booking.intender.email, + 'bookingFrom': booking.booking_from, + 'bookingTo': booking.booking_to, + 'visitorCategory': booking.visitor_category, + 'personCount': booking.person_count, + 'numberOfRooms': booking.number_of_rooms, + 'purpose': booking.purpose, + 'billToBeSettledBy': booking.bill_to_be_settled_by, + 'remarks': booking.remark, + 'visitorName': booking.visitor.first().visitor_name if booking.visitor.exists() else '', + 'visitorEmail': booking.visitor.first().visitor_email if booking.visitor.exists() else '', + 'visitorPhone': booking.visitor.first().visitor_phone if booking.visitor.exists() else '', + 'visitorOrganization': booking.visitor.first().visitor_organization if booking.visitor.exists() else '', + 'visitorAddress': booking.visitor.first().visitor_address if booking.visitor.exists() else '', + 'availableRooms': list(RoomDetail.objects.filter(room_status='Available').values('room_number')) + } + return JsonResponse(booking_data) + except BookingDetail.DoesNotExist: + return JsonResponse({'error': 'Booking not found'}, status=404) + # updating a booking request @login_required(login_url='/accounts/login/') @@ -512,6 +881,51 @@ def update_booking(request): else: return HttpResponseRedirect('/visitorhostel/') +# new confirm booking byVhIncharge + +@csrf_exempt +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +@login_required(login_url='/accounts/login/') +def confirm_booking_new(request): + if request.method == 'POST': + try: + booking_id = request.data.get('booking_id') + modified_category = request.data.get('modified_category') + rooms = request.data.get('rooms', []) + remarks = request.data.get('remarks') + action = request.data.get('action') + + booking = BookingDetail.objects.select_related('intender', 'caretaker').get(id=booking_id) + if action == 'accept': + booking.status = 'Confirmed' + elif action == 'reject': + booking.status = 'Rejected' + booking.modified_visitor_category = modified_category + booking.remark = remarks + + # Clear existing rooms and add new rooms + booking.rooms.clear() + for room in rooms: + room_object = RoomDetail.objects.get(room_number=room) + booking.rooms.add(room_object) + booking.number_of_rooms_alloted = len(rooms) + booking.save() + + # Notification of booking confirmation or rejection + visitors_hostel_notif(request.user, booking.intender, 'booking_confirmation' if action == 'accept' else 'booking_rejection') + + return JsonResponse({'success': f'Booking successfully {action}ed'}) + except BookingDetail.DoesNotExist: + return JsonResponse({'error': 'Booking not found'}, status=404) + except RoomDetail.DoesNotExist: + return JsonResponse({'error': 'One or more rooms not found'}, status=404) + except Exception as e: + return JsonResponse({'error': str(e)}, status=400) + else: + return JsonResponse({'error': 'Invalid request method'}, status=400) + # confirm booking by VhIncharge @@ -549,7 +963,9 @@ def confirm_booking(request): return HttpResponseRedirect('/visitorhostel/') -@login_required(login_url='/accounts/login/') +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) def cancel_booking(request): if request.method == 'POST': user = request.user @@ -608,8 +1024,10 @@ def cancel_booking_request(request): # rehject a booking request - -@login_required(login_url='/accounts/login/') +@csrf_exempt +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) def reject_booking(request): if request.method == 'POST': booking_id = request.POST.get('booking-id') @@ -792,6 +1210,29 @@ def bill_generation(request): else: return HttpResponseRedirect('/visitorhostel/') + +# get available rooms list between date range + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def room_availabity_new(request): + if request.method == 'POST': + date_1 = request.data.get('start_date') + date_2 = request.data.get('end_date') + available_rooms_list = [] + + available_rooms_bw_dates = booking_details(date_1, date_2) + + for room in available_rooms_bw_dates: + available_rooms_list.append(room.room_number) + + available_rooms_array = np.asarray(available_rooms_list) + + # Return available rooms in a JSON response + return JsonResponse({'available_rooms': available_rooms_array.tolist()}) + else: + return JsonResponse({'error': 'Invalid request method'}, status=400) # get available rooms list between date range @@ -814,6 +1255,82 @@ def room_availabity(request): return HttpResponseRedirect('/visitorhostel/') + + +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def check_partial_booking(request): + """ + API to check room availability with partial booking support. + """ + if request.method == 'POST': + date_1 = request.data.get('start_date') + date_2 = request.data.get('end_date') + + if not (date_1 and date_2): + return JsonResponse({'error': 'Start date and end date are required.'}, status=400) + + # Convert input dates to datetime objects + start_date = datetime.datetime.strptime(date_1, "%Y-%m-%d").date() + end_date = datetime.datetime.strptime(date_2, "%Y-%m-%d").date() + + # Fetch all rooms + rooms = RoomDetail.objects.all() + response_data = [] + + for room in rooms: + room_id = room.id + room_number = room.room_number + room_type = room.room_type + + # Check for existing bookings for the given room + overlapping_bookings = BookingDetail.objects.filter( + rooms__id=room_id, + booking_from__lt=end_date, + booking_to__gt=start_date, + status="Confirmed" + ).order_by('booking_from') + + # Initialize response data + partial_available = False + available_ranges = [] + + # If there are overlapping bookings, find the partial availability + if overlapping_bookings.exists(): + partial_available = True + current_start = start_date + + for booking in overlapping_bookings: + if booking.booking_from > current_start: + available_ranges.append({ + 'from': current_start, + 'to': booking.booking_from + }) + current_start = booking.booking_to + + if current_start < end_date: + available_ranges.append({ + 'from': current_start, + 'to': end_date + }) + + # Append room data to response + response_data.append({ + 'room_id': room_id, + 'room_number': room_number, + 'room_type': room_type, + 'requested_from': date_1, + 'requested_to': date_2, + 'is_fully_available': not overlapping_bookings.exists(), + 'is_partial_available': partial_available, + 'available_ranges': available_ranges if partial_available else None, + }) + + return JsonResponse(response_data, safe=False) + + else: + return JsonResponse({'error': 'Invalid request method'}, status=400) @login_required(login_url='/accounts/login/') def add_to_inventory(request): if request.method == 'POST': @@ -1001,3 +1518,278 @@ def forward_booking(request): return HttpResponseRedirect('/visitorhostel/') else: return HttpResponseRedirect('/visitorhostel/') + +import logging +logger = logging.getLogger(__name__) +@csrf_exempt +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def forward_booking_new(request): + try: + booking_id = request.data.get('booking_id') + modified_category = request.data.get('modified_category') + rooms = request.data.get('rooms', []) + remarks = request.data.get('remarks') + + logger.info(f"Received rooms: {rooms}") + + booking = BookingDetail.objects.select_related('intender', 'caretaker').get(id=booking_id) + booking.status = "Forward" + booking.modified_visitor_category = modified_category + booking.remark = remarks + + # Clear existing rooms and add new rooms + booking.rooms.clear() + for room in rooms: + try: + room_object = RoomDetail.objects.get(room_number=room) + booking.rooms.add(room_object) + except RoomDetail.DoesNotExist: + logger.error(f"Room {room} does not exist") + return JsonResponse({'error': f'Room {room} not found'}, status=404) + booking.number_of_rooms_alloted = len(rooms) + booking.save() + + # Notify the VhIncharge about the forwarded booking + incharge_designations = HoldsDesignation.objects.select_related( + 'user', 'working', 'designation').filter(designation__name="VhIncharge") + + if not incharge_designations.exists(): + return JsonResponse({'error': 'VhIncharge not found'}, status=404) + + incharge_name = incharge_designations.first() + visitors_hostel_notif(request.user, incharge_name.user, 'booking_forwarded') + + return JsonResponse({'success': 'Booking successfully forwarded'}) + except BookingDetail.DoesNotExist: + return JsonResponse({'error': 'Booking not found'}, status=404) + except RoomDetail.DoesNotExist: + return JsonResponse({'error': 'One or more rooms not found'}, status=404) + except Exception as e: + return JsonResponse({'error': str(e)}, status=400) + + +#account statements + +# Fetch all inventory items +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def get_inventory_items(request): + inventories = Inventory.objects.all() + serializer = InventorySerializer(inventories, many=True) + return Response(serializer.data) + +# Fetch a specific inventory item by ID +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def get_inventory_item(request, pk): + try: + inventory = Inventory.objects.get(id=pk) + serializer = InventorySerializer(inventory) + return Response(serializer.data) + except Inventory.DoesNotExist: + return Response({"error": "Inventory item not found"}, status=404) + +# Fetch all bills +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def get_inventory_bills(request): + bills = InventoryBill.objects.all() + serializer = InventoryBillSerializer(bills, many=True) + return Response(serializer.data) + +# Fetch a specific bill by ID +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def get_inventory_bill(request, pk): + try: + bill = InventoryBill.objects.get(id=pk) + serializer = InventoryBillSerializer(bill) + return Response(serializer.data) + except InventoryBill.DoesNotExist: + return Response({"error": "Bill not found"}, status=404) + + +#income +# account statements + +from rest_framework.decorators import api_view, permission_classes, authentication_classes +from rest_framework.response import Response +from rest_framework.permissions import IsAuthenticated +from rest_framework.authentication import TokenAuthentication +from .models import BookingDetail +from .serializers import BookingDetailSerializer + +from datetime import date + +from datetime import date +from django.db.models import Q + +# Fetch all booking details +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def get_all_bills(request): + bookings = BookingDetail.objects.filter(Q(status="Confirmed") | Q(status="Active")) + response_data = [] + print("BOOKING DATA >>>> ", bookings) + + for booking in bookings: + # Calculate the number of days of stay + num_days = (booking.booking_to - booking.booking_from).days + 1 + + # Determine the per-day cost based on the visitor category + visitor_costs = {'A': 0, 'B': 500, 'C': 800, 'D': 1400} + per_day_cost = visitor_costs.get(booking.visitor_category, 900) + room_bill = num_days * per_day_cost + + # Use a transaction to ensure atomicity of bill creation + with transaction.atomic(): + # Check if booking already has an associated bill + if hasattr(booking, 'bill') and booking.bill: + bill = booking.bill + total_bill = bill.meal_bill + room_bill + bill_id = bill.id + bill_date = bill.bill_date + else: + # Create a new bill if it doesn't exist + bill = Bill.objects.create( + booking=booking, + meal_bill=0.0, # Assuming initial meal bill is 0 + room_bill=room_bill, + payment_status=False, + bill_date=booking.booking_to, # Set bill_date to the checkout date + caretaker=booking.caretaker # Ensure caretaker is set + ) + # Refresh booking instance to ensure it's linked to the new bill + booking.refresh_from_db() + total_bill = bill.room_bill + bill_id = bill.id + bill_date = bill.bill_date + + # Append the booking's billing information to the response list + response_data.append({ + 'intender_name': booking.intender.username, # Assuming `username` for the intender's name + 'booking_from': booking.booking_from, + 'booking_to': booking.booking_to, + 'total_bill': total_bill, + 'bill_id': bill_id, + 'bill_date': bill_date, + }) + + return Response(response_data) + +from django.http import JsonResponse +from rest_framework.response import Response +from django.db import transaction + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def get_bills_id(request, pk): + try: + booking = BookingDetail.objects.get(id=pk, status="Confirmed") + + # Calculate the number of days of stay + num_days = (booking.booking_to - booking.booking_from).days + 1 + + # Determine the per-day cost based on the visitor category + visitor_costs = {'A': 0, 'B': 500, 'C': 800, 'D': 1400} + per_day_cost = visitor_costs.get(booking.visitor_category, 900) + room_bill = num_days * per_day_cost + + # Use a transaction to ensure bill creation is committed immediately + with transaction.atomic(): + # Check if booking already has a bill + if hasattr(booking, 'bill') and booking.bill: + bill = booking.bill + total_bill = bill.meal_bill + room_bill + bill_id = bill.id + bill_date = bill.bill_date + else: + # Create and link a new bill if it doesn't exist + bill = Bill.objects.create( + booking=booking, + meal_bill=0, # Assuming meal bill starts at 0 + room_bill=room_bill, + payment_status=False, + bill_date=booking.booking_to # Checkout date as bill_date + ) + # Refresh the booking to link the new bill + booking.refresh_from_db() + total_bill = bill.room_bill + bill_id = bill.id + bill_date = bill.bill_date + + # Prepare response data with all necessary billing details + response_data = { + 'intender_name': booking.intender.username, # Assuming `username` for intender's name + 'booking_from': booking.booking_from, + 'booking_to': booking.booking_to, + 'total_bill': total_bill, + 'bill_id': bill_id, + 'bill_date': bill_date, + } + return Response(response_data) + + except BookingDetail.DoesNotExist: + return Response({"error": "Booking detail not found"}, status=404) + + +from django.utils import timezone + +@api_view(['GET']) +@permission_classes([IsAuthenticated]) +@authentication_classes([TokenAuthentication]) +def completed_bookings(request): + # Check the user's designation + vhcaretaker = request.user.holds_designations.filter( + designation__name='VhCaretaker').exists() + vhincharge = request.user.holds_designations.filter( + designation__name='VhIncharge').exists() + + # Determine the user's designation + user_designation = "Intender" + if vhincharge: + user_designation = "VhIncharge" + elif vhcaretaker: + user_designation = "VhCaretaker" + + if request.method == 'GET': + current_date = timezone.now().date() + + # Fetch completed bookings based on the user's designation + if user_designation in ["VhIncharge", "VhCaretaker"]: + # For VhIncharge or VhCaretaker, fetch all completed bookings with booking_to date older than the current date + all_bookings = BookingDetail.objects.select_related('intender').filter( + status='Confirmed', + booking_to__lt=current_date + ) + else: + # For Intenders, fetch only their completed bookings with booking_to date older than the current date + all_bookings = BookingDetail.objects.select_related('intender').filter( + intender=request.user, + status='Confirmed', + booking_to__lt=current_date + ) + + # Serialize the queryset to a list of dictionaries with required fields + bookings_list = [ + { + 'intender': booking.intender.first_name, + 'bookingDate': booking.booking_date.isoformat() if booking.booking_date else None, + 'checkIn': booking.booking_from.isoformat() if booking.booking_from else None, + 'checkOut': booking.booking_to.isoformat() if booking.booking_to else None, + 'category': booking.visitor_category, + } + for booking in all_bookings + ] + + return JsonResponse({'completed_bookings': bookings_list}) + else: + return JsonResponse({'error': 'Invalid request method'}, status=400) \ No newline at end of file diff --git a/FusionIIIT/media/Attachment.png b/FusionIIIT/media/Attachment.png deleted file mode 100644 index 9ba023255..000000000 Binary files a/FusionIIIT/media/Attachment.png and /dev/null differ diff --git a/FusionIIIT/media/Attachment_2wB6DYP.png b/FusionIIIT/media/Attachment_2wB6DYP.png deleted file mode 100644 index 9ba023255..000000000 Binary files a/FusionIIIT/media/Attachment_2wB6DYP.png and /dev/null differ diff --git a/FusionIIIT/media/Attachment_6Bg7khy.png b/FusionIIIT/media/Attachment_6Bg7khy.png deleted file mode 100644 index 9ba023255..000000000 Binary files a/FusionIIIT/media/Attachment_6Bg7khy.png and /dev/null differ diff --git a/FusionIIIT/media/Attachment_BXfow1b.png b/FusionIIIT/media/Attachment_BXfow1b.png deleted file mode 100644 index 9ba023255..000000000 Binary files a/FusionIIIT/media/Attachment_BXfow1b.png and /dev/null differ diff --git a/FusionIIIT/media/Attachment_Bu2H6ra.png b/FusionIIIT/media/Attachment_Bu2H6ra.png deleted file mode 100644 index 9ba023255..000000000 Binary files a/FusionIIIT/media/Attachment_Bu2H6ra.png and /dev/null differ diff --git a/FusionIIIT/media/Attachment_F2iCzSM.png b/FusionIIIT/media/Attachment_F2iCzSM.png deleted file mode 100644 index 9ba023255..000000000 Binary files a/FusionIIIT/media/Attachment_F2iCzSM.png and /dev/null differ diff --git a/FusionIIIT/media/Attachment_WTPVGvW.png b/FusionIIIT/media/Attachment_WTPVGvW.png deleted file mode 100644 index 9ba023255..000000000 Binary files a/FusionIIIT/media/Attachment_WTPVGvW.png and /dev/null differ diff --git a/FusionIIIT/media/Attachment_eb9Cr4e.png b/FusionIIIT/media/Attachment_eb9Cr4e.png deleted file mode 100644 index 9ba023255..000000000 Binary files a/FusionIIIT/media/Attachment_eb9Cr4e.png and /dev/null differ diff --git a/FusionIIIT/media/Attachment_pWCnqui.png b/FusionIIIT/media/Attachment_pWCnqui.png deleted file mode 100644 index 9ba023255..000000000 Binary files a/FusionIIIT/media/Attachment_pWCnqui.png and /dev/null differ diff --git a/FusionIIIT/media/Attachment_rZRHYsn.png b/FusionIIIT/media/Attachment_rZRHYsn.png deleted file mode 100644 index 9ba023255..000000000 Binary files a/FusionIIIT/media/Attachment_rZRHYsn.png and /dev/null differ diff --git a/FusionIIIT/media/Attachment_wNScezL.png b/FusionIIIT/media/Attachment_wNScezL.png deleted file mode 100644 index 9ba023255..000000000 Binary files a/FusionIIIT/media/Attachment_wNScezL.png and /dev/null differ diff --git a/FusionIIIT/media/Capture.PNG b/FusionIIIT/media/Capture.PNG deleted file mode 100644 index 8910f1f82..000000000 Binary files a/FusionIIIT/media/Capture.PNG and /dev/null differ diff --git a/FusionIIIT/media/Screenshot_249.png b/FusionIIIT/media/Screenshot_249.png deleted file mode 100644 index 4a5a9166d..000000000 Binary files a/FusionIIIT/media/Screenshot_249.png and /dev/null differ diff --git a/FusionIIIT/media/Screenshot_249_cj6yEIP.png b/FusionIIIT/media/Screenshot_249_cj6yEIP.png deleted file mode 100644 index 4a5a9166d..000000000 Binary files a/FusionIIIT/media/Screenshot_249_cj6yEIP.png and /dev/null differ diff --git a/FusionIIIT/media/Screenshot_from_2020-01-16_152125.png b/FusionIIIT/media/Screenshot_from_2020-01-16_152125.png deleted file mode 100644 index 1b2deb080..000000000 Binary files a/FusionIIIT/media/Screenshot_from_2020-01-16_152125.png and /dev/null differ diff --git a/FusionIIIT/media/Untitled.png b/FusionIIIT/media/Untitled.png deleted file mode 100644 index 8ebc234bd..000000000 Binary files a/FusionIIIT/media/Untitled.png and /dev/null differ diff --git a/FusionIIIT/media/fileee.png b/FusionIIIT/media/fileee.png deleted file mode 100644 index 0b823eee5..000000000 Binary files a/FusionIIIT/media/fileee.png and /dev/null differ diff --git a/FusionIIIT/media/fileee_7KmL2aR.png b/FusionIIIT/media/fileee_7KmL2aR.png deleted file mode 100644 index 0b823eee5..000000000 Binary files a/FusionIIIT/media/fileee_7KmL2aR.png and /dev/null differ diff --git a/FusionIIIT/media/fileee_EAtuz13.png b/FusionIIIT/media/fileee_EAtuz13.png deleted file mode 100644 index 0b823eee5..000000000 Binary files a/FusionIIIT/media/fileee_EAtuz13.png and /dev/null differ diff --git a/FusionIIIT/media/fileee_FCTHv2B.png b/FusionIIIT/media/fileee_FCTHv2B.png deleted file mode 100644 index 0b823eee5..000000000 Binary files a/FusionIIIT/media/fileee_FCTHv2B.png and /dev/null differ diff --git a/FusionIIIT/media/fileee_MHquUFL.png b/FusionIIIT/media/fileee_MHquUFL.png deleted file mode 100644 index 0b823eee5..000000000 Binary files a/FusionIIIT/media/fileee_MHquUFL.png and /dev/null differ diff --git a/FusionIIIT/media/fileee_egFLH3c.png b/FusionIIIT/media/fileee_egFLH3c.png deleted file mode 100644 index 0b823eee5..000000000 Binary files a/FusionIIIT/media/fileee_egFLH3c.png and /dev/null differ diff --git a/FusionIIIT/media/final.png b/FusionIIIT/media/final.png deleted file mode 100644 index 50bf4def1..000000000 Binary files a/FusionIIIT/media/final.png and /dev/null differ diff --git a/FusionIIIT/media/final_rkiLRiF.png b/FusionIIIT/media/final_rkiLRiF.png deleted file mode 100644 index 50bf4def1..000000000 Binary files a/FusionIIIT/media/final_rkiLRiF.png and /dev/null differ diff --git a/FusionIIIT/media/qwqw.png b/FusionIIIT/media/qwqw.png deleted file mode 100644 index a3fa8c79f..000000000 Binary files a/FusionIIIT/media/qwqw.png and /dev/null differ diff --git a/FusionIIIT/media/text_not_aligned.png b/FusionIIIT/media/text_not_aligned.png deleted file mode 100644 index 49b2eb59b..000000000 Binary files a/FusionIIIT/media/text_not_aligned.png and /dev/null differ diff --git a/FusionIIIT/notification/admin.py b/FusionIIIT/notification/admin.py new file mode 100644 index 000000000..c8a0866df --- /dev/null +++ b/FusionIIIT/notification/admin.py @@ -0,0 +1,19 @@ +from django.contrib import admin +from .models import Announcements, AnnouncementRecipients + +# Customize the admin interface for Announcements +@admin.register(Announcements) +class AnnouncementsAdmin(admin.ModelAdmin): + list_display = ('created_by', 'created_at', 'message', 'target_group', 'department', 'batch') + search_fields = ('message', 'created_by__username', 'department') + list_filter = ('target_group', 'department', 'created_at') + date_hierarchy = 'created_at' + ordering = ('-created_at',) + +# Customize the admin interface for AnnouncementRecipients +@admin.register(AnnouncementRecipients) +class AnnouncementRecipientsAdmin(admin.ModelAdmin): + list_display = ('announcement', 'user') + search_fields = ('announcement__message', 'user__user__username') + list_filter = ('announcement__target_group',) + diff --git a/FusionIIIT/notification/forms.py b/FusionIIIT/notification/forms.py new file mode 100644 index 000000000..fe18ec6a9 --- /dev/null +++ b/FusionIIIT/notification/forms.py @@ -0,0 +1,32 @@ +from django import forms +from .models import Announcements, AnnouncementRecipients +from applications.globals.models import ExtraInfo +from django.contrib.auth.models import User + + +class AnnouncementForm(forms.ModelForm): + specific_users = forms.CharField( + required=False, + widget=forms.SelectMultiple(attrs={'class': 'ui fluid multiple search selection dropdown'}) + ) + + class Meta: + model = Announcements + fields = ['message', 'target_group', 'department', 'batch', 'specific_users'] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def clean(self): + cleaned_data = super().clean() + target_group = cleaned_data.get('target_group') + + # Validation based on target group + if target_group == 'faculty' and not cleaned_data.get('department'): + self.add_error('department', 'Department is required for faculty announcements.') + elif target_group == 'students': + if not cleaned_data.get('department') or not cleaned_data.get('batch'): + self.add_error('department', 'Department is required for student announcements.') + self.add_error('batch', 'Batch is required for student announcements.') + + return cleaned_data \ No newline at end of file diff --git a/FusionIIIT/notification/migrations/0001_initial.py b/FusionIIIT/notification/migrations/0001_initial.py new file mode 100644 index 000000000..6b4bf8941 --- /dev/null +++ b/FusionIIIT/notification/migrations/0001_initial.py @@ -0,0 +1,39 @@ +# Generated by Django 3.1.5 on 2024-11-06 22:10 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('globals', '0002_auto_20241007_2302'), + ] + + operations = [ + migrations.CreateModel( + name='Announcements', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('message', models.CharField(max_length=200)), + ('target_group', models.CharField(choices=[('faculty', 'Faculty'), ('students', 'Students'), ('all', 'All Staff and Students'), ('specific_users', 'Specific Users')], max_length=20)), + ('batch', models.IntegerField(blank=True, null=True)), + ('upload_announcement', models.FileField(default=' ', null=True, upload_to='notifications/upload_announcement')), + ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('department', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='globals.departmentinfo')), + ], + ), + migrations.CreateModel( + name='AnnouncementRecipients', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('announcement', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recipients', to='notification.announcements')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='globals.extrainfo')), + ], + ), + ] diff --git a/FusionIIIT/notification/migrations/0002_announcements_module.py b/FusionIIIT/notification/migrations/0002_announcements_module.py new file mode 100644 index 000000000..43537cf35 --- /dev/null +++ b/FusionIIIT/notification/migrations/0002_announcements_module.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.5 on 2024-11-07 13:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('notification', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='announcements', + name='module', + field=models.CharField(default='Fusion', max_length=200), + ), + ] diff --git a/FusionIIIT/notification/migrations/__init__.py b/FusionIIIT/notification/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/FusionIIIT/notification/models.py b/FusionIIIT/notification/models.py index 71a836239..a6f1e697a 100644 --- a/FusionIIIT/notification/models.py +++ b/FusionIIIT/notification/models.py @@ -1,3 +1,29 @@ from django.db import models +from django.contrib.auth.models import User +from applications.globals.models import ExtraInfo, DepartmentInfo # Create your models here. +class Announcements(models.Model): + TARGET_GROUPS = [ + ('faculty', 'Faculty'), + ('students', 'Students'), + ('all', 'All Staff and Students'), + ('specific_users', 'Specific Users'), + ] + created_by = models.ForeignKey(User, on_delete=models.CASCADE) + created_at = models.DateTimeField(auto_now_add=True) + message = models.CharField(max_length=200) + target_group = models.CharField(max_length=20, choices=TARGET_GROUPS) + department = models.ForeignKey(DepartmentInfo, on_delete=models.CASCADE, null=True, blank=True) + batch = models.IntegerField(null=True, blank=True) + upload_announcement = models.FileField(upload_to='notifications/upload_announcement', null=True, default=" ") + module = models.CharField(max_length=200, default='Fusion') + def __str__(self): + return str(self.created_by.username) + +class AnnouncementRecipients(models.Model): + announcement = models.ForeignKey(Announcements, on_delete=models.CASCADE, related_name='recipients') + user = models.ForeignKey(ExtraInfo, on_delete=models.CASCADE) + + def __str__(self): + return f"{self.user.id} - {self.announcement.message}" \ No newline at end of file diff --git a/FusionIIIT/notification/views.py b/FusionIIIT/notification/views.py index 825d91151..5f134a9a7 100644 --- a/FusionIIIT/notification/views.py +++ b/FusionIIIT/notification/views.py @@ -1,9 +1,118 @@ -from django.shortcuts import render +from django.shortcuts import render, redirect from requests import Response from notifications.signals import notify +from django.core.mail import EmailMessage +from django.template.loader import render_to_string +from Fusion.celery import app +from .forms import AnnouncementForm +from .models import Announcements, AnnouncementRecipients +from applications.globals.models import ExtraInfo +from applications.academic_information.models import Student +from django.contrib import messages +from django.db.models import Q +import ast # Create your views here. +def create_announcement(request, template_name='notifications/create_announcement.html', module='Module', extra_context=None): + if request.method == 'POST': + form = AnnouncementForm(request.POST) + print(form) + if form.is_valid(): + announcement = form.save(commit=False) + announcement.created_by = request.user + announcement.module = module + announcement.save() + + # If specific users are selected, create entries in AnnouncementRecipients + if form.cleaned_data['target_group'] == 'specific_users': + specific_users = form.cleaned_data['specific_users'] + print(specific_users, type(specific_users)) + # Split the input into individual user IDs and clean them + specific_user_ids = ast.literal_eval(specific_users) + print(specific_user_ids) + + # Fetch corresponding ExtraInfo objects for these user IDs + extra_info_users = ExtraInfo.objects.filter(id__in=specific_user_ids) + print(extra_info_users) + + # Create entries in AnnouncementRecipients for each valid user + for extra_info in extra_info_users: + AnnouncementRecipients.objects.create( + announcement=announcement, + user=extra_info # This links the ExtraInfo object, not User + ) + + messages.success(request, 'Announcement created successfully.') + return redirect('/') + else: + # Handle invalid form and return the errors to the template + messages.error(request, 'There were errors in the form. Please correct them and try again.') + context = {'form': form} # Pass form with errors back to the template + if extra_context: + context.update(extra_context) + return render(request, template_name, context) + else: + form = AnnouncementForm() + # print(form) + context = {'form': form} + rendered_form = render_to_string('notifications/create_announcement.html', context, request=request) + context = {'rendered_form': rendered_form} + if extra_context: + context.update(extra_context) + + return render(request, template_name, context) + + +def announcement_list(request): + user_extrainfo = ExtraInfo.objects.filter(user=request.user).first() + if user_extrainfo.user_type == 'faculty': + announcements = Announcements.objects.filter( + Q(target_group='all') | + (Q(target_group='faculty') & (Q(department=user_extrainfo.department) | Q(department__isnull=True))) + ).order_by('-created_at') + elif user_extrainfo.user_type == 'student': + student = Student.objects.filter(id=user_extrainfo).first() + announcements = Announcements.objects.filter( + Q(target_group='all') | + (Q(target_group='students') & + (Q(department=user_extrainfo.department) | Q(department__isnull=True)) & + (Q(batch=student.batch) | Q(batch__isnull=True)) + ) + ).order_by('-created_at') + else: + announcements = Announcements.objects.filter(target_group='all') + + # Include specific user announcements + specific_announcements = Announcements.objects.filter(recipients__user=user_extrainfo).order_by('-created_at') + + context = { + 'announcements': (announcements | specific_announcements).distinct().order_by('-created_at') + } + return context + +@app.task +def send_notification_email(recipient_username, recipient_email, verb, module): + print("Trying to send notif.") + + # Make sure the recipient has an email address + if recipient_email: + subject = f"New Notification from {module}" + html_content = render_to_string('notifications/email_notification.html', { + 'recipient_username': recipient_username, + 'module': module, + 'verb': verb + }) + + email = EmailMessage( + subject, + html_content, + 'akashsah2003@gmail.com', # Replace with your email + [recipient_email] + ) + email.content_subtype = 'html' + email.send() + def leave_module_notif(sender, recipient, type, date=None): url = 'leave:leave' module = 'Leave Module' @@ -35,6 +144,7 @@ def leave_module_notif(sender, recipient, type, date=None): notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + # send_notification_email(sender=sender, recipient=recipient, url=url, module=module, verb=verb) def placement_cell_notif(sender, recipient, type): @@ -46,6 +156,7 @@ def placement_cell_notif(sender, recipient, type): notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + # send_notification_email(sender=sender, recipient=recipient, url=url, module=module, verb=verb) def academics_module_notif(sender, recipient, type): @@ -57,6 +168,7 @@ def academics_module_notif(sender, recipient, type): notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + # send_notification_email(sender=sender, recipient=recipient, url=url, module=module, verb=verb) def office_module_notif(sender, recipient): @@ -68,6 +180,7 @@ def office_module_notif(sender, recipient): notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) + # send_notification_email(sender=sender, recipient=recipient, url=url, module=module, verb=verb) def central_mess_notif(sender, recipient, type, message=None): @@ -79,6 +192,7 @@ def central_mess_notif(sender, recipient, type, message=None): if type == 'feedback_submitted': verb = 'Your feedback has been successfully submitted.' + send_notification_email(sender=sender, recipient=recipient, url=url, module=module, verb=verb) elif type == 'menu_change_accepted': verb = 'Menu request has been approved' elif type == 'leave_request': @@ -130,6 +244,7 @@ def healthcare_center_notif(sender, recipient, type, message): sender = sender recipient = recipient verb = '' + flag='' if type == 'appoint': verb = "Your Appointment has been booked" elif type == 'amb_request': @@ -154,6 +269,7 @@ def healthcare_center_notif(sender, recipient, type, message): 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) + # send_notification_email.delay(recipient.username, recipient.email, verb, module) def file_tracking_notif(sender, recipient, title): url = 'filetracking:inward' @@ -436,6 +552,26 @@ def office_module_DeanRSPC_notif(sender, recipient, type): notify.send(sender=sender, recipient=recipient, url=url, module=module, verb=verb) +def RSPC_notif(sender, recipient, type): + url = 'rspc' + module = 'RSPC' + sender = sender + recipient = recipient + verb = "" + + if type == "Approved": + verb = "Your request has been approved." + elif type == "Rejected": + verb = "Your request has been rejected." + elif type == "Processing": + verb = "You have a new request to process." + elif type == "Created": + verb = "Your project has been added to RSPC." + elif type == "Forwording": + verb = f"Your request has been forworded to {sender.username}. Kindly wait for decision" + + notify.send(sender=sender, recipient=recipient, + url=url, module=module, verb=verb) def research_procedures_notif(sender, recipient, type): url = 'research_procedures:patent_registration' @@ -496,4 +632,84 @@ def course_management_notif(sender, recipient, type, course, course_name, cours 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) \ No newline at end of file + 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) +def iwd_notif(sender,recipient,type): + module= 'iwdModuleV2' + url= 'iwdModuleV2:iwdModuleV2' + verb="" + if type == "file_forward": + verb= "file forwarded from " + sender.username+"." + if type == "Request_added": + verb= "Request added by "+ sender.username + "." + if type == "Request_approved": + verb = "Request approved by " + sender.username + "." + if type == "Request_rejected": + verb = "Request rejected by " + sender.username + "." + notify.send(sender=sender,recipient=recipient,url=url,module=module,verb=verb) \ No newline at end of file diff --git a/FusionIIIT/templates/academic_procedures/academic.html b/FusionIIIT/templates/academic_procedures/academic.html index 217e011b5..a08692126 100644 --- a/FusionIIIT/templates/academic_procedures/academic.html +++ b/FusionIIIT/templates/academic_procedures/academic.html @@ -186,7 +186,7 @@ {% include 'academic_procedures/auto_pre_registration.html' %}
- {% include 'academic_procedures/auto_finalregister.html' %} + {% include 'academic_procedures/finalregister.html' %}
diff --git a/FusionIIIT/templates/academic_procedures/academicfac.html b/FusionIIIT/templates/academic_procedures/academicfac.html index 53095463c..51d48685f 100644 --- a/FusionIIIT/templates/academic_procedures/academicfac.html +++ b/FusionIIIT/templates/academic_procedures/academicfac.html @@ -84,7 +84,7 @@

Programme

Branch

-

Year

+

Download Roll List

@@ -99,7 +99,7 @@ {{course.course_id.version }} {{course.batch_id.name }} {{course.batch_id.discipline.name }} - {{course.batch_id.year }} + @@ -107,7 +107,7 @@
{% csrf_token %} - +
@@ -146,7 +146,7 @@ - + {%if items.0.type != "Swayam" %} @@ -156,7 +156,7 @@ - + {%endif %} {% endfor %} diff --git a/FusionIIIT/templates/academic_procedures/finalregister.html b/FusionIIIT/templates/academic_procedures/finalregister.html index 387aa659f..e9a000f7e 100755 --- a/FusionIIIT/templates/academic_procedures/finalregister.html +++ b/FusionIIIT/templates/academic_procedures/finalregister.html @@ -143,6 +143,9 @@ + + + diff --git a/FusionIIIT/templates/account/base.html b/FusionIIIT/templates/account/base.html index 986600600..b2bc50b08 100755 --- a/FusionIIIT/templates/account/base.html +++ b/FusionIIIT/templates/account/base.html @@ -70,11 +70,12 @@
{% else %} +
+ min-width: 360px;background-color: unset;backdrop-filter: blur(3px);"> {% endif %} {% block content %} @@ -83,6 +84,8 @@ {% if request.user.is_authenticated %}
+
+
{% comment %}The central-rail segment ends here!{% endcomment %} diff --git a/FusionIIIT/templates/account/login.html b/FusionIIIT/templates/account/login.html index 9bbff7e94..5940456f2 100755 --- a/FusionIIIT/templates/account/login.html +++ b/FusionIIIT/templates/account/login.html @@ -1,16 +1,17 @@ {% extends "account/base.html" %} -{%block content%} +{% block content %} {% load i18n %} {% load account socialaccount %} {% load static semanticui %} +
User Image + src="{% static 'globals/img/user.png' %}" + style="margin-top: -27.5%; margin-left: 27.5%;" + alt="User Image">
- Login -
+ Login +
@@ -18,31 +19,56 @@ {% csrf_token %} {% render_form form %} {% if redirect_field_value %} - + {% endif %}
-
{% get_providers as socialaccount_providers %}
-
- {% if socialaccount_providers %} -
-
- {% include "socialaccount/snippets/provider_list.html" with process="login" %} -
+
+ {% if socialaccount_providers %} +
+
+ {% include "socialaccount/snippets/provider_list.html" with process="login" %}
- {% include "socialaccount/snippets/login_extra.html" %} - {% endif %} -
+
+ {% include "socialaccount/snippets/login_extra.html" %} + {% endif %} +
-{% endblock %} +{% if form.errors %} + +{% endif %} + + +{% endblock %} + \ No newline at end of file diff --git a/FusionIIIT/templates/ais/generateSheet.html b/FusionIIIT/templates/ais/generateSheet.html index 59613a28d..16996f7e2 100755 --- a/FusionIIIT/templates/ais/generateSheet.html +++ b/FusionIIIT/templates/ais/generateSheet.html @@ -34,7 +34,7 @@