from rest_framework import serializers from drf_spectacular.utils import extend_schema_field from apps.events.models import Event, EventRegistration, RegistrationStatus, EventCategory, LocationType from apps.profiles.models import Institution, InstitutionMember from apps.account.models import User class EventOrganizerMinimalSerializer(serializers.ModelSerializer): class Meta: model = Institution fields = ['id', 'name', 'slug', 'type', 'city', 'country', 'avatar', 'verification_status'] class EventListSerializer(serializers.ModelSerializer): organizer = EventOrganizerMinimalSerializer(read_only=True) class Meta: model = Event fields = [ 'id', 'title', 'slug', 'category', 'event_date', 'start_time', 'end_time', 'speaker_name', 'speaker_title', 'speaker_avatar', 'location_type', 'venue_address', 'cover_image', 'capacity', 'registration_count', 'is_active', 'is_featured', 'language', 'tags', 'organizer', 'created_at', ] class EventDetailSerializer(serializers.ModelSerializer): organizer = EventOrganizerMinimalSerializer(read_only=True) is_registered = serializers.SerializerMethodField() my_registration = serializers.SerializerMethodField() class Meta: model = Event fields = [ 'id', 'title', 'slug', 'description', 'category', 'event_date', 'start_time', 'end_time', 'speaker_name', 'speaker_title', 'speaker_avatar', 'location_type', 'venue_address', 'online_meeting_url', 'cover_image', 'capacity', 'registration_count', 'is_active', 'is_featured', 'language', 'tags', 'organizer', 'is_registered', 'my_registration', 'created_at', 'updated_at', ] @extend_schema_field(serializers.BooleanField()) def get_is_registered(self, obj) -> bool: request = self.context.get('request') if not request or not request.user or not request.user.is_authenticated: return False return obj.registrations.filter(user=request.user, status=RegistrationStatus.REGISTERED).exists() @extend_schema_field(serializers.DictField(allow_null=True)) def get_my_registration(self, obj): request = self.context.get('request') if not request or not request.user or not request.user.is_authenticated: return None reg = obj.registrations.filter(user=request.user).first() if not reg: return None return { 'id': reg.id, 'status': reg.status, 'registered_at': reg.registered_at, 'notes': reg.notes, } class EventCreateUpdateSerializer(serializers.ModelSerializer): organizer_id = serializers.PrimaryKeyRelatedField( queryset=Institution.objects.all(), source='organizer', write_only=True ) class Meta: model = Event fields = [ 'id', 'title', 'description', 'organizer_id', 'category', 'event_date', 'start_time', 'end_time', 'speaker_name', 'speaker_title', 'speaker_avatar', 'location_type', 'venue_address', 'online_meeting_url', 'cover_image', 'capacity', 'is_active', 'is_featured', 'language', 'tags', ] def validate(self, attrs): request = self.context.get('request') user = request.user if request else None organizer = attrs.get('organizer') or (self.instance.organizer if self.instance else None) if user and not (user.is_superuser or getattr(user, 'user_type', None) in ['super_admin', 'regional_admin']): if organizer: is_member = InstitutionMember.objects.filter( institution=organizer, user=user, role__in=['admin', 'editor'] ).exists() if not is_member: raise serializers.ValidationError({"organizer_id": "You are not authorized to manage events for this institution."}) return attrs def create(self, validated_data): request = self.context.get('request') if request and request.user.is_authenticated: validated_data['created_by'] = request.user return super().create(validated_data) class EventParticipantUserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['id', 'email', 'fullname', 'avatar'] class EventRegistrationSerializer(serializers.ModelSerializer): user = EventParticipantUserSerializer(read_only=True) class Meta: model = EventRegistration fields = ['id', 'event', 'user', 'status', 'notes', 'registered_at'] read_only_fields = ['id', 'event', 'user', 'registered_at'] class EventRegisterInputSerializer(serializers.Serializer): notes = serializers.CharField(required=False, allow_blank=True, default="") class EventCalendarItemSerializer(serializers.ModelSerializer): organizer_name = serializers.CharField(source='organizer.name', read_only=True) class Meta: model = Event fields = [ 'id', 'title', 'slug', 'category', 'event_date', 'start_time', 'end_time', 'location_type', 'organizer_name', 'is_featured', ]