- 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>
67 lines
3.2 KiB
JavaScript
67 lines
3.2 KiB
JavaScript
/* -*- coding: utf-8 -*- */
|
|
/**
|
|
* 노무·장비 수량 계산기(wM_Edit_XRate · 손료계수 수정) 계산 — 화면 없이 숫자만 (calc_xrate.js)
|
|
* 근거: REA 30 ST_EdiLWi labor_equipment_quantity_rules.json(0x442f97 · 0x442fec · 0x4434b4 · 0x443634)
|
|
* 일일수량 = Q11(기준수량 × 조건계수 × 적용율 ÷ 100)
|
|
* 적용수량 = 일일수량 0 이면 0 · 아니면 Qp(조수량 × (노무 1 · 장비 8) ÷ 일일수량)
|
|
* 자동 자리 = 기준수량 정수부 자릿수 + 1 (2~6 사이로 묶음) · 일일수량이 아니라 기준수량을 봄
|
|
* 조건식 = 빈칸 걷은 뒤 * + - . / 0~9 ^ 만 허용(괄호 없음) · 빈 식 = 1
|
|
* Q_d = DP_Common.MROUNDUD(x, d, 1) — 선택 1 = 첫 버림 자리 ≥ 5 이면 한 단위 올림(0 반대쪽 · 사사오입)
|
|
* 근거: REA 32 §1.1(DP_Common 0x454044 · 0x4544f0 올림 판정) · 원형 = exec_calc.js mroundud(한 벌)
|
|
*/
|
|
const StmateXRate = (() => {
|
|
const EV = () =>
|
|
(typeof window !== "undefined" && window.STMATE_SMT_EVAL) ||
|
|
(typeof require !== "undefined" ? require("./smt_eval.js") : null);
|
|
|
|
const EX = () =>
|
|
(typeof window !== "undefined" && window.STMATE_EXEC) ||
|
|
(typeof require !== "undefined" ? require("./exec_calc.js") : null);
|
|
|
|
// Q_d = MROUNDUD(v, d, 1) — 원형(exec_calc) 이 안 실렸으면 같은 방향(사사오입 · 0 반대쪽)으로
|
|
function q(v, d) {
|
|
const ex = EX();
|
|
if (ex && ex.mroundud) return ex.mroundud(v, d, 1);
|
|
const f = 10 ** d,
|
|
r = Math.floor(Math.abs(Number(v) || 0) * f + 0.5 + 1e-9) / f;
|
|
return v < 0 ? -r : r;
|
|
}
|
|
|
|
// 조건계수 — 허용 글자만 · 괄호 금지 · 계산은 식 계산기(CALC_STR_URC 대응)
|
|
function condFactor(text) {
|
|
const s = String(text ?? "").replace(/\s+/g, "");
|
|
if (!s) return { ok: true, value: 1 };
|
|
if (!/^[0-9.+\-*/^]+$/.test(s))
|
|
return { ok: false, value: 1, error: "조건식에 쓸 수 없는 글자" };
|
|
const v = Number(EV().evalExpr(s, {}));
|
|
return Number.isFinite(v)
|
|
? { ok: true, value: v }
|
|
: { ok: false, value: 1, error: "조건식 오류" };
|
|
}
|
|
|
|
// 자동 자리 — 기준수량 정수부 자릿수 + 1, 2~6
|
|
function autoPoint(qty1) {
|
|
const n = String(Math.trunc(Math.abs(Number(qty1) || 0))).length;
|
|
return Math.min(6, Math.max(2, n + 1));
|
|
}
|
|
|
|
/**
|
|
* inp: { qty1 기준수량, cond 조건식, hrat 적용율(%), lqty 조수량, labor 참=노무, point 자리, auto 자동자리 }
|
|
* 돌려줌: { ok, cond, qday 일일수량, point, cqty 적용수량 }
|
|
*/
|
|
function compute(inp = {}) {
|
|
const c = condFactor(inp.cond);
|
|
const qty1 = Number(inp.qty1) || 0;
|
|
const qday = q((qty1 * c.value * (Number(inp.hrat) || 0)) / 100, 11);
|
|
const point = inp.auto ? autoPoint(qty1) : Math.round(Number(inp.point) || 0);
|
|
const per = inp.labor ? 1 : 8;
|
|
const cqty = qday === 0 ? 0 : q(((Number(inp.lqty) || 0) * per) / qday, point);
|
|
return { ok: c.ok, error: c.error, cond: c.value, qday, point, cqty };
|
|
}
|
|
|
|
return { condFactor, autoPoint, compute, round: q };
|
|
})();
|
|
|
|
if (typeof window !== "undefined") window.STMATE_XRATE = StmateXRate;
|
|
if (typeof module !== "undefined" && module.exports) module.exports = StmateXRate;
|