Files
Aislo/resources/tester/test_183_b09_material_list.py
T
eomsangdonandClaude Opus 5.5 20f17827d3 feat(b09): 재료비목록표 = 쓰는 자재만 · 수량 = 역전개 총수량 · 비고 = 쓰는 곳 (183-1)
- 수요: 사본 일위대가 자재 · 굳힌 사전조합 자재 코드도(Linked.used_keys) → 대가 재료 줄 단가가 MT 줄에서 남
- 두 번 셈(Router.compute_twice): 1차 셈 → 대가 · 산근 · 중기 재료 줄 · B08 줄 · 관급 · 별도 줄만 남김(Summary.used_materials) · 1차 역전개 총수량 = material_qty → 2차 셈
- 수량 원천: Calc_Base 짝 material_sheet 가 material_qty(없는 키 빈칸) · 없으면 입력 줄 수량(거울)
- 화면: 비고 = 쓰는 곳(대가 · 산근 · 중기 n호표 · 내역 자재대) · 안내 글
- 실측 엄상준_검증: 141 → 24줄 · 목록 수량 = 재료비수량금액집계표 수량 · 목록표에 없음 0
- 시험: test_183_b09_material_list

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SE9MxeXTu2uaDZ55BJowAY
2026-10-10 11:57:14 +09:00

89 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""183-1 재료비목록표 = 연결된 일위대가 · 산근 · 중기가 쓰는 자재만 · 수량 · 단가 한 줄 · 쓰는 곳.
- 수요: 사본 일위대가 자재 · 굳힌 사전조합 자재 코드도 든다(`Linked.used_keys`)
- 거름: 대가 · 산근 · 중기 블록 재료 줄 · B08 줄 · 관급 · 별도 줄만 남김(`Summary.used_materials`)
- 수량 = 입력 `material_qty`(1차 역전개 총수량) — `Calc_Base` 짝 거울 · 두 번 셈(`Router.compute_twice`)
- 화면 비고 = 쓰는 곳(`UI_Tabs_Base.usesOf`)
"""
import json
from pathlib import Path
from B09_Estimation import B09_Estimation_Router as router_mod
from B09_Estimation.B09_Estimation_Calc_Base import compute_base
from B09_Estimation.B09_Estimation_Linked import used_keys
from B09_Estimation.B09_Estimation_Summary import used_materials
from resources.tester.test_144_b09_base_calc import _run_ts
ROOT = Path(__file__).resolve().parents[2]
MATERIALS = [
{"key": "MT1", "name": "쓰는 자재", "prices": {"물가자료": 1000}},
{"key": "MT2", "name": "고르기 후보", "prices": {"물가자료": 500}},
{"key": "MT3", "name": "관급 표시", "prices": {"물가자료": 300}},
{"key": "MO1", "name": "경유", "prices": {"유가": 1800}},
{"key": "b08:pipe_800", "name": "파형강관", "prices": {}, "qty": 8, "supply": "관급"},
]
USER = {"materials": {"MT3": {"supply": "관급"}}}
SG = [{"key": "SG1", "no": 1, "lines": [{"kind": "material", "ref": {"key": "MT1"}, "qty": 2}]}]
MACHINE = [{"key": "EQ1", "lines": [{"kind": "material", "ref": {"key": "MO1"}, "qty": None}]}]
def test_사본_일위대가_자재_사전조합_자재_코드도_수요(tmp_path):
labor = {
"줄": {"담은로직": [], "자재": [{"코드": "MT000053"}, {"코드": "PM000001"}]},
"참조사본": {"참조|system||SC-000001": {"담은로직": [], "자재": [{"코드": "MT000008"}]}},
}
(tmp_path / "일위대가.json").write_text(json.dumps(labor, ensure_ascii=False), "utf-8")
assert used_keys(tmp_path) == ["MT000053", "MT000008"] # 개인 자재(PM) = 원가 표 밖
def test_쓰는_자재만_남김():
sheets = {"sg": SG, "daega_blocks": [], "machine_blocks": MACHINE}
inputs = {"materials": MATERIALS}
assert used_materials(sheets, inputs, USER) == {"MT1", "MO1", "MT3", "b08:pipe_800"}
def test_수량_원천_material_qty_거울():
inputs = {"labor": [], "machines": [], "materials": MATERIALS}
old = {r["key"]: r["qty"] for r in compute_base(inputs, USER)["material"]}
assert old["b08:pipe_800"] == 8 and old["MT1"] is None # 없으면 입력 줄 수량(지금 길)
got = compute_base({**inputs, "material_qty": {"MT1": 6, "b08:pipe_800": 8}}, USER)
rows = {r["key"]: r for r in got["material"]}
assert (rows["MT1"]["qty"], rows["MT1"]["amount"]) == (6, 6000)
assert rows["MT2"]["qty"] is None and rows["MT2"]["amount"] is None # 없는 키 = 빈칸
for case in (inputs, {**inputs, "material_qty": {"MT1": 6}}):
assert _run_ts(case, USER) == compute_base(case, USER)
def test_두_번_셈_후보_줄_빠지고_수량_역전개(monkeypatch):
calls = []
def fake(root, inputs, user):
calls.append([m["key"] for m in inputs["materials"]])
base = compute_base(inputs, user)
bill = {"rows": [{"kind": "item", "qty": 3, "ref": {"tab": "sg", "key": "SG1"}}]}
return {**base, "sg": SG, "daega_blocks": [], "machine_blocks": MACHINE, "bill": bill}
monkeypatch.setattr(router_mod, "compute_sheets", fake)
inputs = {"labor": [], "machines": [], "materials": list(MATERIALS)}
sheets, summary = router_mod.compute_twice(Path("."), inputs, USER)
assert calls[0] == [m["key"] for m in MATERIALS]
assert calls[1] == ["MT1", "MT3", "MO1", "b08:pipe_800"] # 후보 MT2 뺌
assert inputs["material_qty"] == {"MT1": 6.0} # 설계내역서 3 × 호표 2
rows = {r["key"]: r for r in sheets["material"]}
assert (rows["MT1"]["qty"], rows["MT1"]["amount"]) == (6.0, 6000)
assert [r["qty"] for r in summary["sum_material"]] == [rows["MT1"]["qty"]] # 집계표와 같은 값
def test_화면_비고_쓰는_곳():
src = (ROOT / "B09_Estimation" / "B09_Estimation_UI_Tabs_Base.ts").read_text(encoding="utf-8")
for label in (
"`대가 ${b.no}호표`",
"`산근 ${b.no}호표`",
"`중기 ${n + 1}호표`",
'"내역 자재대"',
):
assert label in src
assert 'text("uses", "비고(쓰는 곳)"' in src and 'text("origin", "비고"' not in src