diff --git a/apps/edr-freight-api/src/modules/warehouses/warehouse-inventory.controller.ts b/apps/edr-freight-api/src/modules/warehouses/warehouse-inventory.controller.ts index acd31bd51..0174ef3e9 100644 --- a/apps/edr-freight-api/src/modules/warehouses/warehouse-inventory.controller.ts +++ b/apps/edr-freight-api/src/modules/warehouses/warehouse-inventory.controller.ts @@ -556,6 +556,12 @@ export class WarehouseInventoryController { return this.inventoryService.bookingContainerWeights(bookingId); } + @Get('bookings/:bookingId/location') + @ApiOperation({ summary: "Warehouse location of a booking's inventory (customer portal)" }) + bookingLocation(@Param('bookingId', ParseUUIDPipe) bookingId: string) { + return this.inventoryService.bookingLocation(bookingId); + } + @Post(':id/deliver') @BookingStaff(FREIGHT_PERMS.warehouseInventory.deliver) @ApiOperation({ summary: 'Deliver import goods to the customer + capture proof of delivery' }) diff --git a/apps/edr-freight-api/src/modules/warehouses/warehouse-inventory.service.ts b/apps/edr-freight-api/src/modules/warehouses/warehouse-inventory.service.ts index 50c71f485..b5df563d9 100644 --- a/apps/edr-freight-api/src/modules/warehouses/warehouse-inventory.service.ts +++ b/apps/edr-freight-api/src/modules/warehouses/warehouse-inventory.service.ts @@ -1030,6 +1030,28 @@ export class WarehouseInventoryService { return this.findAll({ ...filter, status: 'READY_FOR_LOADING' }); } + /** + * Warehouse location rows for one booking, trimmed for the customer portal: + * no staff guard on the route, so only location fields leave the API — + * never notes, fees or inspection internals. + */ + async bookingLocation(bookingId: string) { + const items = await this.inventoryRepository.findAll({ + where: { bookingId }, + relations: { warehouse: true, yard: true, zone: true }, + order: { createdAt: 'DESC' }, + }); + return items.map((i) => ({ + id: i.id, + bookingId: i.bookingId, + status: i.status, + arrivedAt: i.arrivedAt ?? null, + warehouse: i.warehouse ? { id: i.warehouse.id, name: i.warehouse.name, code: i.warehouse.code } : null, + yard: i.yard ? { id: i.yard.id, name: i.yard.name, code: i.yard.code } : null, + zone: i.zone ? { id: i.zone.id, name: i.zone.name, code: i.zone.code } : null, + })); + } + async findById(id: string): Promise { const item = await this.inventoryRepository.findById(id, { relations: { warehouse: { facility: true }, yard: true, zone: true }, diff --git a/apps/edr-freight-web/portal/src/pages/bookings/BookingDetailPage/components/WarehouseLocationCard.tsx b/apps/edr-freight-web/portal/src/pages/bookings/BookingDetailPage/components/WarehouseLocationCard.tsx index cf20912cd..799059451 100644 --- a/apps/edr-freight-web/portal/src/pages/bookings/BookingDetailPage/components/WarehouseLocationCard.tsx +++ b/apps/edr-freight-web/portal/src/pages/bookings/BookingDetailPage/components/WarehouseLocationCard.tsx @@ -23,8 +23,8 @@ function Row({ label, value }: { label: string; value: React.ReactNode }) { export function WarehouseLocationCard({ bookingId }: WarehouseLocationCardProps) { const { data, isLoading } = useQuery({ - queryKey: ["warehouse-inventory", bookingId], - queryFn: () => warehouseService.listInventory({ bookingId }), + queryKey: ["warehouse-inventory", "booking-location", bookingId], + queryFn: () => warehouseService.bookingLocation(bookingId), }); const items = data ?? []; diff --git a/apps/edr-freight-web/portal/src/services/warehouse.service.ts b/apps/edr-freight-web/portal/src/services/warehouse.service.ts index dfb6042cc..b641a8809 100644 --- a/apps/edr-freight-web/portal/src/services/warehouse.service.ts +++ b/apps/edr-freight-web/portal/src/services/warehouse.service.ts @@ -49,6 +49,12 @@ export const warehouseService = { return data?.data ?? data ?? []; }, + /** Customer-safe location endpoint — the plain list is staff-only (403 for portal users). */ + bookingLocation: async (bookingId: string): Promise => { + const { data } = await client.get(`/warehouse-inventory/bookings/${bookingId}/location`); + return data?.data ?? data ?? []; + }, + bookingSchedule: async (bookingId: string): Promise => { const { data } = await client.get(`/warehouse-inventory/booking-schedule/${bookingId}`); return data?.data ?? data ?? { schedule: null, wagon: null };