- 시험 615 통과 · 브라우저 화면 13개·메뉴 90개 오류 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
78 lines
3.5 KiB
JavaScript
78 lines
3.5 KiB
JavaScript
// STMATE 재현 앱 보호표시(UC) 일괄 손질 제외 · 코드종류별 성분 검사 — stdin = /api/load 결과 + {prot: [코드]}
|
|
// 결과 = 손질별 바뀐 코드(보호 없음 · 보호 있음) · 보호해제 자동할증 · 성분 검사 · 저장 요청 COSTN 칸
|
|
globalThis.window = globalThis;
|
|
const D = "../../tools/stmate-test/";
|
|
const Calc = require(D + "calc.js");
|
|
require(D + "view_prj_boq.js");
|
|
const UA = require(D + "ui_code_amt.js");
|
|
const U = require(D + "ui_dan.js");
|
|
const PA = require(D + "scr_edit_price.js");
|
|
const CK = require(D + "ui_code_check.js");
|
|
|
|
let buf = "";
|
|
process.stdin.setEncoding("utf8");
|
|
process.stdin.on("data", (x) => (buf += x));
|
|
process.stdin.on("end", () => {
|
|
const src = JSON.parse(buf);
|
|
const prot = new Set(src.prot || []);
|
|
const rowsOf = (mark) => {
|
|
const rows = JSON.parse(JSON.stringify(src.costn_rows));
|
|
if (mark) rows.forEach((r) => prot.has(U.codeOf(r)) && (r.UC = "T"));
|
|
return rows;
|
|
};
|
|
const codes = (list) => list.map((x) => x.code).sort();
|
|
const ops = {
|
|
adoptAll: (rows) => U.adoptAll(rows, "min", { kinds: "MLS", keepUser: false }),
|
|
edtHal: (rows) => U.edtHal(rows, { kinds: "MLS", pct: 110 }),
|
|
halAll: (rows) => UA.halAll(rows, { kinds: "MLSW", how: "rate", value: 5 }),
|
|
chgAmt: (rows) => UA.chgAmt(rows, { kinds: "MLSW", from: 1, to: 1, rate: 103 }),
|
|
adoptCand: (rows) => PA.adoptCandidates(rows, { mode: "min", slot: 1 }).changed,
|
|
};
|
|
const out = { ops: {} };
|
|
for (const [k, fn] of Object.entries(ops)) {
|
|
const a = fn(rowsOf(false)),
|
|
rows = rowsOf(true),
|
|
b = fn(rows);
|
|
const untouched = [...prot].every((c) => {
|
|
const r0 = src.costn_rows.find((r) => U.codeOf(r) === c),
|
|
r1 = rows.find((r) => U.codeOf(r) === c);
|
|
return ["MAMT1", "LAMT1", "SAMT1", "TAMT1"].every((f) => r0[f] === r1[f]);
|
|
});
|
|
out.ops[k] = { plain: codes(a), marked: codes(b), untouched };
|
|
}
|
|
// 보호해제 자동할증 — 그 행만 일괄할증과 같은 값
|
|
{
|
|
const rows = rowsOf(true);
|
|
const c = [...prot][0];
|
|
const r = rows.find((x) => U.codeOf(x) === c);
|
|
const hal = { how: "rate", value: 5, digits: 0, mode: "trunc" };
|
|
const res = U.setProtect(r, false, { autoHal: hal });
|
|
const ref = UA.halAll(rowsOf(false), Object.assign({ kinds: c[0], codes: [c] }, hal));
|
|
out.autoHal = { uc: r.UC, got: res.hal && res.hal.to, want: ref[0] && ref[0].to };
|
|
}
|
|
out.bdProtected = src.costn_rows.filter(
|
|
(r) => /^[BD]/.test(U.codeOf(r)) && U.isProtected(r),
|
|
).length;
|
|
// 성분 검사 — 원본 그대로 · 일부러 어긋낸 행
|
|
{
|
|
out.check = CK.checkComponents(src.costn_rows);
|
|
out.checkBoq = Object.values(src.boq_tables || {}).flatMap((rows) => CK.checkBoq(rows));
|
|
const rows = rowsOf(false);
|
|
const m = rows.find((r) => /^M/.test(U.codeOf(r)) && Number(r.MAMT1) > 0);
|
|
const b = rows.find((r) => /^B/.test(U.codeOf(r)) && Number(r.TAMT1) > 0);
|
|
m.LAMT1 = "5";
|
|
b.TAMT1 = String(Number(b.TAMT1) + 1);
|
|
out.broken = { m: U.codeOf(m), b: U.codeOf(b), res: CK.checkComponents(rows) };
|
|
}
|
|
// 저장 요청 — 보호 켠 행만 COSTN UC 가 바뀜
|
|
{
|
|
const load = JSON.parse(JSON.stringify(src));
|
|
load.costn_rows.forEach((r) => prot.has(U.codeOf(r)) && U.setProtect(r, true));
|
|
const ctx = { state: load.sim_state, dbfData: load, currentSourcePath: load.source_path };
|
|
ctx.uiState = { editedSmtMap: {} };
|
|
ctx.computed = Calc.calculateAll(ctx.state);
|
|
out.payload = window.STMATE_VIEW_PRJ_BOQ.buildSavePayload(ctx);
|
|
}
|
|
process.stdout.write(JSON.stringify(out));
|
|
});
|