From 7d1b9c5657439d2fff287f60b9aba79a5dfdf089 Mon Sep 17 00:00:00 2001 From: N3WT DE COMPET Date: Wed, 12 Mar 2025 14:04:35 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20Gestion=20des=20rattachements=20de=20Gu?= =?UTF-8?q?ardian=20=C3=A0=20des=20RF=20d=C3=A9j=C3=A0=20existants?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Back-End/Auth/serializers.py | 81 ++++----- Back-End/Auth/urls.py | 5 +- Back-End/Auth/views.py | 71 +++++++- .../management/commands/init_mock_datas.py | 160 +++++++++--------- .../management/mock_datas/profiles.json | 34 ---- Back-End/School/serializers.py | 31 ++-- Back-End/Subscriptions/serializers.py | 41 +++-- .../app/[locale]/admin/subscriptions/page.js | 6 +- .../src/app/actions/subscriptionAction.js | 2 +- .../components/Inscription/InscriptionForm.js | 6 +- 10 files changed, 241 insertions(+), 196 deletions(-) delete mode 100644 Back-End/School/management/mock_datas/profiles.json diff --git a/Back-End/Auth/serializers.py b/Back-End/Auth/serializers.py index 2647a14..7c11b85 100644 --- a/Back-End/Auth/serializers.py +++ b/Back-End/Auth/serializers.py @@ -5,12 +5,17 @@ from Establishment.models import Establishment class ProfileSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) password = serializers.CharField(write_only=True) + roles = serializers.SerializerMethodField() class Meta: model = Profile - fields = ['id', 'password', 'email', 'code', 'datePeremption', 'username'] + fields = ['id', 'password', 'email', 'code', 'datePeremption', 'username', 'roles'] extra_kwargs = {'password': {'write_only': True}} + def get_roles(self, obj): + roles = ProfileRole.objects.filter(profile=obj) + return [{'role_type': role.role_type, 'establishment': role.establishment.id, 'is_active': role.is_active} for role in roles] + def create(self, validated_data): user = Profile( username=validated_data['username'], @@ -37,70 +42,44 @@ class ProfileSerializer(serializers.ModelSerializer): def to_representation(self, instance): ret = super().to_representation(instance) ret['password'] = '********' + ret['roles'] = self.get_roles(instance) return ret class ProfileRoleSerializer(serializers.ModelSerializer): - profile = ProfileSerializer() - establishment = serializers.PrimaryKeyRelatedField(queryset=Establishment.objects.all()) + profile = serializers.PrimaryKeyRelatedField(queryset=Profile.objects.all(), required=False) + profile_data = ProfileSerializer(write_only=True, required=False) class Meta: model = ProfileRole - fields = ['role_type', 'establishment', 'is_active', 'profile'] + fields = ['role_type', 'establishment', 'is_active', 'profile', 'profile_data'] def create(self, validated_data): - profile_data = validated_data.pop('profile') - profile_serializer = ProfileSerializer(data=profile_data) - profile_serializer.is_valid(raise_exception=True) - profile = profile_serializer.save() + profile_data = validated_data.pop('profile_data', None) + profile = validated_data.pop('profile', None) + + if profile_data: + profile_serializer = ProfileSerializer(data=profile_data) + profile_serializer.is_valid(raise_exception=True) + profile = profile_serializer.save() + elif profile: + profile = Profile.objects.get(id=profile.id) + profile_role = ProfileRole.objects.create(profile=profile, **validated_data) return profile_role def update(self, instance, validated_data): - profile_data = validated_data.pop('profile') - profile_serializer = ProfileSerializer(instance.profile, data=profile_data) - profile_serializer.is_valid(raise_exception=True) - profile = profile_serializer.save() + profile_data = validated_data.pop('profile_data', None) + profile = validated_data.pop('profile', None) + + if profile_data: + profile_serializer = ProfileSerializer(instance.profile, data=profile_data) + profile_serializer.is_valid(raise_exception=True) + profile = profile_serializer.save() + elif profile: + profile = Profile.objects.get(id=profile.id) instance.role_type = validated_data.get('role_type', instance.role_type) instance.establishment_id = validated_data.get('establishment', instance.establishment.id) instance.is_active = validated_data.get('is_active', instance.is_active) instance.save() - return instance - -class ProfilUpdateSerializer(serializers.ModelSerializer): - roles = ProfileRoleSerializer(many=True, required=False) - - class Meta: - model = Profile - fields = ['id', 'password', 'email', 'code', 'datePeremption', 'username', 'roles'] - extra_kwargs = { - 'password': {'write_only': True, 'required': False} - } - - def update(self, instance, validated_data): - roles_data = validated_data.pop('roles', []) - password = validated_data.pop('password', None) - instance = super().update(instance, validated_data) - - if password: - instance.set_password(password) - - instance.full_clean() - instance.save() - - for role_data in roles_data: - ProfileRole.objects.update_or_create( - profile=instance, - establishment_id=role_data.get('establishment_id'), - defaults={ - 'role_type': role_data.get('role_type'), - 'is_active': role_data.get('is_active', True) - } - ) - - return instance - - def to_representation(self, instance): - ret = super().to_representation(instance) - ret['password'] = '********' - return ret + return instance \ No newline at end of file diff --git a/Back-End/Auth/urls.py b/Back-End/Auth/urls.py index d795b0b..a918c19 100644 --- a/Back-End/Auth/urls.py +++ b/Back-End/Auth/urls.py @@ -2,7 +2,7 @@ from django.urls import path, re_path from . import views import Auth.views -from Auth.views import ProfileSimpleView, ProfileView, SessionView, LoginView, RefreshJWTView, SubscribeView, NewPasswordView, ResetPasswordView +from Auth.views import ProfileRoleView, ProfileRoleSimpleView, ProfileSimpleView, ProfileView, SessionView, LoginView, RefreshJWTView, SubscribeView, NewPasswordView, ResetPasswordView urlpatterns = [ re_path(r'^csrf$', Auth.views.csrf, name='csrf'), @@ -16,4 +16,7 @@ urlpatterns = [ re_path(r'^profiles$', ProfileView.as_view(), name="profile"), re_path(r'^profiles/(?P[0-9]+)$', ProfileSimpleView.as_view(), name="profile"), + + re_path(r'^profileRoles$', ProfileRoleView.as_view(), name="profileRoles"), + re_path(r'^profileRoles/(?P[0-9]+)$', ProfileRoleSimpleView.as_view(), name="profileRoles"), ] \ No newline at end of file diff --git a/Back-End/Auth/views.py b/Back-End/Auth/views.py index ca3351a..0f4d669 100644 --- a/Back-End/Auth/views.py +++ b/Back-End/Auth/views.py @@ -22,7 +22,7 @@ from . import validator from .models import Profile, ProfileRole from rest_framework.decorators import action, api_view -from Auth.serializers import ProfileSerializer, ProfilUpdateSerializer +from Auth.serializers import ProfileSerializer, ProfileRoleSerializer from Subscriptions.models import RegistrationForm from Subscriptions.signals import clear_cache import Subscriptions.mailManager as mailer @@ -130,7 +130,7 @@ class ProfileSimpleView(APIView): @swagger_auto_schema( operation_description="Mettre à jour un profil", - request_body=ProfilUpdateSerializer, + request_body=ProfileSerializer, responses={ 200: 'Mise à jour réussie', 400: 'Données invalides' @@ -139,7 +139,7 @@ class ProfileSimpleView(APIView): def put(self, request, id): data = JSONParser().parse(request) profil = Profile.objects.get(id=id) - profil_serializer = ProfilUpdateSerializer(profil, data=data) + profil_serializer = ProfileSerializer(profil, data=data) if profil_serializer.is_valid(): profil_serializer.save() return JsonResponse(profil_serializer.data, safe=False) @@ -529,3 +529,68 @@ class ResetPasswordView(APIView): retourErreur = '' return JsonResponse({'message': retour, "errorMessage": retourErreur, "errorFields": errorFields}, safe=False) + +class ProfileRoleView(APIView): + @swagger_auto_schema( + operation_description="Obtenir la liste des profile_roles", + responses={200: ProfileRoleSerializer(many=True)} + ) + def get(self, request): + profiles_roles_List = bdd.getAllObjects(_objectName=ProfileRole) + profile_roles_serializer = ProfileRoleSerializer(profiles_roles_List, many=True) + return JsonResponse(profile_roles_serializer.data, safe=False) + + @swagger_auto_schema( + operation_description="Créer un nouveau profile_role", + request_body=ProfileRoleSerializer, + responses={ + 200: ProfileRoleSerializer, + 400: 'Données invalides' + } + ) + def post(self, request): + profile_role_data = JSONParser().parse(request) + profile_role_serializer = ProfileRoleSerializer(data=profile_role_data) + + if profile_role_serializer.is_valid(): + profile_role = profile_role_serializer.save() + return JsonResponse(profile_role_serializer.data, safe=False) + + return JsonResponse(profile_role_serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST) + +@method_decorator(csrf_protect, name='dispatch') +@method_decorator(ensure_csrf_cookie, name='dispatch') +class ProfileRoleSimpleView(APIView): + @swagger_auto_schema( + operation_description="Obtenir un profile_role par son ID", + responses={200: ProfileRoleSerializer} + ) + def get(self, request, id): + profile_role = bdd.getObject(ProfileRole, "id", id) + profile_role_serializer = ProfileRoleSerializer(profile_role) + return JsonResponse(profile_role_serializer.data, safe=False) + + @swagger_auto_schema( + operation_description="Mettre à jour un profile_role", + request_body=ProfileRoleSerializer, + responses={ + 200: 'Mise à jour réussie', + 400: 'Données invalides' + } + ) + def put(self, request, id): + data = JSONParser().parse(request) + profile_role = ProfileRole.objects.get(id=id) + profile_role_serializer = ProfileRoleSerializer(profile_role, data=data) + if profile_role_serializer.is_valid(): + profile_role_serializer.save() + return JsonResponse(profile_role_serializer.data, safe=False) + + return JsonResponse(profile_role_serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST) + + @swagger_auto_schema( + operation_description="Supprimer un profile_role", + responses={200: 'Suppression réussie'} + ) + def delete(self, request, id): + return bdd.delete_object(ProfileRole, id) \ No newline at end of file diff --git a/Back-End/School/management/commands/init_mock_datas.py b/Back-End/School/management/commands/init_mock_datas.py index 1e3cd05..77c5a07 100644 --- a/Back-End/School/management/commands/init_mock_datas.py +++ b/Back-End/School/management/commands/init_mock_datas.py @@ -52,7 +52,7 @@ class Command(BaseCommand): def handle(self, *args, **kwargs): self.init_establishments() - #self.init_profiles() + self.init_profiles() self.init_fees() self.init_discounts() self.init_payment_modes() @@ -81,57 +81,47 @@ class Command(BaseCommand): self.stdout.write(self.style.ERROR(f'Error in data for establishment: {serializer.errors}')) def init_profiles(self): - profiles_data = self.load_data('profiles.json') + fake = Faker() - for profile_data in profiles_data: - # Randomize the number of roles to create (between 1 et 3) - num_roles = random.randint(1, 3) - selected_roles = [] + for _ in range(50): + # Générer des données fictives pour le profil + profile_data = { + "username": fake.user_name(), + "email": fake.email(), + "password": "Provisoire01!", + "code": "", + "datePeremption": "" + } - for _ in range(num_roles): - establishment = random.choice(self.establishments) - role_type = random.choice([ProfileRole.RoleType.PROFIL_ECOLE, ProfileRole.RoleType.PROFIL_ADMIN, ProfileRole.RoleType.PROFIL_PARENT]) - - # Ensure no duplicate ADMIN role for the same establishment - if role_type == ProfileRole.RoleType.PROFIL_ADMIN: - if any(role['role_type'] == ProfileRole.RoleType.PROFIL_ADMIN and role['establishment'] == establishment.id for role in selected_roles): - continue - - selected_roles.append({ - "role_type": role_type, - "establishment": establishment.id, - "establishment_name": establishment.name - }) - - # Generate email based on the selected roles and establishment - role_types = '-'.join([f"{ProfileRole.RoleType(role['role_type']).name.replace('PROFIL_', '')}_{role['establishment_name'].replace(' ', '')}" for role in selected_roles]) - email = f"{profile_data['username']}-{role_types}@exemple.com" - - # Add email to profile data - profile_data['email'] = email - - serializer = ProfileSerializer(data=profile_data) - if serializer.is_valid(): - profile = serializer.save() + # Créer le profil + profile_serializer = ProfileSerializer(data=profile_data) + if profile_serializer.is_valid(): + profile = profile_serializer.save() profile.set_password(profile_data["password"]) profile.save() self.stdout.write(self.style.SUCCESS(f'Profile {profile.email} created successfully')) - # Create or update the profile role for each selected role using ProfileRoleSerializer - for role in selected_roles: - role_data = { - "profile": profile.id, # Passer l'ID du profil au lieu de l'instance de modèle Profile - "establishment": role["establishment"], - "role_type": role["role_type"], + # Créer entre 1 et 3 ProfileRole pour chaque profil + num_roles = random.randint(1, 3) + for _ in range(num_roles): + establishment = random.choice(self.establishments) + role_type = random.choice([ProfileRole.RoleType.PROFIL_ECOLE, ProfileRole.RoleType.PROFIL_ADMIN, ProfileRole.RoleType.PROFIL_PARENT]) + + profile_role_data = { + "profile": profile.id, + "establishment": establishment.id, + "role_type": role_type, "is_active": True } - role_serializer = ProfileRoleSerializer(data=role_data) - if role_serializer.is_valid(): - role_serializer.save() + + profile_role_serializer = ProfileRoleSerializer(data=profile_role_data) + if profile_role_serializer.is_valid(): + profile_role_serializer.save() + self.stdout.write(self.style.SUCCESS(f'ProfileRole for {profile.email} created successfully with role type {role_type}')) else: - self.stdout.write(self.style.ERROR(f'Error in data for profile role: {role_serializer.errors}')) + self.stdout.write(self.style.ERROR(f'Error in data for profile role: {profile_role_serializer.errors}')) else: - self.stdout.write(self.style.ERROR(f'Error in data for profile: {serializer.errors}')) + self.stdout.write(self.style.ERROR(f'Error in data for profile: {profile_serializer.errors}')) def init_fees(self): fees_data = self.load_data('fees.json') @@ -239,35 +229,42 @@ class Command(BaseCommand): def init_teachers(self): fake = Faker() - # Récupérer tous les établissements - establishments = self.establishments + # Récupérer tous les profils existants avec un rôle ECOLE ou ADMIN + profiles_with_roles = Profile.objects.filter(roles__role_type__in=[ProfileRole.RoleType.PROFIL_ECOLE, ProfileRole.RoleType.PROFIL_ADMIN]).distinct() - for establishment in establishments: - # Générer des données fictives pour le profil - profile_data = { - "username": fake.user_name(), - "email": fake.email(), - "password": "Provisoire01!", - "code": "", - "datePeremption": "" - } + if not profiles_with_roles.exists(): + self.stdout.write(self.style.ERROR('No profiles with role_type ECOLE or ADMIN found')) + return - # Générer des données fictives pour le profile_role - profile_role_data = { - "establishment": establishment.id, - "role_type": fake.random_int(min=ProfileRole.RoleType.PROFIL_ECOLE, max=ProfileRole.RoleType.PROFIL_ADMIN), - "is_active": True, - "profile": profile_data - } + used_profiles = set() + + for _ in range(15): + # Récupérer un profil aléatoire qui n'a pas encore été utilisé + available_profiles = profiles_with_roles.exclude(id__in=used_profiles) + if not available_profiles.exists(): + self.stdout.write(self.style.ERROR('Not enough profiles with role_type ECOLE or ADMIN available')) + break + + profile = random.choice(available_profiles) + used_profiles.add(profile.id) + + # Récupérer les ProfileRole associés au profil avec les rôles ECOLE ou ADMIN + profile_roles = ProfileRole.objects.filter(profile=profile, role_type__in=[ProfileRole.RoleType.PROFIL_ECOLE, ProfileRole.RoleType.PROFIL_ADMIN]) + + if not profile_roles.exists(): + self.stdout.write(self.style.ERROR(f'No ProfileRole with role_type ECOLE or ADMIN found for profile {profile.email}')) + continue + + profile_role = random.choice(profile_roles) # Générer des données fictives pour l'enseignant teacher_data = { "last_name": fake.last_name(), - "first_name": f"{fake.first_name()} - {establishment.name}", - "profile_role": profile_role_data + "first_name": f"{fake.first_name()} - {profile_role.establishment.name}", + "profile_role": profile_role.id } - establishment_specialities = list(Speciality.objects.filter(establishment=establishment)) + establishment_specialities = list(Speciality.objects.filter(establishment=profile_role.establishment)) num_specialities = min(random.randint(1, 3), len(establishment_specialities)) selected_specialities = random.sample(establishment_specialities, num_specialities) @@ -278,7 +275,7 @@ class Command(BaseCommand): # Associer les spécialités teacher.specialities.set(selected_specialities) teacher.save() - self.stdout.write(self.style.SUCCESS(f'Teacher {teacher.last_name} created successfully for establishment {establishment.name}')) + self.stdout.write(self.style.SUCCESS(f'Teacher {teacher.last_name} created successfully for establishment {profile_role.establishment.name}')) else: self.stdout.write(self.style.ERROR(f'Error in data for teacher: {teacher_serializer.errors}')) @@ -335,26 +332,33 @@ class Command(BaseCommand): file_group_count = RegistrationFileGroup.objects.count() + # Récupérer tous les profils existants avec un ProfileRole Parent + profiles_with_parent_role = Profile.objects.filter(roles__role_type=ProfileRole.RoleType.PROFIL_PARENT).distinct() + + if not profiles_with_parent_role.exists(): + self.stdout.write(self.style.ERROR('No profiles with ProfileRole Parent found')) + return + + used_profiles = set() + for _ in range(50): establishment = random.choice(self.establishments) - # Générer des données fictives pour le profil - profile_data = { - "username": fake.user_name(), - "email": fake.email(), - "password": "Provisoire01!", - "code": "", - "datePeremption": "" - } + # Récupérer un profil aléatoire qui n'a pas encore été utilisé + available_profiles = profiles_with_parent_role.exclude(id__in=used_profiles) + if not available_profiles.exists(): + self.stdout.write(self.style.ERROR('Not enough profiles with ProfileRole Parent available')) + break + + profile = random.choice(available_profiles) + used_profiles.add(profile.id) + + # Récupérer le ProfileRole Parent associé au profil + profile_role = ProfileRole.objects.filter(profile=profile, role_type=ProfileRole.RoleType.PROFIL_PARENT).first() # Générer des données fictives pour le guardian guardian_data = { - "profile_role": { - "establishment": establishment.id, - "role_type": ProfileRole.RoleType.PROFIL_PARENT, - "is_active": True, - "profile": profile_data - }, + "profile_role": profile_role.id, "last_name": fake.last_name(), "first_name": fake.first_name(), "birth_date": fake.date_of_birth().strftime('%Y-%m-%d'), diff --git a/Back-End/School/management/mock_datas/profiles.json b/Back-End/School/management/mock_datas/profiles.json deleted file mode 100644 index f59adf8..0000000 --- a/Back-End/School/management/mock_datas/profiles.json +++ /dev/null @@ -1,34 +0,0 @@ -[ - { - "username": "albus.dumbledore", - "password": "Provisoire01!" - }, - { - "username": "severus.rogue", - "password": "Provisoire01!" - }, - { - "username": "minerva.mcgonagall", - "password": "Provisoire01!" - }, - { - "username": "pomona.chourave", - "password": "Provisoire01!" - }, - { - "username": "rubeus.hagrid", - "password": "Provisoire01!" - }, - { - "username": "filius.flitwick", - "password": "Provisoire01!" - }, - { - "username": "pomona.sprout", - "password": "Provisoire01!" - }, - { - "username": "aurora.sinistra", - "password": "Provisoire01!" - } -] \ No newline at end of file diff --git a/Back-End/School/serializers.py b/Back-End/School/serializers.py index f8791b6..fb26e21 100644 --- a/Back-End/School/serializers.py +++ b/Back-End/School/serializers.py @@ -35,7 +35,8 @@ class TeacherSerializer(serializers.ModelSerializer): updated_date_formatted = serializers.SerializerMethodField() role_type = serializers.SerializerMethodField() associated_profile_email = serializers.SerializerMethodField() - profile_role = ProfileRoleSerializer() + profile_role = serializers.PrimaryKeyRelatedField(queryset=ProfileRole.objects.all(), required=False) + profile_role_data = ProfileRoleSerializer(write_only=True, required=False) class Meta: model = Teacher @@ -43,14 +44,19 @@ class TeacherSerializer(serializers.ModelSerializer): def create(self, validated_data): specialities_data = validated_data.pop('specialities', None) - profile_role_data = validated_data.pop('profile_role') - establishment_id = profile_role_data.pop('establishment').id - profile_role_data['establishment'] = establishment_id + profile_role_data = validated_data.pop('profile_role_data', None) + profile_role = validated_data.pop('profile_role', None) - # Créer l'instance de ProfileRole - profile_role_serializer = ProfileRoleSerializer(data=profile_role_data) - profile_role_serializer.is_valid(raise_exception=True) - profile_role = profile_role_serializer.save() + if profile_role_data: + establishment_id = profile_role_data.pop('establishment').id + profile_role_data['establishment'] = establishment_id + + # Créer l'instance de ProfileRole + profile_role_serializer = ProfileRoleSerializer(data=profile_role_data) + profile_role_serializer.is_valid(raise_exception=True) + profile_role = profile_role_serializer.save() + elif profile_role: + profile_role = ProfileRole.objects.get(id=profile_role.id) # Créer l'enseignant avec l'instance de ProfileRole teacher = Teacher.objects.create(profile_role=profile_role, **validated_data) @@ -61,7 +67,8 @@ class TeacherSerializer(serializers.ModelSerializer): def update(self, instance, validated_data): specialities_data = validated_data.pop('specialities', []) - profile_role_data = validated_data.pop('profile_role', None) + profile_role_data = validated_data.pop('profile_role_data', None) + profile_role = validated_data.pop('profile_role', None) if profile_role_data: establishment_id = profile_role_data.pop('establishment').id @@ -69,6 +76,8 @@ class TeacherSerializer(serializers.ModelSerializer): profile_role_serializer = ProfileRoleSerializer(instance.profile_role, data=profile_role_data) profile_role_serializer.is_valid(raise_exception=True) profile_role_serializer.save() + elif profile_role: + instance.profile_role = ProfileRole.objects.get(id=profile_role.id) instance.last_name = validated_data.get('last_name', instance.last_name) instance.first_name = validated_data.get('first_name', instance.first_name) @@ -92,7 +101,9 @@ class TeacherSerializer(serializers.ModelSerializer): return [{'id': speciality.id, 'name': speciality.name, 'color_code': speciality.color_code} for speciality in obj.specialities.all()] def get_associated_profile_email(self, obj): - return obj.profile_role.profile.email + if obj.profile_role and obj.profile_role.profile: + return obj.profile_role.profile.email + return None class PlanningSerializer(serializers.ModelSerializer): class Meta: diff --git a/Back-End/Subscriptions/serializers.py b/Back-End/Subscriptions/serializers.py index a72c214..86d2870 100644 --- a/Back-End/Subscriptions/serializers.py +++ b/Back-End/Subscriptions/serializers.py @@ -31,7 +31,9 @@ class GuardianSimpleSerializer(serializers.ModelSerializer): fields = ['id', 'associated_profile_email'] def get_associated_profile_email(self, obj): - return obj.profile_role.profile.email + if obj.profile_role and obj.profile_role.profile: + return obj.profile_role.profile.email + return None class RegistrationFormSimpleSerializer(serializers.ModelSerializer): guardians = GuardianSimpleSerializer(many=True, source='student.guardians') @@ -73,7 +75,8 @@ class SiblingSerializer(serializers.ModelSerializer): class GuardianSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) - profile_role = ProfileRoleSerializer() + profile_role = serializers.PrimaryKeyRelatedField(queryset=ProfileRole.objects.all(), required=False) + profile_role_data = ProfileRoleSerializer(write_only=True, required=False) associated_profile_email = serializers.SerializerMethodField() class Meta: @@ -81,7 +84,9 @@ class GuardianSerializer(serializers.ModelSerializer): fields = '__all__' def get_associated_profile_email(self, obj): - return obj.profile_role.profile.email + if obj.profile_role and obj.profile_role.profile: + return obj.profile_role.profile.email + return None class StudentSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) @@ -101,15 +106,21 @@ class StudentSerializer(serializers.ModelSerializer): def create_or_update_guardians(self, guardians_data): guardians_ids = [] for guardian_data in guardians_data: - profile_role_data = guardian_data.pop('profile_role') - establishment_id = profile_role_data.pop('establishment').id - profile_role_data['establishment'] = establishment_id + profile_role_data = guardian_data.pop('profile_role_data', None) + profile_role = guardian_data.pop('profile_role', None) - profile_role_serializer = ProfileRoleSerializer(data=profile_role_data) - profile_role_serializer.is_valid(raise_exception=True) - profile_role = profile_role_serializer.save() + if profile_role_data: + establishment_id = profile_role_data.pop('establishment').id + profile_role_data['establishment'] = establishment_id - guardian_data['profile_role'] = profile_role + profile_role_serializer = ProfileRoleSerializer(data=profile_role_data) + profile_role_serializer.is_valid(raise_exception=True) + profile_role = profile_role_serializer.save() + elif profile_role: + profile_role = ProfileRole.objects.get(id=profile_role.id) + + if profile_role: + guardian_data['profile_role'] = profile_role guardian_instance, created = Guardian.objects.update_or_create( id=guardian_data.get('id'), @@ -141,7 +152,7 @@ class StudentSerializer(serializers.ModelSerializer): def create(self, validated_data): guardians_data = validated_data.pop('guardians', []) siblings_data = validated_data.pop('siblings', []) - languages_data = validated_data.pop('lanspoken_languagesguages', []) + languages_data = validated_data.pop('spoken_languages', []) student = Student.objects.create(**validated_data) student.guardians.set(self.create_or_update_guardians(guardians_data)) student.siblings.set(self.create_or_update_siblings(siblings_data)) @@ -268,10 +279,16 @@ class RegistrationFormByParentSerializer(serializers.ModelSerializer): class GuardianByDICreationSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) + associated_profile_email = serializers.SerializerMethodField() class Meta: model = Guardian - fields = ['id', 'last_name', 'first_name', 'email', 'profile'] + fields = ['id', 'last_name', 'first_name', 'associated_profile_email'] + + def get_associated_profile_email(self, obj): + if obj.profile_role and obj.profile_role.profile: + return obj.profile_role.profile.email + return None class StudentByRFCreationSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) diff --git a/Front-End/src/app/[locale]/admin/subscriptions/page.js b/Front-End/src/app/[locale]/admin/subscriptions/page.js index e89e44e..15e9c91 100644 --- a/Front-End/src/app/[locale]/admin/subscriptions/page.js +++ b/Front-End/src/app/[locale]/admin/subscriptions/page.js @@ -170,7 +170,7 @@ useEffect(() => { const fetchInitialData = () => { Promise.all([ fetchClasses(selectedEstablishmentId), - fetchStudents(selectedEstablishmentId) // Utiliser l'ID de l'établissement ici + fetchStudents(selectedEstablishmentId) ]) .then(([classesData, studentsData]) => { setClasses(classesData); @@ -374,11 +374,11 @@ useEffect(()=>{ last_name: updatedData.studentLastName, first_name: updatedData.studentFirstName, guardians: updatedData.selectedGuardians.length !== 0 ? updatedData.selectedGuardians.map(guardianId => ({ id: guardianId })) : [{ - profile_role: { + profile_role_data: { establishment: selectedEstablishmentId, role_type: 2, is_active: false, - profile: { + profile_data: { email: updatedData.guardianEmail, password: 'Provisoire01!', username: updatedData.guardianEmail, diff --git a/Front-End/src/app/actions/subscriptionAction.js b/Front-End/src/app/actions/subscriptionAction.js index 47c7128..da4c4d5 100644 --- a/Front-End/src/app/actions/subscriptionAction.js +++ b/Front-End/src/app/actions/subscriptionAction.js @@ -99,7 +99,7 @@ export const archiveRegisterForm = (id) => { }).then(requestResponseHandler) } -export const fetchStudents = (id=null, establishment) => { +export const fetchStudents = (establishment, id=null) => { const url = (id)?`${BE_SUBSCRIPTION_STUDENTS_URL}/${id}`:`${BE_SUBSCRIPTION_STUDENTS_URL}?establishment_id=${establishment}`; const request = new Request( url, diff --git a/Front-End/src/components/Inscription/InscriptionForm.js b/Front-End/src/components/Inscription/InscriptionForm.js index 92899f1..e382956 100644 --- a/Front-End/src/components/Inscription/InscriptionForm.js +++ b/Front-End/src/components/Inscription/InscriptionForm.js @@ -346,10 +346,10 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r type="checkbox" checked={formData.selectedGuardians.includes(guardian.id)} className="form-checkbox h-5 w-5 text-emerald-600" - onChange={() => handleResponsableSelection(guardian.id, guardian.email)} + onChange={() => handleResponsableSelection(guardian.id, guardian.associated_profile_email)} /> - {guardian.last_name && guardian.first_name ? `${guardian.last_name} ${guardian.first_name}` : `${guardian.email}`} + {guardian.last_name && guardian.first_name ? `${guardian.last_name} ${guardian.first_name}` : `${guardian.associated_profile_email}`} @@ -563,7 +563,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r {guardian.last_name} {guardian.first_name} - {guardian.email} + {guardian.associated_profile_email} ))}