mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-22 08:48:38 +00:00
ProductPostgresRepository.get took .first() with no ORDER BY, so when a measure type has several active material rows (the live catalogue holds 74 solar_pv, 5 high_heat_retention_storage_heaters) the chosen row — hence the cost and material_id — depended on the database's physical row order. Order by id so a re-seed prices the same product every time. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
40 lines
1.6 KiB
Python
40 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
from sqlmodel import Session, col, select
|
|
|
|
from domain.modelling.contingencies import contingency_rate
|
|
from domain.modelling.product import Product
|
|
from infrastructure.postgres.product_table import MaterialRow
|
|
from repositories.product.product_repository import ProductRepository
|
|
|
|
|
|
class ProductPostgresRepository(ProductRepository):
|
|
"""Reads the ``material`` catalogue table and maps an active row to a
|
|
Product: `total_cost` becomes the fully-loaded `unit_cost_per_m2`, and the
|
|
per-Measure-Type contingency is joined from config."""
|
|
|
|
def __init__(self, session: Session) -> None:
|
|
self._session = session
|
|
|
|
def get(self, measure_type: str) -> Product:
|
|
# The live catalogue holds many active rows per type; order by id so the
|
|
# pick is deterministic (a re-seed prices the same) rather than relying
|
|
# on the database's physical row order.
|
|
row: MaterialRow | None = self._session.exec(
|
|
select(MaterialRow)
|
|
.where(
|
|
col(MaterialRow.type) == measure_type,
|
|
col(MaterialRow.is_active).is_(True),
|
|
)
|
|
.order_by(col(MaterialRow.id))
|
|
).first()
|
|
if row is None:
|
|
raise ValueError(f"no active product for measure type {measure_type!r}")
|
|
if row.total_cost is None:
|
|
raise ValueError(f"product {measure_type!r} has no total_cost")
|
|
return Product(
|
|
measure_type=measure_type,
|
|
unit_cost_per_m2=row.total_cost,
|
|
contingency_rate=contingency_rate(measure_type),
|
|
id=row.id,
|
|
)
|