161 lines
7.2 KiB
JavaScript
161 lines
7.2 KiB
JavaScript
const fs = require("node:fs");
|
|
const path = require("node:path");
|
|
const vm = require("node:vm");
|
|
const base = path.resolve(__dirname, "../../tools/est-test");
|
|
const context = vm.createContext({ structuredClone, console });
|
|
for (const file of [
|
|
"native-math.js",
|
|
"native-formula.js",
|
|
"native-machine.js",
|
|
"native-rows.js",
|
|
"native-text.js",
|
|
"native-quantity.cjs",
|
|
"native-wonga.js",
|
|
"native-engine.js",
|
|
"native-escalation.js",
|
|
"native-progress.js",
|
|
"native-business.js",
|
|
"native-resources.js",
|
|
"native-schedule.js",
|
|
"native-model.js",
|
|
"native-c3r.js",
|
|
"native-exchange.js",
|
|
"native-verify.js",
|
|
]) {
|
|
vm.runInContext(fs.readFileSync(path.join(base, file), "utf8"), context, { filename: file });
|
|
}
|
|
const project = JSON.parse(fs.readFileSync(path.join(base, "sample.json"), "utf8"));
|
|
context.project = project;
|
|
const command = process.argv[2];
|
|
let result;
|
|
if (command === "machine")
|
|
result = vm.runInContext(
|
|
"EstMachine.calculate(project.tables.MachMainDat, project.tables.MachGijunDat, project.options)",
|
|
context,
|
|
);
|
|
else if (command === "head")
|
|
result = vm.runInContext("EstRows.head(project.tables.HeadMainDat, project.options)", context);
|
|
else if (command === "estimate")
|
|
result = vm.runInContext("EstRows.estimate(project.tables.EstMainDat, project.options)", context);
|
|
else if (command === "text")
|
|
result = vm.runInContext(
|
|
"EstText.calculate(project.tables.CostMainDat, project.options)",
|
|
context,
|
|
);
|
|
else if (command === "wonga")
|
|
result = vm.runInContext("EstWonga.calculate(project.tables.Wonga, project.options)", context);
|
|
else if (command === "all") result = vm.runInContext("EstNative.calculate(project)", context);
|
|
else if (command === "text-layout") {
|
|
context.cases = JSON.parse(
|
|
fs.readFileSync(path.join(__dirname, "fixtures/est_text_layout_cases.json"), "utf8"),
|
|
);
|
|
result = vm.runInContext(
|
|
"cases.map(item=>({code:item.code,...EstText.calculate(item.rows)}))",
|
|
context,
|
|
);
|
|
} else if (command === "manual") {
|
|
project.options.AutoCalc = false;
|
|
project.tables.EstMainDat[1].GN += 100;
|
|
result = require(path.join(base, "server.cjs")).calculate(project);
|
|
} else if (command === "refresh")
|
|
result = vm.runInContext(
|
|
"project.options.SourceRefresh=true; EstNative.calculate(project)",
|
|
context,
|
|
);
|
|
else if (command === "repeat")
|
|
result = vm.runInContext(
|
|
'project.options.SourceRefresh=true; project.tables.LaborcDat.forEach(row=>{for(const key of ["Cost1","Cost2","Cost3","Cost4","Cost5","Cost6"]) row[key] = Number(row[key] || 0)*1.1}); const a=EstNative.calculate(project); [a,EstNative.calculate(a)]',
|
|
context,
|
|
);
|
|
else if (command === "import")
|
|
result = require(path.join(base, "import-estx.cjs")).importEstx(fs.readFileSync(process.argv[3]));
|
|
else if (command === "baseline-size") {
|
|
context.input = require(path.join(base, "import-estx.cjs")).importEstx(
|
|
fs.readFileSync(process.argv[3]),
|
|
);
|
|
const baseline = vm.runInContext("EstBusiness.baseline(input)", context);
|
|
result = {
|
|
bytes: Buffer.byteLength(JSON.stringify(baseline), "utf8"),
|
|
archivePreserved: baseline.originalArchive === context.input.originalArchive,
|
|
};
|
|
} else if (command === "blob-tail") {
|
|
const { blob } = require(path.join(base, "import-estx.cjs")),
|
|
bytes = Buffer.alloc(1536);
|
|
bytes.writeUInt32LE(2, 516);
|
|
bytes.writeUInt16LE(3, 520);
|
|
bytes.writeUInt32LE(7, 522);
|
|
bytes.writeUInt32LE(3, 526);
|
|
bytes.write("abc", 530);
|
|
bytes.writeUInt32LE(1, 1024);
|
|
bytes.writeUInt16LE(3, 1032);
|
|
bytes.write("xyz", 1042);
|
|
const value = blob(bytes, 1, 7).toString();
|
|
bytes.writeUInt32LE(4, 526);
|
|
bytes.writeUInt32LE(0, 516);
|
|
let truncated = "";
|
|
try {
|
|
blob(bytes, 1, 7);
|
|
} catch (error) {
|
|
truncated = error.message;
|
|
}
|
|
result = { value, truncated };
|
|
} else if (command === "extended") {
|
|
context.extended = JSON.parse(
|
|
fs.readFileSync(path.join(__dirname, "fixtures/est_native_extended.json"), "utf8"),
|
|
);
|
|
result = vm.runInContext(
|
|
`({
|
|
head: EstRows.head(extended.tables.HeadMainDat, extended.options),
|
|
text: EstText.calculate(extended.tables.CostMainDat, extended.options),
|
|
machine: EstMachine.calculate(extended.tables.MachMainDat, extended.tables.MachGijunDat, extended.options)
|
|
})`,
|
|
context,
|
|
);
|
|
} else if (command === "quantity") {
|
|
context.sheets = JSON.parse(
|
|
fs.readFileSync(path.join(__dirname, "fixtures/est_quantity_sheets.json"), "utf8"),
|
|
);
|
|
result = vm.runInContext(
|
|
"sheets.map(sheet=>({Code:sheet.Code,original:sheet.items,...EstQuantity.calculate(sheet)}))",
|
|
context,
|
|
);
|
|
} else if (command === "business")
|
|
result = vm.runInContext(
|
|
`
|
|
const p=EstNative.empty();
|
|
p.tables.StuffcDat=[{Code:'M',Name:'material',Cost1:100,ValueIndex:0}];
|
|
p.tables.HeadMainDat=[{Index:1,Code:'H',Name:'head'},{Index:0,Code:'M',LinkIndex:5,GN:2}];
|
|
p.tables.HeadTitleDat=[{Code:'H',Name:'head'}];
|
|
p.tables.EstMainDat=[{PkID:1,Code:'H',Name:'item',GN:10,LinkIndex:103},{PkID:2,Name:'direct',LinkIndex:54}];
|
|
p.tables.EstMainDat.push({PkID:4,Name:'부가세',LinkIndex:58},{PkID:5,Name:'total',LinkIndex:55});
|
|
p.tables.Wonga=[{Gubun:'G',Name:'material',BaseField:'GC',Cost:0},{Gubun:'V',Name:'부가세',VSusic:'G*0.1',Youl:'10%'},{Gubun:'T',Name:'total',VSusic:'G+V',LinkIndex:55}];
|
|
let q=EstNative.calculate(p);q=EstBusiness.baseline(q);
|
|
q.progress=[{id:'one',inputs:{'1':{Gum:25,GumMode:'ratio',Sa:1.5}},approved:true,locked:false}];
|
|
const first=EstBusiness.progress(q,'one');q.progress[0].result=first;q.progress[0].locked=true;
|
|
q.progress.push({id:'two',inputs:{'1':{Gum:500,GumMode:'amount',Sa:1}},approved:false,locked:false});
|
|
const second=EstBusiness.progress(q,'two');
|
|
q.annual=[{name:'1차',formula:'[계약수량]*0.4'},{name:'2차',formula:'[계약수량]-[1차]'}];
|
|
const years=EstBusiness.annual(q);const resources=EstResources.calculate(q);
|
|
const esc=structuredClone(q);esc.options.SourceRefresh=false;
|
|
Object.assign(esc.tables.EstMainDat[0],{AGU:180,GU:240,EscPlanned:2,EscActual:3,EscProgress:1});
|
|
const escalation=EstBusiness.escalation(esc);
|
|
const changed=structuredClone(q);changed.tables.StuffcDat[0].Cost1=120;
|
|
changed.tables.EstMainDat.splice(1,0,{PkID:3,Code:'M',Name:'new',GN:1,LinkIndex:5,NewItem:true});
|
|
const originals=[0,1,2].map(method=>EstBusiness.original(changed,method));
|
|
const bid=EstBusiness.bid(q,[90]);const bidAgain=EstBusiness.bid(bid,[90]);
|
|
const bidResources=EstResources.calculate(bid);
|
|
const converted=structuredClone(q);converted.tables.HeadMainDat.push({Index:0,GN:0.5,LinkIndex:68,Size:'unit conversion'});
|
|
const convertedResources=EstResources.calculate(converted);
|
|
const equipment=EstNative.empty();
|
|
equipment.tables.MachMainDat=[{Index:1,Code:'E',Name:'equipment',Unite:'hr'},{Index:-2,Name:'주연료',GN:1,TU:100}];
|
|
equipment.tables.HeadMainDat=[{Index:1,Code:'H',Name:'head'},{Index:0,LinkIndex:105,Code:'E',GN:2}];
|
|
equipment.tables.HeadTitleDat=[{Code:'H'}];equipment.tables.EstMainDat=[{PkID:1,LinkIndex:103,Code:'H',GN:10},{LinkIndex:54}];
|
|
const equipmentResources=EstResources.calculate(equipment);
|
|
({first,second,years,resources,escalation,originals,bid,bidAgain,bidResources,convertedResources,equipmentResources,project:q});
|
|
`,
|
|
context,
|
|
);
|
|
else if (command === "math") result = vm.runInContext(process.argv[3], context);
|
|
else throw Error("unknown command");
|
|
process.stdout.write(JSON.stringify(result));
|