from rest_framework import serializers from .models import RegistrationFileGroup, RegistrationForm, Student, Guardian, Sibling, Language, RegistrationTemplateMaster, RegistrationTemplate from School.models import SchoolClass, Fee, Discount, FeeType from School.serializers import FeeSerializer, DiscountSerializer from Auth.models import ProfileRole, Profile from Auth.serializers import ProfileSerializer, ProfileRoleSerializer from GestionMessagerie.models import Messagerie from GestionNotification.models import Notification from N3wtSchool import settings from django.utils import timezone import pytz from datetime import datetime import Subscriptions.util as util class RegistrationTemplateMasterSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) class Meta: model = RegistrationTemplateMaster fields = '__all__' class RegistrationTemplateSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) class Meta: model = RegistrationTemplate fields = '__all__' class GuardianSimpleSerializer(serializers.ModelSerializer): associated_profile_email = serializers.SerializerMethodField() class Meta: model = Guardian fields = ['id', '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 RegistrationFormSimpleSerializer(serializers.ModelSerializer): guardians = GuardianSimpleSerializer(many=True, source='student.guardians') last_name = serializers.SerializerMethodField() first_name = serializers.SerializerMethodField() class Meta: model = RegistrationForm fields = ['student_id', 'last_name', 'first_name', 'guardians'] def get_last_name(self, obj): return obj.student.last_name def get_first_name(self, obj): return obj.student.first_name class RegistrationFileGroupSerializer(serializers.ModelSerializer): registration_forms = serializers.SerializerMethodField() class Meta: model = RegistrationFileGroup fields = '__all__' def get_registration_forms(self, obj): forms = RegistrationForm.objects.filter(fileGroup=obj) return RegistrationFormSimpleSerializer(forms, many=True).data class LanguageSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) class Meta: model = Language fields = '__all__' class SiblingSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) class Meta: model = Sibling fields = '__all__' class GuardianSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) 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: model = Guardian fields = '__all__' 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 StudentSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) guardians = GuardianSerializer(many=True, required=False) siblings = SiblingSerializer(many=True, required=False) spoken_languages = LanguageSerializer(many=True, required=False) associated_class_id = serializers.PrimaryKeyRelatedField(queryset=SchoolClass.objects.all(), source='associated_class', required=False, write_only=False, read_only=False) age = serializers.SerializerMethodField() formatted_birth_date = serializers.SerializerMethodField() birth_date = serializers.DateField(input_formats=['%d-%m-%Y', '%Y-%m-%d'], required=False, allow_null=True) associated_class_name = serializers.SerializerMethodField() class Meta: model = Student fields = '__all__' def create_or_update_guardians(self, guardians_data): guardians_ids = [] for guardian_data in guardians_data: profile_role_data = guardian_data.pop('profile_role_data', None) profile_role = guardian_data.pop('profile_role', None) if profile_role_data: # Vérifiez si 'profile' est un objet ou une clé primaire if isinstance(profile_role_data.get('profile'), Profile): profile_role_data['profile'] = profile_role_data['profile'].id establishment_id = profile_role_data.pop('establishment').id profile_role_data['establishment'] = establishment_id 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'), defaults=guardian_data ) guardians_ids.append(guardian_instance.id) return guardians_ids def create_or_update_siblings(self, siblings_data): siblings_ids = [] for sibling_data in siblings_data: sibling_instance, created = Sibling.objects.update_or_create( id=sibling_data.get('id'), defaults=sibling_data ) siblings_ids.append(sibling_instance.id) return siblings_ids def create_or_update_languages(self, languages_data): languages_ids = [] for language_data in languages_data: language_instance, created = Language.objects.update_or_create( id=language_data.get('id'), defaults=language_data ) languages_ids.append(language_instance.id) return languages_ids def create(self, validated_data): guardians_data = validated_data.pop('guardians', []) siblings_data = validated_data.pop('siblings', []) 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)) student.spoken_languages.set(self.create_or_update_languages(languages_data)) return student def update(self, instance, validated_data): guardians_data = validated_data.pop('guardians', []) siblings_data = validated_data.pop('siblings', []) languages_data = validated_data.pop('spoken_languages', []) if guardians_data: instance.guardians.set(self.create_or_update_guardians(guardians_data)) if siblings_data: instance.siblings.set(self.create_or_update_siblings(siblings_data)) if languages_data: instance.spoken_languages.set(self.create_or_update_languages(languages_data)) for field in self.fields: try: setattr(instance, field, validated_data[field]) except KeyError: pass instance.save() return instance def get_age(self, obj): return obj.age def get_formatted_birth_date(self, obj): return obj.formatted_birth_date def get_associated_class_name(self, obj): return obj.associated_class.atmosphereName if obj.associated_class else None class RegistrationFormSerializer(serializers.ModelSerializer): student = StudentSerializer(many=False, required=False) registration_file = serializers.FileField(required=False) sepa_file = serializers.FileField(required=False) status_label = serializers.SerializerMethodField() formatted_last_update = serializers.SerializerMethodField() registration_files = RegistrationTemplateSerializer(many=True, required=False) fees = serializers.PrimaryKeyRelatedField(queryset=Fee.objects.all(), many=True, required=False) discounts = serializers.PrimaryKeyRelatedField(queryset=Discount.objects.all(), many=True, required=False) totalRegistrationFees = serializers.SerializerMethodField() totalTuitionFees = serializers.SerializerMethodField() class Meta: model = RegistrationForm fields = '__all__' def create(self, validated_data): student_data = validated_data.pop('student') student = StudentSerializer.create(StudentSerializer(), student_data) fees_data = validated_data.pop('fees', []) discounts_data = validated_data.pop('discounts', []) registrationForm = RegistrationForm.objects.create(student=student, **validated_data) # Associer les IDs des objets Fee et Discount au RegistrationForm registrationForm.fees.set([fee.id for fee in fees_data]) registrationForm.discounts.set([discount.id for discount in discounts_data]) return registrationForm def update(self, instance, validated_data): student_data = validated_data.pop('student', None) fees_data = validated_data.pop('fees', None) discounts_data = validated_data.pop('discounts', None) if student_data: student = instance.student StudentSerializer.update(StudentSerializer(), student, student_data) for field in self.fields: try: setattr(instance, field, validated_data[field]) except KeyError: pass instance.last_update = util.convertToStr(util._now(), '%d-%m-%Y %H:%M') instance.save() # Associer les IDs des objets Fee et Discount au RegistrationForm if fees_data is not None: instance.fees.set([fee.id for fee in fees_data]) if discounts_data is not None: instance.discounts.set([discount.id for discount in discounts_data]) return instance def get_status_label(self, obj): return obj.get_status_display() def get_formatted_last_update(self, obj): utc_time = timezone.localtime(obj.last_update) # Convert to local time local_tz = pytz.timezone(settings.TZ_APPLI) local_time = utc_time.astimezone(local_tz) return local_time.strftime("%d-%m-%Y %H:%M") def get_totalRegistrationFees(self, obj): return sum(fee.base_amount for fee in obj.fees.filter(type=FeeType.REGISTRATION_FEE)) def get_totalTuitionFees(self, obj): return sum(fee.base_amount for fee in obj.fees.filter(type=FeeType.TUITION_FEE)) class StudentByParentSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) class Meta: model = Student fields = ['id', 'last_name', 'first_name'] def __init__(self, *args, **kwargs): super(StudentByParentSerializer, self).__init__(*args, **kwargs) for field in self.fields: self.fields[field].required = False class RegistrationFormByParentSerializer(serializers.ModelSerializer): student = StudentByParentSerializer(many=False, required=True) class Meta: model = RegistrationForm fields = ['student', 'status'] def __init__(self, *args, **kwargs): super(RegistrationFormByParentSerializer, self).__init__(*args, **kwargs) for field in self.fields: self.fields[field].required = False class GuardianByDICreationSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) associated_profile_email = serializers.SerializerMethodField() class Meta: model = Guardian 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) guardians = GuardianByDICreationSerializer(many=True, required=False) class Meta: model = Student fields = ['id', 'last_name', 'first_name', 'guardians'] def __init__(self, *args, **kwargs): super(StudentByRFCreationSerializer, self).__init__(*args, **kwargs) for field in self.fields: self.fields[field].required = False class NotificationSerializer(serializers.ModelSerializer): notification_type_label = serializers.ReadOnlyField() class Meta: model = Notification fields = '__all__'