Files
Aislo/resources/tester/test_799_1_subtotals.py
T
eomsangdonandClaude Opus 5.5 7480aebc96 feat(804-6): 옛 수식 탭 걷음 · 줄 쌓기 = 첫 「수식」 탭(요구 686-1)
- M01 단가산출 기초 · M02 단가산출 상세 보기 = 수식(줄 쌓기 · 기본) · 단가산출 상세 둘
- 줄 쌓기에 M02 사본 [단가 갱신] · [재생성](미리 셈 → 알림 → 저장 · 고침 있으면 막음) · 판 바뀜(409) 문서 그대로면 새 판으로 다시 저장 옮김
- 옛 수식 문서 화면 걷음(formula_doc_screen · defs · edit · lines · math · math_model · rows · sub · formula_doc.css) · 이미 안 부르던 796-2 수식 나무 화면(LogicLab_Equation · Defs · Var · css · M01_Logic_Equation_Model · sheet_formula_cell · ui_template_equation_defs · edit) 걷음 — 18 파일 4,860 줄
- formula_doc_render = 줄 쌓기가 쓰는 reach 만 · 옵션 가로 CSS 는 line_stack.css 로
- 남김 = 계산기 common_util_formula_doc* · 서버 길 · 옵션 · 사본 표지 · 합계 상자 · KaTeX · 시험 페이지 tools/line-stack-test
- 시험: test_796_2 지움(걷은 화면 원본 검사뿐) · 799_1 · 800_2 걷은 화면 줄만 뺌 · 799_2 · 802_4b2 · 804_2 보기 · 화면 파일 대상 바꿈 · test_804_6 새로(걷은 파일 · 부르는 곳 없음 · 첫 탭 · 사본 할일)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 11:09:44 +09:00

101 lines
3.2 KiB
Python

"""799-1 단가산출 소계 · 끝수 · 합계 지킴(보이기만 — 금액 셈은 그대로).
① 예시 셋 — 굴착기(블록 한 줄) · 거푸집(자원 + 덧줄) · 지게(자원) : 줄 합 + 끝수 = 합계(비목마다).
② 표본 — 호표 로직 여럿 : 합계 = 엔진 끝수 입힌 비목 합(전후 같음) · 줄 합 + 끝수 = 합계 · 결과 로직은 소계 없음.
③ 부품 짝 — `ui_template_equation_sum.ts` 가 서버 칸 이름을 그대로 읽음.
"""
from __future__ import annotations
import importlib
from decimal import Decimal as D
from pathlib import Path
from M01_MasterData import M01_MasterData_Store as store
mf = importlib.import_module("master_formula")
mcut = importlib.import_module("master_cut")
meq = importlib.import_module("master_equation")
COSTS = ("노무비", "재료비", "경비", "계")
def _whole():
return store.loaded()[1]
def _logics() -> list[dict]:
"""M01 로직 줄 전부(키 순)."""
w = _whole()
return [
r
for tid, rows in sorted(w.index.items())
if mf.mk.GROUP_OF.get(tid) == "로직"
for r in rows.values()
]
def _export(key: str) -> dict:
w = _whole()
return meq.export(w, key, meq.given_of(w, w.logic(key), None))
def _closes(eq: dict) -> None:
sub = eq["소계"]
for k in COSTS:
got = sum((r[k] for r in sub["줄"]), D(0)) + sub["끝수"][k]
assert got == eq["합계"][k], (eq["열쇠"], k, got, eq["합계"][k])
def test_굴착기_블록_한_줄_끝수():
eq = _export("GC001148")
rows = eq["소계"]["줄"]
assert [r["갈래"] for r in rows] == ["블록"] and rows[0]["이름"] == "굴착기(무한궤도)"
assert (rows[0]["노무비"], rows[0]["재료비"], rows[0]["경비"]) == (
D("437.1"),
D("88.2"),
D("116.0"),
)
assert eq["합계"]["계"] == D("641.0") and eq["소계"]["끝수"]["계"] == D("-0.3")
_closes(eq)
def test_거푸집_자원_덧줄_지게_자원():
eq = _export("GC000211")
assert [r["갈래"] for r in eq["소계"]["줄"]] == ["직접"] # 801-3 직접 줄 한 묶음
_closes(eq)
eq = _export("GC001140")
assert [r["갈래"] for r in eq["소계"]["줄"]] == ["직접"]
_closes(eq)
def test_표본_합계는_엔진_끝수_그대로():
w = _whole()
keys = [x["키"] for x in _logics() if x.get("호표")][::25]
assert keys, "표본 없음"
seen = 0
for key in keys:
try:
eq = _export(key)
except mf.FormulaError:
continue
if "소계" not in eq:
continue
seen += 1
_closes(eq)
raw = mf.run(w, key, meq.given_of(w, w.logic(key), None))
cut = mcut.engine(w, key, raw)
assert {k: eq["합계"][k] for k in COSTS} == {k: cut[k] for k in COSTS}, key
assert seen >= 10
def test_결과_로직은_소계_없음():
key = next(x["키"] for x in _logics() if "결과" in x)
assert "소계" not in _export(key)
def test_화면_부품이_서버_칸을_읽음():
ts = Path("ui_template/ui_template_equation_sum.ts").read_text(encoding="utf-8")
for name in ("노무비", "재료비", "경비", "끝수", "합계"):
assert name in ts