@pisell/pisellos 2.1.129 → 2.1.130

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 (44) hide show
  1. package/dist/modules/Order/index.d.ts +4 -0
  2. package/dist/modules/Order/index.js +18 -1
  3. package/dist/modules/Order/types.d.ts +9 -1
  4. package/dist/modules/Order/utils.d.ts +7 -0
  5. package/dist/modules/Order/utils.js +27 -11
  6. package/dist/solution/ScanOrder/index.d.ts +27 -3
  7. package/dist/solution/ScanOrder/index.js +865 -481
  8. package/dist/solution/ScanOrder/types.d.ts +34 -24
  9. package/dist/solution/ScanOrder/types.js +5 -1
  10. package/dist/solution/ScanOrder/utils.d.ts +13 -1
  11. package/dist/solution/ScanOrder/utils.js +45 -6
  12. package/dist/solution/VenueBooking/index.d.ts +28 -5
  13. package/dist/solution/VenueBooking/index.js +428 -193
  14. package/dist/solution/VenueBooking/types.d.ts +23 -0
  15. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -1
  16. package/dist/solution/VenueBooking/utils/dateSummary.js +1 -1
  17. package/dist/solution/VenueBooking/utils/resource.d.ts +11 -1
  18. package/dist/solution/VenueBooking/utils/resource.js +57 -21
  19. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +5 -0
  20. package/dist/solution/VenueBooking/utils/slotMerge.js +33 -12
  21. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +1 -1
  22. package/dist/solution/VenueBooking/utils/timeSlot.js +259 -62
  23. package/lib/modules/Order/index.d.ts +4 -0
  24. package/lib/modules/Order/index.js +14 -1
  25. package/lib/modules/Order/types.d.ts +9 -1
  26. package/lib/modules/Order/utils.d.ts +7 -0
  27. package/lib/modules/Order/utils.js +22 -12
  28. package/lib/solution/ScanOrder/index.d.ts +27 -3
  29. package/lib/solution/ScanOrder/index.js +409 -114
  30. package/lib/solution/ScanOrder/types.d.ts +34 -24
  31. package/lib/solution/ScanOrder/utils.d.ts +13 -1
  32. package/lib/solution/ScanOrder/utils.js +37 -0
  33. package/lib/solution/VenueBooking/index.d.ts +28 -5
  34. package/lib/solution/VenueBooking/index.js +193 -45
  35. package/lib/solution/VenueBooking/types.d.ts +23 -0
  36. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -1
  37. package/lib/solution/VenueBooking/utils/dateSummary.js +1 -1
  38. package/lib/solution/VenueBooking/utils/resource.d.ts +11 -1
  39. package/lib/solution/VenueBooking/utils/resource.js +15 -4
  40. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +5 -0
  41. package/lib/solution/VenueBooking/utils/slotMerge.js +29 -12
  42. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +1 -1
  43. package/lib/solution/VenueBooking/utils/timeSlot.js +182 -43
  44. package/package.json +1 -1
@@ -1,3 +1,13 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
3
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
9
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
10
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
1
11
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
2
12
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
3
13
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -6,6 +16,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
6
16
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
7
17
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
8
18
  import dayjs from 'dayjs';
19
+ import Decimal from 'decimal.js';
9
20
  export function isBusinessHoursCrossDay(config) {
10
21
  var _config$businessStart = config.businessStartTime.split(':').map(Number),
11
22
  _config$businessStart2 = _slicedToArray(_config$businessStart, 2),
@@ -152,6 +163,160 @@ export function computeSlotStatus(params) {
152
163
  remainingCapacity: remaining
153
164
  };
154
165
  }
