@ticketboothapp/booking 1.2.166 → 1.2.168

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.
Files changed (65) hide show
  1. package/package.json +1 -1
  2. package/src/components/booking/AdminChangeBookingContent.tsx +15 -1
  3. package/src/components/booking/AdminChangeBookingFlow.tsx +274 -94
  4. package/src/components/booking/AdminChangeCheckoutPanel.tsx +49 -13
  5. package/src/components/booking/AdminChangePricingPanel.tsx +400 -134
  6. package/src/components/booking/AdminChangePromoEditor.tsx +97 -0
  7. package/src/components/booking/AdminChangeReceiptComparison.tsx +172 -147
  8. package/src/components/booking/ChangeBookingFlow.tsx +6 -3
  9. package/src/components/booking/ChangeBookingQuoteStatusPlaceholder.tsx +7 -2
  10. package/src/components/booking/ChangeBookingSelectionControlsPanel.tsx +6 -0
  11. package/src/components/booking/ChangeBookingTicketsAndAddOnsPanel.tsx +80 -0
  12. package/src/components/booking/NewBookingFlow.tsx +14 -2
  13. package/src/components/booking/PickupLocationSelector.module.css +22 -0
  14. package/src/components/booking/PickupLocationSelector.tsx +3 -3
  15. package/src/components/booking/PriceBreakdown.tsx +66 -15
  16. package/src/components/booking/PriceSummary.tsx +16 -0
  17. package/src/components/booking/PrivateShuttleBookingFlow.tsx +52 -14
  18. package/src/components/booking/PrivateShuttleCheckoutSection.tsx +95 -54
  19. package/src/components/booking/admin-adjustment-components.ts +44 -0
  20. package/src/components/booking/admin-adjustment-tax-behavior.ts +50 -0
  21. package/src/components/booking/admin-change-flow-state-helpers.ts +10 -0
  22. package/src/components/booking/admin-change-provider-payload.ts +12 -1
  23. package/src/components/booking/admin-change-quote-request-key.ts +41 -1
  24. package/src/components/booking/admin-change-receipt-lines.ts +49 -0
  25. package/src/components/booking/admin-change-v2-quote-request.ts +109 -0
  26. package/src/components/booking/admin-refund-decision-context.ts +122 -0
  27. package/src/components/booking/admin-refund-disposition.ts +71 -2
  28. package/src/components/booking/availability-date-selection.ts +16 -0
  29. package/src/components/booking/booking-flow-types.ts +4 -0
  30. package/src/components/booking/booking-flow.css +5 -0
  31. package/src/components/booking/change-booking-error-message.ts +137 -0
  32. package/src/components/booking/change-booking-flow-helpers.ts +77 -2
  33. package/src/components/booking/change-booking-quote-guards.ts +4 -1
  34. package/src/components/booking/change-booking-quote-state.ts +44 -1
  35. package/src/components/booking/incompatible-add-on-selections.ts +19 -0
  36. package/src/components/booking/private-shuttle-availability.ts +14 -0
  37. package/src/components/booking/private-shuttle-cancellation-policy.ts +9 -0
  38. package/src/components/booking/private-shuttle-checkout-controller.ts +5 -0
  39. package/src/components/booking/private-shuttle-provider-change-runner.ts +21 -0
  40. package/src/components/booking/private-shuttle-reservation-runner.ts +5 -3
  41. package/src/components/booking/provider-dashboard-change-booking.ts +18 -2
  42. package/src/components/booking/use-standard-booking-availability.ts +5 -2
  43. package/src/components/booking/useAdminChangeCheckoutController.ts +56 -1
  44. package/src/components/booking/useAdminChangeProductReset.ts +6 -0
  45. package/src/components/booking/useAdminChangeProtectedPricing.ts +4 -0
  46. package/src/components/booking/useAdminChangeQuoteDisplayState.tsx +8 -6
  47. package/src/components/booking/useAdminChangeQuotePreview.ts +146 -61
  48. package/src/components/booking/useAdminCustomReceiptLines.ts +171 -10
  49. package/src/components/booking/useAdminProviderPricingAdjustments.ts +50 -19
  50. package/src/components/booking/useBookingAvailabilityAddOns.ts +26 -4
  51. package/src/components/booking/useBookingPromoAndQuantityController.ts +16 -2
  52. package/src/components/booking/useChangeBookingAddOnFloorController.ts +15 -9
  53. package/src/components/booking/useChangeBookingAutoSelections.ts +60 -17
  54. package/src/components/booking/useChangeBookingInitialHydration.ts +10 -7
  55. package/src/components/booking/useChangeBookingQuotePreview.ts +3 -1
  56. package/src/components/booking/useChangeBookingSelectionDetails.ts +23 -17
  57. package/src/components/booking/useStandardBookingAutoSelections.ts +55 -7
  58. package/src/lib/booking/booking-cutoffs.ts +22 -0
  59. package/src/lib/booking/change-booking-server-preview.ts +92 -5
  60. package/src/lib/booking/change-flow-pricing.ts +12 -0
  61. package/src/lib/booking/i18n/messages/en.json +1 -0
  62. package/src/lib/booking/i18n/messages/fr.json +1 -0
  63. package/src/lib/booking-api.ts +76 -1
  64. package/test/change-booking-helpers.test.ts +1319 -7
  65. package/src/components/booking/useAdminChangePricingDebugPanel.tsx +0 -178
