107 lines
4.0 KiB
JavaScript
107 lines
4.0 KiB
JavaScript
process.env.CANGKU_SKIP_BOOTSTRAP = '1';
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const XLSX = require('xlsx');
|
||
const cloudDb = require('../src/config/cloudDatabase');
|
||
|
||
// 表格的 12 个流水列 → 配置字段名
|
||
const FLOW_FIELDS = [
|
||
['加工进仓', 'processIn'],
|
||
['采购退货', 'purchaseReturn'],
|
||
['采购进仓', 'purchaseIn'],
|
||
['其它进仓', 'otherIn'],
|
||
['其它退货', 'otherReturn'],
|
||
['销售出仓', 'salesOut'],
|
||
['盘点', 'stocktaking'],
|
||
['加工出仓', 'processOut'],
|
||
['调拨出', 'transferOut'],
|
||
['销售退货', 'salesReturn'],
|
||
['调拨入', 'transferIn'],
|
||
['其它出库', 'otherOut'],
|
||
];
|
||
|
||
(async () => {
|
||
const wb = XLSX.readFile('C:/Users/15018737611/Desktop/库存监控.xlsx');
|
||
const rows = XLSX.utils.sheet_to_json(wb.Sheets['Sheet1'], { header: 1, defval: '' });
|
||
const h = rows[0];
|
||
const idx = Object.fromEntries(h.map((c, i) => [String(c).trim(), i]));
|
||
|
||
const level1 = String(rows[1][idx['一级功能按键']]).trim();
|
||
const level2 = String(rows[1][idx['二级功能按键']]).trim();
|
||
console.log('一级功能:', level1, '| 二级功能:', level2);
|
||
|
||
const whs = await cloudDb.query(`SELECT name, wms_co_id FROM rpt.jst_warehouseInfo`);
|
||
const byName = new Map(whs.map((w) => [String(w.name).trim(), w.wms_co_id]));
|
||
|
||
const records = [];
|
||
const missing = [];
|
||
for (const r of rows.slice(1)) {
|
||
const sheetName = String(r[idx['仓库']] || '').trim();
|
||
if (!sheetName) continue;
|
||
const base = sheetName.replace(/主仓$/, '');
|
||
const wmsCoId = byName.get(base) ?? byName.get(sheetName) ?? null;
|
||
if (wmsCoId == null) missing.push(sheetName);
|
||
|
||
const num = (k) => {
|
||
const v = r[idx[k]];
|
||
return typeof v === 'number' ? v : Number(String(v || '').replace(/,/g, '')) || 0;
|
||
};
|
||
|
||
const flows = Object.fromEntries(FLOW_FIELDS.map(([cn, en]) => [en, num(cn)]));
|
||
const openExtra = r[idx['期初']]; // 第二个「期初」列,索引会与「期初数量」冲突,单独处理
|
||
records.push({
|
||
warehouse: sheetName,
|
||
dbWarehouse: base,
|
||
wmsCoId,
|
||
openingQty: num('期初数量'),
|
||
openingQtyExtra: typeof openExtra === 'number' ? openExtra : Number(openExtra) || 0,
|
||
...flows,
|
||
});
|
||
}
|
||
|
||
console.log('记录数:', records.length, '| 缺 wms_co_id:', missing.length, missing.join(',') || '(无)');
|
||
|
||
const FLOW_COLUMNS_DEF = FLOW_FIELDS.map(([cn, en]) => ({ label: cn, field: en }));
|
||
const out = `/**
|
||
* 每日进销存 —— 2026-09-22 进销存基准流水
|
||
*
|
||
* 来源:桌面《库存监控.xlsx》(聚水潭 22 号进销存导出)
|
||
* 用途:业务库 JSReportReplica 没有按天的历史库存结存表,也缺少调拨/盘点/加工/其它出入库
|
||
* 单据表,期初与各流水列无法从业务库还原,故以该导出作为 22 号基准值。
|
||
*
|
||
* 口径约定:
|
||
* - openingQty 与 12 个流水列:22 号基准值(本文件静态存储)
|
||
* - 期末数量:运行时取 jst_inventoryInfo 实时库存(与本文件基准期末一致,24/25 精确)
|
||
* - 库存周转天数 / 四级库存量:运行时由 pm_stockMonitor 计算
|
||
*/
|
||
|
||
/** 一级/二级菜单名(取自表格) */
|
||
const DAILY_INVENTORY_LEVEL1 = '${level1}';
|
||
const DAILY_INVENTORY_LEVEL2 = '${level2}';
|
||
|
||
/** 基准数据日期 */
|
||
const BASELINE_DATE = '2026-09-22';
|
||
|
||
/** 12 个流水列的中文表头与字段映射(顺序与表格一致) */
|
||
const FLOW_COLUMNS = ${JSON.stringify(FLOW_COLUMNS_DEF, null, 2)};
|
||
|
||
/** 25 个仓库的 22 号基准流水 */
|
||
const DAILY_INVENTORY_BASELINE = ${JSON.stringify(records, null, 2)};
|
||
|
||
module.exports = {
|
||
DAILY_INVENTORY_LEVEL1,
|
||
DAILY_INVENTORY_LEVEL2,
|
||
BASELINE_DATE,
|
||
FLOW_COLUMNS,
|
||
DAILY_INVENTORY_BASELINE,
|
||
};
|
||
`;
|
||
|
||
const target = path.join(__dirname, '../src/config/dailyInventoryBaseline.js');
|
||
fs.writeFileSync(target, out, 'utf8');
|
||
console.log('已生成:', target);
|
||
console.log('\n前 2 条预览:');
|
||
console.log(JSON.stringify(records.slice(0, 2), null, 1));
|
||
process.exit(0);
|
||
})().catch((e) => { console.log('ERR', e.message); process.exit(1); });
|