166
+
167
+ /**
168
+ * 合并多个子商品的同一个时段为一个"外层 slot"。
169
+ * - status 取优先级最高的(available > partially_occupied > occupied > unavailable / past)
170
+ * - price 取非空子 slot 中最小的那个
171
+ * - 其它字段使用第一个参考子 slot(外层 slot 不带 productId)
172
+ */
173
+ function mergeSubSlots(subSlots) {
174
+ var priority = {
175
+ available: 5,
176
+ partially_occupied: 4,
177
+ occupied: 3,
178
+ unavailable: 2,
179
+ past: 1
180
+ };
181
+ var best = subSlots[0];
182
+ var _iterator5 = _createForOfIteratorHelper(subSlots),
183
+ _step5;
184
+ try {
185
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
186
+ var _priority$slot$status, _priority$best$status;
187
+ var slot = _step5.value;
188
+ if (((_priority$slot$status = priority[slot.status]) !== null && _priority$slot$status !== void 0 ? _priority$slot$status : 0) > ((_priority$best$status = priority[best.status]) !== null && _priority$best$status !== void 0 ? _priority$best$status : 0)) best = slot;
189
+ }
190
+ } catch (err) {
191
+ _iterator5.e(err);
192
+ } finally {
193
+ _iterator5.f();
194
+ }
195
+ var minPrice = null;
196
+ var _iterator6 = _createForOfIteratorHelper(subSlots),
197
+ _step6;
198
+ try {
199
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
200
+ var _slot = _step6.value;
201
+ if (_slot.price == null) continue;
202
+ var decimal = new Decimal(_slot.price || '0');
203
+ if (!minPrice || decimal.lt(minPrice)) minPrice = decimal;
204
+ }
205
+ } catch (err) {
206
+ _iterator6.e(err);
207
+ } finally {
208
+ _iterator6.f();
209
+ }
210
+ return {
211
+ startTime: best.startTime,
212
+ endTime: best.endTime,
213
+ status: best.status,
214
+ price: minPrice ? minPrice.toFixed(2) : null,
215
+ resourceId: best.resourceId,
216
+ resourceFormId: best.resourceFormId,
217
+ capacity: best.capacity,
218
+ remainingCapacity: best.remainingCapacity
219
+ };
220
+ }
221
+ function buildProductSlots(params) {
222
+ var date = params.date,
223
+ config = params.config,
224
+ resource = params.resource,
225
+ mapping = params.mapping,
226
+ timeLabels = params.timeLabels,
227
+ timesForDate = params.timesForDate,
228
+ events = params.events,
229
+ resCapacity = params.resCapacity,
230
+ now = params.now,
231
+ crossDay = params.crossDay,
232
+ quotationPriceMap = params.quotationPriceMap,
233
+ childRawResources = params.childRawResources,
234
+ childTimesCache = params.childTimesCache,
235
+ childEventsCache = params.childEventsCache,
236
+ config_businessStartHour = params.config_businessStartHour;
237
+ var slots = [];
238
+ var _iterator7 = _createForOfIteratorHelper(timeLabels),
239
+ _step7;
240
+ try {
241
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
242
+ var _quotationPriceMap$ge;
243
+ var label = _step7.value;
244
+ var _label$split$map = label.split(':').map(Number),
245
+ _label$split$map2 = _slicedToArray(_label$split$map, 1),
246
+ h = _label$split$map2[0];
247
+ var isNextDay = crossDay && h < config_businessStartHour;
248
+ var slotDate = isNextDay ? dayjs(date).add(1, 'day').format('YYYY-MM-DD') : date;
249
+ var slotStart = dayjs("".concat(slotDate, " ").concat(label));
250
+ var slotEnd = slotStart.add(config.slotDurationMinutes, 'minute');
251
+ var status = void 0;
252
+ var remainingCapacity = null;
253
+ if (slotStart.isBefore(now)) {
254
+ status = 'past';
255
+ } else if (!isSlotWithinResourceTimes(slotStart, slotEnd, timesForDate)) {
256
+ status = 'unavailable';
257
+ } else {
258
+ var result = computeSlotStatus({
259
+ slotStart: slotStart,
260
+ slotEnd: slotEnd,
261
+ events: events,
262
+ resourceType: mapping.resourceType,
263
+ capacity: resCapacity
264
+ });
265
+ status = result.status;
266
+ remainingCapacity = result.remainingCapacity;
267
+ if (status !== 'occupied' && childRawResources && childRawResources.length) {
268
+ for (var i = 0; i < childRawResources.length; i++) {
269
+ var _childTimesCache$i, _childEventsCache$i, _child$capacity;
270
+ var child = childRawResources[i];
271
+ var childTimes = (_childTimesCache$i = childTimesCache === null || childTimesCache === void 0 ? void 0 : childTimesCache[i]) !== null && _childTimesCache$i !== void 0 ? _childTimesCache$i : getResourceTimesForDate(child, date, config);
272
+ var childEvents = (_childEventsCache$i = childEventsCache === null || childEventsCache === void 0 ? void 0 : childEventsCache[i]) !== null && _childEventsCache$i !== void 0 ? _childEventsCache$i : collectEventsForDate(child, date, config);
273
+ if (!isSlotWithinResourceTimes(slotStart, slotEnd, childTimes)) {
274
+ status = 'unavailable';
275
+ remainingCapacity = null;
276
+ break;
277
+ }
278
+ var childType = child.type || 'single';
279
+ var childResult = computeSlotStatus({
280
+ slotStart: slotStart,
281
+ slotEnd: slotEnd,
282
+ events: childEvents,
283
+ resourceType: childType,
284
+ capacity: (_child$capacity = child.capacity) !== null && _child$capacity !== void 0 ? _child$capacity : 1
285
+ });
286
+ if (childResult.status === 'occupied') {
287
+ status = 'occupied';
288
+ remainingCapacity = 0;
289
+ break;
290
+ }
291
+ if (childResult.status === 'partially_occupied' && status === 'available') {
292
+ var _remainingCapacity;
293
+ status = 'partially_occupied';
294
+ remainingCapacity = Math.min((_remainingCapacity = remainingCapacity) !== null && _remainingCapacity !== void 0 ? _remainingCapacity : childResult.remainingCapacity, childResult.remainingCapacity);
295
+ }
296
+ }
297
+ }
298
+ }
299
+ var isBookable = status === 'available' || status === 'partially_occupied';
300
+ var slotStartStr = slotStart.format('YYYY-MM-DD HH:mm');
301
+ slots.push({
302
+ startTime: slotStartStr,
303
+ endTime: slotEnd.format('YYYY-MM-DD HH:mm'),
304
+ status: status,
305
+ price: isBookable ? (_quotationPriceMap$ge = quotationPriceMap === null || quotationPriceMap === void 0 ? void 0 : quotationPriceMap.get("".concat(mapping.productId, ":").concat(slotStartStr))) !== null && _quotationPriceMap$ge !== void 0 ? _quotationPriceMap$ge : mapping.price : null,
306
+ resourceId: resource.resourceId,
307
+ resourceFormId: resource.formId,
308
+ capacity: status === 'past' || status === 'unavailable' ? null : resCapacity,
309
+ remainingCapacity: remainingCapacity,
310
+ productId: mapping.productId
311
+ });
312
+ }
313
+ } catch (err) {
314
+ _iterator7.e(err);
315
+ } finally {
316
+ _iterator7.f();
317
+ }
318
+ return slots;
319
+ }
155
320
  export function buildTimeSlotGrid(params) {
156
321
  var date = params.date,
157
322
  config = params.config,
@@ -161,83 +326,115 @@ export function buildTimeSlotGrid(params) {
161
326
  var timeLabels = generateTimeLabels(config);
162
327
  var now = dayjs();
163
328
  var crossDay = isBusinessHoursCrossDay(config);
329
+ var config_businessStartHour = Number(config.businessStartTime.split(':')[0]);
330
+ var rawResourceById = new Map();
331
+ var _iterator8 = _createForOfIteratorHelper(rawResources),
332
+ _step8;
333
+ try {
334
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
335
+ var item = _step8.value;
336
+ rawResourceById.set(item.resourceId, item);
337
+ }
338
+ } catch (err) {
339
+ _iterator8.e(err);
340
+ } finally {
341
+ _iterator8.f();
342
+ }
164
343
  var resources = [];
165
- var _iterator5 = _createForOfIteratorHelper(rawResources),
166
- _step5;
344
+ var _iterator9 = _createForOfIteratorHelper(rawResources),
345
+ _step9;
167
346
  try {
168
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
347
+ var _loop = function _loop() {
169
348
  var _resource$capacity;
170
- var resource = _step5.value;
171
- var mapping = resourceProductMap.get(resource.resourceId);
172
- if (!mapping) continue;
349
+ var resource = _step9.value;
350
+ var mappings = resourceProductMap.get(resource.resourceId);
351
+ if (!mappings || !mappings.length) return 1; // continue
173
352
  var timesForDate = getResourceTimesForDate(resource, date, config);
174
353
  var events = collectEventsForDate(resource, date, config);
175
354
  var resCapacity = (_resource$capacity = resource.capacity) !== null && _resource$capacity !== void 0 ? _resource$capacity : 1;
176
- var slots = [];
177
- var _iterator6 = _createForOfIteratorHelper(timeLabels),
178
- _step6;
179
- try {
180
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
181
- var _quotationPriceMap$ge;
182
- var label = _step6.value;
183
- var _label$split$map = label.split(':').map(Number),
184
- _label$split$map2 = _slicedToArray(_label$split$map, 2),
185
- h = _label$split$map2[0],
186
- m = _label$split$map2[1];
187
- var isNextDay = crossDay && h < Number(config.businessStartTime.split(':')[0]);
188
- var slotDate = isNextDay ? dayjs(date).add(1, 'day').format('YYYY-MM-DD') : date;
189
- var slotStart = dayjs("".concat(slotDate, " ").concat(label));
190
- var slotEnd = slotStart.add(config.slotDurationMinutes, 'minute');
191
- var status = void 0;
192
- var remainingCapacity = null;
193
- if (slotStart.isBefore(now)) {
194
- status = 'past';
195
- } else if (!isSlotWithinResourceTimes(slotStart, slotEnd, timesForDate)) {
196
- status = 'unavailable';
197
- } else {
198
- var result = computeSlotStatus({
199
- slotStart: slotStart,
200
- slotEnd: slotEnd,
201
- events: events,
202
- resourceType: mapping.resourceType,
203
- capacity: resCapacity
204
- });
205
- status = result.status;
206
- remainingCapacity = result.remainingCapacity;
207
- }
208
- var isBookable = status === 'available' || status === 'partially_occupied';
209
- var slotStartStr = slotStart.format('YYYY-MM-DD HH:mm');
210
- slots.push({
211
- startTime: slotStartStr,
212
- endTime: slotEnd.format('YYYY-MM-DD HH:mm'),
213
- status: status,
214
- price: isBookable ? (_quotationPriceMap$ge = quotationPriceMap === null || quotationPriceMap === void 0 ? void 0 : quotationPriceMap.get("".concat(mapping.productId, ":").concat(slotStartStr))) !== null && _quotationPriceMap$ge !== void 0 ? _quotationPriceMap$ge : mapping.price : null,
215
- resourceId: resource.resourceId,
216
- resourceFormId: resource.formId,
217
- capacity: status === 'past' || status === 'unavailable' ? null : resCapacity,
218
- remainingCapacity: remainingCapacity
355
+ var combined = resource.combined_resource;
356
+ var isCombined = !!(combined && combined.status === 1 && Array.isArray(combined.resource_ids) && combined.resource_ids.length);
357
+ var childRawResources = isCombined ? combined.resource_ids.map(function (id) {
358
+ return rawResourceById.get(id);
359
+ }).filter(function (r) {
360
+ return !!r;
361
+ }) : undefined;
362
+ var childTimesCache = childRawResources === null || childRawResources === void 0 ? void 0 : childRawResources.map(function (child) {
363
+ return getResourceTimesForDate(child, date, config);
364
+ });
365
+ var childEventsCache = childRawResources === null || childRawResources === void 0 ? void 0 : childRawResources.map(function (child) {
366
+ return collectEventsForDate(child, date, config);
367
+ });
368
+ var subRows = mappings.map(function (mapping) {
369
+ var productSlots = buildProductSlots({
370
+ date: date,
371
+ config: config,
372
+ resource: resource,
373
+ mapping: mapping,
374
+ timeLabels: timeLabels,
375
+ timesForDate: timesForDate,
376
+ events: events,
377
+ resCapacity: resCapacity,
378
+ now: now,
379
+ crossDay: crossDay,
380
+ quotationPriceMap: quotationPriceMap,
381
+ childRawResources: childRawResources,
382
+ childTimesCache: childTimesCache,
383
+ childEventsCache: childEventsCache,
384
+ config_businessStartHour: config_businessStartHour
385
+ });
386
+ return {
387
+ productId: mapping.productId,
388
+ productTitle: mapping.productTitle,
389
+ price: mapping.price,
390
+ slots: productSlots
391
+ };
392
+ });
393
+ var hasMultipleProducts = subRows.length > 1;
394
+ var primary = mappings[0];
395
+ var outerSlots;
396
+ if (hasMultipleProducts) {
397
+ outerSlots = timeLabels.map(function (_label, slotIndex) {
398
+ var group = subRows.map(function (row) {
399
+ return row.slots[slotIndex];
219
400
  });
220
- }
221
- } catch (err) {
222
- _iterator6.e(err);
223
- } finally {
224
- _iterator6.f();
401
+ return mergeSubSlots(group);
402
+ });
403
+ } else {
404
+ outerSlots = subRows[0].slots.map(function (slot) {
405
+ return _objectSpread(_objectSpread({}, slot), {}, {
406
+ productId: undefined
407
+ });
408
+ });
225
409
  }
226
- resources.push({
410
+ var row = {
227
411
  resourceId: resource.resourceId,
228
412
  resourceFormId: resource.formId,
229
- resourceName: resource.main_field || mapping.resourceName,
230
- productId: mapping.productId,
231
- productTitle: mapping.productTitle,
232
- slots: slots
233
- });
413
+ resourceName: resource.main_field || primary.resourceName,
414
+ productId: primary.productId,
415
+ productTitle: primary.productTitle,
416
+ slots: outerSlots
417
+ };
418
+ if (hasMultipleProducts) {
419
+ row.products = subRows;
420
+ row.hasMultipleProducts = true;
421
+ }
422
+ if (isCombined && combined) {
423
+ row.combinedResource = {
424
+ resourceIds: _toConsumableArray(combined.resource_ids)
425
+ };
426
+ }
427
+ resources.push(row);
428
+ };
429
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
430
+ if (_loop()) continue;
234
431
  }
235
432
 
236
433
  // 按 productId 分组排序,确保同一商品的场地连续排列
237
434
  } catch (err) {
238
- _iterator5.e(err);
435
+ _iterator9.e(err);
239
436
  } finally {
240
- _iterator5.f();
437
+ _iterator9.f();
241
438
  }
242
439
  var productOrder = new Map();
243
440
  for (var _i = 0, _resources = resources; _i < _resources.length; _i++) {
@@ -2,6 +2,7 @@ import { Module, PisellCore, ModuleOptions } from '../../types';
2
2
  import { BaseModule } from '../BaseModule';
3
3
  import { OrderModuleAPI, CommitOrderParams, SubmitScanOrderParams, ScanOrderMoreParams, CheckoutOrderParams } from './types';
4
4
  import { CartItem } from '../Cart/types';
5
+ import { type SubmitPayloadEnhancer } from './utils';
5
6
  import type { ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderSummary, ScanOrderTempOrder } from '../../solution/ScanOrder/types';
6
7
  import type { Discount } from '../Discount/types';
7
8
  import { UnavailableReason } from '../Rules/types';
@@ -57,6 +58,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
57
58
  persistTempOrder(): void;
58
59
  private createDefaultTempOrderInstance;
59
60
  ensureTempOrder(): ScanOrderTempOrder;
61
+ restoreOrder(): ScanOrderTempOrder;
60
62
  getTempOrder(): ScanOrderTempOrder | null;
61
63
  addNewOrder(): Promise<ScanOrderTempOrder>;
62
64
  getOrderProducts(): ScanOrderOrderProduct[];
@@ -66,6 +68,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
66
68
  }): Promise<ScanOrderSummary | null>;
67
69
  getScanOrderSummary(): Promise<ScanOrderSummary>;
68
70
  updateTempOrderNote(note: string): string;
71
+ updateTempOrderBuzzer(buzzer: string): string;
69
72
  updateTempOrderContactsInfo(contactsInfo: any[]): any[];
70
73
  addProductToOrder(product: Partial<ScanOrderOrderProduct> & ScanOrderOrderProductIdentity): Promise<ScanOrderOrderProduct[]>;
71
74
  updateProductInOrder(params: {
@@ -80,6 +83,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
80
83
  businessCode?: string;
81
84
  channel?: string;
82
85
  type?: string;
86
+ enhancePayload?: SubmitPayloadEnhancer;
83
87
  }): Promise<T>;
84
88
  createOrder(params: CommitOrderParams['query']): {
85
89
  type: "virtual" | "appointment_booking";
@@ -313,6 +313,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
313
313
  this.persistTempOrder();
314
314
  return newOrder;
315
315
  }
316
+ restoreOrder() {
317
+ const freshTempOrder = this.createDefaultTempOrderInstance();
318
+ this.store.tempOrder = freshTempOrder;
319
+ this.persistTempOrder();
320
+ return freshTempOrder;
321
+ }
316
322
  getTempOrder() {
317
323
  return this.store.tempOrder;
318
324
  }
@@ -373,6 +379,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
373
379
  this.persistTempOrder();
374
380
  return tempOrder.note;
375
381
  }
