@pisell/pisellos 2.2.180 → 2.2.182

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 (175) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  2. package/dist/modules/BookingContext/index.d.ts +37 -0
  3. package/dist/modules/BookingContext/index.js +436 -0
  4. package/dist/modules/BookingContext/types.d.ts +102 -0
  5. package/dist/modules/BookingContext/types.js +51 -0
  6. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
  7. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +276 -0
  8. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
  9. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +137 -0
  10. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +75 -0
  11. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +215 -0
  12. package/dist/modules/BookingContext/utils/flexible.d.ts +28 -0
  13. package/dist/modules/BookingContext/utils/flexible.js +56 -0
  14. package/dist/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
  15. package/dist/modules/BookingContext/utils/formatResourceList.js +38 -0
  16. package/dist/modules/BookingContext/utils/index.d.ts +11 -0
  17. package/dist/modules/BookingContext/utils/index.js +11 -0
  18. package/dist/modules/BookingContext/utils/noResource.d.ts +13 -0
  19. package/dist/modules/BookingContext/utils/noResource.js +77 -0
  20. package/dist/modules/BookingContext/utils/productExtend.d.ts +72 -0
  21. package/dist/modules/BookingContext/utils/productExtend.js +339 -0
  22. package/dist/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
  23. package/dist/modules/BookingContext/utils/resourceErrors.js +74 -0
  24. package/dist/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
  25. package/dist/modules/BookingContext/utils/resourceSelection.js +24 -0
  26. package/dist/modules/BookingContext/utils/resources.d.ts +80 -0
  27. package/dist/modules/BookingContext/utils/resources.js +486 -0
  28. package/dist/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
  29. package/dist/modules/BookingContext/utils/serviceTimes.js +151 -0
  30. package/dist/modules/BookingContext/utils/timeSlices.d.ts +42 -0
  31. package/dist/modules/BookingContext/utils/timeSlices.js +100 -0
  32. package/dist/modules/Customer/index.d.ts +6 -0
  33. package/dist/modules/Customer/index.js +129 -83
  34. package/dist/modules/Customer/types.d.ts +2 -0
  35. package/dist/modules/Discount/index.js +4 -3
  36. package/dist/modules/Discount/types.d.ts +1 -0
  37. package/dist/modules/Order/index.d.ts +101 -10
  38. package/dist/modules/Order/index.js +1444 -490
  39. package/dist/modules/Order/types.d.ts +201 -18
  40. package/dist/modules/Order/types.js +31 -0
  41. package/dist/modules/Order/utils/manualProductDiscount.d.ts +106 -0
  42. package/dist/modules/Order/utils/manualProductDiscount.js +210 -0
  43. package/dist/modules/Order/utils.d.ts +83 -1
  44. package/dist/modules/Order/utils.js +405 -61
  45. package/dist/modules/Product/index.d.ts +1 -1
  46. package/dist/modules/Quotation/index.d.ts +0 -1
  47. package/dist/modules/Quotation/index.js +23 -21
  48. package/dist/modules/Rules/index.d.ts +4 -0
  49. package/dist/modules/Rules/index.js +43 -39
  50. package/dist/modules/Rules/types.d.ts +1 -0
  51. package/dist/modules/SalesSummary/index.js +4 -2
  52. package/dist/modules/SalesSummary/utils.js +21 -7
  53. package/dist/modules/Schedule/index.js +6 -2
  54. package/dist/modules/index.d.ts +1 -0
  55. package/dist/modules/index.js +2 -1
  56. package/dist/server/index.js +87 -29
  57. package/dist/server/modules/order/index.d.ts +23 -0
  58. package/dist/server/modules/order/index.js +123 -46
  59. package/dist/server/modules/order/utils/filterOrders.js +20 -6
  60. package/dist/server/modules/products/index.d.ts +1 -1
  61. package/dist/server/modules/products/index.js +130 -113
  62. package/dist/server/modules/schedule/index.js +13 -6
  63. package/dist/solution/BaseSales/index.d.ts +89 -7
  64. package/dist/solution/BaseSales/index.js +1489 -366
  65. package/dist/solution/BaseSales/types.d.ts +67 -1
  66. package/dist/solution/BaseSales/types.js +3 -1
  67. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +275 -0
  68. package/dist/solution/BaseSales/utils/cartPromotion.js +1258 -0
  69. package/dist/solution/BaseSales/utils/quotationPrice.d.ts +7 -0
  70. package/dist/solution/BaseSales/utils/quotationPrice.js +237 -0
  71. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +68 -16
  72. package/dist/solution/BaseSales/utils.js +46 -8
  73. package/dist/solution/BookingByStep/index.d.ts +1 -1
  74. package/dist/solution/BookingTicket/index.d.ts +152 -2
  75. package/dist/solution/BookingTicket/index.js +848 -184
  76. package/dist/solution/BookingTicket/types.d.ts +2 -0
  77. package/dist/solution/BookingTicket/types.js +3 -0
  78. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +113 -0
  79. package/dist/solution/BookingTicket/utils/addProductDecision.js +346 -0
  80. package/dist/solution/BookingTicket/utils/cartView.js +4 -2
  81. package/dist/solution/ScanOrder/index.d.ts +9 -3
  82. package/dist/solution/ScanOrder/index.js +231 -128
  83. package/dist/solution/ScanOrder/utils.js +46 -8
  84. package/dist/solution/VenueBooking/index.d.ts +5 -2
  85. package/dist/solution/VenueBooking/index.js +103 -55
  86. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +4 -0
  87. package/dist/solution/VenueBooking/utils/slotMerge.js +10 -0
  88. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  89. package/lib/modules/BookingContext/index.d.ts +37 -0
  90. package/lib/modules/BookingContext/index.js +297 -0
  91. package/lib/modules/BookingContext/types.d.ts +102 -0
  92. package/lib/modules/BookingContext/types.js +34 -0
  93. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.d.ts +16 -0
  94. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +271 -0
  95. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +8 -0
  96. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +141 -0
  97. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +75 -0
  98. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +198 -0
  99. package/lib/modules/BookingContext/utils/flexible.d.ts +28 -0
  100. package/lib/modules/BookingContext/utils/flexible.js +80 -0
  101. package/lib/modules/BookingContext/utils/formatResourceList.d.ts +8 -0
  102. package/lib/modules/BookingContext/utils/formatResourceList.js +50 -0
  103. package/lib/modules/BookingContext/utils/index.d.ts +11 -0
  104. package/lib/modules/BookingContext/utils/index.js +43 -0
  105. package/lib/modules/BookingContext/utils/noResource.d.ts +13 -0
  106. package/lib/modules/BookingContext/utils/noResource.js +90 -0
  107. package/lib/modules/BookingContext/utils/productExtend.d.ts +72 -0
  108. package/lib/modules/BookingContext/utils/productExtend.js +283 -0
  109. package/lib/modules/BookingContext/utils/resourceErrors.d.ts +41 -0
  110. package/lib/modules/BookingContext/utils/resourceErrors.js +80 -0
  111. package/lib/modules/BookingContext/utils/resourceSelection.d.ts +7 -0
  112. package/lib/modules/BookingContext/utils/resourceSelection.js +46 -0
  113. package/lib/modules/BookingContext/utils/resources.d.ts +80 -0
  114. package/lib/modules/BookingContext/utils/resources.js +377 -0
  115. package/lib/modules/BookingContext/utils/serviceTimes.d.ts +55 -0
  116. package/lib/modules/BookingContext/utils/serviceTimes.js +162 -0
  117. package/lib/modules/BookingContext/utils/timeSlices.d.ts +42 -0
  118. package/lib/modules/BookingContext/utils/timeSlices.js +124 -0
  119. package/lib/modules/Customer/index.d.ts +6 -0
  120. package/lib/modules/Customer/index.js +26 -11
  121. package/lib/modules/Customer/types.d.ts +2 -0
  122. package/lib/modules/Discount/index.js +5 -1
  123. package/lib/modules/Discount/types.d.ts +1 -0
  124. package/lib/modules/Order/index.d.ts +101 -10
  125. package/lib/modules/Order/index.js +751 -114
  126. package/lib/modules/Order/types.d.ts +201 -18
  127. package/lib/modules/Order/types.js +1 -0
  128. package/lib/modules/Order/utils/manualProductDiscount.d.ts +106 -0
  129. package/lib/modules/Order/utils/manualProductDiscount.js +206 -0
  130. package/lib/modules/Order/utils.d.ts +83 -1
  131. package/lib/modules/Order/utils.js +340 -22
  132. package/lib/modules/Product/index.d.ts +1 -1
  133. package/lib/modules/Quotation/index.d.ts +0 -1
  134. package/lib/modules/Quotation/index.js +18 -15
  135. package/lib/modules/Rules/index.d.ts +4 -0
  136. package/lib/modules/Rules/index.js +26 -27
  137. package/lib/modules/Rules/types.d.ts +1 -0
  138. package/lib/modules/SalesSummary/index.js +4 -2
  139. package/lib/modules/SalesSummary/utils.js +21 -7
  140. package/lib/modules/Schedule/index.js +3 -1
  141. package/lib/modules/index.d.ts +1 -0
  142. package/lib/modules/index.js +3 -1
  143. package/lib/server/index.js +41 -4
  144. package/lib/server/modules/order/index.d.ts +23 -0
  145. package/lib/server/modules/order/index.js +46 -14
  146. package/lib/server/modules/order/utils/filterOrders.js +12 -4
  147. package/lib/server/modules/products/index.d.ts +1 -1
  148. package/lib/server/modules/products/index.js +30 -20
  149. package/lib/server/modules/schedule/index.js +2 -1
  150. package/lib/solution/BaseSales/index.d.ts +89 -7
  151. package/lib/solution/BaseSales/index.js +742 -23
  152. package/lib/solution/BaseSales/types.d.ts +67 -1
  153. package/lib/solution/BaseSales/types.js +3 -1
  154. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +275 -0
  155. package/lib/solution/BaseSales/utils/cartPromotion.js +836 -0
  156. package/lib/solution/BaseSales/utils/quotationPrice.d.ts +7 -0
  157. package/lib/solution/BaseSales/utils/quotationPrice.js +277 -0
  158. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +71 -12
  159. package/lib/solution/BaseSales/utils.js +46 -6
  160. package/lib/solution/BookingByStep/index.d.ts +1 -1
  161. package/lib/solution/BookingTicket/index.d.ts +152 -2
  162. package/lib/solution/BookingTicket/index.js +389 -9
  163. package/lib/solution/BookingTicket/types.d.ts +2 -0
  164. package/lib/solution/BookingTicket/types.js +6 -0
  165. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +113 -0
  166. package/lib/solution/BookingTicket/utils/addProductDecision.js +318 -0
  167. package/lib/solution/BookingTicket/utils/cartView.js +4 -2
  168. package/lib/solution/ScanOrder/index.d.ts +9 -3
  169. package/lib/solution/ScanOrder/index.js +147 -66
  170. package/lib/solution/ScanOrder/utils.js +46 -6
  171. package/lib/solution/VenueBooking/index.d.ts +5 -2
  172. package/lib/solution/VenueBooking/index.js +50 -14
  173. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +4 -0
  174. package/lib/solution/VenueBooking/utils/slotMerge.js +10 -0
  175. package/package.json +1 -1
