mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 14:08:11 +00:00
Warehouse Enhancemendt
This commit is contained in:
@@ -80,6 +80,26 @@ export interface ContractView {
|
||||
signedAt: string;
|
||||
signatureImageUrl?: string | null;
|
||||
}>;
|
||||
/** Current viewer's reusable saved signature, if they have one. */
|
||||
savedSignature?: {
|
||||
signerDisplayName: string;
|
||||
signatureImageUrl?: string | null;
|
||||
} | null;
|
||||
}
|
||||
|
||||
export interface ConsolidationWagonSlot {
|
||||
containerTypeCode: string;
|
||||
quantity: number;
|
||||
containersPerWagon: number;
|
||||
remainder: number;
|
||||
slotsNeeded: number;
|
||||
}
|
||||
|
||||
export interface ConsolidationDetails {
|
||||
statusMessage: string;
|
||||
wagonSlots: ConsolidationWagonSlot[];
|
||||
partner: { id: string; reference: string } | null;
|
||||
splitBilling: { bookingShare: number; partnerShare: number } | null;
|
||||
}
|
||||
|
||||
export interface SignContractPayload {
|
||||
@@ -193,6 +213,13 @@ export const bookingsService = {
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
getConsolidationDetails: async (
|
||||
id: string,
|
||||
): Promise<ConsolidationDetails> => {
|
||||
const response = await client.get<ConsolidationDetails>(B.CONSOLIDATION(id));
|
||||
return unwrap(response.data) as ConsolidationDetails;
|
||||
},
|
||||
|
||||
customerSign: (id: string, payload: SignContractPayload) =>
|
||||
postBooking<BookingDetail>(B.CUSTOMER_SIGN(id), {
|
||||
...payload,
|
||||
|
||||
@@ -15,6 +15,15 @@ export interface Cargo {
|
||||
status: 'PENDING' | 'LOADED' | 'IN_TRANSIT' | 'DELIVERED' | 'UNLOADED';
|
||||
loadedAt?: string;
|
||||
unloadedAt?: string;
|
||||
receiverName?: string | null;
|
||||
deliveredAt?: string | null;
|
||||
deliveryRemarks?: string | null;
|
||||
}
|
||||
|
||||
export interface DeliverCargoPayload {
|
||||
receiverName?: string;
|
||||
pickupDate?: string;
|
||||
deliveryRemarks?: string;
|
||||
}
|
||||
|
||||
export const cargoService = {
|
||||
@@ -26,6 +35,7 @@ export const cargoService = {
|
||||
delete: (id: string) => apiClient.delete(`/cargoes/${id}`),
|
||||
load: (cargoId: string, quantity: number, weight: number, volume?: number) =>
|
||||
apiClient.post(`/cargoes/${cargoId}/load`, { quantity, weight, volume }),
|
||||
deliver: (cargoId: string) => apiClient.post(`/cargoes/${cargoId}/deliver`),
|
||||
deliver: (cargoId: string, payload?: DeliverCargoPayload) =>
|
||||
apiClient.post(`/cargoes/${cargoId}/deliver`, payload ?? {}),
|
||||
unload: (cargoId: string) => apiClient.post(`/cargoes/${cargoId}/unload`),
|
||||
};
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { api as apiClient } from '../auth/http';
|
||||
import { URL_CONSTANTS } from '@/constants/URLS';
|
||||
|
||||
export type DriverStatus = 'ACTIVE' | 'INACTIVE' | 'SUSPENDED' | 'ON_LEAVE';
|
||||
|
||||
export interface DriverListFilters {
|
||||
status?: DriverStatus;
|
||||
search?: string;
|
||||
page?: number;
|
||||
limit?: number;
|
||||
sortBy?: string;
|
||||
sortOrder?: 'ASC' | 'DESC';
|
||||
}
|
||||
|
||||
export interface Driver {
|
||||
id: string;
|
||||
licenseNumber: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
email: string;
|
||||
phoneNumber: string;
|
||||
dateOfBirth: string;
|
||||
licenseExpiryDate: string;
|
||||
status: DriverStatus;
|
||||
vehicleTypesAuthorized: string[];
|
||||
address?: string | null;
|
||||
emergencyContact?: string | null;
|
||||
notes?: string | null;
|
||||
totalTrips: number;
|
||||
rating: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export type SaveDriverPayload = Omit<
|
||||
Driver,
|
||||
'id' | 'createdAt' | 'updatedAt' | 'totalTrips' | 'rating'
|
||||
>;
|
||||
|
||||
export const driversService = {
|
||||
getAll: (filters: DriverListFilters = {}) => {
|
||||
const params = new URLSearchParams();
|
||||
if (filters.status) params.set('status', filters.status);
|
||||
if (filters.search) params.set('search', filters.search);
|
||||
if (filters.page) params.set('page', filters.page.toString());
|
||||
if (filters.limit) params.set('limit', filters.limit.toString());
|
||||
if (filters.sortBy) params.set('sortBy', filters.sortBy);
|
||||
if (filters.sortOrder) params.set('sortOrder', filters.sortOrder);
|
||||
const qs = params.toString();
|
||||
return apiClient.get<Driver[]>(
|
||||
`${URL_CONSTANTS.DRIVERS.BASE}${qs ? `?${qs}` : ''}`,
|
||||
);
|
||||
},
|
||||
getById: (id: string) => apiClient.get<Driver>(URL_CONSTANTS.DRIVERS.BY_ID(id)),
|
||||
create: (data: Partial<SaveDriverPayload>) =>
|
||||
apiClient.post(URL_CONSTANTS.DRIVERS.BASE, data),
|
||||
update: (id: string, data: Partial<SaveDriverPayload>) =>
|
||||
apiClient.patch(URL_CONSTANTS.DRIVERS.BY_ID(id), data),
|
||||
delete: (id: string) => apiClient.delete(URL_CONSTANTS.DRIVERS.BY_ID(id)),
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
import { api as apiClient } from '../auth/http';
|
||||
|
||||
import { URL_CONSTANTS } from '@/constants/URLS';
|
||||
import type { Facility } from '@/types/warehouse';
|
||||
|
||||
export const facilityService = {
|
||||
list: () => apiClient.get<Facility[]>(URL_CONSTANTS.FACILITIES.BASE),
|
||||
getById: (id: string) => apiClient.get<Facility>(URL_CONSTANTS.FACILITIES.BY_ID(id)),
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
import { api as client } from "../auth/http";
|
||||
import { URL_CONSTANTS } from "@/constants/URLS";
|
||||
|
||||
const F = URL_CONSTANTS.FILES;
|
||||
|
||||
export const filesService = {
|
||||
/** Stream a stored file by id (backend route: GET /files/:id). */
|
||||
download: async (id: string): Promise<Blob> => {
|
||||
const response = await client.get(F.BY_ID(id), { responseType: "blob" });
|
||||
return response.data as Blob;
|
||||
},
|
||||
};
|
||||
|
||||
/** Download a file blob and trigger a browser save with the given name. */
|
||||
export async function downloadBookingFile(
|
||||
id: string,
|
||||
filename: string,
|
||||
): Promise<void> {
|
||||
const blob = await filesService.download(id);
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
@@ -1,18 +1,31 @@
|
||||
import { cargoService, type Cargo } from "@/services/cargoService";
|
||||
import { containerService, type Container } from "@/services/containerService";
|
||||
import { locomotivesService, type Locomotive } from "@/services/locomotives.service";
|
||||
import {
|
||||
locomotivesService,
|
||||
type Locomotive,
|
||||
type LocomotiveListFilters,
|
||||
} from "@/services/locomotives.service";
|
||||
import { trainService, type Train } from "@/services/trains.service";
|
||||
import { wagonService, type Wagon } from "@/services/wagon.service";
|
||||
import { wagonService, type Wagon, type WagonListFilters } from "@/services/wagon.service";
|
||||
import { vehiclesService, type Vehicle, type VehicleListFilters } from "@/services/vehicles.service";
|
||||
import { driversService, type Driver, type DriverListFilters } from "@/services/drivers.service";
|
||||
import type { FleetResourceSlug } from "@/pages/fleet/config/resources";
|
||||
|
||||
export type FleetRecord = Locomotive | Train | Wagon | Container | Cargo;
|
||||
export type FleetRecord = Locomotive | Train | Wagon | Container | Cargo | Vehicle | Driver;
|
||||
|
||||
const listHandlers: Record<FleetResourceSlug, () => Promise<FleetRecord[]>> = {
|
||||
locomotives: () => locomotivesService.getAll().then((r) => r.data),
|
||||
export type FleetListFilters = WagonListFilters & LocomotiveListFilters & VehicleListFilters & DriverListFilters;
|
||||
|
||||
const listHandlers: Record<
|
||||
FleetResourceSlug,
|
||||
(filters?: FleetListFilters) => Promise<FleetRecord[]>
|
||||
> = {
|
||||
locomotives: (filters) => locomotivesService.getAll(filters ?? {}).then((r) => r.data),
|
||||
trains: () => trainService.getAll().then((r) => r.data),
|
||||
wagons: () => wagonService.getAll().then((r) => r.data),
|
||||
wagons: (filters) => wagonService.getAll(filters ?? {}).then((r) => r.data),
|
||||
containers: () => containerService.getAll().then((r) => r.data),
|
||||
cargoes: () => cargoService.getAll().then((r) => r.data),
|
||||
vehicles: (filters) => vehiclesService.getAll(filters ?? {}).then((r) => r.data),
|
||||
drivers: (filters) => driversService.getAll(filters ?? {}).then((r) => r.data),
|
||||
};
|
||||
|
||||
const createHandlers: Record<FleetResourceSlug, (data: Record<string, unknown>) => Promise<unknown>> = {
|
||||
@@ -21,6 +34,8 @@ const createHandlers: Record<FleetResourceSlug, (data: Record<string, unknown>)
|
||||
wagons: (data) => wagonService.create(data),
|
||||
containers: (data) => containerService.create(data),
|
||||
cargoes: (data) => cargoService.create(data),
|
||||
vehicles: (data) => vehiclesService.create(data),
|
||||
drivers: (data) => driversService.create(data),
|
||||
};
|
||||
|
||||
const updateHandlers: Record<
|
||||
@@ -32,6 +47,8 @@ const updateHandlers: Record<
|
||||
wagons: (id, data) => wagonService.update(id, data),
|
||||
containers: (id, data) => containerService.update(id, data),
|
||||
cargoes: (id, data) => cargoService.update(id, data),
|
||||
vehicles: (id, data) => vehiclesService.update(id, data),
|
||||
drivers: (id, data) => driversService.update(id, data),
|
||||
};
|
||||
|
||||
const removeHandlers: Record<FleetResourceSlug, (id: string) => Promise<unknown>> = {
|
||||
@@ -40,10 +57,12 @@ const removeHandlers: Record<FleetResourceSlug, (id: string) => Promise<unknown>
|
||||
wagons: (id) => wagonService.delete(id),
|
||||
containers: (id) => containerService.delete(id),
|
||||
cargoes: (id) => cargoService.delete(id),
|
||||
vehicles: (id) => vehiclesService.delete(id),
|
||||
drivers: (id) => driversService.delete(id),
|
||||
};
|
||||
|
||||
export const fleetService = {
|
||||
list: (slug: FleetResourceSlug) => listHandlers[slug](),
|
||||
list: (slug: FleetResourceSlug, filters?: FleetListFilters) => listHandlers[slug](filters),
|
||||
create: (slug: FleetResourceSlug, data: Record<string, unknown>) => createHandlers[slug](data),
|
||||
update: (slug: FleetResourceSlug, id: string, data: Record<string, unknown>) =>
|
||||
updateHandlers[slug](id, data),
|
||||
|
||||
@@ -12,12 +12,19 @@ export type LocomotiveStatus =
|
||||
| 'ASSIGNED'
|
||||
| 'OUT_OF_SERVICE';
|
||||
|
||||
export interface LocomotiveListFilters {
|
||||
status?: LocomotiveStatus;
|
||||
currentYardId?: string;
|
||||
}
|
||||
|
||||
export interface Locomotive {
|
||||
id: string;
|
||||
code: string;
|
||||
name?: string | null;
|
||||
locomotiveType: LocomotiveType;
|
||||
status: LocomotiveStatus;
|
||||
currentYardId: string | null;
|
||||
currentYard?: { id: string; label?: string; code?: string } | null;
|
||||
maxPullWeightTons: number;
|
||||
maxTrainLengthMeters: number;
|
||||
powerKw?: number | null;
|
||||
@@ -33,7 +40,15 @@ export type SaveLocomotivePayload = Omit<
|
||||
>;
|
||||
|
||||
export const locomotivesService = {
|
||||
getAll: () => apiClient.get<Locomotive[]>(URL_CONSTANTS.LOCOMOTIVES.BASE),
|
||||
getAll: (filters: LocomotiveListFilters = {}) => {
|
||||
const params = new URLSearchParams();
|
||||
if (filters.status) params.set('status', filters.status);
|
||||
if (filters.currentYardId) params.set('currentYardId', filters.currentYardId);
|
||||
const qs = params.toString();
|
||||
return apiClient.get<Locomotive[]>(
|
||||
`${URL_CONSTANTS.LOCOMOTIVES.BASE}${qs ? `?${qs}` : ''}`,
|
||||
);
|
||||
},
|
||||
getById: (id: string) => apiClient.get<Locomotive>(URL_CONSTANTS.LOCOMOTIVES.BY_ID(id)),
|
||||
create: (data: Partial<SaveLocomotivePayload>) =>
|
||||
apiClient.post(URL_CONSTANTS.LOCOMOTIVES.BASE, data),
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import { api as client } from "../auth/http";
|
||||
import { unwrap } from "@/utils/endpoint";
|
||||
import { URL_CONSTANTS } from "@/constants/URLS";
|
||||
|
||||
const P = URL_CONSTANTS.PAYMENTS;
|
||||
|
||||
export type PaymentStatus =
|
||||
| "action-required"
|
||||
| "processing"
|
||||
| "success"
|
||||
| "failed"
|
||||
| "canceled"
|
||||
| "refunded";
|
||||
|
||||
export type PaymentMethod =
|
||||
| "telebirr"
|
||||
| "cbe-birr"
|
||||
| "ebirr"
|
||||
| "waafi"
|
||||
| "card"
|
||||
| "dmoney"
|
||||
| "cac-bank";
|
||||
|
||||
export interface PaymentRow {
|
||||
id: string;
|
||||
bookingId: string;
|
||||
amount: number;
|
||||
currency: string;
|
||||
method: PaymentMethod;
|
||||
status: PaymentStatus;
|
||||
merchantOrderId: string | null;
|
||||
paidAt: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface PaymentListFilter {
|
||||
search?: string;
|
||||
status?: string;
|
||||
method?: string;
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
}
|
||||
|
||||
export interface PaginatedPayments {
|
||||
items: PaymentRow[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
export interface PaymentSummary {
|
||||
total: number;
|
||||
success: number;
|
||||
processing: number;
|
||||
failed: number;
|
||||
refunded: number;
|
||||
paidAmount: number;
|
||||
}
|
||||
|
||||
export const paymentsService = {
|
||||
list: async (filter?: PaymentListFilter): Promise<PaginatedPayments> => {
|
||||
const params: Record<string, string | number | undefined> = {};
|
||||
if (filter) {
|
||||
if (filter.search) params.search = filter.search;
|
||||
if (filter.status) params.status = filter.status;
|
||||
if (filter.method) params.method = filter.method;
|
||||
if (filter.page != null) params.page = filter.page;
|
||||
if (filter.pageSize != null) params.pageSize = filter.pageSize;
|
||||
}
|
||||
const response = await client.get<PaginatedPayments>(P.ALL, { params });
|
||||
const data = unwrap(response.data) as PaginatedPayments;
|
||||
return {
|
||||
items: data.items ?? [],
|
||||
total: data.total ?? 0,
|
||||
page: data.page ?? 1,
|
||||
pageSize: data.pageSize ?? 10,
|
||||
};
|
||||
},
|
||||
|
||||
getSummary: async (): Promise<PaymentSummary> => {
|
||||
const response = await client.get<PaymentSummary>(P.SUMMARY);
|
||||
return unwrap(response.data) as PaymentSummary;
|
||||
},
|
||||
};
|
||||
@@ -28,7 +28,7 @@ const RESOURCE_BASE: Record<RuleEngineResourceSlug, string> = {
|
||||
"cargo-types": URL_CONSTANTS.RULE_ENGINE.CARGO_TYPES,
|
||||
"container-types": URL_CONSTANTS.RULE_ENGINE.CONTAINER_TYPES,
|
||||
"wagon-types": URL_CONSTANTS.RULE_ENGINE.WAGON_TYPES,
|
||||
"priority-rules": URL_CONSTANTS.RULE_ENGINE.PRIORITY_RULES,
|
||||
"priority-configs": URL_CONSTANTS.RULE_ENGINE.PRIORITY_CONFIGS,
|
||||
"service-types": URL_CONSTANTS.RULE_ENGINE.SERVICE_TYPES,
|
||||
"surcharge-types": URL_CONSTANTS.RULE_ENGINE.SURCHARGE_TYPES,
|
||||
"weight-limit-rules": URL_CONSTANTS.RULE_ENGINE.WEIGHT_LIMIT_RULES,
|
||||
@@ -46,8 +46,8 @@ const byIdPath = (resource: RuleEngineResourceSlug, id: string): string => {
|
||||
return URL_CONSTANTS.RULE_ENGINE.CONTAINER_TYPE_BY_ID(id);
|
||||
case "wagon-types":
|
||||
return URL_CONSTANTS.RULE_ENGINE.WAGON_TYPE_BY_ID(id);
|
||||
case "priority-rules":
|
||||
return URL_CONSTANTS.RULE_ENGINE.PRIORITY_RULE_BY_ID(id);
|
||||
case "priority-configs":
|
||||
return URL_CONSTANTS.RULE_ENGINE.PRIORITY_CONFIG_BY_ID(id);
|
||||
case "service-types":
|
||||
return URL_CONSTANTS.RULE_ENGINE.SERVICE_TYPE_BY_ID(id);
|
||||
case "surcharge-types":
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { api as client } from "../auth/http";
|
||||
import { unwrap } from "@/utils/endpoint";
|
||||
|
||||
const SIGNATURE_URL = "/me/signature";
|
||||
|
||||
export interface SavedSignature {
|
||||
signerDisplayName: string;
|
||||
signatureImageUrl?: string | null;
|
||||
}
|
||||
|
||||
export interface SaveSignaturePayload {
|
||||
signerDisplayName: string;
|
||||
signatureImageBase64: string;
|
||||
}
|
||||
|
||||
export const signaturesService = {
|
||||
/** Returns the current user's reusable signature, or null if none saved. */
|
||||
getMySignature: async (): Promise<SavedSignature | null> => {
|
||||
const response = await client.get<SavedSignature | null>(SIGNATURE_URL);
|
||||
return (unwrap(response.data) as SavedSignature | null) ?? null;
|
||||
},
|
||||
|
||||
saveMySignature: async (
|
||||
payload: SaveSignaturePayload,
|
||||
): Promise<SavedSignature | null> => {
|
||||
const response = await client.put<SavedSignature | null>(
|
||||
SIGNATURE_URL,
|
||||
payload,
|
||||
);
|
||||
return (unwrap(response.data) as SavedSignature | null) ?? null;
|
||||
},
|
||||
};
|
||||
@@ -2,18 +2,27 @@ import { api as client } from '../auth/http';
|
||||
import { unwrap } from '@/utils/endpoint';
|
||||
import { URL_CONSTANTS } from '@/constants/URLS';
|
||||
import type {
|
||||
BatchBoardSchedule,
|
||||
BatchBoardScheduleDetail,
|
||||
BookableSchedule,
|
||||
AssignBookingsPayload,
|
||||
CompositionRemovalEntry,
|
||||
CompositionUnassignedBooking,
|
||||
UnassignedBookingsResponse,
|
||||
CreateTrainSchedulePayload,
|
||||
EligibleContainerBookingsResponse,
|
||||
FreightType,
|
||||
LocomotiveRecord,
|
||||
PinWagonsPayload,
|
||||
RecordCheckpointPayload,
|
||||
TrainScheduleDetail,
|
||||
TrainScheduleFilters,
|
||||
TrainScheduleListItem,
|
||||
TrainSchedulePreviewPayload,
|
||||
TrainSchedulePreviewResponse,
|
||||
TrainSchedulingGlobalRules,
|
||||
TrainTrackResponse,
|
||||
WagonAllocationAttemptResult,
|
||||
YardOption,
|
||||
} from '@/types/trainScheduling';
|
||||
|
||||
@@ -75,6 +84,75 @@ export const trainSchedulingService = {
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
getBatchBoard: async (): Promise<BatchBoardSchedule[]> => {
|
||||
const response = await client.get<BatchBoardSchedule[]>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.BATCH_BOARD,
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
getBatchBoardDetail: async (scheduleId: string): Promise<BatchBoardScheduleDetail> => {
|
||||
const response = await client.get<BatchBoardScheduleDetail>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.BATCH_BOARD_DETAIL(scheduleId),
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
getBookableSchedules: async (
|
||||
originYardId?: string,
|
||||
destinationYardId?: string,
|
||||
): Promise<BookableSchedule[]> => {
|
||||
const response = await client.get<BookableSchedule[]>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.BOOKABLE_SCHEDULES,
|
||||
{ params: { originYardId, destinationYardId } },
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
runBatch: async (scheduleId: string): Promise<BatchBoardScheduleDetail> => {
|
||||
const response = await client.post<BatchBoardScheduleDetail>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.RUN_BATCH(scheduleId),
|
||||
{},
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
runAllocation: async (scheduleId: string): Promise<WagonAllocationAttemptResult> => {
|
||||
const response = await client.post<WagonAllocationAttemptResult>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.RUN_ALLOCATION(scheduleId),
|
||||
{},
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
setBookingWindow: async (
|
||||
scheduleId: string,
|
||||
status: "OPEN" | "CLOSED",
|
||||
): Promise<TrainScheduleDetail> => {
|
||||
const response = await client.patch<TrainScheduleDetail>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.BOOKING_WINDOW(scheduleId),
|
||||
{ status },
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
markBookingPaid: async (bookingId: string): Promise<void> => {
|
||||
await client.post(URL_CONSTANTS.TRAIN_SCHEDULING.MARK_BOOKING_PAID(bookingId), {});
|
||||
},
|
||||
|
||||
expireBooking: async (bookingId: string): Promise<void> => {
|
||||
await client.post(URL_CONSTANTS.TRAIN_SCHEDULING.EXPIRE_BOOKING(bookingId), {});
|
||||
},
|
||||
|
||||
moveBookingSchedule: async (
|
||||
bookingId: string,
|
||||
trainScheduleId: string,
|
||||
): Promise<void> => {
|
||||
await client.post(URL_CONSTANTS.TRAIN_SCHEDULING.MOVE_BOOKING_SCHEDULE(bookingId), {
|
||||
trainScheduleId,
|
||||
});
|
||||
},
|
||||
|
||||
getScheduleById: async (
|
||||
id: string,
|
||||
freightType?: FreightType,
|
||||
@@ -85,6 +163,17 @@ export const trainSchedulingService = {
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
assignUnassignedBooking: async (
|
||||
scheduleId: string,
|
||||
bookingId: string,
|
||||
): Promise<TrainScheduleDetail> => {
|
||||
const response = await client.post<TrainScheduleDetail>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.ASSIGN_UNASSIGNED_BOOKING(scheduleId),
|
||||
{ bookingId },
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
assignBookings: async (
|
||||
scheduleId: string,
|
||||
payload: AssignBookingsPayload,
|
||||
@@ -137,6 +226,32 @@ export const trainSchedulingService = {
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
getTrack: async (scheduleId: string): Promise<TrainTrackResponse> => {
|
||||
const response = await client.get<TrainTrackResponse>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.CHECKPOINTS(scheduleId),
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
recordCheckpoint: async (
|
||||
scheduleId: string,
|
||||
payload: RecordCheckpointPayload,
|
||||
): Promise<TrainTrackResponse> => {
|
||||
const response = await client.post<TrainTrackResponse>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.CHECKPOINTS(scheduleId),
|
||||
payload,
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
arriveSchedule: async (scheduleId: string): Promise<TrainScheduleDetail> => {
|
||||
const response = await client.post<TrainScheduleDetail>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.ARRIVE(scheduleId),
|
||||
{},
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
cancelSchedule: async (
|
||||
id: string,
|
||||
freightType: FreightType = "CONTAINER",
|
||||
@@ -148,15 +263,14 @@ export const trainSchedulingService = {
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
publishSchedule: async (id: string): Promise<TrainScheduleDetail> => {
|
||||
const response = await client.post<TrainScheduleDetail>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.PUBLISH_SCHEDULE(id),
|
||||
{},
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
getAvailableLocomotives: async (): Promise<LocomotiveRecord[]> => {
|
||||
getAvailableLocomotives: async (routeId?: string): Promise<LocomotiveRecord[]> => {
|
||||
if (routeId) {
|
||||
const response = await client.get<LocomotiveRecord[]>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.AVAILABLE_LOCOMOTIVES,
|
||||
{ params: { routeId } },
|
||||
);
|
||||
return unwrap(response.data);
|
||||
}
|
||||
const response = await client.get<LocomotiveRecord[]>(URL_CONSTANTS.LOCOMOTIVES.BASE, {
|
||||
params: { status: 'AVAILABLE' },
|
||||
});
|
||||
@@ -250,4 +364,41 @@ export const trainSchedulingService = {
|
||||
country: yard.country,
|
||||
}));
|
||||
},
|
||||
|
||||
removeWagonSlot: async (scheduleId: string, wagonId: string): Promise<TrainScheduleDetail> => {
|
||||
const response = await client.delete<TrainScheduleDetail>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.REMOVE_WAGON_SLOT(scheduleId, wagonId),
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
updateContainerItem: async (
|
||||
scheduleId: string,
|
||||
itemId: string,
|
||||
payload: { containerNumber: string | null },
|
||||
): Promise<{ id: string; containerNumber: string | null }> => {
|
||||
const response = await client.patch<{ id: string; containerNumber: string | null }>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.UPDATE_CONTAINER_ITEM(scheduleId, itemId),
|
||||
payload,
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
getUnassignedBookings: async (
|
||||
scheduleId: string,
|
||||
): Promise<UnassignedBookingsResponse> => {
|
||||
const response = await client.get<UnassignedBookingsResponse>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.UNASSIGNED_BOOKINGS(scheduleId),
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
|
||||
getCompositionRemovals: async (
|
||||
scheduleId: string,
|
||||
): Promise<CompositionRemovalEntry[]> => {
|
||||
const response = await client.get<CompositionRemovalEntry[]>(
|
||||
URL_CONSTANTS.TRAIN_SCHEDULING.COMPOSITION_REMOVALS(scheduleId),
|
||||
);
|
||||
return unwrap(response.data);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import { api as apiClient } from '../auth/http';
|
||||
import { URL_CONSTANTS } from '@/constants/URLS';
|
||||
|
||||
export type VehicleType = 'TRUCK' | 'VAN' | 'CAR' | 'BUS' | 'TRAILER' | 'TANKER' | 'FLATBED';
|
||||
export type FuelType = 'PETROL' | 'DIESEL' | 'ELECTRIC' | 'HYBRID';
|
||||
export type VehicleStatus = 'ACTIVE' | 'MAINTENANCE' | 'RETIRED' | 'OUT_OF_SERVICE';
|
||||
|
||||
export interface VehicleListFilters {
|
||||
status?: VehicleStatus;
|
||||
search?: string;
|
||||
page?: number;
|
||||
limit?: number;
|
||||
sortBy?: string;
|
||||
sortOrder?: 'ASC' | 'DESC';
|
||||
}
|
||||
|
||||
export interface Vehicle {
|
||||
id: string;
|
||||
plateNumber: string;
|
||||
registrationNumber: string;
|
||||
vehicleType: VehicleType;
|
||||
manufacturer: string;
|
||||
model: string;
|
||||
year: number;
|
||||
fuelType: FuelType;
|
||||
capacity: number;
|
||||
status: VehicleStatus;
|
||||
description?: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export type SaveVehiclePayload = Omit<
|
||||
Vehicle,
|
||||
'id' | 'createdAt' | 'updatedAt' | 'registrationNumber'
|
||||
>;
|
||||
|
||||
export const vehiclesService = {
|
||||
getAll: (filters: VehicleListFilters = {}) => {
|
||||
const params = new URLSearchParams();
|
||||
if (filters.status) params.set('status', filters.status);
|
||||
if (filters.search) params.set('search', filters.search);
|
||||
if (filters.page) params.set('page', filters.page.toString());
|
||||
if (filters.limit) params.set('limit', filters.limit.toString());
|
||||
if (filters.sortBy) params.set('sortBy', filters.sortBy);
|
||||
if (filters.sortOrder) params.set('sortOrder', filters.sortOrder);
|
||||
const qs = params.toString();
|
||||
return apiClient.get<Vehicle[]>(
|
||||
`${URL_CONSTANTS.VEHICLES.BASE}${qs ? `?${qs}` : ''}`,
|
||||
);
|
||||
},
|
||||
getById: (id: string) => apiClient.get<Vehicle>(URL_CONSTANTS.VEHICLES.BY_ID(id)),
|
||||
create: (data: Partial<SaveVehiclePayload>) =>
|
||||
apiClient.post(URL_CONSTANTS.VEHICLES.BASE, data),
|
||||
update: (id: string, data: Partial<SaveVehiclePayload>) =>
|
||||
apiClient.patch(URL_CONSTANTS.VEHICLES.BY_ID(id), data),
|
||||
delete: (id: string) => apiClient.delete(URL_CONSTANTS.VEHICLES.BY_ID(id)),
|
||||
};
|
||||
@@ -24,12 +24,30 @@ export interface Wagon {
|
||||
tareWeight: number;
|
||||
maxPayloadWeight: number;
|
||||
status: Freight.WagonStatus;
|
||||
readiness: Freight.WagonReadiness;
|
||||
currentYardId: string | null;
|
||||
currentYard?: { id: string; label?: string; code?: string } | null;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface WagonListFilters {
|
||||
search?: string;
|
||||
status?: Freight.WagonStatus;
|
||||
currentYardId?: string;
|
||||
wagonTypeId?: string;
|
||||
trainId?: string;
|
||||
}
|
||||
|
||||
export const wagonService = {
|
||||
getAll: () => apiClient.get<Wagon[]>('/wagons'),
|
||||
getAll: (filters: WagonListFilters = {}) => {
|
||||
const params = new URLSearchParams();
|
||||
if (filters.search?.trim()) params.set('search', filters.search.trim());
|
||||
if (filters.status) params.set('status', filters.status);
|
||||
if (filters.currentYardId) params.set('currentYardId', filters.currentYardId);
|
||||
if (filters.wagonTypeId) params.set('wagonTypeId', filters.wagonTypeId);
|
||||
if (filters.trainId) params.set('trainId', filters.trainId);
|
||||
const qs = params.toString();
|
||||
return apiClient.get<Wagon[]>(`/wagons${qs ? `?${qs}` : ''}`);
|
||||
},
|
||||
getById: (id: string) => apiClient.get<Wagon>(`/wagons/${id}`),
|
||||
getByTrain: (trainId: string) => apiClient.get<Wagon[]>(`/wagons?trainId=${trainId}`),
|
||||
assignToTrain: (wagonId: string, trainId: string, sequenceNumber?: number) =>
|
||||
|
||||
@@ -2,20 +2,43 @@ 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,
|
||||
ReleaseOrderPayload,
|
||||
DeliverInventoryPayload,
|
||||
ReserveInventoryPayload,
|
||||
SaveWarehousePayload,
|
||||
SaveYardPayload,
|
||||
SaveZonePayload,
|
||||
Warehouse,
|
||||
WarehouseDashboardSummary,
|
||||
WarehouseFacility,
|
||||
WarehouseActivityLog,
|
||||
WarehouseDashboard,
|
||||
WarehouseFilter,
|
||||
WarehouseInventoryItem,
|
||||
WarehouseLoading,
|
||||
WarehouseYard,
|
||||
WarehouseZone,
|
||||
} from '@/types/warehouse';
|
||||
@@ -31,6 +54,7 @@ export const warehouseService = {
|
||||
apiClient.get<Warehouse[]>(URL_CONSTANTS.WAREHOUSES.BASE, {
|
||||
params: cleanParams(filter ?? {}),
|
||||
}),
|
||||
dashboard: () => 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),
|
||||
@@ -63,24 +87,6 @@ export const warehouseService = {
|
||||
}),
|
||||
receiveInventory: (payload: ReceiveInventoryPayload) =>
|
||||
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RECEIVE, payload),
|
||||
getDashboardSummary: (filter?: InventoryFilter) =>
|
||||
apiClient.get<WarehouseDashboardSummary>(URL_CONSTANTS.WAREHOUSE_INVENTORY.DASHBOARD_SUMMARY, {
|
||||
params: cleanParams(filter ?? {}),
|
||||
}),
|
||||
storeInventory: (id: string) =>
|
||||
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.STORE(id)),
|
||||
reserveInventory: (id: string, payload: ReserveInventoryPayload) =>
|
||||
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RESERVE(id), payload),
|
||||
inspectInventory: (id: string) =>
|
||||
apiClient.patch<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.INSPECT(id)),
|
||||
markReadyForLoading: (id: string) =>
|
||||
apiClient.patch<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.MARK_READY(id)),
|
||||
loadInventory: (id: string) =>
|
||||
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.LOAD(id)),
|
||||
dispatchInventory: (id: string) =>
|
||||
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.DISPATCH(id)),
|
||||
moveInventory: (id: string, payload: MoveInventoryPayload) =>
|
||||
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.MOVE(id), payload),
|
||||
listReadyForLoading: (filter?: InventoryFilter) =>
|
||||
apiClient.get<WarehouseInventoryItem[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.READY_FOR_LOADING, {
|
||||
params: cleanParams(filter ?? {}),
|
||||
@@ -89,4 +95,116 @@ export const warehouseService = {
|
||||
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),
|
||||
deliver: (id: string, payload: DeliverInventoryPayload) =>
|
||||
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.DELIVER(id), payload),
|
||||
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) =>
|
||||
apiClient.get<FeePreview[]>(URL_CONSTANTS.WAREHOUSE_RULES.FEE_PREVIEW(inventoryId)),
|
||||
|
||||
// ── 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)),
|
||||
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) =>
|
||||
apiClient.post<WarehouseFeeInvoice>(URL_CONSTANTS.WAREHOUSE_INVOICES.GENERATE(inventoryId), { confirmZero }),
|
||||
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),
|
||||
gateClearance: (inventoryId: string) =>
|
||||
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVOICES.GATE_CLEARANCE(inventoryId), {}),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user