@pisell/pisellos 2.3.78 → 2.3.79

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.
@@ -131,8 +131,9 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
131
131
  }, {
132
132
  key: "loadProducts",
133
133
  value: function () {
134
- var _loadProducts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
135
- var _this$otherParams;
134
+ var _loadProducts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
135
+ var _this$otherParams,
136
+ _this2 = this;
136
137
  var _ref,
137
138
  _ref$category_ids,
138
139
  category_ids,
@@ -161,14 +162,16 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
161
162
  rawApplicationCode,
162
163
  mappedApplicationCode,
163
164
  queryPayload,
165
+ originalCallback,
166
+ subscriptionCallback,
164
167
  productsData,
165
168
  sortedList,
166
- _args4 = arguments;
167
- return _regeneratorRuntime().wrap(function _callee4$(_context4) {
168
- while (1) switch (_context4.prev = _context4.next) {
169
+ _args5 = arguments;
170
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
171
+ while (1) switch (_context5.prev = _context5.next) {
169
172
  case 0:
170
- _ref = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {}, _ref$category_ids = _ref.category_ids, category_ids = _ref$category_ids === void 0 ? [] : _ref$category_ids, _ref$product_ids = _ref.product_ids, product_ids = _ref$product_ids === void 0 ? [] : _ref$product_ids, _ref$collection = _ref.collection, collection = _ref$collection === void 0 ? [] : _ref$collection, _ref$menu_list_ids = _ref.menu_list_ids, menu_list_ids = _ref$menu_list_ids === void 0 ? [] : _ref$menu_list_ids, paramsCustomerId = _ref.customer_id, _ref$with_count = _ref.with_count, with_count = _ref$with_count === void 0 ? [] : _ref$with_count, schedule_datetime = _ref.schedule_datetime, schedule_date = _ref.schedule_date, cacheId = _ref.cacheId, with_schedule = _ref.with_schedule, extension_type = _ref.extension_type, _ref$status = _ref.status, status = _ref$status === void 0 ? 'published' : _ref$status, strategy_context = _ref.strategy_context;
171
- options = _args4.length > 1 ? _args4[1] : undefined;
173
+ _ref = _args5.length > 0 && _args5[0] !== undefined ? _args5[0] : {}, _ref$category_ids = _ref.category_ids, category_ids = _ref$category_ids === void 0 ? [] : _ref$category_ids, _ref$product_ids = _ref.product_ids, product_ids = _ref$product_ids === void 0 ? [] : _ref$product_ids, _ref$collection = _ref.collection, collection = _ref$collection === void 0 ? [] : _ref$collection, _ref$menu_list_ids = _ref.menu_list_ids, menu_list_ids = _ref$menu_list_ids === void 0 ? [] : _ref$menu_list_ids, paramsCustomerId = _ref.customer_id, _ref$with_count = _ref.with_count, with_count = _ref$with_count === void 0 ? [] : _ref$with_count, schedule_datetime = _ref.schedule_datetime, schedule_date = _ref.schedule_date, cacheId = _ref.cacheId, with_schedule = _ref.with_schedule, extension_type = _ref.extension_type, _ref$status = _ref.status, status = _ref$status === void 0 ? 'published' : _ref$status, strategy_context = _ref.strategy_context;
174
+ options = _args5.length > 1 ? _args5[1] : undefined;
172
175
  // // 如果 schedule_ids 为空,则需要尝试从 schedule 模块里获取
173
176
  // if (!schedule_ids?.length) {
174
177
  // const schedule_ids_data = this.store.schedule
@@ -228,15 +231,38 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
228
231
  extension_type: extension_type,
229
232
  strategy_context: strategy_context
230
233
  });
231
- _context4.next = 11;
234
+ originalCallback = options === null || options === void 0 ? void 0 : options.callback;
235
+ subscriptionCallback = originalCallback ? ( /*#__PURE__*/function () {
236
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(result) {
237
+ var _result$data;
238
+ var products;
239
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
240
+ while (1) switch (_context4.prev = _context4.next) {
241
+ case 0:
242
+ products = Array.isArray(result === null || result === void 0 || (_result$data = result.data) === null || _result$data === void 0 ? void 0 : _result$data.list) ? result.data.list : [];
243
+ _context4.next = 3;
244
+ return _this2.addProduct(products);
245
+ case 3:
246
+ originalCallback(result);
247
+ case 4:
248
+ case "end":
249
+ return _context4.stop();
250
+ }
251
+ }, _callee4);
252
+ }));
253
+ return function (_x5) {
254
+ return _ref2.apply(this, arguments);
255
+ };
256
+ }()) : undefined;
257
+ _context5.next = 13;
232
258
  return this.request.post("/product/query", queryPayload, {
233
259
  osServer: true,
234
- callback: options === null || options === void 0 ? void 0 : options.callback,
260
+ callback: subscriptionCallback,
235
261
  subscriberId: options === null || options === void 0 ? void 0 : options.subscriberId,
236
262
  customToast: function customToast() {}
237
263
  });
238
- case 11:
239
- productsData = _context4.sent;
264
+ case 13:
265
+ productsData = _context5.sent;
240
266
  sortedList = (productsData.data.list || []).slice().sort(function (a, b) {
241
267
  return Number(b.sort) - Number(a.sort);
242
268
  }); // if (sortedList.length) {
@@ -247,12 +273,12 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
247
273
  // })
248
274
  // }
249
275
  this.addProduct(sortedList);
250
- return _context4.abrupt("return", sortedList);
251
- case 15:
276
+ return _context5.abrupt("return", sortedList);
277
+ case 17:
252
278
  case "end":
253
- return _context4.stop();
279
+ return _context5.stop();
254
280
  }
255
- }, _callee4, this);
281
+ }, _callee5, this);
256
282
  }));
257
283
  function loadProducts() {
258
284
  return _loadProducts.apply(this, arguments);
@@ -262,13 +288,13 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
262
288
  }, {
263
289
  key: "loadProductsPrice",
264
290
  value: function () {
265
- var _loadProductsPrice = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(_ref2) {
266
- var _ref2$ids, ids, customer_id, schedule_date, channel, productsData;
267
- return _regeneratorRuntime().wrap(function _callee5$(_context5) {
268
- while (1) switch (_context5.prev = _context5.next) {
291
+ var _loadProductsPrice = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(_ref3) {
292
+ var _ref3$ids, ids, customer_id, schedule_date, channel, productsData;
293
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
294
+ while (1) switch (_context6.prev = _context6.next) {
269
295
  case 0:
270
- _ref2$ids = _ref2.ids, ids = _ref2$ids === void 0 ? [] : _ref2$ids, customer_id = _ref2.customer_id, schedule_date = _ref2.schedule_date, channel = _ref2.channel;
271
- _context5.next = 3;
296
+ _ref3$ids = _ref3.ids, ids = _ref3$ids === void 0 ? [] : _ref3$ids, customer_id = _ref3.customer_id, schedule_date = _ref3.schedule_date, channel = _ref3.channel;
297
+ _context6.next = 3;
272
298
  return this.request.post("/product/query/price", {
273
299
  ids: ids,
274
300
  customer_id: customer_id,
@@ -278,15 +304,15 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
278
304
  useCache: true
279
305
  });
280
306
  case 3:
281
- productsData = _context5.sent;
282
- return _context5.abrupt("return", productsData.data);
307
+ productsData = _context6.sent;
308
+ return _context6.abrupt("return", productsData.data);
283
309
  case 5:
284
310
  case "end":
285
- return _context5.stop();
311
+ return _context6.stop();
286
312
  }
287
- }, _callee5, this);
313
+ }, _callee6, this);
288
314
  }));
289
- function loadProductsPrice(_x5) {
315
+ function loadProductsPrice(_x6) {
290
316
  return _loadProductsPrice.apply(this, arguments);
291
317
  }
292
318
  return loadProductsPrice;
@@ -294,19 +320,19 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
294
320
  }, {
295
321
  key: "getProducts",
296
322
  value: function () {
297
- var _getProducts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
298
- return _regeneratorRuntime().wrap(function _callee6$(_context6) {
299
- while (1) switch (_context6.prev = _context6.next) {
323
+ var _getProducts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7() {
324
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
325
+ while (1) switch (_context7.prev = _context7.next) {
300
326
  case 0:
301
- _context6.next = 2;
327
+ _context7.next = 2;
302
328
  return this.core.effects.emit("".concat(this.name, ":onGetProducts"), this.store.list);
303
329
  case 2:
304
- return _context6.abrupt("return", cloneDeep(this.store.list));
330
+ return _context7.abrupt("return", cloneDeep(this.store.list));
305
331
  case 3:
306
332
  case "end":
307
- return _context6.stop();
333
+ return _context7.stop();
308
334
  }
309
- }, _callee6, this);
335
+ }, _callee7, this);
310
336
  }));
