From 8dd452d8f4d2481c5b5ec424d8771112978b2bb3 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 14 Sep 2026 17:24:32 +0900 Subject: [PATCH] =?UTF-8?q?fix(b08):=20=EA=B4=80=20=EB=B2=BD=C2=B7?= =?UTF-8?q?=EB=8F=8C=EC=8C=93=EA=B8=B0=20=EC=A4=84=20=EC=9D=B8=EA=B3=84?= =?UTF-8?q?=EC=97=90=20=EC=8B=A4=EC=A0=9C=EB=A1=9C=20=EC=93=B4=20=EB=92=B7?= =?UTF-8?q?=EA=B8=B8=EC=9D=B4=20+=20=EC=B6=9C=EC=B2=98=20=E2=80=94=20?= =?UTF-8?q?=EC=95=88=20=EA=B3=A0=EB=A5=B8=20=EB=B2=BD=EB=8F=84=20[?= =?UTF-8?q?=EC=A3=BC]=E2=91=A9=20=ED=91=9C=EC=A4=80=ED=91=9C=20=ED=95=98?= =?UTF-8?q?=ED=95=9C=20=EA=B0=92=EC=9C=BC=EB=A1=9C=2013-04-02/05=20?= =?UTF-8?q?=EA=B0=88=EB=9E=98=EB=A5=BC=20=EA=B3=A0=EB=A6=84=20=C2=B7=20?= =?UTF-8?q?=EA=B3=A0=EB=A5=B8=20=EA=B0=92=EC=9D=80=20=EC=9B=90=EB=B3=B8=20?= =?UTF-8?q?=EA=B7=B8=EB=8C=80=EB=A1=9C(=EC=B6=9C=EC=B2=98=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EC=A0=9C=EC=9B=90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 배정 프로젝트: 인계 줄 18(관 유입·유출부 기슭막이) 갈래 값·판정 근거만 바뀜 · 본체 105,512,060 그대로(모두 미확정) · 전체 1928 통과 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn --- .../B08_Quantity_Engine_Handoff_Rows.py | 9 +++ .../tester/test_b08_back_length_handoff.py | 66 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 resources/tester/test_b08_back_length_handoff.py diff --git a/B08_Quantity/B08_Quantity_Engine_Handoff_Rows.py b/B08_Quantity/B08_Quantity_Engine_Handoff_Rows.py index 6316ab95..1ad700ef 100644 --- a/B08_Quantity/B08_Quantity_Engine_Handoff_Rows.py +++ b/B08_Quantity/B08_Quantity_Engine_Handoff_Rows.py @@ -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 [] diff --git a/resources/tester/test_b08_back_length_handoff.py b/resources/tester/test_b08_back_length_handoff.py new file mode 100644 index 00000000..6ef22f21 --- /dev/null +++ b/resources/tester/test_b08_back_length_handoff.py @@ -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㎝ 를 담는 가장 좁은 구간