fix(M01): 몫이 모두 0 인 장비 줄이 읽는 식에서 사라지던 것 — 0 원 한 줄과 까닭으로 남김

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgUhN55Z3BCYhUJTjwTNfj
This commit is contained in:
2026-09-21 19:58:04 +09:00
co-authored by Claude Opus 5
parent 9a938c0ab0
commit ce0529ff2c
3 changed files with 27 additions and 5 deletions
@@ -47,6 +47,10 @@
- `GC001091`·`GC001096` 진공흡입 준설차 13톤 · 물탱크(살수차) 5,500ℓ · `GC001092` 트럭탑재형 크레인 5톤 · `GC001099` 진공흡입 준설차 13톤
- `GF000137` 트럭 10.5ton · `GF000241` 굴착기(무한궤도) 0.6㎥
### 고친 뒤 (2026-09-21)
`master_text.py` 에 몫 나누기를 `_shares()` 한 자리로 모아, 몫이 전부 0 이면 첫 비목에 0 원 한 줄을 남기고 까닭(「수량 0 — 이 조건에서는 안 쓰는 줄」)을 붙임 — 같은 대조를 다시 돌려 **③ 어긋남 83줄 → 0** · 나머지(①②④·터짐)도 그대로 0(1,291개 전부).
## 딸린 사실
- 비목이 나뉜 하위 로직 줄은 비목마다 한 줄씩 같은 이름으로 나옴(계약대로 · 어긋남 아님).
+12 -5
View File
@@ -86,10 +86,10 @@ def _env_of(master, row: dict, given: dict, depth: int = 0) -> dict:
def _why(item: dict, line: dict) -> str:
"""단가를 못 구했거나 0 인 줄의 까닭 한 마디."""
if line["단가"] not in (0, None):
return ""
if line["수량"] == 0:
return "수량 0 — 이 조건에서는 안 쓰는 줄"
if line["단가"] not in (0, None):
return ""
where = item.get("요소")
where = "재료 고르기 조건" if isinstance(where, dict) else f"{where}"
return f"단가 0 — {where} 값이 아직 없음"
@@ -101,6 +101,15 @@ def _label(item: dict, line: dict) -> str:
return f"{name}({spec})" if spec else name
def _shares(line: dict) -> list[tuple[str, Decimal]]:
"""글로 적을 (비목, 몫) — 비목이 나뉜 로직 줄은 몫이 없는 비목을 건너뜀.
몫이 전부 0 이면 호표 줄이 사라지지 않게 첫 비목에 0 원 한 줄을 남김."""
parts = list(line["비목"].items())
if len(parts) <= 1:
return parts
return [(part, money) for part, money in parts if money != 0] or parts[:1]
def _line_text(item: dict, line: dict, env: dict, master, part: str | None) -> str:
"""「단가 * 수량식 = 금액」 — 비목이 나뉜 로직 줄은 그 비목 몫만."""
qty = render(mf.parse(item["수량"]), env, master)
@@ -134,9 +143,7 @@ def lines(files: dict, key: str, given: dict) -> dict:
env[""] = {r["이름"]: r["금액"] for r in shown if r["이름"]}
items = row.get("호표") or []
for item, line in zip(items, shown):
for part, money in line["비목"].items():
if money == 0 and len(line["비목"]) > 1:
continue # 비목이 나뉜 로직 줄 — 몫이 없는 비목엔 안 적음
for part, money in _shares(line):
split = part if len(line["비목"]) > 1 else None
one = {
"이름": _label(item, line),