mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
populate_sheet writes to new Sero template column layout 🟩
This commit is contained in:
parent
e7954ad83a
commit
0edeeaefa6
3 changed files with 129 additions and 22 deletions
|
|
@ -11,9 +11,10 @@ from domain.magicplan.models import Door, Plan, Room, Window
|
|||
|
||||
_DATA_START_ROW = 6
|
||||
_MAX_ROWS = 50
|
||||
_Y_CF_RANGE = f"Y{_DATA_START_ROW}:Y{_DATA_START_ROW + _MAX_ROWS - 1}"
|
||||
_DOOR_AREA_COL = "U"
|
||||
_DOOR_AREA_CF_RANGE = f"{_DOOR_AREA_COL}{_DATA_START_ROW}:{_DOOR_AREA_COL}{_DATA_START_ROW + _MAX_ROWS - 1}"
|
||||
_Y_THRESHOLD = 7600
|
||||
_Y_HEADER = CellRichText(
|
||||
_DOOR_AREA_HEADER = CellRichText(
|
||||
TextBlock(InlineFont(b=True, sz=11, rFont="Aptos Narrow"), "Area (mm2)\n"),
|
||||
TextBlock(InlineFont(b=True, sz=11, color=Color(rgb="FF0000"), rFont="Aptos Narrow"), "<"),
|
||||
TextBlock(InlineFont(b=True, sz=11, rFont="Aptos Narrow"), " 7600 "),
|
||||
|
|
@ -23,14 +24,14 @@ _Y_HEADER = CellRichText(
|
|||
|
||||
def _apply_column_y_formatting(sheet: Any) -> None:
|
||||
sheet.conditional_formatting.add(
|
||||
_Y_CF_RANGE,
|
||||
_DOOR_AREA_CF_RANGE,
|
||||
CellIsRule(operator="lessThan", formula=[str(_Y_THRESHOLD)], font=Font(color=Color(rgb="FF0000"))),
|
||||
)
|
||||
sheet.conditional_formatting.add(
|
||||
_Y_CF_RANGE,
|
||||
_DOOR_AREA_CF_RANGE,
|
||||
CellIsRule(operator="greaterThan", formula=[str(_Y_THRESHOLD)], font=Font(color=Color(rgb="196B24"))),
|
||||
)
|
||||
sheet["Y3"] = _Y_HEADER
|
||||
sheet[f"{_DOOR_AREA_COL}3"] = _DOOR_AREA_HEADER
|
||||
|
||||
|
||||
def _write_cell(sheet: Any, row: int, col: str, value: Any) -> None:
|
||||
|
|
@ -61,26 +62,25 @@ def populate_sheet(sheet: Any, plan: Plan) -> None:
|
|||
for i, (room_name, window) in enumerate(windows):
|
||||
row = _DATA_START_ROW + i
|
||||
vent = window.ventilation
|
||||
_write_cell(sheet, row, "G", room_name)
|
||||
_write_cell(sheet, row, "H", window.width_m)
|
||||
_write_cell(sheet, row, "I", window.height_m)
|
||||
# J = formula =H*I — do not write
|
||||
_write_cell(sheet, row, "K", vent.opening_type if vent else 0)
|
||||
_write_cell(sheet, row, "L", vent.num_openings if vent else 0)
|
||||
_write_cell(sheet, row, "F", room_name)
|
||||
_write_cell(sheet, row, "G", window.width_m)
|
||||
_write_cell(sheet, row, "H", window.height_m)
|
||||
# I = formula =G*H — do not write
|
||||
_write_cell(sheet, row, "J", vent.opening_type if vent else 0)
|
||||
_write_cell(sheet, row, "K", vent.num_openings if vent else 0)
|
||||
pct = vent.pct_openable if vent else None
|
||||
_write_cell(sheet, row, "M", (pct / 100) if pct is not None else 0)
|
||||
# N = formula =J*M — do not write
|
||||
# O, P = blank (visual check by auditor)
|
||||
_write_cell(sheet, row, "Q", vent.trickle_vent_area_mm2 if vent else 0)
|
||||
_write_cell(sheet, row, "R", vent.num_trickle_vents if vent else 0)
|
||||
# S = formula =Q*R — do not write
|
||||
_write_cell(sheet, row, "L", (pct / 100) if pct is not None else 0)
|
||||
# M = formula =I*L — do not write
|
||||
_write_cell(sheet, row, "N", vent.trickle_vent_area_mm2 if vent else 0)
|
||||
_write_cell(sheet, row, "O", vent.num_trickle_vents if vent else 0)
|
||||
# P = formula =N*O — do not write
|
||||
|
||||
for i, (room_name, door) in enumerate(doors):
|
||||
row = _DATA_START_ROW + i
|
||||
vent = door.ventilation
|
||||
_write_cell(sheet, row, "V", room_name)
|
||||
_write_cell(sheet, row, "W", door.width_mm)
|
||||
_write_cell(sheet, row, "X", vent.undercut_mm if vent else 0)
|
||||
# Y = formula =W*X — do not write
|
||||
_write_cell(sheet, row, "R", room_name)
|
||||
_write_cell(sheet, row, "S", door.width_mm)
|
||||
_write_cell(sheet, row, "T", vent.undercut_mm if vent else 0)
|
||||
# U = formula =S*T — do not write
|
||||
|
||||
_apply_column_y_formatting(sheet)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ from infrastructure.s3.s3_client import S3Client
|
|||
if TYPE_CHECKING:
|
||||
from orchestration.audit_generator_unit_of_work import AuditGeneratorUnitOfWork
|
||||
|
||||
_TEMPLATE_PATH = Path(__file__).parent.parent / "applications" / "audit_generator" / "d1_ventilation_template.xlsx"
|
||||
_TEMPLATE_PATH = Path(__file__).parent.parent / "applications" / "audit_generator" / "Master Sero Template - Data Extraction.xlsx"
|
||||
_SHEET_NAME = "D1 Ventilation"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -92,3 +92,110 @@ def test_raises_when_doors_exceed_50() -> None:
|
|||
# Act / Assert
|
||||
with pytest.raises(ValueError, match="50"):
|
||||
populate_sheet(sheet, plan)
|
||||
|
||||
|
||||
def test_writes_window_room_name_to_column_F() -> None:
|
||||
# Arrange
|
||||
plan = _make_plan(num_rooms=1, num_windows_per_room=1, num_doors_per_room=0)
|
||||
sheet = _blank_sheet()
|
||||
|
||||
# Act
|
||||
populate_sheet(sheet, plan)
|
||||
|
||||
# Assert
|
||||
assert sheet["F6"].value == "Room 0"
|
||||
|
||||
|
||||
def test_writes_window_dimensions_to_columns_G_and_H() -> None:
|
||||
# Arrange
|
||||
plan = _make_plan(num_rooms=1, num_windows_per_room=1, num_doors_per_room=0)
|
||||
sheet = _blank_sheet()
|
||||
|
||||
# Act
|
||||
populate_sheet(sheet, plan)
|
||||
|
||||
# Assert
|
||||
assert sheet["G6"].value == 1.0
|
||||
assert sheet["H6"].value == 1.2
|
||||
|
||||
|
||||
def test_writes_window_opening_data_to_columns_J_K_L() -> None:
|
||||
# Arrange
|
||||
plan = _make_plan(num_rooms=1, num_windows_per_room=1, num_doors_per_room=0)
|
||||
sheet = _blank_sheet()
|
||||
|
||||
# Act
|
||||
populate_sheet(sheet, plan)
|
||||
|
||||
# Assert
|
||||
assert sheet["J6"].value == "Hinged"
|
||||
assert sheet["K6"].value == 1
|
||||
assert sheet["L6"].value == pytest.approx(0.5)
|
||||
|
||||
|
||||
def test_writes_trickle_vent_data_to_columns_N_and_O() -> None:
|
||||
# Arrange
|
||||
plan = _make_plan(num_rooms=1, num_windows_per_room=1, num_doors_per_room=0)
|
||||
sheet = _blank_sheet()
|
||||
|
||||
# Act
|
||||
populate_sheet(sheet, plan)
|
||||
|
||||
# Assert
|
||||
assert sheet["N6"].value == 1000
|
||||
assert sheet["O6"].value == 2
|
||||
|
||||
|
||||
def test_writes_door_room_name_to_column_R() -> None:
|
||||
# Arrange
|
||||
plan = _make_plan(num_rooms=1, num_windows_per_room=0, num_doors_per_room=1)
|
||||
sheet = _blank_sheet()
|
||||
|
||||
# Act
|
||||
populate_sheet(sheet, plan)
|
||||
|
||||
# Assert
|
||||
assert sheet["R6"].value == "Room 0"
|
||||
|
||||
|
||||
def test_writes_door_dimensions_to_columns_S_and_T() -> None:
|
||||
# Arrange
|
||||
plan = _make_plan(num_rooms=1, num_windows_per_room=0, num_doors_per_room=1)
|
||||
sheet = _blank_sheet()
|
||||
|
||||
# Act
|
||||
populate_sheet(sheet, plan)
|
||||
|
||||
# Assert
|
||||
assert sheet["S6"].value == 800.0
|
||||
assert sheet["T6"].value == 10.0
|
||||
|
||||
|
||||
def test_writes_zeros_when_window_has_no_ventilation() -> None:
|
||||
# Arrange
|
||||
rooms = [Room(name="Room 0", width_m=3.0, length_m=4.0, area_m2=12.0, windows=[_make_window(with_ventilation=False)], doors=[])]
|
||||
plan = Plan(uid="u", name="n", address="a", postcode="p", floors=[Floor(level=0, name="G", rooms=rooms)])
|
||||
sheet = _blank_sheet()
|
||||
|
||||
# Act
|
||||
populate_sheet(sheet, plan)
|
||||
|
||||
# Assert
|
||||
assert sheet["J6"].value == 0
|
||||
assert sheet["K6"].value == 0
|
||||
assert sheet["L6"].value == 0
|
||||
assert sheet["N6"].value == 0
|
||||
assert sheet["O6"].value == 0
|
||||
|
||||
|
||||
def test_writes_zeros_when_door_has_no_ventilation() -> None:
|
||||
# Arrange
|
||||
rooms = [Room(name="Room 0", width_m=3.0, length_m=4.0, area_m2=12.0, windows=[], doors=[_make_door(with_ventilation=False)])]
|
||||
plan = Plan(uid="u", name="n", address="a", postcode="p", floors=[Floor(level=0, name="G", rooms=rooms)])
|
||||
sheet = _blank_sheet()
|
||||
|
||||
# Act
|
||||
populate_sheet(sheet, plan)
|
||||
|
||||
# Assert
|
||||
assert sheet["T6"].value == 0
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue