@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
@@ -0,0 +1,74 @@
1
+ const require_runtime = require("../../../../../_virtual/_rolldown/runtime.js");
2
+ let dayjs = require("dayjs");
3
+ dayjs = require_runtime.__toESM(dayjs);
4
+ //#region src/pro/skuDetailModal/flow/modules/date/availabilityWindow.ts
5
+ const AVAILABILITY_RANGE_EDGE_DAYS = 7;
6
+ const AVAILABILITY_RANGE_PRELOAD_DAYS = 28;
7
+ const MAX_AVAILABILITY_RANGE_DAYS = 90;
8
+ const normalizeRange = (range) => {
9
+ const start = (0, dayjs.default)(range.startDate);
10
+ const end = (0, dayjs.default)(range.endDate);
11
+ if (!start.isValid() || !end.isValid()) return null;
12
+ return start.isAfter(end, "day") ? {
13
+ startDate: end.format("YYYY-MM-DD"),
14
+ endDate: start.format("YYYY-MM-DD")
15
+ } : {
16
+ startDate: start.format("YYYY-MM-DD"),
17
+ endDate: end.format("YYYY-MM-DD")
18
+ };
19
+ };
20
+ const resolveAvailabilityDatesCoverage = (dates) => {
21
+ const normalizedDates = (dates || []).map((item) => (0, dayjs.default)(item === null || item === void 0 ? void 0 : item.date)).filter((date) => date.isValid()).sort((left, right) => left.valueOf() - right.valueOf());
22
+ if (normalizedDates.length === 0) return null;
23
+ return {
24
+ startDate: normalizedDates[0].format("YYYY-MM-DD"),
25
+ endDate: normalizedDates[normalizedDates.length - 1].format("YYYY-MM-DD")
26
+ };
27
+ };
28
+ const inclusiveDays = (range) => (0, dayjs.default)(range.endDate).diff((0, dayjs.default)(range.startDate), "day") + 1;
29
+ /**
30
+ * 日历只在接近当前缓存边缘时向外扩展。能与现有覆盖合并且不超过 UBS
31
+ * 90 天上限时优先扩展;跨度更大时围绕用户正在查看的范围移动窗口。
32
+ */
33
+ const resolveSlidingAvailabilityDateRange = (params) => {
34
+ const visibleRange = normalizeRange(params.visibleRange);
35
+ const coverage = resolveAvailabilityDatesCoverage(params.availabilityDates);
36
+ if (!visibleRange || !coverage) return null;
37
+ const visibleStart = (0, dayjs.default)(visibleRange.startDate);
38
+ const visibleEnd = (0, dayjs.default)(visibleRange.endDate);
39
+ const coverageStart = (0, dayjs.default)(coverage.startDate);
40
+ const coverageEnd = (0, dayjs.default)(coverage.endDate);
41
+ const beforeStart = visibleStart.isBefore(coverageStart, "day");
42
+ const nearEnd = visibleEnd.isAfter(coverageEnd.subtract(AVAILABILITY_RANGE_EDGE_DAYS, "day"), "day");
43
+ if (!beforeStart && !nearEnd) return null;
44
+ const browsingForward = !beforeStart;
45
+ const requestedStart = browsingForward ? coverageStart : visibleStart.subtract(AVAILABILITY_RANGE_PRELOAD_DAYS, "day");
46
+ const requestedEnd = browsingForward ? visibleEnd.add(AVAILABILITY_RANGE_PRELOAD_DAYS, "day") : coverageEnd;
47
+ const mergedRange = normalizeRange({
48
+ startDate: requestedStart.format("YYYY-MM-DD"),
49
+ endDate: requestedEnd.format("YYYY-MM-DD")
50
+ });
51
+ if (inclusiveDays(mergedRange) <= MAX_AVAILABILITY_RANGE_DAYS) return mergedRange;
52
+ if (browsingForward) {
53
+ const endDate = requestedEnd;
54
+ return {
55
+ startDate: endDate.subtract(MAX_AVAILABILITY_RANGE_DAYS - 1, "day").format("YYYY-MM-DD"),
56
+ endDate: endDate.format("YYYY-MM-DD")
57
+ };
58
+ }
59
+ const startDate = requestedStart;
60
+ return {
61
+ startDate: startDate.format("YYYY-MM-DD"),
62
+ endDate: startDate.add(MAX_AVAILABILITY_RANGE_DAYS - 1, "day").format("YYYY-MM-DD")
63
+ };
64
+ };
65
+ const mergeAvailabilityDates = (previousDates, nextDates) => {
66
+ const byDate = /* @__PURE__ */ new Map();
67
+ [...previousDates || [], ...nextDates].forEach((item) => {
68
+ if (typeof (item === null || item === void 0 ? void 0 : item.date) === "string" && (0, dayjs.default)(item.date).isValid()) byDate.set(item.date, item);
69
+ });
70
+ return Array.from(byDate.values()).sort((left, right) => (0, dayjs.default)(left.date).valueOf() - (0, dayjs.default)(right.date).valueOf());
71
+ };
72
+ //#endregion
73
+ exports.mergeAvailabilityDates = mergeAvailabilityDates;
74
+ exports.resolveSlidingAvailabilityDateRange = resolveSlidingAvailabilityDateRange;
@@ -11,6 +11,7 @@ const require_utils$2 = require("../../../../../components/eventBooking/componen
11
11
  const require_autoResolution = require("../autoResolution.js");
12
12
  const require_index$1 = require("../../../../../components/eventBooking/components/bookingAvailabilityCalendar/index.js");
13
13
  const require_MultiDayTimeSelect = require("../../../../multiDayTimeSelect/MultiDayTimeSelect.js");
14
+ const require_availabilityWindow = require("./availabilityWindow.js");
14
15
  let dayjs = require("dayjs");
15
16
  dayjs = require_runtime.__toESM(dayjs);
16
17
  let react = require("react");
@@ -19,7 +20,7 @@ let antd = require("antd");
19
20
  let _pisell_utils = require("@pisell/utils");
20
21
  //#region src/pro/skuDetailModal/flow/modules/date/index.tsx
21
22
  const refreshAvailabilityDates = function() {
22
- var _ref = require_asyncToGenerator._asyncToGenerator(function* (context, module) {
23
+ var _ref = require_asyncToGenerator._asyncToGenerator(function* (context, module, requestedDateRange) {
23
24
  const availability = context.services.availability;
24
25
  const allowUnavailable = context.services.allowUnavailableBookingSelection === true;
25
26
  const previousData = context.getModuleData(module.key);
@@ -27,11 +28,13 @@ const refreshAvailabilityDates = function() {
27
28
  context.setModuleData(module.key, {
28
29
  requestVersion,
29
30
  status: "loading",
30
- hasResolvedInitialDate: previousData === null || previousData === void 0 ? void 0 : previousData.hasResolvedInitialDate
31
+ hasResolvedInitialDate: previousData === null || previousData === void 0 ? void 0 : previousData.hasResolvedInitialDate,
32
+ availabilityDates: previousData === null || previousData === void 0 ? void 0 : previousData.availabilityDates
31
33
  });
32
34
  context.setModuleStatus(module.key, "loading");
33
35
  try {
34
36
  var _context$getModuleDat;
37
+ if (requestedDateRange && availability.ensureDateRange) yield availability.ensureDateRange(requestedDateRange);
35
38
  const result = yield availability.queryBookingAvailability(availability.contextId, {
36
39
  target: "date",
37
40
  productIds: [availability.productId],
@@ -39,7 +42,8 @@ const refreshAvailabilityDates = function() {
39
42
  });
40
43
  if (((_context$getModuleDat = context.getModuleData(module.key)) === null || _context$getModuleDat === void 0 ? void 0 : _context$getModuleDat.requestVersion) !== requestVersion) return;
41
44
  const group = result.data.find((item) => String(item === null || item === void 0 ? void 0 : item.productId) === String(availability.productId));
42
- const availabilityDates = Array.isArray(group === null || group === void 0 ? void 0 : group.dates) ? group.dates : [];
45
+ const queriedAvailabilityDates = Array.isArray(group === null || group === void 0 ? void 0 : group.dates) ? group.dates : [];
46
+ const availabilityDates = requestedDateRange ? require_availabilityWindow.mergeAvailabilityDates(previousData === null || previousData === void 0 ? void 0 : previousData.availabilityDates, queriedAvailabilityDates) : queriedAvailabilityDates;
43
47
  const hasResolvedInitialDate = Boolean(previousData === null || previousData === void 0 ? void 0 : previousData.hasResolvedInitialDate);
44
48
  context.setModuleData(module.key, {
45
49
  requestVersion,
@@ -72,13 +76,15 @@ const refreshAvailabilityDates = function() {
72
76
  context.setModuleData(module.key, {
73
77
  requestVersion,
74
78
  status: "error",
75
- error
79
+ error,
80
+ availabilityDates: previousData === null || previousData === void 0 ? void 0 : previousData.availabilityDates,
81
+ hasResolvedInitialDate: previousData === null || previousData === void 0 ? void 0 : previousData.hasResolvedInitialDate
76
82
  });
77
83
  context.setModuleStatus(module.key, "error", message, error);
78
84
  throw error;
79
85
  }
80
86
  });
81
- return function refreshAvailabilityDates(_x, _x2) {
87
+ return function refreshAvailabilityDates(_x, _x2, _x3) {
82
88
  return _ref.apply(this, arguments);
83
89
  };
84
90
  }();
@@ -142,7 +148,7 @@ const hydrateProductDataForDate = function() {
142
148
  context.setModuleStatus(module.key, "loading");
143
149
  return promise;
144
150
  });
145
- return function hydrateProductDataForDate(_x3, _x4, _x5) {
151
+ return function hydrateProductDataForDate(_x4, _x5, _x6) {
146
152
  return _ref2.apply(this, arguments);
147
153
  };
148
154
  }();
@@ -158,7 +164,7 @@ const awaitLatestDateHydration = function() {
158
164
  }
159
165
  if ((data === null || data === void 0 ? void 0 : data.status) === "error") throw data.error instanceof Error ? data.error : new Error(require_i18n.selectionFlowText("pisell2.text.sku.detail.modal.validation.date.refresh.failed"));
160
166
  });
161
- return function awaitLatestDateHydration(_x6, _x7) {
167
+ return function awaitLatestDateHydration(_x7, _x8) {
162
168
  return _ref3.apply(this, arguments);
163
169
  };
164
170
  }();
@@ -294,7 +300,7 @@ const DateFlowModuleComponent = ({ context, module, registerHandle }) => {
294
300
  });
295
301
  }
296
302
  if (availability) {
297
- if ((availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.status) === "loading" || !(availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.availabilityDates)) return /* @__PURE__ */ react.default.createElement(require_LoadingPanel.default, null);
303
+ if (!(availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.availabilityDates)) return /* @__PURE__ */ react.default.createElement(require_LoadingPanel.default, null);
298
304
  if (availabilityData.status === "error") {
299
305
  var _context$moduleState$2;
300
306
  return /* @__PURE__ */ react.default.createElement(antd.Alert, {
@@ -309,6 +315,15 @@ const DateFlowModuleComponent = ({ context, module, registerHandle }) => {
309
315
  availabilityDates: availabilityData.availabilityDates,
310
316
  currentDate: (startDate || (0, dayjs.default)()).format("YYYY-MM-DD"),
311
317
  onCurrentDateChange: () => void 0,
318
+ onVisibleDateRangeChange: (visibleRange) => {
319
+ if (!availability.ensureDateRange) return;
320
+ const requestedDateRange = require_availabilityWindow.resolveSlidingAvailabilityDateRange({
321
+ availabilityDates: availabilityData.availabilityDates,
322
+ visibleRange
323
+ });
324
+ if (!requestedDateRange) return;
325
+ refreshAvailabilityDates(context, module, requestedDateRange).catch(() => void 0);
326
+ },
312
327
  onDateChange: (value) => {
313
328
  const nextDate = (0, dayjs.default)(value);
314
329
  updateDates(nextDate, nextDate, ["booking.startDate", "booking.endDate"]);
@@ -379,7 +394,7 @@ const dateFlowModule = {
379
394
  yield awaitLatestDateHydration(context, module.key);
380
395
  }
381
396
  });
382
- return function refresh(_x8, _x9) {
397
+ return function refresh(_x9, _x10) {
383
398
  return _ref4.apply(this, arguments);
384
399
  };
385
400
  }(),
@@ -64,6 +64,10 @@ const isAvailabilityDateReadyForTime = (context) => {
64
64
  * 部分响应可能出现 available/limited 但 maxPartySize 为 0 的组合,
65
65
  * 普通端必须按已售罄处理;POS 显式开启超售时仍允许恢复和选择。
66
66
  */
67
+ const isAvailabilityCandidateSelectable = (candidate, allowUnavailable = false) => {
68
+ if (allowUnavailable) return true;
69
+ return (!candidate.status || candidate.status === "available" || candidate.status === "limited") && !(typeof candidate.maxPartySize === "number" && candidate.maxPartySize <= 0);
70
+ };
67
71
  const normalizeDurationMinutesValue = (value) => {
68
72
  if (typeof value === "number") return Number.isFinite(value) && value > 0 ? value : null;
69
73
  if (typeof value === "string") {
@@ -171,16 +175,30 @@ const refreshAvailabilityTimes = function() {
171
175
  const posDurationAvailability = isPosDurationAvailabilityContext(context);
172
176
  const posSessionAvailability = isPosSessionAvailabilityContext(context);
173
177
  const posCustomTimeAvailability = posDurationAvailability || posSessionAvailability;
174
- const requestedDuration = getAvailabilityDurationOverride(context, durationOverride);
175
- const requestedStartTime = getAvailabilityStartTimeOverride(context, startTimeOverride);
178
+ const draftRequestedDuration = getAvailabilityDurationOverride(context, durationOverride);
179
+ const draftRequestedStartTime = getAvailabilityStartTimeOverride(context, startTimeOverride);
176
180
  const selectedDate = context.draft.booking.startDate.format("YYYY-MM-DD");
177
181
  const requestId = Date.now() + Math.random();
178
182
  const previousTimeData = context.getModuleData(module.key);
179
- const posCustomTimeHydrationKey = posCustomTimeAvailability && requestedDuration && requestedStartTime ? `${selectedDate}|${requestedStartTime}|${requestedDuration}` : void 0;
183
+ const posCustomTimeHydrationKey = posCustomTimeAvailability && draftRequestedDuration && draftRequestedStartTime ? `${selectedDate}|${draftRequestedStartTime}|${draftRequestedDuration}` : void 0;
184
+ const product = context.draft.productData;
185
+ const effectiveSelectionIntent = require_posCustomTime.resolvePosFlexibleDurationRequestIntent({
186
+ selectionIntent,
187
+ previousSelectionIntent: previousTimeData === null || previousTimeData === void 0 ? void 0 : previousTimeData.posCustomTimeSelectionIntent,
188
+ hydrationKey: posCustomTimeHydrationKey,
189
+ previousHydrationKey: previousTimeData === null || previousTimeData === void 0 ? void 0 : previousTimeData.posCustomTimeHydrationKey
190
+ });
191
+ const suppressFlexiblePresetOverride = posDurationAvailability && require_posCustomTime.isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration) && !require_posCustomTime.shouldApplyPosFlexibleDurationOverride({
192
+ selectionIntent: effectiveSelectionIntent,
193
+ isEditMode: context.services.selectionFlowMode === "edit"
194
+ });
195
+ const requestedDuration = suppressFlexiblePresetOverride ? void 0 : draftRequestedDuration;
196
+ const requestedStartTime = suppressFlexiblePresetOverride ? void 0 : draftRequestedStartTime;
180
197
  context.setModuleData(module.key, {
181
198
  requestId,
182
199
  timeSlots: [],
183
- posCustomTimeHydrationKey
200
+ posCustomTimeHydrationKey,
201
+ posCustomTimeSelectionIntent: effectiveSelectionIntent === "restore" ? void 0 : effectiveSelectionIntent
184
202
  });
185
203
  const group = (yield availability.getProductTimeRanges(availability.contextId, require_objectSpread2._objectSpread2({
186
204
  productIds: [availability.productId],
@@ -191,16 +209,15 @@ const refreshAvailabilityTimes = function() {
191
209
  partySize: require_availabilityModel.resolveSelectionFlowQueryPartySize(context.draft, availability.partySize)
192
210
  }, requestedDuration ? require_objectSpread2._objectSpread2({ durationMinutesByProductId: { [String(availability.productId)]: requestedDuration } }, requestedStartTime ? { durationStartTimesByProductId: { [String(availability.productId)]: [requestedStartTime] } } : {}) : {}))).find((item) => String(item.productId) === String(availability.productId));
193
211
  const candidates = (group === null || group === void 0 ? void 0 : group.ranges) || [];
194
- const product = context.draft.productData;
195
- if (posDurationAvailability && selectionIntent === "restore" && require_posCustomTime.isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration)) {
212
+ if (posDurationAvailability && effectiveSelectionIntent === "restore" && require_posCustomTime.isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration) && candidates.length === 0) {
196
213
  var _context$hostContext, _moduleOptions$slice, _context$draft$bookin2, _normalizeDurationMin3;
197
214
  const moduleOptions = require_index$1.getModuleOptions(module);
198
215
  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;
199
216
  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;
200
- const baseDurationMinutes = require_posCustomTime.resolvePosCustomTimeBaseMinutes(group === null || group === void 0 ? void 0 : group.slotStepMinutes, fallbackSlice);
217
+ const baseDurationMinutes = require_posCustomTime.resolvePosCustomTimeBaseMinutes(getProductDurationMinutes(context), group === null || group === void 0 ? void 0 : group.slotStepMinutes, fallbackSlice);
201
218
  const resetForSelectedDate = require_posCustomTime.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);
202
219
  const nextStartTime = require_posCustomTime.resolvePosCustomTimeDefaultStartTime(resetForSelectedDate ? null : context.draft.booking.startTime, baseDurationMinutes);
203
- const nextDuration = require_posCustomTime.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 : require_posCustomTime.resolvePosFlexibleBusinessDurationMinutes(nextStartTime, (group === null || group === void 0 ? void 0 : group.operatingEndAt) ? (0, dayjs.default)(group.operatingEndAt).format("HH:mm") : void 0));
220
+ const nextDuration = require_posCustomTime.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);
204
221
  const changedFields = [];
205
222
  if (nextStartTime !== context.draft.booking.startTime) changedFields.push("booking.startTime");
206
223
  if (nextDuration !== context.draft.booking.duration) changedFields.push("booking.duration");
@@ -233,7 +250,8 @@ const refreshAvailabilityTimes = function() {
233
250
  timeSlots: [],
234
251
  selectedCandidate: void 0,
235
252
  slotStepMinutes: group === null || group === void 0 ? void 0 : group.slotStepMinutes,
236
- posCustomTimeHydrationKey
253
+ posCustomTimeHydrationKey,
254
+ posCustomTimeSelectionIntent: effectiveSelectionIntent === "restore" ? void 0 : effectiveSelectionIntent
237
255
  });
238
256
  return;
239
257
  }
@@ -249,14 +267,14 @@ const refreshAvailabilityTimes = function() {
249
267
  const existingCandidate = context.draft.booking.selectedCandidate;
250
268
  const draftStartTime = normalizeStartTimeValue(context.draft.booking.startTime);
251
269
  const draftEndTime = normalizeStartTimeValue(context.draft.booking.endTime);
252
- const requestedPosStartTime = requestedStartTime || draftStartTime;
253
- const requestedPosDuration = (_ref4 = requestedDuration !== null && requestedDuration !== void 0 ? requestedDuration : normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _ref4 !== void 0 ? _ref4 : getDraftRangeDurationMinutes(context);
254
- const restoredDraftCandidate = draftStartTime ? times.find((candidate) => require_availabilityModel.isAvailabilityCandidateSelectable(candidate, allowUnavailable) && (posSessionAvailability ? require_posCustomTime.isSameAvailabilityCandidateRange(candidate, {
270
+ const requestedPosStartTime = suppressFlexiblePresetOverride ? requestedStartTime : requestedStartTime || draftStartTime;
271
+ const requestedPosDuration = suppressFlexiblePresetOverride ? requestedDuration : (_ref4 = requestedDuration !== null && requestedDuration !== void 0 ? requestedDuration : normalizeDurationMinutesValue(context.draft.booking.duration)) !== null && _ref4 !== void 0 ? _ref4 : getDraftRangeDurationMinutes(context);
272
+ const restoredDraftCandidate = draftStartTime ? times.find((candidate) => isAvailabilityCandidateSelectable(candidate, allowUnavailable) && (posSessionAvailability ? require_posCustomTime.isSameAvailabilityCandidateRange(candidate, {
255
273
  date: selectedDate,
256
274
  startTime: draftStartTime,
257
275
  durationMinutes: requestedPosDuration
258
276
  }) : isSameCandidateStart(candidate, selectedDate, draftStartTime) && (posDurationAvailability || normalizeStartTimeValue(candidate.endTime) === draftEndTime))) : void 0;
259
- const restoredExistingCandidate = existingCandidate ? times.find((candidate) => require_availabilityModel.isAvailabilityCandidateSelectable(candidate, allowUnavailable) && (candidate.key === existingCandidate.key || (posSessionAvailability ? candidate.source === existingCandidate.source && require_posCustomTime.isSameAvailabilityCandidateRange(candidate, {
277
+ const restoredExistingCandidate = existingCandidate ? times.find((candidate) => isAvailabilityCandidateSelectable(candidate, allowUnavailable) && (candidate.key === existingCandidate.key || (posSessionAvailability ? candidate.source === existingCandidate.source && require_posCustomTime.isSameAvailabilityCandidateRange(candidate, {
260
278
  date: existingCandidate.date,
261
279
  startTime: normalizeStartTimeValue(existingCandidate.startTime),
262
280
  durationMinutes: require_posCustomTime.getAvailabilityCandidateDurationMinutes(existingCandidate)
@@ -266,15 +284,15 @@ const refreshAvailabilityTimes = function() {
266
284
  startTime: requestedPosStartTime,
267
285
  durationMinutes: requestedPosDuration
268
286
  }) : isSameCandidateStart(candidate, selectedDate, requestedPosStartTime)) : void 0;
269
- const customSelectionIntent = posCustomTimeAvailability && selectionIntent === "custom";
270
- const fallbackSelectionIntent = posCustomTimeAvailability && selectionIntent === "fallback";
287
+ const customSelectionIntent = posCustomTimeAvailability && effectiveSelectionIntent === "custom";
288
+ const fallbackSelectionIntent = posCustomTimeAvailability && effectiveSelectionIntent === "fallback";
271
289
  const requestedCustomRange = requestedPosStartTime && requestedPosDuration ? {
272
290
  date: selectedDate,
273
291
  startTime: requestedPosStartTime,
274
292
  durationMinutes: requestedPosDuration
275
293
  } : void 0;
276
294
  const restoredCandidate = require_posCustomTime.resolvePosCustomTimeCandidate({
277
- candidates: times.filter((candidate) => require_availabilityModel.isAvailabilityCandidateSelectable(candidate, allowUnavailable)),
295
+ candidates: times.filter((candidate) => isAvailabilityCandidateSelectable(candidate, allowUnavailable)),
278
296
  customSelectionIntent,
279
297
  fallbackSelectionIntent,
280
298
  requestedCustomRange: customSelectionIntent || fallbackSelectionIntent ? requestedCustomRange : void 0,
@@ -282,7 +300,7 @@ const refreshAvailabilityTimes = function() {
282
300
  restoredExistingCandidate,
283
301
  fallbackCandidate: fallbackOsCandidate
284
302
  });
285
- const normallySelectableCandidates = times.filter((candidate) => require_availabilityModel.isAvailabilityCandidateSelectable(candidate));
303
+ const normallySelectableCandidates = times.filter((candidate) => isAvailabilityCandidateSelectable(candidate));
286
304
  const selectableCandidates = normallySelectableCandidates.length > 0 || !allowUnavailable ? normallySelectableCandidates : times;
287
305
  const shouldPreserveRequestedPosStart = posCustomTimeAvailability && Boolean(requestedPosStartTime && requestedPosDuration);
288
306
  const displayCandidates = posSessionAvailability ? require_posCustomTime.getSessionPresetCandidates(times) : posDurationAvailability && require_posCustomTime.isFlexibleDurationValue(product === null || product === void 0 ? void 0 : product.duration) ? require_posCustomTime.getPosFlexibleDurationPresetCandidates(times, requestedCustomRange, customSelectionIntent, Boolean(!customSelectionIntent && existingCandidate && existingCandidate.date === selectedDate && (previousTimeData === null || previousTimeData === void 0 ? void 0 : previousTimeData.timeSlots.some((slot) => String(slot.id) === String(existingCandidate.key))))) : times;
@@ -293,7 +311,7 @@ const refreshAvailabilityTimes = function() {
293
311
  restoredCandidate,
294
312
  fallbackCandidate,
295
313
  preferPreset: preferPosFlexiblePreset,
296
- minimumPresetStartAt: preferPosFlexiblePreset ? (0, dayjs.default)().toISOString() : void 0
314
+ allowRestoredFallback: fallbackSelectionIntent
297
315
  }) : restoredCandidate || fallbackCandidate;
298
316
  context.setModuleData(module.key, {
299
317
  requestId,
@@ -308,7 +326,8 @@ const refreshAvailabilityTimes = function() {
308
326
  candidate
309
327
  })),
310
328
  selectedCandidate: initialCandidate,
311
- posCustomTimeHydrationKey
329
+ posCustomTimeHydrationKey,
330
+ posCustomTimeSelectionIntent: effectiveSelectionIntent === "restore" ? void 0 : effectiveSelectionIntent
312
331
  });
313
332
  const shouldWriteInitialCandidate = Boolean(initialCandidate) && (posCustomTimeAvailability || !existingCandidate || initialCandidate.key !== existingCandidate.key);
314
333
  if (initialCandidate && shouldWriteInitialCandidate) {
@@ -666,7 +685,7 @@ const TimeFlowModuleComponent = ({ context, module, registerHandle }) => {
666
685
  });
667
686
  const selectedCandidate = availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.selectedCandidate;
668
687
  const posStartTimeSlice = usePosSessionAvailability ? availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.slotStepMinutes : (_availabilityData$slo = availabilityData === null || availabilityData === void 0 ? void 0 : availabilityData.slotStepMinutes) !== null && _availabilityData$slo !== void 0 ? _availabilityData$slo : slice;
669
- selectedCandidate && context.services.allowUnavailableBookingSelection === true && require_availabilityModel.isAvailabilityCandidateSelectable(selectedCandidate);
688
+ selectedCandidate && context.services.allowUnavailableBookingSelection === true && isAvailabilityCandidateSelectable(selectedCandidate);
670
689
  const showCandidateCards = require_posCustomTime.shouldShowPosCustomTimeCandidateCards({
671
690
  isSessionAvailability: usePosSessionAvailability,
672
691
  isDurationAvailability: usePosDurationAvailability,
@@ -1,8 +1,13 @@
1
1
  const require_runtime = require("../../../../../_virtual/_rolldown/runtime.js");
2
- const require_availabilityModel = require("../../availabilityModel.js");
3
2
  let dayjs = require("dayjs");
4
3
  dayjs = require_runtime.__toESM(dayjs);
5
4
  //#region src/pro/skuDetailModal/flow/modules/time/posCustomTime.ts
5
+ const resolvePosFlexibleDurationRequestIntent = (params) => {
6
+ if (params.selectionIntent !== "restore") return params.selectionIntent;
7
+ if (params.hydrationKey && params.hydrationKey === params.previousHydrationKey && params.previousSelectionIntent) return params.previousSelectionIntent;
8
+ return "restore";
9
+ };
10
+ const shouldApplyPosFlexibleDurationOverride = (params) => params.isEditMode || params.selectionIntent !== "restore";
6
11
  const isFlexibleDurationValue = (value) => {
7
12
  if (typeof value === "string") {
8
13
  const text = value.trim().toLowerCase();
@@ -31,24 +36,9 @@ const resolvePosCustomTimeDefaultStartTime = (currentValue, sliceMinutes, now) =
31
36
  const minutes = alignedMinute % 60;
32
37
  return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
33
38
  };
34
- const resolvePosFlexibleBusinessDurationMinutes = (startTime, closingTime) => {
35
- const toMinuteOfDay = (value) => {
36
- if (typeof value !== "string") return null;
37
- const matched = value.trim().match(/^([01]\d|2[0-3]):([0-5]\d)(?::[0-5]\d)?$/);
38
- if (!matched) return null;
39
- return Number(matched[1]) * 60 + Number(matched[2]);
40
- };
41
- const startMinute = toMinuteOfDay(startTime);
42
- const closingMinute = toMinuteOfDay(closingTime);
43
- if (startMinute === null || closingMinute === null) return null;
44
- const duration = closingMinute > startMinute ? closingMinute - startMinute : closingMinute < startMinute ? closingMinute + 1440 - startMinute : 0;
45
- return duration > 0 ? duration : null;
46
- };
47
39
  const shouldResetPosFlexibleTimeForDate = (candidate, selectedDate) => Boolean(candidate && candidate.date !== selectedDate);
48
- const resolvePosCustomTimeDefaultDurationMinutes = (currentValue, baseDurationMinutes, flexibleDefaultMinutes) => {
40
+ const resolvePosCustomTimeDefaultDurationMinutes = (currentValue, baseDurationMinutes) => {
49
41
  if (isFlexibleDurationValue(currentValue)) {
50
- const flexibleMinutes = Number(flexibleDefaultMinutes);
51
- if (Number.isFinite(flexibleMinutes) && flexibleMinutes > 0) return Math.max(1, Math.floor(flexibleMinutes));
52
42
  if (typeof currentValue === "string") {
53
43
  const flexibleMatch = currentValue.trim().toLowerCase().match(/^flexible_(\d+(?:\.\d+)?)$/);
54
44
  if (flexibleMatch) return Math.max(1, Math.floor(Number(flexibleMatch[1])));
@@ -82,14 +72,10 @@ const getPosFlexibleDurationPresetCandidates = (candidates, requestedCustomRange
82
72
  return candidates.filter((candidate) => !isSameAvailabilityCandidateRange(candidate, requestedCustomRange));
83
73
  };
84
74
  const resolvePosFlexibleDurationInitialCandidate = (params) => {
85
- const minimumPresetStartAt = params.minimumPresetStartAt === void 0 ? null : (0, dayjs.default)(params.minimumPresetStartAt);
86
75
  const firstAvailablePreset = params.presetCandidates.find((candidate) => {
87
- if (!require_availabilityModel.isAvailabilityCandidateSelectable(candidate)) return false;
88
- if (!(minimumPresetStartAt === null || minimumPresetStartAt === void 0 ? void 0 : minimumPresetStartAt.isValid())) return true;
89
- const candidateStartAt = (0, dayjs.default)(candidate.startAt);
90
- return candidateStartAt.isValid() && !candidateStartAt.isBefore(minimumPresetStartAt);
76
+ return (!candidate.status || candidate.status === "available" || candidate.status === "limited") && !(typeof candidate.maxPartySize === "number" && candidate.maxPartySize <= 0);
91
77
  });
92
- if (params.preferPreset && firstAvailablePreset) return firstAvailablePreset;
78
+ if (params.preferPreset) return firstAvailablePreset || (params.allowRestoredFallback ? params.restoredCandidate : void 0);
93
79
  return params.restoredCandidate || params.fallbackCandidate;
94
80
  };
95
81
  //#endregion
@@ -102,7 +88,8 @@ exports.resolvePosCustomTimeBaseMinutes = resolvePosCustomTimeBaseMinutes;
102
88
  exports.resolvePosCustomTimeCandidate = resolvePosCustomTimeCandidate;
103
89
  exports.resolvePosCustomTimeDefaultDurationMinutes = resolvePosCustomTimeDefaultDurationMinutes;
104
90
  exports.resolvePosCustomTimeDefaultStartTime = resolvePosCustomTimeDefaultStartTime;
105
- exports.resolvePosFlexibleBusinessDurationMinutes = resolvePosFlexibleBusinessDurationMinutes;
106
91
  exports.resolvePosFlexibleDurationInitialCandidate = resolvePosFlexibleDurationInitialCandidate;
92
+ exports.resolvePosFlexibleDurationRequestIntent = resolvePosFlexibleDurationRequestIntent;
93
+ exports.shouldApplyPosFlexibleDurationOverride = shouldApplyPosFlexibleDurationOverride;
107
94
  exports.shouldResetPosFlexibleTimeForDate = shouldResetPosFlexibleTimeForDate;
108
95
  exports.shouldShowPosCustomTimeCandidateCards = shouldShowPosCustomTimeCandidateCards;
@@ -24,7 +24,11 @@ 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
30
  exports.getPosAutoResolutionDraftKey = getPosAutoResolutionDraftKey;
31
+ exports.isCurrentPosAutoResolutionRun = isCurrentPosAutoResolutionRun;
29
32
  exports.isPosCreateAutoResolutionCandidate = isPosCreateAutoResolutionCandidate;
30
33
  exports.shouldDirectlyConfirmPosSelectionFlow = shouldDirectlyConfirmPosSelectionFlow;
34
+ exports.shouldPreparePosSelectionFlowOnConfirm = 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;
@@ -140,7 +140,7 @@ const resolveInitialAvailabilityCandidate = (source, startDate, endDate, startTi
140
140
  if (endDate && candidateEndDate && candidateEndDate !== endDate.format("YYYY-MM-DD")) return;
141
141
  return rawCandidate;
142
142
  };
143
- const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChange, isShowNote, isShowRemove, confirmLabel, isConfirmDisabled = false, isManualPriceChangeDisabled = false, hidePrimaryActions = false, onCancel, onRemove, onManualPriceChange, onOpenNote, onConfirm }) => {
143
+ const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChange, isShowNote, isShowRemove, confirmLabel, isConfirmDisabled = false, isConfirmLoading = false, isManualPriceChangeDisabled = false, hidePrimaryActions = false, onCancel, onRemove, onManualPriceChange, onOpenNote, onConfirm }) => {
144
144
  const auxiliaryActions = [isShowNote ? /* @__PURE__ */ react.default.createElement(_pisell_materials.Button, {
145
145
  key: "note",
146
146
  type: "default",
@@ -172,6 +172,7 @@ const PcActionButtons = ({ isCreateMode, isRemoveDisabled, isShowManualPriceChan
172
172
  type: "primary",
173
173
  size: "large",
174
174
  disabled: isConfirmDisabled,
175
+ loading: isConfirmLoading,
175
176
  onClick: onConfirm,
176
177
  className: "sku-detail-side-actions-btn sku-detail-side-actions-confirm-btn"
177
178
  }, /* @__PURE__ */ react.default.createElement("span", { className: "sku-detail-content-footer-confirm-btn-text" }, confirmLabel))) : null);
@@ -247,8 +248,10 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
247
248
  const [selectionFlowProcedureSteps, setSelectionFlowProcedureSteps] = (0, react.useState)(null);
248
249
  const [compiledSelectionFlowSteps, setCompiledSelectionFlowSteps] = (0, react.useState)(null);
249
250
  const [posAutoResolutionStatus, setPosAutoResolutionStatus] = (0, react.useState)("idle");
251
+ const [posAutoResolutionConfirmPending, setPosAutoResolutionConfirmPending] = (0, react.useState)(false);
250
252
  const posAutoResolutionRunRef = (0, react.useRef)(0);
251
253
  const posAutoResolutionAbandonedRef = (0, react.useRef)(false);
254
+ const posAutoResolutionConfirmPendingRunRef = (0, react.useRef)(null);
252
255
  const [effectiveSelectionFlowSteps, setEffectiveSelectionFlowSteps] = (0, react.useState)(void 0);
253
256
  const [skuDetailConfig, setSkuDetailConfig] = (0, react.useState)({
254
257
  isShowProductSummary: false,
@@ -810,6 +813,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
810
813
  latestSelectionFlowDraftRef.current = null;
811
814
  posAutoResolutionRunRef.current += 1;
812
815
  posAutoResolutionAbandonedRef.current = false;
816
+ posAutoResolutionConfirmPendingRunRef.current = null;
817
+ setPosAutoResolutionConfirmPending(false);
813
818
  setPosAutoResolutionStatus("idle");
814
819
  setEffectiveSelectionFlowSteps(void 0);
815
820
  setNoteModalOpen(false);
@@ -1321,6 +1326,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
1321
1326
  latestSelectionFlowDraftRef.current = null;
1322
1327
  posAutoResolutionRunRef.current += 1;
1323
1328
  posAutoResolutionAbandonedRef.current = false;
1329
+ posAutoResolutionConfirmPendingRunRef.current = null;
1330
+ setPosAutoResolutionConfirmPending(false);
1324
1331
  setPosAutoResolutionStatus("idle");
1325
1332
  setCurrentStep(0);
1326
1333
  lateQuantityReviewStepIndexRef.current = null;
@@ -1332,6 +1339,8 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
1332
1339
  lateQuantityReviewStepIndexRef.current = null;
1333
1340
  lateQuantityRevalidationTaskRef.current = null;
1334
1341
  posAutoResolutionRunRef.current += 1;
1342
+ posAutoResolutionConfirmPendingRunRef.current = null;
1343
+ setPosAutoResolutionConfirmPending(false);
1335
1344
  setOpen(false);
1336
1345
  setDetailLoading(false);
1337
1346
  setNoteModalOpen(false);
@@ -1351,20 +1360,48 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
1351
1360
  var _snapshot$currentStep;
1352
1361
  const flow = selectionFlowRef.current;
1353
1362
  if (!flow) return false;
1354
- if (canDirectlyConfirmPosSelectionFlow) {
1363
+ const currentFlowStepIndex = flow.getState().currentStepIndex;
1364
+ if (require_posAutoResolution.shouldPreparePosSelectionFlowOnConfirm({
1365
+ eligible: isPosCreateAutoResolutionEligible,
1366
+ currentStepIndex: currentFlowStepIndex,
1367
+ abandoned: posAutoResolutionAbandonedRef.current
1368
+ })) {
1369
+ if (posAutoResolutionConfirmPendingRunRef.current !== null) return false;
1355
1370
  const openTaskId = openTaskIdRef.current;
1356
1371
  const draftKey = require_posAutoResolution.getPosAutoResolutionDraftKey(flow.getState().draft);
1357
1372
  const runId = posAutoResolutionRunRef.current + 1;
1358
1373
  posAutoResolutionRunRef.current = runId;
1359
- const result = yield flow.prepareSteps({ fromStepIndex: 1 });
1360
- if (posAutoResolutionRunRef.current !== runId || openTaskIdRef.current !== openTaskId || posAutoResolutionAbandonedRef.current || require_posAutoResolution.getPosAutoResolutionDraftKey(flow.getState().draft) !== draftKey) return false;
1361
- if (!result.prepared || result.cancelled) {
1362
- setPosAutoResolutionStatus("retained");
1363
- return false;
1374
+ posAutoResolutionConfirmPendingRunRef.current = runId;
1375
+ setPosAutoResolutionConfirmPending(true);
1376
+ setPosAutoResolutionStatus("checking");
1377
+ try {
1378
+ const result = yield flow.prepareSteps({ fromStepIndex: 1 });
1379
+ if (!require_posAutoResolution.isCurrentPosAutoResolutionRun({
1380
+ expectedRunId: runId,
1381
+ currentRunId: posAutoResolutionRunRef.current,
1382
+ expectedOpenTaskId: openTaskId,
1383
+ currentOpenTaskId: openTaskIdRef.current,
1384
+ expectedDraftKey: draftKey,
1385
+ currentDraftKey: require_posAutoResolution.getPosAutoResolutionDraftKey(flow.getState().draft),
1386
+ abandoned: posAutoResolutionAbandonedRef.current,
1387
+ currentStepIndex: flow.getState().currentStepIndex
1388
+ }) || result.cancelled) return false;
1389
+ if (!result.prepared) {
1390
+ posAutoResolutionAbandonedRef.current = true;
1391
+ posAutoResolutionRunRef.current += 1;
1392
+ setPosAutoResolutionStatus("retained");
1393
+ return (yield flow.next()) || false;
1394
+ }
1395
+ setPosAutoResolutionStatus("resolved");
1396
+ const completed = yield flow.complete();
1397
+ if (!completed && openTaskIdRef.current === openTaskId && posAutoResolutionRunRef.current === runId) setPosAutoResolutionStatus("retained");
1398
+ return completed;
1399
+ } finally {
1400
+ if (posAutoResolutionConfirmPendingRunRef.current === runId) {
1401
+ posAutoResolutionConfirmPendingRunRef.current = null;
1402
+ setPosAutoResolutionConfirmPending(false);
1403
+ }
1364
1404
  }
1365
- const completed = yield flow.complete();
1366
- if (!completed && openTaskIdRef.current === openTaskId && posAutoResolutionRunRef.current === runId) setPosAutoResolutionStatus("retained");
1367
- return completed;
1368
1405
  }
1369
1406
  if (isPosCreateAutoResolutionEligible) {
1370
1407
  posAutoResolutionAbandonedRef.current = true;
@@ -1781,8 +1818,9 @@ const SkuDetailModal = ({ onConfirm, onRemove, onClose, variant }, ref) => {
1781
1818
  isShowNote: !!(skuDetailConfig === null || skuDetailConfig === void 0 ? void 0 : skuDetailConfig.isShowNote),
1782
1819
  isShowRemove: (skuDetailConfig === null || skuDetailConfig === void 0 ? void 0 : skuDetailConfig.isShowRemove) !== false,
1783
1820
  confirmLabel: pcConfirmButtonText,
1821
+ isConfirmLoading: posAutoResolutionConfirmPending,
1784
1822
  isManualPriceChangeDisabled: !canOpenManualPriceChange,
1785
- isConfirmDisabled: hasReachedBookingPriceStep && (selectionFlowBookingPricePending || selectionFlowBookingPriceError),
1823
+ isConfirmDisabled: posAutoResolutionConfirmPending || hasReachedBookingPriceStep && (selectionFlowBookingPricePending || selectionFlowBookingPriceError),
1786
1824
  onCancel: handleCancel,
1787
1825
  onRemove: handleRemove,
1788
1826
  onManualPriceChange: handleManualPriceChange,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pisell/private-materials",
3
- "version": "6.12.197",
3
+ "version": "6.12.198",
4
4
  "main": "./lib/index.js",
5
5
  "module": "./es/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -70,8 +70,8 @@
70
70
  "styled-components": "^6.0.0-rc.3",
71
71
  "use-sync-external-store": "^1.6.0",
72
72
  "@pisell/pi-payment-sdk": "0.0.3",
73
- "@pisell/materials": "6.12.55",
74
73
  "@pisell/utils": "3.0.4",
74
+ "@pisell/materials": "6.12.55",
75
75
  "@pisell/icon": "0.0.11",
76
76
  "@pisell/date-picker": "3.0.10"
77
77
  },
@@ -1 +0,0 @@
1
- export { };