"""콘크리트를 자재 축에 세움 · 할증 이름 잇기 (2026-09-09 확정 3차 ⑥). ⚠⚠ **재료비가 통째로 빠져 있던 자리다.** 타설 줄(품셈 12-1)은 **품만** 주고 재료를 안 준다 (서브 일위대가도 재료 0원). 콘크리트를 자재 축에 안 보내면 레미콘 값이 어디에도 없다. ⚠ 겨누는 것 여섯 ① 콘크리트 셋이 자재총괄에 선다 ② 배합은 여전히 분해 안 함(㉢) — 「콘크리트 ㎥」에서 멈춘다 ③ ⚠ 타설 줄과 **겹치지 않는다** — 그쪽은 품, 이쪽은 재료 ④ 할증은 **레미콘일 때만** 붙는다 — 비빔은 시멘트·골재가 각각 할증됨 ⑤ 이형철근 D13·D16 은 할증표 「이형철근」 줄로 이어진다(품셈 1-3-1, 규격 안 가림) ⑥ ⚠ 이름을 **바꾸지 않는다** — 이름만 잇는다(리핑암↔파쇄암과 같은 처방) """ from __future__ import annotations import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(ROOT)) from B08_Quantity.B08_Quantity_Engine_Handoff import build_handoff # noqa: E402 from B08_Quantity.B08_Quantity_Engine_MaterialSummary import ( # noqa: E402 build_table as build_material, ) from B08_Quantity.B08_Quantity_Engine_MaterialSummary import surcharge_lookup_name # noqa: E402 from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table # noqa: E402 def 단위표() -> dict: return build_table( [ { "structure_id": "s1", "type_id": "masonry_wet", "start_m": 0.0, "end_m": 10.0, "options": { "height_m": 2.5, "length_m": 10.0, "back_len_cm": 45, "foundation": "기초유", }, } ] ) def 자재(method: str | None = None) -> dict: return { row["name"]: row for row in build_material(단위표(), concrete_placing_method=method)["rows"] } def test_콘크리트가_자재총괄에_선다() -> None: rows = 자재() assert rows["채움콘크리트"]["net_amount"] > 0 assert rows["버림콘크리트"]["net_amount"] > 0 def test_배합은_분해하지_않는다() -> None: """⚠ 시멘트·모래·자갈로 쪼개면 B09 일위대가와 두 배가 된다(㉢).""" rows = 자재() assert not ({"시멘트", "모래", "자갈"} & set(rows)) def test_타설_줄과_겹치지_않는다() -> None: """타설은 품, 자재는 재료 — 둘 다 서되 같은 것을 두 번 세지 않는다.""" rows = build_handoff(unit_quantity_table=단위표())["work_items"] placing = [row for row in rows if row["name"] == "콘크리트 타설"] assert len(placing) == 1 assert all(row["name"] != "채움콘크리트" for row in rows) def test_할증은_레미콘일_때만_붙는다() -> None: """⚠ 비빔은 시멘트·골재가 각각 할증되는 자리라 레미콘 할증을 붙이면 틀린다.""" 레미콘 = 자재("ready_mixed")["채움콘크리트"] 비빔 = 자재("machine_mixed")["채움콘크리트"] # ⚠ 「안 정함」은 비빔이 아니다 — 타설 줄이 기본값(레디믹스트)으로 도는데 할증만 # 미확보로 두면 같은 프로젝트에서 두 값이 어긋난다(실화면에서 걸린 자리). 안정함 = 자재(None)["채움콘크리트"] assert 안정함["surcharge_pct"] is not None assert "기본값" in 안정함["note"] assert 레미콘["surcharge_pct"] is not None assert 비빔["surcharge_pct"] is None assert "레미콘이 아니라" in 비빔["note"] or "레미콘이 아니라" in str(비빔) def test_이형철근은_규격을_안_가린다() -> None: """품셈 1-3-1 「이형철근」 줄 하나가 D13·D16 을 다 받는다.""" assert surcharge_lookup_name("이형철근 D13", None)[0] == "이형철근" assert surcharge_lookup_name("이형철근 D16", None)[0] == "이형철근" def test_이름을_바꾸지_않는다() -> None: """⚠ 줄 이름이 바뀌면 타설 줄·묶음 조각이 성분을 못 찾는다 — 찾을 때만 다른 이름을 쓴다.""" rows = 자재("ready_mixed") assert "레미콘" not in rows assert rows["채움콘크리트"]["name"] == "채움콘크리트"