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

134 lines
4.4 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.
// REA f18804 → f16638 / f15868 / f15f40 / f16320 → f16ec8.
const EstMachine = (() => {
const { num, components, fixed, floating, even, sum } = EstMath;
const fuels = new Set([
"주연료",
"선박용경유",
"전력",
"경유",
"휘발유",
"중유",
"전",
"가스",
"가솔린",
"디젤",
"diesel",
"gasoline",
"heavyoil",
"lpg",
"l.p.g",
]);
function calculate(rows, criteria, options = {}) {
const settings = new Map(criteria.map((row) => [num(row.Index), num(row.TC)]));
const get = (index) => settings.get(index) ?? 0;
const output = structuredClone(rows),
titles = [],
errors = [];
let head = null,
body = [];
function finish() {
if (!head) return;
components.forEach(
(key) =>
(head[key] = floating(
body.filter((r) => num(r.CalcIndex) < 2).reduce((n, r) => n + num(r[key]), 0),
)),
);
head.TC = sum(head);
titles.push({
...head,
OTC: head.TC,
ONC: head.NC,
OGC: head.GC,
OJC: head.JC,
OSC: head.SC,
});
}
for (const row of output) {
const index = num(row.Index),
link = num(row.LinkIndex);
if (index > 0 && link !== 57) {
finish();
head = row;
body = [];
continue;
}
if (!head || row.Index == null) continue;
if (link === 52) {
finish();
const title = titles[titles.length - 1],
rate = num(row.GN) / 100;
components.forEach((key) => (head[key] = floating(num(title[key]) * rate)));
head.TC = sum(head);
Object.assign(title, head, { NachalRatio: num(row.GN) });
row.TU = title.OTC;
head = null;
body = [];
continue;
}
if (![0, 2].includes(num(row.CalcIndex))) {
body.push(row);
continue;
}
components.forEach((key) => (row[key] = 0));
const q = num(row.GN) / (["%", "%"].includes(row.Unite) ? 100 : 1),
rate = 1 + num(row.Ratio) / 100;
const digits = EstMath.even(get(index));
let value = 0,
field = "JC";
if (index === -3) {
const currency = String(row.Unite || "")[0];
if (currency === "\\") value = num(row.TU) * q * 1e-7;
else if ("$PEFLMY".includes(currency || "\u0000")) {
let exchange = get(currency.charCodeAt(0));
if (currency === "L" && !settings.has(76)) exchange = get(70);
if (currency === "Y") exchange /= 100;
if (!exchange) errors.push(`${head.Name}: 환율 없음 (${currency})`);
const cut = options.DollarCostCut ? 1000 : 1;
// f1580c receives two Currency integers; binary float multiplication can
// turn an exact thousand (226644000) into the previous thousand.
const converted =
Number(
(BigInt(even(num(row.TU) * 10000)) * BigInt(even(exchange * 10000))) /
BigInt(cut * 100000000),
) * cut;
value = converted * q * 1e-7;
} else value = num(row.TU) * q;
value = fixed((even(value * 10000) / 10000) * rate, digits);
} else if (index === -2) {
let unitPrice = num(row.TU),
quantity = q;
if (String(row.Name || "").includes("잡")) {
const fuel = [...body].reverse().find(
(r) =>
num(r.Index) === -2 &&
fuels.has(
String(r.Name || "")
.replace(/\s/g, "")
.toLowerCase(),
),
);
unitPrice = fuel ? num(fuel.GC) || (num(fuel.SCheck) === 3 ? num(fuel.JC) : 0) : 0;
row.TU = unitPrice;
row.Unite = "%";
quantity = num(row.GN) / 100;
}
value = fixed(even(even(unitPrice * quantity * 10000) * rate) / 10000, digits);
field = num(row.SCheck) === 3 ? "JC" : "GC";
} else if (index === -1) {
const coefficient = Math.trunc(get(num(row.NCGasu)) * 1e10) / 1e10;
let price = num(row.TU) * coefficient;
if (options.JDLCalcMethod) price = floating(price, 1);
value = fixed(even(even(price * q * 10000) * rate) / 10000, digits);
field = "NC";
}
row[field] = value;
row.TC = sum(row);
body.push(row);
}
finish();
return { rows: output, titles, errors };
}
return { calculate };
})();