Files
Aislo/resources/tester/test_b08_basin_composite.py
T

83 lines
4.1 KiB
Python

"""12-15 집수정 조립 — 2026-09-14 브레인 ㉯ 남은 몫 판정 ⑴~⑸.
원문 L6460 12-15 표는 조립형(구체·버림 인력 비고 칸 · 다짐기 · 거푸집 합판4회 ·
철근가공조립(보통) · 뚜껑 · 설치비 5%). B08 은 집수정을 12-15 에 곧장(개소) 이어 단가가 안 섰음.
⑴ 다짐기(카탈로그 없음) 빠진 구체 갈래는 안 세움 — 인력만이면 조립 줄이 조용히 싸짐
⑵ □형 원단위에 버림 성분 없음 → 「성분 미확보」 로 막음(0 은 지어냄)
⑶ 철근 갈래는 12-15 표 「보통」(B08 추정 「간단」 걷음 · 4회와 같은 원칙)
⑷ 뚜껑·설치비는 조각 모양이 달라 조립 밖 · 사유만
⑸ 돌집수정은 콘크리트 집수정 표가 아니라 종전대로
목적: 금액을 못 세워도 **조용히 사라지던 것이 사유로 드러남**.
"""
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from B08_Quantity.B08_Quantity_Engine_Handoff import build_handoff # noqa: E402
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table # noqa: E402
CONCRETE = {"structure_id": "b1", "type_id": "pipe_inlet_basin", "start_m": 50.0, "end_m": 50.0,
"options": {"inlet_basin_form": "□형(기본형)", "inlet_basin_material": "콘크리트",
"pipe_diameter_mm": "800"}} # fmt: skip
STONE = {"structure_id": "b2", "type_id": "pipe_inlet_basin", "start_m": 60.0, "end_m": 60.0,
"options": {"inlet_basin_form": "돌집수정 ㄷ형"}} # fmt: skip
def _basin(structure: dict) -> dict:
unit = build_table([structure], {"pipe_inlet_basin": "집수정"})
handoff = build_handoff(unit_quantity_table=unit)
return next(r for r in handoff["work_items"] if r["origin"] == "structure")
def test_버림_갈래는_서고_구체_갈래는_다짐기_없어_안_섬() -> None:
from B09_Estimation.B09_Estimation_UnitPrice import cached_build, detail_of
build = cached_build()
assert "B-FP-12-15#구체콘크리트" not in build.book.titles
rows = detail_of(build, "B-FP-12-15#버림콘크리트")["rows"]
assert {r["ref_code"]: float(r["quantity"]) for r in rows} == {"1013": 0.15, "1002": 0.27}
left = " ".join(build.unattached.get("FP-12-15", []))
assert "구체콘크리트" in left and "봉상후렉시블" in left, left
def test_콘크리트_집수정은_조립_조각으로_가고_막힌_까닭이_드러남() -> None:
row = _basin(CONCRETE)
assert row["work_item_code"] is None, row
codes = {p["code"]: p for p in row["composite_parts"]}
assert codes["FP-12-15#구체콘크리트"]["quantity"] > 0
assert codes["FP-12-04#4회"]["quantity"] > 0
assert "FP-12-03#보통" in codes, list(codes) # ⑶ 표가 적은 갈래
reasons = " ".join(str(m.get("reason")) for m in row["composite_not_ready"] or [])
assert "FP-12-15#버림콘크리트" in {str(m.get("code")) for m in row["composite_not_ready"]}
assert reasons, row
assert "뚜껑" in row["spec_class_basis"] and "설치비" in row["spec_class_basis"] # ⑷
def test_돌집수정은_종전대로_12_15_곧장() -> None:
row = _basin(STONE)
assert row["work_item_code"] == "FP-12-15" and not row["composite_parts"], row
def test_콘크리트_집수정_콘크리트는_타설_줄이_또_세지_않음() -> None:
unit = build_table([CONCRETE], {"pipe_inlet_basin": "집수정"})
handoff = build_handoff(unit_quantity_table=unit)
placing = [
r for r in handoff["work_items"] if str(r["work_item_code"] or "").startswith("FP-12-01")
]
assert not placing, placing # 구체 조각이 셈 — 두 번 안 셈
def test_내역_조립_줄은_금액_없이_사유() -> None:
from B09_Estimation.B09_Estimation_BillOfQuantities import build_bill
unit = build_table([CONCRETE], {"pipe_inlet_basin": "집수정"})
bill = build_bill(build_handoff(unit_quantity_table=unit))
line = next(r for r in bill.rows if r.code is None and "집수정" in r.name)
assert line.amount_krw is None and "묶음 조각" in line.note, line.note