Merge remote-tracking branch 'origin/sub_laptop_7' into sub_laptop_1

This commit is contained in:
2026-10-05 20:31:15 +09:00
3 changed files with 102 additions and 35 deletions
+49 -1
View File
@@ -95,7 +95,9 @@ def test_사전조합_틀린_줄_400_순환_422(world):
sp = _promote(world["system"])
one = {"참조": {**SYS, "키": sp}}
for lines in (
[{"로직": TEN}], # 로직은 못 담음(승격 · 사전조합만)
[{"로직": "GF999999"}], # 모르는 로직
[{"로직": TEN}, {"로직": TEN}], # 같은 로직 두 번(51-11)
[{"로직": TEN, "입력값": [1]}], # 입력값 꼴
[one, one], # 같은 참조 두 번
[{"참조": {**SYS, "키": "SP-000009"}}], # 없는 참조
[{"참조": {**SYS, "키": "SU-000001"}}], # 서고 키 아님
@@ -342,6 +344,52 @@ def test_층_목록_서고_줄은_이름_단위_기준금액을_실음(world):
assert "기준금액" not in rows[2]
def test_사전조합_로직_줄_섞임_합은_손셈_지우기_409_굳힘(world):
from M01_MasterData import M01_MasterData_Store_Cache as cache
from M02_MasterTemplete import M02_Item_Prices as prices
from M02_MasterTemplete import M02_Item_Source as source
sp = _promote(world["system"])
lines = [
{"참조": {**SYS, "키": sp}, "수량": {"손": 2}},
{"로직": STONE, "입력값": {"없는칸": 1}, "수량": {"손": 3}, "메모": "돌"},
{"로직": TEN},
]
sc = _combo(world["system"], lines, "섞음")
saved = _read(world["system"], "precombo", sc)["담은로직"]
assert saved[1:] == [
{"로직": STONE, "입력값": {}, "수량": {"손": 3}, "메모": "돌"},
{"로직": TEN, "입력값": {}, "수량": {"손": 1}, "메모": None},
]
ten, stone = (Decimal(str(_base(c)["계"])) for c in (TEN, STONE))
want = ten / 10 * 2 + stone * 3 + ten / 10 * 1 # 손셈 — 승격 · TEN 은 원/10㎡(배 10)
ref = {**SYS, "키": sc}
with store.at(world["system"]):
doc = labor.clean({"열": "rv", "담은로직": [{"참조": ref, "수량": {"손": 5}}]})
one = labor.calc(doc, {})["줄"][0]
assert one["기준"]["계"] == pytest.approx(float(want))
assert one["반영"]["계"] == pytest.approx(float(want * 5))
assert [x.get("로직") or x["참조"]["키"] for x in one["안"]] == [sp, STONE, TEN]
with store.at(world["system"]), pytest.raises(store.StoreError) as e:
store.delete("promote", sp)
assert e.value.status == 409 and "사전조합 마스터 「섞음」" in e.value.detail
class Gone: # STONE 을 지운 마스터
def logic(self, code):
if code == STONE:
raise cache.cm.mf.FormulaError("없음")
got = cache.labor_errors(Gone())
assert f"사전조합 마스터 「{sc}」 이 로직 「{STONE}」 을 씀 — 거기서 먼저 뺌" in got
rows = source.labor_doc_rows(doc)
assert sorted(refs.frozen_logics(rows["참조사본"])) == sorted([TEN, STONE, TEN])
bundle = prices.to_json(prices.collect([TEN, STONE]))
for key in (sc, sp): # 원본이 사라져도 굳힌 사본으로 같은 값
(world["system"] / refs.kind_of(key) / f"{key}.json").unlink()
got = prices.calc(rows, bundle, {}, {}, None)["줄"][0]
assert got["계"] == pytest.approx(float(want), rel=1e-9)
def test_사전조합이_자기_자신을_담으면_422_수량_기본_1(world):
sp = _promote(world["system"])
a = _combo(world["system"], [{"참조": {**SYS, "키": sp}}], "가")