diff --git a/src/modules/first-leg/store/firstLegDraftCommands.test.mjs b/src/modules/first-leg/store/firstLegDraftCommands.test.mjs index 9c7e901..07941fb 100644 --- a/src/modules/first-leg/store/firstLegDraftCommands.test.mjs +++ b/src/modules/first-leg/store/firstLegDraftCommands.test.mjs @@ -21,7 +21,7 @@ function harness(t) { calls.push(structuredClone(config)) if (config.method === 'GET') { if (behavior.failRead) throw new Error('读取失败') - return { order: { id: 'one', orderNo: 'FL-ONE', version: behavior.version, status: behavior.status, receivingWarehouseId: 'warehouse', destinationCountryCode: 'US' }, cargoes: [] } + return { order: { id: 'one', orderNo: 'FL-ONE', version: behavior.version, status: behavior.status, receivingWarehouseId: 'warehouse', receivingWarehouseAddress: behavior.receivingWarehouseAddress, destinationCountryCode: 'US' }, cargoes: [] } } if (behavior.failWrite || (behavior.failSubmit && config.url.endsWith('/submit'))) throw new Error('响应丢失') if (config.url.endsWith('/submit') && behavior.failSubmitRead) behavior.failRead = true @@ -31,7 +31,7 @@ function harness(t) { vue, pinia, '@/modules/first-leg/api/firstLeg': api, '@/modules/first-leg/api/unifiedOrders': { - getMerchantUnifiedOrder: async () => ({ summary: { orderId: 'one', mainStatus: null }, order: { order: { id: 'one', status: behavior.status, version: behavior.version, receivingWarehouseId: 'warehouse' } }, timeline: [] }), + getMerchantUnifiedOrder: async () => ({ summary: { orderId: 'one', mainStatus: null }, order: { order: { id: 'one', status: behavior.status, version: behavior.version, receivingWarehouseId: 'warehouse', receivingWarehouseAddress: behavior.receivingWarehouseAddress } }, timeline: [] }), isUnifiedOrderQueryUnavailable: () => false, }, '@/modules/first-leg/utils/firstLegOrder': { canClientEditFirstLegOrder: status => status === 'DRAFT', getFirstLegStatusLabel: value => value }, @@ -43,6 +43,51 @@ function harness(t) { return { store, api, calls, behavior, draft } } +function displayedWarehouseAddress(order) { + const view = readFileSync(new URL('../views/FirstLegOrdersView.vue', import.meta.url), 'utf8') + const expressions = [...view.matchAll(/\{\{ (detailOrder\.receivingWarehouseSnapshot\.(?:province|city|address)) \}\}/g)] + assert.equal(expressions.length, 3) + return expressions.map(([, expression]) => new Function('detailOrder', `return ${expression}`)(order)).join('') +} + +test('complete address is identical for cold unified, warm unified, raw detail and remark-only save', async t => { + const h = harness(t) + const fullAddress = 'CN 浙江省 义乌市 仓库路 8 号 322000' + h.behavior.receivingWarehouseAddress = fullAddress + h.store.warehouses = [] + const cold = await h.store.loadDetail('one') + assert.equal(displayedWarehouseAddress(cold), fullAddress) + h.store.warehouses = [{ id: 'warehouse', name: '国内仓', warehouseType: 'DOMESTIC', province: '浙江省', city: '义乌市', address: '主档已更新的地址' }] + h.store.orders = [] + const warm = await h.store.loadDetail('one') + const raw = await h.store.loadDraftDetail('one') + for (const detail of [warm, raw]) { + assert.equal(displayedWarehouseAddress(detail), fullAddress) + assert.equal(detail.receivingWarehouseSnapshot.province, '') + assert.equal(detail.receivingWarehouseSnapshot.city, '') + } + const session = h.store.beginDraftEdit(raw) + h.draft.customerRemark = '仅修改备注' + const saved = await h.store.saveDraft(h.draft, '客户', 'one', session) + assert.equal(displayedWarehouseAddress(saved), fullAddress) + const write = h.calls.find(call => call.method === 'PUT') + assert.equal(write.data.draft.customerRemark, '仅修改备注') + assert.equal(Object.hasOwn(write.data.draft, 'receivingWarehouseAddress'), false) + assert.equal(h.behavior.receivingWarehouseAddress, fullAddress) + assert.equal(h.store.warehouses[0].province, '浙江省') + assert.equal(h.store.warehouses[0].address, '主档已更新的地址') +}) + +test('structured master address stays structured when no order address snapshot exists', async t => { + const h = harness(t) + h.store.warehouses = [{ id: 'warehouse', name: '国内仓', province: '浙江省', city: '义乌市', address: '仓库路 8 号', warehouseType: 'DOMESTIC' }] + const detail = await h.store.loadDetail('one') + assert.equal(detail.receivingWarehouseSnapshot.province, '浙江省') + assert.equal(detail.receivingWarehouseSnapshot.city, '义乌市') + assert.equal(detail.receivingWarehouseSnapshot.address, '仓库路 8 号') + assert.equal(displayedWarehouseAddress(detail), '浙江省义乌市仓库路 8 号') +}) + test('raw and unified cancelled detail remain CANCELLED even when unified mainStatus is null', async t => { const h = harness(t) h.behavior.status = 'CANCELLED' diff --git a/src/modules/first-leg/store/firstLegOrders.ts b/src/modules/first-leg/store/firstLegOrders.ts index 2087295..fdde68a 100644 --- a/src/modules/first-leg/store/firstLegOrders.ts +++ b/src/modules/first-leg/store/firstLegOrders.ts @@ -160,8 +160,10 @@ function orderWarehouseSnapshot(order: MerchantFirstLegOrder, warehouse?: Platfo id: String(order.receivingWarehouseId), code: warehouse?.code ?? '', name: order.receivingWarehouseName, - province: warehouse?.province ?? '', - city: warehouse?.city ?? '', + // Order stores the complete formatted address, including province and city. + // Do not prefix this snapshot with fields from the current warehouse master. + province: '', + city: '', address: order.receivingWarehouseAddress, } }