mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 00:38:11 +00:00
changes
This commit is contained in:
@@ -202,6 +202,7 @@ import {
|
||||
type WagonMovementRecord,
|
||||
type WagonTransferRequest,
|
||||
type CreateTransferRequestPayload,
|
||||
type BulkFulfillResult,
|
||||
type TransferHistory,
|
||||
} from "./wagon.service";
|
||||
import { warehouseService } from "./warehouse.service";
|
||||
@@ -1721,6 +1722,15 @@ export const api = {
|
||||
() => [["wagonTransferRequests"], ["wagons"]],
|
||||
),
|
||||
|
||||
bulkFulfill: endpoint<{ requestIds: string[] }, BulkFulfillResult>(
|
||||
"wagonTransferRequests",
|
||||
"bulkFulfill",
|
||||
({ requestIds }) =>
|
||||
wagonTransferRequestService.bulkFulfill(requestIds).then((r) => r.data),
|
||||
undefined,
|
||||
() => [["wagonTransferRequests"], ["wagons"]],
|
||||
),
|
||||
|
||||
cancel: endpoint<{ id: string }, WagonTransferRequest>(
|
||||
"wagonTransferRequests",
|
||||
"cancel",
|
||||
|
||||
@@ -170,8 +170,35 @@ export const contractsService = {
|
||||
},
|
||||
|
||||
// ── Staff review ──
|
||||
staffAccept: (id: string, validityDays: number) =>
|
||||
postContract<Freight.IContract>(C.STAFF_ACCEPT(id), { validityDays }),
|
||||
staffAccept: (
|
||||
id: string,
|
||||
validityDays: number,
|
||||
documentSnapshot?: Freight.IContractDocumentSnapshot,
|
||||
) =>
|
||||
postContract<Freight.IContract>(C.STAFF_ACCEPT(id), {
|
||||
validityDays,
|
||||
documentSnapshot,
|
||||
}),
|
||||
|
||||
/** The editable per-contract document draft (snapshot or live template). */
|
||||
getContractDocumentDraft: async (
|
||||
id: string,
|
||||
): Promise<Freight.IContractDocumentDraft> => {
|
||||
const response = await client.get(C.CONTRACT_DOCUMENT_DRAFT(id));
|
||||
return unwrap(response.data) as Freight.IContractDocumentDraft;
|
||||
},
|
||||
|
||||
/** Save this contract's edited document articles (never touches the templates). */
|
||||
updateContractDocument: async (
|
||||
id: string,
|
||||
snapshot: Freight.IContractDocumentSnapshot,
|
||||
): Promise<Freight.IContract> => {
|
||||
const response = await client.put(
|
||||
C.CONTRACT_DOCUMENT_ARTICLES(id),
|
||||
snapshot,
|
||||
);
|
||||
return unwrap(response.data) as Freight.IContract;
|
||||
},
|
||||
|
||||
requestChanges: (id: string, note: string) =>
|
||||
postContract<Freight.IContract>(C.STAFF_REQUEST_CHANGES(id), { note }),
|
||||
|
||||
@@ -24,6 +24,30 @@ export interface RuleEngineReorderPayload {
|
||||
requiresDirectorApproval?: boolean;
|
||||
}
|
||||
|
||||
/** Priority-rule approval workflow (all priority-config changes go through it). */
|
||||
const PRIORITY_RULE_CHANGES_BASE = "/priority-rule-change-requests";
|
||||
|
||||
export interface PriorityRuleChangeRequest {
|
||||
id: string;
|
||||
action: "CREATE" | "UPDATE" | "DELETE";
|
||||
priorityConfigId: string | null;
|
||||
priorityConfig?: RuleEngineRecord | null;
|
||||
payload: Record<string, unknown> | null;
|
||||
status: "PENDING" | "APPROVED" | "REJECTED";
|
||||
requestedByUserId: string | null;
|
||||
decidedByUserId: string | null;
|
||||
decidedAt: string | null;
|
||||
decisionNote: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface SubmitPriorityRuleChangePayload {
|
||||
action: "CREATE" | "UPDATE" | "DELETE";
|
||||
priorityConfigId?: string;
|
||||
create?: Record<string, unknown>;
|
||||
update?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
const RESOURCE_BASE: Record<RuleEngineResourceSlug, string> = {
|
||||
"cargo-types": URL_CONSTANTS.RULE_ENGINE.CARGO_TYPES,
|
||||
"container-types": URL_CONSTANTS.RULE_ENGINE.CONTAINER_TYPES,
|
||||
@@ -242,6 +266,46 @@ export const ruleEngineService = {
|
||||
return normalizeEntity<T>(response.data);
|
||||
},
|
||||
|
||||
/** File a priority-rule change (create/update/delete) for approval. */
|
||||
submitPriorityRuleChange: async (
|
||||
payload: SubmitPriorityRuleChangePayload,
|
||||
): Promise<PriorityRuleChangeRequest> => {
|
||||
const response = await client.post(PRIORITY_RULE_CHANGES_BASE, payload);
|
||||
return unwrap(response.data) as PriorityRuleChangeRequest;
|
||||
},
|
||||
|
||||
listPriorityRuleChanges: async (
|
||||
status?: PriorityRuleChangeRequest["status"],
|
||||
): Promise<PriorityRuleChangeRequest[]> => {
|
||||
const response = await client.get(PRIORITY_RULE_CHANGES_BASE, {
|
||||
params: status ? { status } : undefined,
|
||||
});
|
||||
const body = unwrap(response.data) as unknown;
|
||||
return Array.isArray(body) ? (body as PriorityRuleChangeRequest[]) : [];
|
||||
},
|
||||
|
||||
approvePriorityRuleChange: async (
|
||||
id: string,
|
||||
decisionNote?: string,
|
||||
): Promise<PriorityRuleChangeRequest> => {
|
||||
const response = await client.post(
|
||||
`${PRIORITY_RULE_CHANGES_BASE}/${id}/approve`,
|
||||
{ decisionNote },
|
||||
);
|
||||
return unwrap(response.data) as PriorityRuleChangeRequest;
|
||||
},
|
||||
|
||||
rejectPriorityRuleChange: async (
|
||||
id: string,
|
||||
decisionNote?: string,
|
||||
): Promise<PriorityRuleChangeRequest> => {
|
||||
const response = await client.post(
|
||||
`${PRIORITY_RULE_CHANGES_BASE}/${id}/reject`,
|
||||
{ decisionNote },
|
||||
);
|
||||
return unwrap(response.data) as PriorityRuleChangeRequest;
|
||||
},
|
||||
|
||||
getApprovalChain: async (
|
||||
requiresDirectorApproval = true,
|
||||
): Promise<RuleEngineRecord[]> => {
|
||||
|
||||
@@ -108,6 +108,8 @@ export interface WagonTransferRequest {
|
||||
requestedByUserId: string | null;
|
||||
fulfilledByUserId: string | null;
|
||||
fulfilledAt: string | null;
|
||||
/** Why the wagons are needed — required for new requests, shown on the queue. */
|
||||
reason?: string | null;
|
||||
note: string | null;
|
||||
fromYard?: { id: string; label?: string; code?: string } | null;
|
||||
toYard?: { id: string; label?: string; code?: string } | null;
|
||||
@@ -120,9 +122,17 @@ export interface CreateTransferRequestPayload {
|
||||
toYardId: string;
|
||||
wagonTypeId: string;
|
||||
quantity: number;
|
||||
/** Mandatory: why the wagons are needed. */
|
||||
reason: string;
|
||||
note?: string;
|
||||
}
|
||||
|
||||
/** Bulk accept-and-execute result: what ran, what stayed PENDING and why. */
|
||||
export interface BulkFulfillResult {
|
||||
fulfilled: WagonTransferRequest[];
|
||||
skipped: Array<{ id: string; reason: string }>;
|
||||
}
|
||||
|
||||
/** Per-user activity: requests filed/fulfilled + the wagons physically moved. */
|
||||
export interface TransferHistory {
|
||||
requests: WagonTransferRequest[];
|
||||
@@ -146,6 +156,11 @@ export const wagonTransferRequestService = {
|
||||
apiClient.get<WagonTransferRequest>(`/wagon-transfer-requests/${id}`),
|
||||
create: (data: CreateTransferRequestPayload) =>
|
||||
apiClient.post<WagonTransferRequest>('/wagon-transfer-requests', data),
|
||||
/** OCC: accept-and-execute a subset of pending requests (auto-picked wagons). */
|
||||
bulkFulfill: (requestIds: string[]) =>
|
||||
apiClient.post<BulkFulfillResult>('/wagon-transfer-requests/bulk-fulfill', {
|
||||
requestIds,
|
||||
}),
|
||||
/** OCC: execute the transfer with the hand-picked wagons. */
|
||||
fulfill: (id: string, wagonIds: string[]) =>
|
||||
apiClient.post<WagonTransferRequest>(
|
||||
|
||||
Reference in New Issue
Block a user