fix(dispatch): confirm scanned loading without repeated measurements
This commit is contained in:
@@ -70,11 +70,11 @@ function model(fault = '') {
|
||||
if(fault==='outage disguised as rejection')return {http:503,body:{code:'S0503'},requestId:'r',traceId:'t'}
|
||||
return reject(fault==='unrelated gate rejection'?'车次版本已变化':'逐项真实拣货尚未核平')
|
||||
}
|
||||
assert.equal(body.recordVersion,nativeVersion); assert.equal(body.measurements.length,2)
|
||||
assert.equal(body.recordVersion,nativeVersion); assert.equal('measurements' in body,false)
|
||||
stage='DELIVERING';nativeVersion++;trip.trip.status='IN_TRANSIT'
|
||||
for(const [i,s] of state.entries()) { const m=members[i];s.outbound={outboundNo:`OUT${i}`,dispatchNo:'DS-ONE',overseasWarehouseId:'WH',customerId:m.customerId,status:'OUTBOUNDED',packageCount:1};s.delivery={order:{deliveryNo:`DL${i}`,customerId:fault==='foreign delivery'?'OTHER':m.customerId,dispatchNo:'DS-ONE',outboundNo:`OUT${i}`,status:fault==='partial departure'&&i===1?'WAIT_DELIVERY':'DELIVERING',version:0}} }
|
||||
if(fault==='depart deducts again'){state[0].stock.balances[0].availablePackages='-1';state[0].stock.positions[0].availablePackages='-1'}
|
||||
confirmedLoad={manifestHash:body.manifestHash,pallets:copy(body.measurements),operatorId:'PDA-ACTOR',confirmedAt:'2026-10-19T01:00:00Z'}
|
||||
confirmedLoad={manifestHash:body.manifestHash,pallets:members.map((m,i)=>({warehousePalletId:m.palletId,palletSpaces:1,weightKg:100,volumeCbm:1,deliveryIndex:i+1})),operatorId:'PDA-ACTOR',confirmedAt:'2026-10-19T01:00:00Z'}
|
||||
return remember(body,{confirmedLoad,loadingCompletionHash:'LOADED'},token,'LOADING_COMPLETE')
|
||||
}
|
||||
if (path.endsWith('/pick')) {
|
||||
@@ -119,13 +119,13 @@ test('current DTO-shaped two-customer trip rejects unready gate, departs once an
|
||||
assert.ok(!m.calls.some(c=>c.raw.endsWith('/complete')||c.raw.includes('/dispatches/bind')))
|
||||
})
|
||||
|
||||
test('missing physical pallet-space evidence blocks after both real picks without fabricating loading or delivery',async()=>{
|
||||
test('scanned pallets confirm without a separate pallet-space measurement receipt',async()=>{
|
||||
const m=model();delete m.fixture.loadingMeasurements
|
||||
await assert.rejects(verifyFleetCrossCustomer(m.context,m.fixture,{execute:true,readInventory:m.readInventory}),/palletSpaces/)
|
||||
assert.ok(m.state.every(row=>row.picked===1&&row.delivery===null))
|
||||
assert.equal(m.calls.filter(call=>call.raw.endsWith('/loading-complete')).length,1,'only the earlier expected unready rejection was sent')
|
||||
assert.equal(m.calls.some(call=>call.raw.endsWith('/transfer-delivery')),false)
|
||||
await verifyFleetCrossCustomer(m.context,m.fixture,{execute:true,readInventory:m.readInventory})
|
||||
assert.ok(m.state.every(row=>row.picked===1&&row.delivery!==null))
|
||||
assert.ok(m.calls.filter(call=>call.raw.endsWith('/loading-complete')).every(call=>!('measurements' in call.body)))
|
||||
})
|
||||
|
||||
test('explicit rollback verifier runs after both picks and before successful departure',async()=>{
|
||||
const m=model();let calls=0
|
||||
const proof=await verifyFleetCrossCustomer(m.context,m.fixture,{execute:true,readInventory:m.readInventory,
|
||||
|
||||
Reference in New Issue
Block a user