From f2f6c89c0eacb7e1010d9a8a1de1bb73e0f3cd17 Mon Sep 17 00:00:00 2001 From: natib21 Date: Fri, 3 Jul 2026 15:37:24 +0000 Subject: [PATCH] fix --- .../modules/last-mile/last-mile.service.ts | 26 ++++++++++++++++--- .../components/fleet/FleetHistoryModal.tsx | 13 +++++++--- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/apps/edr-freight-api/src/modules/last-mile/last-mile.service.ts b/apps/edr-freight-api/src/modules/last-mile/last-mile.service.ts index f0d39d51c..f5c9696e6 100644 --- a/apps/edr-freight-api/src/modules/last-mile/last-mile.service.ts +++ b/apps/edr-freight-api/src/modules/last-mile/last-mile.service.ts @@ -58,6 +58,23 @@ export class LastMileService { } } + /** Human booking reference for a last-mile record, for the history timeline. + * Uses the already-loaded relation when present, else looks it up. */ + private async resolveBookingRef( + record: LastMile, + ): Promise { + const loaded = (record as LastMile & { booking?: { reference?: string } }) + .booking?.reference; + if (loaded) return loaded; + if (!record.bookingId) return null; + try { + const booking = await this.bookingsRepository.findById(record.bookingId); + return (booking as { reference?: string } | null)?.reference ?? null; + } catch { + return null; + } + } + async acceptBooking(bookingReference: string): Promise { const booking = await this.bookingsRepository.findByReference(bookingReference); @@ -165,7 +182,7 @@ export class LastMileService { lastMileId: record.id, driverId: await this.resolveDriverId(dto.vehicleId), label: record.status, - metadata: { mile: 'LAST' }, + metadata: { mile: 'LAST', bookingRef: await this.resolveBookingRef(record) }, }); } @@ -209,6 +226,7 @@ export class LastMileService { } // Audit the mile↔vehicle (re)assignment on both vehicle and driver lines. + const bookingRef = await this.resolveBookingRef(existing); if (dto.vehicleId !== undefined && dto.vehicleId !== existing.vehicleId) { if (existing.vehicleId) { await this.history.record({ @@ -216,7 +234,7 @@ export class LastMileService { vehicleId: existing.vehicleId, lastMileId: id, driverId: await this.resolveDriverId(existing.vehicleId), - metadata: { mile: 'LAST' }, + metadata: { mile: 'LAST', bookingRef }, }); } if (dto.vehicleId) { @@ -226,7 +244,7 @@ export class LastMileService { lastMileId: id, driverId: await this.resolveDriverId(dto.vehicleId), label: updated.status, - metadata: { mile: 'LAST' }, + metadata: { mile: 'LAST', bookingRef }, }); } } @@ -240,7 +258,7 @@ export class LastMileService { driverId: await this.resolveDriverId(vehicleId), fromValue: existing.status, toValue: dto.status, - metadata: { mile: 'LAST' }, + metadata: { mile: 'LAST', bookingRef }, }); } diff --git a/apps/edr-freight-web/backoffice/src/components/fleet/FleetHistoryModal.tsx b/apps/edr-freight-web/backoffice/src/components/fleet/FleetHistoryModal.tsx index 868ed347d..0e7a0e65b 100644 --- a/apps/edr-freight-web/backoffice/src/components/fleet/FleetHistoryModal.tsx +++ b/apps/edr-freight-web/backoffice/src/components/fleet/FleetHistoryModal.tsx @@ -42,6 +42,13 @@ const arrow = (from?: string | null, to?: string | null) => `${from ?? "—"} → ${to ?? "—"}`; function describe(e: FleetHistoryEvent, entity: "driver" | "vehicle") { + const bookingRef = + typeof e.metadata?.bookingRef === "string" ? e.metadata.bookingRef : null; + const withBooking = (rest?: string) => + [bookingRef ? `Booking ${bookingRef}` : "", rest ?? ""] + .filter(Boolean) + .join(" · "); + switch (e.eventType) { case "DRIVER_REGISTERED": return { @@ -89,19 +96,19 @@ function describe(e: FleetHistoryEvent, entity: "driver" | "vehicle") { return { icon: , title: `${mileLabel(e)}: vehicle assigned`, - text: e.label ? `Status: ${e.label}` : "", + text: withBooking(e.label ? `Status: ${e.label}` : ""), }; case "MILE_VEHICLE_RELEASED": return { icon: , title: `${mileLabel(e)}: vehicle released`, - text: "", + text: withBooking(), }; case "MILE_STATUS_CHANGED": return { icon: , title: `${mileLabel(e)} status`, - text: arrow(e.fromValue, e.toValue), + text: withBooking(arrow(e.fromValue, e.toValue)), }; default: return { icon: , title: e.eventType, text: "" };