resolve merge conflict

This commit is contained in:
Marshal
2026-07-09 03:39:06 +00:00
174 changed files with 8297 additions and 3001 deletions

View File

@@ -3,6 +3,7 @@ import type { FleetResourceSlug } from "@/pages/fleet/config/resources";
import type { BookingDetail } from "@/types/booking";
import type {
Company,
CompanyChangeRequest,
CompanyListFilter,
CompanyProfile,
CompanyStats,
@@ -99,6 +100,7 @@ import type {
LoadInventoryPayload,
LoadPassedExportResult,
MoveInventoryPayload,
StoreInventoryPayload,
PayInvoicePayload,
ReadyToLoadRow,
ReceiveInventoryPayload,
@@ -1051,10 +1053,13 @@ export const api = {
() => [["warehouse-inventory"], ["warehouses"]],
),
store: endpoint<string, WarehouseInventoryItem>(
store: endpoint<
{ id: string; payload?: StoreInventoryPayload },
WarehouseInventoryItem
>(
"warehouse-inventory",
"store",
(id) => warehouseService.store(id).then((r) => r.data),
({ id, payload }) => warehouseService.store(id, payload).then((r) => r.data),
undefined,
() => INVENTORY_INVALIDATIONS,
),
@@ -2261,13 +2266,13 @@ export const api = {
),
setProfileStatus: endpoint<
{ profileId: string; status: ProfileStatus },
{ profileId: string; status: ProfileStatus; note?: string },
CompanyProfile
>(
"customers",
"setProfileStatus",
({ profileId, status }) =>
customersService.setProfileStatus(profileId, status),
({ profileId, status, note }) =>
customersService.setProfileStatus(profileId, status, note),
undefined,
(_input, data) => [
QUERY_KEYS.CUSTOMERS.byId(data.companyId),
@@ -2275,6 +2280,37 @@ export const api = {
],
),
changeRequests: endpoint<{ id: string }, CompanyChangeRequest[]>(
"customers",
"changeRequests",
({ id }) => customersService.changeRequests(id),
({ id }) => QUERY_KEYS.CUSTOMERS.changeRequests(id),
),
approveChangeRequest: endpoint<{ id: string }, CompanyChangeRequest>(
"customers",
"approveChangeRequest",
({ id }) => customersService.approveChangeRequest(id),
undefined,
(_input, data) => [
QUERY_KEYS.CUSTOMERS.changeRequests(data.companyId),
QUERY_KEYS.CUSTOMERS.byId(data.companyId),
QUERY_KEYS.CUSTOMERS.ROOT,
],
),
rejectChangeRequest: endpoint<{ id: string; note: string }, CompanyChangeRequest>(
"customers",
"rejectChangeRequest",
({ id, note }) => customersService.rejectChangeRequest(id, note),
undefined,
(_input, data) => [
QUERY_KEYS.CUSTOMERS.changeRequests(data.companyId),
QUERY_KEYS.CUSTOMERS.byId(data.companyId),
QUERY_KEYS.CUSTOMERS.ROOT,
],
),
setCompanyStatus: endpoint<{ companyId: string; status: string }, unknown>(
"customers",
"setCompanyStatus",

View File

@@ -2,6 +2,7 @@ import { api as apiClient } from "@/auth/http";
import { URL_CONSTANTS } from "@/constants/URLS";
import type {
Company,
CompanyChangeRequest,
CompanyListFilter,
CompanyProfile,
CompanyStats,
@@ -80,11 +81,15 @@ export const customersService = {
.then((r) => r.data);
},
setProfileStatus(profileId: string, status: ProfileStatus): Promise<CompanyProfile> {
setProfileStatus(
profileId: string,
status: ProfileStatus,
note?: string,
): Promise<CompanyProfile> {
return apiClient
.patch<CompanyProfile>(
URL_CONSTANTS.COMPANIES.PROFILE_STATUS(profileId),
{ status },
{ status, note },
)
.then((r) => r.data);
},
@@ -95,4 +100,32 @@ export const customersService = {
.patch(URL_CONSTANTS.COMPANIES.BY_ID(companyId), { status })
.then((r) => r.data);
},
/** List a company's profile-edit change requests (newest first). */
changeRequests(companyId: string): Promise<CompanyChangeRequest[]> {
return apiClient
.get<CompanyChangeRequest[]>(
URL_CONSTANTS.COMPANIES.CHANGE_REQUESTS(companyId),
)
.then((r) => r.data);
},
/** Approve a pending change request — applies the proposed changes. */
approveChangeRequest(id: string): Promise<CompanyChangeRequest> {
return apiClient
.post<CompanyChangeRequest>(
URL_CONSTANTS.COMPANIES.CHANGE_REQUEST_APPROVE(id),
)
.then((r) => r.data);
},
/** Reject a pending change request with a note. */
rejectChangeRequest(id: string, note: string): Promise<CompanyChangeRequest> {
return apiClient
.post<CompanyChangeRequest>(
URL_CONSTANTS.COMPANIES.CHANGE_REQUEST_REJECT(id),
{ note },
)
.then((r) => r.data);
},
};

View File

@@ -30,6 +30,7 @@ import type {
LoadableWagon,
LoadInventoryPayload,
MoveInventoryPayload,
StoreInventoryPayload,
ReceiveInventoryPayload,
ReleaseOrderPayload,
DeliverInventoryPayload,
@@ -63,7 +64,7 @@ import type {
WarehouseZone,
} from '@/types/warehouse';
export type ContainerItemStage = 'PENDING' | 'RECEIVED' | 'GRN' | 'LOADED' | 'LEFT' | 'DELIVERED';
export type ContainerItemStage = 'PENDING' | 'RECEIVED' | 'GRN' | 'ASSIGNED' | 'LOADED' | 'LEFT' | 'DELIVERED';
export interface ContainerItem {
containerNumber: string;
@@ -74,9 +75,12 @@ export interface ContainerItem {
truckPlate: string | null;
truckArrived: boolean;
truckLeft: boolean;
/** Operator has loaded this container onto the truck (customer assignment alone is not "loaded"). */
loaded: boolean;
bookingReference: string | null;
contractId: string | null;
hasLastMile: boolean;
handoverSigned: boolean;
}
/** A pre-dispatch EXPORT train that has inventory waiting to be loaded. */
@@ -135,6 +139,26 @@ export const warehouseService = {
return data?.data ?? data ?? [];
},
/** Ask the customer to sign the booking's handover (creates one if none, then notifies). */
requestHandoverSignature: async (
bookingId: string,
): Promise<{ notified: boolean; reference: string | null; alreadySigned: boolean }> => {
const { data } = await apiClient.post(
`/warehouse-inventory/bookings/${bookingId}/request-handover-signature`,
);
return data?.data ?? data;
},
/** A booking's containers with VGM cargo weight (tonnes) for exit weighing. */
getContainerWeights: async (
bookingId: string,
): Promise<Array<{ containerNumber: string; weightTons: number }>> => {
const { data } = await apiClient.get(
`/warehouse-inventory/bookings/${bookingId}/container-weights`,
);
return data?.data ?? data ?? [];
},
/** Booking container numbers not yet loaded onto any truck. */
getLoadableContainers: async (bookingId: string): Promise<string[]> => {
const { data } = await apiClient.get(
@@ -235,8 +259,8 @@ export const warehouseService = {
}),
// ── Lifecycle (Batch 2) ──────────────────────────────────────────────────
store: (id: string) =>
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.STORE(id)),
store: (id: string, payload?: StoreInventoryPayload) =>
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.STORE(id), payload),
reserve: (payload: ReserveInventoryPayload) =>
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RESERVE, payload),
markReadyForLoading: (id: string) =>