@@ -37,7 +37,9 @@ var import_types = require("./types");
37
37
  var import_utils = require("./utils");
38
38
  var import_utils2 = require("../Product/utils");
39
39
  var import_dayjs = __toESM(require("dayjs"));
40
+ var import_cartPromotion = require("../../solution/BaseSales/utils/cartPromotion");
40
41
  var import_utils3 = require("../../solution/ScanOrder/utils");
42
+ var import_manualProductDiscount = require("./utils/manualProductDiscount");
41
43
  var import_Discount = require("../Discount");
42
44
  var import_Rules = require("../Rules");
43
45
  var import_types2 = require("../Rules/types");
@@ -49,25 +51,51 @@ var OrderModule = class extends import_BaseModule.BaseModule {
49
51
  super(name || "order", version);
50
52
  this.defaultName = "order";
51
53
  this.defaultVersion = "1.0.0";
54
+ // ─── 促销/赠品 ────────────────────────────────────
55
+ /** 评估器引用;由 SalesSdkProvider 注入,未注入时 applyPromotion 静默跳过 */
56
+ this.promotionEvaluator = null;
57
+ /** 赠品选择 resolver;由 SDK host bridge 注入 */
58
+ this.giftSelectResolver = null;
59
+ /** applyPromotion 递归保护 flag(写路径同步调 applyPromotion,禁止重入) */
60
+ this.isApplyingPromotion = false;
61
+ /** 最近一次 applyPromotion 的未满足促销提示 */
62
+ this.lastUnfulfilledPromotions = [];
63
+ /** 最近一次 applyPromotion 的赠品操作 diff(debug / SDK 读取使用) */
64
+ this.lastGiftActions = null;
65
+ /**
66
+ * 是否将 tempOrder 写入 IndexedDB 草稿(orders store)。
67
+ * BigSale 弹窗等短生命周期场景通过 setEnableTempOrderPersist(false) 关闭。
68
+ */
69
+ this.draftPersistEnabled = true;
52
70
  }
53
71
  /**
54
72
  * Populate `savedAmount` on each discount based on product-level discount details.
55
73
  * Only selected discounts get a non-zero value.
56
74
  */
