优化
This commit is contained in:
@@ -4,7 +4,7 @@ import { readFileSync } from 'node:fs'
|
||||
import vm from 'node:vm'
|
||||
|
||||
function setup(confirm, saved = new Map(), scope = 'operator:warehouse') {
|
||||
const context = vm.createContext({ reactive: value => value, PortalHeader: {}, ScanTargetInput: {},
|
||||
const context = vm.createContext({ reactive: value => value, ReturnLabelConfirmation: {}, PortalHeader: {}, ScanTargetInput: {},
|
||||
playSuccessSound() {}, playErrorSound() {}, confirmReturnReceipt: confirm,
|
||||
uni: { setStorageSync: (key, value) => saved.set(key, structuredClone(value)), getStorageSync: key => saved.get(key), removeStorageSync: key => saved.delete(key) } })
|
||||
const store = readFileSync(new URL('../src/stores/warehouse-work.js', import.meta.url), 'utf8')
|
||||
@@ -20,13 +20,14 @@ function setup(confirm, saved = new Map(), scope = 'operator:warehouse') {
|
||||
palletCode: ' PLT-TEST ', palletLength: 10, palletWidth: 10, palletHeight: 10, palletWeight: 1,
|
||||
quantity: () => 2, boxCount: () => 1
|
||||
})
|
||||
Object.defineProperty(instance, 'receiptBatch', { get: () => vm.runInContext('warehouseWork.returnReceipt.pendingBatch', context) })
|
||||
return instance
|
||||
}
|
||||
|
||||
test('SKU lookup displays all pending order lines while retaining scanned SKU for pallet generation', () => {
|
||||
const source = readFileSync(new URL('../src/pages/return-receipt/return-receipt.vue', import.meta.url), 'utf8')
|
||||
const script = source.match(/<script[^>]*>([\s\S]*?)<\/script>/)[1]
|
||||
const component = vm.runInNewContext(script.replace(/^\s*import .*$/mg, '').replace('export default', 'globalThis.component ='), { PortalHeader: {}, ScanTargetInput: {} })
|
||||
const component = vm.runInNewContext(script.replace(/^\s*import .*$/mg, '').replace('export default', 'globalThis.component ='), { ReturnLabelConfirmation: {}, PortalHeader: {}, ScanTargetInput: {} })
|
||||
const lines = [{ skuCode: 'SKU-A', expectedQuantity: 6 }, { skuCode: 'SKU-B', expectedQuantity: 4 }]
|
||||
const instance = { current: { expectedItems: lines }, selectedSku: 'SKU-A' }
|
||||
instance.selectedItems = component.computed.selectedItems.call(instance)
|
||||
@@ -59,14 +60,14 @@ test('PALLET page submits the required palletCode through the actual confirmatio
|
||||
|
||||
test('parcel signing allows an empty code but still rejects quantities above the remaining amount', async () => {
|
||||
const source = readFileSync(new URL('../src/pages/return-receipt/return-receipt.vue', import.meta.url), 'utf8')
|
||||
const component = vm.runInNewContext(source.match(/<script[^>]*>([\s\S]*?)<\/script>/)[1].replace(/^\s*import .*$/mg, '').replace('export default', 'globalThis.component ='), { PortalHeader: {}, ScanTargetInput: {} })
|
||||
const state = { current: {}, selectedItems: [{ skuCode: 'A' }], receiptQuantity: 2, unitType: 'PARCEL', unitCode: '', quantity: () => 2, remaining: () => 3 }
|
||||
const component = vm.runInNewContext(source.match(/<script[^>]*>([\s\S]*?)<\/script>/)[1].replace(/^\s*import .*$/mg, '').replace('export default', 'globalThis.component ='), { ReturnLabelConfirmation: {}, PortalHeader: {}, ScanTargetInput: {} })
|
||||
const state = { current: {}, selectedItems: [{ skuCode: 'A' }], receiptQuantity: 2, unitType: 'PARCEL', boxRows: [{ items: { A: 2 } }], remaining: () => 3 }
|
||||
assert.equal(component.computed.canConfirm.call(state), true)
|
||||
state.quantity = () => 4
|
||||
state.boxRows[0].items.A = 4
|
||||
assert.equal(component.computed.canConfirm.call(state), false)
|
||||
const calls = []
|
||||
const page = setup(async payload => { calls.push(payload); return { unitType: 'PARCEL' } })
|
||||
page.unitType = 'PARCEL'; page.unitCode = ''; page.trackingNo = ''
|
||||
page.unitType = 'PARCEL'; page.unitCode = ''; page.trackingNo = ''; page.boxRows = [{ items: { 'SKU-TEST': 2 } }]
|
||||
await page.confirmReceipt()
|
||||
assert.equal(calls.length, 1)
|
||||
assert.equal(calls[0].trackingNo, undefined)
|
||||
@@ -77,13 +78,72 @@ test('parcel signing allows an empty code but still rejects quantities above the
|
||||
test('parcel waybill is submitted as trackingNo and leaves unitCode for the server', async () => {
|
||||
const calls = []
|
||||
const page = setup(async payload => { calls.push(payload); return { unitType: 'PARCEL' } })
|
||||
page.unitType = 'PARCEL'; page.unitCode = ' sf561626 '; page.trackingNo = 'stale-from-pallet'
|
||||
page.unitType = 'PARCEL'; page.unitCode = ' sf561626 '; page.trackingNo = 'stale-from-pallet'; page.boxRows = [{ items: { 'SKU-TEST': 2 } }]
|
||||
await page.confirmReceipt()
|
||||
assert.equal(calls[0].trackingNo, 'sf561626')
|
||||
assert.equal(calls[0].unitCode, undefined)
|
||||
assert.equal(calls[0].palletCode, undefined)
|
||||
})
|
||||
|
||||
test('batch waybill scans stay on the single parcel waybill input', () => {
|
||||
const page = setup(async () => ({}))
|
||||
page.unitType = 'PARCEL'; page.activeTarget = 'unit'; page.palletCode = ''
|
||||
page.handleScan('WAYBILL-ONE')
|
||||
assert.equal(page.unitCode, 'WAYBILL-ONE'); assert.equal(page.palletCode, '')
|
||||
assert.equal(page.activeTarget, 'unit')
|
||||
page.handleScan('WAYBILL-CORRECTED')
|
||||
assert.equal(page.unitCode, 'WAYBILL-CORRECTED')
|
||||
})
|
||||
|
||||
test('parcel rows must be nonempty and summed quantities cannot exceed the order remainder', () => {
|
||||
const source = readFileSync(new URL('../src/pages/return-receipt/return-receipt.vue', import.meta.url), 'utf8')
|
||||
const component = vm.runInNewContext(source.match(/<script[^>]*>([\s\S]*?)<\/script>/)[1].replace(/^\s*import .*$/mg, '').replace('export default', 'globalThis.component ='), { ReturnLabelConfirmation: {}, PortalHeader: {}, ScanTargetInput: {} })
|
||||
const state = { current: {}, selectedItems: [{ skuCode: 'A' }], receiptQuantity: 4, unitType: 'PARCEL', boxRows: [{ items: { A: 2 } }, { items: { A: 2 } }], remaining: () => 3 }
|
||||
assert.equal(component.computed.canConfirm.call(state), false)
|
||||
state.remaining = () => 5
|
||||
assert.equal(component.computed.canConfirm.call(state), true)
|
||||
state.boxRows[1].items = {}
|
||||
assert.equal(component.computed.canConfirm.call(state), false)
|
||||
})
|
||||
|
||||
test('one submission signs multiple mixed-SKU parcels sharing one waybill and independent labels', async () => {
|
||||
const calls = []
|
||||
const page = setup(async request => {
|
||||
calls.push(JSON.parse(JSON.stringify(request)))
|
||||
return { unitType: 'PARCEL', labels: [{ cartonMark: `RP-${calls.length}`, printableHtml: 'label' }], fullyMatched: false }
|
||||
})
|
||||
page.unitType = 'PARCEL'; page.unitCode = ' WAYBILL-BATCH '; page.trackingNo = 'stale'; page.selectedItems = [{ skuCode: 'SKU-TEST' }, { skuCode: 'SKU-B' }]
|
||||
page.boxRows = [{ items: { 'SKU-TEST': 1, 'SKU-B': 2 } }, { items: { 'SKU-TEST': 3 } }]
|
||||
await page.confirmReceipt()
|
||||
assert.equal(calls.length, 2)
|
||||
assert.deepEqual(calls[0].items, [{ skuCode: 'SKU-TEST', receivedQuantity: 1 }, { skuCode: 'SKU-B', receivedQuantity: 2 }])
|
||||
assert.deepEqual(calls[1].items, [{ skuCode: 'SKU-TEST', receivedQuantity: 3 }])
|
||||
assert.equal(calls[0].trackingNo, 'WAYBILL-BATCH'); assert.equal(calls[1].trackingNo, 'WAYBILL-BATCH')
|
||||
assert.notEqual(calls[0].idempotencyKey, calls[1].idempotencyKey)
|
||||
assert.deepEqual(Array.from(page.result.labels, row => row.cartonMark), ['RP-1', 'RP-2'])
|
||||
})
|
||||
|
||||
test('failed multi-parcel batch resumes immutable requests without re-signing a successful parcel', async () => {
|
||||
const saved = new Map(), calls = []
|
||||
let failSecond = true
|
||||
const confirm = async request => {
|
||||
calls.push(JSON.parse(JSON.stringify(request)))
|
||||
if (request.items[0].receivedQuantity === 2 && failSecond) throw new Error('response lost')
|
||||
return { unitType: 'PARCEL', labels: [{ cartonMark: `RP-${request.items[0].receivedQuantity}`, printableHtml: 'label' }], fullyMatched: false }
|
||||
}
|
||||
const page = setup(confirm, saved)
|
||||
page.unitType = 'PARCEL'; page.unitCode = 'WAYBILL-BATCH'; page.boxRows = [{ items: { 'SKU-TEST': 1 } }, { items: { 'SKU-TEST': 2 } }]
|
||||
await page.confirmReceipt()
|
||||
assert.equal(page.receiptBatch.entries[0].result.labels[0].cartonMark, 'RP-1')
|
||||
failSecond = false
|
||||
const restored = setup(confirm, saved)
|
||||
await restored.confirmReceipt()
|
||||
assert.equal(calls.length, 3)
|
||||
assert.equal(calls[1].idempotencyKey, calls[2].idempotencyKey)
|
||||
assert.deepEqual(calls[1], calls[2])
|
||||
assert.equal(restored.result.labels.length, 2)
|
||||
})
|
||||
|
||||
test('partial receipt continues the same order with fresh pallet measurements', async () => {
|
||||
const page = setup(async () => ({}))
|
||||
page.finishReceipt([{ fullyMatched: false }])
|
||||
|
||||
Reference in New Issue
Block a user