from django.http.response import JsonResponse from rest_framework.views import APIView from rest_framework import status from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect from django.utils.decorators import method_decorator from Subscriptions.models import StudentCompetency, Student from Common.models import Domain from School.models import Competency from N3wtSchool.bdd import delete_object @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') class StudentCompetencyListCreateView(APIView): def get(self, request): student_id = request.GET.get('student_id') if not student_id: return JsonResponse({'error': 'student_id requis'}, status=400) try: student = Student.objects.get(id=student_id) except Student.DoesNotExist: return JsonResponse({'error': 'Élève introuvable'}, status=404) student_competencies = StudentCompetency.objects.filter(student=student).select_related( 'establishment_competency', 'establishment_competency__competency', 'establishment_competency__competency__category', 'establishment_competency__competency__category__domain', 'establishment_competency__custom_category', 'establishment_competency__custom_category__domain', ) result = [] total_competencies = 0 domaines = Domain.objects.all() for domaine in domaines: domaine_dict = { "domaine_id": domaine.id, "domaine_nom": domaine.name, "categories": [] } categories = domaine.categories.all() for categorie in categories: categorie_dict = { "categorie_id": categorie.id, "categorie_nom": categorie.name, "competences": [] } # On ne boucle que sur les compétences du student pour cette catégorie for sc in student_competencies: ec = sc.establishment_competency # Cas compétence de référence if ec.competency and ec.competency.category_id == categorie.id: comp = ec.competency categorie_dict["competences"].append({ "competence_id": ec.id, # <-- retourne l'id de l'EstablishmentCompetency "nom": comp.name, "score": sc.score, "comment": sc.comment or "", }) total_competencies += 1 # Cas compétence custom elif ec.competency is None and ec.custom_category_id == categorie.id: categorie_dict["competences"].append({ "competence_id": ec.id, # <-- retourne l'id de l'EstablishmentCompetency "nom": ec.custom_name, "score": sc.score, "comment": sc.comment or "", }) total_competencies += 1 if categorie_dict["competences"]: domaine_dict["categories"].append(categorie_dict) if domaine_dict["categories"]: result.append(domaine_dict) return JsonResponse({ "count": total_competencies, "data": result }, safe=False, status=200) def put(self, request): """ Met à jour en masse les notes des compétences d'un élève. Attend une liste d'objets {"competenceId": ..., "grade": ...} """ data = request.data if not isinstance(data, list): return JsonResponse({"error": "Une liste est attendue."}, status=400) updated = [] errors = [] for item in data: comp_id = item.get("competenceId") grade = item.get("grade") student_id = item.get('studentId') if comp_id is None or grade is None: errors.append({"competenceId": comp_id, "error": "champ manquant"}) continue try: # Ajoute le filtre student_id sc = StudentCompetency.objects.get( establishment_competency_id=comp_id, student_id=student_id ) sc.score = grade sc.save() updated.append(comp_id) except StudentCompetency.DoesNotExist: errors.append({"competenceId": comp_id, "error": "not found"}) return JsonResponse({"updated": updated, "errors": errors}, status=200) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') class StudentCompetencySimpleView(APIView): def get(self, request, id): return JsonResponse("ok", safe=False, status=status.HTTP_200_OK) # def put(self, request, id): # try: # absence = AbsenceManagement.objects.get(id=id) # serializer = AbsenceManagementSerializer(absence, data=request.data) # if serializer.is_valid(): # serializer.save() # return JsonResponse(serializer.data, safe=False, status=status.HTTP_200_OK) # return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST) # except AbsenceManagement.DoesNotExist: # return JsonResponse({"error": "Absence not found"}, safe=False, status=status.HTTP_404_NOT_FOUND) # def delete(self, request, id): # return delete_object(AbsenceManagement, id)