Merge remote-tracking branch 'origin/dev' into sub_laptop_1

This commit is contained in:
2026-09-14 12:38:19 +09:00
2 changed files with 43 additions and 2 deletions
@@ -283,8 +283,16 @@ def expand_observed(
source_key = str(found.get("source") or "")
options = structure.get("options") or {}
components: list[dict[str, Any]] = []
blocked: list[str] = []
for item in found.get("components") or []:
note = str(item.get("basis_note") or "")
if not item.get("destination"):
# ⛔ 갈 곳 기본값 금지(명세 13장) — 종전 `or "material"` 은 줄이 늘 때 조용히 자재로 샘.
blocked.append(
f"{item['name']}」 관측 원단위 줄에 갈 곳이 없어 물량을 어느 축에도 안 보냄"
" — 표(`structure_unit_observed`)에 적을 것(명세 13장 갈 곳 기본값 금지)"
)
continue
weep = (
weep_component(found, options, scale, scale_note)
if item["name"] == "물구멍관"
@@ -298,7 +306,7 @@ def expand_observed(
"name": item["name"],
"unit": item["unit"],
"amount": float(item["amount"]) * scale,
"destination": item.get("destination") or "material",
"destination": item["destination"],
# 근거를 값 옆에 붙인다 — 관측값임을 화면·인계에서 바로 알아야 한다.
"basis": f"관측 원단위 {item['amount']:g}/{found.get('unit')} × {scale_note}"
+ (f" ({note})" if note else ""),
@@ -308,7 +316,7 @@ def expand_observed(
"spec": str(item.get("spec") or ""),
}
)
notes = [f"관측 원단위 적용 — {found.get('source_note') or source_key}"]
notes = [f"관측 원단위 적용 — {found.get('source_note') or source_key}", *blocked]
# 줄에 붙은 사유(원문끼리 다름 등) — 구조물도 그림도 같은 글자를 씀.
notes.extend(str(note) for note in found.get("notes") or [])
earthwork_note = earthwork_missing_note(found)
@@ -53,3 +53,36 @@ def test_드러난_넷이_제자리로_감() -> None:
sod, sod_notes = soil_guard({"form": ""})
assert {c.name: c.destination for c in sod}[""] == "material"
assert not [note for note in sod_notes if "갈 곳이 표" in note]
def test_관측_원단위_줄도_갈_곳이_없으면_막히고_사유() -> None:
"""관측 원단위 로더의 `destination or "material"` 도 같은 병 — 줄이 늘 때 바로 드러나게."""
from B08_Quantity.B08_Quantity_Engine_ObservedUnit import ObservedUnitTable, expand_observed
table = ObservedUnitTable(
entries=[
{
"type_id": "시험구조물",
"unit": "개소",
"components": [
{"name": "콘크리트", "unit": "", "amount": 1.0, "destination": "unit_price"},
{"name": "새자재", "unit": "", "amount": 2.0},
],
}
]
)
components, notes = expand_observed("시험구조물", {}, {"options": {}}, table)
assert [c["name"] for c in components] == ["콘크리트"]
assert any("새자재" in note and "기본값 금지" in note for note in notes)
def test_관측_원단위_표의_전_줄에_갈_곳이_있음() -> None:
from B08_Quantity.B08_Quantity_Engine_ObservedUnit import load_observed_table
missing = [
(entry.get("type_id"), item.get("name"))
for entry in load_observed_table().entries
for item in entry.get("components") or []
if not item.get("destination")
]
assert missing == []