- 표지 = 수식 문서 머리 · 옛 로직 줄 칸 「부품」 — 기계경비식 9 · 작업량 틀 60(기종 = 기계표 상세구분 · 규격 열쇠) · 계수식 4 · 변환기가 옮김 · 틀 문서 9 장 - 지움 = 작업량당 기계경비 6(GC001145 · 1148 · 1151 · 1156 · 1159 · 1166 · 부르는 곳 0 · 요구 734-4 · 735-4) — 수식 문서 · 옛 로직 · 키대장 폐기 칸 · 빌더 · 변수표 - 이름 꼬리 4 = 원문 제목(지게운반 · 인력운반(기계설비) · 벽돌운반 · 수중펌프 설치 및 해체) · 키 폐기 0 - 서버 = `M01_MasterData_Parts` — M01 `/logics` · M02 `/logic-lib/logics` 목록에서 부품 뺌(1,440) · 키로 열기 · 부르기 그대로 · `/m01/parts`(기종 계산식 · 틀 · 계수식) · `/m02/logic-lib/machine-parts` · 연결 찾기 과녁에서 부품 뺌(1,444 → 1,435 · 판정 코드 그대로) - 금액 전후 = 문서 1,513 · 셈 9,626(기본 + 옵션 표본) 모두 같음 · 791_1 지문 남은 1,513 같음 → 지문 다시 뜸 · 802_2 변환 대조 1,513 · 목록 xlsx 다시 씀(요약 수) - 낡은 시험 = 1,519 · 1,518 기대 → 1,513 · GC001148 견본 → 같은 꼴 GF000089 토사깍기(기계)(블록 Q 39.293 · 합계 2,190) · 지운 6 을 셈하던 줄 걷음 · 목록 수 1,440 · 묶음 328 · 부르는 수 507 - 새 지킴 시험 test_813_2_parts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
101 lines
3.2 KiB
Python
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("GF000089")
|
|
rows = eq["소계"]["줄"]
|
|
assert [r["갈래"] for r in rows] == ["블록"] and rows[0]["이름"] == "굴착기(무한궤도) 0.7㎥"
|
|
assert (rows[0]["노무비"], rows[0]["재료비"], rows[0]["경비"]) == (
|
|
D("901.2"),
|
|
D("665.0"),
|
|
D("624.8"),
|
|
)
|
|
assert eq["합계"]["계"] == D("2190.0") and eq["소계"]["끝수"]["계"] == D("-1.0")
|
|
_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
|