@pisell/private-materials 6.12.197 → 6.12.198

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 (77) hide show
  1. package/build/lowcode/assets-daily.json +11 -11
  2. package/build/lowcode/assets-dev.json +2 -2
  3. package/build/lowcode/assets-prod.json +11 -11
  4. package/build/lowcode/meta.js +1 -1
  5. package/build/lowcode/render/default/view.js +18 -18
  6. package/build/lowcode/view.js +18 -18
  7. package/es/components/bigSale/components/BookingFloatingPanel/useBookingPanelController.js +1 -0
  8. package/es/components/bigSale/components/TimeBar/index.js +1 -0
  9. package/es/components/bigSale/dialog.js +1 -0
  10. package/es/components/bigSale/hooks/useBigSaleContext.js +1 -0
  11. package/es/components/bigSale/hooks/useSelectFloorMapResourceForBigSale.js +1 -0
  12. package/es/components/bigSale/hooks/useSyncBigSaleCartToCds.js +46 -17
  13. package/es/components/bigSale/index.js +1 -0
  14. package/es/components/bigSale/templates/Kiosk/index.js +1 -0
  15. package/es/components/eventBooking/components/bookingAvailabilityCalendar/components/CalendarDate/CalenDateWeek/index.js +5 -1
  16. package/es/components/eventBooking/components/bookingAvailabilityCalendar/components/CalendarDate/index.js +9 -1
  17. package/es/components/eventBooking/components/bookingAvailabilityCalendar/components/SelectDate/index.js +3 -1
  18. package/es/components/eventBooking/components/bookingAvailabilityCalendar/index.d.ts +5 -0
  19. package/es/components/eventBooking/components/bookingAvailabilityCalendar/index.js +2 -1
  20. package/es/components/sharedSecondaryBigSale/SharedSecondaryBigSaleReceiver.js +1 -0
  21. package/es/index.js +2 -0
  22. package/es/plus/pisellReservation/data/bookingToReservationTables.js +1 -1
  23. package/es/plus/pisellReservation/data/reservationDataUtils.js +2 -8
  24. package/es/plus/pisellReservation/floorMap/floorPlanApi.js +1 -1
  25. package/es/plus/pisellReservation/floorMap/reservationMock.js +1 -1
  26. package/es/plus/pisellReservation/index.js +17 -0
  27. package/es/plus/pisellSaleSummaryDetail/index.js +2 -1
  28. package/es/plus/saleDetail/Base.js +1 -0
  29. package/es/plus/saleDetail/components/Client/hooks/useClientSelectorProps.js +1 -0
  30. package/es/plus/saleDetail/components/DetailActions/index.js +1 -0
  31. package/es/plus/saleDetail/components/SummaryFinancialSections/index.js +7 -3
  32. package/es/plus/saleDetail/index.js +1 -0
  33. package/es/plus/saleDetail/tmpl/B/components/Dish/index.js +1 -0
  34. package/es/plus/saleDetail/tmpl/B/components/Pay/index.js +2 -1
  35. package/es/plus/saleDetail/tmpl/B/index.js +1 -0
  36. package/es/plus/saleDetail/utils/paymentStatus.js +15 -0
  37. package/es/plus/salesSdk/index.js +52 -0
  38. package/es/plus/salesSdk/normalProductDetail/NormalProductDetailHostRenderer.js +105 -45
  39. package/es/plus/salesSdk/normalProductDetail/availabilityContextRouting.js +29 -0
  40. package/es/plus/salesSdk/utils/addProductWithFlowDebounced.js +1 -1
  41. package/es/plus/salesSdk/utils/bookingDate.js +1 -1
  42. package/es/plus/salesSdk/utils/customerAuthGate.js +1 -1
  43. package/es/plus/salesSdk/utils/enrichCartLineHolderDisplay.js +1 -1
  44. package/es/pro/Login2.0/AuthModal.d.ts +1 -1
  45. package/es/pro/Login2.0/index.d.ts +2 -1
  46. package/es/pro/Login2.0/shared/types.d.ts +1 -1
  47. package/es/pro/skuDetailModal/flow/modules/date/availabilityWindow.js +71 -0
  48. package/es/pro/skuDetailModal/flow/modules/date/index.js +24 -9
  49. package/es/pro/skuDetailModal/flow/modules/time/index.js +36 -17
  50. package/es/pro/skuDetailModal/flow/modules/time/posCustomTime.js +10 -24
  51. package/es/pro/skuDetailModal/flow/posAutoResolution.js +3 -1
  52. package/es/pro/skuDetailModal/flow/registry.d.ts +2 -2
  53. package/es/pro/skuDetailModal/flow/types.d.ts +8 -0
  54. package/es/pro/skuDetailModal/index.js +50 -12
  55. package/lib/components/bigSale/hooks/useSyncBigSaleCartToCds.js +46 -17
  56. package/lib/components/eventBooking/components/bookingAvailabilityCalendar/components/CalendarDate/CalenDateWeek/index.js +5 -1
  57. package/lib/components/eventBooking/components/bookingAvailabilityCalendar/components/CalendarDate/index.js +9 -1
  58. package/lib/components/eventBooking/components/bookingAvailabilityCalendar/components/SelectDate/index.js +3 -1
  59. package/lib/components/eventBooking/components/bookingAvailabilityCalendar/index.d.ts +5 -0
  60. package/lib/components/eventBooking/components/bookingAvailabilityCalendar/index.js +2 -1
  61. package/lib/plus/pisellReservation/data/reservationDataUtils.js +2 -8
  62. package/lib/plus/pisellSaleSummaryDetail/index.js +2 -1
  63. package/lib/plus/saleDetail/components/SummaryFinancialSections/index.js +6 -3
  64. package/lib/plus/saleDetail/tmpl/B/components/Pay/index.js +2 -1
  65. package/lib/plus/saleDetail/utils/paymentStatus.js +15 -0
  66. package/lib/plus/salesSdk/normalProductDetail/NormalProductDetailHostRenderer.js +105 -45
  67. package/lib/plus/salesSdk/normalProductDetail/availabilityContextRouting.js +32 -0
  68. package/lib/pro/skuDetailModal/flow/modules/date/availabilityWindow.js +74 -0
  69. package/lib/pro/skuDetailModal/flow/modules/date/index.js +24 -9
  70. package/lib/pro/skuDetailModal/flow/modules/time/index.js +39 -20
  71. package/lib/pro/skuDetailModal/flow/modules/time/posCustomTime.js +11 -24
  72. package/lib/pro/skuDetailModal/flow/posAutoResolution.js +4 -0
  73. package/lib/pro/skuDetailModal/flow/registry.d.ts +2 -2
  74. package/lib/pro/skuDetailModal/flow/types.d.ts +8 -0
  75. package/lib/pro/skuDetailModal/index.js +49 -11
  76. package/package.json +2 -2
  77. package/es/private-materials/lowcode/authmodal/meta.d.ts +0 -1
@@ -10,13 +10,14 @@ import { resolveAvailabilityStatus } from "../../../../../components/eventBookin
10
10
  import { findFirstNormallyAvailableDate, validateAvailabilityDateAutoResolution } from "../autoResolution.js";
11
11
  import BookingAvailabilityCalendar from "../../../../../components/eventBooking/components/bookingAvailabilityCalendar/index.js";
12
12
  import MultiDayTimeSelect from "../../../../multiDayTimeSelect/MultiDayTimeSelect.js";
13
+ import { mergeAvailabilityDates, resolveSlidingAvailabilityDateRange } from "./availabilityWindow.js";
13
14
  import dayjs from "dayjs";
14
15
  import React, { useEffect, useMemo, useRef } from "react";
15
16
  import { Alert, DatePicker, Space } from "antd";
