Files
n3wt-school/Back-End/School/serializers.py
2025-05-04 12:08:05 +02:00

272 lines
12 KiB
Python

from rest_framework import serializers
from .models import Teacher, Speciality, SchoolClass, Planning, LEVEL_CHOICES, Discount, Fee, PaymentPlan, PaymentMode
from Auth.models import Profile, ProfileRole
from Subscriptions.models import Student
from Establishment.models import Establishment
from Auth.serializers import ProfileRoleSerializer
from N3wtSchool import settings, bdd
from django.utils import timezone
import pytz
class SpecialitySerializer(serializers.ModelSerializer):
updated_date_formatted = serializers.SerializerMethodField()
class Meta:
model = Speciality
fields = '__all__'
def get_updated_date_formatted(self, obj):
utc_time = timezone.localtime(obj.updated_date) # 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")
class TeacherDetailSerializer(serializers.ModelSerializer):
specialities = SpecialitySerializer(many=True, read_only=True)
class Meta:
model = Teacher
fields = ['id', 'last_name', 'first_name', 'email', 'specialities']
class TeacherSerializer(serializers.ModelSerializer):
specialities = serializers.PrimaryKeyRelatedField(queryset=Speciality.objects.all(), many=True, required=False)
specialities_details = serializers.SerializerMethodField()
updated_date_formatted = serializers.SerializerMethodField()
role_type = serializers.SerializerMethodField()
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 = Teacher
fields = '__all__'
def create_or_update_teacher(self, teacher_data):
profile_role_data = teacher_data.pop('profile_role_data', None)
profile_role = teacher_data.pop('profile_role', None)
# Gestion du ProfileRole
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
# Vérifiez si un ID est fourni pour une mise à jour
profile_role_id = profile_role_data.get('id')
if profile_role_id:
# Mettre à jour un ProfileRole existant
try:
profile_role_instance = ProfileRole.objects.get(id=profile_role_id)
profile_role_serializer = ProfileRoleSerializer(profile_role_instance, data=profile_role_data)
profile_role_serializer.is_valid(raise_exception=True)
profile_role = profile_role_serializer.save()
except ProfileRole.DoesNotExist:
raise serializers.ValidationError({"profile_role_data": f"ProfileRole with id {profile_role_id} does not exist."})
else:
# Créer un nouveau 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:
# Récupérer un ProfileRole existant
profile_role = ProfileRole.objects.get(id=profile_role.id)
if profile_role:
teacher_data['profile_role'] = profile_role
# Vérifier si un Teacher existe déjà pour ce profile_role
teacher_instance = Teacher.objects.filter(profile_role=profile_role).first()
if teacher_instance:
# Mettre à jour les champs existants
for key, value in teacher_data.items():
setattr(teacher_instance, key, value)
teacher_instance.save()
created = False
else:
# Créer un nouveau Teacher
teacher_instance = Teacher.objects.create(**teacher_data)
created = True
return teacher_instance
def create(self, validated_data):
specialities_data = validated_data.pop('specialities', [])
teacher_instance = self.create_or_update_teacher(validated_data)
# Associer les spécialités
if specialities_data:
teacher_instance.specialities.set(specialities_data)
return teacher_instance
def update(self, instance, validated_data):
specialities_data = validated_data.pop('specialities', [])
teacher_instance = self.create_or_update_teacher(validated_data)
# Mettre à jour les spécialités
if specialities_data:
teacher_instance.specialities.set(specialities_data)
return teacher_instance
def get_updated_date_formatted(self, obj):
utc_time = timezone.localtime(obj.updated_date) # 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_specialities_details(self, obj):
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):
if obj.profile_role and obj.profile_role.profile:
return obj.profile_role.profile.email
return None
def get_role_type(self, obj):
if obj.profile_role:
return obj.profile_role.role_type
return None
class PlanningSerializer(serializers.ModelSerializer):
class Meta:
model = Planning
fields = ['id', 'level', 'schedule']
def to_internal_value(self, data):
internal_value = super().to_internal_value(data)
internal_value['schedule'] = data.get('schedule', {})
return internal_value
class StudentDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = ['id', 'last_name', 'first_name', 'photo', 'level']
class SchoolClassSerializer(serializers.ModelSerializer):
updated_date_formatted = serializers.SerializerMethodField()
teachers = serializers.PrimaryKeyRelatedField(queryset=Teacher.objects.all(), many=True, required=False)
establishment = serializers.PrimaryKeyRelatedField(queryset=Establishment.objects.all(), required=False)
teachers_details = serializers.SerializerMethodField()
students = StudentDetailSerializer(many=True, read_only=True)
class Meta:
model = SchoolClass
fields = '__all__'
def create(self, validated_data):
teachers_data = validated_data.pop('teachers', [])
levels_data = validated_data.pop('levels', [])
plannings_data = validated_data.pop('plannings', [])
school_class = SchoolClass.objects.create(
atmosphere_name=validated_data.get('atmosphere_name', ''),
age_range=validated_data.get('age_range', []),
number_of_students=validated_data.get('number_of_students', 0),
teaching_language=validated_data.get('teaching_language', ''),
school_year=validated_data.get('school_year', ''),
levels=levels_data,
type=validated_data.get('type', 1),
time_range=validated_data.get('time_range', ['08:30', '17:30']),
opening_days=validated_data.get('opening_days', [1, 2, 4, 5]),
establishment=validated_data.get('establishment', None)
)
school_class.teachers.set(teachers_data)
for planning_data in plannings_data:
Planning.objects.create(
school_class=school_class,
level=planning_data['level'],
schedule=planning_data.get('schedule', {})
)
return school_class
def update(self, instance, validated_data):
teachers_data = validated_data.pop('teachers', [])
levels_data = validated_data.pop('levels', [])
plannings_data = validated_data.pop('plannings', [])
instance.atmosphere_name = validated_data.get('atmosphere_name', instance.atmosphere_name)
instance.age_range = validated_data.get('age_range', instance.age_range)
instance.number_of_students = validated_data.get('number_of_students', instance.number_of_students)
instance.teaching_language = validated_data.get('teaching_language', instance.teaching_language)
instance.school_year = validated_data.get('school_year', instance.school_year)
instance.levels = levels_data
instance.type = validated_data.get('type', instance.type)
instance.time_range = validated_data.get('time_range', instance.time_range)
instance.opening_days = validated_data.get('opening_days', instance.opening_days)
instance.establishment = validated_data.get('establishment', instance.establishment)
instance.save()
instance.teachers.set(teachers_data)
existing_plannings = {planning.level: planning for planning in instance.plannings.all()}
for planning_data in plannings_data:
level = planning_data['level']
if level in existing_plannings:
# Update existing planning
planning = existing_plannings[level]
planning.schedule = planning_data.get('schedule', planning.schedule)
planning.save()
else:
# Create new planning if level not existing
Planning.objects.create(
school_class=instance,
level=level,
schedule=planning_data.get('schedule', {})
)
return instance
def get_teachers_details(self, obj):
return [{'id': teacher.id, 'last_name': teacher.last_name, 'first_name': teacher.first_name} for teacher in obj.teachers.all()]
def get_updated_date_formatted(self, obj):
utc_time = timezone.localtime(obj.updated_date)
local_tz = pytz.timezone(settings.TZ_APPLI)
local_time = utc_time.astimezone(local_tz)
return local_time.strftime("%d-%m-%Y %H:%M")
class DiscountSerializer(serializers.ModelSerializer):
updated_at_formatted = serializers.SerializerMethodField()
establishment = serializers.PrimaryKeyRelatedField(queryset=Establishment.objects.all(), required=False)
class Meta:
model = Discount
fields = '__all__'
def get_updated_at_formatted(self, obj):
utc_time = timezone.localtime(obj.updated_at)
local_tz = pytz.timezone(settings.TZ_APPLI)
local_time = utc_time.astimezone(local_tz)
return local_time.strftime("%d-%m-%Y %H:%M")
class FeeSerializer(serializers.ModelSerializer):
updated_at_formatted = serializers.SerializerMethodField()
establishment = serializers.PrimaryKeyRelatedField(queryset=Establishment.objects.all(), required=False)
class Meta:
model = Fee
fields = '__all__'
def get_updated_at_formatted(self, obj):
utc_time = timezone.localtime(obj.updated_at)
local_tz = pytz.timezone(settings.TZ_APPLI)
local_time = utc_time.astimezone(local_tz)
return local_time.strftime("%d-%m-%Y %H:%M")
class PaymentPlanSerializer(serializers.ModelSerializer):
class Meta:
model = PaymentPlan
fields = '__all__'
class PaymentModeSerializer(serializers.ModelSerializer):
class Meta:
model = PaymentMode
fields = '__all__'