from rest_framework import serializers from .models import ( Teacher, Speciality, SchoolClass, Planning, LEVEL_CHOICES, Discount, Fee, PaymentPlan, PaymentMode, Domain, Category, Competency, EstablishmentCompetency ) 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 from django.utils import timezone import pytz class DomainSerializer(serializers.ModelSerializer): class Meta: model = Domain fields = '__all__' class CategorySerializer(serializers.ModelSerializer): class Meta: model = Category fields = '__all__' class CompetencySerializer(serializers.ModelSerializer): class Meta: model = Competency fields = '__all__' class EstablishmentCompetencySerializer(serializers.ModelSerializer): class Meta: model = EstablishmentCompetency fields = '__all__' 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__'