mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 15:18:11 +00:00
Approval now snapshots the rate estimate and generates a last-mile contract instead of invoicing immediately. The customer picks a delivery date on the confirm form, then reviews and signs the contract in the portal (saved signature or drawn); the signed PDF is stored as LM_<CustomerName>.pdf and only then is the advance invoice issued. Backoffice shows signature status and the contract download.
67 lines
2.3 KiB
TypeScript
67 lines
2.3 KiB
TypeScript
import { api } from '../auth/http';
|
|
import { URL_CONSTANTS } from '@/constants/URLS';
|
|
|
|
export const LAST_MILE_REQUEST_STATUSES = [
|
|
'AWAITING_CONFIRMATION',
|
|
'SUBMITTED',
|
|
'APPROVED',
|
|
'REJECTED',
|
|
] as const;
|
|
export type LastMileRequestStatus = (typeof LAST_MILE_REQUEST_STATUSES)[number];
|
|
|
|
export interface LastMileRequest {
|
|
id: string;
|
|
bookingId: string;
|
|
booking?: {
|
|
id: string;
|
|
reference?: string;
|
|
companyId?: string;
|
|
company?: { id: string; name?: string } | null;
|
|
} | null;
|
|
trainScheduleId: string;
|
|
status: LastMileRequestStatus;
|
|
requestedContainerNumbers?: string[] | null;
|
|
reminderSentAt?: string | null;
|
|
submittedByUserId?: string | null;
|
|
submittedAt?: string | null;
|
|
reviewedByStaffId?: string | null;
|
|
reviewedAt?: string | null;
|
|
rejectionReason?: string | null;
|
|
resultingLastMileId?: string | null;
|
|
requestedDeliveryDate?: string | null;
|
|
customerSignedAt?: string | null;
|
|
signerDisplayName?: string | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface LastMileRequestListResponse {
|
|
data: LastMileRequest[];
|
|
meta: { total: number; page: number; pageSize: number; totalPages: number };
|
|
}
|
|
|
|
/** Rule-based estimate for the approve dialog — all nulls when no rule covers the job. */
|
|
export interface LastMilePriceEstimate {
|
|
estimatedKm: number | null;
|
|
mode: 'BULK' | 'CONTAINER' | null;
|
|
currency: string | null;
|
|
total: number | null;
|
|
lines: Array<{ description: string; amount: number }>;
|
|
}
|
|
|
|
const LMR = URL_CONSTANTS.LAST_MILE_REQUESTS;
|
|
|
|
export const lastMileRequestsService = {
|
|
list: (params?: { status?: LastMileRequestStatus; bookingId?: string; page?: number; pageSize?: number }) =>
|
|
api.get<LastMileRequestListResponse>(LMR.BASE, { params }),
|
|
getById: (id: string) => api.get<LastMileRequest>(LMR.BY_ID(id)),
|
|
freeTruckCount: () => api.get<{ count: number }>(LMR.FREE_TRUCK_COUNT),
|
|
priceEstimate: (id: string) => api.get<LastMilePriceEstimate>(LMR.PRICE_ESTIMATE(id)),
|
|
approve: (id: string, advanceAmount: number) =>
|
|
api.post<LastMileRequest>(LMR.APPROVE(id), { advanceAmount }),
|
|
reject: (id: string, reason: string) =>
|
|
api.post<LastMileRequest>(LMR.REJECT(id), { reason }),
|
|
contractDocument: (id: string) =>
|
|
api.get<Blob>(LMR.CONTRACT_DOCUMENT(id), { responseType: 'blob' }),
|
|
};
|