mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-27 23:35:01 +00:00
Render the scenario export workbook with a sheet per scenario 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
183d14f5f4
commit
62451aa3c9
4 changed files with 50 additions and 0 deletions
0
infrastructure/xlsx/__init__.py
Normal file
0
infrastructure/xlsx/__init__.py
Normal file
20
infrastructure/xlsx/scenario_export_workbook.py
Normal file
20
infrastructure/xlsx/scenario_export_workbook.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
"""Renders the Scenario Export workbook (ADR-0065).
|
||||
|
||||
One ``.xlsx`` with one sheet per Scenario (model A2), each sheet's rows shaped by
|
||||
``domain.scenario_export`` and painted with the Monday-style branding in
|
||||
``infrastructure.xlsx.branding``. Programmatic openpyxl (no template) so a
|
||||
dynamic number of scenario sheets is handled natively.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Sequence
|
||||
|
||||
from domain.scenario_export.scenario_sheet import ExportSheet
|
||||
|
||||
|
||||
def render_workbook(sheets: Sequence[tuple[str, ExportSheet]]) -> bytes:
|
||||
"""Render the scenario sheets into a single branded ``.xlsx`` as bytes. Each
|
||||
tuple is a Scenario name and its shaped sheet; sheet order follows the input
|
||||
(the requested ``scenario_ids`` order)."""
|
||||
raise NotImplementedError
|
||||
0
tests/infrastructure/xlsx/__init__.py
Normal file
0
tests/infrastructure/xlsx/__init__.py
Normal file
30
tests/infrastructure/xlsx/test_scenario_export_workbook.py
Normal file
30
tests/infrastructure/xlsx/test_scenario_export_workbook.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
"""The Scenario Export workbook renderer (ADR-0065): one branded .xlsx with one
|
||||
sheet per Scenario, headers then rows, verified by re-opening the bytes."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
from openpyxl import load_workbook
|
||||
|
||||
from domain.scenario_export.scenario_sheet import ExportSheet
|
||||
from infrastructure.xlsx.scenario_export_workbook import render_workbook
|
||||
|
||||
|
||||
def test_renders_a_sheet_named_for_the_scenario_with_headers_then_rows() -> None:
|
||||
# arrange — one scenario's shaped sheet.
|
||||
sheet = ExportSheet(
|
||||
columns=("property_id", "loft_insulation"),
|
||||
rows=({"property_id": 1, "loft_insulation": 1200.0},),
|
||||
)
|
||||
|
||||
# act
|
||||
data = render_workbook([("Fabric first", sheet)])
|
||||
|
||||
# assert — a real workbook with a sheet named for the scenario, the column
|
||||
# contract as the header row, and the data beneath it.
|
||||
workbook = load_workbook(BytesIO(data))
|
||||
assert workbook.sheetnames == ["Fabric first"]
|
||||
worksheet = workbook["Fabric first"]
|
||||
assert [cell.value for cell in worksheet[1]] == ["property_id", "loft_insulation"]
|
||||
assert [cell.value for cell in worksheet[2]] == [1, 1200.0]
|
||||
Loading…
Add table
Reference in a new issue