feat(stmate-test): 적용기준 행자부(I_SET_BASE 1) 요율 조회 화면 연결 — 간접노무비·일반관리비·이윤 = RATE_M

- 요율 조회(scr_kanjub_rate.lookup) — 적용기준 1 이면 rateMLookup(ST_KanJub 0x47a1bc) 값으로 KANNO·ILBAN·IYUN · 그 밖 RATE_R 그대로
- 적용기준 콤보를 바꾸면 제비율표 다시 조회(요율 축에 I_SET_BASE)
- 브라우저 확인(봉화2024): 행자부 → 간접노무비 14.5 → 14.6(RATE_M 11줄 RATE1) · 지방계약법 되돌림 14.5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-14 15:50:01 +09:00
co-authored by Claude Opus 5.5
parent 4ff96a6771
commit 7eac0d93b0
3 changed files with 75 additions and 6 deletions
@@ -166,6 +166,38 @@ def test_rate_m_lookup_against_stc_table():
assert [g["band"] for g in res] == [0, 1, 2, 0]
def test_rate_screen_lookup_uses_rate_m_for_set_base_1():
"""요율 조회 화면(scr_kanjub_rate.lookup) — 적용기준 행자부(1)면 간접노무비·일반관리비·이윤만 RATE_M · 그 밖은 RATE_R."""
files = server.read_project_files(str(STC))
rate_r = server.parse_dbf_bytes(files["RATE_R.DBF"])[1]
rows = _rate_m_rows()
opts = {"scale": 100e8, "kongType": 3, "ilbanType": 0, "kikan": 2, "rateMRows": rows}
req = [{"matrix": rate_r, "opts": {**opts, "setBase": b}} for b in (1, 0, 2)]
helper = HELPER.with_name("helper_stmate_kanjub_rate.cjs")
out = subprocess.run(
["node", str(helper)],
input=json.dumps(req),
capture_output=True,
text=True,
encoding="utf-8",
check=True,
)
mo, local, nation = json.loads(out.stdout)
want = run(
{
"mode": "ratem",
"rows": rows,
"cases": [{"scale": 100e8, "kongType": 3, "ilban": 0, "kikan": 2}],
}
)
for c in ("KANNO", "ILBAN", "IYUN"):
assert mo["rates"][c] == want["out"][0]["rates"][c]
assert mo["cells"][c][0] == "RATE_M"
assert local["rates"] == nation["rates"] # 지방·국가는 RATE_R 조회 그대로
for c in ("SANBO", "KUNBO", "ANJUN"):
assert mo["rates"][c] == local["rates"][c]
def test_set_base_combo_pairs_from_dfm():
nodes = json.loads(DFM.read_text(encoding="utf-8"))["nodes"]
combo = next(o for o in _walk(nodes) if o.get("name") == "cmBx_Set_Base")