161 lines
6.4 KiB
JavaScript
161 lines
6.4 KiB
JavaScript
// 원본 줄 단위 연결 도구(spec_part 1~3):
|
|
// 비목별 단가 불러오기(TfrmHead popupCostNC·GC·JC·All 0xf1b54c) — 일위대가 줄의 하위 자료(견적·일위·단산·기계)에서 한 비목 단가만
|
|
// 남기고 나머지 단가 0, 기준비목(OCheck) := 고른 비목(0 전체·1 재료·2 노무·3 경비). 노임·자재·표준 줄은 거부.
|
|
// SUM 색인지정(popMainSumIndex, TfrmSetSumIndex): 고른 줄 SKind := 해제(0)·A(1)…Z(26) — 비율 줄(62)이 코드 글자로 모아 더함.
|
|
// 하위데이타 연결/끊기(mnuDataLink 0xf00e6c): 연결 줄은 끊고(LinkIndex 0, 값은 남김), 끊긴 줄은 일위→단산→기계→표준→견적→자재→노임
|
|
// 차례로 코드(없으면 품명·규격·단위 맞춤)를 찾아 코드·명칭·규격·단위·단가를 가져와 연결. 원본은 초점 한 줄, 웹은 고른 줄 모두.
|
|
const EstRowLinks = (() => {
|
|
const num = (v) => Number(v) || 0;
|
|
const SRC = {
|
|
101: "EstiMateDat",
|
|
103: "HeadTitleDat",
|
|
104: "CostTitleDat",
|
|
105: "MachTitleDat",
|
|
21: "SilJukDat",
|
|
5: "StuffcDat",
|
|
6: "LaborcDat",
|
|
};
|
|
const ORDER = [103, 104, 105, 21, 101, 5, 6];
|
|
const LINKED = new Set([5, 6, 21, 101, 103, 104, 105, 211, 212, 213, 214, 215]);
|
|
const norm = (s) => String(s ?? "").replace(/\s/g, "");
|
|
function byCode(project, kind, code) {
|
|
const c = norm(code);
|
|
return c ? (project.tables[SRC[kind]] || []).find((r) => norm(r.Code) === c) : null;
|
|
}
|
|
|
|
function costPart(project, row, tag) {
|
|
const kind = num(row.LinkIndex);
|
|
if ([5, 6, 21].includes(kind)) throw Error("노임,자재,표준시장단가는 적용할수 없습니다.");
|
|
const src = SRC[kind] ? byCode(project, kind, row.Code) : null,
|
|
v = (k) => num(src?.[k]);
|
|
row.OCheck = tag;
|
|
row.NU = row.GU = row.JU = row.SU = 0;
|
|
if (tag === 0) Object.assign(row, { NU: v("NC"), GU: v("GC"), JU: v("JC"), SU: v("SC") });
|
|
else if (tag === 2) row.NU = v("NC");
|
|
else if (tag === 1) row.GU = v("GC");
|
|
else Object.assign(row, { JU: v("JC"), SU: v("SC") });
|
|
}
|
|
|
|
function sumIndex(view, row, k) {
|
|
if (view === "EstMainDat") {
|
|
if (num(row.Level) > 0 && !num(row.GN))
|
|
throw Error("레벨지정한 라인의 값을 더할값으로 지정할수없습니다.");
|
|
if ([52, 53, 55, 57].includes(num(row.LinkIndex)) || num(row.Index) !== 0)
|
|
throw Error("현재라인의 값은 더할값으로 지정할수없습니다.");
|
|
} else if (num(row.LinkIndex) === 53 || num(row.Index) > 0)
|
|
throw Error("현재라인의 값은 더할값으로 지정할수없습니다.");
|
|
row.SKind = k;
|
|
}
|
|
|
|
function toggle(project, view, row) {
|
|
const li = num(row.LinkIndex);
|
|
if (li) {
|
|
if (LINKED.has(li)) row.LinkIndex = 0;
|
|
return li && LINKED.has(li) ? "unlink" : "skip";
|
|
}
|
|
const tag = { EstMainDat: 1, HeadMainDat: 2, MachMainDat: 4 }[view] ?? 0;
|
|
for (const kind of ORDER) {
|
|
const src = norm(row.Code)
|
|
? byCode(project, kind, row.Code)
|
|
: EstAutoLink.find(project, kind, EstAutoLink.key(row, tag));
|
|
if (!src) continue;
|
|
Object.assign(row, {
|
|
Code: src.Code,
|
|
Name: src.Name ?? "",
|
|
Size: src.Size ?? "",
|
|
Unite: src.Unite ?? "",
|
|
LinkIndex: kind,
|
|
NU: num(src.NC),
|
|
GU: num(src.GC),
|
|
JU: num(src.JC),
|
|
SU: num(src.SC),
|
|
});
|
|
if (kind === 5) row.GU = num(src.TC);
|
|
if (kind === 6) row.NU = num(src.TC);
|
|
row.TU = row.NU + row.GU + row.JU + row.SU;
|
|
return "link";
|
|
}
|
|
throw Error("해당 하위data를 찾지못해 연결시키지 못했습니다.");
|
|
}
|
|
|
|
function picked(state, views) {
|
|
const rows = state.project.tables[state.view] || [],
|
|
list = [...state.selection].filter((i) => rows[i]).sort((a, b) => a - b);
|
|
if (!views.includes(state.view) || !list.length)
|
|
throw Error(
|
|
`${views.length > 2 ? "내역서·일위대가·단가산출·기계경비" : "내역서·일위대가"}에서 줄을 고르세요.`,
|
|
);
|
|
return list;
|
|
}
|
|
|
|
function handle(name, state) {
|
|
if (name === "cost-part") {
|
|
if (state.view !== "HeadMainDat") throw Error("일위대가 화면에서 쓰세요.");
|
|
const list = picked(state, ["HeadMainDat"]);
|
|
EstActions.form(
|
|
"비목별 단가 불러오기",
|
|
[
|
|
{
|
|
name: "tag",
|
|
label: "불러올 비목",
|
|
value: 0,
|
|
choices: [
|
|
[0, "전체비목 불러오기"],
|
|
[2, "노무비만 불러오기"],
|
|
[1, "재료비만 불러오기"],
|
|
[3, "경비만 불러오기"],
|
|
],
|
|
},
|
|
],
|
|
(values) => {
|
|
const probe = structuredClone(state.project);
|
|
list.forEach((i) => costPart(probe, probe.tables.HeadMainDat[i], Number(values.tag)));
|
|
EstApp.change((project) =>
|
|
list.forEach((i) =>
|
|
costPart(project, project.tables.HeadMainDat[i], Number(values.tag)),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
} else if (name === "sum-index") {
|
|
const list = picked(state, ["EstMainDat", "HeadMainDat"]);
|
|
EstActions.form(
|
|
"Sum 색인",
|
|
[
|
|
{
|
|
name: "k",
|
|
label: "색인",
|
|
value: 1,
|
|
choices: [
|
|
[0, "해제"],
|
|
...Array.from({ length: 26 }, (_, i) => [i + 1, String.fromCharCode(65 + i)]),
|
|
],
|
|
},
|
|
],
|
|
(values) => {
|
|
const rows = state.project.tables[state.view];
|
|
list.forEach((i) => sumIndex(state.view, structuredClone(rows[i]), 0));
|
|
EstApp.change((project) =>
|
|
list.forEach((i) =>
|
|
sumIndex(state.view, project.tables[state.view][i], Number(values.k)),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
} else if (name === "data-link") {
|
|
const list = picked(state, ["EstMainDat", "HeadMainDat", "CostMainDat", "MachMainDat"]);
|
|
const probe = structuredClone(state.project);
|
|
list.forEach((i) => toggle(probe, state.view, probe.tables[state.view][i]));
|
|
let out = [];
|
|
EstApp.change((project) => {
|
|
out = list.map((i) => toggle(project, state.view, project.tables[state.view][i]));
|
|
});
|
|
const linked = out.filter((r) => r === "link").length,
|
|
unlinked = out.filter((r) => r === "unlink").length;
|
|
state.notice = `연결 ${linked}줄 · 끊기 ${unlinked}줄`;
|
|
} else return false;
|
|
return true;
|
|
}
|
|
return { costPart, sumIndex, toggle, handle };
|
|
})();
|