diff --git a/B09_Estimation/B09_Estimation_BillOfQuantities_Rows.py b/B09_Estimation/B09_Estimation_BillOfQuantities_Rows.py index 19ec51ac..bcf9bb38 100644 --- a/B09_Estimation/B09_Estimation_BillOfQuantities_Rows.py +++ b/B09_Estimation/B09_Estimation_BillOfQuantities_Rows.py @@ -307,6 +307,13 @@ def _leaf_row( ) return row + # ⚠ **수량이 미확정 산식 위에 서 있는 줄**은 금액과 함께 그 사실을 싣는다. + # 금액이 커질수록 더 그렇다 — 지금 구조물터파기가 내역서에서 가장 큰 줄인데 + # 그 밑수가 사용자 확정을 기다리고 있다(계획서 4-12 3단계). + pending = pending_formula_note(node.code) + if pending: + row.note = " / ".join(part for part in (row.note, pending) if part) + # 쓰인 차례를 기억한다 — 실무 참조번호(「단산 46」)가 그 차례다. if price_code not in result.used_unit_prices: result.used_unit_prices.append(price_code) @@ -323,6 +330,41 @@ def _leaf_row( return row +#: 수량 산식이 **사용자 확정을 기다리는** 공종 — 금액은 세우되 그 사실을 함께 싣는다. +#: +#: ⚠ **값을 우리가 바꾸지 않는다.** 실무 시트와 어긋나는 것이 확인됐을 뿐이고, 어느 쪽으로 +#: 갈지는 설계 판단이다(계획서 4-12 3단계, 확정 대기). +#: 돌쌓기(찰) H=2.0·ℓ3=45 · m당 기준으로 실무 대비 +#: 터파기 실무 0.35 우리 2.30 (약 6.6배) — 실무는 기초만(기초폭 × 깊이 0.3), +#: 우리는 벽 전체를 센다 +#: 되메우기 실무 0.185 우리 0.40 · 잔토정리 실무 0.165 우리 1.90 (위 둘의 차) +_PENDING_FORMULA: dict[str, str] = { + "FP-09-13": ( + "⚠ 터파기 수량 산식이 확정 대기입니다 — 실무 시트는 기초만(기초폭 × 깊이 0.3) 세고 " + "우리는 벽 전체를 셉니다(m당 실무 0.35 vs 우리 2.30, 약 6.6배). 실무 식으로 확정되면 " + "이 줄 금액이 약 1/6.6 로 줄어듭니다." + ), + "FP-09-14": ( + "⚠ 되메우기 수량 산식이 확정 대기입니다 — 터파기와 같은 뿌리입니다" + "(m당 실무 0.185 vs 우리 0.40)." + ), + "FP-09-15": ( + "⚠ 잔토처리 수량 산식이 확정 대기입니다 — 터파기·되메우기의 차라 같은 뿌리입니다" + "(m당 실무 0.165 vs 우리 1.90)." + ), +} + + +def pending_formula_note(code: str | None) -> str: + """그 공종의 수량 산식이 확정 대기인가 — 맞으면 실을 문구.""" + if not code: + return "" + for prefix, note in _PENDING_FORMULA.items(): + if str(code).startswith(prefix): + return note + return "" + + def _material_row(material: HandoffMaterial, result: BillResult) -> BillRow: """자재 한 줄. 공급 구분이 안 갈렸으면 **어느 쪽에도 안 넣는다**.""" row = BillRow( diff --git a/B09_Estimation/B09_Estimation_UnitPrice.py b/B09_Estimation/B09_Estimation_UnitPrice.py index 35b78bd5..79921d94 100644 --- a/B09_Estimation/B09_Estimation_UnitPrice.py +++ b/B09_Estimation/B09_Estimation_UnitPrice.py @@ -306,6 +306,25 @@ def normalize_variant_key(text: str) -> str: return "".join("~" if ch in _TILDE_CHARS else ch for ch in tight) +#: 갈래 이름이 **축이 달라 다르게 불리는** 자리 — 이름을 갈지 않고 여기서 잇는다. +#: +#: ⚠ **우리 축과 품셈 축이 다르다.** 우리 「리핑암」은 B05·B06 의 **지반유형**(캘 수 있는가)이 +#: 낳은 이름이고, 품셈 운반표의 「파쇄암」은 **운반할 때의 상태**(부서졌는가)를 가리킨다. +#: 그래서 일반적으로는 「리핑암 = 파쇄암」이 아니다 — **발파암도 캐고 나면 파쇄암 상태**다 +#: (건설품셈 8장 「발파 또는 리퍼작업 등에 의하여 얻어진 암과 파쇄암…」). +#: +#: ⭐ **다만 이 표 안에서는 성립한다.** 산림품셈 10-11 f 표가 **토사·파쇄암·발파암을 따로** +#: 두었으므로 그 표의 「파쇄암」은 **발파를 뺀 나머지 = 리퍼로 얻은 것**이다. 결정적 증거는 +#: 10-12 [주]③ 이다 — 「적재 재료의 토량환산계수(L)는 토사 1.3, **암절취 1.35**, 발파암 +#: 1.625 적용한다」. 10-11 f 표의 **파쇄암이 1/1.35** 라 **암절취(리핑)과 같은 값**이다. +#: +#: ⚠ **어느 쪽 이름도 갈지 않는다** — 우리 이름을 갈면 B05·B06 이 깨지고, 품셈 이름을 갈면 +#: 원문과 어긋난다. 잇는 자리는 여기 한 곳뿐이다. +VARIANT_ALIASES: dict[str, str] = { + "리핑암": "파쇄암", +} + + def find_variant_code( work_item_code: str, variant_value: str, @@ -320,6 +339,7 @@ def find_variant_code( wanted = normalize_variant_key(variant_value) if not wanted: return None + wanted = VARIANT_ALIASES.get(wanted, wanted) prefix = f"B-{work_item_code}#" candidates = [code for code in prices.book.titles if code.startswith(prefix)]