from rest_framework import serializers from .models import AdminWeeklyAvailability, AppointmentRequest from django.utils import timezone from datetime import datetime, timedelta import json class AdminWeeklyAvailabilitySerializer(serializers.ModelSerializer): available_days_display = serializers.SerializerMethodField() class Meta: model = AdminWeeklyAvailability fields = ['id', 'available_days', 'available_days_display', 'created_at', 'updated_at'] def get_available_days_display(self, obj): days_map = dict(AdminWeeklyAvailability.DAYS_OF_WEEK) return [days_map[day] for day in obj.available_days] class AppointmentRequestSerializer(serializers.ModelSerializer): full_name = serializers.ReadOnlyField() formatted_created_at = serializers.ReadOnlyField() formatted_scheduled_datetime = serializers.ReadOnlyField() preferred_dates_display = serializers.ReadOnlyField() preferred_time_slots_display = serializers.ReadOnlyField() has_jitsi_meeting = serializers.ReadOnlyField() jitsi_meet_url = serializers.ReadOnlyField() jitsi_room_id = serializers.ReadOnlyField() can_join_meeting = serializers.ReadOnlyField() meeting_status = serializers.ReadOnlyField() class Meta: model = AppointmentRequest fields = [ 'id', 'first_name', 'last_name', 'email', 'phone', 'reason', 'preferred_dates', 'preferred_time_slots', 'status', 'scheduled_datetime', 'scheduled_duration', 'rejection_reason', 'jitsi_meet_url', 'jitsi_room_id', 'created_at', 'updated_at', 'full_name', 'formatted_created_at', 'formatted_scheduled_datetime', 'preferred_dates_display', 'preferred_time_slots_display', 'has_jitsi_meeting', 'can_join_meeting', 'meeting_status' ] read_only_fields = [ 'id', 'status', 'scheduled_datetime', 'scheduled_duration', 'rejection_reason', 'jitsi_meet_url', 'jitsi_room_id', 'created_at', 'updated_at' ] class AppointmentRequestCreateSerializer(serializers.ModelSerializer): class Meta: model = AppointmentRequest fields = [ 'first_name', 'last_name', 'email', 'phone', 'reason', 'preferred_dates', 'preferred_time_slots' ] def validate_preferred_dates(self, value): if not value or len(value) == 0: raise serializers.ValidationError("At least one preferred date is required.") today = timezone.now().date() for date_str in value: try: date_obj = datetime.strptime(date_str, '%Y-%m-%d').date() if date_obj < today: raise serializers.ValidationError("Preferred dates cannot be in the past.") except ValueError: raise serializers.ValidationError(f"Invalid date format: {date_str}. Use YYYY-MM-DD.") return value def validate_preferred_time_slots(self, value): if not value or len(value) == 0: raise serializers.ValidationError("At least one time slot is required.") valid_slots = ['morning', 'afternoon', 'evening'] for slot in value: if slot not in valid_slots: raise serializers.ValidationError(f"Invalid time slot: {slot}. Must be one of {valid_slots}.") return value class AppointmentScheduleSerializer(serializers.Serializer): scheduled_datetime = serializers.DateTimeField() scheduled_duration = serializers.IntegerField(default=60, min_value=30, max_value=240) def validate_scheduled_datetime(self, value): if value <= timezone.now(): raise serializers.ValidationError("Scheduled datetime must be in the future.") return value def validate_scheduled_duration(self, value): if value < 30: raise serializers.ValidationError("Duration must be at least 30 minutes.") if value > 240: raise serializers.ValidationError("Duration cannot exceed 4 hours.") return value class AppointmentRejectSerializer(serializers.Serializer): rejection_reason = serializers.CharField(required=False, allow_blank=True)