Files
Aislo/resources/tester/test_723_4_b09_sc_qty.py
T
eomsangdonandClaude Opus 5.5 cf41e303d0 feat(723-4): B09 사본 일위대가(SC) 안 줄 수량 = 굳힌 손 → 구조물 사본 면적 알약 값 → 없음(빈 줄 · 이 공사에서 입력)
- Labor_Source.precombo = 빈 손 1 로 셈 걷음 · 안 줄 · 자재 수량 = 굳힌 옛 손 → 쓰는 구조물 사본 면적 알약 값
  (723-1 「참조 id#차례」 · 「참조 id#자재|코드」 · 짝 = M02_Labor_Expand._qty 차례) → 없음 = qty null · `ask`
- 알약 · 없음 쓴 SC 블록 덮개 열쇠 = `C:참조|S:사본` · `C:참조|L:서고`(쓰는 곳별 · 옛 손뿐 = `C:참조` 그대로)
- 셈 짝(Calc_Labor .py ↔ .ts) = `ask` 줄 수량 비면 비고 · 연결 없음 「수량 없음 — 이 공사에서 입력」 · 702 덮개 qty 입력 뒤 금액 · 글 없음
- 지킴 시험 test_723_4_b09_sc_qty(경고 · 입력 금액 · 알약 굳힘 · 옛 손 · 거울)
- 기존 공사 금액 전후 같음(검증_랩탑메인 · 검증_sub8 B09 셈 답 통째 같음)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 21:55:12 +09:00

106 lines
4.6 KiB
Python

"""723-4 B09 공사 사본의 일위대가(SC) 안 줄 수량 = 프로젝트 값 연결.
- 723-1 = M02 일위대가(SC) 안 줄 · 자재 수량 저장 안 함(null = 수량 없음 · 1 아님)
- 구조물 조합에서 온 SC = 그 사본 면적 알약 값(「참조 id#차례」 · 「참조 id#자재|코드」)으로 굳힘
- 내역에서 바로 쓴 SC(서고 사본) = 빈 줄 `ask` → 이 공사에서 입력(702 덮개 qty) → 금액
- 옛 손(B09 굳힌 사본) = 그대로 · 덮개 열쇠 `C:참조` 그대로(기존 공사 금액 · 덮개 같음)
- 셈 짝(`B09_Estimation_Calc_Labor` .py ↔ .ts) 거울
"""
import importlib.util
import json
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from B09_Estimation.B09_Estimation_Calc_Labor import compute_labor # noqa: E402
from B09_Estimation.B09_Estimation_Labor_Source import ASK, Builder # noqa: E402
from M02_MasterTemplete import M02_Labor_Ref as refs # noqa: E402
_spec = importlib.util.spec_from_file_location(
"b145", Path(__file__).with_name("test_145_2_b09_labor_calc.py")
)
b145 = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(b145)
REF = {"층": "project", "주인": "t", "키": "SC-000001"}
RID = refs.ref_id(REF)
MAT = "MT00001"
SHEETS = {"labor": [], "material": [{"key": MAT, "price": 500}], "machine": []}
def _fix(name, labor):
return {"고정": {"이름": name, "단위": "식", "단가": {"노무비": labor}}}
def _doc(hand=None, mat=None):
"""SC 한 벌 — 고정 줄 둘(노무 1000 · 2000) + 자재 하나 · 손 = hand · mat(None = 수량 없음)."""
q = (lambda v: {"수량": {"손": v}}) if hand is not None else (lambda v: {"수량": None})
return {
"이름": "시험 SC",
"단위": "㎡",
"담은로직": [{**_fix("갑", 1000), **q(hand)}, {**_fix("을", 2000), **q(hand)}],
"자재": [{"코드": MAT, "수량": {"손": mat} if mat is not None else None}],
}
def _build(doc, use=({}, "")):
build = Builder()
whole = {MAT: {"이름": "철선", "규격": "#8", "단위": "kg"}} # 사본 단가 대신(_material 만 읽음)
bid = build.precombo(whole, REF, doc, {}, 1, use)
block = build.blocks[bid]
return {"blocks": [block], "owners": {"pipe@100.0": bid}}, block
def test_수량_없는_SC_서고_사본_경고():
daega, block = _build(_doc(), ({}, "L:lib"))
assert [ln["qty"] for ln in block["lines"]] == [None, None, None]
assert all(ln["ask"] == ASK for ln in block["lines"])
assert block["cover"] == f"C:{RID}|L:lib" # 다른 곳 SC 덮개와 안 섞임
out = compute_labor(daega, SHEETS)
got = out["daega_blocks"][0]
assert got["blank"] == 3 and got["sum"] == 0
assert [ln["why"] for ln in got["lines"]] == [ASK] * 3
assert sum(g["why"] == ASK for g in out["gaps"]) == 3
assert out["daega"][0]["blank"] == 3 # 내역 · 원가계산서 빈 줄(166-6 · 701-3)로 넘어감
def test_이_공사에서_입력_금액():
daega, block = _build(_doc(), ({}, "L:lib"))
cids = [ln["cid"] for ln in block["lines"]]
cover = {block["cover"]: {cids[0]: {"qty": 2}, cids[1]: {"qty": 0.5}, cids[2]: {"qty": 3}}}
got = compute_labor(daega, SHEETS, None, cover)["daega_blocks"][0]
assert [ln["amount"] for ln in got["lines"]] == [2000.0, 1000.0, 1500.0]
assert got["blank"] == 0 and got["sum"] == 4500.0
assert not any("why" in ln for ln in got["lines"]) # 입력 뒤 경고 글 없음
def test_구조물_조합_알약_값_굳힘():
given = {f"{RID}#0": 1.5, f"{RID}#1": 2, f"{RID}#자재|{MAT}": 4}
daega, block = _build(_doc(), (given, "S:pipe@100.0"))
assert [ln["qty"] for ln in block["lines"]] == [1.5, 2.0, 4.0]
assert not any("ask" in ln for ln in block["lines"])
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 and got["blank"] == 0
def test_옛_손_그대로():
daega, block = _build(_doc(hand=3, mat=2), ({}, "S:pipe@100.0"))
assert [ln["qty"] for ln in block["lines"]] == [3.0, 3.0, 2.0]
assert block["cover"] == f"C:{RID}" # 옛 덮개 열쇠 그대로
got = compute_labor(daega, SHEETS)["daega_blocks"][0]
assert got["sum"] == 3000.0 + 6000.0 + 1000.0
def test_거울_파이썬_TS():
daega, block = _build(_doc(), ({}, "L:lib"))
cid = block["lines"][0]["cid"]
for cover in ({}, {block["cover"]: {cid: {"qty": 2}}}):
py = json.loads(json.dumps(compute_labor(daega, SHEETS, {}, cover), ensure_ascii=False))
ts = b145._ts(daega, SHEETS, {}, cover)
assert b145._same(py, ts["out"])