@ticketboothapp/booking 1.2.60 → 1.2.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1754,12 +1754,16 @@ export function BookingFlow({
|
|
|
1754
1754
|
return product.productId.trim();
|
|
1755
1755
|
}, [initialValues?.productId, product.productId]);
|
|
1756
1756
|
|
|
1757
|
-
/**
|
|
1757
|
+
/**
|
|
1758
|
+
* Receipt paid floors (max(receipt, catalog) on protected seats / return) — **customer self-serve only**.
|
|
1759
|
+
* Provider dashboard uses live catalog so cheaper itinerary → lower total / refund (`changeFlowBalanceVsOriginal` provider).
|
|
1760
|
+
*/
|
|
1758
1761
|
const changeFlowApplyReceiptPaidFloors = useMemo(
|
|
1759
1762
|
() =>
|
|
1760
1763
|
isChangeFlow &&
|
|
1764
|
+
!isProviderDashboardChange &&
|
|
1761
1765
|
changeFlowBookingParentProductIdForFloors === product.productId.trim(),
|
|
1762
|
-
[isChangeFlow, changeFlowBookingParentProductIdForFloors, product.productId],
|
|
1766
|
+
[isChangeFlow, isProviderDashboardChange, changeFlowBookingParentProductIdForFloors, product.productId],
|
|
1763
1767
|
);
|
|
1764
1768
|
|
|
1765
1769
|
useEffect(() => {
|
|
@@ -2478,14 +2482,6 @@ export function BookingFlow({
|
|
|
2478
2482
|
selectedReturnOption?.dateTime,
|
|
2479
2483
|
]);
|
|
2480
2484
|
/** Same outbound + return as original booking: incremental seats use live pricing; receipt floors apply only after itinerary changes. */
|
|
2481
|
-
const changeFlowSameItineraryAsOriginalBooking = useMemo(
|
|
2482
|
-
() =>
|
|
2483
|
-
isChangeFlow &&
|
|
2484
|
-
changeFlowOutboundMatchesOriginalSelection &&
|
|
2485
|
-
changeFlowReturnMatchesOriginalSelection,
|
|
2486
|
-
[isChangeFlow, changeFlowOutboundMatchesOriginalSelection, changeFlowReturnMatchesOriginalSelection],
|
|
2487
|
-
);
|
|
2488
|
-
|
|
2489
2485
|
const returnOptionsWithFloor = useMemo(() => {
|
|
2490
2486
|
const options = selectedAvailability?.returnOptions ?? [];
|
|
2491
2487
|
if (!isChangeFlow && effectiveChangeFlowReturnUnitFloorPerPerson == null) return options;
|
|
@@ -2493,15 +2489,9 @@ export function BookingFlow({
|
|
|
2493
2489
|
const vacancyCredit = changeFlowSeatCreditForReturnAvailabilityId(opt.returnAvailabilityId);
|
|
2494
2490
|
const adjustedVacancies = Math.max(0, opt.vacancies ?? 0) + vacancyCredit;
|
|
2495
2491
|
const rawPerPerson = opt.priceAdjustmentByCurrency?.[currency] ?? 0;
|
|
2492
|
+
// Floors on return cards only for self-serve; provider sees catalog prices (refunds when cheaper).
|
|
2496
2493
|
const applyReturnFloor =
|
|
2497
|
-
effectiveChangeFlowReturnUnitFloorPerPerson != null &&
|
|
2498
|
-
(
|
|
2499
|
-
// Public self-serve change flow should always display the paid return floor on cards.
|
|
2500
|
-
isCustomerSelfServeChange ||
|
|
2501
|
-
// For non-public paths, only apply floor after itinerary changes.
|
|
2502
|
-
!isChangeFlow ||
|
|
2503
|
-
!changeFlowSameItineraryAsOriginalBooking
|
|
2504
|
-
);
|
|
2494
|
+
effectiveChangeFlowReturnUnitFloorPerPerson != null && isCustomerSelfServeChange;
|
|
2505
2495
|
const flooredPerPerson = applyReturnFloor
|
|
2506
2496
|
? Math.max(rawPerPerson, effectiveChangeFlowReturnUnitFloorPerPerson!)
|
|
2507
2497
|
: rawPerPerson;
|
|
@@ -2519,7 +2509,6 @@ export function BookingFlow({
|
|
|
2519
2509
|
selectedAvailability?.returnOptions,
|
|
2520
2510
|
isChangeFlow,
|
|
2521
2511
|
effectiveChangeFlowReturnUnitFloorPerPerson,
|
|
2522
|
-
changeFlowSameItineraryAsOriginalBooking,
|
|
2523
2512
|
isCustomerSelfServeChange,
|
|
2524
2513
|
currency,
|
|
2525
2514
|
changeFlowSeatCreditForReturnAvailabilityId,
|
|
@@ -2527,7 +2516,7 @@ export function BookingFlow({
|
|
|
2527
2516
|
|
|
2528
2517
|
const selectedReturnOptionWithFloor = useMemo(() => {
|
|
2529
2518
|
if (!selectedReturnOption || !isChangeFlow || effectiveChangeFlowReturnUnitFloorPerPerson == null) return selectedReturnOption;
|
|
2530
|
-
if (!isCustomerSelfServeChange
|
|
2519
|
+
if (!isCustomerSelfServeChange) return selectedReturnOption;
|
|
2531
2520
|
const rawPerPerson = selectedReturnOption.priceAdjustmentByCurrency?.[currency] ?? 0;
|
|
2532
2521
|
const flooredPerPerson = Math.max(rawPerPerson, effectiveChangeFlowReturnUnitFloorPerPerson);
|
|
2533
2522
|
if (flooredPerPerson === rawPerPerson) return selectedReturnOption;
|
|
@@ -2542,29 +2531,15 @@ export function BookingFlow({
|
|
|
2542
2531
|
selectedReturnOption,
|
|
2543
2532
|
isChangeFlow,
|
|
2544
2533
|
effectiveChangeFlowReturnUnitFloorPerPerson,
|
|
2545
|
-
changeFlowSameItineraryAsOriginalBooking,
|
|
2546
2534
|
isCustomerSelfServeChange,
|
|
2547
2535
|
currency,
|
|
2548
2536
|
]);
|
|
2549
2537
|
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
changeFlowSameItineraryAsOriginalBooking &&
|
|
2556
|
-
!isCustomerSelfServeChange
|
|
2557
|
-
) {
|
|
2558
|
-
return selectedReturnOption ?? null;
|
|
2559
|
-
}
|
|
2560
|
-
return selectedReturnOptionWithFloor;
|
|
2561
|
-
}, [
|
|
2562
|
-
isChangeFlow,
|
|
2563
|
-
changeFlowSameItineraryAsOriginalBooking,
|
|
2564
|
-
isCustomerSelfServeChange,
|
|
2565
|
-
selectedReturnOption,
|
|
2566
|
-
selectedReturnOptionWithFloor,
|
|
2567
|
-
]);
|
|
2538
|
+
/** Order-summary return row uses self-serve floors via [selectedReturnOptionWithFloor]; provider stays catalog-only. */
|
|
2539
|
+
const returnOptionForOrderSummary = useMemo(
|
|
2540
|
+
() => selectedReturnOptionWithFloor,
|
|
2541
|
+
[selectedReturnOptionWithFloor],
|
|
2542
|
+
);
|
|
2568
2543
|
const effectiveSelectedPickupVacancies = useMemo(() => {
|
|
2569
2544
|
if (!selectedAvailability) return 0;
|
|
2570
2545
|
const seatCredit = changeFlowSeatCreditForOutboundAvailability(selectedAvailability);
|
|
@@ -4984,7 +4959,9 @@ export function BookingFlow({
|
|
|
4984
4959
|
showCapacity={isAdmin}
|
|
4985
4960
|
extraDiscountPercent={calendarDiscountPercent}
|
|
4986
4961
|
capDiscountBadgesToBookingDate={
|
|
4987
|
-
isChangeFlow &&
|
|
4962
|
+
isChangeFlow &&
|
|
4963
|
+
changeFlowApplyReceiptPaidFloors &&
|
|
4964
|
+
changeFlowTicketBookedUnitPriceByCategory.size > 0
|
|
4988
4965
|
? changeFlowOriginalDate
|
|
4989
4966
|
: null
|
|
4990
4967
|
}
|
|
@@ -5111,7 +5088,11 @@ export function BookingFlow({
|
|
|
5111
5088
|
t={t}
|
|
5112
5089
|
onQuantityChange={handleQuantityChange}
|
|
5113
5090
|
minimumQuantities={changeBookingMinimumQuantities}
|
|
5114
|
-
ticketUnitFloorByCategory={
|
|
5091
|
+
ticketUnitFloorByCategory={
|
|
5092
|
+
isChangeFlow && changeFlowApplyReceiptPaidFloors
|
|
5093
|
+
? changeFlowTicketBookedUnitPriceByCategory
|
|
5094
|
+
: undefined
|
|
5095
|
+
}
|
|
5115
5096
|
/>
|
|
5116
5097
|
)}
|
|
5117
5098
|
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* ## Change-booking pricing — product rules (frontend)
|
|
3
3
|
*
|
|
4
4
|
* Use this file as the **spec checklist** when debating behavior with product; BookingFlow adds **gates** (parent product,
|
|
5
|
-
* channel
|
|
5
|
+
* channel) on top of these formulas.
|
|
6
6
|
*
|
|
7
7
|
* ### 1. When receipt “paid floors” apply
|
|
8
|
-
* Only
|
|
9
|
-
* in BookingFlow).
|
|
8
|
+
* Only **customer self-serve** change flow, when the booking’s **parent catalog product** matches the **loaded product**
|
|
9
|
+
* (`changeFlowApplyReceiptPaidFloors` in BookingFlow). **Provider dashboard** change flow uses **live catalog only** (no
|
|
10
|
+
* floors) so a cheaper date/return yields a lower total / refund via signed balance.
|
|
10
11
|
*
|
|
11
12
|
* ### 2. Tickets (per category)
|
|
12
13
|
* For each category where we can infer an average **unit paid** from the stored receipt:
|
|
@@ -22,15 +23,13 @@
|
|
|
22
23
|
* passengers pay each line’s **live** per-person amount only.
|
|
23
24
|
*
|
|
24
25
|
* ### 4. Return option — **order total / checkout**
|
|
25
|
-
*
|
|
26
|
-
* **per person** = **`max(live catalog return for the selected slot, floor)`**; **row total** = party size × that amount
|
|
27
|
-
* (
|
|
26
|
+
* When §1 floors apply and a per-person return floor exists (API `returnUnitFloorPerPerson` or receipt RETURN lines):
|
|
27
|
+
* **per person** = **`max(live catalog return for the selected slot, floor)`**; **row total** = party size × that amount.
|
|
28
|
+
* Provider dashboard: **live catalog return only** (no floor).
|
|
28
29
|
*
|
|
29
30
|
* ### 5. Return option — **picker UI only** (BookingFlow)
|
|
30
|
-
* **Self-serve:** return
|
|
31
|
-
* **Provider
|
|
32
|
-
* only (floor hidden) until the itinerary changes; after a change, same as self-serve. **Totals** still follow §4 when
|
|
33
|
-
* floors are on.
|
|
31
|
+
* **Self-serve:** return cards use the floored per-person price when a floor exists (aligned with §4).
|
|
32
|
+
* **Provider dashboard:** cards show **catalog** prices only (no floor).
|
|
34
33
|
*
|
|
35
34
|
* ### 6. Quote “new booking” total & balance
|
|
36
35
|
* **FE proposed total** = full cart math (subtotal + tax − promo), cent-rounded; optional **1¢ reconcile** to old receipt
|