fix(est): apply selected quantity calculations

This commit is contained in:
2026-11-07 07:37:40 +09:00
parent 864ff1f55b
commit 4c6bb9d70a
5 changed files with 71 additions and 40 deletions
+41 -19
View File
@@ -113,6 +113,44 @@ const EstQuantity = (() => {
errors: result.errors,
};
}
function totals(project, selected) {
let items;
if (selected && selected !== "manual") {
const sheet = project.quantitySheets?.find((s) => s.Code === selected);
if (!sheet) throw Error("선택한 수량산출서가 없습니다.");
const output = calculate(sheet);
if (output.errors.length) throw Error(output.errors.join(" / "));
items = output.items;
} else {
const values = Object.create(null);
items = (project.quantities || []).map((row) => {
if (!row.Code || Object.hasOwn(values, row.Code))
throw Error(`산출코드가 비어 있거나 중복됩니다: ${row.Code || ""}`);
const GN = EstMath.floating(
EstExpression.evaluate(row.formula || "0", (key) => values[key]),
row.digits ?? 2,
1,
);
values[row.Code] = GN;
return { ...row, GN };
});
}
const quantities = new Map();
for (const item of items) {
const code = item.TargetCode ?? item.LinkCode;
if (!code) continue;
const targets = project.tables.EstMainDat.filter((r) => r.Code === code && !Number(r.Level));
if (!targets.length) throw Error(`연결 내역코드 없음: ${code}`);
if (targets.length > 1) throw Error(`연결 내역코드 중복: ${code}`);
quantities.set(code, (quantities.get(code) || 0) + Number(item.GN || 0));
}
if (!quantities.size) throw Error("연결할 내역코드를 먼저 입력하세요.");
return quantities;
}
function applyTotals(project, quantities) {
for (const row of project.tables.EstMainDat)
if (quantities.has(row.Code) && !Number(row.Level)) row.GN = quantities.get(row.Code);
}
function selector(state) {
const { esc } = EstApp;
return `<div class="business-tools"><label>수량산출서 <select id="quantity-sheet-choice"><option value="manual">수식표 직접 작성</option>${(state.project.quantitySheets || []).map((sheet) => `<option value="${esc(sheet.Code)}" ${state.quantitySheet === sheet.Code ? "selected" : ""}>${esc(sheet.Name || sheet.Code)}</option>`).join("")}</select></label><button data-quantity-new>새 산출서</button></div>`;
@@ -224,30 +262,14 @@ const EstQuantity = (() => {
}
if (!event.target.closest("[data-quantity-apply]")) return;
try {
const output = calculate(sheet);
if (output.errors.length) throw Error(output.errors.join(" / "));
const quantities = new Map();
for (const item of output.items)
if (item.TargetCode ?? item.LinkCode) {
const code = item.TargetCode ?? item.LinkCode;
const targets = state.project.tables.EstMainDat.filter(
(r) => r.Code === code && !Number(r.Level),
);
if (!targets.length) throw Error(`연결 내역코드 없음: ${code}`);
if (targets.length > 1) throw Error(`연결 내역코드 중복: ${code}`);
quantities.set(code, (quantities.get(code) || 0) + Number(item.GN || 0));
}
if (!quantities.size) throw Error("연결할 내역코드를 먼저 입력하세요.");
EstApp.change(() => {
for (const row of state.project.tables.EstMainDat)
if (quantities.has(row.Code) && !Number(row.Level)) row.GN = quantities.get(row.Code);
});
const quantities = totals(state.project, state.quantitySheet);
EstApp.change(() => applyTotals(state.project, quantities));
} catch (error) {
EstApp.state.notice = error.message;
EstApp.render();
}
});
}
return { entities, fromWpt, calculate, selector, render, install };
return { entities, fromWpt, calculate, totals, applyTotals, selector, render, install };
})();
if (typeof module !== "undefined" && module.exports) module.exports = EstQuantity;