@ticketboothapp/booking 1.2.86 → 1.2.87

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.86",
3
+ "version": "1.2.87",
4
4
  "private": false,
5
5
  "sideEffects": [
6
6
  "**/*.css",
@@ -142,6 +142,41 @@ function omitZeroAmountPromoDiscountSummaryLines(lines: PriceSummaryLine[]): Pri
142
142
  });
143
143
  }
144
144
 
145
+ /**
146
+ * `serverPreview.priceSummaryLines` tracks the last quote response; ticket row qty can lag the picker until debounced quote
147
+ * completes. Align ticket rows to live {@link quantities} and rescale line total proportionally (same idea as admin
148
+ * `mapSummaryLinesToFeReceiptLineItems`); tax-included reconcile then aligns euros to display total.
149
+ */
150
+ function resolveTicketQtyFromQuantities(
151
+ category: string,
152
+ quantities: Record<string, number>,
153
+ ): number | undefined {
154
+ const c = category.trim();
155
+ if (Object.prototype.hasOwnProperty.call(quantities, c)) return quantities[c];
156
+ const up = c.toUpperCase();
157
+ for (const [key, val] of Object.entries(quantities)) {
158
+ if (key.toUpperCase() === up) return val;
159
+ }
160
+ return undefined;
161
+ }
162
+
163
+ function mergePickerTicketQtyIntoPriceSummaryLines(
164
+ lines: PriceSummaryLine[],
165
+ quantities: Record<string, number>,
166
+ ): PriceSummaryLine[] {
167
+ return lines.map((line) => {
168
+ if (line.kind !== 'ticket') return line;
169
+ const uiQty = resolveTicketQtyFromQuantities(line.category, quantities);
170
+ const lineQty = Math.max(0, Number(line.qty) || 0);
171
+ const effectiveQty = uiQty != null && uiQty >= 0 ? Math.round(uiQty) : lineQty;
172
+ let itemTotal = roundMoney(line.itemTotal);
173
+ if (lineQty > 0 && effectiveQty !== lineQty) {
174
+ itemTotal = roundMoney((line.itemTotal * effectiveQty) / lineQty);
175
+ }
176
+ return { ...line, qty: Math.max(0, effectiveQty), itemTotal };
177
+ });
178
+ }
179
+
145
180
  function formatTicketLineItemsForSummary(lines: Array<{ category: string; qty: number }>): string {
146
181
  const labels: Record<string, string> = {
147
182
  ADULT: 'adult',
@@ -2963,7 +2998,10 @@ export function ChangeBookingFlow({
2963
2998
  let raw: PriceSummaryLine[];
2964
2999
  if (suppressSelfServeCurrencyUi && selfServePricingConfirmed) {
2965
3000
  const serverLines = latestChangeQuote?.serverPreview?.priceSummaryLines;
2966
- raw = serverLines && serverLines.length > 0 ? serverLines : checkoutPriceSummaryLines;
3001
+ raw =
3002
+ serverLines && serverLines.length > 0
3003
+ ? mergePickerTicketQtyIntoPriceSummaryLines(serverLines, quantities)
3004
+ : checkoutPriceSummaryLines;
2967
3005
  } else {
2968
3006
  raw = checkoutPriceSummaryLines;
2969
3007
  }
@@ -2973,6 +3011,7 @@ export function ChangeBookingFlow({
2973
3011
  selfServePricingConfirmed,
2974
3012
  checkoutPriceSummaryLines,
2975
3013
  latestChangeQuote?.serverPreview?.priceSummaryLines,
3014
+ quantities,
2976
3015
  ]);
2977
3016
 
2978
3017
  /** Receipt/server lines already include {@link PriceSummary}'s TAX row — do not also pass `taxAmount` or it duplicates. */