Files
pda-overseas-uniapp/tests/warehouse-transfer-mixed-cartons.test.mjs
2026-10-16 17:43:48 +08:00

128 lines
6.6 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
const source = await readFile(new URL('../src/pages/warehouse-transfer/warehouse-transfer.vue', import.meta.url), 'utf8')
const script = source.match(/<script>([\s\S]*?)<\/script>/)[1].replace(/^import .+$/gm, '').replace('export default', 'return')
const page = new Function('CartonCountFields', 'PortalHeader', 'ScanTargetInput', 'session', 'uni', script)({}, {}, {}, { currentUser: null }, { showModal: options => options.success({confirm:true}), getStorageSync: key => globalThis.uni?.getStorageSync(key) })
function context() {
const ctx = { ...page.data(), selected: { transferNo: 'WT1', packageCount: 2, items: [{ id: '1', skuCode: 'A' }, { id: '2', skuCode: 'B' }], cartons: [] }, saveCartonDraft() {} }
for (const [name, method] of Object.entries(page.methods)) ctx[name] = method.bind(ctx)
for (const [name, getter] of Object.entries(page.computed)) Object.defineProperty(ctx, name, { get: getter.bind(ctx), configurable: true })
ctx.saveCartonDraft = () => {}
return ctx
}
const box = (sku = 'A', quantity = 3) => ({ received: true, length: 10, width: 20, height: 30, weight: 2, items: [{ skuCode: sku, quantity }] })
test('one carton can add distinct forecast SKUs and validates every quantity', () => {
const ctx = context(), current = box()
ctx.addCartonSku(current)
assert.deepEqual(current.items, [{ skuCode: 'A', quantity: 3 }, { skuCode: 'B', quantity: '' }])
assert.equal(ctx.validCartonSkuLines(current), false)
current.items[1].quantity = 7
assert.equal(ctx.validCartonSkuLines(current), true)
ctx.addCartonSku(current)
assert.equal(current.items.length, 2)
current.items[1].skuCode = 'A'
assert.equal(ctx.validCartonSkuLines(current), false)
current.items[1].skuCode = 'FOREIGN'
assert.equal(ctx.validCartonSkuLines(current), false)
})
test('single SKU batch changes never overwrite mixed carton contents', () => {
const ctx = context(), single = box(), mixed = box()
mixed.items.push({ skuCode: 'B', quantity: 7 })
ctx.cartonBoxes = [single, mixed]; ctx.batchSku = 'A'
ctx.selectBatchCartons(true)
assert.deepEqual(ctx.batchSelectedIndexes, [0])
ctx.toggleBatchCarton(1)
assert.deepEqual(ctx.batchSelectedIndexes, [0])
assert.equal(ctx.previousMatchingCarton(1), null)
assert.equal(ctx.cartonQuantity, 13)
})
test('delete only changes actual draft and preserves forecast; additions keep their own SKU rows', async () => {
const ctx = context()
ctx.cartonBoxes = [box(), box('B')]; ctx.batchSelectedIndexes = [1]
await ctx.removeCarton(0)
assert.equal(ctx.cartonBoxes.length, 1)
assert.equal(ctx.selected.packageCount, 2)
assert.deepEqual(ctx.batchSelectedIndexes, [])
ctx.addExtraCarton()
assert.equal(ctx.cartonBoxes.length, 2)
assert.equal(ctx.cartonBoxes[1].items[0].skuCode, 'A')
ctx.cartonBoxes[1].items[0].quantity = 8
assert.equal(ctx.cartonBoxes[0].items[0].quantity, 3)
})
test('draft reload preserves deletions, including an empty actual list', () => {
const ctx = context()
ctx.selected.cartons = [{ cartonMark: 'BOX1', transferItemId: '1', status: 'EXPECTED' }, { cartonMark: 'BOX2', transferItemId: '2', status: 'EXPECTED' }]
let saved = { forecastMarks: ['BOX1','BOX2'], boxes: [{ ...box('B'), cartonMark: 'BOX2', transferItemId: '2' }], discrepancyReason: '少到一箱' }
globalThis.uni = { getStorageSync: () => saved }
try {
ctx.restoreCartons()
assert.equal(ctx.cartonBoxes.length, 1)
assert.equal(ctx.cartonBoxes[0].cartonMark, 'BOX2')
assert.equal(ctx.countDiscrepancyReason, '少到一箱')
saved = { forecastMarks: ['BOX1','BOX2'], boxes: [], discrepancyReason: '重新录入' }
ctx.restoreCartons()
assert.equal(ctx.cartonBoxes.length, 0)
assert.equal(ctx.selected.cartons.length, 2)
} finally { delete globalThis.uni }
})
test('100 same SKU cartons accept two distinct specification groups and independent exceptions', () => {
const ctx = context()
ctx.selected.packageCount = 100
ctx.pallets = [{ generated: true, draftId: 'P1' }, { generated: true, draftId: 'P2' }]
ctx.cartonBoxes = Array.from({ length: 100 }, (_, index) => ({ ...box('A', ''), localKey: `BOX-${index}`, transferItemId: '1', length: '', width: '', height: '', weight: '' }))
ctx.batchSku = 'A'; ctx.batchPalletId = 'P1'; ctx.batchBox = { ...box('A', 12), length: 40, width: 30, height: 20, weight: 5 }
ctx.selectBatchCartons(true)
for (let index = 60; index < 100; index++) ctx.toggleBatchCarton(index)
assert.equal(ctx.batchTargetBoxes.length, 60)
assert.equal(ctx.batchTotalQuantity, 720)
ctx.applyBatchCartons()
assert.equal(ctx.cartonBoxes[59].items[0].quantity, 12)
assert.equal(ctx.cartonBoxes[60].items[0].quantity, '')
ctx.selectBatchCartons(true)
for (let index = 0; index < 60; index++) ctx.toggleBatchCarton(index)
ctx.batchPalletId = 'P2'; ctx.batchBox = { ...box('A', 8), length: 50, width: 40, height: 30, weight: 7 }
ctx.applyBatchCartons()
assert.equal(ctx.palletSummary(ctx.pallets[0]).cartonCount, 60)
assert.equal(ctx.palletSummary(ctx.pallets[1]).cartonCount, 40)
assert.equal(ctx.cartonQuantity, 1040)
assert.equal(ctx.totalWeight, '580.00')
assert.equal(ctx.totalVolume, '3.840')
assert.equal(ctx.cartonCountReady, true)
ctx.cartonBoxes[0].items[0].quantity = 11
ctx.cartonBoxes[0].weight = 6
assert.equal(ctx.cartonBoxes[1].items[0].quantity, 12)
assert.equal(ctx.cartonBoxes[1].weight, 5)
assert.equal(ctx.batchBox.items[0].quantity, 8)
assert.equal(ctx.cartonQuantity, 1039)
assert.equal(ctx.totalWeight, '581.00')
})
test('copy previous matching SKU skips other SKUs and preserves the target pallet', () => {
const ctx = context()
ctx.cartonBoxes = [{ ...box('A', 12), length: 40, width: 30, height: 20, weight: 5, transferPalletId: 'P1' }, box('B', 99), { ...box('A', ''), transferPalletId: 'P2' }]
ctx.copyPreviousCarton(2)
assert.equal(ctx.cartonBoxes[2].length, 40)
assert.equal(ctx.cartonBoxes[2].weight, 5)
assert.equal(ctx.cartonBoxes[2].items[0].quantity, 12)
assert.equal(ctx.cartonBoxes[2].transferPalletId, 'P2')
ctx.cartonBoxes[2].items[0].quantity = 9
assert.equal(ctx.cartonBoxes[0].items[0].quantity, 12)
})
test('预报箱可调整原SKU,新增无绑定箱也可清点', () => {
const ctx = context(); const current = { ...box('B', 4), cartonMark: 'FORECAST-1', transferItemId: '1' }
assert.equal(ctx.validCartonSkuLines(current), true)
current.transferItemId = null
assert.equal(ctx.validCartonSkuLines(current), true)
current.items[0].skuCode = 'OTHER'
assert.equal(ctx.validCartonSkuLines(current), false)
assert.doesNotMatch(source, /:lock-first-sku="Boolean\(box.cartonMark\)"/)
})