// 「조달청 표준공사코드 적용」 대화 화면 — 왼쪽 조달청 목록(불러온 PPS 표) · 오른쪽 작업데이타 7종 탭. 계산은 native-code-change.js.
const EstCodeChangeView = (() => {
const PAGE = 100,
COLORS = { 1: "#fff59d", 2: "#f8d7e0", 3: "#ffcc80" };
const C = () => EstCodeChange;
function open(state, tag) {
const view = state.view,
guess = {
HeadMainDat: 103,
CostMainDat: 104,
MachMainDat: 105,
SilJukDat: 21,
EstiMateDat: 101,
StuffcDat: 5,
LaborcDat: 6,
}[view];
const cc = (state.codeChange ||= {
pps: {},
word: "",
rowWord: "",
autoMove: true,
nameChange: false,
});
cc.tag = tag ?? cc.tag ?? guess ?? 6;
cc.rows = C().load(state.project, cc.tag);
C().validate(state.project, cc.tag, cc.rows);
cc.sel = cc.rows.length ? 0 : undefined;
cc.page = 0;
cc.dirty = false;
cc.pick = undefined;
draw(state);
}
function ppsKind(tag) {
return [21, 103, 104].includes(tag) ? "HEAD" : "STUFFC";
}
function shownRows(cc) {
const w = String(cc.rowWord || "").replace(/[\s|()]/g, "");
return cc.rows
.map((r, i) => ({ r, i }))
.filter(
({ r }) =>
!w ||
(cc.rowMode === "name"
? `${r.Name}${r.Size}`.replace(/[\s|()]/g, "").includes(w)
: String(r.OldCode)
.replace(/[\s|()]/g, "")
.includes(w)),
);
}
function draw(state) {
const { esc } = EstApp,
cc = state.codeChange,
C2 = C(),
list = cc.pps[ppsKind(cc.tag)] || [],
found = C2.search(list, cc.word).slice(0, PAGE),
rows = shownRows(cc),
pages = Math.max(1, Math.ceil(rows.length / PAGE)),
page = Math.min(cc.page, pages - 1);
const tabs = C2.ORDER.map(
(t) =>
``,
).join("");
const left = `
`;
const body = rows
.slice(page * PAGE, page * PAGE + PAGE)
.map(
({ r, i }) =>
`${[
``,
esc(r.Index ?? ""),
esc(r.OldCode),
``,
esc(r.Name),
esc(r.Size),
esc(r.Unite),
esc(r.Bigo),
]
.map((v) => `| ${v} | `)
.join("")}
`,
)
.join("");
const user = cc.pick ? safeUser(state) : "";
const right = `${tabs}
${rows.length}행 · ${page + 1}/${pages}
| No | 당초코드 | 변경코드 | 명칭 | 규격 | 단위 | 비고 |
${body}
*조달청호환 코드로 미변경(노랑), 중복코드(연분홍 비고란 참조), 코드자리수틀림(진황색)*
`;
const tools = [
``,
``,
``,
``,
``,
``,
``,
``,
``,
``,
].join(" ");
EstApp.showDialog(
`조달청 표준공사코드 적용 — ${C2.NAMES[cc.tag]}`,
`${cc.message ? `${esc(cc.message)}
` : ""}${left}${right}
${tools}
`,
);
cc.message = "";
}
function safeUser(state) {
const cc = state.codeChange;
if (!cc.pick || [21, 105, 101].includes(cc.tag)) return "";
try {
return C().userCode(state.project, cc.tag, cc.rows, cc.pick.Code);
} catch {
return "";
}
}
async function run(name, state, node) {
const cc = state.codeChange;
if (name === "code-change") return open(state);
if (!cc) return;
const C2 = C();
if (name === "code-change-tab") {
if (cc.dirty && confirm(`변경된 ${C2.NAMES[cc.tag]} 의 코드를 내역서 전체에 적용할까요?`))
applyNow(state);
return open(state, Number(node.dataset.tag));
}
if (name === "code-change-search")
cc.word = document.querySelector("[data-cc-word]")?.value ?? "";
else if (name === "code-change-all") cc.word = "";
else if (name === "code-change-rowsearch") {
cc.rowWord = document.querySelector("[data-cc-rowword]")?.value ?? "";
cc.rowMode = document.querySelector("[data-cc-rowmode]")?.value;
cc.page = 0;
} else if (name === "code-change-page")
cc.page = Math.max(0, cc.page + Number(node.dataset.step));
else if (name === "code-change-input" || name === "code-change-user") {
if (!cc.pick) throw Error("조달청코드 목록에서 코드를 고르세요.");
const code = name === "code-change-user" ? safeUser(state) : cc.pick.Code;
C2.input(
state.project,
cc.tag,
cc.rows,
cc.sel,
code,
name === "code-change-input" && cc.nameChange ? { ...cc.pick, nameChange: true } : null,
);
cc.dirty = true;
if (cc.autoMove && cc.sel < cc.rows.length - 1) cc.sel++;
} else if (name === "code-change-cancel") C2.cancel(cc.rows, cc.sel);
else if (name === "code-change-auto") {
C2.auto(cc.rows);
cc.dirty = true;
} else if (name === "code-change-dasan") {
if (!confirm("코드를 일련번호로 새로 부여하시겠습니까?")) return;
C2.dasan(cc.rows, cc.tag);
cc.dirty = true;
} else if (name === "code-change-bulk") return pickEstx(state);
else if (name === "code-change-apply") {
if (!confirm(`변경된 ${C2.NAMES[cc.tag]} 의 코드를 내역서 전체에 적용할까요?`)) return;
applyNow(state);
} else if (name === "code-change-close") {
if (
cc.dirty &&
!confirm("내역서에 변경된 코드를 적용하지 않았습니다.코드변경작업을 종료하시겠습니까?")
)
return;
EstApp.byId("dialog").close();
state.codeChange = { ...cc, rows: [], dirty: false };
return;
}
draw(state);
}
function applyNow(state) {
const cc = state.codeChange,
C2 = C();
if (
C2.validate(state.project, cc.tag, cc.rows) &&
!confirm("조달청코드로 변경안된 데이타가 있습니다.그래도 적용하시겠습니까??")
)
return;
let count = 0;
EstApp.change((project) => (count = C2.apply(project, cc.tag, cc.rows)));
cc.dirty = false;
state.notice = `${C2.NAMES[cc.tag]}의 코드변경이 완료 되었습니다. (${count}행)`;
}
function pickEstx(state) {
const cc = state.codeChange,
picker = document.createElement("input");
picker.type = "file";
picker.accept = ".estx";
picker.addEventListener("change", async () => {
try {
const file = picker.files[0];
if (!file) return;
if (
!confirm(
`현재 작업데이타의 ${C().NAMES[cc.tag]} 코드를 "${file.name}"의 코드로 변경하시겠습니까?`,
)
)
return;
const source = await EstApp.api(`/api/import?name=${encodeURIComponent(file.name)}`, {
method: "POST",
body: file,
});
const n = C().bulk(state.project, cc.tag, cc.rows, source);
if (n) cc.dirty = true;
cc.message = n
? `${n}개 코드를 바꿨습니다. 적용을 누르세요.`
: "코드가 변경된 항목이 없습니다.";
} catch (error) {
cc.message = error.message;
}
draw(state);
});
picker.click();
}
function install() {
document.addEventListener("change", async (event) => {
const t = event.target,
state = EstApp.state,
cc = state.codeChange;
if (!cc?.rows) return;
try {
if (t.dataset.ccRow !== undefined) cc.sel = Number(t.dataset.ccRow);
else if (t.dataset.ccPick !== undefined)
cc.pick = EstCodeChange.search(cc.pps[ppsKind(cc.tag)] || [], cc.word)[
Number(t.dataset.ccPick)
];
else if (t.dataset.ccOpt !== undefined) cc[t.dataset.ccOpt] = t.checked;
else if (t.dataset.ccCode !== undefined) {
const i = Number(t.dataset.ccCode);
C().input(state.project, cc.tag, cc.rows, i, t.value);
cc.dirty = true;
} else if (t.dataset.ccPps !== undefined) {
const file = t.files[0];
if (!file) return;
const rows = await EstApp.api("/api/pps-table", { method: "POST", body: file });
const kind = rows.some((r) => /공사$/.test(r.Gubun ?? "")) ? "HEAD" : "STUFFC";
cc.pps[kind] = rows;
cc.message = `조달청 ${kind === "HEAD" ? "공종" : "물품"} 코드 ${rows.length}개를 불러왔습니다.`;
} else return;
} catch (error) {
cc.message = error.message;
}
draw(state);
});
}
const names = new Set([
"code-change",
"code-change-tab",
"code-change-search",
"code-change-all",
"code-change-rowsearch",
"code-change-page",
"code-change-input",
"code-change-user",
"code-change-cancel",
"code-change-auto",
"code-change-dasan",
"code-change-bulk",
"code-change-apply",
"code-change-close",
]);
function handle(name, state, node) {
if (!names.has(name)) return false;
run(name, state, node).catch((error) => {
if (!state.codeChange?.rows) return void (state.notice = error.message);
state.codeChange.message = error.message;
draw(state);
});
return true;
}
if (typeof document !== "undefined" && document.addEventListener) install();
return { open, handle };
})();