fix(est): apply selected quantity calculations
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user