- 시험 615 통과 · 브라우저 화면 13개·메뉴 90개 오류 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
63 lines
2.5 KiB
JavaScript
63 lines
2.5 KiB
JavaScript
/**
|
|
* STMATE w 8.0 — 단가 성분 검사 (ui_code_check.js) · 화면·DOM 없음(node 시험 가능)
|
|
* 근거: 지식DB STmate/old/20_분석 10 §3(검증 조건식 `TAMT1 <> MAMT1 + LAMT1 + SAMT1` 세 모듈 · TAMT = 총계)
|
|
* · 코드종류별 성분 — L → LAMT = TAMT · M → MAMT = TAMT · S → SAMT = TAMT · 복합/W → TAMT = M + L + S
|
|
* 차수 칸 1~4 마다 · 내역(BOQ) 단가코드 행은 단가 칸(TAMTn)과 금액 칸(T_AMTn) 둘 다
|
|
*/
|
|
(function (global) {
|
|
"use strict";
|
|
|
|
const txt = (v) => String(v == null ? "" : v).trim();
|
|
const num = (v) => {
|
|
const n = parseFloat(txt(v).replace(/,/g, ""));
|
|
return Number.isFinite(n) ? n : 0;
|
|
};
|
|
const OWN = { M: "M", L: "L", S: "S" };
|
|
const STRUCT = /^(T\d|E\d|C\d|:)$/;
|
|
const near = (a, b) => Math.abs(a - b) < 1e-6;
|
|
|
|
// 한 칸 무리 검사 — pre(단가 "" · 금액 "_")
|
|
function checkSlot(r, code, s, pre, where) {
|
|
const out = [];
|
|
const f = (k) => `${k}${pre}AMT${s}`;
|
|
if (!(f("T") in r)) return out;
|
|
const v = { M: num(r[f("M")]), L: num(r[f("L")]), S: num(r[f("S")]), T: num(r[f("T")]) };
|
|
if (!near(v.T, v.M + v.L + v.S))
|
|
out.push({ where, code, slot: s, rule: "sum", msg: `${f("T")} ≠ 재+노+경`, v });
|
|
const own = OWN[code[0]];
|
|
if (own && ["M", "L", "S"].some((k) => k !== own && v[k] !== 0))
|
|
out.push({ where, code, slot: s, rule: "own", msg: `${own} 코드에 다른 비목 금액`, v });
|
|
return out;
|
|
}
|
|
|
|
/** COSTN 행 — 차수 칸 1~4 · [{ where, code, slot, rule: sum|own, msg, v }] */
|
|
function checkComponents(rows) {
|
|
const out = [];
|
|
for (const r of rows || []) {
|
|
const c = txt(r.CODE).toUpperCase();
|
|
if (!c) continue;
|
|
for (const s of [1, 2, 3, 4]) out.push(...checkSlot(r, c, s, "", "COSTN"));
|
|
}
|
|
return out;
|
|
}
|
|
|
|
/** 내역 단가코드 행 — 단가(TAMTn) · 금액(T_AMTn) · % 줄은 금액 칸만 */
|
|
function checkBoq(rows) {
|
|
const out = [];
|
|
for (const r of rows || []) {
|
|
const c = txt(r.BDCODE1).toUpperCase();
|
|
if (!c || STRUCT.test(c)) continue;
|
|
const pct = txt(r.UNIT1).endsWith("%");
|
|
for (const s of [1, 2, 3, 4]) {
|
|
if (!pct) out.push(...checkSlot(r, c, s, "", `BOQ#${r._recno}`));
|
|
out.push(...checkSlot(r, c, s, "_", `BOQ#${r._recno}`));
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
const api = { checkComponents, checkBoq };
|
|
global.STMATE_UI_CODE_CHECK = api;
|
|
if (typeof module !== "undefined" && module.exports) module.exports = api;
|
|
})(typeof window !== "undefined" ? window : globalThis);
|