- 끝수 한 곳 `master_cut.py`(B09 `rounddown` 재사용) — 엔진 답에 입힘: 줄 비목마다 0.1 원 버림 · 하위 로직 줄 = 하위 끝수 계 × 수량 · 덧줄 = 버린 줄 합으로 다시 셈 · 비목 합 1 원 버림 · 중간 칸도 버린 값 - 쓰는 곳: M01 시험 계산(`check_master.calc`) · 읽는 식(`master_text.lines`) · 옛 조합 미리보기(`master_combo`) · M02 `run_line`(단가산출 · 일위대가 · 펼침) · 별도계상 뺀 기준 · 켜쌓기율 곱 뒤 · 일위대가 반영 · 반영합 · 비율 줄 · 사전조합 안 줄 - 일위대가 반영 TS 짝(`Labor_Calc.ts`) 같은 끝수 · 거울 헬퍼가 상대 경로 .ts 가져옴 - B09 = `run_line(raw=True)` 엔진 날 값(제 단가로 다시 버림 · % 덧줄 율 비 그대로) — 검증_sub3 B09 247 칸 전후 같음 - `master_text` 꼴 셋 = `common_util_money` 로 갈음(줄 금액 `fmt_line_money` · 식 안 금액 = 버린 0.1 원) - 화면: 상세 줄 금액 · 시험 계산 줄 · 중간 돈 = `formatLineMoney` · 일위대가 반영 칸 0.1 원 · 상세 바닥 · 박스 · 인력재료경비 비목 소계 = 줄 합 1 원 버림 - 테스트1 네 보기 · 서고 목록 = 124,419(옛 124,420 / 124,419.85) · 재료 줄 11,694.6 + 23,425.6 + 1,404.8 = 소계 36,525 - 새 지킴 시험 test_751_3_money_cut - 옛 날 금액(끝수 없음)을 대조하던 시험 24 파일 고침 — 까닭 = 금액 규칙이 줄 0.1 원 · 소계 1 원 버림으로 바뀜(고정 값 → 새 값 · 줄 합 = 계 → 줄 합 아래 비목마다 1 원 안 · 곱 비 = 끝수 폭 안) · 실무 xlsx 영월 엑셀 같음 22 → 23 · 이어 붙이는 TS 시험(704_3 · 717_2b)에 `rounddown` 같은 식 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
116 lines
5.9 KiB
Python
116 lines
5.9 KiB
Python
"""725-1 · 725-2 단가산출 [항목 추가] 못 셈 줄 — 더한줄 로직 입력 = 공통 옵션 › 로직 기본값 ·
|
||
그래도 빈 입력 · 수량 없는 일위대가 줄 = 그 줄만 금액 없음 + 까닭 · 나머지 셈 계속(임시 storage)."""
|
||
|
||
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
|
||
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 — 같은 임시 층
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
GF = "GF000099" # 측구터파기 토사 · 입력 지역 · 보정작업
|
||
PCT = "GC001109" # 입력 없음 · 인력 둘 + 덧줄 %
|
||
GF_LINE = {"종류": "로직", "로직": GF, "입력값": {}, "수량": 1}
|
||
PCT_LINE = {"종류": "로직", "로직": PCT, "입력값": {}, "수량": 1}
|
||
|
||
|
||
def _sk(folder, **doc):
|
||
with store.at(folder):
|
||
made = refs.create("sangeun", {"이름": "sub7임시", "단위": "㎥", "더한줄": [], **doc})
|
||
return store.read("sangeun", made["이름"])["문서"]
|
||
|
||
|
||
def _run(folder, doc, given=None):
|
||
with store.at(folder):
|
||
return calc.calc_doc(doc, given)
|
||
|
||
|
||
def _line(got, cid):
|
||
return next(x for x in got["줄"] if x["cid"] == cid)
|
||
|
||
|
||
def _m01(code, values):
|
||
return float(labor.run_line(m01.loaded()[1], code, values, None, None)["기준"]["계"])
|
||
|
||
|
||
@pytest.mark.parametrize(
|
||
("given", "want"),
|
||
[
|
||
(None, {"지역": "전국평균", "보정작업": "해당 없음"}), # 로직 기본값
|
||
({"지역": "서울"}, {"지역": "서울", "보정작업": "해당 없음"}), # 공통 옵션 › 기본값
|
||
],
|
||
)
|
||
def test_added_logic_takes_common_then_default(world, given, want): # noqa: F811
|
||
"""입력 있는 로직 더한줄(입력값 {}) = 공통 옵션 넣은 M01 셈 · 계 = 바탕 + 그 줄."""
|
||
doc = _sk(world["personal"], 바탕={"로직": GF}, 더한줄=[GF_LINE])
|
||
plain = _sk(world["personal"], 바탕={"로직": GF})
|
||
got, bare = _run(world["personal"], doc, given), _run(world["personal"], plain, given)
|
||
one = _m01(GF, want)
|
||
assert got["빠진줄"] == [] and not got.get("까닭")
|
||
assert _line(got, "add:#0")["금액"] == pytest.approx(one, rel=1e-9)
|
||
assert got["기준"]["계"] - bare["기준"]["계"] == pytest.approx(one, rel=1e-9)
|
||
assert doc["더한줄"][0]["입력값"] == {} # 문서에 안 적음 — 공통 옵션을 바꾸면 따라감
|
||
|
||
|
||
def test_line_without_input_only_that_line_drops(world, monkeypatch): # noqa: F811
|
||
"""기본값도 없는 입력 = 그 줄만 금액 — · 까닭 · 계 = 나머지 · 쓰는 자리 = 기준 없음."""
|
||
monkeypatch.setattr(calc, "_defaults", lambda whole, code: {})
|
||
doc = _sk(world["personal"], 더한줄=[GF_LINE, PCT_LINE])
|
||
rest = _sk(world["personal"], 더한줄=[PCT_LINE])
|
||
got, want = _run(world["personal"], doc), _run(world["personal"], rest)
|
||
gap = _line(got, "add:#0")
|
||
assert gap["금액"] is None and gap["까닭"] == "입력 「지역」 없음"
|
||
assert got["빠진줄"] == [{"cid": "add:#0", "이름": gap["이름"], "까닭": "입력 「지역」 없음"}]
|
||
assert gap["이름"] # 이름 남음 — 화면 줄 빼기 자리
|
||
assert got["기준"]["계"] == pytest.approx(float(want["기준"]["계"]), rel=1e-9)
|
||
assert _line(got, "add:#1")["금액"] == pytest.approx(float(want["기준"]["계"]), rel=1e-9)
|
||
with store.at(world["personal"]):
|
||
up = refs.Expand(m01.loaded()[1])({**MINE, "키": doc["키"]})
|
||
assert up["기준"] is None and "입력 「지역」 없음" in up["까닭"]
|
||
|
||
|
||
def test_precombo_in_sk_flattened_no_gap(world): # noqa: F811
|
||
"""740-1 — SK 에 넣은 일위대가 = 줄마다 더한줄로 펼쳐 담음(수량 = 넣은 수 × 1) · 빠진 줄 없음."""
|
||
with store.at(world["personal"]):
|
||
sc = refs.create(
|
||
"precombo", {"이름": "sub7임시SC", "단위": "㎥", "담은로직": [{"로직": PCT}]}
|
||
)
|
||
line = {"참조": {**MINE, "키": sc["이름"]}, "수량": 2}
|
||
doc = _sk(world["personal"], 더한줄=[line, PCT_LINE])
|
||
rest = _sk(world["personal"], 더한줄=[PCT_LINE])
|
||
got, want = _run(world["personal"], doc), _run(world["personal"], rest)
|
||
assert doc["더한줄"][0]["로직"] == PCT and doc["더한줄"][0]["본뜬"]["키"] == sc["이름"]
|
||
assert got["빠진줄"] == []
|
||
assert got["기준"]["계"] == pytest.approx(3 * float(want["기준"]["계"]), rel=1e-9)
|
||
|
||
|
||
def test_screen_shows_dropped_lines():
|
||
"""화면 — 빠진 줄 띠(이름 · 까닭) · 금액 없는 줄 계산서 금액 —."""
|
||
ts = (ROOT / "M02_MasterTemplete" / "M02_MasterTemplete_Sangeun_Detail.ts").read_text("utf-8")
|
||
assert "ans?.빠진줄" in ts and 'L("M02_SangeunGap")' in ts
|
||
|
||
|
||
def test_no_base_common_option_seoul(world): # noqa: F811
|
||
"""725-6 — 바탕 없는 SK 도 공통 옵션(지역 서울) 따라감 = M01 셈."""
|
||
doc = _sk(world["personal"], 더한줄=[GF_LINE])
|
||
got = _run(world["personal"], doc, {"지역": "서울"})
|
||
assert got["빠진줄"] == [], got
|
||
assert got["기준"], {k: v for k, v in got.items() if k != "줄"}
|
||
assert got["기준"]["계"] == pytest.approx(_m01(GF, {"지역": "서울", "보정작업": "해당 없음"}))
|
||
assert float(got["기준"]["계"]) == 5295 # 751-3 끝수(옛 날 값 5,297.37)
|
||
|
||
|
||
def test_screen_no_base_inputs_and_gap_dash():
|
||
"""725-6 화면 — 바탕 없음 = 더한줄 로직 입력 모음 칸 · 못 셈 줄 금액 「—」 + 까닭 풍선."""
|
||
ts = (ROOT / "M02_MasterTemplete" / "M02_MasterTemplete_Sangeun_Detail.ts").read_text("utf-8")
|
||
assert "입력: extra" in ts and "syncExtra" in ts and "void recalc(); // 750-2" in ts
|
||
ho = (ROOT / "M01_MasterData" / "M01_MasterData_UI_LogicLab_Ho.ts").read_text("utf-8")
|
||
assert "e.line?.까닭 ? gapCell" in ho and "title: why" in ho
|