import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http' export type LoadingListMode = 'preload' | 'confirmed' export interface LoadingCustomer { accountId: string customerName: string | null } export interface PreloadSummary { planId: string preloadNo: string containerNo: string | null internalContainerNo: string | null customers: LoadingCustomer[] warehouseId: string | null warehouseName: string | null vesselName: string | null voyageNo: string | null containerType: string | null status: string skuCount: string totalPackageCount: string totalVolumeCbm: number totalGrossWeightKg: number createdAt: string version: number } export interface ConfirmedSummary { planId: string loadingListNo: string warehouseId: string | null warehouseName: string | null containerNo: string | null internalContainerNo: string | null status: string totalPackageCount: string totalGrossWeightKg: number totalNetWeightKg: number totalVolumeCbm: number totalQuantity: string remark: string | null createdBy: string | null createdByName: string | null createdAt: string version: number } export type LoadingListSummary = PreloadSummary | ConfirmedSummary export interface LoadingItem { itemId: string accountId: string customerName: string | null inboundId: string inboundDetailId: string inboundCode: string | null skuCode: string | null destinationWarehouse: string | null chineseName: string | null englishName: string | null goodsImageUrl: string | null packageCount: number palletCount: number grossWeightKg: number netWeightKg: number volumeCbm: number dimensionalWeightKg: number productQuantity: string unitsPerPackage: number fbaTrackingNo: string | null shipmentNo: string | null shippingMark: string | null internalRemark: string | null customerRemark: string | null warehouseRemark: string | null loadSequence: number frozenAt: string | null } export interface LoadingHistory { historyId: string itemId: string | null actionType: string fromStatus: string | null toStatus: string | null beforeSnapshot: string | null afterSnapshot: string | null operatorId: string operatorName: string | null operationReason: string | null occurredAt: string } export interface LoadingDetail { summary: T items: LoadingItem[] histories: LoadingHistory[] } export interface LoadingListPage { records: T[] page: number size: number total: number pages: number } export interface LoadingListQuery { page: number size: number warehouseId: string keyword?: string createdFrom?: string createdTo?: string } export interface TransportUpdateRequest { containerNo: string | null voyageNo: string | null expectedVersion: number operationReason: string | null } type RawId = string | number | null | undefined type RawPage = Omit, 'page' | 'size' | 'total' | 'pages'> & { page: string | number size: string | number total: string | number pages: string | number } const basePath = '/platform/v1/first-leg' function requiredId(value: RawId) { return String(value ?? '') } function optionalId(value: RawId) { return value === null || value === undefined ? null : String(value) } function normalizePreloadSummary(raw: PreloadSummary): PreloadSummary { return { ...raw, planId: requiredId(raw.planId), warehouseId: optionalId(raw.warehouseId), skuCount: String(raw.skuCount ?? '0'), totalPackageCount: String(raw.totalPackageCount ?? '0'), customers: (raw.customers || []).map((customer) => ({ ...customer, accountId: requiredId(customer.accountId), })), } } function normalizeConfirmedSummary(raw: ConfirmedSummary): ConfirmedSummary { return { ...raw, planId: requiredId(raw.planId), warehouseId: optionalId(raw.warehouseId), createdBy: optionalId(raw.createdBy), totalPackageCount: String(raw.totalPackageCount ?? '0'), totalQuantity: String(raw.totalQuantity ?? '0'), } } function normalizeItem(raw: LoadingItem): LoadingItem { return { ...raw, itemId: requiredId(raw.itemId), accountId: requiredId(raw.accountId), inboundId: requiredId(raw.inboundId), inboundDetailId: requiredId(raw.inboundDetailId), productQuantity: String(raw.productQuantity ?? '0'), } } function normalizeHistory(raw: LoadingHistory): LoadingHistory { return { ...raw, historyId: requiredId(raw.historyId), itemId: optionalId(raw.itemId), operatorId: requiredId(raw.operatorId), } } function normalizePage(raw: RawPage, normalize: (row: T) => T): LoadingListPage { return { records: (raw.records || []).map(normalize), page: Number(raw.page), size: Number(raw.size), total: Number(raw.total), pages: Number(raw.pages), } } function idempotencyKey(planId: string) { return `admin-preload-transport-${planId}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}` } export async function listPreloadPlans(query: LoadingListQuery) { const response = await http.get>, ApiEnvelope>>( `${basePath}/loading-plans`, { params: { ...query, status: 'LOADING' } }, ) return normalizePage(unwrapApiResponse(response), normalizePreloadSummary) } export async function getPreloadPlan(planId: string, warehouseId: string) { const response = await http.get>, ApiEnvelope>>( `${basePath}/loading-plans/${planId}`, { params: { warehouseId } }, ) const result = unwrapApiResponse(response) return { summary: normalizePreloadSummary(result.summary), items: (result.items || []).map(normalizeItem), histories: (result.histories || []).map(normalizeHistory), } } export async function updatePreloadTransport(planId: string, warehouseId: string, request: TransportUpdateRequest) { const response = await http.patch>, ApiEnvelope>>( `${basePath}/loading-plans/${planId}/transport`, request, { params: { warehouseId }, headers: { 'Idempotency-Key': idempotencyKey(planId) } }, ) const result = unwrapApiResponse(response) return { summary: normalizePreloadSummary(result.summary), items: (result.items || []).map(normalizeItem), histories: (result.histories || []).map(normalizeHistory), } } export async function listConfirmedLoadingLists(query: LoadingListQuery) { const response = await http.get>, ApiEnvelope>>( `${basePath}/loading-lists`, { params: query }, ) return normalizePage(unwrapApiResponse(response), normalizeConfirmedSummary) } export async function getConfirmedLoadingList(planId: string, warehouseId: string) { const response = await http.get>, ApiEnvelope>>( `${basePath}/loading-lists/${planId}`, { params: { warehouseId } }, ) const result = unwrapApiResponse(response) return { summary: normalizeConfirmedSummary(result.summary), items: (result.items || []).map(normalizeItem), histories: (result.histories || []).map(normalizeHistory), } }