99 lines
3.9 KiB
Python
99 lines
3.9 KiB
Python
"""STMATE 재현 앱 구성 조립 설정 — 소수 자리(KCD·BPN·ACD·JCD·ECD) · 외산장비 환율($ 구간·€·¥).
|
||
|
||
근거: 22번 §3.4(0·1·2 자리) · REA 14 TWM_SET_SYS 안내문
|
||
KCD 중기사용료 금액 · BPN 일위대가표 금액 · ACD 단가산출서 금액 · JCD 「X」의 중기노임 단가 · ECD 「X」의 $장비 단가
|
||
₩/$(10만$이상은 ed_EXH) · ₩/€ · ₩/100¥ · 단가의 조사시점(ARENM) = 환율 칸 1/2.
|
||
실무 7건 값(KCD·ACD·BPN = 1 · ECD = 0 · JCD 0/1 · EXLNM = EXHNM)은 test_stmate_ilwi_eval 이 1원 대조 · 여기는 손셈.
|
||
"""
|
||
|
||
import json
|
||
import subprocess
|
||
from pathlib import Path
|
||
|
||
HELPER = Path(__file__).with_name("helper_stmate_smt_opts.cjs")
|
||
|
||
|
||
def run(*cases):
|
||
out = subprocess.check_output(
|
||
["node", str(HELPER)],
|
||
input=json.dumps({"cases": list(cases)}, ensure_ascii=False),
|
||
text=True,
|
||
encoding="utf-8",
|
||
)
|
||
return json.loads(out)
|
||
|
||
|
||
def comp(rows, table, ini=None, code="X00001", row=None):
|
||
return {"rows": rows, "table": table, "ini": ini or {}, "code": code, "row": row or {}}
|
||
|
||
|
||
M1 = {"M00001": {"M": 333, "L": 0, "S": 0, "unit": "kg"}}
|
||
ROWS = [{"CODE": "M00001", "QTY1": 0.33}] # 333 × 0.33 = 109.89
|
||
|
||
|
||
def test_line_digits_by_kind():
|
||
a, b, c, d = run(
|
||
comp(ROWS, M1, {"KCDNM": "1"}),
|
||
comp(ROWS, M1, {"KCDNM": "0"}),
|
||
comp(ROWS, M1, {"BPNNM": "2"}, code="B00001"),
|
||
comp(ROWS, M1, {"KCDNM": "0", "BPNNM": "1"}, code="B00001"),
|
||
)
|
||
# 줄 금액 109.89 → 1 자리 109.8 · 0 자리 109 · 결과는 원 미만 절사
|
||
assert a["opts"]["lineDigits"] == 1 and b["opts"]["lineDigits"] == 0
|
||
assert c["opts"]["lineDigits"] == 2 and d["opts"]["lineDigits"] == 1
|
||
assert a["M"] == b["M"] == 109
|
||
|
||
|
||
def test_line_digits_change_sum():
|
||
rows = [{"CODE": "M00001", "QTY1": 0.33}] * 3 # 109.89 × 3
|
||
one, zero, two = run(
|
||
comp(rows, M1, {"KCDNM": "1"}),
|
||
comp(rows, M1, {"KCDNM": "0"}),
|
||
comp(rows, M1, {"KCDNM": "2"}),
|
||
)
|
||
assert (one["M"], zero["M"], two["M"]) == (329, 327, 329) # 329.4 · 327 · 329.67
|
||
|
||
|
||
def test_acd_digits_for_smt():
|
||
a, b = run(comp([], {}, {"ACDNM": "0"}), comp([], {}, {}))
|
||
assert a["smtLine"] == 0 and b["smtLine"] == 1
|
||
|
||
|
||
def test_wage_digits_jcd():
|
||
table = {"L00001": {"M": 0, "L": 100001, "S": 0, "unit": "인"}}
|
||
rows = [{"CODE": "L00001", "QTY1": 10}]
|
||
ini = {"CONLD": "L00001", "RXXNM": "1/8", "KCDNM": "2"}
|
||
j0, j1 = run(comp(rows, table, {**ini, "JCDNM": "0"}), comp(rows, table, {**ini, "JCDNM": "1"}))
|
||
# 100001 / 8 = 12500.125 → JCD 0 = 12500 · JCD 1 = 12500.1 → × 10
|
||
assert j0["L"] == 125000 and j1["L"] == 125001
|
||
|
||
|
||
def test_foreign_units_and_usd_band():
|
||
table = {
|
||
"S00001": {"M": 0, "L": 0, "S": 49594, "unit": "$"},
|
||
"S00002": {"M": 0, "L": 0, "S": 150000, "unit": "$"},
|
||
"S00003": {"M": 0, "L": 0, "S": 1000, "unit": "€"},
|
||
"S00004": {"M": 0, "L": 0, "S": 1000, "unit": "¥"},
|
||
}
|
||
ini = {"EXLNM1": "1470", "EXHNM1": "1500", "EXEUR1": "1423", "EXYEN1": "915"}
|
||
ini |= {"EXLNM2": "1000", "EXHNM2": "1000", "EXEUR2": "1000", "EXYEN2": "1000"}
|
||
one = lambda c: [{"CODE": c, "QTY1": 1}] # noqa: E731
|
||
r = run(
|
||
comp(one("S00001"), table, ini),
|
||
comp(one("S00002"), table, ini),
|
||
comp(one("S00003"), table, ini),
|
||
comp(one("S00004"), table, ini),
|
||
comp(one("S00001"), table, {**ini, "ARENM": "2"}),
|
||
)
|
||
# 단가(천원) = 가격 × 환율 ÷ 1000 · 10만$ 이상 = EXHNM · ¥ 는 100¥당
|
||
assert [x["S"] for x in r] == [72903, 225000, 1423, 9, 49594]
|
||
|
||
|
||
def test_usd_real_case_ulljin():
|
||
# 울진 X00127 트럭트랙터 — S00346 49594$ × 1470 ÷ 1000 × 0.2529 = 18437(저장 SAMT1)
|
||
table = {"S00346": {"M": 0, "L": 0, "S": 49594, "unit": "$"}}
|
||
(r,) = run(
|
||
comp([{"CODE": "S00346", "QTY1": 0.2529}], table, {"EXLNM1": "1470", "EXHNM1": "1470"})
|
||
)
|
||
assert r["S"] == 18437
|