@@ -3,10 +3,16 @@ import type {
3
3
  ProviderDashboardInitialBooking,
4
4
  } from './provider-dashboard-change-booking';
5
5
  import type { PrivateShuttleAddOnSelection } from './private-shuttle-reservation-runner';
6
+ import {
7
+ buildPrivateShuttleItineraryDisplayForStorage,
8
+ type PrivateShuttleCheckoutItineraryItem,
9
+ } from './private-shuttle-reservation-runner';
6
10
 
7
11
  export interface ApplyPrivateShuttleProviderChangeParams {
8
12
  onChangeBooking: (data: ProviderDashboardChangeBookingPayload) => Promise<void>;
13
+ parentProductId: string;
9
14
  selectedOption: string;
15
+ selectedAvailabilityId?: string | null;
10
16
  selectedDate: string;
11
17
  selectedStartTime: string;
12
18
  billableResourceCount: number;
@@ -22,13 +28,18 @@ export interface ApplyPrivateShuttleProviderChangeParams {
22
28
  activePromoCode: string | null;
23
29
  totalPrice: number;
24
30
  additionalHoursCount: number;
31
+ draftItineraryDestinations: string[];
32
+ draftItineraryPlanningNotes: string;
33
+ itineraryDisplayItems: PrivateShuttleCheckoutItineraryItem[];
25
34
  isAdmin: boolean;
26
35
  providerChangeAuthoritativeReceipt?: ProviderDashboardChangeBookingPayload['authoritativeReceipt'];
27
36
  }
28
37
 
29
38
  export async function applyPrivateShuttleProviderChange({
30
39
  onChangeBooking,
40
+ parentProductId,
31
41
  selectedOption,
42
+ selectedAvailabilityId,
32
43
  selectedDate,
33
44
  selectedStartTime,
34
45
  billableResourceCount,
@@ -44,6 +55,9 @@ export async function applyPrivateShuttleProviderChange({
44
55
  activePromoCode,
45
56
  totalPrice,
46
57
  additionalHoursCount,
58
+ draftItineraryDestinations,
59
+ draftItineraryPlanningNotes,
60
+ itineraryDisplayItems,
47
61
  isAdmin,
48
62
  providerChangeAuthoritativeReceipt,
49
63
  }: ApplyPrivateShuttleProviderChangeParams): Promise<void> {
@@ -52,7 +66,9 @@ export async function applyPrivateShuttleProviderChange({
52
66
  const startTimeISO = `${selectedDate}T${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:00-06:00`;
53
67
 
54
68
  await onChangeBooking({
69
+ parentProductId,
55
70
  productId: selectedOption,
71
+ availabilityId: selectedAvailabilityId ?? null,
56
72
  dateTime: selectedDate,
57
73
  bookingItems,
58
74
  returnAvailabilityId: null,
@@ -60,6 +76,11 @@ export async function applyPrivateShuttleProviderChange({
60
76
  travelerHotel:
61
77
  selectedPickupLocationName ?? customPickupAddress ?? initialBooking?.travelerHotel ?? null,
62
78
  startTime: startTimeISO,
79
+ draftItinerary: {
80
+ destinations: draftItineraryDestinations,
81
+ planningNotes: draftItineraryPlanningNotes.trim(),
82
+ },
83
+ itineraryDisplay: buildPrivateShuttleItineraryDisplayForStorage(itineraryDisplayItems),
63
84
  passengerCount,
64
85
  childSafetySeatsCount: childSafetySeatsCount > 0 ? childSafetySeatsCount : null,
65
86
  foodRestrictions: foodRestrictions.trim() || null,
@@ -84,10 +84,11 @@ export interface ReservePrivateShuttleForCheckoutParams {
84
84
  pricingProfileIdForAvailabilities: string | null;
85
85
  }
86
86
 
87
- function buildPrivateShuttleItineraryDisplayForStorage(
87
+ export function buildPrivateShuttleItineraryDisplayForStorage(
88
88
  itineraryDisplayItems: PrivateShuttleCheckoutItineraryItem[]
89
89
  ): ItineraryDisplayStep[] {
90
- return itineraryDisplayItems.map((item, i) => {
90
+ let hasPickup = false;
91
+ return itineraryDisplayItems.map((item) => {
91
92
  if (item.isProposedStops) {
92
93
  return {
93
94
  stepType: ItineraryStepType.draft,
@@ -95,7 +96,8 @@ function buildPrivateShuttleItineraryDisplayForStorage(
95
96
  place: item.label,
96
97
  };
97
98
  }
98
- const isPickup = i === 0;
99
+ const isPickup = !hasPickup;
100
+ hasPickup = true;
99
101
  return {
100
102
  stepType: isPickup ? ItineraryStepType.pickup : ItineraryStepType.drop_off,
101
103
  time: item.time ?? 'TBD',
@@ -1,5 +1,5 @@
1
1
  import type { Currency } from './CurrencySwitcher';
2
- import type { ItineraryDisplayStep } from '../../lib/booking-api';
2
+ import type { AdminPromoApplicationScope, ItineraryDisplayStep } from '../../lib/booking-api';
3
3
 
4
4
  export type AdminAmendmentAdjustmentMode =
5
5
  | 'FIXED_AMOUNT'
@@ -45,6 +45,10 @@ export type ProviderDashboardChangeBookingPayload = {
45
45
  pickupLocationId?: string | null;
46
46
  travelerHotel?: string | null;
47
47
  startTime?: string | null;
48
+ draftItinerary?: {
49
+ destinations?: string[];
50
+ planningNotes?: string;
51
+ } | null;
48
52
  itineraryDisplay?: ItineraryDisplayStep[] | null;
49
53
  passengerCount?: number | null;
50
54
  childSafetySeatsCount?: number | null;
@@ -52,6 +56,7 @@ export type ProviderDashboardChangeBookingPayload = {
52
56
  addOnSelections?: Array<{ addOnId: string; variantId?: string; quantity?: number }> | null;
53
57
  cancellationPolicyId?: string | null;
54
58
  promoCode?: string | null;
59
+ promoApplicationScope?: AdminPromoApplicationScope | null;
55
60
  newTotalAmount?: number;
56
61
  additionalHoursCount?: number | null;
57
62
  pricingAdjustment?: {
@@ -99,6 +104,8 @@ export type ProviderDashboardChangeBookingPayload = {
99
104
  /** Seeds the flow when opening provider change-booking (matches TicketBooth `BookingWidget` `initialBooking`). */
100
105
  export type ProviderDashboardInitialBooking = {
101
106
  bookingReference: string;
107
+ /** Original parent catalog product id; required when the editor is mounted on a different target family. */
108
+ parentProductId?: string | null;
102
109
  productId: string;
103
110
  availabilityId?: string;
104
111
  dateTime: string;
@@ -111,9 +118,18 @@ export type ProviderDashboardInitialBooking = {
111
118
  pickupLocationId?: string | null;
112
119
  travelerHotel?: string | null;
113
120
  startTime?: string | null;
114
- privateShuttleDetails?: { passengerCount?: number };
121
+ privateShuttleDetails?: {
122
+ passengerCount?: number;
123
+ requestedPassengerCount?: number | null;
124
+ };
115
125
  cancellationPolicyId?: string | null;
116
126
  promoCode?: string | null;
117
127
  additionalHoursCount?: number | null;
118
128
  addOnSelections?: Array<{ addOnId: string; variantId?: string; quantity?: number }> | null;
129
+ customer?: {
130
+ firstName?: string | null;
131
+ lastName?: string | null;
132
+ email?: string | null;
133
+ phoneNumber?: string | null;
134
+ } | null;
119
135
  };
@@ -18,7 +18,10 @@ import {
18
18
  type Product,
19
19
  type ReturnOption,
20
20
  } from '../../lib/booking-api';
21
- import { filterAvailabilitiesAfterPublicBookingCutoff } from '../../lib/booking/booking-cutoffs';
21
+ import {
22
+ filterAvailabilitiesAfterCurrentTime,
23
+ filterAvailabilitiesAfterPublicBookingCutoff,
24
+ } from '../../lib/booking/booking-cutoffs';
22
25
  import { shouldReplacePricingConfig } from '../../lib/booking/pricing-config';
23
26
  import { useAvailabilitiesCache, buildAvailabilitiesCacheKey } from '../../contexts/AvailabilitiesCacheContext';
24
27
  import {
@@ -628,7 +631,7 @@ export function useStandardBookingAvailability({
628
631
  });
629
632
 
630
633
  return isAdmin
631
- ? currentOrFutureAvailabilities
634
+ ? filterAvailabilitiesAfterCurrentTime(currentOrFutureAvailabilities, bookingCutoffNow)
632
635
  : filterAvailabilitiesAfterPublicBookingCutoff(
633
636
  currentOrFutureAvailabilities,
634
637
  bookingCutoffNow,
@@ -12,7 +12,9 @@ import {
12
12
  type AddOn,
13
13
  type AdminAmendmentOperationSnapshot,
14
14
  type AdminAmendmentRefundDisposition,
15
+ type AdminAmendmentActiveAdjustmentSnapshot,
15
16
  type AdminFeAuthoritativeReceipt,
17
+ type AdminPromoApplicationScope,
16
18
  type Availability,
17
19
  type ChangeBookingQuotePricingDriftDetail,
18
20
  type ChangeBookingQuoteTicketPricingTrace,
@@ -41,6 +43,7 @@ import {
41
43
  import type { ChangeBookingFlowProps } from './booking-flow-types';
42
44
  import type { CheckoutModalLineItem } from './CheckoutModal';
43
45
  import type { Currency } from './CurrencySwitcher';
46
+ import type { AdminAdjustmentComponentOption } from './admin-adjustment-components';
44
47
  import {
45
48
  findMergedAvailabilityForSelection,
46
49
  findMergedReturnVacancies,
@@ -67,6 +70,10 @@ import {
67
70
  confirmFreeAdminCustomerChange,
68
71
  quoteAdminCustomerChangeForCheckout,
69
72
  } from './admin-change-customer-quote-runner';
73
+ import {
74
+ buildAdminChangeV2QuoteRequest,
75
+ quoteAdminChangeV2ForUi,
76
+ } from './admin-change-v2-quote-request';
70
77
  import {
71
78
  reservationHoldHasExpired,
72
79
  RESERVATION_HOLD_EXPIRED_MESSAGE,
@@ -86,6 +93,10 @@ export interface AdminChangeLatestQuote {
86
93
  quoteExpiresAt?: string;
87
94
  pricingVersion?: string;
88
95
  quotedTotal?: number;
96
+ amountPreviouslyPaid?: number;
97
+ currentPaymentCreditTotal?: number;
98
+ projectedPaymentCreditTotal?: number;
99
+ refundCandidate?: number;
89
100
  paymentCreditTotal?: number;
90
101
  refundDecisionOperations?: AdminAmendmentOperationSnapshot[];
91
102
  returnPriceTreatmentOperations?: AdminAmendmentOperationSnapshot[];
@@ -95,8 +106,11 @@ export interface AdminChangeLatestQuote {
95
106
  quotePreviousTotalCents?: number;
96
107
  quoteNewTotalCents?: number;
97
108
  serverPreview: ChangeBookingServerPreview;
109
+ authoritativeItineraryDisplay?: ItineraryDisplayStep[] | null;
98
110
  pricingDriftDetail?: ChangeBookingQuotePricingDriftDetail;
99
111
  ticketPricingTrace?: ChangeBookingQuoteTicketPricingTrace | null;
112
+ selectableAdjustmentComponents?: AdminAdjustmentComponentOption[];
113
+ reversibleAdjustments?: AdminAmendmentActiveAdjustmentSnapshot[];
100
114
  }
101
115
 
102
116
  export interface UseAdminChangeCheckoutControllerParams {
@@ -136,10 +150,12 @@ export interface UseAdminChangeCheckoutControllerParams {
136
150
  onChangeBooking?: ChangeBookingFlowProps['onChangeBooking'];
137
151
  cancellationPolicyId: string | null;
138
152
  appliedPromoCode: string | null;
153
+ promoApplicationScope: AdminPromoApplicationScope;
139
154
  displayChangeFlowProposedTotalWithEditableLines: number;
140
155
  providerPricingOverrides: AdminChangeProviderLineOverride[];
141
156
  mergedProviderAdditionalAdjustments: AdminChangeProviderAdditionalAdjustment[];
142
157
  adminStructuredAdjustments: NonNullable<ProviderDashboardChangeBookingPayload['structuredAdjustments']>;
158
+ adminReverseAdjustmentIds: string[];
143
159
  refundDispositionsByOperationId: NonNullable<
144
160
  ProviderDashboardChangeBookingPayload['refundDispositionsByOperationId']
145
161
  >;
@@ -237,10 +253,12 @@ export function useAdminChangeCheckoutController({
237
253
  onChangeBooking,
238
254
  cancellationPolicyId,
239
255
  appliedPromoCode,
256
+ promoApplicationScope,
240
257
  displayChangeFlowProposedTotalWithEditableLines,
241
258
  providerPricingOverrides,
242
259
  mergedProviderAdditionalAdjustments,
243
260
  adminStructuredAdjustments,
261
+ adminReverseAdjustmentIds,
244
262
  refundDispositionsByOperationId,
245
263
  providerApplyAuthoritativeReceipt,
246
264
  onSuccess,
@@ -358,10 +376,12 @@ export function useAdminChangeCheckoutController({
358
376
  cancellationPolicyId,
359
377
  initialCancellationPolicyId: initialValues?.cancellationPolicyId ?? null,
360
378
  appliedPromoCode,
379
+ promoApplicationScope,
361
380
  newTotalAmount: displayChangeFlowProposedTotalWithEditableLines,
362
381
  providerPricingOverrides,
363
382
  mergedProviderAdditionalAdjustments,
364
383
  adminStructuredAdjustments,
384
+ adminReverseAdjustmentIds,
365
385
  refundDispositionsByOperationId,
366
386
  pricingV2QuoteId: authoritativeQuote?.quoteId ?? null,
367
387
  pricingV2QuotedTotal: authoritativeQuote?.quotedTotal ?? authoritativeQuote?.serverDisplay?.total ?? null,
@@ -461,7 +481,42 @@ export function useAdminChangeCheckoutController({
461
481
  let confirmedChangeAmountDueForCheckout: number | null = null;
462
482
  let authoritativeChangeQuoteForCheckout = latestChangeQuote;
463
483
 
464
- if (isCustomerSelfServeChange) {
484
+ if (isProviderDashboardChange && isChangeBookingContext) {
485
+ const bookingReference = initialValues?.bookingReference?.trim();
486
+ if (!bookingReference) throw new Error('Missing booking reference.');
487
+ authoritativeChangeQuoteForCheckout = await quoteAdminChangeV2ForUi(
488
+ buildAdminChangeV2QuoteRequest({
489
+ bookingReference,
490
+ lastName,
491
+ parentProductId: product.productId,
492
+ optionId: availabilityProductOptionId,
493
+ selectedAvailability,
494
+ pickupLocationId,
495
+ returnAvailabilityId: selectedReturnOption?.returnAvailabilityId ?? null,
496
+ bookingItems,
497
+ addOnSelections,
498
+ cancellationPolicyId,
499
+ promoCode: appliedPromoCode,
500
+ promoApplicationScope,
501
+ structuredAdjustments: adminStructuredAdjustments,
502
+ reverseAdjustmentIds: adminReverseAdjustmentIds,
503
+ includeSelectableAdjustmentComponents: adminStructuredAdjustments.some(
504
+ (adjustment) => adjustment.scope === 'SELECTED_COMPONENTS',
505
+ ),
506
+ refundDispositionsByOperationId,
507
+ previousPassengerCount: changeFlowInitialTicketCount,
508
+ previousAvailabilityId: initialValues?.availabilityId ?? null,
509
+ previousReturnAvailabilityId: initialValues?.returnAvailabilityId ?? null,
510
+ }),
511
+ {
512
+ total: changeFlowNewBookingTotal,
513
+ subtotal: effectiveSubtotalForCheckout,
514
+ tax: effectiveTax,
515
+ },
516
+ currency,
517
+ );
518
+ setLatestChangeQuote(authoritativeChangeQuoteForCheckout);
519
+ } else if (isCustomerSelfServeChange) {
465
520
  const quoteResult = await quoteAdminCustomerChangeForCheckout({
466
521
  bookingReference: initialValues?.bookingReference,
467
522
  lastName,
@@ -8,6 +8,7 @@ interface ResetRef {
8
8
 
9
9
  export interface UseAdminChangeProductResetParams {
10
10
  selectedChangeProductId: string;
11
+ setQuantities: Dispatch<SetStateAction<Record<string, number>>>;
11
12
  setSelectedAvailability: Dispatch<SetStateAction<Availability | null>>;
12
13
  setSelectedReturnOption: Dispatch<SetStateAction<ReturnOption | null>>;
13
14
  setAddOns: Dispatch<SetStateAction<AddOn[]>>;
@@ -21,6 +22,7 @@ export interface UseAdminChangeProductResetParams {
21
22
 
22
23
  export function useAdminChangeProductReset({
23
24
  selectedChangeProductId,
25
+ setQuantities,
24
26
  setSelectedAvailability,
25
27
  setSelectedReturnOption,
26
28
  setAddOns,
@@ -36,6 +38,9 @@ export function useAdminChangeProductReset({
36
38
  useEffect(() => {
37
39
  if (previousSelectedChangeProductIdRef.current === selectedChangeProductId) return;
38
40
  previousSelectedChangeProductIdRef.current = selectedChangeProductId;
41
+ // Ticket categories belong to the selected product family. In particular, a private
42
+ // RESOURCE quantity must not survive a switch to a regular ADULT/CHILD/INFANT product.
43
+ setQuantities({});
39
44
  setSelectedAvailability(null);
40
45
  setSelectedReturnOption(null);
41
46
  setAddOns([]);
@@ -47,6 +52,7 @@ export function useAdminChangeProductReset({
47
52
  setError('');
48
53
  }, [
49
54
  selectedChangeProductId,
55
+ setQuantities,
50
56
  setSelectedAvailability,
51
57
  setSelectedReturnOption,
52
58
  setAddOns,
@@ -20,6 +20,7 @@ type AdminCustomReceiptLine = {
20
20
  amountInput: string;
21
21
  amountSign?: number;
22
22
  calculation: 'FIXED_AMOUNT' | 'PERCENTAGE';
23
+ sourceAdjustmentId?: string;
23
24
  };
24
25
 
25
26
  function addOnSelectionTotal(selections: AddOnSelection[] | null | undefined, addOns: AddOn[]): number {
@@ -220,6 +221,9 @@ export function useAdminChangeProtectedPricing({
220
221
  () =>
221
222
  roundMoney(
222
223
  adminCustomReceiptLines.reduce((sum, line) => {
224
+ // Existing ledger adjustments are already included in the persisted receipt. Their
225
+ // edit delta is server-priced as reverse + replace and must not be added again here.
226
+ if (line.sourceAdjustmentId) return sum;
223
227
  if (line.calculation !== 'FIXED_AMOUNT') return sum;
224
228
  const raw = line.amountInput.trim();
225
229
  if (raw === '' || raw === '+' || raw === '-') return sum;
@@ -55,7 +55,7 @@ export interface UseAdminChangeQuoteDisplayStateParams {
55
55
  pickupLocationId: string | null;
56
56
  quantities: Record<string, number>;
57
57
  addOnSelections: AddOnSelection[];
58
- initialAddOnMinQtyByKey: Map<string, number>;
58
+ initialAddOnQtyByKey: Map<string, number>;
59
59
  changeFlowResolvedInitialProductOptionId: string | null;
60
60
  selectedParentProductChanged: boolean;
61
61
  isProviderDashboardChange: boolean;
@@ -65,6 +65,7 @@ export interface UseAdminChangeQuoteDisplayStateParams {
65
65
  editableSummaryPreSubtotalDelta: number;
66
66
  adminCustomAdjustmentTotal: number;
67
67
  adminCustomReceiptLines: AdminCustomReceiptLine[];
68
+ adminReverseAdjustmentIds: string[];
68
69
  isManualOverrideEligibleLine: (line: ProviderDashboardPricingLine) => boolean;
69
70
  isAdmin: boolean;
70
71
  useAdminFeAuthoritativeQuote: boolean;
@@ -99,7 +100,7 @@ export function useAdminChangeQuoteDisplayState({
99
100
  pickupLocationId,
100
101
  quantities,
101
102
  addOnSelections,
102
- initialAddOnMinQtyByKey,
103
+ initialAddOnQtyByKey,
103
104
  changeFlowResolvedInitialProductOptionId,
104
105
  selectedParentProductChanged,
105
106
  isProviderDashboardChange,
@@ -109,6 +110,7 @@ export function useAdminChangeQuoteDisplayState({
109
110
  editableSummaryPreSubtotalDelta,
110
111
  adminCustomAdjustmentTotal,
111
112
  adminCustomReceiptLines,
113
+ adminReverseAdjustmentIds,
112
114
  isManualOverrideEligibleLine,
113
115
  isAdmin,
114
116
  useAdminFeAuthoritativeQuote,
@@ -321,14 +323,14 @@ export function useAdminChangeQuoteDisplayState({
321
323
  pickupLocationId,
322
324
  quantities,
323
325
  addOnSelections,
324
- initialAddOnMinQtyByKey,
326
+ initialAddOnQtyByKey,
325
327
  changeFlowResolvedInitialProductOptionId,
326
328
  productChanged: selectedParentProductChanged,
327
329
  });
328
330
  const hasChangeSelection =
329
- isProviderDashboardChange
331
+ (isProviderDashboardChange
330
332
  ? changeSelectionDetails.hasOperationalChangesFromInitial
331
- : changeSelectionDetails.hasChangesFromInitial;
333
+ : changeSelectionDetails.hasChangesFromInitial) || Boolean(appliedPromoCode);
332
334
 
333
335
  const {
334
336
  providerTotalsPreview,
@@ -344,8 +346,8 @@ export function useAdminChangeQuoteDisplayState({
344
346
  providerQuotedLines,
345
347
  hasChangeSelection,
346
348
  editableSummaryPreSubtotalDelta,
347
- adminCustomAdjustmentTotal,
348
349
  adminCustomReceiptLines,
350
+ adminReverseAdjustmentIds,
349
351
  isManualOverrideEligibleLine,
350
352
  });
351
353