feat(est): reproduce native tables and calculations
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
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 };
|
||||
})();
|
||||
Reference in New Issue
Block a user