class CatalogsPerSubjectRemarks(generics.RetrieveUpdateAPIView): permission_classes = (IsTeacher, ) serializer_class = CatalogsPerSubjectRemarksSerializer lookup_field = 'id' http_method_names = [ GET.lower(), PUT.lower(), OPTIONS.lower(), HEAD.lower() ] def get_queryset(self): profile = self.request.user.user_profile return StudentCatalogPerSubject.objects.filter(teacher_id=profile.id, )
class GradeDetail(UpdateAPIView, DestroyAPIView): permission_classes = (IsTeacher, ) serializer_class = SubjectGradeUpdateSerializer http_method_names = [ DELETE.lower(), PUT.lower(), OPTIONS.lower(), HEAD.lower() ] @lru_cache(maxsize=None) def get_object(self): return get_object_or_404( SubjectGrade.objects.select_related( 'catalog_per_subject__study_class').prefetch_related( 'catalog_per_subject__absences', 'catalog_per_subject__examination_grades'), id=self.kwargs['id'], catalog_per_subject__teacher_id=self.request.user.user_profile) def check_grade_can_be_edited(self): grade = self.get_object() # TODO uncomment after it's tested # if not can_update_grades_or_absences(grade.catalog_per_subject.study_class): # return Response({'message': _(f'Cannot {action} grades at this time.')}, # status=status.HTTP_400_BAD_REQUEST) def update(self, request, *args, **kwargs): return self.check_grade_can_be_edited() or super().update( request, *args, **kwargs) def delete(self, request, *args, **kwargs): instance = self.get_object() catalog = instance.catalog_per_subject if catalog.is_coordination_subject: return Response( {'message': _("Can't delete coordination subject grade.")}, status=status.HTTP_400_BAD_REQUEST) error = self.check_grade_can_be_edited() if error: return error instance.delete() compute_averages([catalog], instance.semester) update_last_change_in_catalog(request.user.user_profile) return Response(StudentCatalogPerSubjectSerializer(catalog).data)
class SchoolUnitDetail(generics.RetrieveUpdateAPIView): permission_classes = (IsAdministrator, ) queryset = RegisteredSchoolUnit.objects.all() lookup_field = 'id' http_method_names = [ GET.lower(), PUT.lower(), OPTIONS.lower(), HEAD.lower() ] def get_serializer_class(self): if self.request.method == PUT: return RegisteredSchoolUnitUpdateSerializer return RegisteredSchoolUnitDetailSerializer
class CurrentAcademicYearCalendar(RetrieveUpdateAPIView): permission_classes = (AcademicCalendarPermissionClass, ) serializer_class = CurrentAcademicYearCalendarSerializer http_method_names = [ GET.lower(), PUT.lower(), OPTIONS.lower(), HEAD.lower() ] def get_object(self): calendar = get_current_academic_calendar() if not calendar: raise Http404() return calendar
class MyAccountDetail(generics.RetrieveUpdateAPIView): permission_classes = (IsAuthenticated, ) http_method_names = [ GET.lower(), PUT.lower(), HEAD.lower(), OPTIONS.lower() ] def get_serializer_class(self): user_role = self.request.user.user_profile.user_role if user_role == UserProfile.UserRoles.STUDENT: return MyAccountStudentSerializer if user_role == UserProfile.UserRoles.PARENT: return MyAccountParentSerializer return MyAccountSerializer def get_object(self): return self.request.user.user_profile
class AcademicProgramDetail(generics.RetrieveUpdateDestroyAPIView): permission_classes = (IsPrincipal, ) lookup_field = 'id' http_method_names = [ GET.lower(), PATCH.lower(), DELETE.lower(), OPTIONS.lower(), HEAD.lower() ] def get_serializer_class(self): if self.request.method == PATCH: return AcademicProgramUpdateSerializer return AcademicProgramDetailSerializer def get_serializer_context(self): context = super().get_serializer_context() context.update({ 'generic_academic_program_id': self.get_object().generic_academic_program_id, 'academic_year': self.get_object().academic_year, 'school_unit': self.request.user.user_profile.school_unit }) return context def get_queryset(self): return AcademicProgram.objects.filter( school_unit=self.request.user.user_profile.school_unit) @lru_cache(maxsize=None) def get_object(self): return super().get_object() def delete(self, request, *args, **kwargs): program = self.get_object() if program.classes_count > 0: return Response( { 'message': _("Cannot delete an academic program that still has study classes assigned." ) }, status=status.HTTP_400_BAD_REQUEST) return self.destroy(request, *args, **kwargs) def partial_update(self, request, *args, **kwargs): current_academic_year_calendar = get_current_academic_calendar() if not current_academic_year_calendar: raise Http404() if current_academic_year_calendar.academic_year != self.get_object( ).academic_year: return Response( { 'message': _('Invalid year, must be the current academic year.') }, status=status.HTTP_400_BAD_REQUEST) # TODO uncomment after it's tested # if timezone.now().date() > datetime.date(current_academic_year_calendar.created.year, 9, 15): # return Response( # {'message': _('Academic programs must be updated before 15th of September of the current year.')}, # status=status.HTTP_400_BAD_REQUEST # ) return super().partial_update(request, *args, **kwargs)
class ExaminationGradeDetail(generics.UpdateAPIView, generics.DestroyAPIView): permission_classes = (IsTeacher, ) serializer_class = ExaminationGradeUpdateSerializer http_method_names = [ DELETE.lower(), PUT.lower(), OPTIONS.lower(), HEAD.lower() ] @lru_cache(maxsize=None) def get_object(self): return get_object_or_404( ExaminationGrade.objects.select_related( 'catalog_per_subject__study_class').prefetch_related( 'catalog_per_subject__grades', 'catalog_per_subject__absences'), id=self.kwargs['id'], catalog_per_subject__teacher_id=self.request.user.user_profile) def check_grade_can_be_edited(self): examination_grade = self.get_object() action = _('delete') if self.request.method == DELETE else _('update') if examination_grade.created < timezone.now() - timezone.timedelta( hours=2): return Response( { 'message': _('Cannot {} a grade that was created more than 2 hours ago.' ).format(action) }, status=status.HTTP_400_BAD_REQUEST) if not can_update_examination_grades( examination_grade.catalog_per_subject.study_class, examination_grade.grade_type): return Response( { 'message': _('Cannot {} grades at this time.').format(action) }, status=status.HTTP_400_BAD_REQUEST) def update(self, request, *args, **kwargs): return self.check_grade_can_be_edited() or super().update( request, *args, **kwargs) def delete(self, request, *args, **kwargs): error = self.check_grade_can_be_edited() if error: return error instance = self.get_object() instance.delete() change_averages_after_examination_grade_operation( [instance.catalog_per_subject], instance.grade_type, instance.semester) update_last_change_in_catalog(request.user.user_profile) return Response( StudentCatalogPerSubjectSerializer( instance.catalog_per_subject).data)
class UserProfileDetail(UserProfileDetailBase, generics.RetrieveUpdateDestroyAPIView): http_method_names = [ GET.lower(), PUT.lower(), DELETE.lower(), HEAD.lower(), OPTIONS.lower() ] def get_queryset(self): if self.request.method in [PUT, DELETE]: return super().get_queryset() profile = self.request.user.user_profile school_filter = {} if profile.user_role == UserProfile.UserRoles.ADMINISTRATOR: user_roles = [ UserProfile.UserRoles.ADMINISTRATOR, UserProfile.UserRoles.PRINCIPAL ] else: school_filter['school_unit'] = profile.school_unit_id if profile.user_role == UserProfile.UserRoles.PRINCIPAL: user_roles = [ UserProfile.UserRoles.TEACHER, UserProfile.UserRoles.PARENT, UserProfile.UserRoles.STUDENT ] elif profile.user_role == UserProfile.UserRoles.TEACHER: user_roles = [ UserProfile.UserRoles.TEACHER, UserProfile.UserRoles.PARENT, UserProfile.UserRoles.STUDENT ] else: user_roles = [ UserProfile.UserRoles.PRINCIPAL, UserProfile.UserRoles.TEACHER ] return UserProfile.objects.select_related('user', 'student_in_class') \ .filter(user_role__in=user_roles, user__is_staff=False, **school_filter) @staticmethod def has_assigned_study_classes(teacher): current_academic_calendar = get_current_academic_calendar() if current_academic_calendar is None: return False return teacher.teacher_class_through.filter( academic_year=current_academic_calendar.academic_year).exists() def delete(self, request, *args, **kwargs): requested_profile = self.get_object() if requested_profile.last_online or \ (requested_profile.user_role == UserProfile.UserRoles.PRINCIPAL and getattr(requested_profile, 'registered_school_unit', None)) or \ (requested_profile.user_role == UserProfile.UserRoles.TEACHER and self.has_assigned_study_classes(requested_profile)) or \ (requested_profile.user_role == UserProfile.UserRoles.STUDENT and (SubjectGrade.objects.filter(student=requested_profile).exists() or SubjectAbsence.objects.filter(student=requested_profile).exists() or ExaminationGrade.objects.filter(student=requested_profile).exists())): return Response( { 'message': _("This user cannot be deleted because it's either active or has data." ) }, status=status.HTTP_400_BAD_REQUEST) user = requested_profile.user requested_profile.delete() user.delete() return Response(status=status.HTTP_204_NO_CONTENT)