@pisell/pisellos 0.0.500 → 0.0.501

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 (57) hide show
  1. package/dist/model/strategy/adapter/itemRule/adapter.d.ts +8 -0
  2. package/dist/model/strategy/adapter/itemRule/adapter.js +52 -8
  3. package/dist/model/strategy/adapter/itemRule/examples.d.ts +15 -0
  4. package/dist/model/strategy/adapter/itemRule/examples.js +68 -1
  5. package/dist/model/strategy/adapter/itemRule/index.d.ts +1 -1
  6. package/dist/model/strategy/adapter/itemRule/index.js +1 -1
  7. package/dist/model/strategy/adapter/itemRule/type.d.ts +20 -1
  8. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  9. package/dist/modules/Order/index.d.ts +6 -0
  10. package/dist/modules/Order/index.js +42 -38
  11. package/dist/modules/Order/types.d.ts +4 -0
  12. package/dist/modules/Order/utils.d.ts +28 -0
  13. package/dist/modules/Order/utils.js +93 -13
  14. package/dist/modules/ProductList/index.js +2 -2
  15. package/dist/modules/Quotation/index.js +6 -3
  16. package/dist/modules/SalesSummary/types.d.ts +2 -1
  17. package/dist/modules/SalesSummary/utils.js +10 -10
  18. package/dist/modules/Schedule/utils.d.ts +1 -1
  19. package/dist/solution/BookingByStep/index.d.ts +2 -2
  20. package/dist/solution/ScanOrder/index.d.ts +7 -0
  21. package/dist/solution/ScanOrder/index.js +284 -67
  22. package/dist/solution/ScanOrder/types.d.ts +22 -5
  23. package/dist/solution/ScanOrder/utils.d.ts +26 -0
  24. package/dist/solution/ScanOrder/utils.js +191 -44
  25. package/dist/solution/VenueBooking/index.d.ts +14 -0
  26. package/dist/solution/VenueBooking/index.js +318 -144
  27. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  28. package/dist/solution/VenueBooking/utils/dateSummary.js +6 -4
  29. package/lib/model/strategy/adapter/itemRule/adapter.d.ts +8 -0
  30. package/lib/model/strategy/adapter/itemRule/adapter.js +41 -2
  31. package/lib/model/strategy/adapter/itemRule/examples.d.ts +15 -0
  32. package/lib/model/strategy/adapter/itemRule/examples.js +47 -0
  33. package/lib/model/strategy/adapter/itemRule/index.d.ts +1 -1
  34. package/lib/model/strategy/adapter/itemRule/index.js +2 -0
  35. package/lib/model/strategy/adapter/itemRule/type.d.ts +20 -1
  36. package/lib/model/strategy/adapter/promotion/index.js +0 -49
  37. package/lib/modules/Order/index.d.ts +6 -0
  38. package/lib/modules/Order/index.js +20 -36
  39. package/lib/modules/Order/types.d.ts +4 -0
  40. package/lib/modules/Order/utils.d.ts +28 -0
  41. package/lib/modules/Order/utils.js +78 -9
  42. package/lib/modules/ProductList/index.js +3 -2
  43. package/lib/modules/Quotation/index.js +3 -0
  44. package/lib/modules/SalesSummary/types.d.ts +2 -1
  45. package/lib/modules/SalesSummary/utils.js +2 -2
  46. package/lib/modules/Schedule/utils.d.ts +1 -1
  47. package/lib/solution/BookingByStep/index.d.ts +2 -2
  48. package/lib/solution/ScanOrder/index.d.ts +7 -0
  49. package/lib/solution/ScanOrder/index.js +162 -18
  50. package/lib/solution/ScanOrder/types.d.ts +22 -5
  51. package/lib/solution/ScanOrder/utils.d.ts +26 -0
  52. package/lib/solution/ScanOrder/utils.js +128 -19
  53. package/lib/solution/VenueBooking/index.d.ts +14 -0
  54. package/lib/solution/VenueBooking/index.js +156 -30
  55. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  56. package/lib/solution/VenueBooking/utils/dateSummary.js +13 -4
  57. package/package.json +1 -1
