From fdd781ca465315d323e55d5e9225d7576cdb9ee9 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sun, 1 Nov 2026 16:04:58 +0900 Subject: [PATCH] auto: 2026-11-01 16:04 (ESD_LAPTOP) --- resources/tester/test_715_sangeun_engine.py | 84 +++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 resources/tester/test_715_sangeun_engine.py diff --git a/resources/tester/test_715_sangeun_engine.py b/resources/tester/test_715_sangeun_engine.py new file mode 100644 index 000000000..e0c01a8e3 --- /dev/null +++ b/resources/tester/test_715_sangeun_engine.py @@ -0,0 +1,84 @@ +# ruff: noqa: F811 — 임시 층 fixture(world)를 test_m02_labor_ref 에서 받아 씀 +"""M02 단가산출(SK) 엔진 입력 덧칸(PLAN 715-1b · `master_pick` `단가` · `값묶음`) — 고친 줄 값 = 손셈. + +줄 단가 덮개 = 손 단가 · 로직 줄 노 · 재 · 경 덮개 = 값묶음(일부면 엔진 값 위) · 덧줄 % 가 덮인 값에서 +다시 셈 · 더한줄 참조(SK · SC) · 고정 = 먼저 셈한 1 단위 묶음. 덧칸 없는 줄 = 엔진 값 그대로. +""" + +from decimal import Decimal + +import pytest + +from M01_MasterData import M01_MasterData_Store as m01 +from M02_MasterTemplete import M02_Labor_Doc as labor +from M02_MasterTemplete import M02_Labor_Ref as refs +from M02_MasterTemplete import M02_MasterTemplete_Store as store +from M02_MasterTemplete import M02_Sangeun_Calc as calc +from resources.tester.test_m02_labor_ref import MINE, world # noqa: F401 — 같은 임시 층 + +PCT = "GC001109" # 원/㎡ · 인력 둘 + 「노무비 * 3 / 100」 +SUB = "GC000999" # 원/주 · 인력 둘 + 로직 줄(GC000275) + + +def _whole(): + return m01.loaded()[1] + + +def _run(**doc): + from M02_MasterTemplete import M02_Sangeun_Doc as sd + + whole = _whole() + clean = sd.clean({"키": "SK-000001", "이름": "시험", "단위": "㎡", **doc}, None, whole) + return calc.run(clean, whole) + + +def test_price_cover_is_hand_price_and_pct_follows(): + bare = labor.run_line(_whole(), PCT, {}) + first, second = bare["줄"][0], bare["줄"][1] + got = _run(바탕={"로직": PCT}, 덮개={"labor:LB000036#0": {"labor": 200000}}) + line = got["줄"][0] + assert line["단가"] == 200000 and line["출처"] == "손 단가" + want = Decimal(str(first["수량"])) * 200000 + Decimal(str(second["금액"])) + assert got["기준"]["노무비"] == pytest.approx(float(want)) + assert got["기준"]["경비"] == pytest.approx(float(want * 3 / 100), abs=1) + + +def test_bundle_cover_on_logic_line_partial(): + bare = labor.run_line(_whole(), SUB, {}) + sub = bare["줄"][2] + got = _run(바탕={"로직": SUB}, 덮개={"logic:GC000275#0": {"expense": 1000}}) + line = got["줄"][2] + qty = Decimal(str(sub["수량"])) + assert line["비목"]["경비"] == pytest.approx(float(qty * 1000)) + assert line["비목"]["노무비"] == pytest.approx(float(sub["비목"]["노무비"])) # 안 덮은 칸 = 엔진 값 + + +def test_untouched_lines_same_as_engine(): + bare = labor.run_line(_whole(), SUB, {}) + got = _run(바탕={"로직": SUB}) + assert got["기준"]["계"] == pytest.approx(float(bare["기준"]["계"])) + + +def test_added_ref_and_fixed_lines(world): + """더한줄 = SK 참조 2 · 고정 줄 1 — 값 = 2 × 그 SK 1 단위 + 고정 단가.""" + with store.at(world["personal"]): + sk = refs.create("sangeun", {"이름": "밑", "단위": "㎡", "바탕": {"로직": PCT}, "더한줄": []})[ + "이름" + ] + unit = calc.calc_doc(store.read("sangeun", sk)["문서"])["1단위"]["계"] + top = refs.create( + "sangeun", + { + "이름": "위", + "단위": "식", + "바탕": None, + "더한줄": [ + {"참조": {**MINE, "키": sk}, "수량": 2}, + {"고정": {"이름": "운반", "단위": "식", "단가": {"경비": 5000}}, "수량": 1}, + ], + }, + )["이름"] + got = calc.calc_doc(store.read("sangeun", top)["문서"]) + assert got["기준"]["계"] == pytest.approx(unit * 2 + 5000, abs=1) + expense = labor.run_line(_whole(), PCT, {})["기준"]["경비"] + assert got["기준"]["경비"] == pytest.approx(5000 + 2 * float(expense), abs=1)