- A 코드 = COSTA · S_JDA 참 = 저장 단가 · 거짓 = AAMTn 노무비율 나눔 · ACTTYP·ACTOPT = PRJLST · calcBoq·api_load 연결 - EXRNM 참 = S 줄만 단가×율/1000 · ECD 자리 버림 · 천원 · 전각 $ - 손료 계수 반올림 = 첫 버림 자리 5 이상 올림 - 적용기준 국가 2·지방 0·행자부 1 · 행자부 RATE_M 조회 rateMLookup - 지식DB 36번 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
35 lines
1.5 KiB
Python
35 lines
1.5 KiB
Python
"""STMATE 재현 앱 수량 계산기(wM_Edit_XRate) 반올림 방향 — Q_d = MROUNDUD(x, d, 선택 1).
|
||
|
||
근거: REA 30 labor_equipment_quantity_rules.json(0x442f97 일일수량 Q_11 · 0x442fec 적용수량 Q_p · 선택 1)
|
||
REA 32 §1.1 MROUNDUD(DP_Common 0x454044) — 선택 1 = 첫 버림 자리 ≥ 5 이면 한 단위 올림(0 반대쪽)
|
||
기대값은 이 규칙의 손셈 — 경계(첫 버림 자리 5)에서 절사·은행가 반올림과 갈림.
|
||
"""
|
||
|
||
import json
|
||
import subprocess
|
||
from pathlib import Path
|
||
|
||
HELPER = Path(__file__).with_name("helper_stmate_smt_tools.cjs")
|
||
|
||
|
||
def call(*calls):
|
||
payload = [{"fn": f, "args": list(a)} for f, *a in calls]
|
||
out = subprocess.check_output(
|
||
["node", str(HELPER)], input=json.dumps(payload), text=True, encoding="utf-8"
|
||
)
|
||
return json.loads(out)
|
||
|
||
|
||
def test_applied_quantity_half_rounds_away_from_zero():
|
||
lab, eq, mid = call(
|
||
("compute", {"qty1": 8, "cond": "", "hrat": 100, "lqty": 1, "labor": True, "point": 2}),
|
||
("compute", {"qty1": 64, "cond": "", "hrat": 100, "lqty": 1, "labor": False, "point": 2}),
|
||
("compute", {"qty1": 16, "cond": "", "hrat": 100, "lqty": 1, "labor": True, "point": 3}),
|
||
)
|
||
# 1 ÷ 8 = 0.125 → 2자리 첫 버림 자리 5 → 0.13(절사 0.12 · 은행가 0.12)
|
||
assert lab["qday"] == 8 and lab["cqty"] == 0.13
|
||
# 장비 1 × 8 ÷ 64 = 0.125 → 0.13
|
||
assert eq["cqty"] == 0.13
|
||
# 1 ÷ 16 = 0.0625 → 3자리 첫 버림 자리 5 → 0.063
|
||
assert mid["cqty"] == 0.063
|