Files
Aislo/resources/tester/test_742_1_sc_qty_saved.py
T
eomsangdonandClaude Opus 5.5 b68a246602 feat(742-1): 일위대가 안 줄 수량 = 사용자 입력 저장 · 기준단위 단가 / 수량 반영 금액 열
- 723-1 「안 줄 수량 null」 걷음 — SC 줄 · 자재 수량 {손} 저장(새 줄 1 · 빈 칸 = 「수량 입력」 · 금액 빠짐)
- 셈 차례: 층 = 알약 값 → 저장 수량 · 공사 굳힌 사본 = 굳힌 손 → 알약 → 저장(with_pills 가 {저장} 칸으로 옮김)
- 불러오기로 만든 일위대가 = 엑셀 수량을 저장 수량으로(본뜬.실무수량 같은 값 남김)
- 단가산출 안 일위대가 = 저장 수량으로 금액(수량 없음 없어짐) · B08 자재 · B09 내 자료집 저장도 같은 차례
- 일위대가표 수량 칸 = 문서에 저장(휘발 임시 칸 걷음) · 합계 열 「기준단위 단가」 · 「수량 반영 금액」
- 낡은 시험(723 · 175 · 204-2 · 702-3 · 703 · 717-4 · 719-1 · 719-2 · hopyo build · flow · labor ref)의 null 단언을
  저장 수량 단언으로 고침 — 723-1 결정이 742-1(요구 584-1)로 바뀜 · 새 지킴 시험 test_742_1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 20:03:48 +09:00

141 lines
6.9 KiB
Python

