Files
Aislo/resources/tester/test_149_4_pct_extra.py
T
eomsangdonandClaude Opus 5.5 651dc4b818 feat(m02): % 덧줄 표기 — 율 · 규격 덧칸 · 하위 행 · M01 시험계산(149-4)
- 서버 `M02_Labor_Doc.pct_extras` = 식 「X * Y / 100」 덧줄에 율(Y) · 규격(노무비의 % · 인건비의 % · 줄 이름의 %) · `run_line` 에서 부름
- M01 `/calc` 도 같은 도우미(늦은 부름)
- 화면 `pctView` 한 벌 = 이름 (규격) · 수량 = 율 · 단위 % — M02 하위 행 · M01 시험계산 표
- 금액 · 엔진 줄(식 · 1) 그대로 · 금액 식 덧줄(기계손료 등) 그대로 · 마스터 안 고침

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SE9MxeXTu2uaDZ55BJowAY
2026-10-09 19:11:36 +09:00

60 lines
2.9 KiB
Python

"""% 덧줄 표기(PLAN 149-4) — 식 「X * Y / 100」 덧줄 = 덧칸 율 · 규격 · 금액 · 단위 · 수량 그대로.
- M02 `run_line` → 큰돌쌓기 찰쌓기 제잡비 설치 9 · 안 함 3 · 「노무비의 %」
- 인력 줄 합 밑수 = 「인건비의 %」 · 호표 줄 밑수 = 「그 줄 이름의 %」 · 금액 식(기계손료) = 덧칸 없음
- M01 시험계산(`post_calc`) 도 같은 도우미 · 화면 두 곳은 `pctView` 한 벌
"""
from decimal import Decimal
from pathlib import Path
from M01_MasterData import M01_MasterData_Router as m01_router
from M01_MasterData import M01_MasterData_Store as m01
from M02_MasterTemplete import M02_Labor_Doc as labor
ROOT = Path(__file__).resolve().parents[2]
def _extra(code: str, given: dict | None = None, name: str | None = None) -> dict:
got = labor.run_line(m01.loaded()[1], code, given or {})
assert got["까닭"] is None
lines = [x for x in got["줄"] if x.get("단위") == "식" and (name is None or x["이름"] == name)]
assert lines, code
return {**lines[-1], "_기준": got["기준"]}
def test_큰돌쌓기_찰쌓기_제잡비_율_설치_9_안함_3_금액_그대로():
for pipe, rate in (("설치", 9), ("설치 안 함", 3)):
x = _extra("GF000227", {"물빼기파이프": pipe}, "제잡비")
assert x["율"] == Decimal(rate) and x["규격"] == "노무비의 %"
assert x["단위"] == "식" and x["수량"] == 1 # 엔진 줄은 그대로 · 표기는 화면
labor_sum = x["_기준"]["노무비"]
assert abs(x["금액"] - labor_sum * rate / 100) < Decimal("0.01")
def test_인건비_호표줄_밑수_금액식은_덧칸_없음():
x = _extra("GC000198")
assert x["율"] == 2 and x["규격"] == "인건비의 %"
x = _extra("GF000002", name="잡품")
assert x["규격"] == "휘발유(체인톱)의 %" and x["율"] > 0
mach = _extra("GC000267", name="기계손료")
assert "율" not in mach and "규격" not in mach
mat = _extra("GC000267", name="잡재료비")
assert mat["규격"] == "재료비의 %"
def test_M01_시험계산도_율_규격():
given = {"물빼기파이프": "설치", "직경": "60", "지역": "전국평균", "보정작업": "해당 없음"}
got = m01_router.post_calc(m01_router.CalcBody(key="GF000227", inputs=given))
extra = [x for x in got["lines"] if x["이름"] == "제잡비"][0]
assert extra["율"] == 9 and extra["규격"] == "노무비의 %"
def test_화면_두_곳_pctView_한_벌():
api = (ROOT / "M01_MasterData/M01_MasterData_UI_Logic_Api.ts").read_text("utf-8")
assert "x.율 == null" in api and 'qty: x.율, unit: "%"' in api
rows = (ROOT / "M02_MasterTemplete/M02_MasterTemplete_Labor_Rows.ts").read_text("utf-8")
assert "const shown = pctView(x);" in rows and "qty: shown.qty," in rows
calc = (ROOT / "M01_MasterData/M01_MasterData_UI_Logic_Calc.ts").read_text("utf-8")
assert "formatNumber(pctView(line).qty)" in calc