mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 11:21:18 +00:00
308 lines
16 KiB
TypeScript
308 lines
16 KiB
TypeScript
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,
|
|
InitiateWarehouseInvoicePaymentPayload,
|
|
WarehouseInvoicePaymentResponse,
|
|
BookingScheduleView,
|
|
InventoryFilter,
|
|
InventoryInquiryFilter,
|
|
InventoryInquiryResult,
|
|
InventoryMovement,
|
|
LoadableWagon,
|
|
LoadInventoryPayload,
|
|
MoveInventoryPayload,
|
|
ReceiveInventoryPayload,
|
|
ReleaseOrderPayload,
|
|
DeliverInventoryPayload,
|
|
EligibleBooking,
|
|
BulkReceivePayload,
|
|
BulkReceiveResult,
|
|
LoadPassedExportResult,
|
|
BulkInspectPayload,
|
|
BulkInspectResult,
|
|
ReadyToLoadRow,
|
|
BulkDispatchResult,
|
|
AutoUnloadExportDjiboutiResult,
|
|
ExportTrain,
|
|
ExportTrainItem,
|
|
ImportTrain,
|
|
ImportTrainItem,
|
|
ImportUnloadedItem,
|
|
AutoUnloadArrivedResult,
|
|
ReserveInventoryPayload,
|
|
SaveWarehousePayload,
|
|
SaveYardPayload,
|
|
SaveZonePayload,
|
|
Warehouse,
|
|
WarehouseActivityLog,
|
|
WarehouseDashboard,
|
|
WarehouseFacility,
|
|
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<Warehouse[]>(URL_CONSTANTS.WAREHOUSES.BASE, {
|
|
params: cleanParams(filter ?? {}),
|
|
}),
|
|
dashboard: () => apiClient.get<WarehouseDashboard>(URL_CONSTANTS.WAREHOUSES.DASHBOARD),
|
|
getDashboardSummary: (_filter?: InventoryFilter) =>
|
|
apiClient.get<WarehouseDashboard>(URL_CONSTANTS.WAREHOUSES.DASHBOARD),
|
|
getById: (id: string) => apiClient.get<Warehouse>(URL_CONSTANTS.WAREHOUSES.BY_ID(id)),
|
|
create: (payload: SaveWarehousePayload) =>
|
|
apiClient.post<Warehouse>(URL_CONSTANTS.WAREHOUSES.BASE, payload),
|
|
update: (id: string, payload: Partial<SaveWarehousePayload>) =>
|
|
apiClient.patch<Warehouse>(URL_CONSTANTS.WAREHOUSES.BY_ID(id), payload),
|
|
listFacilities: () => apiClient.get<WarehouseFacility[]>(URL_CONSTANTS.RULE_ENGINE.YARDS),
|
|
|
|
// ── Yards ────────────────────────────────────────────────────────────────
|
|
listYards: (warehouseId: string) =>
|
|
apiClient.get<WarehouseYard[]>(URL_CONSTANTS.WAREHOUSES.YARDS(warehouseId)),
|
|
listAllYards: () => apiClient.get<WarehouseYard[]>(URL_CONSTANTS.WAREHOUSE_YARDS.BASE),
|
|
createYard: (warehouseId: string, payload: SaveYardPayload) =>
|
|
apiClient.post<WarehouseYard>(URL_CONSTANTS.WAREHOUSES.YARDS(warehouseId), payload),
|
|
getYard: (id: string) => apiClient.get<WarehouseYard>(URL_CONSTANTS.WAREHOUSE_YARDS.BY_ID(id)),
|
|
updateYard: (id: string, payload: Partial<SaveYardPayload>) =>
|
|
apiClient.patch<WarehouseYard>(URL_CONSTANTS.WAREHOUSE_YARDS.BY_ID(id), payload),
|
|
|
|
// ── Zones ──────────────────────────────────────────────────────────────
|
|
listZones: (yardId: string) =>
|
|
apiClient.get<WarehouseZone[]>(URL_CONSTANTS.WAREHOUSE_YARDS.ZONES(yardId)),
|
|
listAllZones: () => apiClient.get<WarehouseZone[]>(URL_CONSTANTS.WAREHOUSE_ZONES.BASE),
|
|
createZone: (yardId: string, payload: SaveZonePayload) =>
|
|
apiClient.post<WarehouseZone>(URL_CONSTANTS.WAREHOUSE_YARDS.ZONES(yardId), payload),
|
|
getZone: (id: string) => apiClient.get<WarehouseZone>(URL_CONSTANTS.WAREHOUSE_ZONES.BY_ID(id)),
|
|
updateZone: (id: string, payload: Partial<SaveZonePayload>) =>
|
|
apiClient.patch<WarehouseZone>(URL_CONSTANTS.WAREHOUSE_ZONES.BY_ID(id), payload),
|
|
|
|
// ── Inventory ──────────────────────────────────────────────────────────
|
|
listInventory: (filter?: InventoryFilter) =>
|
|
apiClient.get<WarehouseInventoryItem[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.BASE, {
|
|
params: cleanParams(filter ?? {}),
|
|
}),
|
|
receiveInventory: (payload: ReceiveInventoryPayload) =>
|
|
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RECEIVE, payload),
|
|
listReadyForLoading: (filter?: InventoryFilter) =>
|
|
apiClient.get<WarehouseInventoryItem[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.READY_FOR_LOADING, {
|
|
params: cleanParams(filter ?? {}),
|
|
}),
|
|
inquiry: (filter: InventoryInquiryFilter) =>
|
|
apiClient.get<InventoryInquiryResult[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.INQUIRY, {
|
|
params: cleanParams(filter ?? {}),
|
|
}),
|
|
|
|
// ── Lifecycle (Batch 2) ──────────────────────────────────────────────────
|
|
store: (id: string) =>
|
|
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.STORE(id)),
|
|
reserve: (payload: ReserveInventoryPayload) =>
|
|
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RESERVE, payload),
|
|
markReadyForLoading: (id: string) =>
|
|
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.MARK_READY(id)),
|
|
load: (id: string, payload: LoadInventoryPayload) =>
|
|
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.LOAD(id), payload),
|
|
dispatch: (id: string) =>
|
|
apiClient.patch<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.DISPATCH(id)),
|
|
|
|
// ── Import branch (READY_FOR_PICKUP → DELIVERED) ─────────────────────────
|
|
markReadyForPickup: (id: string) =>
|
|
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.MARK_READY_PICKUP(id)),
|
|
release: (id: string, payload: ReleaseOrderPayload) =>
|
|
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RELEASE(id), payload),
|
|
downloadReleaseDocument: (id: string) =>
|
|
apiClient.get<Blob>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RELEASE_DOCUMENT(id), {
|
|
responseType: 'blob',
|
|
}),
|
|
downloadGrnDocument: (id: string) =>
|
|
apiClient.get<Blob>(URL_CONSTANTS.WAREHOUSE_INVENTORY.GRN_DOCUMENT(id), {
|
|
responseType: 'blob',
|
|
}),
|
|
downloadHandoverDocument: (id: string) =>
|
|
apiClient.get<Blob>(URL_CONSTANTS.WAREHOUSE_INVENTORY.HANDOVER_DOCUMENT(id), {
|
|
responseType: 'blob',
|
|
}),
|
|
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, {}),
|
|
bulkMarkInspected: (payload: BulkInspectPayload) =>
|
|
apiClient.post<BulkInspectResult>(URL_CONSTANTS.WAREHOUSE_INVENTORY.BULK_MARK_INSPECTED, payload),
|
|
receivedExport: () =>
|
|
apiClient.get<ReadyToLoadRow[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RECEIVED_EXPORT),
|
|
readyToLoadExport: () =>
|
|
apiClient.get<ReadyToLoadRow[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.READY_TO_LOAD_EXPORT),
|
|
loadedExport: () =>
|
|
apiClient.get<ReadyToLoadRow[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.LOADED_EXPORT),
|
|
bulkDispatchExport: (inventoryIds: string[]) =>
|
|
apiClient.post<BulkDispatchResult>(URL_CONSTANTS.WAREHOUSE_INVENTORY.BULK_DISPATCH_EXPORT, {
|
|
inventoryIds,
|
|
}),
|
|
importArriveQueue: () =>
|
|
apiClient.get<ImportTrain[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.IMPORT_ARRIVE_QUEUE),
|
|
importTrainItems: (scheduleId: string) =>
|
|
apiClient.get<ImportTrainItem[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.IMPORT_TRAIN_ITEMS(scheduleId)),
|
|
autoUnloadArrivedBookings: (payload: {
|
|
scheduleId: string;
|
|
warehouseId?: string;
|
|
assignments?: { bookingId: string; warehouseId: string; yardId: string; zoneId: string }[];
|
|
}) =>
|
|
apiClient.post<AutoUnloadArrivedResult>(
|
|
URL_CONSTANTS.WAREHOUSE_INVENTORY.IMPORT_AUTO_UNLOAD_ARRIVED,
|
|
payload,
|
|
),
|
|
importUnloadedQueue: () =>
|
|
apiClient.get<ImportUnloadedItem[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.IMPORT_UNLOADED_QUEUE),
|
|
importPickupReadyQueue: () =>
|
|
apiClient.get<ImportUnloadedItem[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.IMPORT_PICKUP_READY_QUEUE),
|
|
exportDjiboutiArrivalQueue: () =>
|
|
apiClient.get<ExportTrain[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.EXPORT_DJIBOUTI_ARRIVAL_QUEUE),
|
|
exportDjiboutiTrainItems: (scheduleId: string) =>
|
|
apiClient.get<ExportTrainItem[]>(
|
|
URL_CONSTANTS.WAREHOUSE_INVENTORY.EXPORT_DJIBOUTI_TRAIN_ITEMS(scheduleId),
|
|
),
|
|
autoUnloadExportAtDjibouti: (scheduleId: string) =>
|
|
apiClient.post<AutoUnloadExportDjiboutiResult>(
|
|
URL_CONSTANTS.WAREHOUSE_INVENTORY.EXPORT_AUTO_UNLOAD_AT_DJIBOUTI,
|
|
{ scheduleId },
|
|
),
|
|
move: (id: string, payload: MoveInventoryPayload) =>
|
|
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.MOVE(id), payload),
|
|
movements: (id: string) =>
|
|
apiClient.get<InventoryMovement[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.MOVEMENTS(id)),
|
|
activity: (id: string) =>
|
|
apiClient.get<WarehouseActivityLog[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.ACTIVITY(id)),
|
|
|
|
// ── Loading (Batch 3) ─────────────────────────────────────────────────────
|
|
loadableWagons: () =>
|
|
apiClient.get<LoadableWagon[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.LOADABLE_WAGONS),
|
|
bookingSchedule: (bookingId: string) =>
|
|
apiClient.get<BookingScheduleView>(URL_CONSTANTS.WAREHOUSE_INVENTORY.BOOKING_SCHEDULE(bookingId)),
|
|
inventoryLoadings: (id: string) =>
|
|
apiClient.get<WarehouseLoading[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.LOADINGS(id)),
|
|
loadings: (params?: { bookingId?: string; wagonId?: string }) =>
|
|
apiClient.get<WarehouseLoading[]>(URL_CONSTANTS.WAREHOUSE_LOADINGS.BASE, {
|
|
params: cleanParams(params ?? {}),
|
|
}),
|
|
|
|
// ── Batch 4.5: Arrival / Unload / Load automation ──────────────────────────
|
|
arrivalQueue: () =>
|
|
apiClient.get<ArrivalQueueItem[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.ARRIVAL_QUEUE),
|
|
autoUnloadArrived: () =>
|
|
apiClient.post<AutoUnloadResult>(URL_CONSTANTS.WAREHOUSE_INVENTORY.AUTO_UNLOAD_ARRIVED),
|
|
autoLoadReady: () =>
|
|
apiClient.post<AutoLoadResult>(URL_CONSTANTS.WAREHOUSE_INVENTORY.AUTO_LOAD_READY),
|
|
unloadBooking: (bookingId: string, payload?: Record<string, unknown>) =>
|
|
apiClient.post<WarehouseInventoryItem>(
|
|
URL_CONSTANTS.WAREHOUSE_INVENTORY.UNLOAD_BOOKING(bookingId),
|
|
payload ?? {},
|
|
),
|
|
|
|
// ── Batch 4.5: Inspection reports ──────────────────────────────────────────
|
|
listInspectionReports: (inventoryId: string) =>
|
|
apiClient.get<InspectionReport[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.INSPECTION_REPORTS(inventoryId)),
|
|
createInspectionReport: (inventoryId: string, payload: InspectionReportPayload) =>
|
|
apiClient.post<InspectionReport>(
|
|
URL_CONSTANTS.WAREHOUSE_INVENTORY.INSPECTION_REPORTS(inventoryId),
|
|
payload,
|
|
),
|
|
getInspectionReport: (id: string) =>
|
|
apiClient.get<InspectionReport>(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<InspectionAttachment[]>(
|
|
URL_CONSTANTS.WAREHOUSE_INSPECTION.ATTACHMENTS(id),
|
|
form,
|
|
{ headers: { 'Content-Type': 'multipart/form-data' } },
|
|
);
|
|
},
|
|
|
|
// ── Batch 5: Allocation + Fee rules / previews ─────────────────────────────
|
|
listAllocationRules: () =>
|
|
apiClient.get<AllocationRule[]>(URL_CONSTANTS.WAREHOUSE_RULES.ALLOCATION),
|
|
createAllocationRule: (payload: SaveAllocationRulePayload) =>
|
|
apiClient.post<AllocationRule>(URL_CONSTANTS.WAREHOUSE_RULES.ALLOCATION, payload),
|
|
updateAllocationRule: (id: string, payload: Partial<SaveAllocationRulePayload>) =>
|
|
apiClient.patch<AllocationRule>(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<AllocationPreviewResult | null>(URL_CONSTANTS.WAREHOUSE_RULES.ALLOCATION_PREVIEW, criteria),
|
|
|
|
listFeeRules: () => apiClient.get<FeeRule[]>(URL_CONSTANTS.WAREHOUSE_RULES.FEES),
|
|
createFeeRule: (payload: SaveFeeRulePayload) =>
|
|
apiClient.post<FeeRule>(URL_CONSTANTS.WAREHOUSE_RULES.FEES, payload),
|
|
updateFeeRule: (id: string, payload: Partial<SaveFeeRulePayload>) =>
|
|
apiClient.patch<FeeRule>(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, billingCurrency?: 'ETB' | 'USD') =>
|
|
apiClient.get<FeePreview[]>(URL_CONSTANTS.WAREHOUSE_RULES.FEE_PREVIEW(inventoryId), {
|
|
params: cleanParams({ billingCurrency }),
|
|
}),
|
|
|
|
// ── Batch 6: Warehouse fee invoices ────────────────────────────────────────
|
|
listInvoices: (filter?: WarehouseInvoiceFilter) =>
|
|
apiClient.get<WarehouseFeeInvoice[]>(URL_CONSTANTS.WAREHOUSE_INVOICES.BASE, {
|
|
params: cleanParams(filter ?? {}),
|
|
}),
|
|
getInvoice: (id: string) =>
|
|
apiClient.get<WarehouseFeeInvoice>(URL_CONSTANTS.WAREHOUSE_INVOICES.BY_ID(id)),
|
|
downloadInvoiceDocument: (id: string) =>
|
|
apiClient.get<Blob>(URL_CONSTANTS.WAREHOUSE_INVOICES.DOCUMENT(id), {
|
|
responseType: 'blob',
|
|
}),
|
|
downloadInvoiceReceipt: (id: string) =>
|
|
apiClient.get<Blob>(URL_CONSTANTS.WAREHOUSE_INVOICES.RECEIPT(id), {
|
|
responseType: 'blob',
|
|
}),
|
|
invoicesForInventory: (inventoryId: string) =>
|
|
apiClient.get<WarehouseFeeInvoice[]>(URL_CONSTANTS.WAREHOUSE_INVOICES.FOR_INVENTORY(inventoryId)),
|
|
invoicesForBooking: (bookingId: string) =>
|
|
apiClient.get<WarehouseFeeInvoice[]>(URL_CONSTANTS.WAREHOUSE_INVOICES.FOR_BOOKING(bookingId)),
|
|
generateInvoice: (inventoryId: string, confirmZero = false, billingCurrency?: 'ETB' | 'USD') =>
|
|
apiClient.post<WarehouseFeeInvoice>(URL_CONSTANTS.WAREHOUSE_INVOICES.GENERATE(inventoryId), {
|
|
confirmZero,
|
|
billingCurrency,
|
|
}),
|
|
cancelInvoice: (id: string) =>
|
|
apiClient.patch<WarehouseFeeInvoice>(URL_CONSTANTS.WAREHOUSE_INVOICES.CANCEL(id)),
|
|
payInvoice: (id: string, payload: PayInvoicePayload) =>
|
|
apiClient.post<WarehouseFeeInvoice>(URL_CONSTANTS.WAREHOUSE_INVOICES.PAY(id), payload),
|
|
payInvoiceOnline: (id: string, payload: InitiateWarehouseInvoicePaymentPayload) =>
|
|
apiClient.post<WarehouseInvoicePaymentResponse>(URL_CONSTANTS.WAREHOUSE_INVOICES.PAY_ONLINE(id), payload),
|
|
gateClearance: (inventoryId: string) =>
|
|
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVOICES.GATE_CLEARANCE(inventoryId), {}),
|
|
};
|