Spaces:
Running
Running
| 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." | |
| ) | |