Files
Aislo/resources/tester/test_715_sangeun_engine.py
T
eomsangdonandClaude Opus 5.5 c60b87c111 feat(715-1b): 엔진 입력 덧칸 — 호표 줄 단가(손 단가) · 로직 줄 값묶음(노 · 재 · 경) · SK 고친 줄 셈 마무리
- master_pick — _priced 앞 「단가」 덧칸 = 손 단가(찾기 없음 · 출처 「손 단가」) · bundled(값묶음 셋 = 그것 · 일부 = 엔진 값 위 · 계 = 셋 합)
- master_formula — 로직 줄 묶음 부르는 줄 하나(mp.bundled) · 712-1 출력 묶음과 다른 이름
- M01 호표 5,266 줄에 덧칸 없음 · M01 1,469 로직 값 전후 같음
- 시험 test_715_sangeun_engine.py 다시 넣음(손 단가 · 3 % 다시 셈 · 값묶음 일부 · 참조 · 고정 더한줄)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 16:38:19 +09:00

87 lines
3.6 KiB
Python

# 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 labor._json(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)