136 lines
6.2 KiB
Python
136 lines
6.2 KiB
Python
# ruff: noqa: F811 — 임시 층 fixture(world)를 test_m02_labor_ref 에서 받아 씀
|
|
"""일위대가 · 사전조합 줄 덮개 · [단가산출로 저장] · 단위 빈칸 막기(PLAN 715-3) — 임시 storage.
|
|
|
|
줄 덮개 = 그 줄에만(단가산출 원본 그대로) · 값 = 같은 덮개 SK 값 = 손셈 ·
|
|
줄 고름(차례)이 뺀줄 뒤 제자리 ·
|
|
[단가산출로 저장] = 새 SK + 참조 줄 · 같은 값 · 단위 빈칸 400 · 덮개 없는 줄 = 옛 값.
|
|
"""
|
|
|
|
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" # 원/㎡ · 인력 둘(LB000036 · LB000002) + 「노무비 * 3 / 100」
|
|
TWO_MATS = "GC000565" # 원/m · 재료 줄 둘
|
|
COVER = {"덮개": {"labor:LB000036#0": {"qty": 0.5}}}
|
|
|
|
|
|
def _whole():
|
|
return m01.loaded()[1]
|
|
|
|
|
|
def _sc(folder, lines, unit="㎡"):
|
|
with store.at(folder):
|
|
return refs.create("precombo", {"이름": "조합", "단위": unit, "담은로직": lines})["이름"]
|
|
|
|
|
|
def _value(folder, key):
|
|
with store.at(folder):
|
|
return refs.Expand(_whole())({**MINE, "키": key})
|
|
|
|
|
|
def test_logic_line_cover_in_precombo(world):
|
|
"""사전조합 로직 줄 덮개 = 같은 덮개 SK 값 · 손셈(품 0.5 × 단가 + 둘째 줄 · 3 % 덧줄)."""
|
|
bare = labor.run_line(_whole(), PCT, {})
|
|
sc = _sc(world["personal"], [{"로직": PCT, "패치": COVER}])
|
|
with store.at(world["personal"]):
|
|
kept = store.read("precombo", sc)["문서"]["담은로직"][0]
|
|
assert kept["패치"] == COVER
|
|
got = _value(world["personal"], sc)["기준"]
|
|
labor_sum = Decimal("0.5") * Decimal(str(bare["줄"][0]["단가"])) + Decimal(
|
|
str(bare["줄"][1]["금액"])
|
|
)
|
|
assert got["노무비"] == pytest.approx(labor_sum)
|
|
assert got["경비"] == pytest.approx(labor_sum * 3 / 100, abs=1)
|
|
|
|
|
|
def test_line_pick_by_order_stays_after_drop(world):
|
|
"""줄 고름 = 바탕 호표 차례(2) · 패치 뺀줄로 첫 재료 줄을 빼도 그 자재가 그 줄에."""
|
|
import master_pick as mp
|
|
|
|
whole = _whole()
|
|
row = whole.logic(TWO_MATS)
|
|
item = row["호표"][2]
|
|
want = mp.search(whole, item["요소"], {}, item.get("단위"))[1]
|
|
one = {
|
|
"로직": TWO_MATS,
|
|
"고름": {"2": want},
|
|
"자재표시": {"2": {"별도계상": "직접계산"}},
|
|
"패치": {"뺀줄": ["material:" + row["호표"][1]["이름"] + "#0"]},
|
|
}
|
|
with store.at(world["personal"]):
|
|
doc = labor.clean({"담은로직": [one]})
|
|
got = labor.calc(doc, {})["줄"][0]
|
|
picked = [x for x in got["줄"] if x.get("품목")]
|
|
assert [x["품목"]["키"] for x in picked] == [want]
|
|
|
|
|
|
def test_ref_line_cover_only_that_line(world):
|
|
"""SK 참조 줄 덮개 = 그 줄만 · SK 원본 · 다른 줄 값 그대로."""
|
|
with store.at(world["personal"]):
|
|
sk = refs.create(
|
|
"sangeun", {"이름": "밑", "단위": "㎡", "바탕": {"로직": PCT}, "더한줄": []}
|
|
)["이름"]
|
|
before = store.read("sangeun", sk)["판"]
|
|
ref = {**MINE, "키": sk}
|
|
sc = _sc(
|
|
world["personal"],
|
|
[{"참조": ref, "수량": {"손": 1}, "패치": COVER}, {"로직": "GC001111", "수량": {"손": 1}}],
|
|
)
|
|
inner = _value(world["personal"], sc)["안"]
|
|
plain = _value(world["personal"], _sc(world["personal"], [{"참조": ref}]))["기준"]
|
|
covered = calc.calc_doc(
|
|
{"키": "SK-000999", "이름": "x", "단위": "㎡", "바탕": {"로직": PCT}, **COVER}
|
|
)
|
|
assert inner[0]["기준"]["계"] == pytest.approx(Decimal(str(covered["1단위"]["계"])))
|
|
assert inner[0]["기준"]["계"] != plain["계"]
|
|
with store.at(world["personal"]):
|
|
assert store.read("sangeun", sk)["판"] == before
|
|
|
|
|
|
def test_save_as_sangeun(world):
|
|
"""[단가산출로 저장] — 새 SK(바탕 · 입력값 · 고름 cid · 덮개) · 참조 줄 · 같은 1 단위 값."""
|
|
one = {"로직": PCT, "패치": COVER, "수량": {"손": 2}, "별칭": "내 줄"}
|
|
with store.at(world["personal"]):
|
|
line_value = labor.calc(labor.clean({"담은로직": [one]}), {})["줄"][0]["기준"]
|
|
got = calc.from_line(one, "줄로 만든", "㎡")
|
|
doc = store.read("sangeun", got["이름"])["문서"]
|
|
value = calc.calc_doc(doc)["기준"]
|
|
assert got["줄"] == {"참조": {**MINE, "키": got["이름"]}, "수량": {"손": 2}, "별칭": "내 줄"}
|
|
assert doc["바탕"] == {"로직": PCT} and doc["덮개"]["labor:LB000036#0"]["qty"] == 0.5
|
|
assert value["계"] == pytest.approx(line_value["계"])
|
|
|
|
|
|
def test_refusals(world):
|
|
with store.at(world["personal"]):
|
|
with pytest.raises(store.StoreError, match="단위가 빔"):
|
|
refs.create("precombo", {"이름": "x", "단위": " ", "담은로직": [{"로직": PCT}]})
|
|
assert refs.create("precombo", {"이름": "빈 새 문서", "단위": None, "담은로직": []})["이름"]
|
|
bad = {"로직": PCT, "패치": {"더한줄": [{"참조": {**MINE, "키": "SK-000001"}, "수량": 1}]}}
|
|
with pytest.raises(store.StoreError, match="참조 못 넣음"):
|
|
labor.clean({"담은로직": [bad]})
|
|
with pytest.raises(store.StoreError, match="수가 아님"):
|
|
labor.clean(
|
|
{"담은로직": [{"로직": PCT, "패치": {"덮개": {"labor:LB000036#0": {"qty": "식"}}}}]}
|
|
)
|
|
sc = _sc(world["personal"], [{"로직": PCT}])
|
|
with pytest.raises(store.StoreError, match="줄 덮개는"):
|
|
labor.clean({"담은로직": [{"참조": {**MINE, "키": sc}, "패치": COVER}]})
|
|
|
|
|
|
def test_no_patch_same_value(world):
|
|
"""덮개 없는 줄 = run_line 값 그대로(옛 셈 길)."""
|
|
sc = _sc(world["personal"], [{"로직": PCT, "패치": {}}])
|
|
with store.at(world["personal"]):
|
|
assert "패치" not in store.read("precombo", sc)["문서"]["담은로직"][0]
|
|
assert _value(world["personal"], sc)["기준"]["계"] == pytest.approx(
|
|
labor.run_line(_whole(), PCT, {})["기준"]["계"]
|
|
)
|