fix(B09): 「성분이 빠져 못 세움」을 「일위대가 없음」과 갈라 냄
메인 창이 물음 — 종단배수 셋이 같은 모양(밑수 1 m)인데 맹암거만 금액이 서고 산마루측구·소단측구는 안 서는 까닭 **표 성격이 달랐음** — 맹암거(F0345)는 수량이 실제로 적힌 소요량표라 자원 4줄이 붙어 25,492.1원/m 로 섬. 나머지 둘은 **수량 칸이 비어 있고 참조로만** 적힘 ``` FP-12-09-02 철근가공조립 | ton | (빈칸) | 「철근가공조립(간단)의 30%」 FP-12-09-03 거 푸 집 | 회 | (빈칸) ``` ⇒ 값을 지어낼 수 없어 **금액을 안 만드는 것이 맞음**(지금 방침 그대로) - 다만 화면 사유가 **「일위대가 없음」으로 뭉뚱그려지고** 있었음 — 「아직 안 만든 것」과 「성분이 빠져 못 세운 것」은 **할 일이 다름**. 사유를 갈라 적음: 「성분이 빠져 단가를 못 세웠습니다 — 철근가공조립 줄을 못 풀었습니다」 - `UnitPriceBuild.component_gaps` 로 자원 축의 사유를 화면까지 나름 - 짝 시험 — 성분 빠진 쪽은 금액 없음 + 사유 표시, **맹암거는 그대로 금액이 섬** 검증: pytest 213 통과(신규 1). 맹암거 40m × 25,492.1 = 1,019,685원 — 메인 값과 일치 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -208,8 +208,16 @@ def _leaf_row(
|
||||
row.note = f"이 공종엔 일위대가가 없고 한 층 아래에 있습니다 — 후보: {names}"
|
||||
reason = f"일위대가가 하위 공종에 있음(후보 {len(children)}건)"
|
||||
else:
|
||||
row.note = "일위대가가 아직 없습니다 — 금액을 0 으로 때우지 않습니다."
|
||||
reason = "일위대가 없음"
|
||||
# ⚠ 「아직 안 만든 것」과 「성분이 빠져 못 세운 것」은 **할 일이 다르다**.
|
||||
# 뭉뚱그리면 사용자가 무엇을 기다려야 하는지 못 읽는다(2026-09-08 산마루측구:
|
||||
# 표에 수량 칸이 비어 있고 「철근가공조립(간단)의 30 %」처럼 참조로만 적힌 자리).
|
||||
gap = unit_prices.component_gaps.get(node.code)
|
||||
if gap:
|
||||
row.note = f"성분이 빠져 단가를 못 세웠습니다 — {gap}"
|
||||
reason = f"성분 미확보 — {gap}"
|
||||
else:
|
||||
row.note = "일위대가가 아직 없습니다 — 금액을 0 으로 때우지 않습니다."
|
||||
reason = "일위대가 없음"
|
||||
result.missing.append(
|
||||
{
|
||||
"name": row.name,
|
||||
|
||||
@@ -78,6 +78,10 @@ class UnitPriceBuild:
|
||||
skipped: list[str] = field(default_factory=list)
|
||||
#: 기계 성분이 비어 있는 채로 쓰인 기종 (연료·조종원 미확보).
|
||||
incomplete_machines: list[str] = field(default_factory=list)
|
||||
#: 자원은 알아봤는데 **값을 못 읽은 줄**이 있어 단가를 못 세운 공종 — 사유 문구.
|
||||
#: ⚠ 일위대가가 **아예 안 선** 경우에도 남는다 — 「일위대가 없음」과 「성분이 빠져
|
||||
#: 못 세움」은 할 일이 다르므로 화면에서 갈라 보여야 한다(2026-09-08 산마루측구).
|
||||
component_gaps: dict[str, str] = field(default_factory=dict)
|
||||
#: 배분율 표인데 일부 몫만 붙은 공종 — 「단가가 일부만 섬」. 값은 붙은 몫(%).
|
||||
partial_ratio: dict[str, Decimal] = field(default_factory=dict)
|
||||
#: 시공능력 공식으로 장비 몫을 세운 공종 — 산출근거를 화면에 그대로 보인다.
|
||||
@@ -315,6 +319,7 @@ def build_unit_prices(axis: AxisResult | None = None) -> UnitPriceBuild:
|
||||
names = {w["work_item_code"]: w.get("name", "") for w in master.get("work_items", [])}
|
||||
|
||||
build = UnitPriceBuild()
|
||||
build.component_gaps = dict(axis.partial_items)
|
||||
missing_basis = load_basis_missing()
|
||||
wages = load_operator_wages()
|
||||
_add_labor_titles(build.book, wages)
|
||||
|
||||
Reference in New Issue
Block a user