Files
Aislo/resources/tester/test_750_1_sk_views.py
T
eomsangdonandClaude Opus 5.5 9d2b8e4021 feat(750-1): SK 셈 답 하나에 보기 넷 — 텍스트 수식 글 · 시험 계산 중간 · 일위대가 줄 모달 줄모드
- 새 `M02_Sangeun_Views` — SK 고친 줄(`_Over`) · 같은 입력 · 같은 고름 위에서 `master_text.lines` + `annotate` = `글` · 줄마다 cid · 금액 · 소계 · 계 = SK 줄 · 기준(별도계상 뺌 · 단위 환산 ÷배 · 못 셈 까닭) · `중간` = 시험 계산 중간값
- `calc_doc` — 문서 `줄모드` true = 일위대가 그 줄 셈(`line` · 별도계상 기본) · 몸 `보기` false = 덧칸 안 지음(바탕 원값 셈)
- `master_text.lines` · `master_sheet_line.annotate` — `files` 자리에 Master 도 받음(파일 묶음 길 그대로 · M01 `/text` 답 같음)
- `lineDoc` — `줄모드: true`(일위대가 줄 모달 89,299.60 = 그 줄 금액)
- 시험 `test_717_3` — lineDoc = as_doc 대조에서 `줄모드` 칸 따로 확인(서버 as_doc 은 `line` 인자로 줄 셈 · 문서 칸 없음)
- 새 지킴 `test_750_1_sk_views` — 변형 일곱 · 참조 바탕 · 줄 모달 · 보기 false

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 22:32:23 +09:00

95 lines
4.3 KiB
Python

"""SK 보기 넷 = 셈 답 하나(PLAN 750-1 · 요구 588-1) — 화면 셈 답 `글`(텍스트 수식) ·
시험 계산(`줄` · `기준` · `중간`) = SK 줄 · 계 · 변형 일곱(기본 · 줄 빼기 · 더하기 · 덧줄 ·
별도계상 · 단위 환산 · 재료 고름) + 참조 바탕 · 일위대가 줄 모달(`줄모드`) = 일위대가 그 줄 셈 ·
`보기` false = 덧칸 없음 · M01 엔진 · storage 안 씀."""
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_Sangeun_Calc as calc
from M02_MasterTemplete import M02_Sangeun_Doc as sd
from M02_MasterTemplete import M02_Sangeun_Views as views
FORM = "GC000211" # 6-3-1 합판거푸집 — 재료 일곱 · 소모자재 = 재료비 % 덧줄
PLY = "material:합판(내수 12㎜)#0"
DOC = {"키": "SK-000002", "이름": "테스트1", "단위": "㎡", "바탕": {"로직": FORM}}
ADD = {"종류": "인력", "요소": "LB000002", "이름": "보통인부(더함)", "단위": "인", "수량": 0.05}
CASES = {
"기본": {},
"줄 빼기": {"뺀줄": ["material:각재#0"]},
"더하기": {"더한줄": [ADD]},
"덧줄": {"덮개": {"pct:소모자재#0": {"qty": 5}}},
"별도계상": {"자재표시": {PLY: {"별도계상": "별도계상"}}},
"단위 환산": {"단위": "10㎡"},
"재료 고름": {"고름": {PLY: "MT000020"}},
}
def _whole():
return m01.loaded()[1]
def _answer(doc: dict, read=None, line: bool = False) -> dict:
"""`calc_doc` 와 같은 길(층 검사만 뺌)."""
whole = _whole()
clean = sd.clean(doc, None, whole)
got = calc.run(clean, whole, None, read or calc.refs.read_ref, detail=True, line=line)
return labor._json(views.finish(calc.per_unit(got, clean)))
def _same(a: dict) -> None:
text, base = a["글"], a["기준"]
assert text["ok"] is True
money: dict[str, float] = {}
for g in text["groups"]:
assert g["소계"] == pytest.approx(base[g["비목"]])
for one in g["줄"]:
money[one["cid"]] = money.get(one["cid"], 0) + (one["금액"] or 0)
assert set(money) == {x["cid"] for x in a["줄"]} # 글 줄 = SK 줄(cid)
for x in a["줄"]:
assert money[x["cid"]] == pytest.approx(x["금액"] or 0)
assert text["계"] == pytest.approx(base["계"])
assert sum(x["금액"] or 0 for x in a["줄"]) == pytest.approx(base["계"]) # 시험 계산 표 합
assert a["중간"] and all(not isinstance(v, (dict, list)) for v in a["중간"].values())
@pytest.mark.parametrize("name", list(CASES))
def test_four_views_one_answer(name):
a = _answer({**DOC, **CASES[name]})
_same(a)
if name == "별도계상":
assert all(one.get("cid") != PLY for g in a["글"]["groups"] for one in g["줄"])
if name == "단위 환산":
assert a["글"]["나눔"] == pytest.approx(0.1)
plain = _answer(DOC)
assert a["기준"]["계"] == pytest.approx(plain["기준"]["계"] * 10)
if name == "재료 고름":
assert a["기준"]["재료비"] != pytest.approx(_answer(DOC)["기준"]["재료비"])
def test_ref_base_same():
"""참조 바탕(SK 위 SK) — 글도 바탕 SK 고친 줄 위에서."""
parent = {**DOC, **CASES["덧줄"], "뺀줄": ["material:각재#0"]}
ref = {"층": "personal", "주인": None, "키": "SK-000002"}
_same(_answer({**DOC, "키": "SK-000003", "바탕": {"참조": ref}}, read=lambda r: parent))
def test_row_modal_is_hopyo_line():
"""일위대가 줄 모달(`줄모드`) = 일위대가 그 줄 셈(별도계상 기본 · 747 한쪽 흠)."""
whole = _whole()
line = labor._json(labor.drop_apart(labor.run_line(whole, FORM, None), {}))
got = _answer({**DOC, "단위": "식", "줄모드": True}, line=True)
assert got["기준"]["계"] == pytest.approx(line["기준"]["계"])
assert [x["이름"] for x in got["줄"]] == [x["이름"] for x in line["줄"]]
_same(got)
def test_no_views_flag():
"""`보기` false(바탕 원값 셈) = 금액만 · 덧칸 없음 · 금액 같음."""
whole = _whole()
clean = sd.clean(DOC, None, whole)
got = labor._json(calc.run(clean, whole, None, detail=True, seen=False))
assert "글" not in got and "중간" not in got
assert got["기준"]["계"] == pytest.approx(_answer(DOC)["기준"]["계"])