Coverage for backend/django/Economics/formulas/native_properties/specs.py: 100%
34 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-06-23 21:51 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-06-23 21:51 +0000
1from __future__ import annotations
3from dataclasses import dataclass
5from Economics.studies.models import EconomicsStudy
8BASE_CAPITAL_COST = "base_capital_cost"
9PURCHASE_BASIS_EQUIPMENT = "purchase_basis_equipment"
10INSTALLED_BASIS_EQUIPMENT = "installed_basis_equipment"
11CONTINGENCY = "contingency"
12PEAK_DEMAND = "peak_demand"
13ELECTRICAL_UPGRADE = "electrical_upgrade"
14ANNUAL_OPERATING_EXPENSE = "annual_operating_expense"
15CAPEX = "capex"
16ANNUAL_REVENUE = "annual_revenue"
17ANNUAL_PROFIT = "annual_profit"
18ANNUAL_SAVINGS = "annual_savings"
19INCREMENTAL_CAPEX = "incremental_capex"
20NPV = "npv"
21ROI_PERCENT = "roi_percent"
22LCOH = "lcoh"
25@dataclass(frozen=True)
26class EconomicsNativePropertySpec:
27 """Registry contract for economics fields projected as ordinary properties."""
29 field_key: str
30 display_name: str
31 property_key: str
32 unit_type: str
33 unit: str
34 editable: bool
35 solve_visible: bool
36 result_metric_key: str | None
39def native_property_specs(study: EconomicsStudy) -> tuple[EconomicsNativePropertySpec, ...]:
40 """Return the first-pass economics native fields for a study."""
42 currency = _study_currency(study)
43 return (
44 EconomicsNativePropertySpec(
45 field_key=BASE_CAPITAL_COST,
46 display_name="Base capital cost",
47 property_key="economics.base_capital_cost",
48 unit_type="currency",
49 unit=currency,
50 editable=False,
51 solve_visible=True,
52 result_metric_key=None,
53 ),
54 EconomicsNativePropertySpec(
55 field_key=PURCHASE_BASIS_EQUIPMENT,
56 display_name="Purchased basis equipment",
57 property_key="economics.purchase_basis_equipment",
58 unit_type="currency",
59 unit=currency,
60 editable=False,
61 solve_visible=True,
62 result_metric_key="purchase_basis_equipment",
63 ),
64 EconomicsNativePropertySpec(
65 field_key=INSTALLED_BASIS_EQUIPMENT,
66 display_name="Installed basis equipment",
67 property_key="economics.installed_basis_equipment",
68 unit_type="currency",
69 unit=currency,
70 editable=False,
71 solve_visible=True,
72 result_metric_key="installed_basis_equipment",
73 ),
74 EconomicsNativePropertySpec(
75 field_key=CONTINGENCY,
76 display_name="Contingency",
77 property_key="economics.contingency",
78 unit_type="currency",
79 unit=currency,
80 editable=False,
81 solve_visible=True,
82 result_metric_key="contingency",
83 ),
84 EconomicsNativePropertySpec(
85 field_key=PEAK_DEMAND,
86 display_name="Peak demand",
87 property_key="economics.peak_demand",
88 unit_type="heatflow",
89 unit="kW",
90 editable=False,
91 solve_visible=True,
92 result_metric_key="peak_demand",
93 ),
94 EconomicsNativePropertySpec(
95 field_key=ELECTRICAL_UPGRADE,
96 display_name="Electrical upgrade",
97 property_key="economics.electrical_upgrade",
98 unit_type="currency",
99 unit=currency,
100 editable=False,
101 solve_visible=True,
102 result_metric_key="electrical_upgrade",
103 ),
104 EconomicsNativePropertySpec(
105 field_key=ANNUAL_OPERATING_EXPENSE,
106 display_name="Annual operating expense",
107 property_key="economics.annual_operating_expense",
108 unit_type="costRate",
109 unit=f"{currency}/year",
110 editable=False,
111 solve_visible=True,
112 result_metric_key="annual_opex",
113 ),
114 EconomicsNativePropertySpec(
115 field_key=CAPEX,
116 display_name="Total capital cost",
117 property_key="economics.capex",
118 unit_type="currency",
119 unit=currency,
120 editable=False,
121 solve_visible=True,
122 result_metric_key="capex",
123 ),
124 EconomicsNativePropertySpec(
125 field_key=ANNUAL_REVENUE,
126 display_name="Annual revenue",
127 property_key="economics.annual_revenue",
128 unit_type="costRate",
129 unit=f"{currency}/year",
130 editable=False,
131 solve_visible=True,
132 result_metric_key="annual_revenue",
133 ),
134 EconomicsNativePropertySpec(
135 field_key=ANNUAL_PROFIT,
136 display_name="Annual profit",
137 property_key="economics.annual_profit",
138 unit_type="costRate",
139 unit=f"{currency}/year",
140 editable=False,
141 solve_visible=True,
142 result_metric_key="annual_profit",
143 ),
144 EconomicsNativePropertySpec(
145 field_key=ANNUAL_SAVINGS,
146 display_name="Annual savings",
147 property_key="economics.annual_savings",
148 unit_type="costRate",
149 unit=f"{currency}/year",
150 editable=False,
151 solve_visible=True,
152 result_metric_key="annual_savings",
153 ),
154 EconomicsNativePropertySpec(
155 field_key=INCREMENTAL_CAPEX,
156 display_name="Incremental capital cost",
157 property_key="economics.incremental_capex",
158 unit_type="currency",
159 unit=currency,
160 editable=False,
161 solve_visible=True,
162 result_metric_key="incremental_capex",
163 ),
164 EconomicsNativePropertySpec(
165 field_key=NPV,
166 display_name="NPV",
167 property_key="economics.npv",
168 unit_type="currency",
169 unit=currency,
170 editable=False,
171 solve_visible=True,
172 result_metric_key="npv",
173 ),
174 EconomicsNativePropertySpec(
175 field_key=ROI_PERCENT,
176 display_name="ROI",
177 property_key="economics.roi_percent",
178 unit_type="percentage",
179 unit="percent",
180 editable=False,
181 solve_visible=True,
182 result_metric_key="roi_percent",
183 ),
184 EconomicsNativePropertySpec(
185 field_key=LCOH,
186 display_name="LCOH",
187 property_key="economics.lcoh",
188 unit_type="currency",
189 unit=f"{currency}/MWh",
190 editable=False,
191 solve_visible=True,
192 result_metric_key="lcoh",
193 ),
194 )
197def _study_currency(study: EconomicsStudy) -> str:
198 assumptions = getattr(study, "assumptions", None)
199 return getattr(assumptions, "currency", None) or "NZD"