From c2aca6d2e64bd1068b3cee0f9d23fa221070766d Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 13 Jul 2026 23:14:41 +0000 Subject: [PATCH] =?UTF-8?q?Carry=20the=20Plan's=20post-works=20figures=20o?= =?UTF-8?q?nto=20the=20export=20row=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- domain/scenario_export/scenario_sheet.py | 33 +++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/domain/scenario_export/scenario_sheet.py b/domain/scenario_export/scenario_sheet.py index 64cb5a6d9..8f7dc681c 100644 --- a/domain/scenario_export/scenario_sheet.py +++ b/domain/scenario_export/scenario_sheet.py @@ -64,6 +64,24 @@ _SAVINGS_COLUMNS: tuple[str, ...] = ( # Package-level totals, trailing the savings roll-ups. _TOTAL_COLUMNS: tuple[str, ...] = ("total_retrofit_cost",) +# The default Plan's post-works figures, taken straight from the persisted Plan +# (the SAP calculator's output) with no recompute (ADR-0065). +_PLAN_COLUMNS: tuple[str, ...] = ( + "post_sap_points", + "post_epc_rating", + "cost_of_works", + "contingency_cost", + "co2_savings", + "energy_bill_savings", + "energy_consumption_savings", + "valuation_increase", +) + + +def _blank(value: Any) -> Any: + """A missing value renders as a blank cell, not a zero or ``None``.""" + return "" if value is None else value + def _sum(values: Sequence[Optional[float]]) -> float: """Sum optional numbers, treating an absent contribution as zero.""" @@ -145,7 +163,11 @@ def shape_scenario_sheet( ) -> ExportSheet: """Shape one Scenario's Properties into a wide export sheet (ADR-0065).""" columns: tuple[str, ...] = ( - _ID_COLUMNS + _ALL_MEASURE_COLUMNS + _SAVINGS_COLUMNS + _TOTAL_COLUMNS + _ID_COLUMNS + + _ALL_MEASURE_COLUMNS + + _SAVINGS_COLUMNS + + _TOTAL_COLUMNS + + _PLAN_COLUMNS ) rows: list[dict[str, Any]] = [] for prop in properties: @@ -171,5 +193,14 @@ def shape_scenario_sheet( [m.energy_cost_savings for m in prop.measures] ) row["total_retrofit_cost"] = _sum([m.estimated_cost for m in prop.measures]) + # The default Plan's post-works figures, passed through as persisted. + row["post_sap_points"] = _blank(prop.post_sap_points) + row["post_epc_rating"] = _blank(prop.post_epc_rating) + row["cost_of_works"] = _blank(prop.cost_of_works) + row["contingency_cost"] = _blank(prop.contingency_cost) + row["co2_savings"] = _blank(prop.co2_savings) + row["energy_bill_savings"] = _blank(prop.energy_bill_savings) + row["energy_consumption_savings"] = _blank(prop.energy_consumption_savings) + row["valuation_increase"] = _blank(prop.valuation_increase) rows.append(row) return ExportSheet(columns=columns, rows=tuple(rows))