fix(epc): source baseline carbon/energy/bills from lodged columns

Per domain semantics: lodged_* on property_baseline_performance is the
gov-registry (actual) figure, effective_* is the modelling-adjusted baseline.
Use the lodged columns for the "current" carbon/primary-energy display and the
individual cost columns (summed) for bills. Bills return NULL when no baseline
row exists, so they're excluded from AVG/SUM rather than shown as £0.

(property_baseline_performance is still unwritten DB-wide; this makes the reads
correct for when the pipeline populates it.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-17 01:07:00 +00:00
parent ef55c49e43
commit f3e00429f9
2 changed files with 30 additions and 13 deletions

View file

@ -778,7 +778,7 @@ export async function getProperties(
epl.registration_date,
epl.inspection_date,
epl.total_floor_area_m2,
bp.effective_co2_emissions_t_per_yr,
bp.lodged_co2_emissions_t_per_yr,
p.lexiscore
LIMIT ${limit} OFFSET ${offset};
`);

View file

@ -73,22 +73,39 @@ export const newApproachJoins = sql`
LEFT JOIN epc_property epp ON epp.property_id = p.id AND epp.source = 'predicted'
`;
/** Baseline carbon (t CO₂/yr). New: effective performance. Legacy: e.co2_emissions. */
/**
* Baseline carbon (t CO/yr). New: the lodged (gov-registry) value. Legacy:
* e.co2_emissions. Swap to `effective_co2_emissions_t_per_yr` if the
* modelling-adjusted baseline is wanted instead.
*/
export const carbonSql = (e: Alias) =>
sql`CASE WHEN ${isNewApproachSql} THEN bp.effective_co2_emissions_t_per_yr ELSE ${e}.co2_emissions END`;
sql`CASE WHEN ${isNewApproachSql} THEN bp.lodged_co2_emissions_t_per_yr ELSE ${e}.co2_emissions END`;
/** Primary energy intensity (kWh/m²/yr). New: effective performance. Legacy: e.primary_energy_consumption. */
/** Primary energy intensity (kWh/m²/yr). New: lodged value. Legacy: e.primary_energy_consumption. */
export const energyConsumptionSql = (e: Alias) =>
sql`CASE WHEN ${isNewApproachSql} THEN bp.effective_primary_energy_intensity_kwh_per_m2_yr ELSE ${e}.primary_energy_consumption END`;
sql`CASE WHEN ${isNewApproachSql} THEN bp.lodged_primary_energy_intensity_kwh_per_m2_yr ELSE ${e}.primary_energy_consumption END`;
/**
* Annual energy bill (£). New: property_baseline_performance.total_annual_bill_gbp
* (NULL when the bill block hasn't been derived yet excluded from AVG/SUM).
* Legacy: the old component-sum formula incl. standing charges and the
* installed-measures adjustment.
* Annual energy bill (£). New: sum of the individual cost columns on
* property_baseline_performance (NULL when no baseline row exists, so it's
* excluded from AVG/SUM rather than counted as £0). Legacy: the old
* component-sum formula incl. standing charges and the installed-measures
* adjustment.
*/
export const billsSql = (e: Alias) =>
sql`CASE WHEN ${isNewApproachSql} THEN bp.total_annual_bill_gbp ELSE (
sql`CASE WHEN ${isNewApproachSql} THEN (
CASE WHEN bp.id IS NULL THEN NULL ELSE (
COALESCE(bp.heating_cost_gbp, 0) +
COALESCE(bp.hot_water_cost_gbp, 0) +
COALESCE(bp.lighting_cost_gbp, 0) +
COALESCE(bp.appliances_cost_gbp, 0) +
COALESCE(bp.cooking_cost_gbp, 0) +
COALESCE(bp.pumps_fans_cost_gbp, 0) +
COALESCE(bp.cooling_cost_gbp, 0) +
COALESCE(bp.standing_charges_gbp, 0) -
COALESCE(bp.seg_credit_gbp, 0)
) END
) ELSE (
${e}.heating_cost_current +
${e}.hot_water_cost_current +
${e}.lighting_cost_current +
@ -272,8 +289,8 @@ async function resolveNewConditionReport(
energyTariff: null,
currentEnergyDemand: sumKwh,
primaryEnergyConsumption:
baseline?.effectivePrimaryEnergyIntensityKwhPerM2Yr ?? null,
co2Emissions: baseline?.effectiveCo2EmissionsTPerYr ?? null,
baseline?.lodgedPrimaryEnergyIntensityKwhPerM2Yr ?? null,
co2Emissions: baseline?.lodgedCo2EmissionsTPerYr ?? null,
heatingEnergyCostCurrent: baseline?.heatingCostGbp ?? null,
hotWaterEnergyCostCurrent: baseline?.hotWaterCostGbp ?? null,
lightingEnergyCostCurrent: baseline?.lightingCostGbp ?? null,
@ -395,7 +412,7 @@ export async function resolveDetailsEpcMeta(
return {
currentEnergyDemand,
co2Emissions: baseline?.effectiveCo2EmissionsTPerYr ?? null,
co2Emissions: baseline?.lodgedCo2EmissionsTPerYr ?? null,
estimated: !lodged && !!predicted,
};
}