import fs from "fs"; const path = "src/services/parse/packing-list.ts"; let src = fs.readFileSync(path, "utf8"); if (!src.includes("validatePackingFill")) { src = src.replace( `import { mapChannel } from "./channel-map";`, `import { mapChannel } from "./channel-map"; import { validatePackingFill } from "./packing-fill-rules";`, ); } const oldBlock = ` const channelRaw = String(raw.F_Transporter ?? "").trim(); const mapped = mapChannel(channelRaw); const fba = String(raw.F_FBACode ?? "").trim(); const ctnsNum = parseNumber(raw.F_CTNS); const ctns = ctnsNum == null ? 0 : Math.trunc(ctnsNum); const cbm = parseNumber(raw.F_CBM); const weight = parseNumber(raw.F_Weight); const addr = raw.F_Address != null ? String(raw.F_Address).trim() : ""; const express = /^(UPS|FEDEX|USPS|DHL)$/i.test( mapped.transporter || channelRaw, ); const invalid_reasons: string[] = []; // 亚马逊仓必填仓库代码;快�?私人地址可空 if (!fba && !express && !addr) invalid_reasons.push("仓库ID缺失"); if (!mapped.transporter) invalid_reasons.push("渠道缺失"); if (!ctns || ctns <= 0) invalid_reasons.push("件数无效"); if (cbm == null) invalid_reasons.push("总体积缺�?); if (weight == null) invalid_reasons.push("毛重缺失"); const warnings: string[] = []; if (mapped.unmapped && mapped.transporter) warnings.push("CHANNEL_UNMAPPED"); let shipmentId = raw.F_ShipmentID != null ? String(raw.F_ShipmentID).trim() : ""; if (!shipmentId) shipmentId = "/"; const fbaIdRaw = raw.F_FBAID != null ? String(raw.F_FBAID).trim() : ""; const refRaw = raw.F_ReferenceId != null ? String(raw.F_ReferenceId).trim() : ""; // 一格多 ID:警告(不自动拆行) if (/[\\s,�?/;]+/.test(fbaIdRaw) && /FBA/i.test(fbaIdRaw)) { warnings.push("MULTI_FBAID_IN_CELL"); } if (/[\\s,�?/;]{2,}/.test(refRaw)) { warnings.push("MULTI_REFERENCE_IN_CELL"); }`; const neuBlock = ` const channelRaw = String(raw.F_Transporter ?? "").trim(); const mapped = mapChannel(channelRaw); const fbaRaw = String(raw.F_FBACode ?? "").trim(); const ctnsNum = parseNumber(raw.F_CTNS); const ctns = ctnsNum == null ? 0 : Math.trunc(ctnsNum); const cbm = parseNumber(raw.F_CBM); const weight = parseNumber(raw.F_Weight); const addr = raw.F_Address != null ? String(raw.F_Address).trim() : ""; const fbaIdRaw = raw.F_FBAID != null ? String(raw.F_FBAID).trim() : ""; const refRaw = raw.F_ReferenceId != null ? String(raw.F_ReferenceId).trim() : ""; const shipmentIdRaw = raw.F_ShipmentID != null ? String(raw.F_ShipmentID).trim() : ""; const fill = validatePackingFill({ channelRaw, transporter: mapped.transporter, warehouseId: fbaRaw, ctns, cbm, weight, address: addr, shipmentId: shipmentIdRaw, fbaId: fbaIdRaw, referenceId: refRaw, rawCtns: raw.F_CTNS != null ? String(raw.F_CTNS) : undefined, rawCbm: raw.F_CBM != null ? String(raw.F_CBM) : undefined, rawWeight: raw.F_Weight != null ? String(raw.F_Weight) : undefined, }); const fba = fill.warehouseId; const shipmentId = fill.shipmentId; const invalid_reasons = [...fill.invalid_reasons]; const warnings = [...fill.warnings]; if (mapped.unmapped && mapped.transporter) warnings.push("CHANNEL_UNMAPPED");`; if (!src.includes(oldBlock)) { // try without double escapes for regex in character class const old2 = oldBlock.replace(/\\s/g, "\\s").replace(/\\\\/g, "\\"); // Just find by markers const a = src.indexOf("const channelRaw = String(raw.F_Transporter"); const b = src.indexOf("const dateB = toShanghaiDateString"); if (a < 0 || b < 0) { console.error("markers", a, b); process.exit(1); } src = src.slice(0, a) + neuBlock + "\n\n " + src.slice(b); } else { src = src.replace(oldBlock, neuBlock); } // Fix shipments.push F_FBACode: fba fs.writeFileSync(path, src); console.log("wired", src.includes("validatePackingFill"), src.includes("fill.warehouseId"));