diff --git a/B08_Quantity/B08_Quantity_Engine_Handoff.py b/B08_Quantity/B08_Quantity_Engine_Handoff.py index b9eb7d51..46df17d7 100644 --- a/B08_Quantity/B08_Quantity_Engine_Handoff.py +++ b/B08_Quantity/B08_Quantity_Engine_Handoff.py @@ -583,13 +583,23 @@ def _haul_rows( return rows, unmatched -def blocked_of(structure: dict[str, Any], class_basis: str = "") -> tuple[str | None, str]: +def blocked_of( + structure: dict[str, Any], class_basis: str = "", has_code: bool = False +) -> tuple[str | None, str]: """(막힌 갈래, 사유). 안 막혔으면 `(None, "")`. ⚠ 사유 문구는 **`B08_Quantity_Wording` 것을 그대로** 쓴다 — 두 벌로 짜면 갈린다. 전개 알림(`notes`)에 이미 사람 말로 적혀 있으므로 그것을 그대로 옮긴다. + + ⚠⚠ **전개식이 없다고 다 막힌 것이 아니다** (2026-09-08 V-3 에서 드러남). + B군 종단배수(산마루측구 12-9-2 · 소단측구 12-9-3 · 맹암거 12-10)는 품셈 밑수가 + **1 m** 라 **연장이 곧 수량**이다 — 원단위 전개가 필요 없다. 그런데 「성분이 없으면 + 전개식 없음」으로 단정해 B09 가 **「우리가 만들 것」으로 빼 금액이 0** 이었다. + **공종코드가 붙었고 수량이 있으면 막힌 것이 아니다.** """ notes = [str(note) for note in structure.get("notes") or []] + if has_code and float(structure.get("length_m") or 0.0) > 0: + return None, "" if structure.get("components"): # 물량은 섰는데 **단가 갈래**를 못 고른 자리(돌쌓기 뒷길이 등). if class_basis and "입력되지 않았습니다" in class_basis: @@ -647,7 +657,7 @@ def _structure_rows( parts_missing: list[dict[str, Any]] = [] if composite: parts, parts_missing = composite_quantities(structure, composite, mapping) - blocked_kind, blocked_reason = blocked_of(structure, class_basis) + blocked_kind, blocked_reason = blocked_of(structure, class_basis, has_code=bool(code)) # 갈래 축과 **저장 제원 원본값**. 가공하지 않는다. variant_axis = str(entry.get("variant_axis") or "") or None variant_value = (structure.get("options") or {}).get(variant_axis) if variant_axis else None diff --git a/resources/data_work_item_mapping/work_item_mapping_2026-01-01.json b/resources/data_work_item_mapping/work_item_mapping_2026-01-01.json index 1463a427..c041c79a 100644 --- a/resources/data_work_item_mapping/work_item_mapping_2026-01-01.json +++ b/resources/data_work_item_mapping/work_item_mapping_2026-01-01.json @@ -150,6 +150,24 @@ }, "class_note": "메/찰(`bond`)은 **공종 자체가 갈리는 의미 판정**이라 여기서 고른다. 직경 갈래는 `variant_value` 로 원본값만 보낸다 — 원문이 물결표를 섞어 써서.", "variant_axis": "stone_cm" + }, + { + "type_id": "ditch_ridge", + "work_item_code": "FP-12-09-02", + "master_name": "측구 > 산마루 측구", + "note": "품셈 12-9-2 · 밑수 1 m — 구조물 연장(m)이 그대로 수량이다. 2026-09-08 V-3 확인에서 이었다(그전에는 매핑이 없어 연장은 오는데 공종코드가 비어 있었다)." + }, + { + "type_id": "ditch_berm", + "work_item_code": "FP-12-09-03", + "master_name": "측구 > 소단 측구", + "note": "품셈 12-9-3 · 밑수 1 m" + }, + { + "type_id": "underdrain", + "work_item_code": "FP-12-10", + "master_name": "맹암거", + "note": "품셈 12-10 · 밑수 1 m" } ], "pending_user": { @@ -171,6 +189,18 @@ "FP-09-05 발파암" ], "why": "설계자가 넣는 암 갈래 이름(풍화암·연암·보통암·경암)이 리핑이냐 발파냐를 말하지 않음. 갈래마다 시공법을 지정하는 칸이 필요함" + }, + { + "type_id": "chute", + "name": "도수로·산비탈수로", + "why": "품셈 12장 측구 계열(12-9-1 L형 · 12-9-2 산마루 · 12-9-3 소단)과 12-10 맹암거에 **해당 공종이 없음**(2026-09-08 마스터 전수). 「수로」로 검색해도 나오는 것은 그 셋뿐임.", + "needs": "어느 공종으로 볼지 사용자 확정 — 또는 별도 표준도·일위대가" + }, + { + "type_id": "slope_drain", + "name": "절토사면 배수로", + "why": "위와 같음 — 품셈에 그 이름의 공종이 없음.", + "needs": "어느 공종으로 볼지 사용자 확정" } ] },