311
337
  function getProducts() {
312
338
  return _getProducts.apply(this, arguments);
@@ -316,25 +342,25 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
316
342
  }, {
317
343
  key: "getProduct",
318
344
  value: function () {
319
- var _getProduct = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(id) {
345
+ var _getProduct = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(id) {
320
346
  var product;
321
- return _regeneratorRuntime().wrap(function _callee7$(_context7) {
322
- while (1) switch (_context7.prev = _context7.next) {
347
+ return _regeneratorRuntime().wrap(function _callee8$(_context8) {
348
+ while (1) switch (_context8.prev = _context8.next) {
323
349
  case 0:
324
- _context7.next = 2;
350
+ _context8.next = 2;
325
351
  return this.core.effects.emit("".concat(this.name, ":onGetProduct"), this.store.list);
326
352
  case 2:
327
353
  product = this.store.list.find(function (product) {
328
354
  return product.id === id;
329
355
  });
330
- return _context7.abrupt("return", product ? cloneDeep(product) : undefined);
356
+ return _context8.abrupt("return", product ? cloneDeep(product) : undefined);
331
357
  case 4:
332
358
  case "end":
333
- return _context7.stop();
359
+ return _context8.stop();
334
360
  }
335
- }, _callee7, this);
361
+ }, _callee8, this);
336
362
  }));
337
- function getProduct(_x6) {
363
+ function getProduct(_x7) {
338
364
  return _getProduct.apply(this, arguments);
339
365
  }
340
366
  return getProduct;
@@ -342,25 +368,25 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
342
368
  }, {
343
369
  key: "getProductByIds",
344
370
  value: function () {
345
- var _getProductByIds = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(ids) {
371
+ var _getProductByIds = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(ids) {
346
372
  var products;
347
- return _regeneratorRuntime().wrap(function _callee8$(_context8) {
348
- while (1) switch (_context8.prev = _context8.next) {
373
+ return _regeneratorRuntime().wrap(function _callee9$(_context9) {
374
+ while (1) switch (_context9.prev = _context9.next) {
349
375
  case 0:
350
- _context8.next = 2;
376
+ _context9.next = 2;
351
377
  return this.core.effects.emit("".concat(this.name, ":onGetProductByIds"), this.store.list);
352
378
  case 2:
353
379
  products = this.store.list.filter(function (product) {
354
380
  return ids.includes(product.id);
355
381
  });
356
- return _context8.abrupt("return", products);
382
+ return _context9.abrupt("return", products);
357
383
  case 4:
358
384
  case "end":
359
- return _context8.stop();
385
+ return _context9.stop();
360
386
  }
361
- }, _callee8, this);
387
+ }, _callee9, this);
362
388
  }));
363
- function getProductByIds(_x7) {
389
+ function getProductByIds(_x8) {
364
390
  return _getProductByIds.apply(this, arguments);
365
391
  }
366
392
  return getProductByIds;
@@ -368,23 +394,23 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
368
394
  }, {
369
395
  key: "addProduct",
370
396
  value: function () {
371
- var _addProduct = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(products) {
372
- var _this2 = this;
373
- return _regeneratorRuntime().wrap(function _callee9$(_context9) {
374
- while (1) switch (_context9.prev = _context9.next) {
397
+ var _addProduct = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(products) {
398
+ var _this3 = this;
399
+ return _regeneratorRuntime().wrap(function _callee10$(_context10) {
400
+ while (1) switch (_context10.prev = _context10.next) {
375
401
  case 0:
376
402
  // list 需要根据 id 去重
377
403
  if (!this.store.list) {
378
404
  this.store.list = [];
379
405
  }
380
406
  products.forEach(function (n) {
381
- var index = _this2.store.list.findIndex(function (m) {
407
+ var index = _this3.store.list.findIndex(function (m) {
382
408
  return m.id === n.id;
383
409
  });
384
410
  if (index === -1) {
385
- _this2.store.list.push(n);
411
+ _this3.store.list.push(n);
386
412
  } else {
387
- _this2.store.list[index] = n;
413
+ _this3.store.list[index] = n;
388
414
  }
389
415
  });
390
416
  // 根据 sort 值做降序排序(数字越大越靠前)
@@ -394,11 +420,11 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
394
420
  this.core.effects.emit("".concat(this.name, ":changed"), this.store.list);
395
421
  case 4:
396
422
  case "end":
397
- return _context9.stop();
423
+ return _context10.stop();
398
424
  }
399
- }, _callee9, this);
425
+ }, _callee10, this);
400
426
  }));
401
- function addProduct(_x8) {
427
+ function addProduct(_x9) {
402
428
  return _addProduct.apply(this, arguments);
403
429
  }
404
430
  return addProduct;
@@ -406,18 +432,18 @@ export var ProductList = /*#__PURE__*/function (_BaseModule) {
406
432
  }, {
407
433
  key: "selectProducts",
408
434
  value: function () {
409
- var _selectProducts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(products) {
410
- return _regeneratorRuntime().wrap(function _callee10$(_context10) {
411
- while (1) switch (_context10.prev = _context10.next) {
435
+ var _selectProducts = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(products) {
436
+ return _regeneratorRuntime().wrap(function _callee11$(_context11) {
437
+ while (1) switch (_context11.prev = _context11.next) {
412
438
  case 0:
413
439
  this.store.selectProducts = products;
414
440
  case 1:
415
441
  case "end":
416
- return _context10.stop();
442
+ return _context11.stop();
417
443
  }
418
- }, _callee10, this);
444
+ }, _callee11, this);
419
445
  }));
420
- function selectProducts(_x9) {
446
+ function selectProducts(_x10) {
421
447
  return _selectProducts.apply(this, arguments);
422
448
  }
423
449
  return selectProducts;
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
326
326
  date: string;
327
327
  status: string;
328
328
  week: string;
329
- weekNum: 0 | 1 | 2 | 5 | 4 | 3 | 6;
329
+ weekNum: 0 | 1 | 2 | 5 | 3 | 4 | 6;
330
330
  }[]>;
331
331
  submitTimeSlot(timeSlots: TimeSliceItem): void;
332
332
  private getScheduleDataByIds;
@@ -334,7 +334,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
334
334
  * 获取当前的客户搜索条件
335
335
  * @returns 当前搜索条件
336
336
  */
337
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
337
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
338
338
  /**
339
339
  * 获取客户列表状态(包含滚动加载相关状态)
340
340
  * @returns 客户状态
@@ -453,7 +453,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
453
453
  * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
454
454
  * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
455
455
  */
456
- decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
456
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
457
+ action: "reloadCatalog";
458
+ } | {
459
+ action: "add";
460
+ cacheItem: any;
461
+ } | {
462
+ action: "requiresDetail";
463
+ payload: AddProductRequiresDetailPayload;
464
+ } | {
465
+ action: "requiresBookingEdit";
466
+ cacheItem: any;
467
+ payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
468
+ };
457
469
  /** 规格弹窗 callback 后的第二段决策。 */
458
470
  decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
459
471
  /**
@@ -1062,6 +1062,137 @@ function buildBookingFromAvailabilitySelection(params) {
1062
1062
  } : {})
1063
1063
  });
1064
1064
  }
1065
+ var POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES = new Set(['past', 'booking_cutoff', 'resource_full', 'resource_unavailable', 'resource_capacity_exceeded',
1066
+ // A required group whose selected resource is outside its window is surfaced
1067
+ // as missing_resource at group level. Structural validation below still
1068
+ // rejects a genuinely missing selection.
1069
+ 'missing_resource']);
1070
+ function matchesForcedSelectionGroup(selection, group) {
1071
+ var hasGroupId = typeof selection.requirementGroupId === 'string' && selection.requirementGroupId.trim().length > 0;
1072
+ var hasFormId = selection.formId !== undefined && selection.formId !== null;
1073
+ if (!hasGroupId && !hasFormId) return false;
1074
+ if (hasGroupId && selection.requirementGroupId !== group.id) return false;
1075
+ if (hasFormId && !sameAvailabilityId(selection.formId, group.formId)) return false;
1076
+ return true;
1077
+ }
1078
+
1079
+ /**
1080
+ * POS may intentionally overbook a configured time/resource. Rebuild the
1081
+ * assignments from the submitted, structurally valid resource identities so
1082
+ * a full/unavailable option is not silently dropped by normal availability
1083
+ * evaluation. This deliberately ignores capacity, occupancy and resource
1084
+ * windows, while retaining product/group/resource identity and selection
1085
+ * cardinality checks.
1086
+ */
1087
+ function buildPosForcedAvailabilityAssignments(params) {
1088
+ var product = params.product,
1089
+ resources = params.resources,
1090
+ candidate = params.candidate,
1091
+ requirementSelections = params.requirementSelections,
1092
+ partySize = params.partySize;
1093
+ var groups = product.requirementGroups || [];
1094
+ var conflicts = [];
1095
+ var assignments = [];
1096
+ var selectionsByGroup = new Map();
1097
+ var addConflict = function addConflict(code, message) {
1098
+ var details = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1099
+ return conflicts.push(_objectSpread({
1100
+ code: code,
1101
+ message: message,
1102
+ productId: candidate.productId,
1103
+ candidateKey: candidate.key
1104
+ }, details));
1105
+ };
1106
+ requirementSelections.forEach(function (selection) {
1107
+ var _group$min, _group$max;
1108
+ var matchedGroups = groups.filter(function (group) {
1109
+ return matchesForcedSelectionGroup(selection, group);
1110
+ });
1111
+ if (matchedGroups.length !== 1) {
1112
+ addConflict('invalid_requirement_group', '选择的资源组不属于当前商品', {
1113
+ requirementGroupId: selection.requirementGroupId,
1114
+ formId: selection.formId
1115
+ });
1116
+ return;
1117
+ }
1118
+ var group = matchedGroups[0];
1119
+ if (selectionsByGroup.has(group.id)) {
1120
+ addConflict('invalid_selection_count', "\u8D44\u6E90\u7EC4 ".concat(group.id, " \u88AB\u91CD\u590D\u63D0\u4EA4"), {
1121
+ requirementGroupId: group.id,
1122
+ formId: group.formId
1123
+ });
1124
+ return;
1125
+ }
1126
+ selectionsByGroup.set(group.id, selection);
1127
+ if (!Array.isArray(selection.resourceIds)) {
1128
+ addConflict('invalid_selection_count', "\u8D44\u6E90\u7EC4 ".concat(group.id, " \u7684\u8D44\u6E90\u9009\u62E9\u5FC5\u987B\u662F\u6570\u7EC4"), {
1129
+ requirementGroupId: group.id,
1130
+ formId: group.formId
1131
+ });
1132
+ return;
1133
+ }
1134
+ var selectedResourceIds = Array.from(new Map(selection.resourceIds.map(function (resourceId) {
1135
+ return [String(resourceId), resourceId];
1136
+ })).values());
1137
+ var required = group.required !== false;
1138
+ var min = Math.max(required ? 1 : 0, Number((_group$min = group.min) !== null && _group$min !== void 0 ? _group$min : required ? 1 : 0) || 0);
1139
+ var max = Math.max(min, Number((_group$max = group.max) !== null && _group$max !== void 0 ? _group$max : Math.max(min, 1)) || Math.max(min, 1));
1140
+ if (selectedResourceIds.length < min) {
1141
+ addConflict('missing_resource', "\u8D44\u6E90\u7EC4 ".concat(group.id, " \u7F3A\u5C11\u5DF2\u9009\u8D44\u6E90"), {
1142
+ requirementGroupId: group.id,
1143
+ formId: group.formId
1144
+ });
1145
+ return;
1146
+ }
1147
+ if (selectedResourceIds.length > max) {
1148
+ addConflict('invalid_selection_count', "\u8D44\u6E90\u7EC4 ".concat(group.id, " \u5DF2\u9009\u8D44\u6E90\u6570\u91CF\u8D85\u51FA\u4E0A\u9650"), {
1149
+ requirementGroupId: group.id,
1150
+ formId: group.formId
1151
+ });
1152
+ return;
1153
+ }
1154
+ selectedResourceIds.forEach(function (resourceId) {
1155
+ var _group$resourceIds2, _group$formId, _candidate$primarySch5, _candidate$primarySch6;
1156
+ var resource = resources.find(function (item) {
1157
+ return sameAvailabilityId(item.id, resourceId);
1158
+ });
1159
+ var belongsToGroup = Boolean(resource && !(group.formId !== undefined && resource.formId !== undefined && !sameAvailabilityId(group.formId, resource.formId)) && !((_group$resourceIds2 = group.resourceIds) !== null && _group$resourceIds2 !== void 0 && _group$resourceIds2.length && !group.resourceIds.some(function (id) {
1160
+ return sameAvailabilityId(id, resourceId);
1161
+ })));
1162
+ if (!resource || !belongsToGroup) {
1163
+ addConflict('resource_unavailable', "\u8D44\u6E90 ".concat(String(resourceId), " \u4E0D\u5C5E\u4E8E\u5F53\u524D\u5546\u54C1\u8D44\u6E90\u7EC4"), {
1164
+ requirementGroupId: group.id,
1165
+ formId: group.formId,
1166
+ resourceId: resourceId
1167
+ });
1168
+ return;
1169
+ }
1170
+ assignments.push({
1171
+ productId: product.id,
1172
+ resourceId: resourceId,
1173
+ formId: (_group$formId = group.formId) !== null && _group$formId !== void 0 ? _group$formId : resource.formId,
1174
+ startAt: candidate.bookingStartAt || candidate.startAt,
1175
+ endAt: candidate.bookingEndAt || candidate.endAt,
1176
+ capacityRequired: Math.max(1, partySize),
1177
+ scheduleId: (_candidate$primarySch5 = candidate.primaryScheduleRef) === null || _candidate$primarySch5 === void 0 ? void 0 : _candidate$primarySch5.scheduleId,
1178
+ timeSlotId: (_candidate$primarySch6 = candidate.primaryScheduleRef) === null || _candidate$primarySch6 === void 0 ? void 0 : _candidate$primarySch6.timeSlotId
1179
+ });
1180
+ });
1181
+ });
1182
+ groups.filter(function (group) {
1183
+ return group.required !== false;
1184
+ }).forEach(function (group) {
1185
+ if (selectionsByGroup.has(group.id)) return;
1186
+ addConflict('missing_resource', "\u8D44\u6E90\u7EC4 ".concat(group.id, " \u7F3A\u5C11\u5DF2\u9009\u8D44\u6E90"), {
1187
+ requirementGroupId: group.id,
1188
+ formId: group.formId
1189
+ });
1190
+ });
1191
+ return {
1192
+ assignments: assignments,
1193
+ conflicts: conflicts
1194
+ };
1195
+ }
1065
1196
  export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
1066
1197
  _inherits(UnifiedBookingSalesImpl, _BookingTicket);
1067
1198
  var _super = _createSuper(UnifiedBookingSalesImpl);
@@ -2041,7 +2172,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
2041
2172
  key: "getProtocol",
2042
2173
  value: (function () {
2043
2174
  var _getProtocol = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee13(policyId) {
2044
- var normalizedPolicyId;
2175
+ var normalizedPolicyId, policyUrl;
2045
2176
  return _regeneratorRuntime().wrap(function _callee13$(_context13) {
2046
2177
  while (1) switch (_context13.prev = _context13.next) {
2047
2178
  case 0:
@@ -2052,8 +2183,12 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
2052
2183
  }
2053
2184
  throw new Error('[UnifiedBookingSales] getProtocol 需要 policyId');
2054
2185
  case 3:
2055
- return _context13.abrupt("return", this.request.get("/shop-policy/".concat(encodeURIComponent(normalizedPolicyId))));
2056
- case 4:
2186
+ policyUrl = 'shop-policy';
2187
+ if (this.otherParams.platform === 'kiosk' || this.otherParams.platform === 'pos' || this.otherParams.platform === 'shop') {
2188
+ policyUrl = 'policy';
2189
+ }
2190
+ return _context13.abrupt("return", this.request.get("/".concat(policyUrl, "/").concat(encodeURIComponent(normalizedPolicyId))));
2191
+ case 6:
2057
2192
  case "end":
2058
2193
  return _context13.stop();
2059
2194
  }
@@ -2491,23 +2626,26 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
2491
2626
  }, {
2492
2627
  key: "buildUnifiedOrderProduct",
2493
2628
  value: function buildUnifiedOrderProduct(sourceProduct, ownershipKey, product) {
2494
- var _sourceProduct$id, _ref33, _sourceProduct$produc, _ref34, _ref35, _sourceProduct$quanti, _sourceProduct$price, _ref36, _ref37, _sourceProduct$sellin;
2629
+ var _ref33, _sourceProduct$_exten, _sourceProduct$_exten2, _sourceProduct$metada, _sourceProduct$id, _ref34, _sourceProduct$produc, _ref35, _ref36, _sourceProduct$quanti, _sourceProduct$price, _ref37, _ref38, _sourceProduct$sellin;
2495
2630
  var normalizedProductRaw = (product === null || product === void 0 ? void 0 : product.raw) || {};
2631
+ var quotationShelfId = (_ref33 = (_sourceProduct$_exten = (_sourceProduct$_exten2 = sourceProduct._extend) === null || _sourceProduct$_exten2 === void 0 ? void 0 : _sourceProduct$_exten2.quotation_shelf_id) !== null && _sourceProduct$_exten !== void 0 ? _sourceProduct$_exten : sourceProduct.quotation_shelf_id) !== null && _ref33 !== void 0 ? _ref33 : (_sourceProduct$metada = sourceProduct.metadata) === null || _sourceProduct$metada === void 0 ? void 0 : _sourceProduct$metada.quotation_shelf_id;
2496
2632
  var orderProduct = this.transformBaseProductToOrderProduct({
2497
2633
  payload: _objectSpread(_objectSpread({}, sourceProduct), {}, {
2498
2634
  id: (_sourceProduct$id = sourceProduct.id) !== null && _sourceProduct$id !== void 0 ? _sourceProduct$id : product === null || product === void 0 ? void 0 : product.id,
2499
- product_id: (_ref33 = (_sourceProduct$produc = sourceProduct.product_id) !== null && _sourceProduct$produc !== void 0 ? _sourceProduct$produc : sourceProduct.id) !== null && _ref33 !== void 0 ? _ref33 : product === null || product === void 0 ? void 0 : product.id,
2500
- quantity: (_ref34 = (_ref35 = (_sourceProduct$quanti = sourceProduct.quantity) !== null && _sourceProduct$quanti !== void 0 ? _sourceProduct$quanti : sourceProduct.num) !== null && _ref35 !== void 0 ? _ref35 : product === null || product === void 0 ? void 0 : product.quantity) !== null && _ref34 !== void 0 ? _ref34 : 1,
2635
+ product_id: (_ref34 = (_sourceProduct$produc = sourceProduct.product_id) !== null && _sourceProduct$produc !== void 0 ? _sourceProduct$produc : sourceProduct.id) !== null && _ref34 !== void 0 ? _ref34 : product === null || product === void 0 ? void 0 : product.id,
2636
+ quantity: (_ref35 = (_ref36 = (_sourceProduct$quanti = sourceProduct.quantity) !== null && _sourceProduct$quanti !== void 0 ? _sourceProduct$quanti : sourceProduct.num) !== null && _ref36 !== void 0 ? _ref36 : product === null || product === void 0 ? void 0 : product.quantity) !== null && _ref35 !== void 0 ? _ref35 : 1,
2501
2637
  price: (_sourceProduct$price = sourceProduct.price) !== null && _sourceProduct$price !== void 0 ? _sourceProduct$price : normalizedProductRaw.price,
2502
- selling_price: (_ref36 = (_ref37 = (_sourceProduct$sellin = sourceProduct.selling_price) !== null && _sourceProduct$sellin !== void 0 ? _sourceProduct$sellin : sourceProduct.price) !== null && _ref37 !== void 0 ? _ref37 : normalizedProductRaw.selling_price) !== null && _ref36 !== void 0 ? _ref36 : normalizedProductRaw.price,
2638
+ selling_price: (_ref37 = (_ref38 = (_sourceProduct$sellin = sourceProduct.selling_price) !== null && _sourceProduct$sellin !== void 0 ? _sourceProduct$sellin : sourceProduct.price) !== null && _ref38 !== void 0 ? _ref38 : normalizedProductRaw.selling_price) !== null && _ref37 !== void 0 ? _ref37 : normalizedProductRaw.price,
2503
2639
  metadata: _objectSpread(_objectSpread({}, sourceProduct.metadata || {}), {}, _defineProperty({}, ownershipKey, true))
2504
2640
  }),
2505
2641
  sourceProduct: sourceProduct
2506
2642
  });
2507
2643
  if (orderProduct && _typeof(orderProduct) === 'object') {
2508
- // BaseSales may rebuild metadata from its price source. Stamp ownership after that transform
2509
- // so each UnifiedBookingSales entry point can replace only its own temporary lines.
2510
- orderProduct.metadata = _objectSpread(_objectSpread({}, orderProduct.metadata || {}), {}, _defineProperty({}, ownershipKey, true));
2644
+ // BaseSales may rebuild metadata from its price source. Stamp ownership and the selected
2645
+ // quotation shelf after that transform so neither booking adds nor edits lose quote identity.
2646
+ orderProduct.metadata = _objectSpread(_objectSpread({}, orderProduct.metadata || {}), {}, _defineProperty({}, ownershipKey, true), quotationShelfId !== undefined ? {
2647
+ quotation_shelf_id: quotationShelfId
2648
+ } : {});
2511
2649
  }
2512
2650
  return orderProduct;
2513
2651
  }
@@ -2657,7 +2795,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
2657
2795
  key: "addRetailProduct",
2658
2796
  value: (function () {
2659
2797
  var _addRetailProduct = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee21(params) {
2660
- var _params$quantity, _ref38, _params$productId, _params$product, _params$product2;
2798
+ var _params$quantity, _ref39, _params$productId, _params$product, _params$product2;
2661
2799
  var quantity, productId, sourceProduct, products, orderProduct;
2662
2800
  return _regeneratorRuntime().wrap(function _callee21$(_context21) {
2663
2801
  while (1) switch (_context21.prev = _context21.next) {
@@ -2669,7 +2807,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
2669
2807
  }
2670
2808
  throw new Error('[UnifiedBookingSales] retail 商品数量必须大于 0');
2671
2809
  case 3:
2672
- productId = (_ref38 = (_params$productId = params.productId) !== null && _params$productId !== void 0 ? _params$productId : (_params$product = params.product) === null || _params$product === void 0 ? void 0 : _params$product.id) !== null && _ref38 !== void 0 ? _ref38 : (_params$product2 = params.product) === null || _params$product2 === void 0 ? void 0 : _params$product2.product_id;
2810
+ productId = (_ref39 = (_params$productId = params.productId) !== null && _params$productId !== void 0 ? _params$productId : (_params$product = params.product) === null || _params$product === void 0 ? void 0 : _params$product.id) !== null && _ref39 !== void 0 ? _ref39 : (_params$product2 = params.product) === null || _params$product2 === void 0 ? void 0 : _params$product2.product_id;
2673
2811
  sourceProduct = params.product;
2674
2812
  if (!sourceProduct && productId !== undefined && productId !== null) {
2675
2813
  sourceProduct = this.unifiedProductCatalog.find(function (product) {
@@ -2974,8 +3112,8 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
2974
3112
  return _context22.abrupt("return", normalized.filter(function (product) {
2975
3113
  var _product$requirementG2;
2976
3114
  return (_product$requirementG2 = product.requirementGroups) === null || _product$requirementG2 === void 0 ? void 0 : _product$requirementG2.some(function (group) {
2977
- var _group$resourceIds2;
2978
- return (_group$resourceIds2 = group.resourceIds) === null || _group$resourceIds2 === void 0 ? void 0 : _group$resourceIds2.some(function (resourceId) {
3115
+ var _group$resourceIds3;
3116
+ return (_group$resourceIds3 = group.resourceIds) === null || _group$resourceIds3 === void 0 ? void 0 : _group$resourceIds3.some(function (resourceId) {
2979
3117
  return prepare.resourceIds.some(function (id) {
2980
3118
  return sameAvailabilityId(id, resourceId);
2981
3119
  });
@@ -3273,7 +3411,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
3273
3411
  var products = Array.isArray(tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.products) ? tempOrder.products : [];
3274
3412
  var bookings = Array.isArray(tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.bookings) ? tempOrder.bookings : [];
3275
3413
  productLineUids.forEach(function (requestedUid) {
3276
- var _ref39, _product$booking_uid2, _product$metadata5;
3414
+ var _ref40, _product$booking_uid2, _product$metadata5;
3277
3415
  var product = products.find(function (line) {
3278
3416
  return getProductLineUid(line) === String(requestedUid);
3279
3417
  });
@@ -3283,7 +3421,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
3283
3421
  });
3284
3422
  }
3285
3423
  var productUid = getProductLineUid(product);
3286
- var linkedBookingUid = String((_ref39 = (_product$booking_uid2 = product.booking_uid) !== null && _product$booking_uid2 !== void 0 ? _product$booking_uid2 : (_product$metadata5 = product.metadata) === null || _product$metadata5 === void 0 ? void 0 : _product$metadata5.booking_uid) !== null && _ref39 !== void 0 ? _ref39 : '');
3424
+ var linkedBookingUid = String((_ref40 = (_product$booking_uid2 = product.booking_uid) !== null && _product$booking_uid2 !== void 0 ? _product$booking_uid2 : (_product$metadata5 = product.metadata) === null || _product$metadata5 === void 0 ? void 0 : _product$metadata5.booking_uid) !== null && _ref40 !== void 0 ? _ref40 : '');
3287
3425
  var linkedBookings = bookings.filter(function (booking) {
3288
3426
  var _booking$product_uid;
3289
3427
  return linkedBookingUid && getBookingUid(booking) === linkedBookingUid || productUid && String((_booking$product_uid = booking.product_uid) !== null && _booking$product_uid !== void 0 ? _booking$product_uid : '') === productUid;
@@ -3329,16 +3467,16 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
3329
3467
  var _this5 = this;
3330
3468
  var bookings = Array.isArray(tempOrder === null || tempOrder === void 0 ? void 0 : tempOrder.bookings) ? tempOrder.bookings : [];
3331
3469
  return bookings.flatMap(function (booking) {
3332
- var _ref40, _booking$product_uid2, _booking$metadata2;
3470
+ var _ref41, _booking$product_uid2, _booking$metadata2;
3333
3471
  var bookingUid = getBookingUid(booking);
3334
- var productUid = String((_ref40 = (_booking$product_uid2 = booking.product_uid) !== null && _booking$product_uid2 !== void 0 ? _booking$product_uid2 : (_booking$metadata2 = booking.metadata) === null || _booking$metadata2 === void 0 ? void 0 : _booking$metadata2.product_uid) !== null && _ref40 !== void 0 ? _ref40 : '');
3472
+ var productUid = String((_ref41 = (_booking$product_uid2 = booking.product_uid) !== null && _booking$product_uid2 !== void 0 ? _booking$product_uid2 : (_booking$metadata2 = booking.metadata) === null || _booking$metadata2 === void 0 ? void 0 : _booking$metadata2.product_uid) !== null && _ref41 !== void 0 ? _ref41 : '');
3335
3473
  var scheduleEventId = toNumberId(booking.schedule_event_id);
3336
3474
  var startAt = booking.start_at || "".concat(booking.start_date || '', " ").concat(booking.start_time || '').trim();
3337
3475
  var endAt = booking.end_at || "".concat(booking.end_date || booking.start_date || '', " ").concat(booking.end_time || '').trim();
3338
3476
  var resources = Array.isArray(booking.resources) ? booking.resources : [];
3339
3477
  return resources.flatMap(function (resource) {
3340
- var _ref41, _resource$resource_id, _ref42, _resource$capacity;
3341
- var resourceId = (_ref41 = (_resource$resource_id = resource.resource_id) !== null && _resource$resource_id !== void 0 ? _resource$resource_id : resource.relation_id) !== null && _ref41 !== void 0 ? _ref41 : resource.id;
3478
+ var _ref42, _resource$resource_id, _ref43, _resource$capacity;
3479
+ var resourceId = (_ref42 = (_resource$resource_id = resource.resource_id) !== null && _resource$resource_id !== void 0 ? _resource$resource_id : resource.relation_id) !== null && _ref42 !== void 0 ? _ref42 : resource.id;
3342
3480
  if (resourceId == null || !startAt || !endAt) return [];
3343
3481
  var range = normalizeAvailabilityLocalDateTimeRange({
3344
3482
  startAt: startAt,
@@ -3351,7 +3489,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
3351
3489
  resourceId: resourceId,
3352
3490
  startAt: range.startAt,
3353
3491
  endAt: range.endAt,
3354
- pax: Math.max(1, Number((_ref42 = (_resource$capacity = resource.capacity) !== null && _resource$capacity !== void 0 ? _resource$capacity : booking.capacity) !== null && _ref42 !== void 0 ? _ref42 : 1) || 1),
3492
+ pax: Math.max(1, Number((_ref43 = (_resource$capacity = resource.capacity) !== null && _resource$capacity !== void 0 ? _resource$capacity : booking.capacity) !== null && _ref43 !== void 0 ? _ref43 : 1) || 1),
3355
3493
  source: 'cart',
3356
3494
  scheduleEventId: scheduleEventId,
3357
3495
  bookingUid: bookingUid || undefined,
@@ -4165,9 +4303,9 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4165
4303
  }, {
4166
4304
  key: "findLinkedBooking",
4167
4305
  value: function findLinkedBooking(product) {
4168
- var _ref44, _product$booking_uid3, _product$metadata6, _this$getTempOrder3;
4306
+ var _ref45, _product$booking_uid3, _product$metadata6, _this$getTempOrder3;
4169
4307
  var productUid = getProductLineUid(product);
4170
- var bookingUid = String((_ref44 = (_product$booking_uid3 = product.booking_uid) !== null && _product$booking_uid3 !== void 0 ? _product$booking_uid3 : (_product$metadata6 = product.metadata) === null || _product$metadata6 === void 0 ? void 0 : _product$metadata6.booking_uid) !== null && _ref44 !== void 0 ? _ref44 : '');
4308
+ var bookingUid = String((_ref45 = (_product$booking_uid3 = product.booking_uid) !== null && _product$booking_uid3 !== void 0 ? _product$booking_uid3 : (_product$metadata6 = product.metadata) === null || _product$metadata6 === void 0 ? void 0 : _product$metadata6.booking_uid) !== null && _ref45 !== void 0 ? _ref45 : '');
4171
4309
  return (((_this$getTempOrder3 = this.getTempOrder()) === null || _this$getTempOrder3 === void 0 ? void 0 : _this$getTempOrder3.bookings) || []).find(function (booking) {
4172
4310
  var _booking$product_uid3;
4173
4311
  return bookingUid && getBookingUid(booking) === bookingUid || productUid && String((_booking$product_uid3 = booking.product_uid) !== null && _booking$product_uid3 !== void 0 ? _booking$product_uid3 : '') === productUid;
@@ -4179,7 +4317,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4179
4317
  key: "commitAvailabilitySelection",
4180
4318
  value: (function () {
4181
4319
  var _commitAvailabilitySelection = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee37(contextId, params) {
4182
- var normalizedContextId, _params$bookingCount, _ref45, _params$orderProduct$, _params$orderProduct, _params$orderProduct2, _params$orderProduct3, _params$orderProduct$2, _params$orderProduct4, _params$orderProduct5, _editingLine$product_, _baseProjection$meta$, _refreshedProjection$, _baseProjection$meta$2, _ref46, _params$orderProduct$3, _params$orderProduct6, _existingBooking$meta, _ref47, _ref48, _params$orderProduct$4, _params$orderProduct7, _params$orderProduct8, _existingBooking$meta2, _existingBooking$hold, bookingCount, orderProductQuantity, partySize, _yield$this$ensureAva3, context, projectionEntry, refreshed, boundEditingUids, orderProductId, editingLine, _editingLine$product_2, baseProjection, commitWriteGuard, prepareParams, fallbackResources, commitSnapshot, refreshedProjection, _baseProjection$meta$3, latestContext, refreshedRanges, refreshedCandidateBase, validation, capacityConflict, revalidationEntry, revalidatedContext, refreshedCandidate, product, existingBooking, existingBookingUid, booking, transformed, productLineUid, bookingUid, productLineUids, bookingUids, _transformed$product_, _transformed$product_2, _transformed$product_3, _ref49, _transformed$product_4, _this$getTempOrder4, _this$getTempOrder5, _this$getTempOrder6, beforeProductLineUids, beforeBookingUids, products, addedLines, addedBookings, nextContext, result;
4320
+ var normalizedContextId, _params$bookingCount, _ref46, _params$orderProduct$, _params$orderProduct, _params$orderProduct2, _params$orderProduct3, _params$orderProduct$2, _params$orderProduct4, _params$orderProduct5, _editingLine$product_, _baseProjection$meta$, _refreshedProjection$, _baseProjection$meta$2, _this$otherParams$pla, _this$otherParams17, _ref47, _params$orderProduct$3, _params$orderProduct6, _existingBooking$meta, _ref48, _ref49, _params$orderProduct$4, _params$orderProduct7, _params$orderProduct8, _existingBooking$meta2, _existingBooking$hold, bookingCount, orderProductQuantity, partySize, _yield$this$ensureAva3, context, projectionEntry, refreshed, boundEditingUids, orderProductId, editingLine, _editingLine$product_2, baseProjection, commitWriteGuard, prepareParams, fallbackResources, commitSnapshot, refreshedProjection, _baseProjection$meta$3, latestContext, refreshedRanges, refreshedCandidateBase, product, validation, allowPosAvailabilityOverride, forced, capacityConflict, revalidationEntry, revalidatedContext, refreshedCandidate, existingBooking, existingBookingUid, booking, transformed, productLineUid, bookingUid, productLineUids, bookingUids, _transformed$product_, _transformed$product_2, _transformed$product_3, _ref50, _transformed$product_4, _this$getTempOrder4, _this$getTempOrder5, _this$getTempOrder6, beforeProductLineUids, beforeBookingUids, products, addedLines, addedBookings, nextContext, result;
4183
4321
  return _regeneratorRuntime().wrap(function _callee37$(_context37) {
4184
4322
  while (1) switch (_context37.prev = _context37.next) {
4185
4323
  case 0:
@@ -4213,7 +4351,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4213
4351
  bookingCount: bookingCount
4214
4352
  });
4215
4353
  case 11:
4216
- orderProductQuantity = (_ref45 = (_params$orderProduct$ = (_params$orderProduct = params.orderProduct) === null || _params$orderProduct === void 0 ? void 0 : _params$orderProduct.num) !== null && _params$orderProduct$ !== void 0 ? _params$orderProduct$ : (_params$orderProduct2 = params.orderProduct) === null || _params$orderProduct2 === void 0 ? void 0 : _params$orderProduct2.quantity) !== null && _ref45 !== void 0 ? _ref45 : (_params$orderProduct3 = params.orderProduct) === null || _params$orderProduct3 === void 0 || (_params$orderProduct3 = _params$orderProduct3._extend) === null || _params$orderProduct3 === void 0 ? void 0 : _params$orderProduct3.quantity;
4354
+ orderProductQuantity = (_ref46 = (_params$orderProduct$ = (_params$orderProduct = params.orderProduct) === null || _params$orderProduct === void 0 ? void 0 : _params$orderProduct.num) !== null && _params$orderProduct$ !== void 0 ? _params$orderProduct$ : (_params$orderProduct2 = params.orderProduct) === null || _params$orderProduct2 === void 0 ? void 0 : _params$orderProduct2.quantity) !== null && _ref46 !== void 0 ? _ref46 : (_params$orderProduct3 = params.orderProduct) === null || _params$orderProduct3 === void 0 || (_params$orderProduct3 = _params$orderProduct3._extend) === null || _params$orderProduct3 === void 0 ? void 0 : _params$orderProduct3.quantity;
4217
4355
  if (!(orderProductQuantity !== undefined && orderProductQuantity !== null && Number(orderProductQuantity) !== bookingCount)) {
4218
4356
  _context37.next = 14;
4219
4357
  break;
@@ -4429,14 +4567,46 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4429
4567
  refreshedSnapshotId: refreshedProjection.meta.snapshotId
4430
4568
  });
4431
4569
  case 72:
4570
+ product = refreshedProjection.products.find(function (item) {
4571
+ return sameAvailabilityId(item.id, refreshedCandidateBase.productId);
4572
+ });
4573
+ if (product) {
4574
+ _context37.next = 75;
4575
+ break;
4576
+ }
4577
+ throw new AvailabilityError('REVALIDATION_FAILED', '缓存重校验后商品不在 projection 中', {
4578
+ productId: refreshedCandidateBase.productId
4579
+ });
4580
+ case 75:
4432
4581
  validation = validateAvailabilitySelection(refreshedProjection, {
4433
4582
  candidate: refreshedCandidateBase,
4434
4583
  requirementSelections: params.requirementSelections,
4435
4584
  partySize: partySize,
4436
4585
  bookingCount: bookingCount
4437
4586
  });
4587
+ allowPosAvailabilityOverride = String((_this$otherParams$pla = (_this$otherParams17 = this.otherParams) === null || _this$otherParams17 === void 0 ? void 0 : _this$otherParams17.platform) !== null && _this$otherParams$pla !== void 0 ? _this$otherParams$pla : '').trim().toLowerCase() === 'pos';
4588
+ if (allowPosAvailabilityOverride && !validation.ok && validation.conflicts.every(function (conflict) {
4589
+ return POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES.has(conflict.code);
4590
+ })) {
4591
+ forced = buildPosForcedAvailabilityAssignments({
4592
+ product: product,
4593
+ resources: refreshedProjection.resources,
4594
+ candidate: refreshedCandidateBase,
4595
+ requirementSelections: params.requirementSelections,
4596
+ partySize: partySize
4597
+ });
4598
+ validation = forced.conflicts.length > 0 ? _objectSpread(_objectSpread({}, validation), {}, {
4599
+ assignments: [],
4600
+ conflicts: forced.conflicts
4601
+ }) : _objectSpread(_objectSpread({}, validation), {}, {
4602
+ ok: true,
4603
+ status: validation.availability.status,
4604
+ assignments: forced.assignments,
4605
+ conflicts: []
4606
+ });
4607
+ }
4438
4608
  if (validation.ok) {
4439
- _context37.next = 76;
4609
+ _context37.next = 81;
4440
4610
  break;
4441
4611
  }
4442
4612
  capacityConflict = validation.conflicts.find(function (conflict) {
@@ -4446,7 +4616,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4446
4616
  validation: validation,
4447
4617
  refreshedSnapshotId: refreshedProjection.meta.snapshotId
4448
4618
  });
4449
- case 76:
4619
+ case 81:
4450
4620
  // Revalidation failure must leave the caller's candidate reusable. Only publish the
4451
4621
  // refreshed projection/version after candidate and resource validation has passed;
4452
4622
  // otherwise a second Confirm from the still-open modal would incorrectly become stale.
@@ -4459,7 +4629,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4459
4629
  incrementVersion: true
4460
4630
  });
4461
4631
  revalidatedContext = this.getAvailabilityContextEntry(normalizedContextId);
4462
- _context37.next = 80;
4632
+ _context37.next = 85;
4463
4633
  return this.emitAvailabilityDiagnostic({
4464
4634
  action: 'refresh',
4465
4635
  contextId: normalizedContextId,
@@ -4470,7 +4640,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4470
4640
  previousOrderRevision: baseProjection.meta.orderRevision,
4471
4641
  reason: 'commit_cached_occupancy_revalidation'
4472
4642
  });
4473
- case 80:
4643
+ case 85:
4474
4644
  commitWriteGuard = {
4475
4645
  contextId: normalizedContextId,
4476
4646
  expectedVersion: revalidatedContext.activeVersion,
@@ -4479,27 +4649,16 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4479
4649
  expectedOrderRevision: revalidationEntry.orderRevision
4480
4650
  };
4481
4651
  refreshedCandidate = this.decorateAvailabilityCandidate(normalizedContextId, revalidatedContext.activeVersion, refreshedCandidateBase);
4482
- product = refreshedProjection.products.find(function (item) {
4483
- return sameAvailabilityId(item.id, refreshedCandidate.productId);
4484
- });
4485
- if (product) {
4486
- _context37.next = 85;
4487
- break;
4488
- }
4489
- throw new AvailabilityError('REVALIDATION_FAILED', '缓存重校验后商品不在 projection 中', {
4490
- productId: refreshedCandidate.productId
4491
- });
4492
- case 85:
4493
4652
  existingBooking = editingLine ? this.findLinkedBooking(editingLine) : undefined;
4494
4653
  existingBookingUid = existingBooking ? getBookingUid(existingBooking) : '';
4495
4654
  if (!(params.mode === 'edit' && !existingBookingUid)) {
4496
- _context37.next = 89;
4655
+ _context37.next = 91;
4497
4656
  break;
4498
4657
  }
4499
4658
  throw new AvailabilityError('PRODUCT_LINE_NOT_FOUND', '编辑商品行缺少关联 booking', {
4500
4659
  productLineUid: params.productLineUid
4501
4660
  });
4502
- case 89:
4661
+ case 91:
4503
4662
  this.assertAvailabilityCommitWriteCAS(commitWriteGuard);
4504
4663
  booking = buildBookingFromAvailabilitySelection({
4505
4664
  assignments: validation.assignments,
@@ -4507,21 +4666,21 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4507
4666
  product: product,
4508
4667
  resources: refreshedProjection.resources,
4509
4668
  bookingUid: existingBookingUid || undefined,
4510
- holder: (_ref46 = (_params$orderProduct$3 = (_params$orderProduct6 = params.orderProduct) === null || _params$orderProduct6 === void 0 || (_params$orderProduct6 = _params$orderProduct6._extend) === null || _params$orderProduct6 === void 0 ? void 0 : _params$orderProduct6.holder) !== null && _params$orderProduct$3 !== void 0 ? _params$orderProduct$3 : existingBooking === null || existingBooking === void 0 ? void 0 : existingBooking.holder) !== null && _ref46 !== void 0 ? _ref46 : existingBooking === null || existingBooking === void 0 || (_existingBooking$meta = existingBooking.metadata) === null || _existingBooking$meta === void 0 ? void 0 : _existingBooking$meta.holder,
4511
- holderIds: (_ref47 = (_ref48 = (_params$orderProduct$4 = (_params$orderProduct7 = params.orderProduct) === null || _params$orderProduct7 === void 0 || (_params$orderProduct7 = _params$orderProduct7._extend) === null || _params$orderProduct7 === void 0 ? void 0 : _params$orderProduct7.holder_id) !== null && _params$orderProduct$4 !== void 0 ? _params$orderProduct$4 : (_params$orderProduct8 = params.orderProduct) === null || _params$orderProduct8 === void 0 || (_params$orderProduct8 = _params$orderProduct8._extend) === null || _params$orderProduct8 === void 0 || (_params$orderProduct8 = _params$orderProduct8.holder) === null || _params$orderProduct8 === void 0 ? void 0 : _params$orderProduct8.form_record) !== null && _ref48 !== void 0 ? _ref48 : existingBooking === null || existingBooking === void 0 || (_existingBooking$meta2 = existingBooking.metadata) === null || _existingBooking$meta2 === void 0 ? void 0 : _existingBooking$meta2.holder_id) !== null && _ref47 !== void 0 ? _ref47 : existingBooking === null || existingBooking === void 0 || (_existingBooking$hold = existingBooking.holder) === null || _existingBooking$hold === void 0 ? void 0 : _existingBooking$hold.form_record
4669
+ holder: (_ref47 = (_params$orderProduct$3 = (_params$orderProduct6 = params.orderProduct) === null || _params$orderProduct6 === void 0 || (_params$orderProduct6 = _params$orderProduct6._extend) === null || _params$orderProduct6 === void 0 ? void 0 : _params$orderProduct6.holder) !== null && _params$orderProduct$3 !== void 0 ? _params$orderProduct$3 : existingBooking === null || existingBooking === void 0 ? void 0 : existingBooking.holder) !== null && _ref47 !== void 0 ? _ref47 : existingBooking === null || existingBooking === void 0 || (_existingBooking$meta = existingBooking.metadata) === null || _existingBooking$meta === void 0 ? void 0 : _existingBooking$meta.holder,
4670
+ holderIds: (_ref48 = (_ref49 = (_params$orderProduct$4 = (_params$orderProduct7 = params.orderProduct) === null || _params$orderProduct7 === void 0 || (_params$orderProduct7 = _params$orderProduct7._extend) === null || _params$orderProduct7 === void 0 ? void 0 : _params$orderProduct7.holder_id) !== null && _params$orderProduct$4 !== void 0 ? _params$orderProduct$4 : (_params$orderProduct8 = params.orderProduct) === null || _params$orderProduct8 === void 0 || (_params$orderProduct8 = _params$orderProduct8._extend) === null || _params$orderProduct8 === void 0 || (_params$orderProduct8 = _params$orderProduct8.holder) === null || _params$orderProduct8 === void 0 ? void 0 : _params$orderProduct8.form_record) !== null && _ref49 !== void 0 ? _ref49 : existingBooking === null || existingBooking === void 0 || (_existingBooking$meta2 = existingBooking.metadata) === null || _existingBooking$meta2 === void 0 ? void 0 : _existingBooking$meta2.holder_id) !== null && _ref48 !== void 0 ? _ref48 : existingBooking === null || existingBooking === void 0 || (_existingBooking$hold = existingBooking.holder) === null || _existingBooking$hold === void 0 ? void 0 : _existingBooking$hold.form_record
4512
4671
  });
4513
4672
  transformed = this.buildUnifiedOrderProduct(_objectSpread(_objectSpread({}, params.orderProduct), {}, {
4514
4673
  num: bookingCount,
4515
4674
  quantity: bookingCount
4516
4675
  }), 'unified_booking_sales', product);
4517
4676
  if (transformed) {
4518
- _context37.next = 94;
4677
+ _context37.next = 96;
4519
4678
  break;
4520
4679
  }
4521
4680
  throw new AvailabilityError('INVALID_TARGET_FILTER', 'orderProduct 无法转换为订单行', {
4522
4681
  orderProduct: params.orderProduct
4523
4682
  });
4524
- case 94:
4683
+ case 96:
4525
4684
  transformed.num = bookingCount;
4526
4685
  transformed.metadata = _objectSpread(_objectSpread({}, transformed.metadata || {}), {}, {
4527
4686
  unified_booking_sales: true,
@@ -4534,7 +4693,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4534
4693
  productLineUids = [];
4535
4694
  bookingUids = [];
4536
4695
  if (!(params.mode === 'edit' && editingLine && params.productLineUid)) {
4537
- _context37.next = 113;
4696
+ _context37.next = 115;
4538
4697
  break;
4539
4698
  }
4540
4699
  transformed.product_sku = (_transformed$product_ = transformed.product_sku) !== null && _transformed$product_ !== void 0 ? _transformed$product_ : editingLine.product_sku;
@@ -4544,31 +4703,35 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4544
4703
  unique_identification_number: params.productLineUid,
4545
4704
  booking_uid: existingBookingUid
4546
4705
  });
4547
- _context37.next = 107;
4548
- return this.updateOrderProduct({
4706
+ _context37.next = 109;
4707
+ return this.updateOrderProduct(_objectSpread(_objectSpread({
4549
4708
  product_id: (_transformed$product_3 = transformed.product_id) !== null && _transformed$product_3 !== void 0 ? _transformed$product_3 : editingLine.product_id,
4550
- product_variant_id: (_ref49 = (_transformed$product_4 = transformed.product_variant_id) !== null && _transformed$product_4 !== void 0 ? _transformed$product_4 : editingLine.product_variant_id) !== null && _ref49 !== void 0 ? _ref49 : 0,
4709
+ product_variant_id: (_ref50 = (_transformed$product_4 = transformed.product_variant_id) !== null && _transformed$product_4 !== void 0 ? _transformed$product_4 : editingLine.product_variant_id) !== null && _ref50 !== void 0 ? _ref50 : 0,
4551
4710
  unique_identification_number: params.productLineUid,
4552
4711
  updates: transformed,
4553
4712
  booking: booking
4554
- });
4555
- case 107:
4713
+ }, params.allowBookingReprice !== undefined ? {
4714
+ allow_booking_reprice: params.allowBookingReprice
4715
+ } : {}), params.allowBookingDiscountReapply !== undefined ? {
4716
+ allow_booking_discount_reapply: params.allowBookingDiscountReapply
4717
+ } : {}));
4718
+ case 109:
4556
4719
  productLineUid = params.productLineUid;
4557
4720
  bookingUid = existingBookingUid;
4558
4721
  productLineUids = [productLineUid];
4559
4722
  bookingUids = [bookingUid];
4560
- _context37.next = 125;
4723
+ _context37.next = 127;
4561
4724
  break;
4562
- case 113:
4725
+ case 115:
4563
4726
  beforeProductLineUids = new Set((((_this$getTempOrder4 = this.getTempOrder()) === null || _this$getTempOrder4 === void 0 ? void 0 : _this$getTempOrder4.products) || []).map(function (line) {
4564
4727
  return getProductLineUid(line);
4565
4728
  }).filter(Boolean));
4566
4729
  beforeBookingUids = new Set((((_this$getTempOrder5 = this.getTempOrder()) === null || _this$getTempOrder5 === void 0 ? void 0 : _this$getTempOrder5.bookings) || []).map(function (item) {
4567
4730
  return getBookingUid(item);
4568
4731
  }).filter(Boolean));
4569
- _context37.next = 117;
4732
+ _context37.next = 119;
4570
4733
  return this.addProductToOrder(transformed, booking);
4571
- case 117:
4734
+ case 119:
4572
4735
  products = _context37.sent;
4573
4736
  addedLines = products.filter(function (line) {
4574
4737
  var _line$product_id, _line$metadata;
@@ -4586,13 +4749,13 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4586
4749
  }).filter(Boolean);
4587
4750
  if (bookingUids.length === 0) {
4588
4751
  bookingUids = addedLines.map(function (line) {
4589
- var _ref50, _line$booking_uid, _line$metadata2;
4590
- return String((_ref50 = (_line$booking_uid = line.booking_uid) !== null && _line$booking_uid !== void 0 ? _line$booking_uid : (_line$metadata2 = line.metadata) === null || _line$metadata2 === void 0 ? void 0 : _line$metadata2.booking_uid) !== null && _ref50 !== void 0 ? _ref50 : '');
4752
+ var _ref51, _line$booking_uid, _line$metadata2;
4753
+ return String((_ref51 = (_line$booking_uid = line.booking_uid) !== null && _line$booking_uid !== void 0 ? _line$booking_uid : (_line$metadata2 = line.metadata) === null || _line$metadata2 === void 0 ? void 0 : _line$metadata2.booking_uid) !== null && _ref51 !== void 0 ? _ref51 : '');
4591
4754
  }).filter(Boolean);
4592
4755
  }
4593
4756
  productLineUid = productLineUids[productLineUids.length - 1] || '';
4594
4757
  bookingUid = bookingUids[bookingUids.length - 1] || '';
4595
- case 125:
4758
+ case 127:
4596
4759
  this.invalidateAvailabilityContextsAfterCommit();
4597
4760
  nextContext = this.getAvailabilityContextEntry(normalizedContextId);
4598
4761
  result = {
@@ -4606,21 +4769,21 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4606
4769
  productLineUids: productLineUids,
4607
4770
  bookingUids: bookingUids
4608
4771
  };
4609
- _context37.next = 130;
4772
+ _context37.next = 132;
4610
4773
  return this.core.effects.emit("".concat(this.name, ":").concat(UnifiedBookingSalesHooks.onAvailabilitySelectionCommitted), result);
4611
- case 130:
4774
+ case 132:
4612
4775
  return _context37.abrupt("return", result);
4613
- case 131:
4614
- _context37.prev = 131;
4615
- _context37.next = 134;
4776
+ case 133:
4777
+ _context37.prev = 133;
4778
+ _context37.next = 136;
4616
4779
  return this.releaseAvailabilityCommitLock(normalizedContextId);
4617
- case 134:
4618
- return _context37.finish(131);
4619
- case 135:
4780
+ case 136:
4781
+ return _context37.finish(133);
4782
+ case 137:
4620
4783
  case "end":
4621
4784
  return _context37.stop();
4622
4785
  }
4623
- }, _callee37, this, [[5,, 131, 135]]);
4786
+ }, _callee37, this, [[5,, 133, 137]]);
4624
4787
  }));
4625
4788
  function commitAvailabilitySelection(_x32, _x33) {
4626
4789
  return _commitAvailabilitySelection.apply(this, arguments);
@@ -151,6 +151,10 @@ export interface ContextualCommitAvailabilitySelectionParams {
151
151
  requirementSelections: AvailabilityRequirementSelection[];
152
152
  partySize: number;
153
153
  bookingCount?: number;
154
+ /** 编辑预约时,允许本次显式报价覆盖已落库订单行的历史价格。 */
155
+ allowBookingReprice?: boolean;
156
+ /** 编辑预约重报价后,允许订单模块重新应用已选编辑态折扣。 */
157
+ allowBookingDiscountReapply?: boolean;
154
158
  }
155
159
  export type UnifiedBookingSalesCommitAvailabilitySelectionParams = ContextualCommitAvailabilitySelectionParams;
156
160
  export interface UnifiedBookingSalesCommitAvailabilitySelectionResult {
@@ -1,46 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "BUY_X_GET_Y_FREE_STRATEGY", {
7
- enumerable: true,
8
- get: function () {
9
- return _examples.BUY_X_GET_Y_FREE_STRATEGY;
10
- }
11
- });
12
- Object.defineProperty(exports, "ITEM_REWARD_STRATEGY", {
13
- enumerable: true,
14
- get: function () {
15
- return _examples.ITEM_REWARD_STRATEGY;
16
- }
17
- });
18
- Object.defineProperty(exports, "PromotionAdapter", {
19
- enumerable: true,
20
- get: function () {
21
- return _adapter.PromotionAdapter;
22
- }
23
- });
24
- Object.defineProperty(exports, "PromotionEvaluator", {
25
- enumerable: true,
26
- get: function () {
27
- return _evaluator.PromotionEvaluator;
28
- }
29
- });
30
- Object.defineProperty(exports, "X_ITEMS_FOR_Y_PRICE_STRATEGY", {
31
- enumerable: true,
32
- get: function () {
33
- return _examples.X_ITEMS_FOR_Y_PRICE_STRATEGY;
34
- }
35
- });
36
- Object.defineProperty(exports, "default", {
37
- enumerable: true,
38
- get: function () {
39
- return _adapter.default;
40
- }
41
- });
42
- var _evaluator = require("./evaluator");
43
- var _adapter = _interopRequireWildcard(require("./adapter"));
44
- var _examples = require("./examples");
45
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
46
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
1
+ "use strict";
@@ -149,9 +149,15 @@ class ProductList extends _BaseModule.BaseModule {
149
149
  extension_type,
150
150
  strategy_context
151
151
  };
152
+ const originalCallback = options?.callback;
153
+ const subscriptionCallback = originalCallback ? async result => {
154
+ const products = Array.isArray(result?.data?.list) ? result.data.list : [];
155
+ await this.addProduct(products);
156
+ originalCallback(result);
157
+ } : undefined;
152
158
  const productsData = await this.request.post(`/product/query`, queryPayload, {
153
159
  osServer: true,
154
- callback: options?.callback,
160
+ callback: subscriptionCallback,
155
161
  subscriberId: options?.subscriberId,
156
162
  customToast: () => {}
157
163
  });
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
326
326
  date: string;
327
327
  status: string;
328
328
  week: string;
329
- weekNum: 0 | 1 | 2 | 5 | 4 | 3 | 6;
329
+ weekNum: 0 | 1 | 2 | 5 | 3 | 4 | 6;
330
330
  }[]>;
331
331
  submitTimeSlot(timeSlots: TimeSliceItem): void;
332
332
  private getScheduleDataByIds;
@@ -334,7 +334,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
334
334
  * 获取当前的客户搜索条件
335
335
  * @returns 当前搜索条件
336
336
  */
337
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
337
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
338
338
  /**
339
339
  * 获取客户列表状态(包含滚动加载相关状态)
340
340
  * @returns 客户状态
@@ -453,7 +453,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
453
453
  * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
454
454
  * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
455
455
  */
456
- decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
456
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
457
+ action: "reloadCatalog";
458
+ } | {
459
+ action: "add";
460
+ cacheItem: any;
461
+ } | {
462
+ action: "requiresDetail";
463
+ payload: AddProductRequiresDetailPayload;
464
+ } | {
465
+ action: "requiresBookingEdit";
466
+ cacheItem: any;
467
+ payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
468
+ };
457
469
  /** 规格弹窗 callback 后的第二段决策。 */
458
470
  decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
459
471
  /**
@@ -980,6 +980,125 @@ function buildBookingFromAvailabilitySelection(params) {
980
980
  }
981
981
  };
982
982
  }
983
+ const POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES = new Set(['past', 'booking_cutoff', 'resource_full', 'resource_unavailable', 'resource_capacity_exceeded',
984
+ // A required group whose selected resource is outside its window is surfaced
985
+ // as missing_resource at group level. Structural validation below still
986
+ // rejects a genuinely missing selection.
987
+ 'missing_resource']);
988
+ function matchesForcedSelectionGroup(selection, group) {
989
+ const hasGroupId = typeof selection.requirementGroupId === 'string' && selection.requirementGroupId.trim().length > 0;
990
+ const hasFormId = selection.formId !== undefined && selection.formId !== null;
991
+ if (!hasGroupId && !hasFormId) return false;
992
+ if (hasGroupId && selection.requirementGroupId !== group.id) return false;
993
+ if (hasFormId && !sameAvailabilityId(selection.formId, group.formId)) return false;
994
+ return true;
995
+ }
996
+
997
+ /**
998
+ * POS may intentionally overbook a configured time/resource. Rebuild the
999
+ * assignments from the submitted, structurally valid resource identities so
1000
+ * a full/unavailable option is not silently dropped by normal availability
1001
+ * evaluation. This deliberately ignores capacity, occupancy and resource
1002
+ * windows, while retaining product/group/resource identity and selection
1003
+ * cardinality checks.
1004
+ */
1005
+ function buildPosForcedAvailabilityAssignments(params) {
1006
+ const {
1007
+ product,
1008
+ resources,
1009
+ candidate,
1010
+ requirementSelections,
1011
+ partySize
1012
+ } = params;
1013
+ const groups = product.requirementGroups || [];
1014
+ const conflicts = [];
1015
+ const assignments = [];
1016
+ const selectionsByGroup = new Map();
1017
+ const addConflict = (code, message, details = {}) => conflicts.push({
1018
+ code,
1019
+ message,
1020
+ productId: candidate.productId,
1021
+ candidateKey: candidate.key,
1022
+ ...details
1023
+ });
1024
+ requirementSelections.forEach(selection => {
1025
+ const matchedGroups = groups.filter(group => matchesForcedSelectionGroup(selection, group));
1026
+ if (matchedGroups.length !== 1) {
1027
+ addConflict('invalid_requirement_group', '选择的资源组不属于当前商品', {
1028
+ requirementGroupId: selection.requirementGroupId,
1029
+ formId: selection.formId
1030
+ });
1031
+ return;
1032
+ }
1033
+ const group = matchedGroups[0];
1034
+ if (selectionsByGroup.has(group.id)) {
1035
+ addConflict('invalid_selection_count', `资源组 ${group.id} 被重复提交`, {
1036
+ requirementGroupId: group.id,
1037
+ formId: group.formId
1038
+ });
1039
+ return;
1040
+ }
1041
+ selectionsByGroup.set(group.id, selection);
1042
+ if (!Array.isArray(selection.resourceIds)) {
1043
+ addConflict('invalid_selection_count', `资源组 ${group.id} 的资源选择必须是数组`, {
1044
+ requirementGroupId: group.id,
1045
+ formId: group.formId
1046
+ });
1047
+ return;
1048
+ }
1049
+ const selectedResourceIds = Array.from(new Map(selection.resourceIds.map(resourceId => [String(resourceId), resourceId])).values());
1050
+ const required = group.required !== false;
1051
+ const min = Math.max(required ? 1 : 0, Number(group.min ?? (required ? 1 : 0)) || 0);
1052
+ const max = Math.max(min, Number(group.max ?? Math.max(min, 1)) || Math.max(min, 1));
1053
+ if (selectedResourceIds.length < min) {
1054
+ addConflict('missing_resource', `资源组 ${group.id} 缺少已选资源`, {
1055
+ requirementGroupId: group.id,
1056
+ formId: group.formId
1057
+ });
1058
+ return;
1059
+ }
1060
+ if (selectedResourceIds.length > max) {
1061
+ addConflict('invalid_selection_count', `资源组 ${group.id} 已选资源数量超出上限`, {
1062
+ requirementGroupId: group.id,
1063
+ formId: group.formId
1064
+ });
1065
+ return;
1066
+ }
1067
+ selectedResourceIds.forEach(resourceId => {
1068
+ const resource = resources.find(item => sameAvailabilityId(item.id, resourceId));
1069
+ const belongsToGroup = Boolean(resource && !(group.formId !== undefined && resource.formId !== undefined && !sameAvailabilityId(group.formId, resource.formId)) && !(group.resourceIds?.length && !group.resourceIds.some(id => sameAvailabilityId(id, resourceId))));
1070
+ if (!resource || !belongsToGroup) {
1071
+ addConflict('resource_unavailable', `资源 ${String(resourceId)} 不属于当前商品资源组`, {
1072
+ requirementGroupId: group.id,
1073
+ formId: group.formId,
1074
+ resourceId
1075
+ });
1076
+ return;
1077
+ }
1078
+ assignments.push({
1079
+ productId: product.id,
1080
+ resourceId,
1081
+ formId: group.formId ?? resource.formId,
1082
+ startAt: candidate.bookingStartAt || candidate.startAt,
1083
+ endAt: candidate.bookingEndAt || candidate.endAt,
1084
+ capacityRequired: Math.max(1, partySize),
1085
+ scheduleId: candidate.primaryScheduleRef?.scheduleId,
1086
+ timeSlotId: candidate.primaryScheduleRef?.timeSlotId
1087
+ });
1088
+ });
1089
+ });
1090
+ groups.filter(group => group.required !== false).forEach(group => {
1091
+ if (selectionsByGroup.has(group.id)) return;
1092
+ addConflict('missing_resource', `资源组 ${group.id} 缺少已选资源`, {
1093
+ requirementGroupId: group.id,
1094
+ formId: group.formId
1095
+ });
1096
+ });
1097
+ return {
1098
+ assignments,
1099
+ conflicts
1100
+ };
1101
+ }
983
1102
  class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
984
1103
  defaultName = 'unifiedBookingSales';
985
1104
  defaultVersion = '1.0.0';
@@ -1529,7 +1648,11 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1529
1648
  if (!normalizedPolicyId) {
1530
1649
  throw new Error('[UnifiedBookingSales] getProtocol 需要 policyId');
1531
1650
  }
1532
- return this.request.get(`/shop-policy/${encodeURIComponent(normalizedPolicyId)}`);
1651
+ let policyUrl = 'shop-policy';
1652
+ if (this.otherParams.platform === 'kiosk' || this.otherParams.platform === 'pos' || this.otherParams.platform === 'shop') {
1653
+ policyUrl = 'policy';
1654
+ }
1655
+ return this.request.get(`/${policyUrl}/${encodeURIComponent(normalizedPolicyId)}`);
1533
1656
  }
1534
1657
 
1535
1658
  /**
@@ -1721,6 +1844,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1721
1844
  }
1722
1845
  buildUnifiedOrderProduct(sourceProduct, ownershipKey, product) {
1723
1846
  const normalizedProductRaw = product?.raw || {};
1847
+ const quotationShelfId = sourceProduct._extend?.quotation_shelf_id ?? sourceProduct.quotation_shelf_id ?? sourceProduct.metadata?.quotation_shelf_id;
1724
1848
  const orderProduct = this.transformBaseProductToOrderProduct({
1725
1849
  payload: {
1726
1850
  ...sourceProduct,
@@ -1737,11 +1861,14 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1737
1861
  sourceProduct
1738
1862
  });
1739
1863
  if (orderProduct && typeof orderProduct === 'object') {
1740
- // BaseSales may rebuild metadata from its price source. Stamp ownership after that transform
1741
- // so each UnifiedBookingSales entry point can replace only its own temporary lines.
1864
+ // BaseSales may rebuild metadata from its price source. Stamp ownership and the selected
1865
+ // quotation shelf after that transform so neither booking adds nor edits lose quote identity.
1742
1866
  orderProduct.metadata = {
1743
1867
  ...(orderProduct.metadata || {}),
1744
- [ownershipKey]: true
1868
+ [ownershipKey]: true,
1869
+ ...(quotationShelfId !== undefined ? {
1870
+ quotation_shelf_id: quotationShelfId
1871
+ } : {})
1745
1872
  };
1746
1873
  }
1747
1874
  return orderProduct;
@@ -2901,12 +3028,39 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
2901
3028
  refreshedSnapshotId: refreshedProjection.meta.snapshotId
2902
3029
  });
2903
3030
  }
2904
- const validation = (0, _ResourcePlanner.validateAvailabilitySelection)(refreshedProjection, {
3031
+ const product = refreshedProjection.products.find(item => sameAvailabilityId(item.id, refreshedCandidateBase.productId));
3032
+ if (!product) {
3033
+ throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', '缓存重校验后商品不在 projection 中', {
3034
+ productId: refreshedCandidateBase.productId
3035
+ });
3036
+ }
3037
+ let validation = (0, _ResourcePlanner.validateAvailabilitySelection)(refreshedProjection, {
2905
3038
  candidate: refreshedCandidateBase,
2906
3039
  requirementSelections: params.requirementSelections,
2907
3040
  partySize,
2908
3041
  bookingCount
2909
3042
  });
3043
+ const allowPosAvailabilityOverride = String(this.otherParams?.platform ?? '').trim().toLowerCase() === 'pos';
3044
+ if (allowPosAvailabilityOverride && !validation.ok && validation.conflicts.every(conflict => POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES.has(conflict.code))) {
3045
+ const forced = buildPosForcedAvailabilityAssignments({
3046
+ product,
3047
+ resources: refreshedProjection.resources,
3048
+ candidate: refreshedCandidateBase,
3049
+ requirementSelections: params.requirementSelections,
3050
+ partySize
3051
+ });
3052
+ validation = forced.conflicts.length > 0 ? {
3053
+ ...validation,
3054
+ assignments: [],
3055
+ conflicts: forced.conflicts
3056
+ } : {
3057
+ ...validation,
3058
+ ok: true,
3059
+ status: validation.availability.status,
3060
+ assignments: forced.assignments,
3061
+ conflicts: []
3062
+ };
3063
+ }
2910
3064
  if (!validation.ok) {
2911
3065
  const capacityConflict = validation.conflicts.find(conflict => conflict.code === 'resource_capacity_exceeded');
2912
3066
  throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', capacityConflict?.message || '缓存重校验后资源已不可提交', {
@@ -2944,12 +3098,6 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
2944
3098
  expectedOrderRevision: revalidationEntry.orderRevision
2945
3099
  };
2946
3100
  const refreshedCandidate = this.decorateAvailabilityCandidate(normalizedContextId, revalidatedContext.activeVersion, refreshedCandidateBase);
2947
- const product = refreshedProjection.products.find(item => sameAvailabilityId(item.id, refreshedCandidate.productId));
2948
- if (!product) {
2949
- throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', '缓存重校验后商品不在 projection 中', {
2950
- productId: refreshedCandidate.productId
2951
- });
2952
- }
2953
3101
  const existingBooking = editingLine ? this.findLinkedBooking(editingLine) : undefined;
2954
3102
  const existingBookingUid = existingBooking ? getBookingUid(existingBooking) : '';
2955
3103
  if (params.mode === 'edit' && !existingBookingUid) {
@@ -3004,7 +3152,13 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
3004
3152
  product_variant_id: transformed.product_variant_id ?? editingLine.product_variant_id ?? 0,
3005
3153
  unique_identification_number: params.productLineUid,
3006
3154
  updates: transformed,
3007
- booking
3155
+ booking,
3156
+ ...(params.allowBookingReprice !== undefined ? {
3157
+ allow_booking_reprice: params.allowBookingReprice
3158
+ } : {}),
3159
+ ...(params.allowBookingDiscountReapply !== undefined ? {
3160
+ allow_booking_discount_reapply: params.allowBookingDiscountReapply
3161
+ } : {})
3008
3162
  });
3009
3163
  productLineUid = params.productLineUid;
3010
3164
  bookingUid = existingBookingUid;
@@ -151,6 +151,10 @@ export interface ContextualCommitAvailabilitySelectionParams {
151
151
  requirementSelections: AvailabilityRequirementSelection[];
152
152
  partySize: number;
153
153
  bookingCount?: number;
154
+ /** 编辑预约时,允许本次显式报价覆盖已落库订单行的历史价格。 */
155
+ allowBookingReprice?: boolean;
156
+ /** 编辑预约重报价后,允许订单模块重新应用已选编辑态折扣。 */
157
+ allowBookingDiscountReapply?: boolean;
154
158
  }
155
159
  export type UnifiedBookingSalesCommitAvailabilitySelectionParams = ContextualCommitAvailabilitySelectionParams;
156
160
  export interface UnifiedBookingSalesCommitAvailabilitySelectionResult {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.3.78",
4
+ "version": "2.3.79",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",