import { api as apiClient } from '../auth/http'; import { URL_CONSTANTS } from '@/constants/URLS'; import type { AllocationCriteria, AllocationPreviewResult, AllocationRule, ArrivalQueueItem, AutoLoadResult, AutoUnloadResult, FeePreview, FeeRule, InspectionAttachment, InspectionReport, InspectionReportPayload, SaveAllocationRulePayload, SaveFeeRulePayload, WarehouseFeeInvoice, WarehouseInvoiceFilter, PayInvoicePayload, BookingScheduleView, InventoryFilter, InventoryInquiryFilter, InventoryInquiryResult, InventoryMovement, LoadableWagon, LoadInventoryPayload, MoveInventoryPayload, ReceiveInventoryPayload, ReserveInventoryPayload, SaveWarehousePayload, SaveYardPayload, SaveZonePayload, Warehouse, WarehouseActivityLog, WarehouseDashboard, WarehouseFilter, WarehouseInventoryItem, WarehouseLoading, WarehouseYard, WarehouseZone, } from '@/types/warehouse'; const cleanParams = (params: object) => Object.fromEntries( Object.entries(params).filter(([, value]) => value !== undefined && value !== '' && value !== null), ); export const warehouseService = { // ── Warehouses ────────────────────────────────────────────────────────── list: (filter?: WarehouseFilter) => apiClient.get(URL_CONSTANTS.WAREHOUSES.BASE, { params: cleanParams(filter ?? {}), }), dashboard: () => apiClient.get(URL_CONSTANTS.WAREHOUSES.DASHBOARD), getById: (id: string) => apiClient.get(URL_CONSTANTS.WAREHOUSES.BY_ID(id)), create: (payload: SaveWarehousePayload) => apiClient.post(URL_CONSTANTS.WAREHOUSES.BASE, payload), update: (id: string, payload: Partial) => apiClient.patch(URL_CONSTANTS.WAREHOUSES.BY_ID(id), payload), // ── Yards ──────────────────────────────────────────────────────────────── listYards: (warehouseId: string) => apiClient.get(URL_CONSTANTS.WAREHOUSES.YARDS(warehouseId)), createYard: (warehouseId: string, payload: SaveYardPayload) => apiClient.post(URL_CONSTANTS.WAREHOUSES.YARDS(warehouseId), payload), getYard: (id: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_YARDS.BY_ID(id)), updateYard: (id: string, payload: Partial) => apiClient.patch(URL_CONSTANTS.WAREHOUSE_YARDS.BY_ID(id), payload), // ── Zones ────────────────────────────────────────────────────────────── listZones: (yardId: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_YARDS.ZONES(yardId)), createZone: (yardId: string, payload: SaveZonePayload) => apiClient.post(URL_CONSTANTS.WAREHOUSE_YARDS.ZONES(yardId), payload), getZone: (id: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_ZONES.BY_ID(id)), updateZone: (id: string, payload: Partial) => apiClient.patch(URL_CONSTANTS.WAREHOUSE_ZONES.BY_ID(id), payload), // ── Inventory ────────────────────────────────────────────────────────── listInventory: (filter?: InventoryFilter) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVENTORY.BASE, { params: cleanParams(filter ?? {}), }), receiveInventory: (payload: ReceiveInventoryPayload) => apiClient.post(URL_CONSTANTS.WAREHOUSE_INVENTORY.RECEIVE, payload), listReadyForLoading: (filter?: InventoryFilter) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVENTORY.READY_FOR_LOADING, { params: cleanParams(filter ?? {}), }), inquiry: (filter: InventoryInquiryFilter) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVENTORY.INQUIRY, { params: cleanParams(filter ?? {}), }), // ── Lifecycle (Batch 2) ────────────────────────────────────────────────── store: (id: string) => apiClient.post(URL_CONSTANTS.WAREHOUSE_INVENTORY.STORE(id)), reserve: (payload: ReserveInventoryPayload) => apiClient.post(URL_CONSTANTS.WAREHOUSE_INVENTORY.RESERVE, payload), markReadyForLoading: (id: string) => apiClient.post(URL_CONSTANTS.WAREHOUSE_INVENTORY.MARK_READY(id)), load: (id: string, payload: LoadInventoryPayload) => apiClient.post(URL_CONSTANTS.WAREHOUSE_INVENTORY.LOAD(id), payload), dispatch: (id: string) => apiClient.patch(URL_CONSTANTS.WAREHOUSE_INVENTORY.DISPATCH(id)), move: (id: string, payload: MoveInventoryPayload) => apiClient.post(URL_CONSTANTS.WAREHOUSE_INVENTORY.MOVE(id), payload), movements: (id: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVENTORY.MOVEMENTS(id)), activity: (id: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVENTORY.ACTIVITY(id)), // ── Loading (Batch 3) ───────────────────────────────────────────────────── loadableWagons: () => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVENTORY.LOADABLE_WAGONS), bookingSchedule: (bookingId: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVENTORY.BOOKING_SCHEDULE(bookingId)), inventoryLoadings: (id: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVENTORY.LOADINGS(id)), loadings: (params?: { bookingId?: string; wagonId?: string }) => apiClient.get(URL_CONSTANTS.WAREHOUSE_LOADINGS.BASE, { params: cleanParams(params ?? {}), }), // ── Batch 4.5: Arrival / Unload / Load automation ────────────────────────── arrivalQueue: () => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVENTORY.ARRIVAL_QUEUE), autoUnloadArrived: () => apiClient.post(URL_CONSTANTS.WAREHOUSE_INVENTORY.AUTO_UNLOAD_ARRIVED), autoLoadReady: () => apiClient.post(URL_CONSTANTS.WAREHOUSE_INVENTORY.AUTO_LOAD_READY), unloadBooking: (bookingId: string, payload?: Record) => apiClient.post( URL_CONSTANTS.WAREHOUSE_INVENTORY.UNLOAD_BOOKING(bookingId), payload ?? {}, ), // ── Batch 4.5: Inspection reports ────────────────────────────────────────── listInspectionReports: (inventoryId: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVENTORY.INSPECTION_REPORTS(inventoryId)), createInspectionReport: (inventoryId: string, payload: InspectionReportPayload) => apiClient.post( URL_CONSTANTS.WAREHOUSE_INVENTORY.INSPECTION_REPORTS(inventoryId), payload, ), getInspectionReport: (id: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INSPECTION.BY_ID(id)), uploadInspectionAttachments: (id: string, files: File[]) => { const form = new FormData(); files.forEach((file) => form.append('files', file)); return apiClient.post( URL_CONSTANTS.WAREHOUSE_INSPECTION.ATTACHMENTS(id), form, { headers: { 'Content-Type': 'multipart/form-data' } }, ); }, // ── Batch 5: Allocation + Fee rules / previews ───────────────────────────── listAllocationRules: () => apiClient.get(URL_CONSTANTS.WAREHOUSE_RULES.ALLOCATION), createAllocationRule: (payload: SaveAllocationRulePayload) => apiClient.post(URL_CONSTANTS.WAREHOUSE_RULES.ALLOCATION, payload), updateAllocationRule: (id: string, payload: Partial) => apiClient.patch(URL_CONSTANTS.WAREHOUSE_RULES.ALLOCATION_BY_ID(id), payload), deleteAllocationRule: (id: string) => apiClient.delete(URL_CONSTANTS.WAREHOUSE_RULES.ALLOCATION_BY_ID(id)), previewAllocation: (criteria: AllocationCriteria) => apiClient.post(URL_CONSTANTS.WAREHOUSE_RULES.ALLOCATION_PREVIEW, criteria), listFeeRules: () => apiClient.get(URL_CONSTANTS.WAREHOUSE_RULES.FEES), createFeeRule: (payload: SaveFeeRulePayload) => apiClient.post(URL_CONSTANTS.WAREHOUSE_RULES.FEES, payload), updateFeeRule: (id: string, payload: Partial) => apiClient.patch(URL_CONSTANTS.WAREHOUSE_RULES.FEES_BY_ID(id), payload), deleteFeeRule: (id: string) => apiClient.delete(URL_CONSTANTS.WAREHOUSE_RULES.FEES_BY_ID(id)), feePreview: (inventoryId: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_RULES.FEE_PREVIEW(inventoryId)), // ── Batch 6: Warehouse fee invoices ──────────────────────────────────────── listInvoices: (filter?: WarehouseInvoiceFilter) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVOICES.BASE, { params: cleanParams(filter ?? {}), }), getInvoice: (id: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVOICES.BY_ID(id)), invoicesForInventory: (inventoryId: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVOICES.FOR_INVENTORY(inventoryId)), invoicesForBooking: (bookingId: string) => apiClient.get(URL_CONSTANTS.WAREHOUSE_INVOICES.FOR_BOOKING(bookingId)), generateInvoice: (inventoryId: string, confirmZero = false) => apiClient.post(URL_CONSTANTS.WAREHOUSE_INVOICES.GENERATE(inventoryId), { confirmZero }), cancelInvoice: (id: string) => apiClient.patch(URL_CONSTANTS.WAREHOUSE_INVOICES.CANCEL(id)), payInvoice: (id: string, payload: PayInvoicePayload) => apiClient.post(URL_CONSTANTS.WAREHOUSE_INVOICES.PAY(id), payload), gateClearance: (inventoryId: string) => apiClient.post(URL_CONSTANTS.WAREHOUSE_INVOICES.GATE_CLEARANCE(inventoryId), {}), };