from rest_framework import serializers from datetime import datetime class IncomeSerializer(serializers.Serializer): id = serializers.CharField(read_only=True) title = serializers.CharField(max_length=200) amount = serializers.DecimalField(max_digits=10, decimal_places=2) category = serializers.CharField(max_length=100, required=False, allow_blank=True) date = serializers.DateField() description = serializers.CharField(required=False, allow_blank=True) is_recurring = serializers.BooleanField(default=False) recurrence_interval = serializers.ChoiceField( choices=['daily', 'weekly', 'monthly', 'yearly'], required=False, allow_null=True, allow_blank=True ) def validate(self, data): if data.get('recurrence_interval') == '': data['recurrence_interval'] = None if data.get('is_recurring') and not data.get('recurrence_interval'): raise serializers.ValidationError("Recurrence interval is required for recurring income.") return data class ExpenseSerializer(serializers.Serializer): id = serializers.CharField(read_only=True) title = serializers.CharField(max_length=200) amount = serializers.DecimalField(max_digits=10, decimal_places=2) category = serializers.CharField(max_length=100, required=False, allow_blank=True) date = serializers.DateField() is_recurring = serializers.BooleanField(default=False) recurrence_interval = serializers.ChoiceField( choices=['daily', 'weekly', 'monthly', 'yearly'], required=False, allow_null=True, allow_blank=True ) description = serializers.CharField(required=False, allow_blank=True) def validate(self, data): if data.get('recurrence_interval') == '': data['recurrence_interval'] = None if data.get('is_recurring') and not data.get('recurrence_interval'): raise serializers.ValidationError("Recurrence interval is required for recurring expense.") return data class BudgetSerializer(serializers.Serializer): id = serializers.CharField(read_only=True) category = serializers.CharField(max_length=100) limit_amount = serializers.FloatField() month = serializers.CharField(max_length=7) # Format: YYYY-MM # Read-only fields for status spent_amount = serializers.FloatField(read_only=True) remaining_amount = serializers.FloatField(read_only=True) is_exceeded = serializers.BooleanField(read_only=True) alert_message = serializers.CharField(read_only=True) class SavingsGoalSerializer(serializers.Serializer): id = serializers.CharField(read_only=True) name = serializers.CharField(max_length=200) target_amount = serializers.FloatField() current_amount = serializers.FloatField(default=0.0) category = serializers.CharField(max_length=100, required=False, allow_blank=True) target_date = serializers.DateField(required=False, allow_null=True) color = serializers.CharField(max_length=20, default='#6366f1') # Read-only progress progress_percentage = serializers.FloatField(read_only=True) is_completed = serializers.BooleanField(read_only=True) def to_internal_value(self, data): # Handle empty string for target_date if 'target_date' in data and data['target_date'] == '': data = data.copy() data['target_date'] = None return super().to_internal_value(data)