from rest_framework import generics, permissions from rest_framework.viewsets import ModelViewSet from rest_framework.authentication import TokenAuthentication from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from django.db.models import Q from apps.certificate.models import Certificate from apps.certificate.serializers import AdminCertificateSerializer, CertificateRequestSerializer, CertificateSerializer from apps.account.permissions import IsSuperAdmin from apps.course.models import Course from apps.course.models.course import extract_text_from_json from utils.pagination import StandardResultsSetPagination def find_matching_course_ids(search_term: str): normalized = (search_term or "").strip().lower() if not normalized: return [] matching_ids = list( Course.objects.filter( Q(title__icontains=search_term) | Q(slug__icontains=search_term) ).values_list("id", flat=True) ) if matching_ids: return matching_ids for course in Course.objects.all().only("id", "title", "slug"): title_text = extract_text_from_json(course.title).lower() slug_text = extract_text_from_json(course.slug).lower() if normalized in title_text or normalized in slug_text: matching_ids.append(course.id) return matching_ids class CertificateRequestView(generics.CreateAPIView): queryset = Certificate.objects.all() serializer_class = CertificateRequestSerializer permission_classes = [permissions.IsAuthenticated] authentication_classes = [TokenAuthentication] @swagger_auto_schema( operation_description="Request a certificate for completed course", tags=["Imam-Javad - Certificate"], responses={ 201: openapi.Response( description="Certificate request created successfully" ) } ) def post(self, request, *args, **kwargs): return super().post(request, *args, **kwargs) def perform_create(self, serializer): serializer.save(student=self.request.user) class UserCertificatesListView(generics.ListAPIView): serializer_class = CertificateSerializer permission_classes = [permissions.IsAuthenticated] authentication_classes = [TokenAuthentication] pagination_class = StandardResultsSetPagination @swagger_auto_schema( operation_description="Get list of user's certificates", tags=["Imam-Javad - Certificate"], responses={ 200: openapi.Response( description="List of user certificates", schema=CertificateSerializer(many=True) ) } ) def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) def get_queryset(self): return Certificate.objects.filter(student=self.request.user).order_by('-created_at') def is_professor(request): return getattr(request.user, 'user_type', None) == 'professor' class AdminCertificateViewSet(ModelViewSet): queryset = Certificate.objects.all() serializer_class = AdminCertificateSerializer permission_classes = [permissions.IsAuthenticated, IsSuperAdmin] authentication_classes = [TokenAuthentication] pagination_class = StandardResultsSetPagination def get_queryset(self): queryset = Certificate.objects.all().select_related('student', 'course') # Professors can only see certificates for students in their courses if is_professor(self.request): queryset = queryset.filter(course__professor_id=self.request.user.id) # Search query search_query = self.request.query_params.get('search', None) has_search = False if search_query: has_search = True matching_course_ids = find_matching_course_ids(search_query) from django.db.models import Case, When, Value, IntegerField queryset = queryset.filter( Q(student__fullname__icontains=search_query) | Q(student__email__icontains=search_query) | Q(course_id__in=matching_course_ids) ).annotate( search_relevance=Case( When(student__fullname__icontains=search_query, then=Value(3)), When(student__email__icontains=search_query, then=Value(2)), When(course_id__in=matching_course_ids, then=Value(1)), default=Value(0), output_field=IntegerField() ) ) # Filters status_param = self.request.query_params.get('status', None) if status_param: queryset = queryset.filter(status=status_param) course_id = self.request.query_params.get('course', None) if course_id: queryset = queryset.filter(course_id=course_id) student_id = self.request.query_params.get('student', None) if student_id: queryset = queryset.filter(student_id=student_id) issued_date = self.request.query_params.get('issued_date', None) if issued_date: queryset = queryset.filter(created_at__date=issued_date) issued_after = self.request.query_params.get('issued_after', None) if issued_after: queryset = queryset.filter(created_at__date__gte=issued_after) issued_before = self.request.query_params.get('issued_before', None) if issued_before: queryset = queryset.filter(created_at__date__lte=issued_before) if has_search: return queryset.order_by('-search_relevance', '-created_at') return queryset.order_by('-created_at')