16
17
  import { locales } from "@pisell/utils";
17
18
  //#region src/pro/skuDetailModal/flow/modules/date/index.tsx
18
19
  const refreshAvailabilityDates = function() {
19
- var _ref = _asyncToGenerator(function* (context, module) {
20
+ var _ref = _asyncToGenerator(function* (context, module, requestedDateRange) {
20
21
  const availability = context.services.availability;
21
22
  const allowUnavailable = context.services.allowUnavailableBookingSelection === true;
22
23
  const previousData = context.getModuleData(module.key);
@@ -24,11 +25,13 @@ const refreshAvailabilityDates = function() {
24
25
  context.setModuleData(module.key, {
25
26
  requestVersion,
26
27
  status: "loading",
27
- hasResolvedInitialDate: previousData === null || previousData === void 0 ? void 0 : previousData.hasResolvedInitialDate
28
+ hasResolvedInitialDate: previousData === null || previousData === void 0 ? void 0 : previousData.hasResolvedInitialDate,
29
+ availabilityDates: previousData === null || previousData === void 0 ? void 0 : previousData.availabilityDates
28
30
  });
29
31
  context.setModuleStatus(module.key, "loading");
30
32
  try {
31
33
  var _context$getModuleDat;
34
+ if (requestedDateRange && availability.ensureDateRange) yield availability.ensureDateRange(requestedDateRange);
32
35
  const result = yield availability.queryBookingAvailability(availability.contextId, {
33
36
  target: "date",
34
37
  productIds: [availability.productId],
@@ -36,7 +39,8 @@ const refreshAvailabilityDates = function() {
36
39
  });
37
40
  if (((_context$getModuleDat = context.getModuleData(module.key)) === null || _context$getModuleDat === void 0 ? void 0 : _context$getModuleDat.requestVersion) !== requestVersion) return;
38
41
  const group = result.data.find((item) => String(item === null || item === void 0 ? void 0 : item.productId) === String(availability.productId));
39
- const availabilityDates = Array.isArray(group === null || group === void 0 ? void 0 : group.dates) ? group.dates : [];
42
+ const queriedAvailabilityDates = Array.isArray(group === null || group === void 0 ? void 0 : group.dates) ? group.dates : [];
43
+ const availabilityDates = requestedDateRange ? mergeAvailabilityDates(previousData === null || previousData === void 0 ? void 0 : previousData.availabilityDates, queriedAvailabilityDates) : queriedAvailabilityDates;
40
44
  const hasResolvedInitialDate = Boolean(previousData === null || previousData === void 0 ? void 0 : previousData.hasResolvedInitialDate);
41
45
  context.setModuleData(module.key, {
42
46
  requestVersion,
@@ -69,13 +73,15 @@ const refreshAvailabilityDates = function() {
69
73
  context.setModuleData(module.key, {
70
74
  requestVersion,
71
75
  status: "error",
72
- error
76
+ error,
77
+ availabilityDates: previousData === null || previousData === void 0 ? void 0 : previousData.availabilityDates,
78
+ hasResolvedInitialDate: previousData === null || previousData === void 0 ? void 0 : previousData.hasResolvedInitialDate
73
79
  });
74
80
  context.setModuleStatus(module.key, "error", message, error);
75
81
  throw error;
76
82
  }
77
83
  });
78
- return function refreshAvailabilityDates(_x, _x2) {
84
+ return function refreshAvailabilityDates(_x, _x2, _x3) {
79
85
  return _ref.apply(this, arguments);
80
86
  };
81
87
  }();
@@ -139,7 +145,7 @@ const hydrateProductDataForDate = function() {
139
145
  context.setModuleStatus(module.key, "loading");
140
146
  return promise;
141
147
  });
142
- return function hydrateProductDataForDate(_x3, _x4, _x5) {
148
+ return function hydrateProductDataForDate(_x4, _x5, _x6) {
143
149
  return _ref2.apply(this, arguments);
144
150
  };
145
151
  }();
@@ -155,7 +161,7 @@ const awaitLatestDateHydration = function() {
155
161
  }
156
162
  if ((data === null || data === void 0 ? void 0 : data.status) === "error") throw data.error instanceof Error ? data.error : new Error(selectionFlowText("pisell2.text.sku.detail.modal.validation.date.refresh.failed"));
157
163
  });
158
- return function awaitLatestDateHydration(_x6, _x7) {
164
+ return function awaitLatestDateHydration(_x7, _x8) {
159
165
  return _ref3.apply(this, arguments);
160
166
  };
161
167
  }();
@@ -291,7 +297,7 @@ const DateFlowModuleComponent = ({ context, module, registerHandle }) => {
291
297
  });
292
298
  }
293
299
  if (availability) {
294
- if ((availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.status) === "loading" || !(availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.availabilityDates)) return /* @__PURE__ */ React.createElement(SkuDetailLoadingPanel, null);
300
+ if (!(availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.availabilityDates)) return /* @__PURE__ */ React.createElement(SkuDetailLoadingPanel, null);
295
301
  if (availabilityData.status === "error") {
296
302
  var _context$moduleState$2;
297
303
  return /* @__PURE__ */ React.createElement(Alert, {
@@ -306,6 +312,15 @@ const DateFlowModuleComponent = ({ context, module, registerHandle }) => {
306
312
  availabilityDates: availabilityData.availabilityDates,
307
313
  currentDate: (startDate || dayjs()).format("YYYY-MM-DD"),
308
314
  onCurrentDateChange: () => void 0,
315
+ onVisibleDateRangeChange: (visibleRange) => {
316
+ if (!availability.ensureDateRange) return;
317
+ const requestedDateRange = resolveSlidingAvailabilityDateRange({
318
+ availabilityDates: availabilityData.availabilityDates,
319
+ visibleRange
320
+ });
321
+ if (!requestedDateRange) return;
322
+ refreshAvailabilityDates(context, module, requestedDateRange).catch(() => void 0);
323
+ },
309
324
  onDateChange: (value) => {
310
325
  const nextDate = dayjs(value);
311
326
  updateDates(nextDate, nextDate, ["booking.startDate", "booking.endDate"]);
@@ -376,7 +391,7 @@ const dateFlowModule = {
376
391
  yield awaitLatestDateHydration(context, module.key);
377
392
  }
378
393
  });
379
- return function refresh(_x8, _x9) {
394
+ return function refresh(_x9, _x10) {
380
395
  return _ref4.apply(this, arguments);
381
396
  };
382
397
  }(),
@@ -6,12 +6,12 @@ import { getDiscountTime, getServiceTimes, isSessionProduct } from "../../../../
6
6
  import Duration from "../../../../../components/booking/materiels/duration/index.js";
7
7
  import SkuDetailLoadingPanel from "../../../LoadingPanel.js";
8
8
  import { selectionFlowText } from "../../i18n.js";
9
- import { isAvailabilityCandidateSelectable, resolveSelectionFlowQueryPartySize } from "../../availabilityModel.js";
9
+ import { resolveSelectionFlowQueryPartySize } from "../../availabilityModel.js";
10
10
  import { buildDraftCacheItem, getModuleOptions, getUnsupportedBookingFlowReason, isSameCalendarDay, isSameDateValue } from "../shared/index.js";
11
11
  import TimeResourceSelector from "../../../../../components/eventBooking/components/timeResourceSelector/index.js";
12
12
  import { resolveAvailabilityStatus } from "../../../../../components/eventBooking/components/bookingAvailabilityCalendar/utils.js";
13
13
  import { validateAvailabilityTimeAutoResolution } from "../autoResolution.js";
14
- import { getAvailabilityCandidateDurationMinutes, getPosFlexibleDurationPresetCandidates, getSessionPresetCandidates, isFlexibleDurationValue, isSameAvailabilityCandidateRange, resolvePosCustomTimeBaseMinutes, resolvePosCustomTimeCandidate, resolvePosCustomTimeDefaultDurationMinutes, resolvePosCustomTimeDefaultStartTime, resolvePosFlexibleBusinessDurationMinutes, resolvePosFlexibleDurationInitialCandidate, shouldResetPosFlexibleTimeForDate, shouldShowPosCustomTimeCandidateCards } from "./posCustomTime.js";
14
+ import { getAvailabilityCandidateDurationMinutes, getPosFlexibleDurationPresetCandidates, getSessionPresetCandidates, isFlexibleDurationValue, isSameAvailabilityCandidateRange, resolvePosCustomTimeBaseMinutes, resolvePosCustomTimeCandidate, resolvePosCustomTimeDefaultDurationMinutes, resolvePosCustomTimeDefaultStartTime, resolvePosFlexibleDurationInitialCandidate, resolvePosFlexibleDurationRequestIntent, shouldApplyPosFlexibleDurationOverride, shouldResetPosFlexibleTimeForDate, shouldShowPosCustomTimeCandidateCards } from "./posCustomTime.js";
15
15
  import dayjs from "dayjs";
16
16
  import React, { useEffect, useMemo } from "react";
17
17
  import { Alert, Space } from "antd";
@@ -60,6 +60,10 @@ const isAvailabilityDateReadyForTime = (context) => {
60
60
  * 部分响应可能出现 available/limited 但 maxPartySize 为 0 的组合,
61
61
  * 普通端必须按已售罄处理;POS 显式开启超售时仍允许恢复和选择。
62
62
  */
63
+ const isAvailabilityCandidateSelectable = (candidate, allowUnavailable = false) => {
64
+ if (allowUnavailable) return true;
65
+ return (!candidate.status || candidate.status === "available" || candidate.status === "limited") && !(typeof candidate.maxPartySize === "number" && candidate.maxPartySize <= 0);
66
+ };
63
67
  const normalizeDurationMinutesValue = (value) => {
64
68
  if (typeof value === "number") return Number.isFinite(value) && value > 0 ? value : null;
65
69
  if (typeof value === "string") {
@@ -167,16 +171,30 @@ const refreshAvailabilityTimes = function() {
167
171
  const posDurationAvailability = isPosDurationAvailabilityContext(context);
168
172
  const posSessionAvailability = isPosSessionAvailabilityContext(context);
169
173
  const posCustomTimeAvailability = posDurationAvailability || posSessionAvailability;
170
- const requestedDuration = getAvailabilityDurationOverride(context, durationOverride);
171
- const requestedStartTime = getAvailabilityStartTimeOverride(context, startTimeOverride);
174
+ const draftRequestedDuration = getAvailabilityDurationOverride(context, durationOverride);
175
+ const draftRequestedStartTime = getAvailabilityStartTimeOverride(context, startTimeOverride);
172
176
  const selectedDate = context.draft.booking.startDate.format("YYYY-MM-DD");
173
177
  const requestId = Date.now() + Math.random();
174
178
  const previousTimeData = context.getModuleData(module.key);
175
- const posCustomTimeHydrationKey = posCustomTimeAvailability && requestedDuration && requestedStartTime ? `${selectedDate}|${requestedStartTime}|${requestedDuration}` : void 0;
179
+ const posCustomTimeHydrationKey = posCustomTimeAvailability && draftRequestedDuration && draftRequestedStartTime ? `${selectedDate}|${draftRequestedStartTime}|${draftRequestedDuration}` : void 0;
180
+ const product = context.draft.productData;
181
+ const effectiveSelectionIntent = resolvePosFlexibleDurationRequestIntent({
182
+ selectionIntent,
183
+ previousSelectionIntent: previousTimeData === null || previousTimeData === void 0 ? void 0 : previousTimeData.posCustomTimeSelectionIntent,
184
+ hydrationKey: posCustomTimeHydrationKey,
185
+ previousHydrationKey: previousTimeData === null || previousTimeData === void 0 ? void 0 : previousTimeData.posCustomTimeHydrationKey
186
+ });
187
+ const suppressFlexiblePresetOverride = posDurationAvailability && isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration) && !shouldApplyPosFlexibleDurationOverride({
188
+ selectionIntent: effectiveSelectionIntent,
189
+ isEditMode: context.services.selectionFlowMode === "edit"
190
+ });
191
+ const requestedDuration = suppressFlexiblePresetOverride ? void 0 : draftRequestedDuration;
192
+ const requestedStartTime = suppressFlexiblePresetOverride ? void 0 : draftRequestedStartTime;
176
193
  context.setModuleData(module.key, {
177
194
  requestId,
178
195
  timeSlots: [],
179
- posCustomTimeHydrationKey
196
+ posCustomTimeHydrationKey,
197
+ posCustomTimeSelectionIntent: effectiveSelectionIntent === "restore" ? void 0 : effectiveSelectionIntent
180
198
  });
181
199
  const group = (yield availability.getProductTimeRanges(availability.contextId, _objectSpread2({
182
200
  productIds: [availability.productId],
@@ -187,16 +205,15 @@ const refreshAvailabilityTimes = function() {
187
205
  partySize: resolveSelectionFlowQueryPartySize(context.draft, availability.partySize)
188
206
  }, requestedDuration ? _objectSpread2({ durationMinutesByProductId: { [String(availability.productId)]: requestedDuration } }, requestedStartTime ? { durationStartTimesByProductId: { [String(availability.productId)]: [requestedStartTime] } } : {}) : {}))).find((item) => String(item.productId) === String(availability.productId));
189
207
  const candidates = (group === null || group === void 0 ? void 0 : group.ranges) || [];
190
- const product = context.draft.productData;
191
- if (posDurationAvailability && selectionIntent === "restore" && isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration)) {
208
+ if (posDurationAvailability && effectiveSelectionIntent === "restore" && isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration) && candidates.length === 0) {
192
209
  var _context$hostContext, _moduleOptions$slice, _context$draft$bookin2, _normalizeDurationMin3;
193
210
  const moduleOptions = getModuleOptions(module);
194
211
  const configuredSlice = (_context$hostContext = context.hostContext) === null || _context$hostContext === void 0 || (_context$hostContext = _context$hostContext.bookingConfig) === null || _context$hostContext === void 0 || (_context$hostContext = _context$hostContext.config) === null || _context$hostContext === void 0 || (_context$hostContext = _context$hostContext.basic) === null || _context$hostContext === void 0 ? void 0 : _context$hostContext.service_time;
195
212
  const fallbackSlice = (_moduleOptions$slice = moduleOptions.slice) !== null && _moduleOptions$slice !== void 0 ? _moduleOptions$slice : typeof configuredSlice === "object" ? configuredSlice === null || configuredSlice === void 0 ? void 0 : configuredSlice.value : configuredSlice;
196
- const baseDurationMinutes = resolvePosCustomTimeBaseMinutes(group === null || group === void 0 ? void 0 : group.slotStepMinutes, fallbackSlice);
213
+ const baseDurationMinutes = resolvePosCustomTimeBaseMinutes(getProductDurationMinutes(context), group === null || group === void 0 ? void 0 : group.slotStepMinutes, fallbackSlice);
197
214
  const resetForSelectedDate = shouldResetPosFlexibleTimeForDate((_context$draft$bookin2 = context.draft.booking.selectedCandidate) !== null && _context$draft$bookin2 !== void 0 ? _context$draft$bookin2 : previousTimeData === null || previousTimeData === void 0 ? void 0 : previousTimeData.selectedCandidate, selectedDate);
198
215
  const nextStartTime = resolvePosCustomTimeDefaultStartTime(resetForSelectedDate ? null : context.draft.booking.startTime, baseDurationMinutes);
199
- const nextDuration = resolvePosCustomTimeDefaultDurationMinutes(resetForSelectedDate ? product === null || product === void 0 ? void 0 : product.duration : (_normalizeDurationMin3 = normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _normalizeDurationMin3 !== void 0 ? _normalizeDurationMin3 : context.draft.booking.duration, baseDurationMinutes, context.services.selectionFlowMode === "edit" ? void 0 : resolvePosFlexibleBusinessDurationMinutes(nextStartTime, (group === null || group === void 0 ? void 0 : group.operatingEndAt) ? dayjs(group.operatingEndAt).format("HH:mm") : void 0));
216
+ const nextDuration = resolvePosCustomTimeDefaultDurationMinutes(resetForSelectedDate ? product === null || product === void 0 ? void 0 : product.duration : (_normalizeDurationMin3 = normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _normalizeDurationMin3 !== void 0 ? _normalizeDurationMin3 : context.draft.booking.duration, baseDurationMinutes);
200
217
  const changedFields = [];
201
218
  if (nextStartTime !== context.draft.booking.startTime) changedFields.push("booking.startTime");
202
219
  if (nextDuration !== context.draft.booking.duration) changedFields.push("booking.duration");
@@ -229,7 +246,8 @@ const refreshAvailabilityTimes = function() {
229
246
  timeSlots: [],
230
247
  selectedCandidate: void 0,
231
248
  slotStepMinutes: group === null || group === void 0 ? void 0 : group.slotStepMinutes,
232
- posCustomTimeHydrationKey
249
+ posCustomTimeHydrationKey,
250
+ posCustomTimeSelectionIntent: effectiveSelectionIntent === "restore" ? void 0 : effectiveSelectionIntent
233
251
  });
234
252
  return;
235
253
  }
@@ -245,8 +263,8 @@ const refreshAvailabilityTimes = function() {
245
263
  const existingCandidate = context.draft.booking.selectedCandidate;
246
264
  const draftStartTime = normalizeStartTimeValue(context.draft.booking.startTime);
247
265
  const draftEndTime = normalizeStartTimeValue(context.draft.booking.endTime);
248
- const requestedPosStartTime = requestedStartTime || draftStartTime;
249
- const requestedPosDuration = (_ref4 = requestedDuration !== null && requestedDuration !== void 0 ? requestedDuration : normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _ref4 !== void 0 ? _ref4 : getDraftRangeDurationMinutes(context);
266
+ const requestedPosStartTime = suppressFlexiblePresetOverride ? requestedStartTime : requestedStartTime || draftStartTime;
267
+ const requestedPosDuration = suppressFlexiblePresetOverride ? requestedDuration : (_ref4 = requestedDuration !== null && requestedDuration !== void 0 ? requestedDuration : normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _ref4 !== void 0 ? _ref4 : getDraftRangeDurationMinutes(context);
250
268
  const restoredDraftCandidate = draftStartTime ? times.find((candidate) => isAvailabilityCandidateSelectable(candidate, allowUnavailable) && (posSessionAvailability ? isSameAvailabilityCandidateRange(candidate, {
251
269
  date: selectedDate,
252
270
  startTime: draftStartTime,
@@ -262,8 +280,8 @@ const refreshAvailabilityTimes = function() {
262
280
  startTime: requestedPosStartTime,
263
281
  durationMinutes: requestedPosDuration
264
282
  }) : isSameCandidateStart(candidate, selectedDate, requestedPosStartTime)) : void 0;
265
- const customSelectionIntent = posCustomTimeAvailability && selectionIntent === "custom";
266
- const fallbackSelectionIntent = posCustomTimeAvailability && selectionIntent === "fallback";
283
+ const customSelectionIntent = posCustomTimeAvailability && effectiveSelectionIntent === "custom";
284
+ const fallbackSelectionIntent = posCustomTimeAvailability && effectiveSelectionIntent === "fallback";
267
285
  const requestedCustomRange = requestedPosStartTime && requestedPosDuration ? {
268
286
  date: selectedDate,
269
287
  startTime: requestedPosStartTime,
@@ -289,7 +307,7 @@ const refreshAvailabilityTimes = function() {
289
307
  restoredCandidate,
290
308
  fallbackCandidate,
291
309
  preferPreset: preferPosFlexiblePreset,
292
- minimumPresetStartAt: preferPosFlexiblePreset ? dayjs().toISOString() : void 0
310
+ allowRestoredFallback: fallbackSelectionIntent
293
311
  }) : restoredCandidate || fallbackCandidate;
294
312
  context.setModuleData(module.key, {
295
313
  requestId,
@@ -304,7 +322,8 @@ const refreshAvailabilityTimes = function() {
304
322
  candidate
305
323
  })),
306
324
  selectedCandidate: initialCandidate,
307
- posCustomTimeHydrationKey
325
+ posCustomTimeHydrationKey,
326
+ posCustomTimeSelectionIntent: effectiveSelectionIntent === "restore" ? void 0 : effectiveSelectionIntent
308
327
  });
309
328
  const shouldWriteInitialCandidate = Boolean(initialCandidate) && (posCustomTimeAvailability || !existingCandidate || initialCandidate.key !== existingCandidate.key);
310
329
  if (initialCandidate && shouldWriteInitialCandidate) {
@@ -1,6 +1,11 @@
1
- import { isAvailabilityCandidateSelectable } from "../../availabilityModel.js";
2
1
  import dayjs from "dayjs";
3
2
  //#region src/pro/skuDetailModal/flow/modules/time/posCustomTime.ts
3
+ const resolvePosFlexibleDurationRequestIntent = (params) => {
4
+ if (params.selectionIntent !== "restore") return params.selectionIntent;
5
+ if (params.hydrationKey && params.hydrationKey === params.previousHydrationKey && params.previousSelectionIntent) return params.previousSelectionIntent;
6
+ return "restore";
7
+ };
8
+ const shouldApplyPosFlexibleDurationOverride = (params) => params.isEditMode || params.selectionIntent !== "restore";
4
9
  const isFlexibleDurationValue = (value) => {
5
10
  if (typeof value === "string") {
6
11
  const text = value.trim().toLowerCase();
@@ -29,24 +34,9 @@ const resolvePosCustomTimeDefaultStartTime = (currentValue, sliceMinutes, now) =
29
34
  const minutes = alignedMinute % 60;
30
35
  return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
31
36
  };
32
- const resolvePosFlexibleBusinessDurationMinutes = (startTime, closingTime) => {
33
- const toMinuteOfDay = (value) => {
34
- if (typeof value !== "string") return null;
35
- const matched = value.trim().match(/^([01]\d|2[0-3]):([0-5]\d)(?::[0-5]\d)?$/);
36
- if (!matched) return null;
37
- return Number(matched[1]) * 60 + Number(matched[2]);
38
- };
39
- const startMinute = toMinuteOfDay(startTime);
40
- const closingMinute = toMinuteOfDay(closingTime);
41
- if (startMinute === null || closingMinute === null) return null;
42
- const duration = closingMinute > startMinute ? closingMinute - startMinute : closingMinute < startMinute ? closingMinute + 1440 - startMinute : 0;
43
- return duration > 0 ? duration : null;
44
- };
45
37
  const shouldResetPosFlexibleTimeForDate = (candidate, selectedDate) => Boolean(candidate && candidate.date !== selectedDate);
46
- const resolvePosCustomTimeDefaultDurationMinutes = (currentValue, baseDurationMinutes, flexibleDefaultMinutes) => {
38
+ const resolvePosCustomTimeDefaultDurationMinutes = (currentValue, baseDurationMinutes) => {
47
39
  if (isFlexibleDurationValue(currentValue)) {
48
- const flexibleMinutes = Number(flexibleDefaultMinutes);
49
- if (Number.isFinite(flexibleMinutes) && flexibleMinutes > 0) return Math.max(1, Math.floor(flexibleMinutes));
50
40
  if (typeof currentValue === "string") {
51
41
  const flexibleMatch = currentValue.trim().toLowerCase().match(/^flexible_(\d+(?:\.\d+)?)$/);
52
42
  if (flexibleMatch) return Math.max(1, Math.floor(Number(flexibleMatch[1])));
@@ -80,15 +70,11 @@ const getPosFlexibleDurationPresetCandidates = (candidates, requestedCustomRange
80
70
  return candidates.filter((candidate) => !isSameAvailabilityCandidateRange(candidate, requestedCustomRange));
81
71
  };
82
72
  const resolvePosFlexibleDurationInitialCandidate = (params) => {
83
- const minimumPresetStartAt = params.minimumPresetStartAt === void 0 ? null : dayjs(params.minimumPresetStartAt);
84
73
  const firstAvailablePreset = params.presetCandidates.find((candidate) => {
85
- if (!isAvailabilityCandidateSelectable(candidate)) return false;
86
- if (!(minimumPresetStartAt === null || minimumPresetStartAt === void 0 ? void 0 : minimumPresetStartAt.isValid())) return true;
87
- const candidateStartAt = dayjs(candidate.startAt);
88
- return candidateStartAt.isValid() && !candidateStartAt.isBefore(minimumPresetStartAt);
74
+ return (!candidate.status || candidate.status === "available" || candidate.status === "limited") && !(typeof candidate.maxPartySize === "number" && candidate.maxPartySize <= 0);
89
75
  });
90
- if (params.preferPreset && firstAvailablePreset) return firstAvailablePreset;
76
+ if (params.preferPreset) return firstAvailablePreset || (params.allowRestoredFallback ? params.restoredCandidate : void 0);
91
77
  return params.restoredCandidate || params.fallbackCandidate;
92
78
  };
93
79
  //#endregion
94
- export { getAvailabilityCandidateDurationMinutes, getPosFlexibleDurationPresetCandidates, getSessionPresetCandidates, isFlexibleDurationValue, isSameAvailabilityCandidateRange, resolvePosCustomTimeBaseMinutes, resolvePosCustomTimeCandidate, resolvePosCustomTimeDefaultDurationMinutes, resolvePosCustomTimeDefaultStartTime, resolvePosFlexibleBusinessDurationMinutes, resolvePosFlexibleDurationInitialCandidate, shouldResetPosFlexibleTimeForDate, shouldShowPosCustomTimeCandidateCards };
80
+ export { getAvailabilityCandidateDurationMinutes, getPosFlexibleDurationPresetCandidates, getSessionPresetCandidates, isFlexibleDurationValue, isSameAvailabilityCandidateRange, resolvePosCustomTimeBaseMinutes, resolvePosCustomTimeCandidate, resolvePosCustomTimeDefaultDurationMinutes, resolvePosCustomTimeDefaultStartTime, resolvePosFlexibleDurationInitialCandidate, resolvePosFlexibleDurationRequestIntent, shouldApplyPosFlexibleDurationOverride, shouldResetPosFlexibleTimeForDate, shouldShowPosCustomTimeCandidateCards };
@@ -24,5 +24,7 @@ const getPosAutoResolutionDraftKey = (draft) => {
24
24
  });
25
25
  };
26
26
  const shouldDirectlyConfirmPosSelectionFlow = ({ eligible, status, currentStepIndex }) => eligible && status === "resolved" && currentStepIndex === 0;
27
+ const shouldPreparePosSelectionFlowOnConfirm = ({ eligible, currentStepIndex, abandoned }) => eligible && currentStepIndex === 0 && !abandoned;
28
+ const isCurrentPosAutoResolutionRun = ({ expectedRunId, currentRunId, expectedOpenTaskId, currentOpenTaskId, expectedDraftKey, currentDraftKey, abandoned, currentStepIndex }) => expectedRunId === currentRunId && expectedOpenTaskId === currentOpenTaskId && expectedDraftKey === currentDraftKey && !abandoned && currentStepIndex === 0;
27
29
  //#endregion
28
- export { getPosAutoResolutionDraftKey, isPosCreateAutoResolutionCandidate, shouldDirectlyConfirmPosSelectionFlow };
30
+ export { getPosAutoResolutionDraftKey, isCurrentPosAutoResolutionRun, isPosCreateAutoResolutionCandidate, shouldDirectlyConfirmPosSelectionFlow, shouldPreparePosSelectionFlowOnConfirm };
@@ -35,7 +35,7 @@ declare const flowModuleRegistry: {
35
35
  Component: _$react.FC<FlowModuleProps<string>>;
36
36
  initializeWhileInactive: true;
37
37
  hardRequires: ("productData" | "booking.selectedCandidate")[];
38
- refreshOn: ("productData" | "skuValue" | "quantity" | "booking.customerId" | "booking.duration" | "booking.selectedCandidate")[];
38
+ refreshOn: ("productData" | "quantity" | "skuValue" | "booking.customerId" | "booking.duration" | "booking.selectedCandidate")[];
39
39
  isApplicable: (context: _$_pisell_materials_src0.SelectionFlowContextValue<SelectionFlowDraft, SelectionFlowDraftUpdate, SelectionDraftField, string, SelectionFlowServices, unknown>) => boolean;
40
40
  canInitialize: (context: _$_pisell_materials_src0.SelectionFlowContextValue<SelectionFlowDraft, SelectionFlowDraftUpdate, SelectionDraftField, string, SelectionFlowServices, unknown>) => boolean;
41
41
  refresh: (context: SelectionFlowContextValue<string>, module: CompiledSelectionFlowModuleConfig<string>) => Promise<void>;
@@ -52,7 +52,7 @@ declare const flowModuleRegistry: {
52
52
  Component: _$react.FC<FlowModuleProps<string>>;
53
53
  provides: "booking.capacity"[];
54
54
  hardRequires: "productData"[];
55
- refreshOn: ("productData" | "skuValue" | "quantity")[];
55
+ refreshOn: ("productData" | "quantity" | "skuValue")[];
56
56
  isApplicable: (context: _$_pisell_materials_src0.SelectionFlowContextValue<SelectionFlowDraft, SelectionFlowDraftUpdate, SelectionDraftField, "capacity", SelectionFlowServices, unknown>) => boolean;
57
57
  canInitialize: () => true;
58
58
  refresh: (context: _$_pisell_materials_src0.SelectionFlowContextValue<SelectionFlowDraft, SelectionFlowDraftUpdate, SelectionDraftField, "capacity", SelectionFlowServices, unknown>, module: _$_pisell_materials_src0.CompiledSelectionFlowModuleConfig<"capacity">) => void;
@@ -163,6 +163,14 @@ interface SelectionFlowAvailabilityService {
163
163
  contextId: string;
164
164
  productId: number | string;
165
165
  partySize: number;
166
+ /**
167
+ * 日历浏览超出当前投影时,按新的可视日期窗口准备一个 Availability context。
168
+ * Host 负责复用已覆盖该范围的 context,并保留仍可能被当前选择引用的旧 context。
169
+ */
170
+ ensureDateRange?: (dateRange: {
171
+ startDate: string;
172
+ endDate: string;
173
+ }) => Promise<void>;
166
174
  getProductTimeRanges: (contextId: string, request: Record<string, unknown>) => Promise<Array<{
167
175
  productId: number | string;
168
176
  title?: string;
@@ -37,7 +37,7 @@ import { flowModuleRegistry } from "./flow/registry.js";
37
37
  import SkuDetailSelectionFlowView from "./flow/SkuDetailSelectionFlowView.js";
38
38
  import { isSkuOnlyDraftChange } from "./flow/isSkuOnlyDraftChange.js";
39
39
  import { getLateQuantityReviewStepIndex, revalidateBookingSelectionAfterQuantityChange } from "./flow/revalidateBookingSelection.js";
40
- import { getPosAutoResolutionDraftKey, isPosCreateAutoResolutionCandidate, shouldDirectlyConfirmPosSelectionFlow } from "./flow/posAutoResolution.js";
40
+ import { getPosAutoResolutionDraftKey, isCurrentPosAutoResolutionRun, isPosCreateAutoResolutionCandidate, shouldDirectlyConfirmPosSelectionFlow, shouldPreparePosSelectionFlowOnConfirm } from "./flow/posAutoResolution.js";
41
41
  import dayjs from "dayjs";
42
42
  import React, { forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
43
43
  import { locales } from "@pisell/utils";
@@ -134,7 +134,7 @@ const resolveInitialAvailabilityCandidate = (source, startDate, endDate, startTi
134
134
  if (endDate && candidateEndDate && candidateEndDate !== endDate.format("YYYY-MM-DD")) return;
135
135
  return rawCandidate;
136
136
  };
137
- const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChange, isShowNote, isShowRemove, confirmLabel, isConfirmDisabled = false, isManualPriceChangeDisabled = false, hidePrimaryActions = false, onCancel, onRemove, onManualPriceChange, onOpenNote, onConfirm }) => {
137
+ const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChange, isShowNote, isShowRemove, confirmLabel, isConfirmDisabled = false, isConfirmLoading = false, isManualPriceChangeDisabled = false, hidePrimaryActions = false, onCancel, onRemove, onManualPriceChange, onOpenNote, onConfirm }) => {
138
138
  const auxiliaryActions = [isShowNote ? /* @__PURE__ */ React.createElement(Button, {
139
139
  key: "note",
140
140
  type: "default",
@@ -166,6 +166,7 @@ const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChan
166
166
  type: "primary",
167
167
  size: "large",
168
168
  disabled: isConfirmDisabled,
169
+ loading: isConfirmLoading,
169
170
  onClick: onConfirm,
170
171
  className: "sku-detail-side-actions-btn sku-detail-side-actions-confirm-btn"
171
172
  }, /* @__PURE__ */ React.createElement("span", { className: "sku-detail-content-footer-confirm-btn-text" }, confirmLabel))) : null);
@@ -241,8 +242,10 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
241
242
  const [selectionFlowProcedureSteps, setSelectionFlowProcedureSteps] = useState(null);
242
243
  const [compiledSelectionFlowSteps, setCompiledSelectionFlowSteps] = useState(null);
243
244
  const [posAutoResolutionStatus, setPosAutoResolutionStatus] = useState("idle");
245
+ const [posAutoResolutionConfirmPending, setPosAutoResolutionConfirmPending] = useState(false);
244
246
  const posAutoResolutionRunRef = useRef(0);
245
247
  const posAutoResolutionAbandonedRef = useRef(false);
248
+ const posAutoResolutionConfirmPendingRunRef = useRef(null);
246
249
  const [effectiveSelectionFlowSteps, setEffectiveSelectionFlowSteps] = useState(void 0);
247
250
  const [skuDetailConfig, setSkuDetailConfig] = useState({
248
251
  isShowProductSummary: false,
@@ -804,6 +807,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
804
807
  latestSelectionFlowDraftRef.current = null;
805
808
  posAutoResolutionRunRef.current += 1;
806
809
  posAutoResolutionAbandonedRef.current = false;
810
+ posAutoResolutionConfirmPendingRunRef.current = null;
811
+ setPosAutoResolutionConfirmPending(false);
807
812
  setPosAutoResolutionStatus("idle");
808
813
  setEffectiveSelectionFlowSteps(void 0);
809
814
  setNoteModalOpen(false);
@@ -1315,6 +1320,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
1315
1320
  latestSelectionFlowDraftRef.current = null;
1316
1321
  posAutoResolutionRunRef.current += 1;
1317
1322
  posAutoResolutionAbandonedRef.current = false;
1323
+ posAutoResolutionConfirmPendingRunRef.current = null;
1324
+ setPosAutoResolutionConfirmPending(false);
1318
1325
  setPosAutoResolutionStatus("idle");
1319
1326
  setCurrentStep(0);
1320
1327
  lateQuantityReviewStepIndexRef.current = null;
@@ -1326,6 +1333,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
1326
1333
  lateQuantityReviewStepIndexRef.current = null;
1327
1334
  lateQuantityRevalidationTaskRef.current = null;
1328
1335
  posAutoResolutionRunRef.current += 1;
1336
+ posAutoResolutionConfirmPendingRunRef.current = null;
1337
+ setPosAutoResolutionConfirmPending(false);
1329
1338
  setOpen(false);
1330
1339
  setDetailLoading(false);
1331
1340
  setNoteModalOpen(false);
@@ -1345,20 +1354,48 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
1345
1354
  var _snapshot$currentStep;
1346
1355
  const flow = selectionFlowRef.current;
1347
1356
  if (!flow) return false;
1348
- if (canDirectlyConfirmPosSelectionFlow) {
1357
+ const currentFlowStepIndex = flow.getState().currentStepIndex;
1358
+ if (shouldPreparePosSelectionFlowOnConfirm({
1359
+ eligible: isPosCreateAutoResolutionEligible,
1360
+ currentStepIndex: currentFlowStepIndex,
1361
+ abandoned: posAutoResolutionAbandonedRef.current
1362
+ })) {
1363
+ if (posAutoResolutionConfirmPendingRunRef.current !== null) return false;
1349
1364
  const openTaskId = openTaskIdRef.current;
1350
1365
  const draftKey = getPosAutoResolutionDraftKey(flow.getState().draft);
1351
1366
  const runId = posAutoResolutionRunRef.current + 1;
1352
1367
  posAutoResolutionRunRef.current = runId;
1353
- const result = yield flow.prepareSteps({ fromStepIndex: 1 });
1354
- if (posAutoResolutionRunRef.current !== runId || openTaskIdRef.current !== openTaskId || posAutoResolutionAbandonedRef.current || getPosAutoResolutionDraftKey(flow.getState().draft) !== draftKey) return false;
1355
- if (!result.prepared || result.cancelled) {
1356
- setPosAutoResolutionStatus("retained");
1357
- return false;
1368
+ posAutoResolutionConfirmPendingRunRef.current = runId;
1369
+ setPosAutoResolutionConfirmPending(true);
1370
+ setPosAutoResolutionStatus("checking");
1371
+ try {
1372
+ const result = yield flow.prepareSteps({ fromStepIndex: 1 });
1373
+ if (!isCurrentPosAutoResolutionRun({
1374
+ expectedRunId: runId,
1375
+ currentRunId: posAutoResolutionRunRef.current,
1376
+ expectedOpenTaskId: openTaskId,
1377
+ currentOpenTaskId: openTaskIdRef.current,
1378
+ expectedDraftKey: draftKey,
1379
+ currentDraftKey: getPosAutoResolutionDraftKey(flow.getState().draft),
1380
+ abandoned: posAutoResolutionAbandonedRef.current,
1381
+ currentStepIndex: flow.getState().currentStepIndex
1382
+ }) || result.cancelled) return false;
1383
+ if (!result.prepared) {
1384
+ posAutoResolutionAbandonedRef.current = true;
1385
+ posAutoResolutionRunRef.current += 1;
1386
+ setPosAutoResolutionStatus("retained");
1387
+ return (yield flow.next()) || false;
1388
+ }
1389
+ setPosAutoResolutionStatus("resolved");
1390
+ const completed = yield flow.complete();
1391
+ if (!completed && openTaskIdRef.current === openTaskId && posAutoResolutionRunRef.current === runId) setPosAutoResolutionStatus("retained");
1392
+ return completed;
1393
+ } finally {
1394
+ if (posAutoResolutionConfirmPendingRunRef.current === runId) {
1395
+ posAutoResolutionConfirmPendingRunRef.current = null;
1396
+ setPosAutoResolutionConfirmPending(false);
1397
+ }
1358
1398
  }
1359
- const completed = yield flow.complete();
1360
- if (!completed && openTaskIdRef.current === openTaskId && posAutoResolutionRunRef.current === runId) setPosAutoResolutionStatus("retained");
1361
- return completed;
1362
1399
  }
1363
1400
  if (isPosCreateAutoResolutionEligible) {
1364
1401
  posAutoResolutionAbandonedRef.current = true;
@@ -1775,8 +1812,9 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
1775
1812
  isShowNote: !!(skuDetailConfig === null || skuDetailConfig === void 0 ? void 0 : skuDetailConfig.isShowNote),
1776
1813
  isShowRemove: (skuDetailConfig === null || skuDetailConfig === void 0 ? void 0 : skuDetailConfig.isShowRemove) !== false,
1777
1814
  confirmLabel: pcConfirmButtonText,
1815
+ isConfirmLoading: posAutoResolutionConfirmPending,
1778
1816
  isManualPriceChangeDisabled: !canOpenManualPriceChange,
1779
- isConfirmDisabled: hasReachedBookingPriceStep && (selectionFlowBookingPricePending || selectionFlowBookingPriceError),
1817
+ isConfirmDisabled: posAutoResolutionConfirmPending || hasReachedBookingPriceStep && (selectionFlowBookingPricePending || selectionFlowBookingPriceError),
1780
1818
  onCancel: handleCancel,
1781
1819
  onRemove: handleRemove,
1782
1820
  onManualPriceChange: handleManualPriceChange,
@@ -251,15 +251,18 @@ const buildCdsProductPayload = (cartLine, params) => {
251
251
  return payload;
252
252
  };
253
253
  const buildCartUpdatePayload = (context, params) => {
254
- var _context$summary, _context$sales, _summary$product_orig, _summary$total_amount, _summary$expect_amoun;
254
+ var _context$summary, _context$sales, _context$sales2, _bookingTicket$getOrd, _amountSnapshot$summa, _bookingTicket$getTem, _summary$product_orig, _context$cart, _ref, _amountSnapshot$total, _amountSnapshot$summa2, _amountSnapshot$summa3;
255
255
  const cartLines = getCartProductLines(context === null || context === void 0 ? void 0 : context.cart);
256
256
  if (!cartLines.length) return require_objectSpread2._objectSpread2({ currency_symbol: params.currencySymbol }, EMPTY_CART_UPDATE);
257
257
  const products = cartLines.map((cartLine) => buildCdsProductPayload(cartLine, params));
258
- const summary = (_context$summary = context.summary) === null || _context$summary === void 0 ? void 0 : _context$summary.summary;
258
+ const contextSummary = (_context$summary = context.summary) === null || _context$summary === void 0 ? void 0 : _context$summary.summary;
259
259
  const tempOrder = (_context$sales = context.sales) === null || _context$sales === void 0 ? void 0 : _context$sales.tempOrder;
260
- const payments = tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.payments;
260
+ const bookingTicket = (_context$sales2 = context.sales) === null || _context$sales2 === void 0 ? void 0 : _context$sales2.bookingTicket;
261
+ const amountSnapshot = bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getOrd = bookingTicket.getOrderAmountSnapshot) === null || _bookingTicket$getOrd === void 0 ? void 0 : _bookingTicket$getOrd.call(bookingTicket);
262
+ const summary = (_amountSnapshot$summa = amountSnapshot === null || amountSnapshot === void 0 ? void 0 : amountSnapshot.summary) !== null && _amountSnapshot$summa !== void 0 ? _amountSnapshot$summa : contextSummary;
263
+ const currentTempOrder = (bookingTicket === null || bookingTicket === void 0 || (_bookingTicket$getTem = bookingTicket.getTempOrder) === null || _bookingTicket$getTem === void 0 ? void 0 : _bookingTicket$getTem.call(bookingTicket)) || tempOrder;
264
+ const payments = currentTempOrder === null || currentTempOrder === void 0 ? void 0 : currentTempOrder.payments;
261
265
  const isTaxIncluded = Number(tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.is_price_include_tax) === 1;
262
- const hasPendingWalletPayment = toArray(payments).some(isPendingWalletPayment);
263
266
  const cartProducts = cartLines.map((cartLine) => cartLine.product);
264
267
  const fees = [
265
268
  {
@@ -281,7 +284,8 @@ const buildCartUpdatePayload = (context, params) => {
281
284
  type: "tax"
282
285
  });
283
286
  }
284
- fees.push(...collectOrderPassFees(tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.discount_list));
287
+ const cartOrderPassFees = collectOrderPassFees(context === null || context === void 0 || (_context$cart = context.cart) === null || _context$cart === void 0 ? void 0 : _context$cart.discountList);
288
+ fees.push(...cartOrderPassFees.length ? cartOrderPassFees : collectOrderPassFees(tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.discount_list));
285
289
  if (toFiniteNumber(tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.shop_discount) > 0) fees.push({
286
290
  isReduce: true,
287
291
  title: callLocaleText("pisell2.sale-detail.manual-order-adjustment"),
@@ -289,15 +293,16 @@ const buildCartUpdatePayload = (context, params) => {
289
293
  type: "order_discount"
290
294
  });
291
295
  fees.push(...collectWalletPaymentFees(payments, params.locale));
292
- const effectiveAmountDue = hasPendingWalletPayment ? require_utils.resolveEffectiveSaleDetailAmountDue({
296
+ const effectiveAmountDue = require_utils.resolveEffectiveSaleDetailAmountDue({
297
+ baseSalesAmountGap: amountSnapshot === null || amountSnapshot === void 0 ? void 0 : amountSnapshot.amountGap,
293
298
  amountGap: summary === null || summary === void 0 ? void 0 : summary.amount_gap,
294
- fallbackAmount: (_summary$total_amount = summary === null || summary === void 0 ? void 0 : summary.total_amount) !== null && _summary$total_amount !== void 0 ? _summary$total_amount : summary === null || summary === void 0 ? void 0 : summary.expect_amount,
295
- orderPaidAmount: summary === null || summary === void 0 ? void 0 : summary.order_paid_amount,
299
+ fallbackAmount: (_ref = (_amountSnapshot$total = amountSnapshot === null || amountSnapshot === void 0 ? void 0 : amountSnapshot.totalAmount) !== null && _amountSnapshot$total !== void 0 ? _amountSnapshot$total : summary === null || summary === void 0 ? void 0 : summary.total_amount) !== null && _ref !== void 0 ? _ref : summary === null || summary === void 0 ? void 0 : summary.expect_amount,
300
+ orderPaidAmount: (_amountSnapshot$summa2 = amountSnapshot === null || amountSnapshot === void 0 || (_amountSnapshot$summa3 = amountSnapshot.summary) === null || _amountSnapshot$summa3 === void 0 ? void 0 : _amountSnapshot$summa3.order_paid_amount) !== null && _amountSnapshot$summa2 !== void 0 ? _amountSnapshot$summa2 : summary === null || summary === void 0 ? void 0 : summary.order_paid_amount,
296
301
  payments
297
- }) : null;
302
+ });
298
303
  return {
299
304
  currency_symbol: params.currencySymbol,
300
- total: effectiveAmountDue !== null ? effectiveAmountDue.toFixed(2) : (_summary$expect_amoun = summary === null || summary === void 0 ? void 0 : summary.expect_amount) !== null && _summary$expect_amoun !== void 0 ? _summary$expect_amoun : "0",
305
+ total: effectiveAmountDue.toFixed(2),
301
306
  products,
302
307
  fees
303
308
  };
@@ -306,7 +311,7 @@ const buildCartUpdatePayload = (context, params) => {
306
311
  * Standard 大促模板购物车变更时,向 Native CDS 同步购物车快照。
307
312
  */
308
313
  function useSyncBigSaleCartToCds(context, options = {}) {
309
- var _context$cart, _context$cart2, _context$cart3, _context$summary2, _context$sales2, _context$sales3, _context$sales4;
314
+ var _context$cart2, _context$cart3, _context$cart4, _context$cart5, _context$summary2, _context$sales3, _context$sales4, _context$sales5, _context$sales7;
310
315
  const engineContext = require_useEngineContext.default();
311
316
  const { enabled = true } = options;
312
317
  (0, react.useEffect)(() => {
@@ -319,13 +324,37 @@ function useSyncBigSaleCartToCds(context, options = {}) {
319
324
  locale
320
325
  }));
321
326
  }, [
322
- context === null || context === void 0 || (_context$cart = context.cart) === null || _context$cart === void 0 ? void 0 : _context$cart.bookings,
323
- context === null || context === void 0 || (_context$cart2 = context.cart) === null || _context$cart2 === void 0 ? void 0 : _context$cart2.displayLines,
324
- context === null || context === void 0 || (_context$cart3 = context.cart) === null || _context$cart3 === void 0 ? void 0 : _context$cart3.items,
327
+ context === null || context === void 0 || (_context$cart2 = context.cart) === null || _context$cart2 === void 0 ? void 0 : _context$cart2.bookings,
328
+ context === null || context === void 0 || (_context$cart3 = context.cart) === null || _context$cart3 === void 0 ? void 0 : _context$cart3.discountList,
329
+ context === null || context === void 0 || (_context$cart4 = context.cart) === null || _context$cart4 === void 0 ? void 0 : _context$cart4.displayLines,
330
+ context === null || context === void 0 || (_context$cart5 = context.cart) === null || _context$cart5 === void 0 ? void 0 : _context$cart5.items,
325
331
  context === null || context === void 0 || (_context$summary2 = context.summary) === null || _context$summary2 === void 0 ? void 0 : _context$summary2.summary,
326
- context === null || context === void 0 || (_context$sales2 = context.sales) === null || _context$sales2 === void 0 ? void 0 : _context$sales2.tempOrder,
327
- context === null || context === void 0 || (_context$sales3 = context.sales) === null || _context$sales3 === void 0 || (_context$sales3 = _context$sales3.tempOrder) === null || _context$sales3 === void 0 ? void 0 : _context$sales3.payments,
328
- context === null || context === void 0 || (_context$sales4 = context.sales) === null || _context$sales4 === void 0 ? void 0 : _context$sales4.bookingTicket,
332
+ context === null || context === void 0 || (_context$sales3 = context.sales) === null || _context$sales3 === void 0 ? void 0 : _context$sales3.tempOrder,
333
+ context === null || context === void 0 || (_context$sales4 = context.sales) === null || _context$sales4 === void 0 || (_context$sales4 = _context$sales4.tempOrder) === null || _context$sales4 === void 0 ? void 0 : _context$sales4.payments,
334
+ context === null || context === void 0 || (_context$sales5 = context.sales) === null || _context$sales5 === void 0 ? void 0 : _context$sales5.bookingTicket,
335
+ engineContext,
336
+ enabled
337
+ ]);
338
+ (0, react.useEffect)(() => {
339
+ var _context$sales6, _engineContext$appHel2;
340
+ if (!enabled) return void 0;
341
+ const bookingTicket = context === null || context === void 0 || (_context$sales6 = context.sales) === null || _context$sales6 === void 0 ? void 0 : _context$sales6.bookingTicket;
342
+ if (!bookingTicket || typeof bookingTicket.effectsOn !== "function") return;
343
+ const utils = (engineContext === null || engineContext === void 0 || (_engineContext$appHel2 = engineContext.appHelper) === null || _engineContext$appHel2 === void 0 ? void 0 : _engineContext$appHel2.utils) || {};
344
+ const off = bookingTicket.effectsOn("onTempOrderReplaced", () => {
345
+ var _bookingTicket$getTem2;
346
+ const tempOrder = (_bookingTicket$getTem2 = bookingTicket.getTempOrder) === null || _bookingTicket$getTem2 === void 0 ? void 0 : _bookingTicket$getTem2.call(bookingTicket);
347
+ if (!tempOrder) return;
348
+ if (toArray(tempOrder.products).length > 0 || toArray(tempOrder.bookings).length > 0) return;
349
+ postCartUpdateToCds(utils, require_objectSpread2._objectSpread2({ currency_symbol: getCurrencySymbol(utils) }, EMPTY_CART_UPDATE));
350
+ });
351
+ return () => {
352
+ try {
353
+ off();
354
+ } catch (_unused) {}
355
+ };
356
+ }, [
357
+ context === null || context === void 0 || (_context$sales7 = context.sales) === null || _context$sales7 === void 0 ? void 0 : _context$sales7.bookingTicket,
329
358
  engineContext,
330
359
  enabled
331
360
  ]);
@@ -14,7 +14,7 @@ classnames = require_runtime.__toESM(classnames);
14
14
  require("./index.less");
15
15
  //#region src/components/eventBooking/components/bookingAvailabilityCalendar/components/CalendarDate/CalenDateWeek/index.tsx
16
16
  const CalenDateWeek = (props) => {
17
- const { currentDate, dateChange, productId, timeList, dateLimitData, getLimitData, cutTime, showStatusBar = true, showDisabledStatus = true, ignoreAvailabilityDisabled = false, enforceAvailabilitySelection = false, minSelectableDate, minViewDate, enableRangeSelection = false, selectedRangeStartDate, selectedRangeEndDate, showMonthHeader = false, enableSwipeNavigation = false, disableCallToBook = false, navigationVariant = "default" } = props;
17
+ const { currentDate, dateChange, productId, timeList, dateLimitData, getLimitData, cutTime, showStatusBar = true, showDisabledStatus = true, ignoreAvailabilityDisabled = false, enforceAvailabilitySelection = false, minSelectableDate, minViewDate, enableRangeSelection = false, selectedRangeStartDate, selectedRangeEndDate, showMonthHeader = false, enableSwipeNavigation = false, disableCallToBook = false, navigationVariant = "default", onVisibleDateRangeChange } = props;
18
18
  const [weekList, setWeekList] = (0, react.useState)([]);
19
19
  const [weekAnchorDate, setWeekAnchorDate] = (0, react.useState)(currentDate);
20
20
  const [pendingWeekList, setPendingWeekList] = (0, react.useState)(null);
@@ -166,6 +166,10 @@ const CalenDateWeek = (props) => {
166
166
  if (pendingWeekAnchorDate && pendingWeekList) {
167
167
  setWeekAnchorDate(pendingWeekAnchorDate);
168
168
  setWeekList(pendingWeekList);
169
+ onVisibleDateRangeChange === null || onVisibleDateRangeChange === void 0 || onVisibleDateRangeChange({
170
+ startDate: pendingWeekList[0],
171
+ endDate: pendingWeekList[pendingWeekList.length - 1]
172
+ });
169
173
  }
170
174
  setPendingWeekAnchorDate(null);
171
175
  setPendingWeekList(null);