382
+ updateTempOrderBuzzer(buzzer) {
383
+ const tempOrder = this.ensureTempOrder();
384
+ tempOrder.buzzer = String(buzzer || "");
385
+ this.persistTempOrder();
386
+ return tempOrder.buzzer;
387
+ }
376
388
  updateTempOrderContactsInfo(contactsInfo) {
377
389
  const tempOrder = this.ensureTempOrder();
378
390
  tempOrder.contacts_info = Array.isArray(contactsInfo) ? contactsInfo : [];
@@ -457,7 +469,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
457
469
  platform: params == null ? void 0 : params.platform,
458
470
  businessCode: params == null ? void 0 : params.businessCode,
459
471
  channel: params == null ? void 0 : params.channel,
460
- type: params == null ? void 0 : params.type
472
+ type: params == null ? void 0 : params.type,
473
+ enhance: params == null ? void 0 : params.enhancePayload
461
474
  });
462
475
  let result;
463
476
  if (tempOrder.order_id) {
@@ -3,6 +3,7 @@ import type { ScanOrderTempOrder, ScanOrderOrderProduct, ScanOrderOrderProductId
3
3
  import type { DiscountModule } from '../Discount';
4
4
  import type { RulesModule } from '../Rules';
5
5
  import type { Discount } from '../Discount/types';
6
+ import type { SubmitPayloadEnhancer } from './utils';
6
7
  export declare enum OrderHooks {
7
8
  OnOrderCreate = "order:onOrderCreate",
8
9
  OnOrderUpdate = "order:onOrderUpdate",
@@ -68,10 +69,12 @@ export interface SubmitScanOrderBooking {
68
69
  start_time?: string;
69
70
  end_time?: string;
70
71
  metadata?: Record<string, any>;
72
+ resources?: Array<Record<string, any>>;
73
+ product_uid?: string;
71
74
  }
72
75
  export interface SubmitScanOrderFormRecord {
73
76
  form_id: number | string;
74
- form_record_ids: Array<number | string>;
77
+ form_record_id: number | string;
75
78
  }
76
79
  export interface SubmitScanOrderParams {
77
80
  url?: string;
@@ -107,6 +110,8 @@ export interface SubmitScanOrderParams {
107
110
  shop_discount: string;
108
111
  surcharge_fee: string;
109
112
  note: string;
113
+ delivery_type?: string;
114
+ table_number?: Record<string, any>;
110
115
  schedule_date: string;
111
116
  created_at?: string;
112
117
  products: SubmitScanOrderProduct[];
@@ -195,12 +200,14 @@ export interface OrderModuleAPI {
195
200
  getTempOrder: () => ScanOrderTempOrder | null;
196
201
  ensureTempOrder: () => ScanOrderTempOrder;
197
202
  addNewOrder: () => Promise<ScanOrderTempOrder>;
203
+ restoreOrder: () => ScanOrderTempOrder;
198
204
  getOrderProducts: () => ScanOrderOrderProduct[];
199
205
  getScanOrderSummary: () => Promise<ScanOrderSummary>;
200
206
  recalculateSummary: (options?: {
201
207
  createIfMissing?: boolean;
202
208
  }) => Promise<ScanOrderSummary | null>;
203
209
  updateTempOrderNote: (note: string) => string;
210
+ updateTempOrderBuzzer: (buzzer: string) => string;
204
211
  updateTempOrderContactsInfo: (contactsInfo: any[]) => any[];
205
212
  addProductToOrder: (product: Partial<ScanOrderOrderProduct> & ScanOrderOrderProductIdentity) => Promise<ScanOrderOrderProduct[]>;
206
213
  updateProductInOrder: (params: {
@@ -216,6 +223,7 @@ export interface OrderModuleAPI {
216
223
  businessCode?: string;
217
224
  channel?: string;
218
225
  type?: string;
226
+ enhancePayload?: SubmitPayloadEnhancer;
219
227
  }) => Promise<T>;
220
228
  loadDiscountConfig: (params: {
221
229
  customerId: number;
@@ -56,6 +56,12 @@ export declare function createDefaultTempOrder(params: {
56
56
  now: string;
57
57
  summary?: ScanOrderSummary;
58
58
  }): ScanOrderTempOrder;
59
+ export interface SubmitPayloadEnhancerContext {
60
+ tempOrder: ScanOrderTempOrder;
61
+ bookingUuid: string;
62
+ now: Date;
63
+ }
64
+ export type SubmitPayloadEnhancer = (payload: ScanOrderSubmitPayload, ctx: SubmitPayloadEnhancerContext) => ScanOrderSubmitPayload;
59
65
  export declare function buildSubmitPayload(params: {
60
66
  tempOrder: ScanOrderTempOrder;
61
67
  cacheId?: string;
@@ -64,6 +70,7 @@ export declare function buildSubmitPayload(params: {
64
70
  businessCode?: string;
65
71
  channel?: string;
66
72
  type?: string;
73
+ enhance?: SubmitPayloadEnhancer;
67
74
  }): ScanOrderSubmitPayload;
68
75
  export declare function formatV1Product(products: ScanOrderSubmitProduct[]): {
69
76
  bundle: any[];
@@ -172,6 +172,9 @@ function normalizeSubmitProduct(product) {
172
172
  if (rawMetadata.price_breakdown) {
173
173
  cleanMetadata.price_breakdown = rawMetadata.price_breakdown;
174
174
  }
175
+ if (rawMetadata.is_rule !== void 0) {
176
+ cleanMetadata.is_rule = rawMetadata.is_rule;
177
+ }
175
178
  return {
176
179
  ...submitProduct,
177
180
  ...bookingUid ? { booking_uid: bookingUid } : {},
@@ -286,7 +289,8 @@ function buildSubmitPayload(params) {
286
289
  platform,
287
290
  businessCode,
288
291
  channel,
289
- type
292
+ type,
293
+ enhance
290
294
  } = params;
291
295
  const scheduleDate = tempOrder.schedule_date || tempOrder.created_at || formatDateTime(now);
292
296
  const summary = tempOrder.summary || (0, import_utils.createEmptySummary)();
@@ -297,8 +301,8 @@ function buildSubmitPayload(params) {
297
301
  const bookingDuration = resolveTableOccupancyDuration(tempOrder);
298
302
  const bookingEnd = bookingStart.add(bookingDuration, "minute");
299
303
  const bookings = relationId && tableFormId ? [{
300
- relation_id: relationId,
301
- form_id: tableFormId,
304
+ relation_id: 0,
305
+ form_id: 0,
302
306
  start_time: bookingStart.format("HH:mm"),
303
307
  start_date: bookingStart.format("YYYY-MM-DD"),
304
308
  end_time: bookingEnd.format("HH:mm"),
@@ -310,17 +314,17 @@ function buildSubmitPayload(params) {
310
314
  },
311
315
  select_date: bookingStart.format("YYYY-MM-DD"),
312
316
  is_all: false,
313
- "like_status": "common",
314
- "schedule_id": 0,
315
- "relation_type": "form",
316
- "number": 1
317
+ like_status: "common",
318
+ schedule_id: 0,
319
+ relation_type: "",
320
+ number: 1
317
321
  }] : tempOrder.bookings || [];
318
322
  const formRecordIds = relationId && tableFormId ? [{
319
323
  form_id: tableFormId,
320
- form_record_ids: [relationId]
324
+ form_record_id: relationId
321
325
  }] : void 0;
322
326
  const { created_at: _createdAt, summary: _summary, surcharges: _surcharges, ...tempOrderRest } = tempOrder;
323
- return {
327
+ const payload = {
324
328
  ...tempOrderRest,
325
329
  platform: normalizeSubmitPlatform(platform ?? tempOrder.platform),
326
330
  request_unique_idempotency_token: cacheId,
@@ -348,13 +352,19 @@ function buildSubmitPayload(params) {
348
352
  contacts_info: tempOrder.contacts_info || [],
349
353
  // holder: tempOrder.holder || null,
350
354
  // summary,
351
- metadata: {
352
- ...tempOrder.metadata
353
- },
355
+ metadata: (() => {
356
+ const {
357
+ collect_pax: _collectPax,
358
+ table_occupancy_duration: _tableOccupancyDuration,
359
+ ...rest
360
+ } = tempOrder.metadata || {};
361
+ return { ...rest };
362
+ })(),
354
363
  products: (tempOrder.products || []).map(
355
364
  (product) => normalizeSubmitProduct(product)
356
365
  )
357
366
  };
367
+ return enhance ? enhance(payload, { tempOrder, bookingUuid, now }) : payload;
358
368
  }
359
369
  function formatV1Product(products) {
360
370
  return products.map((product) => {
@@ -1,6 +1,6 @@
1
1
  import { Module, ModuleOptions, PisellCore } from '../../types';
2
2
  import { BaseModule } from '../../modules/BaseModule';
3
- import { ScanOrderAddLogParams, ScanOrderAvailabilityInfo, ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderTableConfigApiData } from './types';
3
+ import { ScanOrderAddLogParams, ScanOrderAvailabilityInfo, ScanOrderOrderProduct, ScanOrderOrderProductIdentity } from './types';
4
4
  import { type CartItemSummary, type PaxInfo, type QuantityCheckResult, type QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
5
5
  import type { StrategyConfig } from '../../model/strategy/type';
6
6
  export * from './types';
@@ -43,7 +43,7 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
43
43
  refresh(): Promise<void>;
44
44
  getStatus(): import("./types").ScanOrderStatus;
45
45
  getEntryContext(): import("./types").ScanOrderEntryContext | null;
46
- getConfig(): ScanOrderTableConfigApiData;
46
+ getConfig(): Record<string, any>;
47
47
  getItemRuleQuantityLimits(): QuantityLimitResult[];
48
48
  getCartValidationPassed(): boolean | null;
49
49
  getCartValidation(): {
@@ -52,10 +52,17 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
52
52
  };
53
53
  getTempOrder(): import("./types").ScanOrderTempOrder | null;
54
54
  updateTempOrderNote(note: string): string;
55
+ setPickupReferenceMode(mode: 'counter_pickup' | 'table_service'): {
56
+ service_type: 'dine_in';
57
+ pickup_reference_mode: 'counter_pickup' | 'table_service';
58
+ };
59
+ setPickupRef(buzzer: string): string;
55
60
  private ensureTempOrder;
56
61
  addNewOrder(): Promise<import("./types").ScanOrderTempOrder>;
62
+ restoreOrder(): Promise<import("./types").ScanOrderTempOrder>;
57
63
  getOrderProducts(): ScanOrderOrderProduct[];
58
64
  getSummary(): Promise<import("./types").ScanOrderSummary>;
65
+ private buildSubmitPayloadEnhancer;
59
66
  submitScanOrder<T = any>(): Promise<T>;
60
67
  addProductToOrder(product: Partial<ScanOrderOrderProduct> & ScanOrderOrderProductIdentity): Promise<ScanOrderOrderProduct[]>;
61
68
  updateProductInOrder(params: {
@@ -78,7 +85,8 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
78
85
  private refreshCartValidationPassed;
79
86
  setItemRuleRuntimeConfig(config?: ScanOrderItemRuleRuntimeConfig): Promise<void>;
80
87
  private normalizeResourceState;
81
- private fetchTableConfigByResourceId;
88
+ private resolveResourceSelectType;
89
+ private fetchResourceOccupyDetailByResourceId;
82
90
  checkResourceAvailable(resourceId: string, hasOrderId: boolean): Promise<ScanOrderAvailabilityInfo>;
83
91
  getAdditionalOrderInfo(): Promise<{
84
92
  orderId: string;
@@ -92,6 +100,22 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
92
100
  setOtherParams(params: Record<string, any>, { cover }?: {
93
101
  cover?: boolean;
94
102
  }): Promise<void>;
103
+ private static readonly UI_STATE_KEY_PREFIX;
104
+ private getUIStateBucketKey;
105
+ private readUIStateBucket;
106
+ private writeUIStateBucket;
107
+ setUIState(key: string, value: any): void;
108
+ getUIState<T = any>(key: string): T | undefined;
109
+ deleteUIState(key: string): void;
110
+ clearUIState(): void;
95
111
  setEntryPaxNumber(number: number): Promise<void>;
96
112
  getEntryPaxNumber(): number | null;
113
+ getFulfillmentModes(): {
114
+ enablePickup: boolean;
115
+ enableTableService: boolean;
116
+ };
117
+ checkManualPickupRef(): {
118
+ enabled: boolean;
119
+ manualInputType?: string;
120
+ };
97
121
  }