"""166-3 재료비목록표 = B08 총괄 합계 × 적용 단가 = 총액 ROUND 0 · 공제 거름 · MT 합침 · 거울.""" import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[2] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) from B09_Estimation import B09_Estimation_Prices as prices # noqa: E402 from B09_Estimation.B09_Estimation_Calc_Base import compute_base # noqa: E402 from resources.tester.test_144_b09_base_calc import _run_ts # noqa: E402 MATERIALS = [ {"key": "MT1", "name": "부직포", "prices": {"물가자료": 1234.5}, "qty": 10.25}, {"key": "MT2", "name": "수량 없는 사본 줄", "prices": {"물가자료": 500}}, {"key": "b08:cement", "name": "시멘트", "prices": {}, "qty": 3.333}, {"key": "b08:sand", "name": "모래", "prices": {}, "qty": 7}, ] INPUTS = {"labor": [], "machines": [], "materials": MATERIALS} USER = {"materials": {"b08:cement": {"applied": 7000.5}}} def test_총액_ROUND_0_빈칸(): rows = {r["key"]: r for r in compute_base(INPUTS, USER)["material"]} assert (rows["MT1"]["qty"], rows["MT1"]["price"], rows["MT1"]["amount"]) == ( 10.25, 1234.5, 12654, ) # 12,653.6 → 반 올림 assert rows["b08:cement"]["amount"] == 23333 # 3.333 × 7000.5 = 23,332.67 assert rows["MT2"]["qty"] is None and rows["MT2"]["amount"] is None # 수량 빈칸 assert rows["b08:sand"]["price"] is None and rows["b08:sand"]["amount"] is None # 단가 빈칸 def test_거울_TS(): for user in ({}, USER): assert _run_ts(INPUTS, user) == compute_base(INPUTS, user) def test_공제_거름_MT_합침(monkeypatch): sheets = { "material": { "rows": [ {"key": "cement", "group": "시멘트", "unit": "포", "amount": 12.5}, {"key": "picked_deduct", "group": "채집석 공제", "unit": "㎥", "amount": 4}, {"key": "MT1", "group": "부직포", "unit": "㎡", "amount": 30.1}, {"key": "MT9", "group": "사본에 없는 MT", "unit": "개", "amount": 2}, {"key": "empty", "group": "수량 없음", "amount": None}, ] } } keys = [r["key"] for r in prices.b08_material_rows(sheets)] assert keys == ["b08:cement", "b08:MT1", "b08:MT9"] monkeypatch.setattr(prices, "_master", lambda: None) monkeypatch.setattr( prices, "demand", lambda master, keys: {"labor": [], "machines": [], "materials": ["MT1", "MO1"], "fuel_keys": {}, "missing": []}, ) # fmt: skip book = {"rows": {"MT1": {"key": "MT1", "name": "부직포"}, "MO1": {"key": "MO1"}}} got = prices.build_inputs(book, [], sheets)["materials"] assert [r["key"] for r in got] == ["MT1", "MO1", "b08:cement", "b08:MT9"] assert got[0]["qty"] == 30.1 and "qty" not in book["rows"]["MT1"] # 책은 안 바꿈 assert got[2]["qty"] == 12.5 def test_167_2_B08_답_한_층_아래_총괄_줄(monkeypatch): """B08 길 답 = {source, sheets: {material: {rows}}} — sheets 를 읽어야 총괄 줄이 들어옴.""" import asyncio from B09_Estimation import B09_Estimation_Router as router_mod rows = [ {"key": "pipe_1200", "group": "파형강관", "spec": "Φ1200mm", "unit": "m", "amount": 7}, { "key": "coupling_1200", "group": "커플링밴드", "spec": "Φ1200mm", "unit": "개", "amount": 0, }, {"key": "합판(준내수)|㎡", "group": "합판(준내수)", "unit": "㎡", "amount": 7}, {"key": "picked_deduct", "group": "채집석 공제", "amount": None}, ] async def materials(_pid): return {"source": {"columns": []}, "notes": [], "sheets": {"material": {"rows": rows}}} async def earthwork(_pid): return None monkeypatch.setattr(router_mod, "material_sheets", materials) monkeypatch.setattr(router_mod, "earthwork_table", earthwork) b08 = asyncio.run(router_mod._b08(None, [])) assert b08["summary"] == {"columns": []} got = prices.b08_material_rows(b08["materials"]) assert [(r["key"], r["qty"], r.get("supply")) for r in got] == [ ("b08:pipe_1200", 7, "관급"), ("b08:coupling_1200", 0, None), ("b08:합판(준내수)|㎡", 7, None), ] s = compute_base({"labor": [], "machines": [], "materials": got}, USER_PIPE) rows_out = {r["key"]: r for r in s["material"]} assert rows_out["b08:pipe_1200"]["supply"] == "별도" # 사용자 표시가 앞섬 plain = compute_base({"labor": [], "machines": [], "materials": got}, {}) assert plain["material"][0]["supply"] == "관급" # 파형강관 기본 = 관급 assert rows_out["b08:합판(준내수)|㎡"]["amount"] == 7 * 12000 assert rows_out["b08:coupling_1200"]["price"] is None # 단가 없음 = 빈칸(견적 칸으로) assert _run_ts({"labor": [], "machines": [], "materials": got}, USER_PIPE) == s USER_PIPE = {"materials": {"b08:합판(준내수)|㎡": {"quote": 12000}, "b08:pipe_1200": {"supply": "별도"}}} # fmt: skip