mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-27 23:35:01 +00:00
Map the default plan's selected measures onto the export row 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
14763638e2
commit
5dab7beae5
2 changed files with 96 additions and 1 deletions
|
|
@ -22,3 +22,6 @@ class MaterialRow(SQLModel, table=True):
|
|||
cost_unit: Optional[str] = Field(default=None)
|
||||
description: Optional[str] = Field(default=None)
|
||||
is_active: bool = Field(default=True)
|
||||
# Whether a solar_pv Option's product bundle includes a battery; the Scenario
|
||||
# Export reads it to pivot solar-with-battery to its own column (ADR-0065).
|
||||
includes_battery: bool = Field(default=False)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,11 @@ from sqlalchemy import Engine
|
|||
from sqlmodel import Session
|
||||
|
||||
from datatypes.epc.domain.epc import Epc
|
||||
from infrastructure.postgres.modelling import PlanModel # registers `plan`
|
||||
from infrastructure.postgres.modelling import ( # registers `plan` + `recommendation`
|
||||
PlanModel,
|
||||
RecommendationModel,
|
||||
)
|
||||
from infrastructure.postgres.product_table import MaterialRow # registers `material`
|
||||
from infrastructure.postgres.property_table import PropertyRow # registers `property`
|
||||
from repositories.scenario_export.scenario_export_postgres_repository import (
|
||||
ScenarioExportPostgresRepository,
|
||||
|
|
@ -91,3 +95,91 @@ def test_excludes_requested_properties_without_a_default_plan_under_the_scenario
|
|||
|
||||
# assert — only #1 (a default Plan under scenario 5) survives (model A).
|
||||
assert [r.property_id for r in rows] == [1]
|
||||
|
||||
|
||||
def test_maps_the_default_plans_selected_measures_with_battery_and_exclusions(
|
||||
db_engine: Engine,
|
||||
) -> None:
|
||||
# arrange — a default Plan with two selected measures (one solar_pv whose
|
||||
# material carries a battery), plus a non-default and an already-installed
|
||||
# recommendation that must be excluded.
|
||||
with Session(db_engine) as session:
|
||||
session.add(PropertyRow(id=1, portfolio_id=100, landlord_property_id="LP1"))
|
||||
session.add(
|
||||
PlanModel(
|
||||
id=10, portfolio_id=100, property_id=1, scenario_id=5, is_default=True
|
||||
)
|
||||
)
|
||||
session.add(MaterialRow(id=1, type="loft_insulation", includes_battery=False))
|
||||
session.add(MaterialRow(id=2, type="solar_pv", includes_battery=True))
|
||||
session.add(
|
||||
RecommendationModel(
|
||||
plan_id=10,
|
||||
property_id=1,
|
||||
type="loft_insulation",
|
||||
measure_type="loft_insulation",
|
||||
description="Loft insulation",
|
||||
estimated_cost=1200.0,
|
||||
sap_points=3.0,
|
||||
co2_equivalent_savings=0.4,
|
||||
kwh_savings=900.0,
|
||||
energy_cost_savings=120.0,
|
||||
material_id=1,
|
||||
default=True,
|
||||
already_installed=False,
|
||||
)
|
||||
)
|
||||
session.add(
|
||||
RecommendationModel(
|
||||
plan_id=10,
|
||||
property_id=1,
|
||||
type="solar_pv",
|
||||
measure_type="solar_pv",
|
||||
description="Solar PV with battery",
|
||||
estimated_cost=6000.0,
|
||||
sap_points=5.0,
|
||||
material_id=2,
|
||||
default=True,
|
||||
already_installed=False,
|
||||
)
|
||||
)
|
||||
session.add(
|
||||
RecommendationModel(
|
||||
plan_id=10,
|
||||
property_id=1,
|
||||
type="double_glazing",
|
||||
measure_type="double_glazing",
|
||||
description="Double glazing (not selected)",
|
||||
estimated_cost=4000.0,
|
||||
default=False,
|
||||
already_installed=False,
|
||||
)
|
||||
)
|
||||
session.add(
|
||||
RecommendationModel(
|
||||
plan_id=10,
|
||||
property_id=1,
|
||||
type="cavity_wall_insulation",
|
||||
measure_type="cavity_wall_insulation",
|
||||
description="CWI (already installed)",
|
||||
estimated_cost=800.0,
|
||||
default=True,
|
||||
already_installed=True,
|
||||
)
|
||||
)
|
||||
session.commit()
|
||||
|
||||
# act
|
||||
with Session(db_engine) as session:
|
||||
rows = ScenarioExportPostgresRepository(session).rows_for(
|
||||
portfolio_id=100, scenario_id=5, property_ids=[1]
|
||||
)
|
||||
|
||||
# assert — only the two selected measures map through, the battery flag is
|
||||
# resolved from the material, and savings are carried per measure.
|
||||
by_type = {m.measure_type: m for m in rows[0].measures}
|
||||
assert set(by_type) == {"loft_insulation", "solar_pv"}
|
||||
assert by_type["loft_insulation"].estimated_cost == 1200.0
|
||||
assert by_type["loft_insulation"].kwh_savings == 900.0
|
||||
assert by_type["loft_insulation"].includes_battery is False
|
||||
assert by_type["solar_pv"].includes_battery is True
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue