import type { WarehouseTransferDetailDto, ReceiveWarehouseTransferPayload, WarehouseTransferReceiptCommandDto } from '../api/warehouseTransfers' import type { PalletDto, ReceivingOverseasWarehouseDto } from '../api/pallets' import type { OverseasLocationDto } from '../api/locations' export type ReceiptTarget = { warehouse: ReceivingOverseasWarehouseDto; pallet: PalletDto; location: OverseasLocationDto } export function canOutboundTransfer(detail: WarehouseTransferDetailDto) { return detail.status === 'ALLOCATED' && !!detail.fbaWarehouseCode && (!detail.needRelabel || (!!detail.relabelNo && ['READY_FOR_OUTBOUND', 'COMPLETED'].includes(detail.relabelStatus || ''))) && !!detail.allocations?.length && detail.allocations.every(a => a.status === 'RESERVED') && detail.allocations.reduce((sum, a) => sum + a.packageCount, 0) === detail.packageCount } export function receiptTargetValid(detail: WarehouseTransferDetailDto, target: ReceiptTarget, previous?: WarehouseTransferReceiptCommandDto['target'] | null) { const { warehouse: w, pallet: p, location: l } = target const same = previous && previous.warehouseId === w.id && previous.palletId === p.id && previous.locationId === l.id return w.warehouseType === 'OVERSEAS' && w.status === 'ACTIVE' && w.customerId === '0' && p.warehouseId === w.id && l.warehouseId === w.id && p.locationId === l.id && p.customerId === '0' && !!p.palletCode && !!l.locationCode && p.fbaWarehouseCode === detail.destinationWarehouseCode && (p.status === 'IDLE' || (same && p.status === 'OCCUPIED')) && (l.locationType === 'VIRTUAL' ? l.status === 'ACTIVE' : (l.status === 'IDLE' || (same && l.status === 'OCCUPIED'))) } export function createReceiptCommand(detail: WarehouseTransferDetailDto, sourceId: string, target: ReceiptTarget, key: string, previous?: WarehouseTransferReceiptCommandDto['target'] | null): ReceiveWarehouseTransferPayload { if (!['OUTBOUNDED', 'PARTIALLY_RECEIVED'].includes(detail.status) || !detail.allocations?.some(a => a.inventoryPositionId === sourceId && a.status === 'SHIPPED') || !detail.destinationWarehouseCode || !receiptTargetValid(detail, target, previous)) throw new Error('来源或目标收货资源不符合本票要求,请重新核对') return { sourceInventoryPositionId: sourceId, destinationOverseasWarehouseId: target.warehouse.id, destinationOverseasWarehouseCode: target.warehouse.warehouseCode, destinationOverseasWarehouseName: target.warehouse.warehouseName, destinationWarehouseId: detail.destinationWarehouseId || undefined, destinationWarehouseCode: detail.destinationWarehouseCode, destinationWarehouseName: detail.destinationWarehouseName || undefined, destinationPalletId: target.pallet.id, destinationPalletNo: target.pallet.palletCode, warehouseLocationId: target.location.id, warehouseLocationCode: target.location.locationCode, batchNo: detail.transferNo, idempotencyKey: key } }