from __future__ import annotations from typing import Any from openpyxl.cell.rich_text import CellRichText, TextBlock from openpyxl.cell.text import InlineFont from openpyxl.formatting.rule import CellIsRule # type: ignore[reportUnknownVariableType] from openpyxl.styles import Color, Font 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}" _Y_THRESHOLD = 7600 _Y_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 "), TextBlock(InlineFont(b=True, sz=11, color=Color(rgb="196B24"), rFont="Aptos Narrow"), "<"), ) def _apply_column_y_formatting(sheet: Any) -> None: sheet.conditional_formatting.add( _Y_CF_RANGE, CellIsRule(operator="lessThan", formula=[str(_Y_THRESHOLD)], font=Font(color=Color(rgb="FF0000"))), ) sheet.conditional_formatting.add( _Y_CF_RANGE, CellIsRule(operator="greaterThan", formula=[str(_Y_THRESHOLD)], font=Font(color=Color(rgb="196B24"))), ) sheet["Y3"] = _Y_HEADER def _write_cell(sheet: Any, row: int, col: str, value: Any) -> None: sheet[f"{col}{row}"] = value def populate_sheet(sheet: Any, plan: Plan) -> None: rooms: list[Room] = [room for floor in plan.floors for room in floor.rooms] windows: list[tuple[str, Window]] = [ (room.name, w) for room in rooms for w in room.windows ] doors: list[tuple[str, Door]] = [ (room.name, d) for room in rooms for d in room.doors ] if len(rooms) > _MAX_ROWS: raise ValueError(f"Room series exceeds {_MAX_ROWS} rows ({len(rooms)} rooms)") if len(windows) > _MAX_ROWS: raise ValueError(f"Window series exceeds {_MAX_ROWS} rows ({len(windows)} windows)") if len(doors) > _MAX_ROWS: raise ValueError(f"Door series exceeds {_MAX_ROWS} rows ({len(doors)} doors)") for i, room in enumerate(rooms): row = _DATA_START_ROW + i _write_cell(sheet, row, "B", room.name) _write_cell(sheet, row, "D", room.area_m2) 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) 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 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 _apply_column_y_formatting(sheet)