116 lines
5.1 KiB
JavaScript
116 lines
5.1 KiB
JavaScript
const EstIssues = (() => {
|
|
let page = 0;
|
|
const grouped = new Set(["HeadMainDat", "CostMainDat", "MachMainDat"]);
|
|
const kinds = {
|
|
5: "StuffcDat",
|
|
6: "LaborcDat",
|
|
21: "SilJukDat",
|
|
101: "EstiMateDat",
|
|
103: "HeadMainDat",
|
|
104: "CostMainDat",
|
|
105: "MachMainDat",
|
|
};
|
|
function scan(project) {
|
|
const issues = [],
|
|
sources = new Map();
|
|
for (const [kind, table] of Object.entries(kinds)) {
|
|
const codes = new Map();
|
|
(project.tables[table] || []).forEach((row, index) => {
|
|
if (!row.Code || (grouped.has(table) && !(Number(row.Index) > 0))) return;
|
|
const list = codes.get(String(row.Code)) || [];
|
|
list.push({ row, index });
|
|
codes.set(String(row.Code), list);
|
|
});
|
|
sources.set(Number(kind), codes);
|
|
for (const [code, list] of codes)
|
|
if (list.length > 1)
|
|
for (const { index } of list) issues.push({ table, index, code, message: "코드 중복" });
|
|
}
|
|
for (const table of ["EstMainDat", "HeadMainDat", "MachMainDat"]) {
|
|
(project.tables[table] || []).forEach((row, index) => {
|
|
if (Number(row.Level) > 0 || Number(row.Index) > 0 || !row.Code) return;
|
|
const codes = sources.get(Number(row.LinkIndex));
|
|
if (!codes) return;
|
|
const matches = codes.get(String(row.Code)) || [];
|
|
if (!matches.length)
|
|
issues.push({ table, index, code: row.Code, message: "연결 자료 없음" });
|
|
else if (matches.length > 1)
|
|
issues.push({ table, index, code: row.Code, message: "연결 코드 중복" });
|
|
else
|
|
for (const field of ["Name", "Size"]) {
|
|
const a = row[field],
|
|
b = matches[0].row[field];
|
|
if (a && b && EstNative.normalize(a) !== EstNative.normalize(b))
|
|
issues.push({
|
|
table,
|
|
index,
|
|
code: row.Code,
|
|
message: field === "Name" ? "연결 품명 차이" : "연결 규격 차이",
|
|
});
|
|
}
|
|
});
|
|
}
|
|
const costs = project.tables.CostMainDat || [],
|
|
costGroups = EstNative.groups(costs);
|
|
for (const message of project.calculation?.errors || []) {
|
|
const text = String(message),
|
|
match = text.match(/^(.+):(\d+) /),
|
|
code = match?.[1],
|
|
group = code && costGroups.get(code),
|
|
offset = match ? Number(match[2]) - 1 : -1,
|
|
unique = group && sources.get(104)?.get(code)?.length === 1,
|
|
index = unique && offset >= 0 && offset < group.rows.length ? group.start + offset : -1;
|
|
issues.push({
|
|
table: index >= 0 ? "CostMainDat" : "",
|
|
index,
|
|
code: index >= 0 ? code : "",
|
|
message: text,
|
|
});
|
|
}
|
|
return issues;
|
|
}
|
|
function render() {
|
|
const { state, esc, byId, titles } = EstApp,
|
|
issues = scan(state.project);
|
|
page = Math.max(0, Math.min(page, Math.ceil(issues.length / 100) - 1));
|
|
const rows = issues.slice(page * 100, page * 100 + 100);
|
|
byId("work-content").innerHTML =
|
|
`<div class="business-tools"><b>자료 오류 검색</b><span>${issues.length}건 · ${page + 1}/${Math.max(1, Math.ceil(issues.length / 100))}쪽</span><button data-issue-page="-1" ${page === 0 ? "disabled" : ""}>이전</button><button data-issue-page="1" ${(page + 1) * 100 >= issues.length ? "disabled" : ""}>다음</button></div><p>연결 품명·규격 차이는 확인이 필요한 항목으로 표시합니다.</p><table class="sheet"><thead><tr><th>자료</th><th>행</th><th>코드</th><th>내용</th><th>이동</th></tr></thead><tbody>${rows.map((item) => `<tr><td>${esc(titles[item.table] || item.table || "전체 계산")}</td><td>${item.index >= 0 ? item.index + 1 : ""}</td><td>${esc(item.code)}</td><td>${esc(item.message)}</td><td>${item.table ? `<button data-issue-table="${esc(item.table)}" data-issue-row="${item.index}">행 열기</button>` : ""}</td></tr>`).join("")}</tbody></table>`;
|
|
}
|
|
function install() {
|
|
document.addEventListener("click", (event) => {
|
|
const step = event.target.closest("[data-issue-page]");
|
|
if (step) {
|
|
page += Number(step.dataset.issuePage);
|
|
render();
|
|
return;
|
|
}
|
|
const node = event.target.closest("[data-issue-table]");
|
|
if (!node) return;
|
|
const table = node.dataset.issueTable,
|
|
index = Number(node.dataset.issueRow),
|
|
rows = EstApp.state.project.tables[table] || [];
|
|
if (!rows[index]) return;
|
|
let group = "";
|
|
if (grouped.has(table))
|
|
for (const [code, item] of EstNative.groups(rows))
|
|
if (index >= item.start && index < item.start + item.rows.length) {
|
|
group = code;
|
|
break;
|
|
}
|
|
if (grouped.has(table) && !group) {
|
|
EstApp.state.notice = "묶음 코드가 중복되거나 해당 행의 묶음이 없어 이동할 수 없습니다.";
|
|
EstApp.render();
|
|
return;
|
|
}
|
|
EstApp.navigate(table, group);
|
|
const visible = EstApp.visibleRows(),
|
|
position = visible.findIndex((item) => item.index === index);
|
|
if (position >= 0) EstApp.state.page = Math.floor(position / 100);
|
|
EstApp.state.selection = new Set([index]);
|
|
EstApp.render();
|
|
});
|
|
}
|
|
return { scan, render, install };
|
|
})();
|