mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-28 23:43:22 +00:00
feat: Sauvegarde des compétences d'un élève [#16]
This commit is contained in:
@ -14,22 +14,6 @@ class Category(models.Model):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Competency(models.Model):
|
||||
name = models.TextField()
|
||||
end_of_cycle = models.BooleanField(default=False, null=True, blank=True)
|
||||
level = models.CharField(max_length=50, null=True, blank=True)
|
||||
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='competencies')
|
||||
|
||||
establishments = models.ManyToManyField(
|
||||
'Establishment.Establishment',
|
||||
through='School.EstablishmentCompetency',
|
||||
related_name='competencies',
|
||||
blank=True
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class PaymentPlanType(models.Model):
|
||||
code = models.CharField(max_length=50, unique=True)
|
||||
label = models.CharField(max_length=255)
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
from rest_framework import serializers
|
||||
from Common.models import (
|
||||
Domain,
|
||||
Category,
|
||||
Competency
|
||||
Category
|
||||
)
|
||||
|
||||
class DomainSerializer(serializers.ModelSerializer):
|
||||
@ -13,9 +12,4 @@ class DomainSerializer(serializers.ModelSerializer):
|
||||
class CategorySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Category
|
||||
fields = '__all__'
|
||||
|
||||
class CompetencySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Competency
|
||||
fields = '__all__'
|
||||
@ -2,7 +2,8 @@ import json
|
||||
import os
|
||||
from django.db.models.signals import post_migrate
|
||||
from django.dispatch import receiver
|
||||
from Common.models import Domain, Category, Competency, PaymentModeType, PaymentPlanType, Cycle, Level
|
||||
from Common.models import Domain, Category, PaymentModeType, PaymentPlanType, Cycle, Level
|
||||
from School.models import Competency
|
||||
|
||||
@receiver(post_migrate)
|
||||
def common_post_migrate(sender, **kwargs):
|
||||
|
||||
@ -3,7 +3,6 @@ from django.urls import path, re_path
|
||||
from .views import (
|
||||
DomainListCreateView, DomainDetailView,
|
||||
CategoryListCreateView, CategoryDetailView,
|
||||
CompetencyListCreateView, CompetencyDetailView,
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
@ -12,7 +11,4 @@ urlpatterns = [
|
||||
|
||||
re_path(r'^categories$', CategoryListCreateView.as_view(), name="category_list_create"),
|
||||
re_path(r'^categories/(?P<id>[0-9]+)$', CategoryDetailView.as_view(), name="category_detail"),
|
||||
|
||||
re_path(r'^competencies$', CompetencyListCreateView.as_view(), name="competency_list_create"),
|
||||
re_path(r'^competencies/(?P<id>[0-9]+)$', CompetencyDetailView.as_view(), name="competency_detail"),
|
||||
]
|
||||
@ -3,15 +3,14 @@ from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect
|
||||
from django.utils.decorators import method_decorator
|
||||
from rest_framework.parsers import JSONParser
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
from .models import (
|
||||
Domain,
|
||||
Category,
|
||||
Competency
|
||||
Category
|
||||
)
|
||||
from .serializers import (
|
||||
DomainSerializer,
|
||||
CategorySerializer,
|
||||
CompetencySerializer
|
||||
CategorySerializer
|
||||
)
|
||||
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@ -109,57 +108,3 @@ class CategoryDetailView(APIView):
|
||||
return JsonResponse({'message': 'Deleted'}, safe=False)
|
||||
except Category.DoesNotExist:
|
||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||
class CompetencyListCreateView(APIView):
|
||||
def get(self, request):
|
||||
cycle = request.GET.get('cycle')
|
||||
if cycle is None:
|
||||
return JsonResponse({'error': 'cycle est requis'}, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
competencies_list = getAllObjects(Competency)
|
||||
competencies_list = competencies_list.filter(
|
||||
category__domain__cycle=cycle
|
||||
).distinct()
|
||||
serializer = CompetencySerializer(competencies_list, many=True)
|
||||
return JsonResponse(serializer.data, safe=False)
|
||||
|
||||
def post(self, request):
|
||||
data = JSONParser().parse(request)
|
||||
serializer = CompetencySerializer(data=data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return JsonResponse(serializer.data, safe=False, status=status.HTTP_201_CREATED)
|
||||
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||
class CompetencyDetailView(APIView):
|
||||
def get(self, request, id):
|
||||
try:
|
||||
competency = Competency.objects.get(id=id)
|
||||
serializer = CompetencySerializer(competency)
|
||||
return JsonResponse(serializer.data, safe=False)
|
||||
except Competency.DoesNotExist:
|
||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def put(self, request, id):
|
||||
try:
|
||||
competency = Competency.objects.get(id=id)
|
||||
except Competency.DoesNotExist:
|
||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||
data = JSONParser().parse(request)
|
||||
serializer = CompetencySerializer(competency, data=data, partial=True)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return JsonResponse(serializer.data, safe=False)
|
||||
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def delete(self, request, id):
|
||||
try:
|
||||
competency = Competency.objects.get(id=id)
|
||||
competency.delete()
|
||||
return JsonResponse({'message': 'Deleted'}, safe=False)
|
||||
except Competency.DoesNotExist:
|
||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@ -7,8 +7,7 @@ from rest_framework import status
|
||||
from .models import Establishment
|
||||
from .serializers import EstablishmentSerializer
|
||||
from N3wtSchool.bdd import delete_object, getAllObjects
|
||||
from School.models import EstablishmentCompetency
|
||||
from Common.models import Competency
|
||||
from School.models import EstablishmentCompetency, Competency
|
||||
from django.db.models import Q
|
||||
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
|
||||
@ -116,6 +116,22 @@ class PaymentMode(models.Model):
|
||||
def __str__(self):
|
||||
return f"{self.mode.label} - {self.get_type_display()}"
|
||||
|
||||
class Competency(models.Model):
|
||||
name = models.TextField()
|
||||
end_of_cycle = models.BooleanField(default=False, null=True, blank=True)
|
||||
level = models.CharField(max_length=50, null=True, blank=True)
|
||||
category = models.ForeignKey('Common.Category', on_delete=models.CASCADE, related_name='competencies')
|
||||
|
||||
establishments = models.ManyToManyField(
|
||||
'Establishment.Establishment',
|
||||
through='School.EstablishmentCompetency',
|
||||
related_name='competencies',
|
||||
blank=True
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class EstablishmentCompetency(models.Model):
|
||||
"""
|
||||
Relation entre un établissement et une compétence.
|
||||
@ -123,7 +139,7 @@ class EstablishmentCompetency(models.Model):
|
||||
"""
|
||||
establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE)
|
||||
competency = models.ForeignKey(
|
||||
'Common.Competency', on_delete=models.CASCADE, null=True, blank=True,
|
||||
'School.Competency', on_delete=models.CASCADE, null=True, blank=True,
|
||||
help_text="Compétence de référence (optionnelle si custom)"
|
||||
)
|
||||
custom_name = models.TextField(null=True, blank=True, help_text="Nom de la compétence custom")
|
||||
|
||||
@ -9,7 +9,8 @@ from .models import (
|
||||
Fee,
|
||||
PaymentPlan,
|
||||
PaymentMode,
|
||||
EstablishmentCompetency
|
||||
EstablishmentCompetency,
|
||||
Competency
|
||||
)
|
||||
from Auth.models import Profile, ProfileRole
|
||||
from Subscriptions.models import Student
|
||||
@ -19,6 +20,12 @@ from N3wtSchool import settings
|
||||
from django.utils import timezone
|
||||
import pytz
|
||||
|
||||
|
||||
class CompetencySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Competency
|
||||
fields = '__all__'
|
||||
|
||||
class EstablishmentCompetencySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = EstablishmentCompetency
|
||||
|
||||
@ -9,6 +9,7 @@ from .views import (
|
||||
DiscountListCreateView, DiscountDetailView,
|
||||
PaymentPlanListCreateView, PaymentPlanDetailView,
|
||||
PaymentModeListCreateView, PaymentModeDetailView,
|
||||
CompetencyListCreateView, CompetencyDetailView,
|
||||
EstablishmentCompetencyListCreateView, EstablishmentCompetencyDetailView,
|
||||
)
|
||||
|
||||
@ -37,6 +38,9 @@ urlpatterns = [
|
||||
re_path(r'^paymentModes$', PaymentModeListCreateView.as_view(), name="payment_mode_list_create"),
|
||||
re_path(r'^paymentModes/(?P<id>[0-9]+)$', PaymentModeDetailView.as_view(), name="payment_mode_detail"),
|
||||
|
||||
re_path(r'^competencies$', CompetencyListCreateView.as_view(), name="competency_list_create"),
|
||||
re_path(r'^competencies/(?P<id>[0-9]+)$', CompetencyDetailView.as_view(), name="competency_detail"),
|
||||
|
||||
re_path(r'^establishmentCompetencies$', EstablishmentCompetencyListCreateView.as_view(), name="establishment_competency_list_create"),
|
||||
re_path(r'^establishmentCompetencies/(?P<id>[0-9]+)$', EstablishmentCompetencyDetailView.as_view(), name="establishment_competency_detail"),
|
||||
]
|
||||
@ -13,7 +13,8 @@ from .models import (
|
||||
Fee,
|
||||
PaymentPlan,
|
||||
PaymentMode,
|
||||
EstablishmentCompetency
|
||||
EstablishmentCompetency,
|
||||
Competency
|
||||
)
|
||||
from .serializers import (
|
||||
TeacherSerializer,
|
||||
@ -24,12 +25,14 @@ from .serializers import (
|
||||
FeeSerializer,
|
||||
PaymentPlanSerializer,
|
||||
PaymentModeSerializer,
|
||||
EstablishmentCompetencySerializer
|
||||
EstablishmentCompetencySerializer,
|
||||
CompetencySerializer
|
||||
)
|
||||
from Common.models import Domain, Category, Competency
|
||||
from Common.models import Domain, Category
|
||||
from N3wtSchool.bdd import delete_object, getAllObjects, getObject
|
||||
from django.db.models import Q
|
||||
from collections import defaultdict
|
||||
from Subscriptions.models import Student, StudentCompetency
|
||||
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||
@ -417,6 +420,60 @@ class PaymentModeDetailView(APIView):
|
||||
def delete(self, request, id):
|
||||
return delete_object(PaymentMode, id)
|
||||
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||
class CompetencyListCreateView(APIView):
|
||||
def get(self, request):
|
||||
cycle = request.GET.get('cycle')
|
||||
if cycle is None:
|
||||
return JsonResponse({'error': 'cycle est requis'}, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
competencies_list = getAllObjects(Competency)
|
||||
competencies_list = competencies_list.filter(
|
||||
category__domain__cycle=cycle
|
||||
).distinct()
|
||||
serializer = CompetencySerializer(competencies_list, many=True)
|
||||
return JsonResponse(serializer.data, safe=False)
|
||||
|
||||
def post(self, request):
|
||||
data = JSONParser().parse(request)
|
||||
serializer = CompetencySerializer(data=data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return JsonResponse(serializer.data, safe=False, status=status.HTTP_201_CREATED)
|
||||
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||
class CompetencyDetailView(APIView):
|
||||
def get(self, request, id):
|
||||
try:
|
||||
competency = Competency.objects.get(id=id)
|
||||
serializer = CompetencySerializer(competency)
|
||||
return JsonResponse(serializer.data, safe=False)
|
||||
except Competency.DoesNotExist:
|
||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def put(self, request, id):
|
||||
try:
|
||||
competency = Competency.objects.get(id=id)
|
||||
except Competency.DoesNotExist:
|
||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||
data = JSONParser().parse(request)
|
||||
serializer = CompetencySerializer(competency, data=data, partial=True)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return JsonResponse(serializer.data, safe=False)
|
||||
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def delete(self, request, id):
|
||||
try:
|
||||
competency = Competency.objects.get(id=id)
|
||||
competency.delete()
|
||||
return JsonResponse({'message': 'Deleted'}, safe=False)
|
||||
except Competency.DoesNotExist:
|
||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||
class EstablishmentCompetencyListCreateView(APIView):
|
||||
@ -541,6 +598,14 @@ class EstablishmentCompetencyListCreateView(APIView):
|
||||
custom_category=category,
|
||||
is_required=False
|
||||
)
|
||||
# Associer à tous les élèves de l'établissement
|
||||
students = Student.objects.filter(associated_class__establishment_id=establishment_id)
|
||||
for student in students:
|
||||
StudentCompetency.objects.get_or_create(
|
||||
student=student,
|
||||
establishment_competency=ec
|
||||
)
|
||||
|
||||
created.append({
|
||||
"competence_id": ec.id,
|
||||
"nom": ec.custom_name,
|
||||
@ -558,6 +623,7 @@ class EstablishmentCompetencyListCreateView(APIView):
|
||||
def delete(self, request):
|
||||
"""
|
||||
Supprime une ou plusieurs compétences custom (EstablishmentCompetency) à partir d'une liste d'IDs.
|
||||
Supprime aussi les StudentCompetency associés.
|
||||
Attendu dans le body :
|
||||
{
|
||||
"ids": [1, 2, 3, ...]
|
||||
@ -571,6 +637,8 @@ class EstablishmentCompetencyListCreateView(APIView):
|
||||
for ec_id in ids:
|
||||
try:
|
||||
ec = EstablishmentCompetency.objects.get(id=ec_id)
|
||||
# Supprimer les StudentCompetency associés
|
||||
StudentCompetency.objects.filter(establishment_competency=ec).delete()
|
||||
ec.delete()
|
||||
deleted.append(ec_id)
|
||||
except EstablishmentCompetency.DoesNotExist:
|
||||
|
||||
@ -324,15 +324,19 @@ class RegistrationSchoolFileTemplate(models.Model):
|
||||
|
||||
class StudentCompetency(models.Model):
|
||||
student = models.ForeignKey('Subscriptions.Student', on_delete=models.CASCADE, related_name='competency_scores')
|
||||
competency = models.ForeignKey('Common.Competency', on_delete=models.CASCADE, related_name='student_scores')
|
||||
establishment_competency = models.ForeignKey('School.EstablishmentCompetency', on_delete=models.CASCADE, related_name='student_scores')
|
||||
score = models.IntegerField(null=True, blank=True)
|
||||
comment = models.TextField(blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('student', 'competency')
|
||||
unique_together = ('student', 'establishment_competency')
|
||||
|
||||
indexes = [
|
||||
models.Index(fields=['student', 'establishment_competency']),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.student} - {self.competency.name} - Score: {self.score}"
|
||||
return f"{self.student} - {self.establishment_competency} - Score: {self.score}"
|
||||
|
||||
####### Parent files templates (par dossier d'inscription) #######
|
||||
class RegistrationParentFileTemplate(models.Model):
|
||||
|
||||
@ -17,7 +17,6 @@ import Subscriptions.util as util
|
||||
from Subscriptions.serializers import RegistrationFormSerializer, RegistrationSchoolFileTemplateSerializer, RegistrationParentFileTemplateSerializer
|
||||
from Subscriptions.pagination import CustomSubscriptionPagination
|
||||
from Subscriptions.models import (
|
||||
Student,
|
||||
Guardian,
|
||||
RegistrationForm,
|
||||
RegistrationSchoolFileTemplate,
|
||||
@ -26,7 +25,7 @@ from Subscriptions.models import (
|
||||
StudentCompetency
|
||||
)
|
||||
from Subscriptions.automate import updateStateMachine
|
||||
from Common.models import Competency
|
||||
from School.models import EstablishmentCompetency
|
||||
|
||||
from N3wtSchool import settings, bdd
|
||||
from django.db.models import Q
|
||||
@ -246,6 +245,7 @@ class RegisterFormWithIdView(APIView):
|
||||
"""
|
||||
|
||||
studentForm_data = request.data.get('data', '{}')
|
||||
|
||||
try:
|
||||
data = json.loads(studentForm_data)
|
||||
except json.JSONDecodeError:
|
||||
@ -306,13 +306,13 @@ class RegisterFormWithIdView(APIView):
|
||||
# L'école doit désormais valider le dossier d'inscription
|
||||
try:
|
||||
# Génération de la fiche d'inscription au format PDF
|
||||
base_dir = os.path.join(settings.MEDIA_ROOT, f"registration_files/dossier_rf_{registerForm.pk}")
|
||||
os.makedirs(base_dir, exist_ok=True)
|
||||
# base_dir = os.path.join(settings.MEDIA_ROOT, f"registration_files/dossier_rf_{registerForm.pk}")
|
||||
# os.makedirs(base_dir, exist_ok=True)
|
||||
|
||||
# Fichier PDF initial
|
||||
initial_pdf = f"{base_dir}/Inscription_{registerForm.student.last_name}_{registerForm.student.first_name}.pdf"
|
||||
registerForm.registration_file = util.rfToPDF(registerForm, initial_pdf)
|
||||
registerForm.save()
|
||||
# # Fichier PDF initial
|
||||
# initial_pdf = f"{base_dir}/Inscription_{registerForm.student.last_name}_{registerForm.student.first_name}.pdf"
|
||||
# registerForm.registration_file = util.rfToPDF(registerForm, initial_pdf)
|
||||
# registerForm.save()
|
||||
|
||||
# Mise à jour de l'automate
|
||||
# Vérification de la présence du fichier SEPA
|
||||
@ -376,7 +376,6 @@ class RegisterFormWithIdView(APIView):
|
||||
File(merged_pdf_content),
|
||||
save=True
|
||||
)
|
||||
|
||||
# Valorisation des StudentCompetency pour l'élève
|
||||
try:
|
||||
student = registerForm.student
|
||||
@ -384,15 +383,19 @@ class RegisterFormWithIdView(APIView):
|
||||
if student.level:
|
||||
cycle = student.level.cycle.number
|
||||
if cycle:
|
||||
competencies = Competency.objects.filter(
|
||||
category__domain__cycle=cycle
|
||||
).filter(
|
||||
Q(end_of_cycle=True) | Q(level=student.level.name)
|
||||
# Récupérer les EstablishmentCompetency de l'établissement et du cycle de l'élève
|
||||
establishment_competencies = EstablishmentCompetency.objects.filter(
|
||||
establishment=registerForm.establishment,
|
||||
custom_category__domain__cycle=cycle
|
||||
) | EstablishmentCompetency.objects.filter(
|
||||
establishment=registerForm.establishment,
|
||||
competency__category__domain__cycle=cycle
|
||||
)
|
||||
for comp in competencies:
|
||||
establishment_competencies = establishment_competencies.distinct()
|
||||
for ec in establishment_competencies:
|
||||
StudentCompetency.objects.get_or_create(
|
||||
student=student,
|
||||
competency=comp
|
||||
establishment_competency=ec
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de la valorisation des StudentCompetency: {e}")
|
||||
|
||||
@ -6,7 +6,8 @@ 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, Competency
|
||||
from Common.models import Domain
|
||||
from School.models import Competency
|
||||
from N3wtSchool.bdd import delete_object
|
||||
|
||||
@method_decorator(csrf_protect, name='dispatch')
|
||||
@ -21,10 +22,14 @@ class StudentCompetencyListCreateView(APIView):
|
||||
except Student.DoesNotExist:
|
||||
return JsonResponse({'error': 'Élève introuvable'}, status=404)
|
||||
|
||||
student_competencies = StudentCompetency.objects.filter(student=student).select_related('competency', 'competency__category', 'competency__category__domain')
|
||||
|
||||
# On ne garde que les IDs des compétences de l'élève
|
||||
student_competency_ids = set(sc.competency_id for sc in student_competencies)
|
||||
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
|
||||
@ -44,15 +49,26 @@ class StudentCompetencyListCreateView(APIView):
|
||||
}
|
||||
# On ne boucle que sur les compétences du student pour cette catégorie
|
||||
for sc in student_competencies:
|
||||
comp = sc.competency
|
||||
if comp.category_id == categorie.id:
|
||||
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": comp.id,
|
||||
"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"]:
|
||||
@ -77,14 +93,13 @@ class StudentCompetencyListCreateView(APIView):
|
||||
comp_id = item.get("competenceId")
|
||||
grade = item.get("grade")
|
||||
student_id = item.get('studentId')
|
||||
print(f'lecture des données : {comp_id} - {grade} - {student_id}')
|
||||
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(
|
||||
competency_id=comp_id,
|
||||
establishment_competency_id=comp_id,
|
||||
student_id=student_id
|
||||
)
|
||||
sc.score = grade
|
||||
|
||||
Reference in New Issue
Block a user