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__'