Files
Aislo/resources/tester/test_b08_fixed_sheet_notes.py
T
2026-09-14 17:27:53 +09:00

97 lines
3.7 KiB
Python

"""㉰ 고정형 장 사유 · ㉱ 규격 다름 (2026-09-14 브레인 판정).
㉰ 고정형을 가져온 장에 **전개 사유(뒷길이 표준·돌 종류…)가 그대로 남아** 고정형 줄과 안 맞음 = 거짓 사유 →
항목 사유(원문 시점 수량·가산 행)를 띄우고 전개 사유는 **남긴 전개 줄(토공·버림·기초잡석·채집석)에 걸린 것만** 둠.
㉱ H=2.0 호표를 H=2.5 벽에 쓰면 벽 수량은 박힌 값(H2.0) · 토공·사토 공제는 장 제원(H2.5) — 밑수가 갈림 →
미확정과 같은 급으로 보임(빨간 테두리·「규격 다름」 배지) · 금액은 섬 · 막지 않음.
"""
from __future__ import annotations
from pathlib import Path
from B05_Profile.B05_Profile_Structures_Schema import StructureInstance
from B08_Quantity.B08_Quantity_Engine_StmateRecipe import recipe_item
from B08_Quantity.B08_Quantity_Engine_StructureSheet import build_standard_sheets
from B08_Quantity.B08_Quantity_Engine_StructureTemplate import apply_templates
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table
ROOT = Path(__file__).resolve().parents[2]
HOPYO = {
"no": 6,
"source_code": "B00010",
"name": "기슭막이(깬잡석,찰쌓기 L3=45m)",
"spec": "H=2.0m, 채집",
"unit": "M",
"basis": [],
"contract_rows": 0,
"rows": [
{
"name": "깬잡석찰쌓기",
"spec": "L3=45",
"amount": 2.09,
"unit": "M2",
"remark": "",
"source_code": "",
},
{
"name": "공구손료",
"spec": "노무비의 %",
"amount": 2,
"unit": "%",
"remark": "",
"source_code": "",
},
],
}
NAMES = {"masonry_wet": "돌쌓기(찰)"}
def _sheet(height: float) -> dict:
wall = StructureInstance.model_validate(
{
"structure_id": "a",
"type_id": "masonry_wet",
"placement": "interval",
"start_m": 0.0,
"end_m": 10.0,
"options": {"height_m": height, "foundation": "기초유"},
}
).model_dump()
templates = {
"masonry_wet": {
**recipe_item(HOPYO, type_id="masonry_wet", file_name="a", project="p"),
"code": "AX-ST-0000abcd",
}
}
table = build_table([wall], NAMES, {}, {}, None, structure_templates=templates)
payload = build_standard_sheets(table, {})
apply_templates(payload, {}, templates)
return payload["sheets"][0]
def test_고정형_장은_항목_사유를_띄우고_남의_사유를_걷는다() -> None:
notes = " / ".join(_sheet(2.0)["notes"])
assert "원문 시점 수량" in notes and "가산 행 1줄" in notes
assert "돌 종류를 안 골라" not in notes and "뒷채움 폭" not in notes
def test_규격이_다르면_미확정_급으로_밑수_갈림을_알린다() -> None:
sheet = _sheet(2.5)
mismatch = sheet["spec_mismatch"]
assert (mismatch["item_height_m"], mismatch["sheet_height_m"]) == (2.0, 2.5)
assert "규격 다름" in sheet["notes"][0]
assert "토공·사토 공제는 장 제원(H=2.5m)" in sheet["notes"][0]
assert any(row["amount"] for row in sheet["rows"]) # 금액·수량은 막지 않음
def test_규격이_같으면_아무것도_안_뜬다() -> None:
sheet = _sheet(2.0)
assert not sheet.get("spec_mismatch")
assert not any("규격 다름" in note for note in sheet["notes"])
def test_화면이_규격_다름을_빨간_배지로() -> None:
ui = (ROOT / "B08_Quantity" / "B08_Quantity_UI_StructureSheet.ts").read_text(encoding="utf-8")
assert "spec_mismatch" in ui and "규격 다름" in ui and "b08-unit__badge" in ui