mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 12:18:11 +00:00
Ticket generation updates
This commit is contained in:
@@ -112,6 +112,15 @@ export default function ConfirmationPage() {
|
|||||||
// backgrounded tabs, so that can take a very long time.
|
// backgrounded tabs, so that can take a very long time.
|
||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
enabled: !!bookingId,
|
enabled: !!bookingId,
|
||||||
|
// Keep polling after CONFIRMED until tickets are issued — ticket generation runs
|
||||||
|
// async after the booking transaction commits (see finalizePaymentSuccess in
|
||||||
|
// payments.service.ts), so the first CONFIRMED fetch often returns an empty
|
||||||
|
// tickets array.
|
||||||
|
refetchInterval: (query) => {
|
||||||
|
const data = query.state.data;
|
||||||
|
if (!data || data.status !== "CONFIRMED") return false;
|
||||||
|
return (data.tickets?.length ?? 0) >= passengers.length ? false : FAST_POLL_INTERVAL_MS;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Poll the payment intent while the booking is PENDING_PAYMENT — fast during the
|
// Poll the payment intent while the booking is PENDING_PAYMENT — fast during the
|
||||||
@@ -153,7 +162,7 @@ export default function ConfirmationPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDownloadVoucher = async () => {
|
const handleDownloadVoucher = async () => {
|
||||||
if (!pnr) {
|
if (!pnr || !bookingId) {
|
||||||
alert("Booking data not available. Please try again.");
|
alert("Booking data not available. Please try again.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -164,23 +173,28 @@ export default function ConfirmationPage() {
|
|||||||
|
|
||||||
setIsGeneratingVoucher(true);
|
setIsGeneratingVoucher(true);
|
||||||
try {
|
try {
|
||||||
const { generatePassengerVoucherPDF } =
|
const { generatePassengerVoucherPDF } = await import("@/lib/generate-voucher");
|
||||||
await import("@/lib/generate-voucher");
|
|
||||||
|
// Always fetch fresh booking data so tickets are present even if the cached
|
||||||
|
// _booking raced ahead of ticket generation (tickets are written async after
|
||||||
|
// the booking is confirmed — see finalizePaymentSuccess in payments.service.ts).
|
||||||
|
const freshBooking: BookingWithTicket = await apiClient.get(`/bookings/${bookingId}`);
|
||||||
|
const bookingData = freshBooking ?? _booking;
|
||||||
|
|
||||||
const activeSchedule = isRoundTrip ? outboundSchedule : selectedSchedule;
|
const activeSchedule = isRoundTrip ? outboundSchedule : selectedSchedule;
|
||||||
// The server-confirmed settled amount/currency (what was actually charged) is
|
// The server-confirmed settled amount/currency (what was actually charged) is
|
||||||
// authoritative — prefer it over the ETB booking fare once available. Shown exactly
|
// authoritative — prefer it over the ETB booking fare once available. Shown exactly
|
||||||
// as returned by the API (no /100, no per-passenger split) on every passenger's
|
// as returned by the API (no /100, no per-passenger split) on every passenger's
|
||||||
// voucher — see fareIsMajorUnits below.
|
// voucher — see fareIsMajorUnits below.
|
||||||
const settledAmountMinor = _booking?.payment?.amountMinor;
|
const settledAmountMinor = bookingData?.payment?.amountMinor;
|
||||||
const settledCurrency = _booking?.payment?.currency;
|
const settledCurrency = bookingData?.payment?.currency;
|
||||||
const hasSettledAmount = settledAmountMinor != null && !!settledCurrency;
|
const hasSettledAmount = settledAmountMinor != null && !!settledCurrency;
|
||||||
// Derive display currency from nationality (same logic as review/payment pages)
|
// Derive display currency from nationality (same logic as review/payment pages)
|
||||||
const nat = (searchCriteria?.nationality ?? '').toUpperCase();
|
const nat = (searchCriteria?.nationality ?? '').toUpperCase();
|
||||||
const passengerDisplayCurrency = nat === 'DJIBOUTIAN' ? 'DJF' : nat === 'ETHIOPIAN' ? 'ETB' : 'USD';
|
const passengerDisplayCurrency = nat === 'DJIBOUTIAN' ? 'DJF' : nat === 'ETHIOPIAN' ? 'ETB' : 'USD';
|
||||||
const voucherCurrency = hasSettledAmount ? settledCurrency! : passengerDisplayCurrency;
|
const voucherCurrency = hasSettledAmount ? settledCurrency! : passengerDisplayCurrency;
|
||||||
const createdAt = _booking?.createdAt || new Date().toISOString();
|
const createdAt = bookingData?.createdAt || new Date().toISOString();
|
||||||
const status = _booking?.status || "CONFIRMED";
|
const status = bookingData?.status || "CONFIRMED";
|
||||||
|
|
||||||
// Compute per-passenger fares (in ETB) using the same logic as the review/payment
|
// Compute per-passenger fares (in ETB) using the same logic as the review/payment
|
||||||
// pages. reviewedPassengerFares is the authoritative source; rebuild from package
|
// pages. reviewedPassengerFares is the authoritative source; rebuild from package
|
||||||
@@ -206,7 +220,7 @@ export default function ConfirmationPage() {
|
|||||||
return isPkgChild ? pkgChildFare : pkgAdultFare;
|
return isPkgChild ? pkgChildFare : pkgAdultFare;
|
||||||
}
|
}
|
||||||
const totalFare =
|
const totalFare =
|
||||||
reviewedTotalMinor ?? paidAmountMinor ?? _booking?.totalMinor ?? 0;
|
reviewedTotalMinor ?? paidAmountMinor ?? bookingData?.totalMinor ?? 0;
|
||||||
return Math.round(totalFare / passengers.length);
|
return Math.round(totalFare / passengers.length);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -254,11 +268,9 @@ export default function ConfirmationPage() {
|
|||||||
// synchronous user-activation window and risk iOS Safari silently blocking them.
|
// synchronous user-activation window and risk iOS Safari silently blocking them.
|
||||||
for (let i = 0; i < passengers.length; i++) {
|
for (let i = 0; i < passengers.length; i++) {
|
||||||
const p = passengers[i];
|
const p = passengers[i];
|
||||||
// Same match-by-name-then-position as the on-screen ticket list above — no
|
|
||||||
// fabricated placeholder if there's no backend ticket data (see generate-voucher.ts).
|
|
||||||
const matchedTicket =
|
const matchedTicket =
|
||||||
_booking?.tickets?.find((t) => t.passengerName === p.name) ??
|
bookingData?.tickets?.find((t) => t.passengerName === p.name) ??
|
||||||
_booking?.tickets?.[i] ??
|
bookingData?.tickets?.[i] ??
|
||||||
null;
|
null;
|
||||||
const ticketNumber = matchedTicket?.barcodePayload || "Not yet issued";
|
const ticketNumber = matchedTicket?.barcodePayload || "Not yet issued";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user