113 lines
3.7 KiB
JavaScript
113 lines
3.7 KiB
JavaScript
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 };
|
||
})();
|