ForgeFlow-ERP/frontend/scripts/test-special-adjustment-ui.mjs
2026-06-12 16:00:56 +08:00

77 lines
3.7 KiB
JavaScript

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import {
specialAdjustmentDirectionLabel,
specialAdjustmentMeasureMode,
specialAdjustmentOperationKeys
} from "../src/utils/specialAdjustmentRules.js";
const viewPath = fileURLToPath(new URL("../src/views/InventoryLedgerView.vue", import.meta.url));
const operationKeys = specialAdjustmentOperationKeys();
assert.equal(specialAdjustmentDirectionLabel("OUT"), "特殊出库");
assert.equal(specialAdjustmentDirectionLabel("out"), "特殊出库");
assert.equal(specialAdjustmentDirectionLabel("IN"), "特殊入库");
assert.equal(specialAdjustmentDirectionLabel(""), "特殊入库");
assert.equal(specialAdjustmentMeasureMode("RAW"), "WEIGHT");
assert.equal(specialAdjustmentMeasureMode("SCRAP"), "WEIGHT");
assert.equal(specialAdjustmentMeasureMode("AUX"), "QTY");
assert.equal(specialAdjustmentMeasureMode("FINISHED"), "QTY_WITH_WEIGHT");
assert.equal(specialAdjustmentMeasureMode("RETURN"), "QTY_WITH_WEIGHT");
assert.equal(specialAdjustmentMeasureMode("SEMI", { remaining_qty: 8, remaining_weight_kg: 0 }), "QTY");
assert.equal(specialAdjustmentMeasureMode("SEMI", { qty_available: 3, weight_available_kg: 0 }), "QTY");
assert.equal(specialAdjustmentMeasureMode("SEMI", { remaining_qty: 0, remaining_weight_kg: 12 }), "WEIGHT");
assert.equal(specialAdjustmentMeasureMode("SEMI", { qty_available: 0, weight_available_kg: 4 }), "WEIGHT");
assert.equal(specialAdjustmentMeasureMode("SEMI", { remaining_qty: 2, remaining_weight_kg: 7 }), "SEMI_SELECT");
assert.equal(specialAdjustmentMeasureMode("SEMI", {}), "SEMI_SELECT");
assert.deepEqual(operationKeys, {
raw: {
in: "raw-special-in",
out: "raw-special-out"
},
semi: {
in: "semi-special-in",
out: "semi-special-out"
},
finished: {
in: "finished-special-in",
out: "finished-special-out"
},
auxiliary: {
in: "aux-special-in",
out: "aux-special-out"
},
scrap: {
in: "scrap-special-in",
out: "scrap-special-out"
},
return: {
in: "return-special-in",
out: "return-special-out"
}
});
const viewSource = readFileSync(viewPath, "utf8");
const flattenedOperationKeys = Object.values(operationKeys).flatMap((entry) => [entry.in, entry.out]);
for (const operationKey of flattenedOperationKeys) {
assert.ok(viewSource.includes(operationKey), `InventoryLedgerView.vue should include ${operationKey}`);
}
assert.ok(viewSource.includes("特殊入库"), "InventoryLedgerView.vue should include the special inbound label");
assert.ok(viewSource.includes("特殊出库"), "InventoryLedgerView.vue should include the special outbound label");
assert.ok(viewSource.includes("入库方式"), "InventoryLedgerView.vue should label the special inbound line mode in Chinese");
assert.ok(viewSource.includes("补增已有明细"), "InventoryLedgerView.vue should allow adding to an existing special inbound stock detail");
assert.ok(viewSource.includes("新增特殊明细"), "InventoryLedgerView.vue should allow creating a new special inbound stock detail");
assert.ok(viewSource.includes("特殊出库必须选择库存明细"), "InventoryLedgerView.vue should keep lot selection required for special outbound");
assert.ok(viewSource.includes("specialAdjustmentLineLotId(line)"), "InventoryLedgerView.vue should route special adjustment lot_id through conditional logic");
assert.ok(viewSource.includes("lot_id: null"), "InventoryLedgerView.vue should submit lot_id null when special inbound creates a new detail");
assert.ok(viewSource.includes("/inventory/special-adjustments"), "InventoryLedgerView.vue should call the special adjustments API");
console.log("special adjustment UI static assertions passed");