mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 07:22:53 +00:00
Update seatmap for blocked seats
This commit is contained in:
@@ -1879,6 +1879,8 @@ export class BookingsService {
|
||||
adultCount: booking.adultCount, childCount: booking.childCount,
|
||||
displayCurrency: booking.displayCurrency, displayTotalMinor: booking.displayTotalMinor ?? undefined,
|
||||
bookingType: booking.bookingType,
|
||||
packageId: (booking as any).packageId ?? null,
|
||||
isPackageBooking: !!(booking as any).packageId,
|
||||
returnLegStatus: (booking as any).returnLegStatus ?? null,
|
||||
outboundBoardedAt: (booking as any).outboundBoardedAt ?? null,
|
||||
returnBoardedAt: (booking as any).returnBoardedAt ?? null,
|
||||
|
||||
@@ -427,6 +427,7 @@ function BookingDetailContent() {
|
||||
</span>
|
||||
</h2>
|
||||
|
||||
{!booking.isPackageBooking && booking.bookingType !== "PACKAGE" && (
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-sm font-bold text-gray-900 dark:text-gray-100">
|
||||
Fare breakdown
|
||||
@@ -481,6 +482,7 @@ function BookingDetailContent() {
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="pt-2 border-t-2 border-gray-200 dark:border-gray-700">
|
||||
<div className="flex justify-between items-center">
|
||||
|
||||
@@ -52,6 +52,7 @@ export default function ReviewPage() {
|
||||
const [timeLeft, setTimeLeft] = useState<string>('');
|
||||
const [seatDetails, setSeatDetails] = useState<Record<string, string>>({});
|
||||
const [fareBreakdown, setFareBreakdown] = useState<any>(null);
|
||||
const [returnFareBreakdown, setReturnFareBreakdown] = useState<any>(null);
|
||||
const [computedTotal, setComputedTotal] = useState<number>(0);
|
||||
|
||||
const isRoundTrip = searchCriteria?.tripType === 'ROUND_TRIP';
|
||||
@@ -173,16 +174,27 @@ const adultPassengerCount = searchCriteria?.adultCount ?? passengers.filter(p =>
|
||||
// Prefers displayFareMinor (converted) from the fare breakdown API when available.
|
||||
// Falls back to raw ETB seat fares (which are always in minor units).
|
||||
const getPassengerSeatFare = (p: any, index?: number): number | null => {
|
||||
if (isRoundTrip) {
|
||||
// Seat-specific fares (set during seat selection) cover each leg separately — use them first.
|
||||
if (p.outboundSeatFareMinor != null || p.inboundSeatFareMinor != null) {
|
||||
if (isPackageBooking) return (p.outboundSeatFareMinor ?? 0) * 2;
|
||||
return (p.outboundSeatFareMinor ?? 0) + (p.inboundSeatFareMinor ?? 0);
|
||||
}
|
||||
// No seat-specific fares: fall back to the per-leg fare-breakdown totals for both legs.
|
||||
if (!isPackageBooking && fareBreakdown?.passengers && returnFareBreakdown?.passengers && index != null) {
|
||||
const obLine = fareBreakdown.passengers[index];
|
||||
const retLine = returnFareBreakdown.passengers[index];
|
||||
const obFare = obLine?.displayFareMinor ?? obLine?.fareMinor;
|
||||
const retFare = retLine?.displayFareMinor ?? retLine?.fareMinor;
|
||||
if (obFare != null && retFare != null) return obFare + retFare;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (!isPackageBooking && fareBreakdown?.passengers && index != null) {
|
||||
const line = fareBreakdown.passengers[index];
|
||||
const displayFare = line?.displayFareMinor ?? line?.fareMinor;
|
||||
if (displayFare != null) return displayFare;
|
||||
}
|
||||
if (isRoundTrip) {
|
||||
if (p.outboundSeatFareMinor == null && p.inboundSeatFareMinor == null) return null;
|
||||
if (isPackageBooking) return (p.outboundSeatFareMinor ?? 0) * 2;
|
||||
return (p.outboundSeatFareMinor ?? 0) + (p.inboundSeatFareMinor ?? 0);
|
||||
}
|
||||
if (p.seatFareMinor == null) return null;
|
||||
return isPackageBooking ? p.seatFareMinor * 2 : p.seatFareMinor;
|
||||
};
|
||||
@@ -541,6 +553,22 @@ const adultPassengerCount = searchCriteria?.adultCount ?? passengers.filter(p =>
|
||||
|
||||
const result: any = await apiClient.get(`/search/fare-breakdown?${params}`);
|
||||
setFareBreakdown(result);
|
||||
|
||||
// For round-trips, also fetch the return leg's fare breakdown so the review page
|
||||
// can display and send the correct combined total (outbound + return per passenger).
|
||||
if (isRoundTrip && inboundSchedule) {
|
||||
const returnScheduleId = (inboundSchedule as any).id;
|
||||
const returnParams = new URLSearchParams({
|
||||
scheduleId: returnScheduleId,
|
||||
originStationId: searchCriteria.destinationStationId,
|
||||
destinationStationId: searchCriteria.originStationId,
|
||||
passengers: passengersParam,
|
||||
displayCurrency: displayCurrencyCode,
|
||||
...(searchCriteria.promoCode ? { promoCode: searchCriteria.promoCode } : {}),
|
||||
});
|
||||
const returnResult: any = await apiClient.get(`/search/fare-breakdown?${returnParams}`);
|
||||
setReturnFareBreakdown(returnResult);
|
||||
}
|
||||
} catch (err) {
|
||||
}
|
||||
})();
|
||||
@@ -566,7 +594,11 @@ const adultPassengerCount = searchCriteria?.adultCount ?? passengers.filter(p =>
|
||||
const isFreeChild = line?.isFree ?? (isChildPassenger && isFirstChild(passengers, i));
|
||||
if (isFreeChild) return sum;
|
||||
const seatFare = getPassengerSeatFare(p, i);
|
||||
const displayFare = line?.displayFareMinor ?? line?.fareMinor;
|
||||
// For round-trips the fallback must combine both legs; for one-way it's the single-leg fare.
|
||||
const obFare = line?.displayFareMinor ?? line?.fareMinor;
|
||||
const retLine = returnFareBreakdown?.passengers?.[i];
|
||||
const retFare = retLine?.displayFareMinor ?? retLine?.fareMinor;
|
||||
const displayFare = isRoundTrip && retFare != null ? (obFare ?? 0) + retFare : obFare;
|
||||
return sum + (seatFare ?? displayFare ?? 0);
|
||||
}, 0);
|
||||
|
||||
@@ -586,26 +618,27 @@ const adultPassengerCount = searchCriteria?.adultCount ?? passengers.filter(p =>
|
||||
? isPkgFreeChild(i)
|
||||
: (line?.isFree ?? (isChild(p) && isFirstChild(passengers, i)));
|
||||
|
||||
// Per-leg fares for round trips — use converted amounts from fareBreakdown when available
|
||||
const displayFare = line?.displayFareMinor ?? line?.fareMinor;
|
||||
// Per-leg fares for round trips — prefer seat-specific fares, then per-leg breakdowns.
|
||||
const retLine = returnFareBreakdown?.passengers?.[i];
|
||||
const obBreakdownFare = line?.displayFareMinor ?? line?.fareMinor;
|
||||
const retBreakdownFare = retLine?.displayFareMinor ?? retLine?.fareMinor;
|
||||
const outboundFare: number | null = isRoundTrip
|
||||
? (isPackageBooking
|
||||
? (packageTierPriceMinor ?? null)
|
||||
: (displayFare != null
|
||||
? Math.round(displayFare / 2)
|
||||
: ((p as any).outboundSeatFareMinor ?? null)))
|
||||
: ((p as any).outboundSeatFareMinor ?? obBreakdownFare ?? null))
|
||||
: null;
|
||||
const inboundFare: number | null = isRoundTrip
|
||||
? (isPackageBooking
|
||||
? (packageTierPriceMinor ?? null)
|
||||
: (displayFare != null
|
||||
? Math.round(displayFare / 2)
|
||||
: ((p as any).inboundSeatFareMinor ?? null)))
|
||||
: ((p as any).inboundSeatFareMinor ?? retBreakdownFare ?? null))
|
||||
: null;
|
||||
const seatFare = getPassengerSeatFare(p, i);
|
||||
const combinedDisplayFare = isRoundTrip && retBreakdownFare != null
|
||||
? (obBreakdownFare ?? 0) + retBreakdownFare
|
||||
: obBreakdownFare;
|
||||
const passengerTotal = isPackageBooking
|
||||
? (isFreeChild ? 0 : (seatFare ?? (isChildPassenger ? pkgChildFare : pkgAdultFare)))
|
||||
: (isFreeChild ? 0 : (seatFare ?? displayFare ?? 0));
|
||||
: (isFreeChild ? 0 : (seatFare ?? combinedDisplayFare ?? 0));
|
||||
|
||||
return (
|
||||
<div key={i} className="border-b border-gray-100 dark:border-gray-800 pb-2 last:border-0">
|
||||
|
||||
@@ -52,7 +52,7 @@ const BedCard = memo(({ bed, isSelected, isAssignedToOther, onToggle }: any) =>
|
||||
? "bg-purple-50 border-purple-300 cursor-not-allowed dark:bg-purple-900/20 dark:border-purple-700"
|
||||
: bed.status === "AVAILABLE"
|
||||
? "bg-green-50 border-green-300 hover:bg-green-100 hover:border-green-400 dark:bg-green-900/20 dark:border-green-700"
|
||||
: bed.status === "BOOKED"
|
||||
: bed.status === "BOOKED" || bed.status === "BLOCKED"
|
||||
? "bg-red-50 border-red-300 cursor-not-allowed dark:bg-red-900/20 dark:border-red-700"
|
||||
: "bg-gray-100 border-gray-300 cursor-not-allowed dark:bg-gray-800 dark:border-gray-700"
|
||||
}`}
|
||||
|
||||
Reference in New Issue
Block a user