"""PLAN 742-1 — M02 일위대가(SC) 안 줄 수량 = 사용자 입력 저장(요구 584-1 · 723-1 「null」 걷음).
- 저장 = 줄 · 자재 `수량 {손}` 그대로(빈 수량 = null · 비율 줄 율) · 다시 열기 같음
- 층 셈 차례 = 알약 값(쓰는 쪽 given) → 저장 수량 → 없으면 「수량 없음」
- 공사 굳힘(`with_pills`) = 저장 수량 `{저장}` 칸으로 옮김
→ 공사 차례 = 굳힌 손(옛 사본 · 707-7) → 알약 → 저장
- 단가산출(SK) 안 일위대가 = 그 저장 수량으로 금액(「수량 없음」 없어짐)
- 화면 일위대가표 = 수량 칸 저장 · 새 줄 1 · 빈 칸 「수량 입력」 ·
합계 열 「기준단위 단가」 · 「수량 반영 금액」
"""
import os
from decimal import Decimal
import pytest
from B09_Estimation.B09_Estimation_Calc_Labor import compute_labor
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 resources.tester.test_723_4_b09_sc_qty import MAT, RID, SHEETS, _build, _doc
from resources.tester.test_m02_labor_ref import world # noqa: F401 — 임시 층 fixture
SRC = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "M02_MasterTemplete")
SYS = {"층": "system", "주인": None}
STONE = "GF000219" # 원/㎡
RATE = {"이름": "공구손료", "단위": "%", "단가": {"노무비": 0, "재료비": 0, "경비": 0}}
def _stone() -> float:
return labor.run_line(m01.loaded()[1], STONE, {})["기준"]["계"]
def _sc(world, lines): # noqa: F811
with store.at(world["system"]):
return refs.create("precombo", {"이름": "저장", "단위": "m", "담은로직": lines})["이름"]
def test_저장_다시_열기_수량_그대로_빈_수량_null_비율_율(world): # noqa: F811
rate = {"고정": {**RATE, "비율": {"기준": "노무비", "비목": "경비"}}, "수량": {"손": 3}}
key = _sc(world, [{"로직": STONE, "수량": {"손": 2.5}}, {"로직": "GF000297"}, rate])
with store.at(world["system"]):
doc = store.read("precombo", key)["문서"]
assert [x["수량"] for x in doc["담은로직"]] == [{"손": 2.5}, None, {"손": 3}]
frozen = refs.with_pills(doc) # 공사 굳힘 = 저장 칸으로(비율 율 · 빈 수량 그대로)
assert [x["수량"] for x in frozen["담은로직"]] == [{"저장": 2.5}, None, {"손": 3}]
assert frozen["알약"]
def test_층_차례_알약_먼저_없으면_저장_없으면_수량_없음(world): # noqa: F811
key = _sc(world, [{"로직": STONE, "수량": {"손": 2}}])
blank = _sc(world, [{"로직": STONE}])
ref, whole = {**SYS, "키": key}, m01.loaded()[1]
with store.at(world["system"]):
saved = refs.Expand(whole)(ref)
fed = refs.Expand(whole, given={f"{refs.ref_id(ref)}#0": 5})(ref)
none = refs.Expand(whole)({**SYS, "키": blank})
assert saved["기준"]["계"] == pytest.approx(_stone() * 2) and saved["안"][0]["수량"] == 2
assert fed["기준"]["계"] == pytest.approx(_stone() * 5) # 알약 있음 = 알약
assert none["기준"] is None and "수량 없음" in none["까닭"] # 빈 수량 = 금액 빠짐
def test_굳힌_사본_차례_굳힌_손_알약_저장(world): # noqa: F811
key = _sc(world, [{"로직": STONE, "수량": {"손": 2}}])
ref, whole = {**SYS, "키": key}, m01.loaded()[1]
with store.at(world["system"]):
doc = refs.read_ref(ref)
frozen = refs.with_pills(doc)
old = {**frozen, "담은로직": [{**frozen["담은로직"][0], "수량": {"손": 9}}]} # 옛 굳힌 손
pill = {f"{refs.ref_id(ref)}#0": 4}
with store.at(world["system"]):
bare = refs.Expand(whole, read=lambda r: frozen)(ref)
fed = refs.Expand(whole, read=lambda r: frozen, given=pill)(ref)
kept = refs.Expand(whole, read=lambda r: old, given=pill)(ref)
assert bare["기준"]["계"] == pytest.approx(_stone() * 2) # 저장
assert fed["기준"]["계"] == pytest.approx(_stone() * 4) # 알약 > 저장
assert kept["기준"]["계"] == pytest.approx(_stone() * 9) # 굳힌 손 > 알약
def _saved_doc():
"""723-4 SC 꼴(고정 노무 1000 · 2000 + 자재 MAT 500) · 저장 수량 2 · 2 · 자재 3
= 굳힌 `{저장}`."""
doc = _doc(hand=2, mat=3)
return {
**doc,
"담은로직": [refs.saved_qty(x) for x in doc["담은로직"]],
"자재": [refs.saved_qty(x) for x in doc["자재"]],
}
def test_B09_저장_수량_금액_알약_있으면_알약():
daega, block = _build(_saved_doc(), ({}, "L:lib"))
assert [ln["qty"] for ln in block["lines"]] == [2.0, 2.0, 3.0]
assert not any(ln.get("ask") for ln in block["lines"]) and block["cover"] == f"C:{RID}"
got = compute_labor(daega, SHEETS)["daega_blocks"][0]
assert got["sum"] == 2000.0 + 4000.0 + 1500.0 and got["blank"] == 0
given = {f"{RID}#0": 1.5, f"{RID}#자재|{MAT}": 4} # 첫 줄 · 자재만 알약 · 둘째 줄 = 저장
daega, block = _build(_saved_doc(), (given, "S:pipe@100.0"))
assert [ln["qty"] for ln in block["lines"]] == [1.5, 2.0, 4.0]
assert block["cover"] == f"C:{RID}|S:pipe@100.0"
got = compute_labor(daega, SHEETS)["daega_blocks"][0]
assert got["sum"] == 1500.0 + 4000.0 + 2000.0
def test_B09_옛_사본_null_은_그대로_빈_줄():
daega, block = _build(_doc(), ({}, "L:lib")) # 723-1 때 굳힌 사본 = 전후 같음
assert [ln["qty"] for ln in block["lines"]] == [None, None, None]
assert compute_labor(daega, SHEETS)["daega_blocks"][0]["blank"] == 3
def test_단가산출_안_일위대가_저장_수량_금액(world): # noqa: F811
from M02_MasterTemplete import M02_Sangeun_Calc as calc
key = _sc(world, [{"로직": STONE, "수량": {"손": 2}}])
sk = {
"키": "SK-000001",
"이름": "겹",
"단위": "식",
"더한줄": [{"참조": {**SYS, "키": key}, "수량": 3}],
}
with store.at(world["system"]):
got = calc.calc_doc(calc.clean_doc(sk, refs.here()))
assert not got["빠진줄"]
assert got["1단위"]["계"] == pytest.approx(float(Decimal(str(_stone())) * 2 * 3), rel=1e-6)
def _src(name: str) -> str:
return open(os.path.join(SRC, name), encoding="utf-8").read()
def test_화면_수량_칸_저장_새_줄_1_두_칸():
table = _src("M02_MasterTemplete_Labor_Table.ts")
assert "const temp = new Map" not in table and "withTemp" not in table # 휘발 칸 걷음
assert "row.수량 = raw ? { 손: v } : null;" in table and "changed(true);" in table
assert table.count("수량: { ...ONE }") == 4 # 기초 · 참조 · 고정 · 자재 새 줄 = 1
assert 'BasePrice: ["기준단위 단가"' in table and 'QtyAmount: ["수량 반영 금액"' in table
assert 'sum_price: t("BasePrice"), sum: t("QtyAmount")' in table
assert 'NeedQty: ["수량 입력"' in table
assert 'if (!edit || key !== "qty" || n === null) return false;' in table # 읽기 층 못 고침