优化
This commit is contained in:
@@ -11,18 +11,63 @@ function setup() {
|
||||
const value = scope.page.data()
|
||||
for(const [key,method] of Object.entries(scope.page.methods)) value[key]=method.bind(value)
|
||||
for(const [key,get] of Object.entries(scope.page.computed)) Object.defineProperty(value,key,{get:()=>get.call(value)})
|
||||
value.selected={transferNo:'WT1',packageCount:1,status:'WAIT_PDA_RECEIVING',items:[{id:'I1',skuCode:'A'}],cartons:[{cartonMark:'BOX1',transferItemId:'I1',status:'EXPECTED'}]}
|
||||
value.selected={transferNo:'WT1',packageCount:1,status:'WAIT_PDA_RECEIVING',items:[{id:'I1',skuCode:'A',quantity:4}],cartons:[{cartonMark:'BOX1',transferItemId:'I1',status:'EXPECTED'}]}
|
||||
value.pallets=[{key:'P1',draftId:'P1',palletNo:'PALLET1',generated:true,bound:false}];value.restoreCartons();Object.assign(value.cartonBoxes[0],{length:10,width:20,height:30,weight:2});value.cartonBoxes[0].items[0].quantity=4
|
||||
return {scope,value,storage}
|
||||
}
|
||||
test('summary toggle preserves measurements and volume uses three decimals',()=>{
|
||||
const {value}=setup()
|
||||
assert.equal(value.summaryCollapsed,false)
|
||||
value.summaryCollapsed=true
|
||||
assert.equal(value.cartonBoxes[0].weight,2)
|
||||
Object.assign(value.cartonBoxes[0],{length:10,width:10,height:6})
|
||||
value.addExtraCarton()
|
||||
Object.assign(value.cartonBoxes[1],{length:10,width:10,height:6,weight:2})
|
||||
assert.equal(value.palletVolume(value.pallets[0]),'0.001')
|
||||
assert.equal(value.totalVolume,'0.001')
|
||||
assert.match(source,/aria-label="添加 SKU"/)
|
||||
assert.match(source,/aria-label="删除箱子"/)
|
||||
})
|
||||
|
||||
test('remeasure preserves saved measurements and unlocks carton editing',async()=>{
|
||||
const {value,scope}=setup();
|
||||
const box={...value.cartonBoxes[0],countedAt:'2026-10-16',status:'COUNTED'};
|
||||
value.selected.cartons=[box]; value.cartonRequestKey='old-key';
|
||||
scope.reopenWarehouseTransferMeasurement=async()=>({...value.selected,cartons:[{...box,countedAt:null}]});
|
||||
await value.remeasure();
|
||||
assert.equal(value.cartonsCounted,false); assert.equal(value.cartonBoxes[0].weight,2);
|
||||
assert.equal(value.cartonBoxes[0].transferPalletId,'P1'); assert.equal(value.cartonRequestKey,'');
|
||||
assert.equal(value.cartonCountReady,true);
|
||||
})
|
||||
|
||||
test('bound pallet deletion retains box values and requires reassignment',async()=>{
|
||||
const {value,scope}=setup();
|
||||
scope.uni.showModal=options=>options.success({confirm:true});
|
||||
value.pallets[0].bound=true;
|
||||
scope.deleteWarehouseTransferPallet=async()=>({...value.selected,pallets:[]});
|
||||
await value.removePallet(0);
|
||||
assert.equal(value.cartonBoxes[0].transferPalletId,''); assert.equal(value.cartonBoxes[0].weight,2);
|
||||
assert.equal(value.generatedPallets.length,0); assert.equal(value.pallets.length,1);
|
||||
assert.equal(value.cartonCountReady,false); assert.equal(value.cartonPalletFilter,'');
|
||||
})
|
||||
|
||||
test('failed pallet deletion retains binding and measurements',async()=>{
|
||||
const {value,scope}=setup();
|
||||
scope.uni.showModal=options=>options.success({confirm:true});
|
||||
scope.deleteWarehouseTransferPallet=async()=>{throw new Error('offline')};
|
||||
await value.removePallet(0);
|
||||
assert.equal(value.cartonBoxes[0].transferPalletId,'P1'); assert.equal(value.pallets[0].busy,false);
|
||||
assert.equal(value.error.message,'offline');
|
||||
})
|
||||
|
||||
test('transfer counts require valid pieces and measurements and record variance reason',()=>{
|
||||
const {value}=setup();assert.equal(value.cartonCountReady,true)
|
||||
value.cartonBoxes[0].items[0].quantity=0;assert.equal(value.cartonCountReady,false)
|
||||
value.cartonBoxes[0].items[0].quantity=1.5;assert.equal(value.cartonCountReady,false)
|
||||
value.cartonBoxes[0].items[0].quantity=4;value.cartonBoxes[0].height=0;assert.equal(value.cartonCountReady,false)
|
||||
value.cartonBoxes[0].height=30;value.addExtraCarton();Object.assign(value.cartonBoxes[1],{length:10,width:20,height:30,weight:2});value.cartonBoxes[1].items[0].quantity=5
|
||||
assert.equal(value.cartonCountReady,false);value.countDiscrepancyReason='多一箱';assert.equal(value.cartonCountReady,true)
|
||||
assert.equal(value.cartonQuantity,9);assert.equal(value.cartonVolume,'0.012000')
|
||||
assert.equal(value.cartonCountReady,true);value.countDiscrepancyReason='多一箱';assert.equal(value.cartonCountReady,true)
|
||||
assert.equal(value.cartonQuantity,9);assert.equal(value.cartonVolume,'0.012')
|
||||
})
|
||||
test('network retry preserves request key and changed content uses a new request',async()=>{
|
||||
const {value,scope}=setup();const requests=[]
|
||||
@@ -32,11 +77,9 @@ test('network retry preserves request key and changed content uses a new request
|
||||
value.cartonBoxes[0].items[0].quantity=8;await value.confirmCartons();assert.notEqual(requests[1].idempotencyKey,requests[2].idempotencyKey)
|
||||
assert.equal(value.countingCartons,false);assert.equal(value.error.message,'offline')
|
||||
})
|
||||
test('draft restores additional cartons and discrepancy reason and scanning rejects foreign box',()=>{
|
||||
test('draft restores additional cartons and discrepancy reason without crossing tasks',()=>{
|
||||
const {value}=setup();value.addExtraCarton();value.countDiscrepancyReason='超收';value.saveCartonDraft();value.restoreCartons()
|
||||
assert.equal(value.cartonBoxes.length,2);assert.equal(value.countDiscrepancyReason,'超收')
|
||||
value.locateCarton('FOREIGN');assert.match(value.error.message,/不属于/)
|
||||
value.locateCarton('BOX1');assert.equal(value.selectedCartonMark,'BOX1');assert.equal(value.cartonScrollTarget,'transfer-box-0')
|
||||
value.selected={...value.selected,transferNo:'WT2'};value.restoreCartons();assert.equal(value.cartonBoxes.length,1)
|
||||
})
|
||||
test('received count gates pallet completion and saving cannot switch active order',()=>{
|
||||
@@ -47,6 +90,7 @@ test('received count gates pallet completion and saving cannot switch active ord
|
||||
|
||||
test('batch applies only selected received boxes of one SKU and preserves independent drafts',()=>{
|
||||
const {value}=setup()
|
||||
value.selected.items.push({id:'I2',skuCode:'B'})
|
||||
value.addExtraCarton();value.addExtraCarton();value.addExtraCarton()
|
||||
value.cartonBoxes[2].items[0].skuCode='B'
|
||||
value.cartonBoxes[3].received=false
|
||||
@@ -127,3 +171,83 @@ test('pallet number can be created before measurements and new boxes receive tha
|
||||
assert.equal(value.cartonBoxes[0].transferPalletId,'CREATED')
|
||||
assert.equal(value.pallets[0].palletNo,'NEWPALLET')
|
||||
})
|
||||
|
||||
// 最终完成入口需要区分无差异、取消、空白原因和网络重试。
|
||||
for (const answer of [{confirm:false}, {confirm:true,content:' '}, {confirm:true,content:'少到一箱'}]) {
|
||||
test('completion handles discrepancy answer '+JSON.stringify(answer),async()=>{
|
||||
const {value,scope}=setup();let requests=[];let prompts=0
|
||||
value.selected.items[0].quantity=5;value.selected.cartons[0].countedAt='2026-10-16'
|
||||
value.pallets[0].bound=true;value.photoFileIds=[91]
|
||||
scope.uni.showModal=options=>{prompts++;options.success(answer)}
|
||||
scope.palletizeWarehouseTransfer=async(no,payload)=>{requests.push(payload);throw new Error('offline')}
|
||||
await value.submit()
|
||||
assert.equal(prompts,1);assert.equal(value.submitting,false)
|
||||
assert.equal(requests.length,answer.confirm && answer.content?.trim()?1:0)
|
||||
if(requests.length){assert.equal(requests[0].discrepancyReason,'少到一箱');await value.submit();assert.equal(requests[0].idempotencyKey,requests[1].idempotencyKey)}
|
||||
})
|
||||
}
|
||||
test('matching SKU counts with different carton count submit without prompting, and missing photos block before prompting',async()=>{
|
||||
const {value,scope}=setup();let prompts=0;let requests=[]
|
||||
value.selected.packageCount=9;value.selected.cartons[0].countedAt='2026-10-16';value.pallets[0].bound=true
|
||||
scope.uni.showModal=()=>{prompts++}
|
||||
scope.palletizeWarehouseTransfer=async(no,payload)=>{requests.push(payload);throw new Error('offline')}
|
||||
await value.submit();assert.equal(requests.length,0);assert.equal(prompts,0)
|
||||
value.photoFileIds=[91];await value.submit();assert.equal(prompts,0);assert.equal(requests.length,1);assert.equal(requests[0].discrepancyReason,null)
|
||||
})
|
||||
|
||||
// 逐箱确认收起、再次编辑及草稿恢复必须保留其他箱的确认状态。
|
||||
test('individual confirmation collapses only that box and resumes from draft',async()=>{
|
||||
const {value,scope}=setup();value.addExtraCarton()
|
||||
Object.assign(value.cartonBoxes[1],{length:10,width:20,height:30,weight:2});value.cartonBoxes[1].items[0].quantity=5
|
||||
let saves=0;scope.countWarehouseTransferCartons=async()=>{saves++;throw new Error('offline')}
|
||||
await value.confirmSingleCarton(value.cartonBoxes[0])
|
||||
assert.equal(value.cartonConfirmed(value.cartonBoxes[0]),true);assert.equal(value.allCartonsConfirmed,false);assert.equal(saves,0)
|
||||
value.restoreCartons();assert.equal(value.cartonConfirmed(value.cartonBoxes[0]),true)
|
||||
await value.editCarton(value.cartonBoxes[0]);assert.equal(value.cartonConfirmed(value.cartonBoxes[0]),false)
|
||||
await value.confirmSingleCarton(value.cartonBoxes[0]);await value.confirmSingleCarton(value.cartonBoxes[1])
|
||||
assert.equal(value.allCartonsConfirmed,true);assert.equal(saves,1);assert.equal(value.error.message,'offline')
|
||||
value.cartonBoxes[0].weight=3;assert.equal(value.cartonConfirmed(value.cartonBoxes[0]),false);assert.equal(value.allCartonsConfirmed,false)
|
||||
})
|
||||
test('saved boxes restore collapsed and editing reopens only selected box',async()=>{
|
||||
const {value,scope}=setup()
|
||||
const first={...value.cartonBoxes[0],quantity:4,countedAt:'2026-10-16',status:'COUNTED'}
|
||||
const second={...first,cartonMark:'BOX2'}
|
||||
value.selected.cartons=[first,second];value.restoreCartons()
|
||||
assert.equal(value.cartonBoxes.every(box=>value.cartonConfirmed(box)),true)
|
||||
scope.reopenWarehouseTransferMeasurement=async()=>({...value.selected,cartons:value.selected.cartons.map(box=>({...box,countedAt:null}))})
|
||||
await value.editCarton(value.cartonBoxes[0])
|
||||
assert.equal(value.cartonsCounted,false);assert.equal(value.cartonConfirmed(value.cartonBoxes[0]),false);assert.equal(value.cartonConfirmed(value.cartonBoxes[1]),true)
|
||||
value.restoreCartons();assert.equal(value.cartonConfirmed(value.cartonBoxes[1]),true)
|
||||
})
|
||||
test('failed reopening preserves confirmed data and invalid box cannot confirm',async()=>{
|
||||
const {value,scope}=setup();value.cartonBoxes[0].weight=0
|
||||
await value.confirmSingleCarton(value.cartonBoxes[0]);assert.equal(value.cartonConfirmed(value.cartonBoxes[0]),false)
|
||||
value.cartonBoxes[0].weight=2;value.selected.cartons=[{...value.cartonBoxes[0],countedAt:'2026-10-16',status:'COUNTED'}];value.restoreCartons()
|
||||
scope.reopenWarehouseTransferMeasurement=async()=>{throw new Error('offline')}
|
||||
await value.editCarton(value.cartonBoxes[0]);assert.equal(value.cartonsCounted,true);assert.equal(value.cartonConfirmed(value.cartonBoxes[0]),true)
|
||||
})
|
||||
|
||||
// 箱数变化不影响 SKU 门禁,异 SKU 正负差异不能按总件数抵消。
|
||||
test('SKU differences compare each SKU and ignore carton count',()=>{
|
||||
const {value}=setup();value.selected.packageCount=9
|
||||
assert.equal(value.hasSkuReceiptDifference,false)
|
||||
value.selected.items.push({id:'I2',skuCode:'B',quantity:3})
|
||||
value.cartonBoxes[0].items=[{skuCode:'A',quantity:3},{skuCode:'B',quantity:4}]
|
||||
assert.equal(value.cartonQuantity,value.forecastSkuQuantity)
|
||||
assert.equal(value.skuReceiptDifferences.length,2)
|
||||
value.cartonBoxes[0].items=[{skuCode:'A',quantity:4},{skuCode:'B',quantity:3}]
|
||||
assert.equal(value.hasSkuReceiptDifference,false)
|
||||
})
|
||||
|
||||
// 客户补箱后,新增预报箱进入PDA,原本机草稿和删除标记不丢失。
|
||||
test('forecast additions merge into existing draft without losing edited boxes',()=>{
|
||||
const {value}=setup();value.cartonBoxes[0].weight=7;value.saveCartonDraft()
|
||||
value.selected.packageCount=2;value.selected.cartons.push({cartonMark:'BOX2',transferItemId:'I1',status:'EXPECTED'})
|
||||
value.restoreCartons();assert.equal(value.cartonBoxes.length,2);assert.equal(value.cartonBoxes[0].weight,7);assert.equal(value.cartonBoxes[1].cartonMark,'BOX2')
|
||||
value.removeCarton(0);value.restoreCartons();assert.equal(value.cartonBoxes.length,1);assert.equal(value.cartonBoxes[0].cartonMark,'BOX2')
|
||||
})
|
||||
test('count payload carries forecast version for stale snapshot rejection',async()=>{
|
||||
const {value,scope}=setup();let payload
|
||||
scope.countWarehouseTransferCartons=async(no,request)=>{payload=request;throw new Error('offline')}
|
||||
await value.confirmCartons();assert.equal(payload.forecastPackageCount,1);assert.equal(payload.boxes[0].cartonMark,'BOX1')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user