mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 21:08:12 +00:00
feat(warehouse): fetch all PAID bookings in one call, classified IMPORT/EXPORT by route
- eligibleBookings(direction?) now returns all import+export bookings when direction omitted (DOMESTIC excluded); per-direction filter preserved for backward compatibility - GET /warehouse-inventory/eligible-bookings (no query) returns the combined set - Frontend: single shared useEligibleBookings() query; both Receive tabs filter client-side by route-derived direction, so only one HTTP request fires Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -61,9 +61,10 @@ export class WarehouseInventoryController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Get('eligible-bookings')
|
@Get('eligible-bookings')
|
||||||
@ApiOperation({ summary: 'Eligible PAID bookings for a direction (IMPORT/EXPORT) not yet received' })
|
@ApiOperation({ summary: 'PAID bookings not yet received, classified IMPORT/EXPORT by route; omit direction for all' })
|
||||||
eligibleBookings(@Query('direction') direction: 'IMPORT' | 'EXPORT') {
|
eligibleBookings(@Query('direction') direction?: string) {
|
||||||
return this.inventoryService.eligibleBookings(direction === 'EXPORT' ? 'EXPORT' : 'IMPORT');
|
const dir = direction === 'IMPORT' || direction === 'EXPORT' ? direction : undefined;
|
||||||
|
return this.inventoryService.eligibleBookings(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('receive-bulk')
|
@Post('receive-bulk')
|
||||||
|
|||||||
@@ -468,8 +468,12 @@ export class WarehouseInventoryService {
|
|||||||
|
|
||||||
// ── Receive (Import/Export bulk) ───────────────────────────────────────────
|
// ── Receive (Import/Export bulk) ───────────────────────────────────────────
|
||||||
|
|
||||||
/** Eligible PAID bookings for a direction (DERIVED FROM ROUTE) that have NOT been received yet. */
|
/**
|
||||||
async eligibleBookings(direction: 'IMPORT' | 'EXPORT'): Promise<EligibleBookingRow[]> {
|
* Eligible PAID bookings that have NOT been received yet, classified IMPORT/EXPORT by route
|
||||||
|
* (origin/destination yard countries). Pass a direction to filter to one; omit it to return
|
||||||
|
* all import + export bookings in a single call (DOMESTIC routes are excluded either way).
|
||||||
|
*/
|
||||||
|
async eligibleBookings(direction?: 'IMPORT' | 'EXPORT'): Promise<EligibleBookingRow[]> {
|
||||||
const rows: Array<
|
const rows: Array<
|
||||||
EligibleBookingRow & { originCountry: string | null; destinationCountry: string | null }
|
EligibleBookingRow & { originCountry: string | null; destinationCountry: string | null }
|
||||||
> = await this.dataSource.query(
|
> = await this.dataSource.query(
|
||||||
@@ -504,7 +508,9 @@ export class WarehouseInventoryService {
|
|||||||
...r,
|
...r,
|
||||||
direction: deriveTradeDirection({ country: r.originCountry }, { country: r.destinationCountry }),
|
direction: deriveTradeDirection({ country: r.originCountry }, { country: r.destinationCountry }),
|
||||||
}))
|
}))
|
||||||
.filter((r) => r.direction === direction);
|
.filter((r) =>
|
||||||
|
direction ? r.direction === direction : r.direction === 'IMPORT' || r.direction === 'EXPORT',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Bulk-receive eligible PAID bookings into a location. Skips duplicates / wrong direction. */
|
/** Bulk-receive eligible PAID bookings into a location. Skips duplicates / wrong direction. */
|
||||||
|
|||||||
@@ -135,7 +135,8 @@ function EligibleTab({
|
|||||||
onChanged?: () => void;
|
onChanged?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { data: rows = [], isLoading } = useEligibleBookings(direction, enabled);
|
const { data: allRows = [], isLoading } = useEligibleBookings(enabled);
|
||||||
|
const rows = useMemo(() => allRows.filter((r) => r.direction === direction), [allRows, direction]);
|
||||||
const bulkReceive = useBulkReceive();
|
const bulkReceive = useBulkReceive();
|
||||||
const loadPassed = useLoadPassedExport();
|
const loadPassed = useLoadPassedExport();
|
||||||
const [selected, setSelected] = useState<Set<string>>(new Set());
|
const [selected, setSelected] = useState<Set<string>>(new Set());
|
||||||
|
|||||||
@@ -307,7 +307,10 @@ export const URL_CONSTANTS = {
|
|||||||
RELEASE: (id: string) => `/warehouse-inventory/${id}/release`,
|
RELEASE: (id: string) => `/warehouse-inventory/${id}/release`,
|
||||||
DELIVER: (id: string) => `/warehouse-inventory/${id}/deliver`,
|
DELIVER: (id: string) => `/warehouse-inventory/${id}/deliver`,
|
||||||
// Receive (Import/Export bulk)
|
// Receive (Import/Export bulk)
|
||||||
ELIGIBLE_BOOKINGS: (direction: string) => `/warehouse-inventory/eligible-bookings?direction=${direction}`,
|
ELIGIBLE_BOOKINGS: (direction?: string) =>
|
||||||
|
direction
|
||||||
|
? `/warehouse-inventory/eligible-bookings?direction=${direction}`
|
||||||
|
: `/warehouse-inventory/eligible-bookings`,
|
||||||
RECEIVE_BULK: '/warehouse-inventory/receive-bulk',
|
RECEIVE_BULK: '/warehouse-inventory/receive-bulk',
|
||||||
LOAD_PASSED_EXPORT: '/warehouse-inventory/load-passed-export',
|
LOAD_PASSED_EXPORT: '/warehouse-inventory/load-passed-export',
|
||||||
BULK_MARK_INSPECTED: '/warehouse-inventory/bulk-mark-inspected',
|
BULK_MARK_INSPECTED: '/warehouse-inventory/bulk-mark-inspected',
|
||||||
|
|||||||
@@ -189,10 +189,15 @@ export const useDeliverInventory = () =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
// ── Receive (Import/Export bulk) ───────────────────────────────────────────
|
// ── Receive (Import/Export bulk) ───────────────────────────────────────────
|
||||||
export function useEligibleBookings(direction: 'IMPORT' | 'EXPORT', enabled = true) {
|
/**
|
||||||
|
* All not-yet-received PAID bookings, classified IMPORT/EXPORT by route, in one call.
|
||||||
|
* Both Receive tabs share this single query (same key) — only one HTTP request fires —
|
||||||
|
* then filter client-side by direction.
|
||||||
|
*/
|
||||||
|
export function useEligibleBookings(enabled = true) {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['warehouse-inventory', 'eligible-bookings', direction],
|
queryKey: ['warehouse-inventory', 'eligible-bookings'],
|
||||||
queryFn: () => warehouseService.eligibleBookings(direction).then((r) => r.data),
|
queryFn: () => warehouseService.eligibleBookings().then((r) => r.data),
|
||||||
enabled,
|
enabled,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export const warehouseService = {
|
|||||||
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.DELIVER(id), payload),
|
apiClient.post<WarehouseInventoryItem>(URL_CONSTANTS.WAREHOUSE_INVENTORY.DELIVER(id), payload),
|
||||||
|
|
||||||
// ── Receive (Import/Export bulk) ─────────────────────────────────────────
|
// ── Receive (Import/Export bulk) ─────────────────────────────────────────
|
||||||
eligibleBookings: (direction: 'IMPORT' | 'EXPORT') =>
|
eligibleBookings: (direction?: 'IMPORT' | 'EXPORT') =>
|
||||||
apiClient.get<EligibleBooking[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.ELIGIBLE_BOOKINGS(direction)),
|
apiClient.get<EligibleBooking[]>(URL_CONSTANTS.WAREHOUSE_INVENTORY.ELIGIBLE_BOOKINGS(direction)),
|
||||||
receiveBulk: (payload: BulkReceivePayload) =>
|
receiveBulk: (payload: BulkReceivePayload) =>
|
||||||
apiClient.post<BulkReceiveResult>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RECEIVE_BULK, payload),
|
apiClient.post<BulkReceiveResult>(URL_CONSTANTS.WAREHOUSE_INVENTORY.RECEIVE_BULK, payload),
|
||||||
|
|||||||
Reference in New Issue
Block a user