@@ -2,9 +2,10 @@ export interface SalesSummaryProduct {
2
2
  product_id: number | null;
3
3
  product_variant_id: number;
4
4
  num: number;
5
+ /** 券后单品单价(订单域成交单价),由 OrderModule 维护。 */
5
6
  selling_price: string;
7
+ /** 券前单品单价(店铺售价)。 */
6
8
  original_price: string;
7
- payment_price: string;
8
9
  tax_fee: string;
9
10
  is_charge_tax?: number;
10
11
  product_option_item?: any[];
@@ -82,7 +82,7 @@ function getBundleUnitPrice(product, useOriginal = false) {
82
82
  }
83
83
  function getUnitPaymentTotal(product) {
84
84
  const variantPrice = getVariantPrice(product);
85
- const basePrice = variantPrice || toDecimal(product.selling_price || product.payment_price);
85
+ const basePrice = variantPrice || toDecimal(product.selling_price);
86
86
  return basePrice.plus(getOptionUnitPrice(product)).plus(getBundleUnitPrice(product));
87
87
  }
88
88
  function getUnitOriginalTotal(product) {
@@ -231,7 +231,7 @@ function calculateSingleItemTax(params) {
231
231
  function getMainProductPaymentTotal(product) {
232
232
  var _a, _b, _c, _d;
233
233
  const variantPrice = getVariantPrice(product);
234
- let total = variantPrice || toDecimal(((_a = product.metadata) == null ? void 0 : _a.main_product_selling_price) ?? product.selling_price ?? product.payment_price);
234
+ let total = variantPrice || toDecimal(((_a = product.metadata) == null ? void 0 : _a.main_product_selling_price) ?? product.selling_price);
235
235
  const mainDiscountList = ((_c = (_b = product._origin) == null ? void 0 : _b.product) == null ? void 0 : _c.discount_list) || ((_d = product._origin) == null ? void 0 : _d.discount_list) || [];
236
236
  const mainDiscountAmount = getDiscountListAmount(
237
237
  mainDiscountList.filter((d) => {
@@ -46,7 +46,7 @@ export declare const formatScheduleResult: (schedule: ScheduleItem) => {
46
46
  };
47
47
  export declare const calcScheduleDateRange: (schedule: ScheduleItem) => any[];
48
48
  export declare const calcCalendarDataBySchedules: (schedules: ScheduleItem[]) => unknown[];
49
- export declare const calcMinTimeMaxTimeBySchedules: (schedules: ScheduleItem[], scheduleAllMap?: ScheduleAllMap, selectDate?: string) => {};
49
+ export declare const calcMinTimeMaxTimeBySchedules: (schedules: ScheduleItem[], scheduleAllMap?: ScheduleAllMap, selectDate?: string) => ScheduleAllMap;
50
50
  /**
51
51
  * @title: 格式化日程数据
52
52
  * @description:
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 1 | 2 | 3 | 4 | 5 | 6;
314
+ weekNum: 0 | 5 | 1 | 4 | 2 | 3 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -330,7 +330,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
330
330
  count: number;
331
331
  left: number;
332
332
  summaryCount: number;
333
- status: "lots_of_space" | "filling_up_fast" | "sold_out";
333
+ status: "sold_out" | "lots_of_space" | "filling_up_fast";
334
334
  }[];
335
335
  /**
336
336
  * 找到多个资源的公共可用时间段
@@ -27,6 +27,8 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
27
27
  private itemRuleConfigsPromise;
28
28
  private itemRulePrefillApplied;
29
29
  private itemRuleRuntimeConfig;
30
+ /** 最近一次 checkResourceAvailable 从预约规则 link 拉取的商品快照 */
31
+ private enabledReservationRuleProducts;
30
32
  private getScanOrderLoggerContext;
31
33
  private serializeError;
32
34
  private addScanOrderLog;
@@ -87,4 +89,9 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
87
89
  }>;
88
90
  getProductList(): Promise<any>;
89
91
  getOtherParams(): Record<string, any>;
92
+ setOtherParams(params: Record<string, any>, { cover }?: {
93
+ cover?: boolean;
94
+ }): Promise<void>;
95
+ setEntryPaxNumber(number: number): Promise<void>;
96
+ getEntryPaxNumber(): number | null;
90
97
  }
@@ -37,6 +37,8 @@ var import_BaseModule = require("../../modules/BaseModule");
37
37
  var import_types = require("./types");
38
38
  var import_utils = require("./utils");
39
39
  var import_types2 = require("../BookingByStep/types");
40
+ var import_ProductList = require("../../modules/ProductList");
41
+ var import_utils2 = require("../../modules/Order/utils");
40
42
  var import_dayjs = __toESM(require("dayjs"));
41
43
  var import_itemRule = require("../../model/strategy/adapter/itemRule");
42
44
  __reExport(ScanOrder_exports, require("./types"), module.exports);
@@ -59,7 +61,8 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
59
61
  cartValidation: {
60
62
  passed: null,
61
63
  failures: []
62
- }
64
+ },
65
+ entryPaxNumber: 1
63
66
  };
64
67
  this.otherParams = {};
65
68
  this.itemRuleEvaluator = new import_itemRule.ItemRuleEvaluator();
@@ -67,6 +70,8 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
67
70
  this.itemRuleConfigsPromise = null;
68
71
  this.itemRulePrefillApplied = false;
69
72
  this.itemRuleRuntimeConfig = {};
73
+ /** 最近一次 checkResourceAvailable 从预约规则 link 拉取的商品快照 */
74
+ this.enabledReservationRuleProducts = [];
70
75
  }
71
76
  getScanOrderLoggerContext() {
72
77
  return {
@@ -410,19 +415,28 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
410
415
  }
411
416
  }
412
417
  async submitScanOrder() {
413
- var _a;
418
+ var _a, _b, _c, _d, _e;
414
419
  this.logMethodStart("submitScanOrder");
415
420
  try {
416
421
  await this.validateBeforeSubmitByItemRule();
417
422
  if (!this.store.order) {
418
423
  throw new Error("scanOrder解决方案需要 order 模块支持");
419
424
  }
425
+ const pax = (0, import_utils2.normalizeSubmitCollectPaxValue)(this.store.entryPaxNumber);
426
+ this.store.entryPaxNumber = pax;
427
+ const tempOrderForSubmit = this.store.order.ensureTempOrder();
428
+ tempOrderForSubmit.metadata = { ...tempOrderForSubmit.metadata, collect_pax: pax };
429
+ this.store.order.persistTempOrder();
420
430
  const result = await this.store.order.submitTempOrder({
421
- cacheId: this.cacheId
431
+ cacheId: this.cacheId,
432
+ platform: (_a = this.otherParams) == null ? void 0 : _a.platform,
433
+ businessCode: (_b = this.otherParams) == null ? void 0 : _b.businessCode,
434
+ channel: (_c = this.otherParams) == null ? void 0 : _c.channel,
435
+ type: (_d = this.otherParams) == null ? void 0 : _d.type
422
436
  });
423
437
  const tempOrder = this.store.order.getTempOrder();
424
438
  this.logMethodSuccess("submitScanOrder", {
425
- productCount: ((_a = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _a.length) || 0
439
+ productCount: ((_e = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _e.length) || 0
426
440
  });
427
441
  return result;
428
442
  } catch (error) {
@@ -691,22 +705,13 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
691
705
  (sourceItem == null ? void 0 : sourceItem.price) ?? (sourceItem == null ? void 0 : sourceItem.selling_price),
692
706
  "0.00"
693
707
  );
694
- const originalPrice = (0, import_utils.toPriceString)(
695
- (sourceItem == null ? void 0 : sourceItem.original_price) ?? (sourceItem == null ? void 0 : sourceItem.price) ?? sellingPrice,
696
- sellingPrice
697
- );
698
- const paymentPrice = (0, import_utils.toPriceString)(
699
- (sourceItem == null ? void 0 : sourceItem.payment_price) ?? (sourceItem == null ? void 0 : sourceItem.price) ?? sellingPrice,
700
- sellingPrice
701
- );
702
708
  tempOrder.products.push(
703
709
  (0, import_utils.normalizeOrderProduct)({
704
710
  product_id: productId,
705
711
  product_variant_id: productVariantId,
706
712
  num: targetQuantity,
707
713
  selling_price: sellingPrice,
708
- original_price: originalPrice,
709
- payment_price: paymentPrice,
714
+ original_price: sellingPrice,
710
715
  metadata: {
711
716
  item_rule_prefill: true,
712
717
  item_rule_id: prefillItem.ruleId
@@ -758,6 +763,10 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
758
763
  });
759
764
  }
760
765
  async applyItemRulePrefill() {
766
+ var _a, _b;
767
+ if ((_b = (_a = this.store.order) == null ? void 0 : _a.getLastOrderInfo) == null ? void 0 : _b.call(_a)) {
768
+ return;
769
+ }
761
770
  this.logMethodStart("applyItemRulePrefill");
762
771
  await this.applyPrefillByItemRule();
763
772
  await this.refreshItemRuleQuantityLimits();
@@ -919,7 +928,8 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
919
928
  isExclusive,
920
929
  isFull,
921
930
  orderNumberPrefix,
922
- raw: config
931
+ raw: config,
932
+ table_form_record: (config == null ? void 0 : config.table_form_record) ?? null
923
933
  };
924
934
  }
925
935
  async fetchTableConfigByResourceId(resourceId) {
@@ -943,7 +953,7 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
943
953
  // 通过 resource_id + 店铺配置
944
954
  // hasOrderId 表示 url 上是否有 orderid,如果是的话,后续的流程会走加单
945
955
  async checkResourceAvailable(resourceId, hasOrderId) {
946
- var _a, _b, _c, _d, _e, _f;
956
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
947
957
  this.logMethodStart("checkResourceAvailable", {
948
958
  resourceId
949
959
  });
@@ -981,6 +991,7 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
981
991
  relation_id: resourceState.relationId,
982
992
  table_form_id: resourceState.tableFormId,
983
993
  deskmate_valid: resourceState.deskmate_valid,
994
+ table_form_record: resourceState.table_form_record,
984
995
  policy: (_c = config == null ? void 0 : config.table_form_record) == null ? void 0 : _c.policy,
985
996
  partyroom_booking: (_d = config == null ? void 0 : config.table_form_record) == null ? void 0 : _d.partyroom_booking
986
997
  };
@@ -988,6 +999,89 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
988
999
  tempOrder.relation_id = resourceId || ((_e = this.otherParams) == null ? void 0 : _e.relation_id);
989
1000
  tempOrder.table_form_id = resourceState.tableFormId;
990
1001
  tempOrder.resource_id = resourceId;
1002
+ const reservationLinkIds = (0, import_utils.collectLinkProductIdsFromReservationRules)(
1003
+ dineInConfig["reservation.enabled_reservation_rules"]
1004
+ );
1005
+ if (reservationLinkIds.length === 0) {
1006
+ this.enabledReservationRuleProducts = [];
1007
+ if (this.store.resource) {
1008
+ delete this.store.resource.requestEntryPax;
1009
+ delete this.store.resource.requestPaxMin;
1010
+ delete this.store.resource.requestPaxMax;
1011
+ }
1012
+ } else {
1013
+ tempOrder.metadata = { ...tempOrder.metadata || {} };
1014
+ delete tempOrder.metadata.table_occupancy_duration;
1015
+ const reservationProductList = new import_ProductList.ProductList(
1016
+ `${this.name}_reservationEnabledRules`,
1017
+ this.defaultVersion
1018
+ );
1019
+ await reservationProductList.initialize(this.core, {
1020
+ store: { list: [], selectProducts: [] },
1021
+ otherParams: {
1022
+ ...this.otherParams,
1023
+ fatherModule: this.name,
1024
+ openCache: Boolean(this.cacheId),
1025
+ cacheId: this.cacheId
1026
+ }
1027
+ });
1028
+ const scheduleDate = (0, import_dayjs.default)().format("YYYY-MM-DD");
1029
+ const scheduleDatetime = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
1030
+ const loaded = await reservationProductList.loadProducts({
1031
+ product_ids: reservationLinkIds,
1032
+ schedule_date: scheduleDate,
1033
+ schedule_datetime: scheduleDatetime,
1034
+ cacheId: this.cacheId
1035
+ });
1036
+ if (Array.isArray(loaded)) {
1037
+ this.enabledReservationRuleProducts = loaded;
1038
+ const occupancyMinutes = (0, import_utils.pickFirstDurationMinutesFromProducts)(loaded);
1039
+ if (occupancyMinutes !== void 0) {
1040
+ tempOrder.metadata.table_occupancy_duration = occupancyMinutes;
1041
+ }
1042
+ if ((0, import_utils.hasCustomCapacityProduct)(loaded)) {
1043
+ availabilityInfo.requestEntryPax = 1;
1044
+ if (this.store.resource)
1045
+ this.store.resource.requestEntryPax = 1;
1046
+ delete availabilityInfo.requestPaxMin;
1047
+ delete availabilityInfo.requestPaxMax;
1048
+ if (this.store.resource) {
1049
+ delete this.store.resource.requestPaxMin;
1050
+ delete this.store.resource.requestPaxMax;
1051
+ }
1052
+ const paxBounds = (0, import_utils.pickFirstCustomCapacityPaxBounds)(loaded);
1053
+ if ((paxBounds == null ? void 0 : paxBounds.min) !== void 0) {
1054
+ availabilityInfo.requestPaxMin = paxBounds.min;
1055
+ if (this.store.resource)
1056
+ this.store.resource.requestPaxMin = paxBounds.min;
1057
+ }
1058
+ if ((paxBounds == null ? void 0 : paxBounds.max) !== void 0) {
1059
+ availabilityInfo.requestPaxMax = paxBounds.max;
1060
+ if (this.store.resource)
1061
+ this.store.resource.requestPaxMax = paxBounds.max;
1062
+ }
1063
+ } else if (this.store.resource) {
1064
+ delete this.store.resource.requestEntryPax;
1065
+ delete this.store.resource.requestPaxMin;
1066
+ delete this.store.resource.requestPaxMax;
1067
+ }
1068
+ } else {
1069
+ this.enabledReservationRuleProducts = [];
1070
+ if (this.store.resource) {
1071
+ delete this.store.resource.requestEntryPax;
1072
+ delete this.store.resource.requestPaxMin;
1073
+ delete this.store.resource.requestPaxMax;
1074
+ }
1075
+ void this.addScanOrderLog({
1076
+ level: "error",
1077
+ title: "[ScanOrder] enabled_reservation_rules product query failed",
1078
+ payload: {
1079
+ linkIds: reservationLinkIds,
1080
+ error: this.serializeError(loaded)
1081
+ }
1082
+ });
1083
+ }
1084
+ }
991
1085
  (_f = this.store.order) == null ? void 0 : _f.persistTempOrder();
992
1086
  if (availabilityInfo.mode === "idle") {
993
1087
  await this.addNewOrder();
@@ -995,8 +1089,32 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
995
1089
  if (availabilityInfo.mode === "additional_order" || availabilityInfo.mode === "additional_order_with_code") {
996
1090
  tempOrder.order_id = resourceState.lastOrderId;
997
1091
  }
998
- await this.refreshItemRuleQuantityLimits();
999
- await this.refreshCartValidationPassed();
1092
+ if (tempOrder.order_id) {
1093
+ const res = await ((_g = this.store.order) == null ? void 0 : _g.getOrderInfoByRemote(tempOrder.order_id));
1094
+ const entryPaxNumber = (_k = (_j = (_i = (_h = res == null ? void 0 : res.data) == null ? void 0 : _h.bookings) == null ? void 0 : _i.find((p) => {
1095
+ var _a2;
1096
+ return (_a2 = p.metadata) == null ? void 0 : _a2.collect_pax;
1097
+ })) == null ? void 0 : _j.metadata) == null ? void 0 : _k.collect_pax;
1098
+ if (entryPaxNumber) {
1099
+ await this.setEntryPaxNumber(entryPaxNumber);
1100
+ }
1101
+ }
1102
+ const lastOrderInfo = (_m = (_l = this.store.order) == null ? void 0 : _l.getLastOrderInfo) == null ? void 0 : _m.call(_l);
1103
+ const historicalItems = hasOrderId && Array.isArray(lastOrderInfo == null ? void 0 : lastOrderInfo.products) ? lastOrderInfo.products.reduce((acc, p) => {
1104
+ if (typeof (p == null ? void 0 : p.product_id) !== "number")
1105
+ return acc;
1106
+ acc.push({
1107
+ product_id: p.product_id,
1108
+ quantity: Number(p.product_quantity) || 0,
1109
+ ...typeof p.product_variant_id === "number" ? { product_variant_id: p.product_variant_id } : {}
1110
+ });
1111
+ return acc;
1112
+ }, []) : [];
1113
+ await this.setItemRuleRuntimeConfig({
1114
+ serviceType: (_n = this.otherParams) == null ? void 0 : _n.businessCode,
1115
+ submissionIndex: hasOrderId ? 1 : 0,
1116
+ historicalItems
1117
+ });
1000
1118
  this.logMethodSuccess("checkResourceAvailable", {
1001
1119
  resourceId,
1002
1120
  mode: availabilityInfo.mode,
@@ -1063,6 +1181,32 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
1063
1181
  getOtherParams() {
1064
1182
  return this.otherParams;
1065
1183
  }
1184
+ async setOtherParams(params, { cover = false } = {}) {
1185
+ if (cover) {
1186
+ this.otherParams = params;
1187
+ } else {
1188
+ this.otherParams = { ...this.otherParams, ...params };
1189
+ }
1190
+ }
1191
+ async setEntryPaxNumber(number) {
1192
+ const pax = (0, import_utils2.normalizeSubmitCollectPaxValue)(number);
1193
+ this.store.entryPaxNumber = pax;
1194
+ if (this.store.order) {
1195
+ const t = this.store.order.ensureTempOrder();
1196
+ t.metadata = { ...t.metadata, collect_pax: pax };
1197
+ this.store.order.persistTempOrder();
1198
+ }
1199
+ this.itemRuleRuntimeConfig = {
1200
+ ...this.itemRuleRuntimeConfig,
1201
+ pax: { total: pax, adult: 0, child: 0 }
1202
+ };
1203
+ this.itemRulePrefillApplied = false;
1204
+ await this.refreshItemRuleQuantityLimits();
1205
+ await this.refreshCartValidationPassed();
1206
+ }
1207
+ getEntryPaxNumber() {
1208
+ return this.store.entryPaxNumber;
1209
+ }
1066
1210
  };
1067
1211
  // Annotate the CommonJS export names for ESM import in node:
1068
1212
  0 && (module.exports = {
@@ -36,9 +36,10 @@ export interface ScanOrderOrderProduct extends ScanOrderOrderProductIdentity {
36
36
  order_detail_id: number | null;
37
37
  num: number;
38
38
  product_option_item: any[];
39
+ /** 券后单品单价(= 订单域实际成交单价)。未应用券时等同 original_price。 */
39
40
  selling_price: string;
41
+ /** 券前单品单价(= 店铺售价),不承载后台划线价语义。 */
40
42
  original_price: string;
41
- payment_price: string;
42
43
  tax_fee: string;
43
44
  is_charge_tax: number;
44
45
  discount_list: any[];
@@ -47,6 +48,11 @@ export interface ScanOrderOrderProduct extends ScanOrderOrderProductIdentity {
47
48
  _origin?: Record<string, any>;
48
49
  }
49
50
  export interface ScanOrderSubmitProduct extends Omit<ScanOrderOrderProduct, '_origin' | 'identity_key'> {
51
+ /**
52
+ * 出站兼容字段:SDK 内部不再消费 payment_price,
53
+ * 仅在提交后端时由 selling_price 派生,保持原有后端契约。
54
+ */
55
+ payment_price: string;
50
56
  }
51
57
  export interface ScanOrderSummary {
52
58
  product_quantity: number;
@@ -121,6 +127,7 @@ export interface ScanOrderTempOrder {
121
127
  holder: Record<string, any> | null;
122
128
  summary: ScanOrderSummary;
123
129
  metadata: Record<string, any>;
130
+ lastOrderInfo?: Record<string, any>;
124
131
  }
125
132
  export interface ScanOrderSubmitPayload extends Omit<ScanOrderTempOrder, 'platform' | 'products' | 'created_at' | 'summary' | 'surcharges'> {
126
133
  platform: 'H5' | 'PC';
@@ -132,6 +139,11 @@ export interface ScanOrderSubmitPayload extends Omit<ScanOrderTempOrder, 'platfo
132
139
  products: ScanOrderSubmitProduct[];
133
140
  }
134
141
  export type ScanOrderAvailabilityMode = 'idle' | 'shop_closed' | 'resource_block' | 'resource_busy' | 'additional_order_with_code' | 'additional_order';
142
+ export interface ScanOrderTableFormRecord {
143
+ policy?: string | null;
144
+ partyroom_booking?: string | null;
145
+ [key: string]: any;
146
+ }
135
147
  export interface ScanOrderAvailabilityInfo {
136
148
  mode: ScanOrderAvailabilityMode;
137
149
  order_id?: string;
@@ -139,8 +151,16 @@ export interface ScanOrderAvailabilityInfo {
139
151
  table_form_id?: string;
140
152
  deskmate_valid?: boolean;
141
153
  errorTips?: string;
154
+ /** `/order/dining/table/config` 返回的 `table_form_record` 原样透出 */
155
+ table_form_record?: ScanOrderTableFormRecord | null;
142
156
  policy?: string | null;
143
157
  partyroom_booking?: string | null;
158
+ /** 预约规则关联商品存在 custom 容量时,由 checkResourceAvailable 置为 1 */
159
+ requestEntryPax?: number;
160
+ /** 首个 `capacity.type === 'custom'` 商品里 `custom[0]` 的 min(人数下限) */
161
+ requestPaxMin?: number;
162
+ /** 首个 `capacity.type === 'custom'` 商品里 `custom[0]` 的 max(人数上限) */
163
+ requestPaxMax?: number;
144
164
  }
145
165
  export interface ScanOrderTableSnackConfig {
146
166
  snack?: boolean | number | string;
@@ -150,9 +170,6 @@ export interface ScanOrderOrderNumberPrefixConfig {
150
170
  table_order?: string;
151
171
  pos?: string;
152
172
  }
153
- export interface ScanOrderTableFormRecord {
154
- policy?: string | null;
155
- }
156
173
  export interface ScanOrderTableConfigApiData {
157
174
  table_max_number?: number | string | null;
158
175
  order_count?: number | string | null;
@@ -183,7 +200,6 @@ export interface ScanOrderResourceState extends ScanOrderAvailabilityInfo {
183
200
  isFull: boolean;
184
201
  orderNumberPrefix: ScanOrderOrderNumberPrefixConfig[];
185
202
  raw: ScanOrderTableConfigApiData | null;
186
- table_form_record?: ScanOrderTableFormRecord | null;
187
203
  }
188
204
  export interface ScanOrderState {
189
205
  entryContext: ScanOrderEntryContext | null;
@@ -201,6 +217,7 @@ export interface ScanOrderState {
201
217
  passed: boolean | null;
202
218
  failures: QuantityCheckResult[];
203
219
  };
220
+ entryPaxNumber: number | null;
204
221
  }
205
222
  export interface ScanOrderLoggerRuntimeConfig {
206
223
  provider?: ScanOrderLoggerProviderType;
@@ -1,6 +1,7 @@
1
1
  import { ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderSummary, ScanOrderTempOrder } from './types';
2
2
  import type { CartItemSummary, ItemRuleBusinessData, PaxInfo, QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
3
3
  import type { StrategyConfig } from '../../model/strategy/type';
4
+ import type { ProductData } from '../../modules/Product/types';
4
5
  /**
5
6
  * 构建金额全为 0 的空 summary。
6
7
  * 作为尚未计算金额时的兜底默认值,避免下游因 undefined 报错。
@@ -58,8 +59,15 @@ export declare function resolveSkuMatchedQuantityLimits(params: {
58
59
  export declare function aggregateItemRuleLimit(matchedLimits: QuantityLimitResult[]): {
59
60
  min: number | undefined;
60
61
  max: number | undefined;
62
+ remainingMax: number | undefined;
61
63
  exact: number | undefined;
62
64
  mustInclude: boolean;
65
+ validationMessage: string | undefined;
66
+ rawValidationMessage: string | Record<string, string> | undefined;
67
+ maxValidationMessage: string | undefined;
68
+ rawMaxValidationMessage: string | Record<string, string> | undefined;
69
+ minValidationMessage: string | undefined;
70
+ rawMinValidationMessage: string | Record<string, string> | undefined;
63
71
  } | null;
64
72
  export declare function buildItemRuleBusinessData(params: {
65
73
  tempOrder: ScanOrderTempOrder;
@@ -91,3 +99,21 @@ export declare function getProductIdentityIndex(products: ScanOrderOrderProduct[
91
99
  * - 保留 _origin 供后续业务流程(如促销规则)使用
92
100
  */
93
101
  export declare function normalizeOrderProduct(product: Partial<ScanOrderOrderProduct> & ScanOrderOrderProductIdentity): ScanOrderOrderProduct;
102
+ /**
103
+ * 从 reservation.enabled_reservation_rules 中收集 type=link 的商品 id。
104
+ */
105
+ export declare function collectLinkProductIdsFromReservationRules(rules: unknown): number[];
106
+ /**
107
+ * 返回列表中第一个带有效 duration.value(分钟)的商品时长。
108
+ */
109
+ export declare function pickFirstDurationMinutesFromProducts(products: ProductData[]): number | undefined;
110
+ /** 是否存在 capacity.type === 'custom' 的商品 */
111
+ export declare function hasCustomCapacityProduct(products: ProductData[]): boolean;
112
+ /**
113
+ * 在商品列表中找到第一个 `capacity.type === 'custom'` 的商品,取其 `custom` 数组第一项的 min/max。
114
+ * 仅返回有限数字字段;若均无法解析则返回 `undefined`。
115
+ */
116
+ export declare function pickFirstCustomCapacityPaxBounds(products: ProductData[]): {
117
+ min?: number;
118
+ max?: number;
119
+ } | undefined;