Files
pda-uniapp/tests/picking-state.test.mjs
T

152 lines
5.4 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('../utils/picking-state.js', import.meta.url), 'utf8')
const state = await import(`data:text/javascript;base64,${Buffer.from(source).toString('base64')}`)
const items = [{ id: 1 }, { id: 2 }, { id: 3 }]
test('inventory resources expose distinct locations and total available cartons', () => {
assert.deepEqual(state.summarizeInventoryResources([
{ locationCode: 'A0', availablePackageCount: 4 },
{ locationCode: 'A0', availablePackageCount: 2 },
{ locationCode: 'B-03', availablePackageCount: 1 },
]), { location: 'A0、B-03', availablePackageCount: 7 })
assert.deepEqual(state.summarizeInventoryResources(null), { location: '', availablePackageCount: null })
})
test('sealed pallet matches its DP code and resolves member cartons as an atomic pallet', () => {
const pallet = { id: '1', unitType: 'SEALED_PALLET', indivisible: true, palletNo: 'DP-260909-0143', boxCodes: ['IN#2-1', 'IN#2-2'], qty: 2 }
assert.equal(state.classifyScan([pallet], {}, 'IN#2-1').type, 'pallet')
assert.equal(state.classifyScan([pallet], {}, pallet.palletNo).type, 'pallet')
assert.equal(state.classifyScan([pallet], { 1: state.ITEM_STATUS.PICKED }, pallet.palletNo).type, 'processed')
})
test('only the authoritative sealed-pallet unit type selects pallet behavior', () => {
assert.equal(state.isSealedPalletItem({ unitType: 'SEALED_PALLET', indivisible: true }), true)
assert.equal(state.isSealedPalletItem({ unitType: 'PALLET', indivisible: true }), false)
assert.equal(state.isSealedPalletItem({ unitType: 'PACKAGE', indivisible: true }), false)
})
test('mixed task keeps package scanning separate from sealed pallet scanning', () => {
const mixed = [{ id: '1', unitType: 'SEALED_PALLET', palletNo: 'DP-260909-0001', boxCodes: ['BOX-1'] }, { id: '2', unitType: 'PACKAGE', boxCodes: ['BOX-2'] }]
assert.equal(state.classifyScan(mixed, {}, 'BOX-2').item.id, '2')
assert.equal(state.classifyScan(mixed, {}, 'DP-260909-0001').item.id, '1')
assert.equal(state.classifyScan(mixed, {}, 'BOX-1').type, 'pallet')
})
test('createItemStates initializes every item as pending', () => {
assert.deepEqual(state.createItemStates(items), {
1: state.ITEM_STATUS.PENDING,
2: state.ITEM_STATUS.PENDING,
3: state.ITEM_STATUS.PENDING,
})
})
test('getPickSummary disables submit before any effective pick', () => {
const summary = state.getPickSummary(items, {
1: state.ITEM_STATUS.SKIPPED,
2: state.ITEM_STATUS.PENDING,
3: state.ITEM_STATUS.PENDING,
})
assert.equal(summary.canSubmit, false)
assert.equal(summary.buttonText, '提交拣货完成')
assert.equal(summary.progress, 33)
})
test('getPickSummary enables early submit after a picked item', () => {
const summary = state.getPickSummary(items, {
1: state.ITEM_STATUS.PICKED,
2: state.ITEM_STATUS.PENDING,
3: state.ITEM_STATUS.PENDING,
})
assert.equal(summary.canSubmit, true)
assert.equal(summary.buttonText, '提交拣货完成')
assert.deepEqual(
{ picked: summary.picked, partial: summary.partial, skipped: summary.skipped, pending: summary.pending },
{ picked: 1, partial: 0, skipped: 0, pending: 2 },
)
})
test('getPickSummary enables submit when every item is processed', () => {
const summary = state.getPickSummary(items, {
1: state.ITEM_STATUS.SKIPPED,
2: state.ITEM_STATUS.SKIPPED,
3: state.ITEM_STATUS.SKIPPED,
})
assert.equal(summary.canSubmit, true)
assert.equal(summary.buttonText, '提交拣货完成')
assert.equal(summary.progress, 100)
})
test('submitStates turns only pending items into skipped', () => {
assert.deepEqual(state.submitStates(items, {
1: state.ITEM_STATUS.PICKED,
2: state.ITEM_STATUS.PARTIAL,
3: state.ITEM_STATUS.PENDING,
}), {
states: {
1: state.ITEM_STATUS.PICKED,
2: state.ITEM_STATUS.PARTIAL,
3: state.ITEM_STATUS.SKIPPED,
},
autoSkippedIds: [3],
})
})
test('classifyScan distinguishes pending, repeated, and unknown carton codes', () => {
const scanItems = [{ id: 1, boxCodes: ['BOX-001'] }, { id: 2, boxCodes: ['BOX-002', 'BOX-003'] }]
assert.deepEqual(state.classifyScan(scanItems, {
1: state.ITEM_STATUS.PICKED,
2: state.ITEM_STATUS.PENDING,
}, 'BOX-002'), {
type: 'pending',
item: scanItems[1],
})
assert.deepEqual(state.classifyScan(scanItems, {
1: state.ITEM_STATUS.PARTIAL,
2: state.ITEM_STATUS.PENDING,
}, 'BOX-001', { 'BOX-001': 1 }), {
type: 'processed',
item: scanItems[0],
status: state.ITEM_STATUS.PARTIAL,
})
assert.deepEqual(state.classifyScan(scanItems, {}, 'NO-SUCH-BOX'), {
type: 'unknown',
item: null,
})
})
test('sealed pallet resolves either its DP code or any member carton as one whole-pallet action', () => {
const pallet = {
id: 9,
unitType: 'SEALED_PALLET',
palletId: '2098348162978738179',
palletNo: 'DP-260911-0047',
indivisible: true,
boxCodes: ['BOX-001', 'BOX-002'],
}
assert.deepEqual(state.classifyScan([pallet], {}, 'DP-260911-0047'), {
type: 'pallet',
item: pallet,
})
assert.deepEqual(state.classifyScan([pallet], {}, 'BOX-001'), {
type: 'pallet',
item: pallet,
matchedBy: 'carton',
})
assert.deepEqual(state.classifyScan([pallet], {
9: state.ITEM_STATUS.PICKED,
}, 'DP-260911-0047', { 'DP-260911-0047': 9 }), {
type: 'processed',
item: pallet,
status: state.ITEM_STATUS.PICKED,
})
})