Files
Aislo/resources/tester/test_b08_basin_composite.py
eomsangdonandClaude Opus 5 7ea2598263 fix(b09): 휘발유 기계에 경유값이 붙던 것 — 운전경비표 연료 종류대로 유가 · 콘크리트 진동기(4611) 원문값 되살려 집수정 구체콘크리트 갈래를 세움
· 연료 — `fuel_kind` 를 조립이 안 읽어 휘발유 기계 10종(래머·플레이트 콤팩터·믹서·커터·진동기)이 경유값이었음 → `M-FUEL-휘발유` · 시도 판도 종류대로 · 기계 하나 사용료·중기경비 장도 같은 값
· 진동기 — 건설품셈 8-3 (4611) 두 줄이 한 칸에 뭉쳐 규격·손료계수가 비었음 → 원문값 되살림(전기식 ø45 0.75㎾ 4,935 · 엔진식 ø45 2.6㎾ 5,101 · 판정 없음)
· 12-15 「봉상후렉시블(45mm)」 → 엔진식 4611-0350 범위 별칭 — 12-15 는 전기·엔진을 안 적음 · 12-34-1 「3.5HP」 = 2.6㎾ · 운전경비표에 엔진식만(브레인 승인) → 구체콘크리트 갈래가 진동기 1/5.4 hr/㎥ 와 함께 섬
· 661 뒤처리 — 중기경비 장의 `#암석` 이 조합 16%·비암석 계수로 보이던 것을 보정 상각·정비·계와 본 잡품률로
· 마스터 재생성 — 12-15 갈래 키만(구체콘크리트 더함)

휘발유 기계 전수 대조: 재료비 +13~113원/hr · 조립에 선 것은 플레이트 콤팩터(+20원/hr → 9-14-02 +5원)와 진동기 · 나머지 제목 그대로 · 프로젝트 내역 그대로 · 잴 시험 일곱 빨강→초록 · 끄기 다섯 빨강 · 전체 시험 1695 + 330 통과
(시험 파일은 앞선 autopush 가 먼저 쓸어 올린 빨강본 — 이 커밋이 초록으로 맞춤)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
2026-09-14 22:40:49 +09:00

86 lines
4.5 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:
"""⑴ 다짐기 빠진 구체 갈래는 안 세움 — 2026-09-14 661 뒤 ① 진동기(엔진식 4611-0350)가 풀려 이제 섬."""
from B09_Estimation.B09_Estimation_UnitPrice import cached_build, detail_of
build = cached_build()
assert "B-FP-12-15#구체콘크리트" 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}
body = {r["ref_code"] for r in detail_of(build, "B-FP-12-15#구체콘크리트")["rows"]}
assert "X-4611-0350" in body, body # 인력만으로 서지 않음(⑴ 까닭 그대로)
left = " ".join(build.unattached.get("FP-12-15", []))
assert "구체콘크리트" not in left and "봉상후렉시블" not 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