@ticketboothapp/booking 1.2.71 → 1.2.72

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.71",
3
+ "version": "1.2.72",
4
4
  "private": false,
5
5
  "sideEffects": [
6
6
  "**/*.css",
@@ -3105,6 +3105,7 @@ export function AdminChangeBookingFlow({
3105
3105
  ticketLineItems: [] as Array<{ category: string; qty: number }>,
3106
3106
  effectiveSubtotal: 0,
3107
3107
  appliedPromoCode: null as string | null,
3108
+ changeBookingPromo: null as { priorAmount?: number } | null,
3108
3109
  });
3109
3110
 
3110
3111
  const promoDiscountFetchKey = useMemo(() => {
@@ -3123,6 +3124,7 @@ export function AdminChangeBookingFlow({
3123
3124
  currency,
3124
3125
  quantitiesSignature,
3125
3126
  String(Math.round(effectiveSubtotal * 100)),
3127
+ lockedPromoCode ? String(Math.round((originalReceipt?.promoAmount ?? 0) * 100)) : '',
3126
3128
  ].join('::');
3127
3129
  }, [
3128
3130
  appliedPromoCode,
@@ -3135,6 +3137,8 @@ export function AdminChangeBookingFlow({
3135
3137
  currency,
3136
3138
  quantitiesSignature,
3137
3139
  effectiveSubtotal,
3140
+ lockedPromoCode,
3141
+ originalReceipt?.promoAmount,
3138
3142
  ]);
3139
3143
 
3140
3144
  promoDiscountParamsRef.current = {
@@ -3142,6 +3146,9 @@ export function AdminChangeBookingFlow({
3142
3146
  ticketLineItems: ticketLineItems.map((l) => ({ category: l.category, qty: l.qty })),
3143
3147
  effectiveSubtotal,
3144
3148
  appliedPromoCode,
3149
+ changeBookingPromo: lockedPromoCode
3150
+ ? { priorAmount: originalReceipt?.promoAmount }
3151
+ : null,
3145
3152
  };
3146
3153
 
3147
3154
  useEffect(() => {
@@ -3161,6 +3168,7 @@ export function AdminChangeBookingFlow({
3161
3168
  ticketLineItems: lines,
3162
3169
  effectiveSubtotal: sub,
3163
3170
  appliedPromoCode: code,
3171
+ changeBookingPromo,
3164
3172
  } = promoDiscountParamsRef.current;
3165
3173
  if (!code || !sel) return;
3166
3174
  const companyId = product.companyId ?? env.COMPANY_ID;
@@ -3178,7 +3186,13 @@ export function AdminChangeBookingFlow({
3178
3186
  currency,
3179
3187
  items,
3180
3188
  sel.dateTime,
3181
- sub
3189
+ sub,
3190
+ changeBookingPromo
3191
+ ? {
3192
+ forBookingChange: true,
3193
+ priorPromoDiscountAmount: changeBookingPromo.priorAmount,
3194
+ }
3195
+ : undefined
3182
3196
  )
3183
3197
  .then((res) => {
3184
3198
  if (cancelled) return;
@@ -3204,7 +3218,7 @@ export function AdminChangeBookingFlow({
3204
3218
 
3205
3219
  // Percentage/fixed promos: tax on discounted amount (promo before GST per CRA guidance).
3206
3220
  // Vouchers and gift cards: tax on full subtotal (voucher discount includes tax on free portion; gift card is payment).
3207
- // Change booking: same as normal — discount from get-promo-discount on the new selection (promo code from booking).
3221
+ // Change booking: get-promo-discount uses forBookingChange + prior promo from receipt so expired codes stay locked (BE).
3208
3222
  const lockedPromoFallbackAmount =
3209
3223
  lockedPromoCode
3210
3224
  ? Math.max(0, originalReceipt?.promoAmount ?? 0)
@@ -2995,6 +2995,8 @@ export function ChangeBookingFlow({
2995
2995
  ticketLineItems: [] as Array<{ category: string; qty: number }>,
2996
2996
  effectiveSubtotal: 0,
2997
2997
  appliedPromoCode: null as string | null,
2998
+ /** Change flow: pass BE stored promo discount for expired / fixed promo locking. */
2999
+ changeBookingPromo: null as { priorAmount?: number } | null,
2998
3000
  });
2999
3001
 
3000
3002
  const promoDiscountFetchKey = useMemo(() => {
@@ -3013,6 +3015,7 @@ export function ChangeBookingFlow({
3013
3015
  currency,
3014
3016
  quantitiesSignature,
3015
3017
  String(Math.round(effectiveSubtotal * 100)),
3018
+ lockedPromoCode ? String(Math.round((originalReceipt?.promoAmount ?? 0) * 100)) : '',
3016
3019
  ].join('::');
3017
3020
  }, [
3018
3021
  appliedPromoCode,
@@ -3025,6 +3028,8 @@ export function ChangeBookingFlow({
3025
3028
  currency,
3026
3029
  quantitiesSignature,
3027
3030
  effectiveSubtotal,
3031
+ lockedPromoCode,
3032
+ originalReceipt?.promoAmount,
3028
3033
  ]);
3029
3034
 
3030
3035
  promoDiscountParamsRef.current = {
@@ -3032,6 +3037,9 @@ export function ChangeBookingFlow({
3032
3037
  ticketLineItems: ticketLineItems.map((l) => ({ category: l.category, qty: l.qty })),
3033
3038
  effectiveSubtotal,
3034
3039
  appliedPromoCode,
3040
+ changeBookingPromo: lockedPromoCode
3041
+ ? { priorAmount: originalReceipt?.promoAmount }
3042
+ : null,
3035
3043
  };
3036
3044
 
3037
3045
  useEffect(() => {
@@ -3051,6 +3059,7 @@ export function ChangeBookingFlow({
3051
3059
  ticketLineItems: lines,
3052
3060
  effectiveSubtotal: sub,
3053
3061
  appliedPromoCode: code,
3062
+ changeBookingPromo,
3054
3063
  } = promoDiscountParamsRef.current;
3055
3064
  if (!code || !sel) return;
3056
3065
  const companyId = product.companyId ?? env.COMPANY_ID;
@@ -3068,7 +3077,13 @@ export function ChangeBookingFlow({
3068
3077
  currency,
3069
3078
  items,
3070
3079
  sel.dateTime,
3071
- sub
3080
+ sub,
3081
+ changeBookingPromo
3082
+ ? {
3083
+ forBookingChange: true,
3084
+ priorPromoDiscountAmount: changeBookingPromo.priorAmount,
3085
+ }
3086
+ : undefined
3072
3087
  )
3073
3088
  .then((res) => {
3074
3089
  if (cancelled) return;
@@ -3094,7 +3109,7 @@ export function ChangeBookingFlow({
3094
3109
 
3095
3110
  // Percentage/fixed promos: tax on discounted amount (promo before GST per CRA guidance).
3096
3111
  // Vouchers and gift cards: tax on full subtotal (voucher discount includes tax on free portion; gift card is payment).
3097
- // Change booking: same as normal discount from get-promo-discount on the new selection (promo code from booking).
3112
+ // Change booking: get-promo-discount uses forBookingChange + receipt prior promo (BE locks expired % / fixed / voucher).
3098
3113
  const lockedPromoFallbackAmount =
3099
3114
  lockedPromoCode
3100
3115
  ? Math.max(0, originalReceipt?.promoAmount ?? 0)
@@ -651,6 +651,13 @@ export interface GetPromoDiscountResponse {
651
651
  isVoucher?: boolean;
652
652
  }
653
653
 
654
+ /** Booking change: server locks discount using stored receipt promo when windows expire / fixed codes. */
655
+ export interface GetPromoDiscountBookingChangeOptions {
656
+ forBookingChange?: boolean;
657
+ /** Stored promo discount from the existing booking (major units, same currency as quote). */
658
+ priorPromoDiscountAmount?: number;
659
+ }
660
+
654
661
  export async function getPromoDiscount(
655
662
  promoCode: string,
656
663
  companyId: string,
@@ -659,7 +666,8 @@ export async function getPromoDiscount(
659
666
  currency: string,
660
667
  items: Array<{ category: string; qty: number }>,
661
668
  dateTime?: string,
662
- subtotal?: number
669
+ subtotal?: number,
670
+ bookingChange?: GetPromoDiscountBookingChangeOptions
663
671
  ): Promise<GetPromoDiscountResponse> {
664
672
  const itemsStr = items.map((i) => `${i.category}:${i.qty}`).join(',');
665
673
  const params = new URLSearchParams({
@@ -672,6 +680,15 @@ export async function getPromoDiscount(
672
680
  });
673
681
  if (dateTime) params.set('dateTime', dateTime);
674
682
  if (subtotal != null && subtotal > 0) params.set('subtotal', String(subtotal));
683
+ if (bookingChange?.forBookingChange === true) {
684
+ params.set('forBookingChange', 'true');
685
+ }
686
+ if (
687
+ bookingChange?.priorPromoDiscountAmount != null &&
688
+ Number.isFinite(bookingChange.priorPromoDiscountAmount)
689
+ ) {
690
+ params.set('priorPromoDiscountAmount', String(bookingChange.priorPromoDiscountAmount));
691
+ }
675
692
  const res = await fetchBookingGetWithRetry(`${API_BASE}/1/get-promo-discount?${params}`);
676
693
  if (!res.ok) {
677
694
  const err = await res.json();