Files
edr-platform/apps/edr-freight-web/backoffice/src/services/routes.service.ts
Marshal 4b7f6d2548 enhance contract and booking services with server-side search and validation improvements
- Added  parameter to  and  for server-side free-text search on contract reference, company name, and booking details.
- Introduced new validation errors in  for container clashes and space issues when creating bookings.
- Implemented paginated dropdown settings retrieval in .
- Updated  to fetch active yards using a new method that handles pagination.
- Enhanced  with a  method to fetch all records by walking through pages.
- Refactored  to support filtering and pagination in schedule listings.
- Improved  to return a paginated list of facilities.
- Updated UI components in  and  to utilize debounced search inputs for better performance.
- Added alerts in  to inform users about booking constraints related to splits and capacity.
- Enhanced  to display notifications for split bookings and capacity usage.
2026-07-12 10:51:31 +00:00

94 lines
3.2 KiB
TypeScript

import { api as apiClient } from '../auth/http';
import { URL_CONSTANTS } from '@/constants/URLS';
import { ruleEngineService } from './ruleEngine/ruleEngine.service';
export type RouteStatus = 'AVAILABLE' | 'MAINTENANCE' | 'DAMAGED' | 'STOP_WORKING';
/** Frozen from yard countries: ET→DJ EXPORT, DJ→ET IMPORT, same country DOMESTIC (intercity, disabled). */
export type RouteDirection = 'IMPORT' | 'EXPORT' | 'DOMESTIC';
export interface YardRef {
id: string;
code: string;
label: string;
country?: string;
}
export interface RouteMilestone {
id: string;
routeId: string;
yardId: string;
sequenceNo: number;
distanceKm?: number | null;
yard?: YardRef | null;
}
export interface RouteRecord {
id: string;
status: RouteStatus;
direction?: RouteDirection;
originYardId: string;
destinationYardId: string;
originYard?: YardRef | null;
destinationYard?: YardRef | null;
milestones?: RouteMilestone[];
}
export interface SaveRoutePayload {
milestones: Array<{ yardId: string; distanceKm?: number }>;
status?: RouteStatus;
}
/**
* Human-readable route label: yard names, not yard codes. Staff read
* "Addis Ababa → Dire Dawa", not "ADDIS_ABABA → DIRE_DAWA". Falls back to the
* code only when a yard has no label.
*
* When milestones are present they ARE the full ordered corridor (origin first,
* destination last), so the label shows every stop:
* "Addis Ababa → Adama → Dire Dawa".
*/
export function formatRouteLabel(route: RouteRecord): string {
const stops = [...(route.milestones ?? [])]
.sort((a, b) => a.sequenceNo - b.sequenceNo)
.map((m) => m.yard?.label ?? m.yard?.code)
.filter((name): name is string => Boolean(name));
if (stops.length >= 2) return stops.join(' → ');
const origin =
route.originYard?.label ?? route.originYard?.code ?? 'Origin';
const dest =
route.destinationYard?.label ?? route.destinationYard?.code ?? 'Destination';
return `${origin}${dest}`;
}
export function totalRouteDistanceKm(route: RouteRecord): number {
return (route.milestones ?? []).reduce(
(sum, m) => sum + Number(m.distanceKm ?? 0),
0,
);
}
export const ROUTE_STATUS_OPTIONS: Array<{ value: RouteStatus; label: string }> = [
{ value: 'AVAILABLE', label: 'Available' },
{ value: 'MAINTENANCE', label: 'Maintenance' },
{ value: 'DAMAGED', label: 'Damaged' },
{ value: 'STOP_WORKING', label: 'Stop working' },
];
export const routesService = {
getAll: (params?: { status?: RouteStatus; search?: string }) =>
apiClient.get<RouteRecord[]>(URL_CONSTANTS.ROUTES.BASE, { params }),
getById: (id: string) => apiClient.get<RouteRecord>(URL_CONSTANTS.ROUTES.BY_ID(id)),
create: (data: SaveRoutePayload) => apiClient.post(URL_CONSTANTS.ROUTES.BASE, data),
update: (id: string, data: Partial<SaveRoutePayload>) =>
apiClient.patch(URL_CONSTANTS.ROUTES.BY_ID(id), data),
deactivate: (id: string) => apiClient.delete(URL_CONSTANTS.ROUTES.BY_ID(id)),
/** All active yards (page-walked — the yards list API caps pageSize at 100). */
getYards: async (): Promise<YardRef[]> => {
const rows = await ruleEngineService.listAll("yards", { isActive: true });
return rows as unknown as YardRef[];
},
};