57
75
  static populateSavedAmounts(productList, discountList) {
58
- var _a, _b;
59
76
  const savedMap = /* @__PURE__ */ new Map();
77
+ const addDiscountAmount = (discount, quantity) => {
78
+ var _a, _b;
79
+ const discountKey = ((_a = discount.discount) == null ? void 0 : _a.resource_id) || discount.id;
80
+ if (discountKey == null)
81
+ return;
82
+ const qty = Number(quantity) || 1;
83
+ const amount = new import_decimal.default(discount.amount || 0).times(qty).plus(((_b = discount.metadata) == null ? void 0 : _b.product_discount_difference) || 0);
84
+ savedMap.set(
85
+ discountKey,
86
+ (savedMap.get(discountKey) || new import_decimal.default(0)).plus(amount)
87
+ );
88
+ };
60
89
  for (const product of productList) {
61
90
  const qty = product.num || 1;
62
91
  for (const pd of product.discount_list || []) {
63
- const discountKey = ((_a = pd.discount) == null ? void 0 : _a.resource_id) || pd.id;
64
- if (discountKey == null)
65
- continue;
66
- const amount = new import_decimal.default(pd.amount || 0).times(qty).plus(((_b = pd.metadata) == null ? void 0 : _b.product_discount_difference) || 0);
67
- savedMap.set(
68
- discountKey,
69
- (savedMap.get(discountKey) || new import_decimal.default(0)).plus(amount)
70
- );
92
+ addDiscountAmount(pd, qty);
93
+ }
94
+ for (const bundle of product.product_bundle || []) {
95
+ const bundleQty = new import_decimal.default(Number(qty) || 1).times(Number((bundle == null ? void 0 : bundle.num) ?? (bundle == null ? void 0 : bundle.quantity) ?? 1) || 1).toNumber();
96
+ for (const pd of (bundle == null ? void 0 : bundle.discount_list) || []) {
97
+ addDiscountAmount(pd, bundleQty);
98
+ }
71
99
  }
72
100
  }
73
101
  for (const d of discountList) {
@@ -75,6 +103,27 @@ var OrderModule = class extends import_BaseModule.BaseModule {
75
103
  d.savedAmount = d.isSelected && key != null && savedMap.has(key) ? savedMap.get(key).toNumber() : 0;
76
104
  }
77
105
  }
106
+ applyProductDiscountPrices(products) {
107
+ return (products || []).map((product) => {
108
+ var _a, _b, _c;
109
+ if ((_a = product.metadata) == null ? void 0 : _a.is_manual_discount)
110
+ return product;
111
+ const totalPerUnitDiscount = (0, import_utils.resolveEffectivePerUnitDiscount)(product);
112
+ const optionSum = (0, import_utils.sumOptionUnitPrice)(product.product_option_item);
113
+ const sourcePrice = ((_b = product.metadata) == null ? void 0 : _b.source_product_price) ?? (((_c = product.metadata) == null ? void 0 : _c.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
114
+ const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
115
+ const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
116
+ if (product.metadata) {
117
+ product.metadata.main_product_selling_price = newMainSellingPrice;
118
+ product.metadata.price_schema_version = 2;
119
+ }
120
+ product.selling_price = (0, import_utils.composeLinePrice)({
121
+ mainPrice: newMainSellingPrice,
122
+ bundle: product.product_bundle
123
+ });
124
+ return product;
125
+ });
126
+ }
78
127
  async initialize(core, options) {
79
128
  var _a, _b, _c;
80
129
  this.core = core;
@@ -101,7 +150,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
101
150
  this.orderHooks = options.hooks || ((_b = otherParams.order) == null ? void 0 : _b.hooks) || ((_c = otherParams.hooks) == null ? void 0 : _c.order);
102
151
  this.otherParams = otherParams;
103
152
  this.registerDiscountModules(options);
104
- this.restoreTempOrderFromStorage();
105
153
  this.logInfo("OrderModule initialized successfully");
106
154
  }
107
155
  /**
@@ -174,21 +222,25 @@ var OrderModule = class extends import_BaseModule.BaseModule {
174
222
  }
175
223
  // ─── Discount: 公共 API ───
176
224
  async loadDiscountConfig(params) {
177
- var _a, _b, _c, _d;
178
- const discountList = await ((_a = this.store.discount) == null ? void 0 : _a.loadPrepareConfig({
225
+ var _a, _b, _c, _d, _e, _f;
226
+ const orderId = params.orderId || ((_a = this.store.tempOrder) == null ? void 0 : _a.order_id) || void 0;
227
+ const discountList = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
179
228
  customer_id: params.customerId,
180
- action: params.action || "create",
229
+ action: params.action || (orderId ? "edit" : "create"),
181
230
  with_good_pass: 1,
182
231
  with_discount_card: 1,
183
232
  with_wallet_pass_holder: 1,
184
- request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
233
+ request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
234
+ ...orderId ? { order_id: orderId } : {}
185
235
  }));
186
236
  if (discountList) {
187
- (_b = this.store.discount) == null ? void 0 : _b.setDiscountList(discountList);
237
+ await ((_c = this.store.discount) == null ? void 0 : _c.setOriginalDiscountList(discountList));
238
+ await ((_d = this.store.discount) == null ? void 0 : _d.setDiscountList(discountList));
188
239
  }
189
- if ((_d = (_c = this.store.tempOrder) == null ? void 0 : _c.products) == null ? void 0 : _d.length) {
240
+ if (params.apply !== false && ((_f = (_e = this.store.tempOrder) == null ? void 0 : _e.products) == null ? void 0 : _f.length)) {
190
241
  this.applyDiscount();
191
242
  }
243
+ return this.getDiscountList();
192
244
  }
193
245
  getDiscountList() {
194
246
  var _a;
@@ -204,6 +256,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
204
256
  type: "clientCalc",
205
257
  isAvailable: false,
206
258
  discountList: this.getDiscountList(),
259
+ scannedDiscountList: resultDiscountList,
207
260
  unavailableReason: import_types2.UnavailableReason.Unknown
208
261
  };
209
262
  }
@@ -212,6 +265,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
212
265
  type: "server",
213
266
  isAvailable: false,
214
267
  discountList: this.getDiscountList(),
268
+ scannedDiscountList: resultDiscountList,
215
269
  unavailableReasonKey
216
270
  };
217
271
  }
@@ -224,7 +278,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
224
278
  return {
225
279
  type: "clientCalc",
226
280
  isAvailable: true,
227
- discountList: this.getDiscountList()
281
+ discountList: this.getDiscountList(),
282
+ scannedDiscountList: resultDiscountList
228
283
  };
229
284
  }
230
285
  const tempOrder = this.store.tempOrder;
@@ -245,6 +300,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
245
300
  type: "clientCalc",
246
301
  isAvailable: isAvailable || false,
247
302
  discountList: newDiscountList || this.getDiscountList(),
303
+ scannedDiscountList: resultDiscountList,
248
304
  unavailableReason
249
305
  };
250
306
  }
@@ -253,6 +309,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
253
309
  const tempOrder = this.store.tempOrder;
254
310
  if (!tempOrder)
255
311
  return;
312
+ delete tempOrder.discount_list;
256
313
  const rulesModule = this.store.rules;
257
314
  if (!rulesModule)
258
315
  return;
@@ -266,7 +323,23 @@ var OrderModule = class extends import_BaseModule.BaseModule {
266
323
  orderTotalAmount: Number(((_d = this.store.summary) == null ? void 0 : _d.total_amount) || 0)
267
324
  });
268
325
  if (result == null ? void 0 : result.productList) {
269
- tempOrder.products = result.productList;
326
+ const previousProductsByUid = (0, import_utils.indexOrderProductsByUid)(tempOrder.products);
327
+ tempOrder.products = this.applyProductDiscountPrices(
328
+ (result.productList || []).map((product, index) => {
329
+ const uid = (0, import_utils.getOrderProductLineUid)(product);
330
+ const previous = (uid ? previousProductsByUid.get(uid) : void 0) ?? previousProductsByUid.get(`__index__:${index}`);
331
+ const mergedProduct = previous ? (0, import_utils.mergeOrderProductDisplayFields)(previous, product) : product;
332
+ return {
333
+ ...mergedProduct,
334
+ discount_list: (0, import_utils.normalizeOrderProductDiscountList)(
335
+ (0, import_manualProductDiscount.syncManualProductDiscountProductNum)(
336
+ mergedProduct.discount_list,
337
+ mergedProduct.num
338
+ )
339
+ )
340
+ };
341
+ })
342
+ );
270
343
  }
271
344
  if (result == null ? void 0 : result.discountList) {
272
345
  OrderModule.populateSavedAmounts(
@@ -274,80 +347,185 @@ var OrderModule = class extends import_BaseModule.BaseModule {
274
347
  result.discountList
275
348
  );
276
349
  (_e = this.store.discount) == null ? void 0 : _e.setDiscountList(result.discountList);
277
- tempOrder.discount_list = result.discountList.filter(
278
- (d) => d.isSelected
279
- );
280
350
  }
281
351
  }
282
- // ─── TempOrder: 初始化入口 ───
283
- initTempOrder(params) {
284
- if (params.cacheId !== void 0)
285
- this.cacheId = params.cacheId;
286
- if (params.salesSummaryModuleName !== void 0)
287
- this.salesSummaryModuleName = params.salesSummaryModuleName;
288
- this.restoreTempOrderFromStorage();
352
+ // ─── 促销/赠品 ──────────────────────────────────────
353
+ /**
354
+ * 注入促销评估器。
355
+ *
356
+ * @example
357
+ * order.setPromotionEvaluator(appHelper.utils.promotionEvaluator);
358
+ */
359
+ setPromotionEvaluator(evaluator) {
360
+ this.promotionEvaluator = evaluator || null;
289
361
  }
290
- // ─── TempOrder: localStorage 持久化 ───
291
- getTempOrderStorageKey() {
292
- if (!this.cacheId)
293
- return null;
294
- return `scanOrder:tempOrder:${this.cacheId}`;
362
+ /**
363
+ * 注入赠品选择 resolver。OS 需要补赠品时会 await 调用 resolver;缺省时跳过新增并 console.warn。
364
+ *
365
+ * @example
366
+ * order.setGiftSelectResolver(async (ctx) => {
367
+ * // SDK 内部决定弹窗 or 自动选第一项,返回完整 OrderProduct[]
368
+ * return giftSelectBridge.request(ctx);
369
+ * });
370
+ */
371
+ setGiftSelectResolver(resolver) {
372
+ this.giftSelectResolver = resolver || null;
295
373
  }
296
- restoreTempOrderFromStorage() {
297
- var _a, _b;
298
- const key = this.getTempOrderStorageKey();
299
- if (!key)
374
+ /**
375
+ * 为商品目录追加促销标签,供上层 Sales 门面复用。
376
+ *
377
+ * @example
378
+ * const products = order.appendPromotionTags(catalogProducts);
379
+ */
380
+ appendPromotionTags(products) {
381
+ return (0, import_cartPromotion.appendPromotionTags)(products, this.promotionEvaluator);
382
+ }
383
+ /**
384
+ * 应用购物车促销:计算 → 差异化赠品 → 写回 tempOrder.products → emit onPromotionApplied。
385
+ *
386
+ * 调用时机:写路径(add/update/remove/clear/setCustomer)末尾自动触发;外部一般无需手动调。
387
+ *
388
+ * 关键约束:
389
+ * - 不调用任何公开 CRUD API(如 removeProductFromOrder),全部内部 mutate tempOrder.products,避免事件风暴;
390
+ * - 用 `isApplyingPromotion` 防递归;
391
+ * - 多选项赠品依赖 giftSelectResolver,未注入则跳过且 console.warn;
392
+ * - 不主动调用 applyDiscount / recalculateSummary,调用方负责跟进。
393
+ */
394
+ async applyPromotion() {
395
+ if (this.isApplyingPromotion)
300
396
  return;
301
- if (!this.window)
397
+ if (!this.promotionEvaluator)
302
398
  return;
303
- const cachedData = this.window.localStorage.getItem(key);
304
- if (!cachedData)
399
+ const tempOrder = this.store.tempOrder;
400
+ if (!tempOrder)
305
401
  return;
402
+ this.isApplyingPromotion = true;
306
403
  try {
307
- const parsedData = JSON.parse(cachedData);
308
- if (!(0, import_utils.isTempOrder)(parsedData)) {
309
- this.window.localStorage.removeItem(key);
310
- return;
404
+ const result = (0, import_cartPromotion.processCartPromotion)(
405
+ tempOrder.products,
406
+ this.promotionEvaluator
407
+ );
408
+ if (result.giftActions.toRemove.length > 0) {
409
+ const removeSet = new Set(result.giftActions.toRemove.map(String));
410
+ result.products = result.products.filter((p) => {
411
+ const uid = (0, import_cartPromotion.getOrderProductUid)(p);
412
+ return uid ? !removeSet.has(String(uid)) : true;
413
+ });
311
414
  }
312
- if (Array.isArray(parsedData.products)) {
313
- for (let i = 0; i < parsedData.products.length; i++) {
314
- const p = parsedData.products[i];
315
- if (!p || typeof p !== "object")
316
- continue;
317
- if (!Array.isArray(p.product_option_item)) {
318
- p.product_option_item = [];
319
- }
320
- if (!Array.isArray(p.product_bundle)) {
321
- p.product_bundle = [];
415
+ for (const reduce of result.giftActions.toReduce) {
416
+ for (const item of reduce.items) {
417
+ const product = result.products.find(
418
+ (p) => (0, import_cartPromotion.getOrderProductUid)(p) === item.uid
419
+ );
420
+ if (product) {
421
+ product.num = item.newQuantity;
322
422
  }
323
- const row = p;
324
- parsedData.products[i] = (0, import_utils3.normalizeOrderProduct)(row);
325
423
  }
326
424
  }
327
- const parsedRecord = parsedData;
328
- this.store.summary = parsedRecord.summary || (0, import_utils.createEmptySummary)();
329
- delete parsedData.summary;
330
- if (parsedRecord.lastOrderInfo) {
331
- this.store.lastOrderInfo = parsedRecord.lastOrderInfo;
332
- delete parsedData.lastOrderInfo;
333
- }
334
- if (!parsedData._extend || typeof parsedData._extend !== "object") {
335
- parsedData._extend = { productsByUid: {} };
336
- } else if (!parsedData._extend.productsByUid) {
337
- parsedData._extend.productsByUid = {};
425
+ if (result.giftActions.toAdd.length > 0) {
426
+ if (!this.giftSelectResolver) {
427
+ if (result.giftActions.toAdd.some((g) => g.giftOptions.length > 1)) {
428
+ console.warn(
429
+ "[OrderModule] giftSelectResolver not set, skip applying gifts",
430
+ result.giftActions.toAdd
431
+ );
432
+ } else {
433
+ console.warn(
434
+ "[OrderModule] giftSelectResolver not set, skip applying single-option gifts",
435
+ result.giftActions.toAdd
436
+ );
437
+ }
438
+ } else {
439
+ for (const addAction of result.giftActions.toAdd) {
440
+ if (addAction.giftOptions.length === 1) {
441
+ const sameStrategy = result.products.find(
442
+ (p) => {
443
+ var _a, _b;
444
+ return ((_b = (_a = p.metadata) == null ? void 0 : _a._giftInfo) == null ? void 0 : _b.strategyId) === addAction.strategyId;
445
+ }
446
+ );
447
+ if (sameStrategy) {
448
+ sameStrategy.num = (Number(sameStrategy.num) || 0) + (addAction.giftCount || 1);
449
+ continue;
450
+ }
451
+ }
452
+ try {
453
+ const giftProducts = await this.giftSelectResolver({
454
+ strategyId: addAction.strategyId,
455
+ strategyName: addAction.strategyName,
456
+ giftCount: addAction.giftCount,
457
+ giftOptions: addAction.giftOptions,
458
+ sourceProductIds: addAction.sourceProductIds
459
+ });
460
+ if (Array.isArray(giftProducts) && giftProducts.length > 0) {
461
+ for (const gp of giftProducts) {
462
+ if (!gp)
463
+ continue;
464
+ result.products.push(gp);
465
+ }
466
+ }
467
+ } catch (error) {
468
+ console.warn(
469
+ "[OrderModule] giftSelectResolver rejected, skip add gift",
470
+ addAction.strategyId,
471
+ error
472
+ );
473
+ }
474
+ }
475
+ }
338
476
  }
339
- this.store.tempOrder = parsedData;
340
- } catch {
341
- (_b = (_a = this.window) == null ? void 0 : _a.localStorage) == null ? void 0 : _b.removeItem(key);
477
+ tempOrder.products = result.products;
478
+ this.lastUnfulfilledPromotions = result.unfulfilledPromotions;
479
+ this.lastGiftActions = result.giftActions;
480
+ const payload = {
481
+ unfulfilledPromotions: result.unfulfilledPromotions,
482
+ giftActions: result.giftActions,
483
+ gifts: result.gifts.map((g) => ({
484
+ strategyId: g.strategyId,
485
+ strategyName: g.strategyName,
486
+ giftCount: g.giftCount,
487
+ giftOptions: g.giftOptions
488
+ })),
489
+ products: tempOrder.products
490
+ };
491
+ this.effectsEmit("onPromotionApplied", payload);
492
+ } catch (error) {
493
+ console.error("[OrderModule] applyPromotion failed", error);
494
+ } finally {
495
+ this.isApplyingPromotion = false;
342
496
  }
343
497
  }
498
+ /** 最近一次 applyPromotion 输出的未满足促销列表 */
499
+ getUnfulfilledPromotions() {
500
+ return this.lastUnfulfilledPromotions;
501
+ }
502
+ /** 最近一次 applyPromotion 输出的赠品操作 diff */
503
+ getLastGiftActions() {
504
+ return this.lastGiftActions;
505
+ }
506
+ // ─── TempOrder: 初始化入口 ───
507
+ initTempOrder(params) {
508
+ if (params.cacheId !== void 0)
509
+ this.cacheId = params.cacheId;
510
+ if (params.salesSummaryModuleName !== void 0)
511
+ this.salesSummaryModuleName = params.salesSummaryModuleName;
512
+ }
513
+ /**
514
+ * 控制 IndexedDB 草稿(saveDraft)是否写入。
515
+ * localStorage 版 tempOrder 持久化已废弃,此方法仅影响 saveDraft。
516
+ *
517
+ * @example
518
+ * order.setEnableTempOrderPersist(false); // BigSale 弹窗:跳过 ~1s 的 dbUpdate
519
+ */
520
+ setEnableTempOrderPersist(enabled) {
521
+ this.draftPersistEnabled = enabled;
522
+ }
523
+ /** 是否允许 saveDraft 写入 IndexedDB 草稿。 */
524
+ isTempOrderPersistEnabled() {
525
+ return this.draftPersistEnabled;
526
+ }
527
+ /** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化;草稿保存请使用 IndexedDB saveDraft。 */
344
528
  persistTempOrder() {
345
- const key = this.getTempOrderStorageKey();
346
- if (!key || !this.store.tempOrder)
347
- return;
348
- if (!this.window)
349
- return;
350
- this.window.localStorage.setItem(key, JSON.stringify(this.store.tempOrder));
351
529
  }
352
530
  // ─── TempOrder: 创建 & 获取 ───
353
531
  createDefaultTempOrderInstance() {
@@ -391,6 +569,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
391
569
  }
392
570
  return tempOrder.request_unique_idempotency_token;
393
571
  }
572
+ buildPaymentSyncIdempotencyToken(tempOrder, payments) {
573
+ const baseToken = this.ensureRequestUniqueIdempotencyToken(tempOrder);
574
+ const paidPaymentsCount = (payments || []).filter((payment) => {
575
+ return String((payment == null ? void 0 : payment.status) || "").toLowerCase() === "paid";
576
+ }).length;
577
+ const paidCount = paidPaymentsCount > 0 ? paidPaymentsCount : payments.length;
578
+ return `${baseToken}_payment_${paidCount}`;
579
+ }
394
580
  hasLocalDatabase() {
395
581
  return !!this.dbManager;
396
582
  }
@@ -478,8 +664,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
478
664
  }
479
665
  async saveDraft() {
480
666
  var _a, _b;
481
- if (!this.dbManager)
667
+ if (!this.draftPersistEnabled || !this.dbManager) {
482
668
  return;
669
+ }
483
670
  const tempOrder = this.ensureTempOrder();
484
671
  const record = this.buildLocalOrderRecord(tempOrder);
485
672
  try {
@@ -493,6 +680,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
493
680
  });
494
681
  }
495
682
  }
683
+ saveDraftInBackground() {
684
+ void this.saveDraft();
685
+ }
496
686
  async hydrateTempOrderFromLocalRecord(record) {
497
687
  return this.hydrateTempOrderFromRecord(record);
498
688
  }
@@ -509,6 +699,33 @@ var OrderModule = class extends import_BaseModule.BaseModule {
509
699
  return sum.plus(amount.minus(rounding));
510
700
  }, new import_decimal.default(0));
511
701
  }
702
+ normalizePaymentSource(payment, options) {
703
+ const paymentRecord = payment;
704
+ const metadata = paymentRecord.metadata && typeof paymentRecord.metadata === "object" ? { ...paymentRecord.metadata } : {};
705
+ if (!metadata.unique_identification_number) {
706
+ metadata.unique_identification_number = (0, import_utils.createUuidV4)();
707
+ }
708
+ const normalized = {
709
+ ...paymentRecord,
710
+ metadata,
711
+ origin_amount: paymentRecord.origin_amount ?? paymentRecord.amount ?? "0.00"
712
+ };
713
+ if (paymentRecord.status !== void 0) {
714
+ normalized.status = paymentRecord.status;
715
+ } else if ((options == null ? void 0 : options.defaultPaid) !== false) {
716
+ normalized.status = "paid";
717
+ }
718
+ return normalized;
719
+ }
720
+ updateTempOrderPaymentStatus(tempOrder) {
721
+ const paymentTotal = this.calculatePaymentTotal(tempOrder.payments || []);
722
+ if (paymentTotal.lte(0)) {
723
+ tempOrder.payment_status = tempOrder.payment_status || "payment_processing";
724
+ return;
725
+ }
726
+ const targetAmount = this.getPaymentTargetAmount();
727
+ tempOrder.payment_status = targetAmount.gt(0) && paymentTotal.gte(targetAmount) ? "paid" : "partially_paid";
728
+ }
512
729
  calculatePaidPaymentSummary(payments) {
513
730
  return (payments || []).reduce(
514
731
  (summary, payment) => {
@@ -537,6 +754,66 @@ var OrderModule = class extends import_BaseModule.BaseModule {
537
754
  const fixedAmount = new import_decimal.default(serviceCharge.amount || 0);
538
755
  return new import_decimal.default(payment.amount || 0).times(percentage).plus(fixedAmount);
539
756
  }
757
+ formatSummaryMetadataMoney(value) {
758
+ if (value === void 0 || value === null || value === "")
759
+ return void 0;
760
+ if (value instanceof import_decimal.default)
761
+ return value.toFixed(2);
762
+ return new import_decimal.default(String(value || 0)).toFixed(2);
763
+ }
764
+ syncSummaryProductMetadata(products) {
765
+ const moneyKeys = [
766
+ "main_product_attached_bundle_surcharge_fee",
767
+ "main_product_attached_bundle_tax_fee",
768
+ "surcharge_rounding_remainder",
769
+ "tax_fee_rounding_remainder"
770
+ ];
771
+ for (const product of products || []) {
772
+ const productRecord = product;
773
+ const metadata = productRecord.metadata && typeof productRecord.metadata === "object" ? { ...productRecord.metadata } : {};
774
+ let hasMetadataPatch = false;
775
+ for (const key of moneyKeys) {
776
+ const value = this.formatSummaryMetadataMoney(productRecord[key]);
777
+ if (value === void 0)
778
+ continue;
779
+ metadata[key] = value;
780
+ hasMetadataPatch = true;
781
+ }
782
+ if (Array.isArray(productRecord.relation_surcharge_ids)) {
783
+ metadata.relation_surcharge_ids = productRecord.relation_surcharge_ids;
784
+ hasMetadataPatch = true;
785
+ }
786
+ if (hasMetadataPatch)
787
+ productRecord.metadata = metadata;
788
+ if (!Array.isArray(productRecord.product_bundle))
789
+ continue;
790
+ for (const bundle of productRecord.product_bundle) {
791
+ const bundleRecord = bundle;
792
+ const bundleMetadata = bundleRecord.metadata && typeof bundleRecord.metadata === "object" ? { ...bundleRecord.metadata } : {};
793
+ let hasBundleMetadataPatch = false;
794
+ const bundleSurchargeFee = this.formatSummaryMetadataMoney(
795
+ bundleRecord.surcharge_fee
796
+ );
797
+ if (bundleSurchargeFee !== void 0) {
798
+ bundleMetadata.surcharge_fee = bundleSurchargeFee;
799
+ hasBundleMetadataPatch = true;
800
+ }
801
+ if (Array.isArray(bundleRecord.relation_surcharge_ids)) {
802
+ bundleMetadata.relation_surcharge_ids = bundleRecord.relation_surcharge_ids;
803
+ hasBundleMetadataPatch = true;
804
+ }
805
+ if (hasBundleMetadataPatch)
806
+ bundleRecord.metadata = bundleMetadata;
807
+ }
808
+ }
809
+ }
810
+ calculateSummaryAmountGap(params) {
811
+ const { tempOrder, summary, orderPaidAmount } = params;
812
+ const depositAmount = summary.deposit_amount || tempOrder.deposit_amount || "0.00";
813
+ const isDeposit = tempOrder.is_deposit === 1 || new import_decimal.default(depositAmount || 0).gt(0);
814
+ const targetAmount = isDeposit ? new import_decimal.default(depositAmount || 0) : new import_decimal.default(summary.total_amount || summary.expect_amount || 0);
815
+ return targetAmount.minus(orderPaidAmount).toFixed(2);
816
+ }
540
817
  getPaymentTargetAmount() {
541
818
  const tempOrder = this.ensureTempOrder();
542
819
  const summary = this.store.summary || (0, import_utils.createEmptySummary)();
@@ -559,17 +836,43 @@ var OrderModule = class extends import_BaseModule.BaseModule {
559
836
  return newOrder;
560
837
  }
561
838
  restoreOrder() {
839
+ var _a, _b;
562
840
  const freshTempOrder = this.createDefaultTempOrderInstance();
563
841
  this.ensureExternalSaleNumber(freshTempOrder);
564
842
  this.store.tempOrder = freshTempOrder;
565
843
  this.store.summary = (0, import_utils.createEmptySummary)();
566
844
  this.store.lastOrderInfo = void 0;
845
+ this.store.syncState = void 0;
846
+ void ((_a = this.store.discount) == null ? void 0 : _a.setOriginalDiscountList([]));
847
+ void ((_b = this.store.discount) == null ? void 0 : _b.setDiscountList([]));
567
848
  this.persistTempOrder();
568
849
  return freshTempOrder;
569
850
  }
570
851
  getTempOrder() {
571
852
  return this.store.tempOrder;
572
853
  }
854
+ async replaceTempOrder(tempOrder, options) {
855
+ if (!(0, import_utils.isTempOrder)(tempOrder)) {
856
+ throw new Error("无效的 tempOrder 数据");
857
+ }
858
+ const nextTempOrder = this.normalizeTempOrderForRuntime(
859
+ (0, import_lodash_es.cloneDeep)(tempOrder),
860
+ { ensureIdentity: false }
861
+ );
862
+ this.store.tempOrder = nextTempOrder;
863
+ if ((options == null ? void 0 : options.recalculateSummary) !== false) {
864
+ await this.recalculateSummary({ createIfMissing: false });
865
+ } else {
866
+ this.store.summary = (0, import_utils.createEmptySummary)();
867
+ }
868
+ if ((options == null ? void 0 : options.persist) !== false) {
869
+ this.persistTempOrder();
870
+ }
871
+ if (options == null ? void 0 : options.saveDraft) {
872
+ await this.saveDraft();
873
+ }
874
+ return nextTempOrder;
875
+ }
573
876
  getOrderIdentity() {
574
877
  var _a;
575
878
  const tempOrder = this.store.tempOrder;
@@ -607,7 +910,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
607
910
  const depositAmount = tempOrder.deposit_amount || summary.deposit_amount || "0.00";
608
911
  const targetAmount = tempOrder.is_deposit === 1 ? new import_decimal.default(depositAmount || 0) : new import_decimal.default(summary.total_amount || summary.expect_amount || 0);
609
912
  const paymentTotal = this.calculatePaymentTotal(tempOrder.payments || []);
610
- const amountGap = import_decimal.default.max(0, targetAmount.minus(paymentTotal)).toFixed(2);
913
+ const amountGap = targetAmount.minus(paymentTotal).toFixed(2);
611
914
  return {
612
915
  isDeposit: tempOrder.is_deposit === 1 || depositAmount !== "0.00",
613
916
  depositAmount,
@@ -650,7 +953,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
650
953
  this.ensureExternalSaleNumber(tempOrder);
651
954
  await this.recalculateSummary({ createIfMissing: true });
652
955
  this.persistTempOrder();
653
- await this.saveDraft();
956
+ if (this.draftPersistEnabled) {
957
+ await this.saveDraft();
958
+ }
654
959
  return tempOrder;
655
960
  }
656
961
  getOrderProducts() {
@@ -718,6 +1023,33 @@ var OrderModule = class extends import_BaseModule.BaseModule {
718
1023
  }
719
1024
  };
720
1025
  }
1026
+ getBookingUniqueIdentificationNumber(booking) {
1027
+ var _a;
1028
+ const uid = (_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.unique_identification_number;
1029
+ if (uid === void 0 || uid === null || uid === "")
1030
+ return null;
1031
+ return String(uid);
1032
+ }
1033
+ findBookingIndexByUniqueIdentificationNumber(tempOrder, uniqueIdentificationNumber) {
1034
+ return (tempOrder.bookings || []).findIndex((booking) => {
1035
+ return this.getBookingUniqueIdentificationNumber(booking) === uniqueIdentificationNumber;
1036
+ });
1037
+ }
1038
+ removeLinkedBookingsForProduct(tempOrder, product) {
1039
+ var _a, _b;
1040
+ const productUid = ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.unique_identification_number) || (product == null ? void 0 : product.unique_identification_number);
1041
+ const bookingUid = (product == null ? void 0 : product.booking_uid) || ((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.booking_uid);
1042
+ if (!productUid && !bookingUid)
1043
+ return;
1044
+ tempOrder.bookings = (tempOrder.bookings || []).filter((booking) => {
1045
+ const currentBookingUid = this.getBookingUniqueIdentificationNumber(booking);
1046
+ if (bookingUid && currentBookingUid === String(bookingUid))
1047
+ return false;
1048
+ if (productUid && String((booking == null ? void 0 : booking.product_uid) || "") === String(productUid))
1049
+ return false;
1050
+ return true;
1051
+ });
1052
+ }
721
1053
  // ─── TempOrder: 金额汇总 ───
722
1054
  getSalesSummary() {
723
1055
  if (!this.salesSummaryModuleName)
@@ -739,6 +1071,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
739
1071
  total_refund_amount: existedSummary.total_refund_amount || "0.00",
740
1072
  customer_paid_amount: paidPaymentSummary.customerPaidAmount.toFixed(2),
741
1073
  order_paid_amount: paidPaymentSummary.orderPaidAmount.toFixed(2),
1074
+ amount_gap: this.calculateSummaryAmountGap({
1075
+ tempOrder,
1076
+ summary: (0, import_utils.createEmptySummary)(),
1077
+ orderPaidAmount: paidPaymentSummary.orderPaidAmount
1078
+ }),
742
1079
  pay_service_charge_amount: paidPaymentSummary.payServiceChargeAmount.toFixed(2)
743
1080
  };
744
1081
  this.store.summary = emptySummary;
@@ -750,11 +1087,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
750
1087
  isPriceIncludeTax: tempOrder.is_price_include_tax,
751
1088
  shopDiscount: tempOrder.shop_discount
752
1089
  });
1090
+ this.syncSummaryProductMetadata(tempOrder.products || []);
753
1091
  const summary = {
754
1092
  ...salesSummaryResult,
755
1093
  total_refund_amount: existedSummary.total_refund_amount || "0.00",
756
1094
  customer_paid_amount: paidPaymentSummary.customerPaidAmount.toFixed(2),
757
1095
  order_paid_amount: paidPaymentSummary.orderPaidAmount.toFixed(2),
1096
+ amount_gap: this.calculateSummaryAmountGap({
1097
+ tempOrder,
1098
+ summary: salesSummaryResult,
1099
+ orderPaidAmount: paidPaymentSummary.orderPaidAmount
1100
+ }),
758
1101
  pay_service_charge_amount: paidPaymentSummary.payServiceChargeAmount.toFixed(2)
759
1102
  };
760
1103
  this.store.summary = summary;
@@ -777,13 +1120,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
777
1120
  this.persistTempOrder();
778
1121
  return summary;
779
1122
  }
780
- // ─── TempOrder: 备注 ───
781
- updateTempOrderNote(note) {
1123
+ updateTempOrderNote(note, sync = false) {
782
1124
  const tempOrder = this.ensureTempOrder();
783
1125
  tempOrder.note = String(note || "");
784
1126
  this.persistTempOrder();
1127
+ if (sync) {
1128
+ const orderId = tempOrder.order_id;
1129
+ if (!orderId)
1130
+ return tempOrder.note;
1131
+ return this.syncTempOrderNoteToRemote(orderId, tempOrder.note);
1132
+ }
785
1133
  return tempOrder.note;
786
1134
  }
1135
+ async syncTempOrderNoteToRemote(orderId, note) {
1136
+ await this.request.put(`/order/order/${orderId}/note`, { note });
1137
+ return note;
1138
+ }
787
1139
  getTempOrderNote() {
788
1140
  var _a;
789
1141
  return ((_a = this.store.tempOrder) == null ? void 0 : _a.note) || "";
@@ -807,10 +1159,29 @@ var OrderModule = class extends import_BaseModule.BaseModule {
807
1159
  this.persistTempOrder();
808
1160
  return tempOrder.contacts_info;
809
1161
  }
1162
+ buildTempOrderCustomer(params) {
1163
+ if (!params.customerId)
1164
+ return null;
1165
+ const source = params.source ? (0, import_lodash_es.cloneDeep)(params.source) : {};
1166
+ const name = source.name ?? source.display_name ?? source.customerName ?? source.customer_name ?? params.customerName;
1167
+ const customerName = source.customer_name ?? source.customerName ?? source.display_name ?? source.name ?? params.customerName;
1168
+ return {
1169
+ ...source,
1170
+ id: source.id ?? params.customerId,
1171
+ customer_id: source.customer_id ?? params.customerId,
1172
+ name: String(name || ""),
1173
+ customer_name: String(customerName || ""),
1174
+ country_calling_code: String(
1175
+ source.country_calling_code ?? source.countryCallingCode ?? params.countryCallingCode
1176
+ ),
1177
+ phone: String(source.phone ?? params.phone),
1178
+ email: String(source.email ?? params.email)
1179
+ };
1180
+ }
810
1181
  /**
811
1182
  * 更新当前 tempOrder 的客户协议字段。
812
1183
  *
813
- * PaymentModal 只需要修改订单里的客户字段;如果外部还有客户模块需要同步,
1184
+ * PaymentModal 只需要修改订单里的客户事实;如果外部还有客户模块需要同步,
814
1185
  * 应由调用方通过回调处理,不能把外部 UI 状态写进 tempOrder。
815
1186
  */
816
1187
  updateTempOrderCustomer(customer) {
@@ -824,6 +1195,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
824
1195
  );
825
1196
  tempOrder.phone = String(customer.phone || "");
826
1197
  tempOrder.email = String(customer.email || "");
1198
+ tempOrder.customer = this.buildTempOrderCustomer({
1199
+ source: customer,
1200
+ customerId: tempOrder.customer_id,
1201
+ customerName: tempOrder.customer_name,
1202
+ countryCallingCode: tempOrder.country_calling_code,
1203
+ phone: tempOrder.phone,
1204
+ email: tempOrder.email
1205
+ });
827
1206
  this.persistTempOrder();
828
1207
  return {
829
1208
  customerId: tempOrder.customer_id,
@@ -838,11 +1217,20 @@ var OrderModule = class extends import_BaseModule.BaseModule {
838
1217
  return;
839
1218
  }
840
1219
  const tempOrder = this.ensureTempOrder();
1220
+ const previousCustomerId = tempOrder.customer_id ?? null;
841
1221
  tempOrder.customer_id = patch.customer_id || patch.id || null;
842
1222
  tempOrder.customer_name = String(patch.customer_name || "");
843
1223
  tempOrder.country_calling_code = String(patch.country_calling_code || "");
844
1224
  tempOrder.phone = String(patch.phone || "");
845
1225
  tempOrder.email = String(patch.email || "");
1226
+ tempOrder.customer = this.buildTempOrderCustomer({
1227
+ source: snapshot || null,
1228
+ customerId: tempOrder.customer_id,
1229
+ customerName: tempOrder.customer_name,
1230
+ countryCallingCode: tempOrder.country_calling_code,
1231
+ phone: tempOrder.phone,
1232
+ email: tempOrder.email
1233
+ });
846
1234
  if (snapshot !== void 0) {
847
1235
  const extend = this.ensureExtend(tempOrder);
848
1236
  if (snapshot === null)
@@ -850,12 +1238,19 @@ var OrderModule = class extends import_BaseModule.BaseModule {
850
1238
  else
851
1239
  extend.customerSnapshot = (0, import_lodash_es.cloneDeep)(snapshot);
852
1240
  }
1241
+ const nextCustomerId = tempOrder.customer_id ?? null;
1242
+ if (String(previousCustomerId ?? "") !== String(nextCustomerId ?? "")) {
1243
+ (0, import_utils.clearTempOrderHolderAssignments)(tempOrder);
1244
+ }
853
1245
  this.persistTempOrder();
854
- this.emitOrderCustomerChange();
1246
+ this.saveDraftInBackground();
1247
+ if (String(previousCustomerId ?? "") !== String(nextCustomerId ?? "")) {
1248
+ this.emitOrderCustomerChange();
1249
+ }
855
1250
  }
856
1251
  getOrderCustomer() {
857
1252
  const tempOrder = this.store.tempOrder;
858
- if (!tempOrder || tempOrder.customer_id === null || tempOrder.customer_id === void 0) {
1253
+ if (!tempOrder || !tempOrder.customer_id) {
859
1254
  return null;
860
1255
  }
861
1256
  return {
@@ -873,14 +1268,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
873
1268
  }
874
1269
  clearOrderCustomer() {
875
1270
  const tempOrder = this.ensureTempOrder();
1271
+ (0, import_utils.clearTempOrderHolderAssignments)(tempOrder);
876
1272
  tempOrder.customer_id = null;
877
1273
  tempOrder.customer_name = "";
878
1274
  tempOrder.country_calling_code = "";
879
1275
  tempOrder.phone = "";
880
1276
  tempOrder.email = "";
1277
+ tempOrder.customer = null;
881
1278
  if (tempOrder._extend)
882
1279
  delete tempOrder._extend.customerSnapshot;
883
1280
  this.persistTempOrder();
1281
+ this.saveDraftInBackground();
884
1282
  this.core.effects.emit(import_types.OrderHooks.OnOrderCustomerChange, null);
885
1283
  }
886
1284
  emitOrderCustomerChange() {
@@ -920,10 +1318,20 @@ var OrderModule = class extends import_BaseModule.BaseModule {
920
1318
  }
921
1319
  /** 追加单个支付项,并立即持久化当前 tempOrder。 */
922
1320
  addOrderPayment(payment) {
1321
+ this.logInfo("addOrderPayment", {
1322
+ payment
1323
+ });
923
1324
  const tempOrder = this.ensureTempOrder();
924
- const mapped = (0, import_utils.mapPaymentItemsToOrderPayments)([payment]);
1325
+ const mapped = (0, import_utils.mapPaymentItemsToOrderPayments)([
1326
+ this.normalizePaymentSource(payment, { defaultPaid: true })
1327
+ ]);
925
1328
  tempOrder.payments = [...tempOrder.payments || [], ...mapped];
926
1329
  this.persistTempOrder();
1330
+ void this.recalculateSummary({ createIfMissing: true }).catch((error) => {
1331
+ this.logError("recalculate summary after addOrderPayment failed", {
1332
+ error: error instanceof Error ? error.message : String(error)
1333
+ });
1334
+ });
927
1335
  return tempOrder.payments;
928
1336
  }
929
1337
  /**
@@ -989,14 +1397,24 @@ var OrderModule = class extends import_BaseModule.BaseModule {
989
1397
  */
990
1398
  updateVoucherOrderPayments(payments) {
991
1399
  const tempOrder = this.ensureTempOrder();
992
- const mappedVouchers = (0, import_utils.mapPaymentItemsToOrderPayments)(payments).filter(
993
- (payment) => payment.voucher_id !== void 0 && Number(payment.voucher_id) !== 0
994
- );
1400
+ const mappedVouchers = (0, import_utils.mapPaymentItemsToOrderPayments)(
1401
+ payments.map(
1402
+ (payment) => this.normalizePaymentSource(payment, { defaultPaid: false })
1403
+ )
1404
+ ).filter((payment) => {
1405
+ return payment.voucher_id !== void 0 && Number(payment.voucher_id) !== 0;
1406
+ });
995
1407
  const nonVoucherPayments = (tempOrder.payments || []).filter((payment) => {
996
1408
  return payment.voucher_id === void 0 || Number(payment.voucher_id) === 0;
997
1409
  });
998
1410
  tempOrder.payments = [...nonVoucherPayments, ...mappedVouchers];
1411
+ this.updateTempOrderPaymentStatus(tempOrder);
999
1412
  this.persistTempOrder();
1413
+ void this.recalculateSummary({ createIfMissing: true }).catch((error) => {
1414
+ this.logError("recalculate summary after updateVoucherOrderPayments failed", {
1415
+ error: error instanceof Error ? error.message : String(error)
1416
+ });
1417
+ });
1000
1418
  return tempOrder.payments;
1001
1419
  }
1002
1420
  async shouldMergeProductToOrder(params) {
@@ -1026,6 +1444,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1026
1444
  productToAdd.product_bundle
1027
1445
  );
1028
1446
  const normalizedIncoming = (0, import_utils3.normalizeOrderProduct)(productToAdd);
1447
+ normalizedIncoming.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
1448
+ normalizedIncoming.discount_list
1449
+ );
1029
1450
  const hasIncomingGoodPass = this.hasGoodPassDiscount(
1030
1451
  normalizedIncoming
1031
1452
  );
@@ -1082,6 +1503,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1082
1503
  unique_identification_number: targetUid
1083
1504
  }
1084
1505
  });
1506
+ normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
1507
+ normalizedProduct.discount_list
1508
+ );
1085
1509
  tempOrder.products[matchedIndex] = {
1086
1510
  ...targetProduct,
1087
1511
  ...normalizedProduct,
@@ -1104,6 +1528,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1104
1528
  if (linked) {
1105
1529
  tempOrder.bookings = [...tempOrder.bookings || [], linked.booking];
1106
1530
  }
1531
+ await this.applyPromotion();
1107
1532
  this.applyDiscount();
1108
1533
  await this.recalculateSummary({ createIfMissing: true });
1109
1534
  this.persistTempOrder();
@@ -1127,15 +1552,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1127
1552
  (item) => (item == null ? void 0 : item.type) === "good_pass" || (item == null ? void 0 : item.tag) === "good_pass"
1128
1553
  );
1129
1554
  }
1130
- async updateProductInOrder(params) {
1131
- var _a, _b, _c, _d, _e;
1555
+ async updateOrderProduct(params) {
1556
+ var _a, _b, _c, _d, _e, _f, _g;
1132
1557
  const {
1133
1558
  product_id,
1134
1559
  product_variant_id,
1135
1560
  updates,
1136
1561
  unique_identification_number,
1562
+ identity_key,
1137
1563
  product_option_item,
1138
- product_bundle
1564
+ product_bundle,
1565
+ booking
1139
1566
  } = params;
1140
1567
  const tempOrder = this.ensureTempOrder();
1141
1568
  const identityLookup = {
@@ -1144,12 +1571,30 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1144
1571
  };
1145
1572
  if (unique_identification_number !== void 0) {
1146
1573
  identityLookup.unique_identification_number = unique_identification_number;
1574
+ if (identity_key === void 0) {
1575
+ identityLookup.identity_key = unique_identification_number;
1576
+ }
1577
+ }
1578
+ if (identity_key !== void 0) {
1579
+ identityLookup.identity_key = identity_key;
1147
1580
  }
1148
1581
  if (product_option_item !== void 0)
1149
1582
  identityLookup.product_option_item = product_option_item;
1150
1583
  if (product_bundle !== void 0)
1151
1584
  identityLookup.product_bundle = product_bundle;
1152
- const productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, identityLookup);
1585
+ let productIndex = -1;
1586
+ if (unique_identification_number !== void 0) {
1587
+ const targetUid = String(unique_identification_number);
1588
+ productIndex = tempOrder.products.findIndex((item) => {
1589
+ var _a2;
1590
+ return String(
1591
+ ((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number || ""
1592
+ ) === targetUid;
1593
+ });
1594
+ }
1595
+ if (productIndex === -1) {
1596
+ productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, identityLookup);
1597
+ }
1153
1598
  if (productIndex === -1) {
1154
1599
  throw new Error("[Order] 目标商品不存在,无法更新");
1155
1600
  }
@@ -1176,28 +1621,178 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1176
1621
  delete nextProduct.metadata.main_product_original_price;
1177
1622
  delete nextProduct.metadata.price_schema_version;
1178
1623
  }
1179
- tempOrder.products[productIndex] = (0, import_utils3.normalizeOrderProduct)(nextProduct);
1624
+ let normalizedProduct = (0, import_utils3.normalizeOrderProduct)(nextProduct);
1625
+ normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
1626
+ normalizedProduct.discount_list
1627
+ );
1628
+ if (booking) {
1629
+ const productUid = String(
1630
+ ((_e = normalizedProduct.metadata) == null ? void 0 : _e.unique_identification_number) || ((_f = targetProduct.metadata) == null ? void 0 : _f.unique_identification_number) || unique_identification_number || (0, import_utils.createUuidV4)()
1631
+ );
1632
+ normalizedProduct.metadata = {
1633
+ ...normalizedProduct.metadata || {},
1634
+ unique_identification_number: productUid
1635
+ };
1636
+ const linked = this.createLinkedProductAndBooking({
1637
+ product: {
1638
+ ...normalizedProduct,
1639
+ unique_identification_number: productUid
1640
+ },
1641
+ booking
1642
+ });
1643
+ this.removeLinkedBookingsForProduct(tempOrder, targetProduct);
1644
+ normalizedProduct = {
1645
+ ...normalizedProduct,
1646
+ booking_uid: linked.bookingUid,
1647
+ metadata: {
1648
+ ...normalizedProduct.metadata || {},
1649
+ booking_uid: linked.bookingUid,
1650
+ unique_identification_number: productUid
1651
+ }
1652
+ };
1653
+ tempOrder.bookings = [...tempOrder.bookings || [], linked.booking];
1654
+ }
1655
+ tempOrder.products[productIndex] = normalizedProduct;
1180
1656
  this.captureProductRuntime(
1181
1657
  tempOrder,
1182
1658
  updates,
1183
1659
  tempOrder.products[productIndex],
1184
- (_e = tempOrder.products[productIndex].metadata) == null ? void 0 : _e.unique_identification_number
1660
+ (_g = tempOrder.products[productIndex].metadata) == null ? void 0 : _g.unique_identification_number
1185
1661
  );
1662
+ await this.applyPromotion();
1186
1663
  this.applyDiscount();
1187
1664
  await this.recalculateSummary({ createIfMissing: true });
1188
1665
  this.persistTempOrder();
1189
1666
  return tempOrder.products;
1190
1667
  }
1191
- async removeProductFromOrder(identity) {
1668
+ async updateOrderProductQuantity(params) {
1669
+ var _a;
1670
+ const {
1671
+ product_id,
1672
+ product_variant_id,
1673
+ num,
1674
+ unique_identification_number,
1675
+ identity_key,
1676
+ product_option_item,
1677
+ product_bundle
1678
+ } = params;
1192
1679
  const tempOrder = this.ensureTempOrder();
1193
- tempOrder.products = tempOrder.products.filter(
1194
- (item) => !(0, import_utils3.isIdentityMatch)(item, identity)
1680
+ const identityLookup = {
1681
+ product_id,
1682
+ product_variant_id
1683
+ };
1684
+ if (unique_identification_number !== void 0) {
1685
+ identityLookup.unique_identification_number = unique_identification_number;
1686
+ if (identity_key === void 0) {
1687
+ identityLookup.identity_key = unique_identification_number;
1688
+ }
1689
+ }
1690
+ if (identity_key !== void 0)
1691
+ identityLookup.identity_key = identity_key;
1692
+ if (product_option_item !== void 0)
1693
+ identityLookup.product_option_item = product_option_item;
1694
+ if (product_bundle !== void 0)
1695
+ identityLookup.product_bundle = product_bundle;
1696
+ let productIndex = -1;
1697
+ if (unique_identification_number !== void 0) {
1698
+ const targetUid = String(unique_identification_number);
1699
+ productIndex = tempOrder.products.findIndex((item) => {
1700
+ var _a2;
1701
+ return String(
1702
+ ((_a2 = item.metadata) == null ? void 0 : _a2.unique_identification_number) || item.unique_identification_number || ""
1703
+ ) === targetUid;
1704
+ });
1705
+ }
1706
+ if (productIndex === -1) {
1707
+ productIndex = (0, import_utils3.getProductIdentityIndex)(tempOrder.products, identityLookup);
1708
+ }
1709
+ if (productIndex === -1) {
1710
+ throw new Error("[Order] 目标商品不存在,无法更新数量");
1711
+ }
1712
+ const targetProduct = tempOrder.products[productIndex];
1713
+ const normalizedProduct = (0, import_utils3.normalizeOrderProduct)({
1714
+ ...targetProduct,
1715
+ num: (0, import_utils3.getSafeProductNum)(num),
1716
+ metadata: {
1717
+ ...targetProduct.metadata || {},
1718
+ unique_identification_number: ((_a = targetProduct.metadata) == null ? void 0 : _a.unique_identification_number) || unique_identification_number
1719
+ }
1720
+ });
1721
+ normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
1722
+ normalizedProduct.discount_list
1195
1723
  );
1724
+ tempOrder.products[productIndex] = normalizedProduct;
1725
+ await this.applyPromotion();
1196
1726
  this.applyDiscount();
1197
1727
  await this.recalculateSummary({ createIfMissing: true });
1198
1728
  this.persistTempOrder();
1199
1729
  return tempOrder.products;
1200
1730
  }
1731
+ updateOrderBooking(params) {
1732
+ const { unique_identification_number, updates } = params;
1733
+ const tempOrder = this.ensureTempOrder();
1734
+ const bookingUid = String(unique_identification_number || "");
1735
+ const bookingIndex = this.findBookingIndexByUniqueIdentificationNumber(
1736
+ tempOrder,
1737
+ bookingUid
1738
+ );
1739
+ if (!bookingUid || bookingIndex === -1) {
1740
+ throw new Error("[Order] 目标 booking 不存在,无法更新");
1741
+ }
1742
+ const targetBooking = tempOrder.bookings[bookingIndex] || {};
1743
+ const nextBooking = {
1744
+ ...targetBooking,
1745
+ ...updates,
1746
+ metadata: {
1747
+ ...targetBooking.metadata || {},
1748
+ ...updates.metadata || {},
1749
+ unique_identification_number: bookingUid
1750
+ }
1751
+ };
1752
+ nextBooking.is_all = (0, import_utils.normalizeBookingIsAll)(nextBooking);
1753
+ nextBooking.sub_type = (0, import_utils.normalizeBookingSubType)(nextBooking);
1754
+ tempOrder.bookings[bookingIndex] = nextBooking;
1755
+ this.persistTempOrder();
1756
+ return tempOrder.bookings;
1757
+ }
1758
+ async removeProductFromOrder(identity) {
1759
+ const tempOrder = this.ensureTempOrder();
1760
+ const removedProducts = [];
1761
+ tempOrder.products = tempOrder.products.filter((item) => {
1762
+ const shouldRemove = (0, import_utils3.isIdentityMatch)(item, identity);
1763
+ if (shouldRemove)
1764
+ removedProducts.push(item);
1765
+ return !shouldRemove;
1766
+ });
1767
+ for (const product of removedProducts) {
1768
+ this.removeLinkedBookingsForProduct(tempOrder, product);
1769
+ }
1770
+ await this.applyPromotion();
1771
+ this.applyDiscount();
1772
+ await this.recalculateSummary({ createIfMissing: true });
1773
+ this.persistTempOrder();
1774
+ return tempOrder.products;
1775
+ }
1776
+ /**
1777
+ * 仅清空购物车行(products / bookings),不重置整单。
1778
+ * 用于「仅清空商品」;客户、备注、支付等协议字段保持不变。
1779
+ */
1780
+ async clearOrderCartLines() {
1781
+ const tempOrder = this.ensureTempOrder();
1782
+ tempOrder.products = [];
1783
+ tempOrder.bookings = [];
1784
+ if (tempOrder._extend && typeof tempOrder._extend === "object") {
1785
+ tempOrder._extend = {
1786
+ ...tempOrder._extend,
1787
+ productsByUid: {}
1788
+ };
1789
+ }
1790
+ await this.applyPromotion();
1791
+ this.applyDiscount();
1792
+ await this.recalculateSummary({ createIfMissing: true });
1793
+ this.persistTempOrder();
1794
+ return tempOrder;
1795
+ }
1201
1796
  // ─── TempOrder: 提交 ───
1202
1797
  /**
1203
1798
  * 提交当前 Sales tempOrder。
@@ -1224,7 +1819,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1224
1819
  ...hasPaymentStatusOverride ? { payment_status: params == null ? void 0 : params.paymentStatus } : {},
1225
1820
  ...hasSmallTicketDataFlagOverride ? { small_ticket_data_flag: params == null ? void 0 : params.smallTicketDataFlag } : {}
1226
1821
  };
1227
- return (params == null ? void 0 : params.enhancePayload) ? params.enhancePayload(nextPayload, ctx) : nextPayload;
1822
+ const enhancedPayload = (params == null ? void 0 : params.enhancePayload) ? params.enhancePayload(nextPayload, ctx) : nextPayload;
1823
+ return enhancedPayload;
1228
1824
  } : void 0;
1229
1825
  const payload = (0, import_utils.buildSubmitPayload)({
1230
1826
  tempOrder,
@@ -1241,6 +1837,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1241
1837
  this.logInfo("submitTempOrder calling sales checkout", {
1242
1838
  orderId: payload.order_id,
1243
1839
  externalSaleNumber: payload.external_sale_number,
1840
+ requestUniqueIdempotencyToken: payload.request_unique_idempotency_token,
1244
1841
  paymentStatus: payload.payment_status,
1245
1842
  paymentsCount: ((_b = payload.payments) == null ? void 0 : _b.length) || 0,
1246
1843
  smallTicketDataFlag: payload.small_ticket_data_flag
@@ -1327,21 +1924,37 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1327
1924
  const mappedPayments = (0, import_utils.mapPaymentItemsToOrderPayments)(
1328
1925
  params.payments || []
1329
1926
  );
1330
- tempOrder.payments = mappedPayments;
1331
- if (params.paymentStatus)
1332
- tempOrder.payment_status = params.paymentStatus;
1333
- this.persistTempOrder();
1334
- await this.saveDraft();
1335
1927
  const paymentTotal = this.calculatePaymentTotal(mappedPayments);
1336
1928
  const targetAmount = this.getPaymentTargetAmount();
1337
1929
  const isFullyPaid = targetAmount.lte(0) ? false : paymentTotal.gte(targetAmount);
1338
- if (!isFullyPaid || !params.submitWhenPaid) {
1930
+ const paymentStatus = isFullyPaid ? params.paymentStatus || "paid" : "partially_paid";
1931
+ tempOrder.payments = mappedPayments;
1932
+ tempOrder.payment_status = paymentStatus;
1933
+ this.persistTempOrder();
1934
+ await this.saveDraft();
1935
+ if (!params.submitWhenPaid) {
1339
1936
  return { isFullyPaid };
1340
1937
  }
1938
+ if (this.store.syncState === "submitting") {
1939
+ return { isFullyPaid };
1940
+ }
1941
+ this.store.syncState = "submitting";
1942
+ const paymentSyncIdempotencyToken = this.buildPaymentSyncIdempotencyToken(
1943
+ tempOrder,
1944
+ mappedPayments
1945
+ );
1341
1946
  const submitResult = await this.submitTempOrder({
1342
1947
  payments: mappedPayments,
1343
- paymentStatus: params.paymentStatus || "paid",
1344
- smallTicketDataFlag: params.smallTicketDataFlag
1948
+ paymentStatus,
1949
+ smallTicketDataFlag: params.smallTicketDataFlag,
1950
+ channel: params.channel,
1951
+ enhancePayload: (payload) => {
1952
+ const nextPayload = {
1953
+ ...payload,
1954
+ request_unique_idempotency_token: paymentSyncIdempotencyToken
1955
+ };
1956
+ return nextPayload;
1957
+ }
1345
1958
  });
1346
1959
  return { isFullyPaid, submitResult };
1347
1960
  }
@@ -1689,6 +2302,33 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1689
2302
  nextTempOrder[key] = raw[key];
1690
2303
  }
1691
2304
  });
2305
+ this.store.tempOrder = nextTempOrder;
2306
+ this.store.summary = raw.summary && typeof raw.summary === "object" ? { ...(0, import_utils.createEmptySummary)(), ...raw.summary } : (0, import_utils.createEmptySummary)();
2307
+ this.store.lastOrderInfo = raw.lastOrderInfo || raw;
2308
+ if (options == null ? void 0 : options.recalcOnHydrate) {
2309
+ await this.recalculateSummary({ createIfMissing: false });
2310
+ }
2311
+ this.persistTempOrder();
2312
+ return nextTempOrder;
2313
+ }
2314
+ normalizeTempOrderForRuntime(raw, options) {
2315
+ const nextTempOrder = {
2316
+ ...this.createDefaultTempOrderInstance(),
2317
+ ...raw || {}
2318
+ };
2319
+ delete nextTempOrder.summary;
2320
+ delete nextTempOrder.lastOrderInfo;
2321
+ delete nextTempOrder.discount_list;
2322
+ delete nextTempOrder.shop_id;
2323
+ delete nextTempOrder.create_date;
2324
+ delete nextTempOrder.total_amount;
2325
+ delete nextTempOrder.expect_amount;
2326
+ delete nextTempOrder.paid_amount;
2327
+ delete nextTempOrder.shop_note;
2328
+ delete nextTempOrder.start_time;
2329
+ delete nextTempOrder.tax_fee;
2330
+ delete nextTempOrder.total_refund_amount;
2331
+ delete nextTempOrder.holder_id;
1692
2332
  nextTempOrder.metadata = raw.metadata && typeof raw.metadata === "object" ? { ...raw.metadata } : {};
1693
2333
  nextTempOrder.holder = raw.holder && typeof raw.holder === "object" ? { ...raw.holder } : null;
1694
2334
  nextTempOrder.products = Array.isArray(raw.products) ? raw.products.map((p) => this.normalizeHydratedOrderProduct(p)) : [];
@@ -1699,7 +2339,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1699
2339
  })) : [];
1700
2340
  nextTempOrder.payments = Array.isArray(raw.payments) ? raw.payments.map((p) => ({ ...p || {} })) : [];
1701
2341
  nextTempOrder.surcharges = Array.isArray(raw.surcharges) ? raw.surcharges.map((s) => ({ ...s || {} })) : [];
1702
- nextTempOrder.discount_list = Array.isArray(raw.discount_list) ? raw.discount_list.map((d) => ({ ...d || {} })) : [];
1703
2342
  nextTempOrder.relation_forms = Array.isArray(raw.relation_forms) ? raw.relation_forms.map((f) => ({ ...f || {} })) : [];
1704
2343
  nextTempOrder.contacts = Array.isArray(raw.contacts) ? raw.contacts.map((c) => ({ ...c || {} })) : [];
1705
2344
  nextTempOrder.contacts_info = raw.contacts_info && typeof raw.contacts_info === "object" && !Array.isArray(raw.contacts_info) ? { ...raw.contacts_info } : null;
@@ -1707,14 +2346,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1707
2346
  ...raw._extend,
1708
2347
  productsByUid: raw._extend.productsByUid || {}
1709
2348
  } : { productsByUid: {} };
1710
- this.ensureExternalSaleNumber(nextTempOrder);
1711
- this.store.tempOrder = nextTempOrder;
1712
- this.store.summary = raw.summary && typeof raw.summary === "object" ? { ...(0, import_utils.createEmptySummary)(), ...raw.summary } : (0, import_utils.createEmptySummary)();
1713
- this.store.lastOrderInfo = raw.lastOrderInfo || raw;
1714
- if (options == null ? void 0 : options.recalcOnHydrate) {
1715
- await this.recalculateSummary({ createIfMissing: false });
2349
+ if ((options == null ? void 0 : options.ensureIdentity) !== false) {
2350
+ this.ensureExternalSaleNumber(nextTempOrder);
1716
2351
  }
1717
- this.persistTempOrder();
1718
2352
  return nextTempOrder;
1719
2353
  }
1720
2354
  normalizeHydratedOrderProduct(product) {
@@ -1733,6 +2367,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1733
2367
  row.metadata.unique_identification_number = (0, import_utils.createUuidV4)();
1734
2368
  }
1735
2369
  const normalized = (0, import_utils3.normalizeOrderProduct)(row);
2370
+ normalized.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
2371
+ normalized.discount_list
2372
+ );
1736
2373
  const result = {
1737
2374
  ...row,
1738
2375
  ...normalized,