- 묶음 한 곳 master_equation_group.bundles: 부른 · 더한 단가산출 하나씩 + 직접 줄(인력 · 재료 · 기계 · 덧줄) 한 묶음 · 돈 없는 줄 · 뺀 줄 = 묶음 아님 · 합계 밖 줄 = 밖 글 - M01 subtotals · M02 M02_Sangeun_Equation_Full 같은 꼴 · 끝수 셈 그대로 · 금액 전후 같음 - 부품 ui_template_equation_sum: 자기 자원 · 덧줄 글 0 · 묶음 하나 = 머리 없음 · 계 · 둘 이상 = 가. 머리 · 소 계 · 단가산출 둘 이상 = 합계 - 옛 시험 기대 고침: test_799_1(갈래 자원 · 덧줄 → 직접 한 묶음) · test_796_2c(줄마다 한 행 → 묶음 · 낱줄 · 밖) — 묶음 꼴이 바뀜 - 새 test_801_3_groups 5 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
69 lines
2.8 KiB
Python
69 lines
2.8 KiB
Python
"""수식 탭 소계 묶음(PLAN 801-3 · 요구 662-3) — 돈 묶음 한 곳 · M01(`master_equation`) · M02(`M02_Sangeun_Equation_Full`) 같은 꼴.
|
|
|
|
묶음 = 부른 · 더한 단가산출(갈래 블록) 하나씩 + 직접 줄(인력 · 재료 · 기계 · 덧줄 · 율) 전부 한 묶음(갈래 직접).
|
|
돈 없는 줄(계 0 · 바탕) · 뺀 줄 = 묶음 아님(식 줄로만 보임) · 합계 밖 줄 = `밖` 으로만.
|
|
머리 · 소계 · 합계 · 계 글자 판정 = 화면 부품(`ui_template_equation_sum.ts`) — 묶음 둘 이상 = 머리 · 소계 ·
|
|
단가산출(블록) 둘 이상 = 합계 · 아니면 계.
|
|
시험 `resources/tester/test_801_3_groups.py`.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from decimal import Decimal
|
|
|
|
COSTS = ("노무비", "재료비", "경비")
|
|
_WORDS = ("인력", "재료", "기계") # 직접 묶음 이름 차례
|
|
|
|
|
|
def _zero(row: dict) -> bool:
|
|
"""돈 없는 바탕 줄 · 뺀 줄 — 묶음 아님."""
|
|
if row.get("상태") == "뺌":
|
|
return True
|
|
return row["계"] == 0 and row.get("상태") in (None, "바탕")
|
|
|
|
|
|
def _name(direct: list[dict]) -> str:
|
|
"""직접 묶음 이름 — 자원 갈래 말(인력 · 재료 · 기계) · 율 줄 = 이름 (율 %) · 덧줄뿐 = 비목 말."""
|
|
words = [w for w in _WORDS if any(r.get("종류") == w for r in direct)]
|
|
words += [
|
|
f"{r['이름']} ({r['수량']}%)" if r.get("수량") not in (None, "") else str(r["이름"])
|
|
for r in direct
|
|
if r["갈래"] == "율"
|
|
]
|
|
if not words:
|
|
words = [k for k in COSTS if any(r[k] != 0 for r in direct)]
|
|
return " · ".join(words)
|
|
|
|
|
|
def bundles(rows: list[dict]) -> dict:
|
|
"""줄(갈래 블록 | 자원 | 덧줄 | 율 · 비목 칸 · 계) → `{줄: 묶음들, 밖: 합계 밖 줄들}` — 금액은 더하기만(셈 안 바꿈)."""
|
|
blocks: list[dict] = []
|
|
direct: list[dict] = []
|
|
out: list[dict] = []
|
|
for row in rows:
|
|
if row.get("합밖"):
|
|
out.append({"이름": row["이름"], "밖금액": row.get("밖금액")})
|
|
elif _zero(row):
|
|
continue
|
|
elif row["갈래"] == "블록":
|
|
blocks.append(row)
|
|
else:
|
|
direct.append(row)
|
|
lines = list(blocks)
|
|
if direct:
|
|
one = {
|
|
"갈래": "직접",
|
|
"이름": _name(direct),
|
|
**{k: sum((r[k] for r in direct), Decimal(0)) for k in COSTS},
|
|
}
|
|
one["계"] = sum((one[k] for k in COSTS), Decimal(0))
|
|
mine = [ # 더한 · 덮은 줄 — 묶음 속에 한 줄씩(고친 줄을 숨기지 않음)
|
|
{k: r[k] for k in ("이름", "상태", "계", "원래") if r.get(k) is not None}
|
|
for r in direct
|
|
if r.get("상태") in ("더함", "덮음")
|
|
]
|
|
if mine:
|
|
one["낱줄"] = mine
|
|
lines.append(one)
|
|
return {"줄": lines, "밖": out}
|