118 lines
7.5 KiB
JavaScript
118 lines
7.5 KiB
JavaScript
import test from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import { transpileModule, ScriptTarget } from 'typescript'
|
|
import { computed, ref, reactive, watch } from 'vue'
|
|
|
|
const view = readFileSync(new URL('./WarehouseServiceView.vue', import.meta.url), 'utf8')
|
|
|
|
test('退货箱明细与来源下拉使用同一份逐箱库存,不请求普通入仓箱接口', async () => {
|
|
const body = view.slice(view.indexOf('async function loadTransferSourceCartons('), view.indexOf('// Snowflake IDs'))
|
|
const code = transpileModule(body, { compilerOptions: { target: ScriptTarget.ES2022 } }).outputText
|
|
const ctx = { transferSourceCartons: { value: [] }, transferSourceError: { value: '' },
|
|
transferSourceLoading: { value: false }, inventoryTransfer: { value: true },
|
|
selectedTransferInventory: { value: 'RETURN_ORDER:RET-1' }, form: { warehouse: 'WH' },
|
|
transferInventoryCandidates: { value: [
|
|
{ sourceType: 'RETURN_CARTON', inboundOrderNo: 'RET-1', cartonMark: 'BOX-1', cartonAvailablePackages: 1,
|
|
cartonSkuItems: [{ skuCode: 'A', quantity: 3 }, { skuCode: 'B', quantity: 2 }] },
|
|
{ sourceType: 'RETURN_PARCEL', inboundOrderNo: 'RET-1', cartonMark: 'BOX-2', cartonAvailablePackages: 1,
|
|
cartonSkuItems: [{ skuCode: 'A', quantity: 1 }] },
|
|
{ sourceType: 'RETURN_CARTON', inboundOrderNo: 'OTHER', cartonMark: 'FOREIGN', cartonAvailablePackages: 1 },
|
|
{ sourceType: 'RETURN_CARTON', inboundOrderNo: 'RET-1', cartonMark: 'OCCUPIED', cartonAvailablePackages: 0 },
|
|
{ sourceType: 'RETURN_CARTON', inboundOrderNo: 'RET-1', cartonMark: 'LABELLED', cartonAvailablePackages: 1, relabelStatus: 'COMPLETED' },
|
|
{ sourceType: 'RETURN_CARTON', inboundOrderNo: 'RET-1', cartonMark: 'PARTIAL', cartonAvailablePackages: 1, relabelledQuantity: 2 },
|
|
] }, getTransferSourceCartons: () => { throw Error('不应调用普通来源箱查询') } }
|
|
const load = new Function(...Object.keys(ctx), 'let transferSourceRequest=0;' + code + ';return loadTransferSourceCartons')(...Object.values(ctx))
|
|
await load()
|
|
assert.deepEqual(ctx.transferSourceCartons.value.map(box => box.cartonMark), ['BOX-1', 'BOX-2'])
|
|
assert.equal(ctx.transferSourceCartons.value[0].quantity, 5)
|
|
assert.equal(ctx.transferSourceCartons.value[0].items.length, 2)
|
|
assert.equal(ctx.transferSourceError.value, '')
|
|
assert.equal(ctx.transferSourceLoading.value, false)
|
|
})
|
|
|
|
test('选择库存来源时隐藏保存草稿并阻止草稿动作', () => {
|
|
assert.match(view, /props\.service === 'transfer' && !inventoryTransfer/)
|
|
assert.match(view, /保存草稿/)
|
|
assert.match(view, /props\.service === 'transfer' && inventoryTransfer\.value && action === 'draft'/)
|
|
assert.match(view, /选择库存来源后不能保存草稿,请直接提交订单/)
|
|
})
|
|
|
|
test('来源库存发往FBA默认开启贴标,清除来源或切换私人仓后恢复选项', () => {
|
|
const source = ref(''), destination = ref('NONE'), form = reactive({ relabel: false })
|
|
const inventoryTransfer = computed(() => Boolean(source.value))
|
|
const body = view.slice(view.indexOf('const transferRelabelRequired ='), view.indexOf('const transferSourceCartons ='))
|
|
const required = new Function('computed', 'watch', 'inventoryTransfer', 'transferDestinationType', 'form', body + ';return transferRelabelRequired')(
|
|
computed, watch, inventoryTransfer, destination, form)
|
|
destination.value = 'FBA'
|
|
assert.equal(form.relabel, false)
|
|
source.value = 'IN-1'
|
|
assert.equal(required.value, true)
|
|
assert.equal(form.relabel, true)
|
|
destination.value = 'PRIVATE'
|
|
assert.equal(required.value, false)
|
|
form.relabel = false
|
|
destination.value = 'FBA'
|
|
assert.equal(form.relabel, true)
|
|
source.value = ''
|
|
assert.equal(required.value, false)
|
|
assert.match(view, /<el-radio-button v-if="!transferRelabelRequired" :value="false">不需要贴标/)
|
|
})
|
|
|
|
function setup() {
|
|
const body = view.slice(view.indexOf('async function selectTransferInventory('), view.indexOf('function selectTransferInboundMethod('))
|
|
const code = transpileModule(body, { compilerOptions: { target: ScriptTarget.ES2022 } }).outputText
|
|
const ctx = { selectedTransferInventory: {value:''}, selectedTransferSourceOrderIds:{value:[]},
|
|
transferSourceCartons:{value:[{cartonMark:'OLD'}]}, transferSourceError:{value:'OLD'}, transferSourceLoading:{value:true},
|
|
transferDestinationType:{value:'NONE'}, form:{warehouse:'WH',inboundNo:''},
|
|
transferInventoryCandidates:{value:[{inboundCode:'IN',skuCode:'SKU',productNameZh:'货品',availablePackages:2},
|
|
{inboundCode:'IN',skuCode:'SKU',availablePackages:3},{inboundCode:'OTHER',skuCode:'OTHER',availablePackages:99}]},
|
|
cargoRows:{value:[]}, inventoryQuantity:Number, createCargoRow:()=>({expectedPackageCount:1}),
|
|
loadTransferSourceCartons:async()=>{}, listRelabelHistoricalOrders:async()=>[{id:'1234567890123456789'}],
|
|
ElMessage:{error(message){throw Error(message)}} }
|
|
const select = new Function(...Object.keys(ctx), 'let transferSourceRequest=0;'+code+'; return selectTransferInventory')(...Object.values(ctx))
|
|
return {ctx,select}
|
|
}
|
|
test('inventory source populates full immutable cargo counts without mixing other inbound orders',async()=>{
|
|
const {ctx,select}=setup(); await select('IN')
|
|
assert.equal(ctx.transferDestinationType.value,'FBA')
|
|
assert.equal(ctx.cargoRows.value.length,1)
|
|
assert.equal(ctx.cargoRows.value[0].expectedPackageCount,5)
|
|
assert.equal(ctx.cargoRows.value[0].quantity,5)
|
|
assert.deepEqual(ctx.selectedTransferSourceOrderIds.value,['1234567890123456789'])
|
|
await select('')
|
|
assert.equal(ctx.form.inboundNo,'')
|
|
assert.deepEqual(ctx.selectedTransferSourceOrderIds.value,[])
|
|
assert.deepEqual(ctx.transferSourceCartons.value,[])
|
|
})
|
|
test('inventory view hides inbound fields and editing actions and shows original carton destination',()=>{
|
|
assert.match(view,/v-if="props.service === 'transfer' && !inventoryTransfer"[^>]*><span><i>\*<\/i>入仓方式/)
|
|
assert.match(view,/<el-radio-button v-if="!inventoryTransfer" value="NONE">/)
|
|
const panel=view.slice(view.indexOf('<section v-if="inventoryTransfer"'),view.indexOf('</section>',view.indexOf('<section v-if="inventoryTransfer"')))
|
|
assert.match(panel,/box.cartonMark/); assert.match(panel,/box.destinationWarehouseCode/)
|
|
assert.doesNotMatch(panel,/v-model|addCargoRow|removeCargoRow|清空/)
|
|
assert.match(view,/!inventoryTransfer\.value && \(!form.warehouse/)
|
|
assert.match(view,/estimatedArrivalAt: inventoryTransfer.value \? undefined : form.estimatedArrivalAt/)
|
|
})
|
|
|
|
test('仓储转运来源下拉包含退货单并使用独立来源编码', () => {
|
|
assert.match(view, /RETURN_ORDER:\$\{returnNo\}/)
|
|
assert.match(view, /退货单|\$\{returnNo\}/)
|
|
assert.match(view, /item\.sourceType === 'RETURN_CARTON' \|\| item\.sourceType === 'RETURN_PARCEL'/)
|
|
assert.match(view, /isReturnSource[\s\S]*item\.sourceType === 'RETURN_CARTON'/)
|
|
})
|
|
|
|
test('退货来源带出实物 SKU 数量并跳过普通历史订单查询', async () => {
|
|
const { ctx, select } = setup()
|
|
ctx.transferInventoryCandidates.value = [{ sourceType: 'RETURN_CARTON', inboundOrderNo: 'RET-1',
|
|
cartonAvailablePackages: 1, skuItems: [{ skuCode: 'SKU', quantity: 1 }],
|
|
cartonSkuItems: [{ skuCode: 'SKU', quantity: 6 }] },
|
|
{ sourceType: 'RETURN_CARTON', inboundOrderNo: 'OTHER', cartonAvailablePackages: 1,
|
|
cartonSkuItems: [{ skuCode: 'FOREIGN', quantity: 99 }] }]
|
|
await select('RETURN_ORDER:RET-1')
|
|
assert.equal(ctx.cargoRows.value.length, 1)
|
|
assert.equal(ctx.cargoRows.value[0].quantity, 6)
|
|
assert.equal(ctx.cargoRows.value[0].expectedPackageCount, 1)
|
|
assert.deepEqual(ctx.selectedTransferSourceOrderIds.value, [])
|
|
})
|