From 589eedba8ac3fa4625fbf35f378af634d37375df Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Wed, 15 Jul 2026 13:53:59 +0000 Subject: [PATCH] =?UTF-8?q?Cite=20C6=20rather=20than=20C3.2=20for=20the=20?= =?UTF-8?q?heat-network=20standing=20charge=20rule=20=F0=9F=9F=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- .../sap10_calculator/rdsap/cert_to_inputs.py | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/domain/sap10_calculator/rdsap/cert_to_inputs.py b/domain/sap10_calculator/rdsap/cert_to_inputs.py index 283b9f8c6..1fc568e03 100644 --- a/domain/sap10_calculator/rdsap/cert_to_inputs.py +++ b/domain/sap10_calculator/rdsap/cert_to_inputs.py @@ -1995,16 +1995,15 @@ def _is_community_heating_hw_from_main(epc: EpcPropertyData) -> bool: def _heat_network_standing_charge_gbp( epc: EpcPropertyData, main: Optional[MainHeatingDetail] ) -> Optional[float]: - """SAP 10.2 Table 12 note (l) + §C3.2 heat-network standing charge, or - None when the dwelling is not on a heat network (caller then falls back - to the fuel-based `additional_standing_charges_gbp`). + """SAP 10.2 Table 12 note (l) + §C6 heat-network standing charge that + REPLACES the dwelling's fuel-based standing, or None when no replacement + applies (`_standing_charges_total_gbp` then composes the fuel-based + `additional_standing_charges_gbp` itself). A heat network carries the Table 12 £120/yr standing charge regardless of the network fuel — full when the SPACE heating is on the network - (§C3.2 "the total standing charge is the normal heat network standing - charge"), halved to £60 when ONLY DHW is provided by the heat network - (note (l)). This REPLACES the fuel-based gas/off-peak standing for a - heat-network main, so it must not be added on top of + (§C6 p.55 "the total standing charge is the normal heat network standing + charge"). Being a TOTAL, it must not be added on top of `additional_standing_charges_gbp` (which would double-count: a Summary-path community-gas main lodges Table-32 code 1 and already draws the £120 gas standing). Worksheet-validated: simulated case 14 @@ -2013,6 +2012,17 @@ def _heat_network_standing_charge_gbp( The API path under-counted this: an EPC community fuel (e.g. 20 = mains gas community) is not a Table-32 gas code, so `_is_gas_code` returned False and the standing came out £0 — cert 9390 lost the whole £120. + + The £60 branch is reachable ONLY for WHC 914 (`_water_heating_main` + returns Main 2 for 914 alone, and 901/902's Main 1 would already have + hit the branch above). Main 2 is a MAIN heating system, so it carries a + space-heating fraction — meaning the space heating IS also a heat + network, which is precisely C6's "unless", pointing at the full £120. + #1608 tracks that; it is deliberately left as-is here. + + NOTE: this is NOT the C6 half charge for water-only networks (WHC + 950/951/952) — that one is additive and lives in + `_standing_charges_total_gbp`. """ if is_heat_network_main(main): return _HEAT_NETWORK_STANDING_CHARGE_GBP