feat(warehouse): Receive Import/Export tabs with bulk receive + load-passed-export

- Backend: GET eligible-bookings?direction, POST receive-bulk, POST load-passed-export
  (reuse autoUnload/autoLoad patterns; no train-schedule/wagon logic changed)
- Frontend: ReceiveInventoryModal split into Import/Export tabs with eligible PAID
  bookings table, select-all/bulk receive, and Load Passed Export Items button
- Single-booking receive and all existing inventory row actions preserved

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hagernesh
2026-06-20 08:29:59 +00:00
parent d7352ba4e8
commit 0005b2edb3
8 changed files with 632 additions and 88 deletions

View File

@@ -29,6 +29,10 @@ import type {
ReceiveInventoryPayload,
ReleaseOrderPayload,
DeliverInventoryPayload,
EligibleBooking,
BulkReceivePayload,
BulkReceiveResult,
LoadPassedExportResult,
ReserveInventoryPayload,
SaveWarehousePayload,
SaveYardPayload,
@@ -114,6 +118,14 @@ export const warehouseService = {
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RELEASE(id), payload),
deliver: (id: string, payload: DeliverInventoryPayload) =>
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.DELIVER(id), payload),
// ── Receive (Import/Export bulk) ─────────────────────────────────────────
eligibleBookings: (direction: 'IMPORT' | 'EXPORT') =>
apiClient.get<EligibleBooking[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.ELIGIBLE_BOOKINGS(direction)),
receiveBulk: (payload: BulkReceivePayload) =>
apiClient.post<BulkReceiveResult>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RECEIVE_BULK, payload),
loadPassedExport: () =>
apiClient.post<LoadPassedExportResult>(URL_CONSTANTS.WAREHOUSE_INVENTORY.LOAD_PASSED_EXPORT, {}),
move: (id: string, payload: MoveInventoryPayload) =>
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.MOVE(id), payload),
movements: (id: string) =>