fix(b08): 관 벽·돌쌓기 줄 인계에 실제로 쓴 뒷길이 + 출처 — 안 고른 벽도 [주]⑩ 표준표 하한 값으로 13-04-02/05 갈래를 고름 · 고른 값은 원본 그대로(출처 저장 제원)

배정 프로젝트: 인계 줄 18(관 유입·유출부 기슭막이) 갈래 값·판정 근거만 바뀜 · 본체 105,512,060 그대로(모두 미확정) · 전체 1928 통과

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
This commit is contained in:
2026-09-14 17:24:32 +09:00
co-authored by Claude Opus 5
parent 9022640b5f
commit 8dd452d8f4
2 changed files with 75 additions and 0 deletions
@@ -441,6 +441,15 @@ def _structure_rows(
# 갈래 축과 **저장 제원 원본값**. 가공하지 않는다.
variant_axis = str(entry.get("variant_axis") or "") or None
variant_value = (structure.get("options") or {}).get(variant_axis) if variant_axis else None
if variant_axis == "back_len_cm":
# 뒷길이만은 **수량표·구조물도가 실제로 쓴 값**과 출처를 싣는다 — 안 고른 벽(관 유입·
# 유출부 기슭막이는 늘 빔)도 [주]⑩ 하한으로 물량이 섰는데 갈래만 못 골랐음(09-14).
from B08_Quantity.B08_Quantity_Engine_StructureFigure import back_length_cm
back, default_note = back_length_cm(structure)
variant_value = str(back) if variant_value in (None, "") else variant_value
used = f"뒷길이 {back}㎝ — {default_note or '저장 제원'}"
class_basis = " · ".join(part for part in (class_basis, used) if part)
secondary_axes = [
{"axis": axis, "value": (structure.get("options") or {}).get(axis)}
for axis in entry.get("secondary_axes") or []
@@ -0,0 +1,66 @@
"""관 벽 · 돌쌓기 줄 뒷길이 — 인계가 **B08 이 실제로 쓴 뒷길이 + 출처**를 싣는다(2026-09-14 브레인).
종전: 인계는 저장 원본 `back_len_cm` 만 실어, 안 고른 벽(관 유입·유출부 기슭막이는 늘 빔)은
`variant_value=None` → B09 가 13-04-02/05 뒷길이 갈래(#35·55·75cm이하)를 못 고름. 그런데 수량표·
구조물도는 이미 품셈 13-4-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 as build_unit # noqa: E402
def _row(type_id: str, options: dict) -> dict:
unit = build_unit(
[
{
"structure_id": "x",
"type_id": type_id,
"start_m": 0.0,
"end_m": 10.0,
"options": options,
}
],
{type_id: type_id},
)
handoff = build_handoff(unit_quantity_table=unit)
return next(r for r in handoff["work_items"] if r["variant_axis"] == "back_len_cm")
def test_안_고른_뒷길이는_표준표_하한을_출처와_함께_보냄() -> None:
row = _row("masonry_wet", {"height_m": 1.5, "length_m": 10.0})
assert row["variant_value"] == "25", row # 찰쌓기 ≤1.5m 하한 25㎝
assert "뒷길이 25㎝" in row["spec_class_basis"] and "[주]⑩" in row["spec_class_basis"]
def test_고른_뒷길이는_원본값_그대로_출처는_저장_제원() -> None:
row = _row("masonry_wet", {"height_m": 1.5, "length_m": 10.0, "back_len_cm": "45"})
assert row["variant_value"] == "45"
assert "[주]⑩" not in row["spec_class_basis"] and "저장 제원" in row["spec_class_basis"]
def test_기슭막이_메쌓기도_하한으로_갈래가_서서_내역_금액이_섬() -> None:
from B09_Estimation.B09_Estimation_BillOfQuantities import build_bill
options = {"height_m": 2.5, "length_m": 10.0, "form": "돌쌓기(메)"}
row = _row("revetment", options)
assert row["variant_value"] == "45", row # 메쌓기 ~3m 하한 36 → 규격 45
assert row["work_item_code"] == "FP-13-04-02" and not row["blocked_kind"], row
unit = build_unit(
[{"structure_id": "x", "type_id": "revetment", "start_m": 0.0, "end_m": 10.0,
"options": options}],
{"revetment": "revetment"},
) # fmt: skip
bill = build_bill(build_handoff(unit_quantity_table=unit))
line = next(r for r in bill.rows if r.code == "FP-13-04-02")
assert line.amount_krw and int(line.amount_krw) > 0, line.note
assert line.price_code.endswith("#55cm이하"), line.price_code # 45㎝ 를 담는 가장 좁은 구간