mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 07:10:57 +00:00
refactor pricing data seeder to fold surcharge types into rates update route meta subtitle to remove surcharge types enhance RuleEngineFormDialog to support conditional field visibility remove surcharge types from URL constants and related services add cargo leaf options query for bulk cargo type selection update RuleEngineResourcePage to utilize cargo leaf options modify resources configuration to remove surcharge types implement migration to fold surcharge types into rates create utility to derive legacy rate types from new rate structure
204 lines
6.5 KiB
TypeScript
204 lines
6.5 KiB
TypeScript
import { api as client } from "@/auth/http";
|
|
import { URL_CONSTANTS } from "@/constants/URLS";
|
|
import type {
|
|
RuleEngineListMeta,
|
|
RuleEngineListResult,
|
|
RuleEngineRecord,
|
|
RuleEngineResourceSlug,
|
|
} from "@/types/rule-engine";
|
|
import { unwrap } from "@/utils/endpoint";
|
|
|
|
export interface RuleEngineListParams {
|
|
search?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
isActive?: boolean;
|
|
status?: string;
|
|
sortBy?: string;
|
|
sortOrder?: "ASC" | "DESC";
|
|
requiresDirectorApproval?: boolean;
|
|
}
|
|
|
|
export interface RuleEngineReorderPayload {
|
|
ids: string[];
|
|
requiresDirectorApproval?: boolean;
|
|
}
|
|
|
|
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-configs": URL_CONSTANTS.RULE_ENGINE.PRIORITY_CONFIGS,
|
|
"service-types": URL_CONSTANTS.RULE_ENGINE.SERVICE_TYPES,
|
|
"weight-limit-rules": URL_CONSTANTS.RULE_ENGINE.WEIGHT_LIMIT_RULES,
|
|
yards: URL_CONSTANTS.RULE_ENGINE.YARDS,
|
|
"shipping-lines": URL_CONSTANTS.RULE_ENGINE.SHIPPING_LINES,
|
|
rates: URL_CONSTANTS.RULE_ENGINE.RATES,
|
|
"approval-rules": URL_CONSTANTS.RULE_ENGINE.APPROVAL_RULES,
|
|
};
|
|
|
|
const byIdPath = (resource: RuleEngineResourceSlug, id: string): string => {
|
|
switch (resource) {
|
|
case "cargo-types":
|
|
return URL_CONSTANTS.RULE_ENGINE.CARGO_TYPE_BY_ID(id);
|
|
case "container-types":
|
|
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-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 "weight-limit-rules":
|
|
return URL_CONSTANTS.RULE_ENGINE.WEIGHT_LIMIT_RULE_BY_ID(id);
|
|
case "yards":
|
|
return URL_CONSTANTS.RULE_ENGINE.YARD_BY_ID(id);
|
|
case "shipping-lines":
|
|
return URL_CONSTANTS.RULE_ENGINE.SHIPPING_LINE_BY_ID(id);
|
|
case "rates":
|
|
return URL_CONSTANTS.RULE_ENGINE.RATE_BY_ID(id);
|
|
case "approval-rules":
|
|
return URL_CONSTANTS.RULE_ENGINE.APPROVAL_RULE_BY_ID(id);
|
|
default:
|
|
return `${RESOURCE_BASE[resource]}/${id}`;
|
|
}
|
|
};
|
|
|
|
const defaultMeta = (dataLength: number, page = 1, pageSize = 10): RuleEngineListMeta => ({
|
|
total: dataLength,
|
|
page,
|
|
pageSize,
|
|
totalPages: Math.max(1, Math.ceil(dataLength / pageSize)),
|
|
});
|
|
|
|
const isPaginatedListResult = <T extends RuleEngineRecord>(
|
|
value: unknown,
|
|
): value is RuleEngineListResult<T> =>
|
|
Boolean(value) &&
|
|
typeof value === "object" &&
|
|
"data" in value &&
|
|
Array.isArray((value as RuleEngineListResult<T>).data);
|
|
|
|
const normalizeList = <T extends RuleEngineRecord>(
|
|
payload: unknown,
|
|
page = 1,
|
|
pageSize = 10,
|
|
): RuleEngineListResult<T> => {
|
|
if (isPaginatedListResult<T>(payload)) {
|
|
return {
|
|
data: payload.data,
|
|
meta: payload.meta ?? defaultMeta(payload.data.length, page, pageSize),
|
|
};
|
|
}
|
|
|
|
const body = unwrap(payload as { data: unknown }) as unknown;
|
|
|
|
if (isPaginatedListResult<T>(body)) {
|
|
return {
|
|
data: body.data,
|
|
meta: body.meta ?? defaultMeta(body.data.length, page, pageSize),
|
|
};
|
|
}
|
|
|
|
if (Array.isArray(body)) {
|
|
return { data: body as T[], meta: defaultMeta(body.length, page, pageSize) };
|
|
}
|
|
|
|
return { data: [], meta: defaultMeta(0, page, pageSize) };
|
|
};
|
|
|
|
const normalizeEntity = <T extends RuleEngineRecord>(payload: unknown): T => {
|
|
return unwrap(payload as { data: T }) as T;
|
|
};
|
|
|
|
export const ruleEngineService = {
|
|
list: async <T extends RuleEngineRecord>(
|
|
resource: RuleEngineResourceSlug,
|
|
params?: RuleEngineListParams,
|
|
): Promise<RuleEngineListResult<T>> => {
|
|
const page = params?.page ?? 1;
|
|
const pageSize = params?.pageSize ?? 10;
|
|
const response = await client.get(RESOURCE_BASE[resource], {
|
|
params: {
|
|
page,
|
|
pageSize,
|
|
search: params?.search,
|
|
isActive: params?.isActive,
|
|
status: params?.status,
|
|
sortBy: params?.sortBy,
|
|
sortOrder: params?.sortOrder,
|
|
requiresDirectorApproval: params?.requiresDirectorApproval,
|
|
},
|
|
});
|
|
return normalizeList<T>(response.data, page, pageSize);
|
|
},
|
|
|
|
getById: async <T extends RuleEngineRecord>(
|
|
resource: RuleEngineResourceSlug,
|
|
id: string,
|
|
): Promise<T> => {
|
|
const response = await client.get(byIdPath(resource, id));
|
|
return normalizeEntity<T>(response.data);
|
|
},
|
|
|
|
create: async <T extends RuleEngineRecord>(
|
|
resource: RuleEngineResourceSlug,
|
|
payload: Record<string, unknown>,
|
|
): Promise<T> => {
|
|
const response = await client.post(RESOURCE_BASE[resource], payload);
|
|
return normalizeEntity<T>(response.data);
|
|
},
|
|
|
|
update: async <T extends RuleEngineRecord>(
|
|
resource: RuleEngineResourceSlug,
|
|
id: string,
|
|
payload: Record<string, unknown>,
|
|
): Promise<T> => {
|
|
const response = await client.patch(byIdPath(resource, id), payload);
|
|
return normalizeEntity<T>(response.data);
|
|
},
|
|
|
|
remove: async (resource: RuleEngineResourceSlug, id: string): Promise<void> => {
|
|
await client.delete(byIdPath(resource, id));
|
|
},
|
|
|
|
reorder: async (
|
|
resource: RuleEngineResourceSlug,
|
|
payload: RuleEngineReorderPayload,
|
|
): Promise<void> => {
|
|
await client.post(`${RESOURCE_BASE[resource]}/reorder`, payload);
|
|
},
|
|
|
|
moveOrder: async (
|
|
resource: RuleEngineResourceSlug,
|
|
id: string,
|
|
direction: "up" | "down",
|
|
): Promise<void> => {
|
|
await client.post(`${byIdPath(resource, id)}/move-order`, { direction });
|
|
},
|
|
|
|
submitRate: async <T extends RuleEngineRecord>(id: string): Promise<T> => {
|
|
const response = await client.post(URL_CONSTANTS.RULE_ENGINE.RATE_SUBMIT(id));
|
|
return normalizeEntity<T>(response.data);
|
|
},
|
|
|
|
approveRate: async <T extends RuleEngineRecord>(id: string): Promise<T> => {
|
|
const response = await client.post(URL_CONSTANTS.RULE_ENGINE.RATE_APPROVE(id));
|
|
return normalizeEntity<T>(response.data);
|
|
},
|
|
|
|
getApprovalChain: async (
|
|
requiresDirectorApproval = true,
|
|
): Promise<RuleEngineRecord[]> => {
|
|
const response = await client.get(URL_CONSTANTS.RULE_ENGINE.APPROVAL_RULES_CHAIN, {
|
|
params: { requiresDirectorApproval },
|
|
});
|
|
const body = unwrap(response.data) as unknown;
|
|
if (Array.isArray(body)) return body as RuleEngineRecord[];
|
|
if (body && typeof body === "object" && "data" in body && Array.isArray((body as { data: unknown }).data)) {
|
|
return (body as { data: RuleEngineRecord[] }).data;
|
|
}
|
|
return [];
|
|
},
|
|
};
|