@ticketboothapp/booking 1.2.67 → 1.2.69

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ticketboothapp/booking",
3
- "version": "1.2.67",
3
+ "version": "1.2.69",
4
4
  "private": false,
5
5
  "sideEffects": [
6
6
  "**/*.css",
@@ -823,7 +823,20 @@ export function AdminChangeBookingFlow({
823
823
  }
824
824
  }, [initialValues?.dateTime, companyTimezone]);
825
825
  const isProviderDashboardChange = Boolean(onChangeBooking);
826
- const isCustomerSelfServeChange = !isProviderDashboardChange;
826
+ /** Any change from an existing booking (public or provider). */
827
+ const isChangeBookingContext = Boolean(initialValues?.bookingReference?.trim());
828
+ /**
829
+ * When the provider passes `onChangeBooking` we normally apply the change immediately on checkout.
830
+ * In provider-dashboard + admin + change mode we need the "Pay now / confirm without payment" step
831
+ * first, so we run the public change-intent quote + PI, then call `onChangeBooking` from
832
+ * `handleConfirmWithoutPayment` (or after paying in the checkout modal).
833
+ */
834
+ const deferProviderApplyToAdminPaymentChoice =
835
+ isAdmin &&
836
+ isChangeBookingContext &&
837
+ bookingAppMode === 'provider-dashboard' &&
838
+ isProviderDashboardChange;
839
+ const isCustomerSelfServeChange = !isProviderDashboardChange || deferProviderApplyToAdminPaymentChoice;
827
840
  /** Do not render catalog-/FE-derived dollar amounts in UI until `quoteChangeBooking` returns `serverDisplay`. */
828
841
  const suppressSelfServeCurrencyUi = isCustomerSelfServeChange;
829
842
 
@@ -4463,7 +4476,7 @@ export function AdminChangeBookingFlow({
4463
4476
  return;
4464
4477
  }
4465
4478
 
4466
- if (onChangeBooking) {
4479
+ if (onChangeBooking && !deferProviderApplyToAdminPaymentChoice) {
4467
4480
  const pickupForChange = pickupLocationId
4468
4481
  ? product.pickupLocations?.find((loc) => loc.id === pickupLocationId)
4469
4482
  : null;
@@ -4498,6 +4511,10 @@ export function AdminChangeBookingFlow({
4498
4511
  previousReturnAvailabilityId: initialValues?.returnAvailabilityId ?? null,
4499
4512
  },
4500
4513
  });
4514
+ const refAfterChange = initialValues?.bookingReference?.trim();
4515
+ if (refAfterChange) {
4516
+ onSuccess?.({ reservationReference: refAfterChange });
4517
+ }
4501
4518
  setLoading(false);
4502
4519
  return;
4503
4520
  }
@@ -4924,6 +4941,82 @@ export function AdminChangeBookingFlow({
4924
4941
  setLoading(true);
4925
4942
  setError('');
4926
4943
  try {
4944
+ if (onChangeBooking) {
4945
+ if (!selectedAvailability) {
4946
+ setError('No availability selected');
4947
+ setLoading(false);
4948
+ return;
4949
+ }
4950
+ const bookingItems = Object.entries(quantities)
4951
+ .filter(([, count]) => count > 0)
4952
+ .map(([category, count]) => ({ category, count }));
4953
+ const availabilityProductOptionId =
4954
+ adminChoiceData.availabilityProductOptionId ||
4955
+ selectedAvailability.productOptionId ||
4956
+ activeOptions[0]?.optionId;
4957
+ if (!availabilityProductOptionId) {
4958
+ setError('No product option selected');
4959
+ setLoading(false);
4960
+ return;
4961
+ }
4962
+ const pickupForChange = pickupLocationId
4963
+ ? product.pickupLocations?.find((loc) => loc.id === pickupLocationId)
4964
+ : null;
4965
+ await onChangeBooking({
4966
+ productId: availabilityProductOptionId,
4967
+ dateTime: selectedAvailability.dateTime,
4968
+ bookingItems,
4969
+ returnAvailabilityId: selectedReturnOption?.returnAvailabilityId ?? null,
4970
+ pickupLocationId: pickupLocationId ?? null,
4971
+ travelerHotel: pickupForChange?.name ?? null,
4972
+ startTime: selectedAvailability.dateTime ?? null,
4973
+ passengerCount: null,
4974
+ childSafetySeatsCount: null,
4975
+ foodRestrictions: null,
4976
+ addOnSelections: addOnSelections.length > 0 ? addOnSelections : null,
4977
+ cancellationPolicyId: cancellationPolicyId ?? initialValues?.cancellationPolicyId ?? null,
4978
+ promoCode: appliedPromoCode ?? null,
4979
+ newTotalAmount: displayChangeFlowProposedTotal,
4980
+ additionalHoursCount: null,
4981
+ pricingAdjustment:
4982
+ providerPricingOverrides.length > 0 || providerAdditionalAdjustments.length > 0
4983
+ ? {
4984
+ mode: 'MANUAL_LINES',
4985
+ lineOverrides: providerPricingOverrides,
4986
+ additionalAdjustments: providerAdditionalAdjustments,
4987
+ }
4988
+ : undefined,
4989
+ capacitySeatCredit: {
4990
+ enabled: true,
4991
+ previousPassengerCount: changeFlowInitialTicketCount,
4992
+ previousAvailabilityId: initialValues?.availabilityId ?? null,
4993
+ previousReturnAvailabilityId: initialValues?.returnAvailabilityId ?? null,
4994
+ },
4995
+ });
4996
+ const bookRef = initialValues?.bookingReference?.trim() || adminChoiceData.reservationReference;
4997
+ setShowAdminPaymentChoice(false);
4998
+ setAdminChoiceData(null);
4999
+ onSuccess?.({ reservationReference: bookRef });
5000
+ const ref = formatBookingRefForDisplay(bookRef);
5001
+ const ln = lastName.trim();
5002
+ if (onShowManage) {
5003
+ onShowManage({ ref, lastName: ln });
5004
+ } else {
5005
+ const params = new URLSearchParams({ ref, lastName: ln, booking_complete: '1' });
5006
+ window.location.href = `/manage-booking?${params.toString()}`;
5007
+ }
5008
+ setLoading(false);
5009
+ return;
5010
+ }
5011
+
5012
+ if (isChangeBookingContext) {
5013
+ setError(
5014
+ 'Confirming a booking change without payment requires your dashboard to pass the provider change handler (onChangeBooking). Use Pay now to complete this change, or wire onChangeBooking in the embed.',
5015
+ );
5016
+ setLoading(false);
5017
+ return;
5018
+ }
5019
+
4927
5020
  const bookingSourceContext = buildBookingSourceContext(bookingSourceAttribution, {
4928
5021
  clientChannelSource: inferClientBookingSourceFromProductIds(
4929
5022
  product.productId,