This commit is contained in:
2026-10-20 11:33:39 +08:00
parent d2f2ecf57a
commit 41a498657c
33 changed files with 909 additions and 88 deletions
@@ -30,6 +30,19 @@ function fixture(): WarehouseTransferDetailDto {
beforeEach(() => { vi.mocked(getWarehouseTransfer).mockReset(); vi.mocked(getWarehouseTransferCartonLabel).mockReset() })
afterEach(() => vi.restoreAllMocks())
describe('转运预报与实际签收明细', () => {
it('keeps historical receipt totals after discard or shipment and leaves unknown declaration differences blank', async () => {
const value = fixture()
value.items[0]!.quantity = null
value.cartons[0]!.status = 'DISCARD_PENDING'
value.cartons[1]!.status = 'SHIPPED'
value.cartons[2]!.status = 'DISCARDED'
vi.mocked(getWarehouseTransfer).mockResolvedValue(value)
const wrapper = render(); await flushPromises()
expect(wrapper.emitted('summary')!.at(-1)![0]).toMatchObject({ boxes: 3, quantity: 27, skus: 2, forecastQuantity: null })
const rows = wrapper.findAllComponents(DataTableStub)[0]!.props('data')
expect(rows[0]).toMatchObject({ receivedQuantity: 20, receivedBoxes: 2, quantityDifference: null })
expect(wrapper.findAll('.test-table')[0]!.text()).toContain('未记录')
})
it('shows every SKU in a mixed box and counts its physical measurements once', async () => {
const value = fixture()
value.cartons = [{ ...value.cartons[0]!, quantity: 10, items: [{ transferItemId: '10', skuCode: 'SKU-A', quantity: 3 }, { transferItemId: '20', skuCode: 'SKU-B', quantity: 7 }] }]
@@ -46,7 +46,8 @@ const cartonsOpen = ref(false)
let generation = 0
// 同一完成原因保存于箱记录,去重后在尾程详情直接展示。
const discrepancyReasons = computed(() => [...new Set((detail.value?.cartons || []).map(box => box.discrepancyReason?.trim()).filter((reason): reason is string => Boolean(reason)))])
const cartons = computed(() => (detail.value?.cartons || []).filter(box => box.status === 'COUNTED'))
// 已签收是历史事实,后续废弃占用、废弃或出库不能从实收汇总中移除。
const cartons = computed(() => (detail.value?.cartons || []).filter(box => ['COUNTED', 'DISCARD_PENDING', 'DISCARDED', 'SHIPPED'].includes(box.status)))
function itemFor(box: WarehouseTransferCartonDto) { return detail.value?.items.find(item => box.transferItemId != null && String(item.id) === String(box.transferItemId)) }
function boxLines(box: WarehouseTransferCartonDto) {
if (box.items?.length) return box.items
@@ -64,9 +65,10 @@ watch([detail, totals], () => emit('summary', detail.value ? { ...totals.value,
const comparisonRows = computed(() => (detail.value?.items || []).map(item => {
const boxes = cartons.value.filter(box => boxLines(box).some(line => String(line.transferItemId) === String(item.id)))
const receivedQuantity = boxes.reduce((sum, box) => sum + boxLines(box).filter(line => String(line.transferItemId) === String(item.id)).reduce((total, line) => total + Number(line.quantity), 0), 0)
return { ...item, receivedQuantity, receivedBoxes: boxes.length, quantityDifference: receivedQuantity - Number(item.quantity || 0), boxDifference: boxes.length - Number(item.packageCount || 0) }
return { ...item, receivedQuantity, receivedBoxes: boxes.length, quantityDifference: item.quantity == null ? null : receivedQuantity - Number(item.quantity), boxDifference: boxes.length - Number(item.packageCount || 0) }
}))
function differenceText(value: unknown) {
if (value == null) return '未记录'
if (!cartons.value.length) return '待签收'
const difference = Number(value)
return difference > 0 ? `+${difference}` : String(difference)