Files
Aislo/resources/tester/test_b09_prep_handoff_bill.py
T
eomsangdonandClaude Opus 5 82755260e2 feat(b08): 표토제거 실무대로 — 노면 + 절토 사면 ㎡ · 운반은 20 m 넘는 몫만 · 층따기 제안값 경고
- 표토제거: 답외구간 FP-09-15-02 · 밑수 ㎡ · 대상 노면·절토대상지(성토 사면 안 셈) · 노면 폭이 빈 측점이 있으면 안 섬
- 표토 운반·적치: 제거 ㎡ × 두께 · 거리 − 압토 20 m · 20 m 이내면 제거 품에 듦
- 층따기: 「제안값(확정 아님)」 경고 줄 · 칸에 자동으로 안 넣음
- 시험: 옛 ㎥ 기대값 넷 갱신 · 노면 면적 평균단면적 시험

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
2026-09-13 23:58:38 +09:00

62 lines
2.7 KiB
Python

"""PLAN 7장 V-12 — 준비공 줄이 B08 인계에서 **B09 내역서까지 하나도 안 새나** (2026-09-13).
「안 하면 표토제거 2,359.03㎥ 가 다시 통째로 사라짐」 자리. 보내는 쪽(B08)과 받는 쪽(B09)을
**마주 걸어** 본다 — 한쪽만 보면 양쪽 다 조용히 틀린다(PLAN 7장 머리 규칙).
⚠ 겨누는 것 둘
① 준비공·부대시설 줄은 **내역 줄 아니면 제외 줄**로 반드시 선다 — 어디에도 없는 줄이 0
② 금액이 서는 줄(`in_bill`)은 **수량째** 내역 본체에 선다 — 표토제거 2,359.035㎥
⚠ 단가가 붙는지는 여기서 안 본다 — 표토 축(시트 9번)·임목축적 입력이 정해져야 서는 자리다.
"""
from __future__ import annotations
import sys
from decimal import Decimal
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_Preparation import build_table as build_prep # noqa: E402
from B09_Estimation.B09_Estimation_BillOfQuantities import build_bill # noqa: E402
SLOPE = {
"face_dressing_fill": 9000.0,
"face_dressing_cut": 6726.9,
"tree_removal_fill": 9000.0,
"tree_removal_cut": 6726.9,
"bench_cut_fill": 9000.0,
}
def _handoff_and_bill():
table = build_prep(SLOPE, [], [], 0.15, road_surface_area_m2=8000.0)
handoff = build_handoff(preparation_table=table)
return handoff, build_bill(handoff)
def test_준비공_줄은_내역_아니면_제외로_반드시_선다() -> None:
handoff, bill = _handoff_and_bill()
sent = [r for r in handoff["work_items"] if r["origin"] == "preparation"]
assert len(sent) >= 6
body = [r.name for r in bill.rows if not r.is_group]
excluded = [r.name for r in bill.excluded]
for row in sent:
landed = body if row["in_bill"] else excluded
assert row["name"] in landed, (row["name"], row["in_bill"])
def test_금액이_서는_줄은_수량째_본체에_선다() -> None:
handoff, bill = _handoff_and_bill()
topsoil = next(r for r in bill.rows if not r.is_group and r.name == "표토제거")
# ⭐ 2026-09-13 「실무대로」 — 노면 8,000 + 절토 사면 6,726.9 ㎡ (두께를 안 곱함)
assert Decimal(str(topsoil.quantity)).quantize(Decimal("0.01")) == Decimal("14726.90")
in_bill = [
r["name"] for r in handoff["work_items"] if r["origin"] == "preparation" and r["in_bill"]
]
assert {"표토제거", "뿌리 적재"} <= set(in_bill)
# ⭐ 2026-09-13 판정 Ⓑ — 제근은 토공집계 뿌리뽑기가 셈. 준비공 줄은 참조(제외 목록)로 간다.
assert "제근·뿌리다듬기" not in in_bill