Files
Aislo/tools/est-test/native-resources.js
T

113 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const EstResources = (() => {
const { num, components } = EstMath;
function calculate(input) {
const project = EstNative.calculate({
...structuredClone(input),
options: { ...input.options, SourceRefresh: true },
});
const tables = project.tables,
heads = EstNative.groups(tables.HeadMainDat),
costs = EstNative.groups(tables.CostMainDat),
output = new Map(),
errors = [...project.calculation.errors];
function record(kind, code, quantity, amount = 0) {
const source = (tables[EstNative.sourceTables[kind]] || []).find((row) => row.Code === code);
if (!source) {
errors.push(`동원 원천 없음: ${kind}/${code}`);
return;
}
const id = `${kind}:${code}`;
const row = output.get(id) || {
Code: code,
Name: source.Name,
Size: source.Size,
Unite: source.Unite,
kind,
quantity: 0,
amount: 0,
};
row.quantity += quantity;
row.amount += amount;
output.set(id, row);
}
function expand(kind, code, multiplier, path) {
const id = `${kind}:${code}`;
if (path.includes(id)) {
errors.push(`동원 순환 참조: ${id}`);
return;
}
if (kind === 104) {
const group = costs.get(code);
if (!group) {
errors.push(`산근 없음: ${code}`);
return;
}
for (const row of group.rows) {
if (!row.ResourceCode || row.ResourceFactor == null) continue;
if ([103, 104].includes(num(row.ResourceKind)))
expand(num(row.ResourceKind), row.ResourceCode, multiplier * num(row.ResourceFactor), [
...path,
id,
]);
else if (num(row.ResourceKind) === 105)
record(105, row.ResourceCode, 0, multiplier * num(row.TC));
else
record(
num(row.ResourceKind),
row.ResourceCode,
multiplier * num(row.ResourceFactor),
multiplier * num(row.TC),
);
}
return;
}
if (kind === 103) {
const group = heads.get(code);
if (!group) {
errors.push(`일위 없음: ${code}`);
return;
}
let rate = 1;
const bid = group.rows.find((row) => num(row.LinkIndex) === 52);
if (bid) rate = num(bid.GN) / 100;
for (const row of group.rows.slice(1)) {
if (num(row.CalcIndex) >= 2 || [51, 52, 58, 62, 68].includes(num(row.LinkIndex)))
continue;
const quantity =
(multiplier * num(row.GN) * rate) / (["%", "%"].includes(row.Unite) ? 100 : 1);
if ([103, 104].includes(num(row.LinkIndex)))
expand(num(row.LinkIndex), row.Code, quantity, [...path, id]);
else if (EstNative.sourceTables[num(row.LinkIndex)])
record(num(row.LinkIndex), row.Code, quantity, multiplier * num(row.TC));
}
return;
}
record(kind, code, multiplier);
}
for (const row of tables.EstMainDat) {
if (num(row.LinkIndex) === 54) break;
if (
num(row.Level) > 0 ||
num(row.CalcIndex) >= 2 ||
!EstNative.sourceTables[num(row.LinkIndex)]
)
continue;
expand(num(row.LinkIndex), row.Code, num(row.GN), []);
}
const rows = [...output.values()];
for (const row of rows)
if (row.kind === 105 && row.amount) {
const price = num(tables.MachTitleDat.find((r) => r.Code === row.Code)?.TC);
if (price) {
row.quantity += row.amount / price;
row.Unite = "HR";
} else {
row.Unite = "제외금액";
row.quantity = 0;
}
}
return { rows, errors: [...new Set(errors)] };
}
return { calculate };
})();