"""712-1 지킴 — 인력 · 재료 · 경비 묶음 셈 때 파생 · 기계경비 판별 한 곳(`master_bundle`).""" from __future__ import annotations import sys from decimal import Decimal from pathlib import Path ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(ROOT / "resources/master_data/scripts")) sys.path.insert(0, str(ROOT)) import check_master as cm # noqa: E402 import master_auto as mau # noqa: E402 import master_bundle as mb # noqa: E402 import master_formula as mf # noqa: E402 FILES = cm.load() MASTER = mf.Master(FILES) LOGICS = {r["키"]: r for d in FILES.values() if d.get("그룹") == "로직" for r in d.get("줄") or []} def test_every_line_bundled(): """호표 · 덧줄 전수 — 하위(못 가름) ≤ 31 · 나머지는 인력 · 재료 · 경비 · 기계경비 줄 = 경비.""" count = dict.fromkeys(mb.BUNDLES, 0) machine = 0 for row in LOGICS.values(): for item in [*row.get("호표", []), *row.get("덧줄", [])]: name, is_mach = mb.bundle(MASTER, item) count[name] += 1 machine += is_mach if is_mach: assert name == "경비" assert sum(count.values()) > 5_000 assert count["하위"] <= 31, count assert machine >= 1_000, machine def test_machine_rule_one_place(): """기계경비 = 결과단위 원/시간 돈 로직 — 작업량(㎥/시간) · 이름 「시간당」 은 아님.""" machines = {k for k, r in LOGICS.items() if mb.is_machine(r)} assert {"GC000267", "GC000268", "GF000145"} <= machines assert not machines & {"GF000102", "GC000422", "GC000260"} # 작업량 · ㎡/시간 · 원/㎡ sys.path.insert(0, str(ROOT)) from M02_MasterTemplete import M02_Hopyo_Ours as ours assert all(ours.is_mach_logic(r) == mb.is_machine(r) for r in LOGICS.values()) def test_run_lines_tagged(): """엔진 `run` 줄마다 `묶음` · 기계경비 줄은 `장비` + 비목 노 · 재 · 경 세 몫.""" seen = set() for key in ("GF000169", "GF000103"): row = LOGICS[key] given = {k: v for k, v in mau.values(MASTER, row).items() if v is not None} got = mf.run(MASTER, key, given) for line in got["줄"]: assert line["묶음"] in mb.BUNDLES seen.add(line["묶음"]) if line.get("장비"): assert set(line["비목"]) == set(mf.COST_ITEMS) total = sum((line["비목"].get(k) or Decimal(0)) for line in got["줄"] for k in line["비목"]) assert abs(total - got["계"]) < 1 assert {"인력", "재료", "하위"} <= seen