from rest_framework import serializers class BillOptimizationRequestSerializer(serializers.Serializer): """ Validates the incoming POST body for /api/solar/bill-optimization-slab/. """ current_bill = serializers.FloatField( min_value=0, help_text="Current monthly electricity bill in ₹ (required).", ) target_bill = serializers.FloatField( min_value=0, help_text="Desired monthly electricity bill in ₹ (required).", ) location = serializers.CharField( required=False, allow_blank=True, default="", help_text="Location label (informational only, not used in calculation).", ) has_solar = serializers.BooleanField( required=False, default=False, help_text="Whether a solar installation already exists.", ) solar_capacity_kw = serializers.FloatField( required=False, allow_null=True, default=None, min_value=0, help_text=( "Existing solar capacity in kW. " "Required when has_solar=true; ignored otherwise." ), ) def validate(self, data): """Cross-field validation.""" current = data["current_bill"] target = data["target_bill"] if target > current: raise serializers.ValidationError( { "target_bill": ( "target_bill must be less than or equal to current_bill. " "If your target is already met, no solar optimisation is needed." ) } ) if data.get("has_solar") and data.get("solar_capacity_kw") is None: raise serializers.ValidationError( {"solar_capacity_kw": "solar_capacity_kw is required when has_solar is true."} ) return data class BillOptimizationResponseSerializer(serializers.Serializer): """ Serializes the successful calculation result from BillOptimizationService. Used for documentation and response shaping. """ current_units = serializers.FloatField( help_text="Estimated monthly units consumed at current bill." ) target_units = serializers.FloatField( help_text="Estimated monthly units consumed at target bill." ) units_to_offset = serializers.FloatField( help_text="Units that solar must offset to reach the target bill." ) recommended_solar_kw = serializers.FloatField( help_text="Additional solar capacity required in kW." ) recommended_panels = serializers.IntegerField( help_text="Number of 540 W panels required (rounded up)." ) estimated_monthly_generation = serializers.FloatField( help_text="Estimated monthly units generated by recommended solar capacity." )