Files
n3wt-school/Back-End/Subscriptions/serializers.py
2025-05-02 17:44:35 +02:00

367 lines
15 KiB
Python

from rest_framework import serializers
from .models import RegistrationFileGroup, RegistrationForm, Student, Guardian, Sibling, Language, RegistrationSchoolFileMaster, RegistrationSchoolFileTemplate, RegistrationParentFileMaster, RegistrationParentFileTemplate
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 RegistrationSchoolFileMasterSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
class Meta:
model = RegistrationSchoolFileMaster
fields = '__all__'
class RegistrationParentFileMasterSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
class Meta:
model = RegistrationParentFileMaster
fields = '__all__'
class RegistrationSchoolFileTemplateSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
file_url = serializers.SerializerMethodField()
class Meta:
model = RegistrationSchoolFileTemplate
fields = '__all__'
def get_file_url(self, obj):
# Retourne l'URL complète du fichier si disponible
return obj.file.url if obj.file else None
class RegistrationParentFileTemplateSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
file_url = serializers.SerializerMethodField()
master_name = serializers.CharField(source='master.name', read_only=True)
master_description = serializers.CharField(source='master.description', read_only=True)
class Meta:
model = RegistrationParentFileTemplate
fields = '__all__'
def get_file_url(self, obj):
# Retourne l'URL complète du fichier si disponible
return obj.file.url if obj.file else None
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, student_instance):
"""
Crée ou met à jour les frères et sœurs associés à un étudiant.
Supprime les frères et sœurs qui ne sont plus présents dans siblings_data.
"""
# Si siblings_data est vide, supprimer tous les frères et sœurs associés
if not siblings_data:
student_instance.siblings.clear() # Supprime toutes les relations
return []
# Récupérer les IDs des frères et sœurs existants
existing_sibling_ids = set(student_instance.siblings.values_list('id', flat=True))
# Créer ou mettre à jour les frères et sœurs
updated_sibling_ids = []
for sibling_data in siblings_data:
sibling_instance, created = Sibling.objects.update_or_create(
id=sibling_data.get('id'),
defaults=sibling_data
)
updated_sibling_ids.append(sibling_instance.id)
# Supprimer les frères et sœurs qui ne sont plus dans siblings_data
siblings_to_delete = existing_sibling_ids - set(updated_sibling_ids)
Sibling.objects.filter(id__in=siblings_to_delete).delete()
return updated_sibling_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))
sibling_ids = self.create_or_update_siblings(siblings_data, instance)
instance.siblings.set(sibling_ids)
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 = RegistrationSchoolFileTemplateSerializer(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', 'sepa_file']
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__'