File size: 2,942 Bytes
4847e7d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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."
    )