@pisell/pisellos 2.2.264 → 2.2.265

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 (152) hide show
  1. package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +50 -0
  2. package/dist/model/strategy/adapter/dataVariant/adapter.js +167 -0
  3. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +89 -0
  4. package/dist/model/strategy/adapter/dataVariant/evaluator.js +780 -0
  5. package/dist/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
  6. package/dist/model/strategy/adapter/dataVariant/examples.js +277 -0
  7. package/dist/model/strategy/adapter/dataVariant/index.d.ts +4 -0
  8. package/dist/model/strategy/adapter/dataVariant/index.js +4 -0
  9. package/dist/model/strategy/adapter/dataVariant/type.d.ts +148 -0
  10. package/dist/model/strategy/adapter/dataVariant/type.js +54 -0
  11. package/dist/model/strategy/adapter/index.d.ts +4 -0
  12. package/dist/model/strategy/adapter/index.js +5 -1
  13. package/dist/model/strategy/adapter/promotion/adapter.d.ts +0 -4
  14. package/dist/model/strategy/adapter/promotion/adapter.js +0 -23
  15. package/dist/model/strategy/adapter/promotion/evaluator.d.ts +0 -17
  16. package/dist/model/strategy/adapter/promotion/evaluator.js +6 -279
  17. package/dist/model/strategy/adapter/promotion/examples.d.ts +0 -86
  18. package/dist/model/strategy/adapter/promotion/examples.js +0 -99
  19. package/dist/model/strategy/adapter/promotion/index.d.ts +1 -1
  20. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  21. package/dist/model/strategy/adapter/promotion/type.d.ts +2 -90
  22. package/dist/model/strategy/adapter/promotion/type.js +0 -45
  23. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +16 -10
  24. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  25. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  26. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +32 -1
  27. package/dist/modules/Discount/index.d.ts +5 -2
  28. package/dist/modules/Discount/index.js +30 -7
  29. package/dist/modules/Discount/types.d.ts +4 -0
  30. package/dist/modules/Order/index.d.ts +41 -10
  31. package/dist/modules/Order/index.js +1370 -808
  32. package/dist/modules/Order/payment-utils.d.ts +26 -0
  33. package/dist/modules/Order/payment-utils.js +225 -0
  34. package/dist/modules/Order/types.d.ts +49 -1
  35. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  36. package/dist/modules/Order/utils/orderCollectionIdentity.js +410 -0
  37. package/dist/modules/Order/utils.d.ts +4 -3
  38. package/dist/modules/Order/utils.js +62 -66
  39. package/dist/modules/Payment/index.d.ts +2 -0
  40. package/dist/modules/Payment/index.js +78 -49
  41. package/dist/modules/Payment/types.d.ts +26 -24
  42. package/dist/modules/Payment/types.js +2 -0
  43. package/dist/modules/Product/types.d.ts +22 -0
  44. package/dist/modules/ProductList/index.d.ts +1 -1
  45. package/dist/modules/ProductList/index.js +4 -2
  46. package/dist/modules/ProductList/types.d.ts +2 -0
  47. package/dist/modules/Rules/index.d.ts +2 -9
  48. package/dist/modules/Rules/index.js +69 -43
  49. package/dist/modules/Rules/types.d.ts +10 -1
  50. package/dist/server/index.d.ts +71 -0
  51. package/dist/server/index.js +2504 -1187
  52. package/dist/server/modules/order/index.d.ts +56 -5
  53. package/dist/server/modules/order/index.js +1718 -834
  54. package/dist/server/modules/order/types.d.ts +15 -3
  55. package/dist/server/modules/order/types.js +1 -1
  56. package/dist/server/modules/products/index.d.ts +31 -8
  57. package/dist/server/modules/products/index.js +549 -390
  58. package/dist/server/modules/products/types.d.ts +18 -0
  59. package/dist/solution/BaseSales/index.d.ts +54 -4
  60. package/dist/solution/BaseSales/index.js +1448 -788
  61. package/dist/solution/BaseSales/types.d.ts +6 -1
  62. package/dist/solution/BaseSales/types.js +1 -1
  63. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +1 -3
  64. package/dist/solution/BaseSales/utils/cartPromotion.js +50 -97
  65. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +9 -4
  66. package/dist/solution/BaseSales/utils/parseSalesResponse.js +6 -8
  67. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -1
  68. package/dist/solution/BookingByStep/index.d.ts +1 -1
  69. package/dist/solution/BookingTicket/index.js +61 -26
  70. package/dist/solution/BookingTicket/types.d.ts +2 -0
  71. package/dist/solution/Sales/index.d.ts +1 -0
  72. package/dist/solution/Sales/index.js +10 -2
  73. package/dist/solution/ScanOrder/index.js +20 -31
  74. package/dist/solution/ShopDiscount/index.js +15 -14
  75. package/dist/solution/VenueBooking/index.js +19 -30
  76. package/dist/utils/payment-number.d.ts +9 -0
  77. package/dist/utils/payment-number.js +69 -0
  78. package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +50 -0
  79. package/lib/model/strategy/adapter/dataVariant/adapter.js +149 -0
  80. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +89 -0
  81. package/lib/model/strategy/adapter/dataVariant/evaluator.js +583 -0
  82. package/lib/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
  83. package/lib/model/strategy/adapter/dataVariant/examples.js +293 -0
  84. package/lib/model/strategy/adapter/dataVariant/index.d.ts +4 -0
  85. package/lib/model/strategy/adapter/dataVariant/index.js +38 -0
  86. package/lib/model/strategy/adapter/dataVariant/type.d.ts +148 -0
  87. package/lib/model/strategy/adapter/dataVariant/type.js +31 -0
  88. package/lib/model/strategy/adapter/index.d.ts +4 -0
  89. package/lib/model/strategy/adapter/index.js +13 -2
  90. package/lib/model/strategy/adapter/promotion/adapter.d.ts +0 -4
  91. package/lib/model/strategy/adapter/promotion/adapter.js +0 -20
  92. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +0 -17
  93. package/lib/model/strategy/adapter/promotion/evaluator.js +0 -235
  94. package/lib/model/strategy/adapter/promotion/examples.d.ts +0 -86
  95. package/lib/model/strategy/adapter/promotion/examples.js +0 -91
  96. package/lib/model/strategy/adapter/promotion/index.d.ts +1 -1
  97. package/lib/model/strategy/adapter/promotion/index.js +0 -2
  98. package/lib/model/strategy/adapter/promotion/type.d.ts +2 -90
  99. package/lib/model/strategy/adapter/promotion/type.js +0 -2
  100. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +5 -0
  101. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +1 -0
  102. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  103. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +23 -2
  104. package/lib/modules/Discount/index.d.ts +5 -2
  105. package/lib/modules/Discount/index.js +23 -3
  106. package/lib/modules/Discount/types.d.ts +4 -0
  107. package/lib/modules/Order/index.d.ts +41 -10
  108. package/lib/modules/Order/index.js +505 -119
  109. package/lib/modules/Order/payment-utils.d.ts +26 -0
  110. package/lib/modules/Order/payment-utils.js +224 -0
  111. package/lib/modules/Order/types.d.ts +49 -1
  112. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  113. package/lib/modules/Order/utils/orderCollectionIdentity.js +418 -0
  114. package/lib/modules/Order/utils.d.ts +4 -3
  115. package/lib/modules/Order/utils.js +27 -26
  116. package/lib/modules/Payment/index.d.ts +2 -0
  117. package/lib/modules/Payment/index.js +33 -12
  118. package/lib/modules/Payment/types.d.ts +26 -24
  119. package/lib/modules/Product/types.d.ts +22 -0
  120. package/lib/modules/ProductList/index.d.ts +1 -1
  121. package/lib/modules/ProductList/index.js +4 -2
  122. package/lib/modules/ProductList/types.d.ts +2 -0
  123. package/lib/modules/Rules/index.d.ts +2 -9
  124. package/lib/modules/Rules/index.js +61 -29
  125. package/lib/modules/Rules/types.d.ts +10 -1
  126. package/lib/server/index.d.ts +71 -0
  127. package/lib/server/index.js +1002 -52
  128. package/lib/server/modules/order/index.d.ts +56 -5
  129. package/lib/server/modules/order/index.js +798 -148
  130. package/lib/server/modules/order/types.d.ts +15 -3
  131. package/lib/server/modules/products/index.d.ts +31 -8
  132. package/lib/server/modules/products/index.js +134 -35
  133. package/lib/server/modules/products/types.d.ts +18 -0
  134. package/lib/solution/BaseSales/index.d.ts +54 -4
  135. package/lib/solution/BaseSales/index.js +475 -50
  136. package/lib/solution/BaseSales/types.d.ts +6 -1
  137. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +1 -3
  138. package/lib/solution/BaseSales/utils/cartPromotion.js +25 -64
  139. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +9 -4
  140. package/lib/solution/BaseSales/utils/parseSalesResponse.js +4 -5
  141. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +8 -0
  142. package/lib/solution/BookingByStep/index.d.ts +1 -1
  143. package/lib/solution/BookingTicket/index.js +35 -9
  144. package/lib/solution/BookingTicket/types.d.ts +2 -0
  145. package/lib/solution/Sales/index.d.ts +1 -0
  146. package/lib/solution/Sales/index.js +5 -3
  147. package/lib/solution/ScanOrder/index.js +0 -8
  148. package/lib/solution/ShopDiscount/index.js +2 -1
  149. package/lib/solution/VenueBooking/index.js +0 -8
  150. package/lib/utils/payment-number.d.ts +9 -0
  151. package/lib/utils/payment-number.js +64 -0
  152. package/package.json +1 -1
@@ -37,10 +37,13 @@ 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_payment_utils = require("./payment-utils");
41
+ var import_payment_number = require("../../utils/payment-number");
40
42
  var import_cartPromotion = require("../../solution/BaseSales/utils/cartPromotion");
41
43
  var import_utils3 = require("../../solution/ScanOrder/utils");
42
44
  var import_manualProductDiscount = require("./utils/manualProductDiscount");
43
45
  var import_bundleDiscountHydration = require("./utils/bundleDiscountHydration");
46
+ var import_orderCollectionIdentity = require("./utils/orderCollectionIdentity");
44
47
  var import_Discount = require("../Discount");
45
48
  var import_Rules = require("../Rules");
46
49
  var import_types2 = require("../Rules/types");
@@ -107,7 +110,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
107
110
  this.draftPersistEnabled = true;
108
111
  }
109
112
  collectHydratedEditDiscounts(products) {
110
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
113
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
111
114
  const discountMap = /* @__PURE__ */ new Map();
112
115
  for (const product of (0, import_bundleDiscountHydration.expandHydratedProductsForDiscountCollection)(products)) {
113
116
  for (const item of (product == null ? void 0 : product.discount_list) || []) {
@@ -137,6 +140,13 @@ var OrderModule = class extends import_BaseModule.BaseModule {
137
140
  existed.amount = Number(existed.amount || 0) + amount;
138
141
  existed.used_par_value = String(Number(existed.used_par_value || 0) + amount);
139
142
  existed.balance = String(Number(existed.balance || 0) + amount);
143
+ const productIds = Array.isArray((_f = existed.limited_relation_product_data) == null ? void 0 : _f.product_ids) ? existed.limited_relation_product_data.product_ids : [];
144
+ if ((product == null ? void 0 : product.product_id) !== void 0 && (product == null ? void 0 : product.product_id) !== null && !productIds.includes(product.product_id)) {
145
+ existed.limited_relation_product_data = {
146
+ ...existed.limited_relation_product_data || {},
147
+ product_ids: [...productIds, product.product_id]
148
+ };
149
+ }
140
150
  existed.applicableProductDetails = [
141
151
  ...existed.applicableProductDetails || [],
142
152
  detail
@@ -153,9 +163,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
153
163
  encoded: "",
154
164
  code: "",
155
165
  tag: type,
156
- product_id: ((_f = item == null ? void 0 : item.discount) == null ? void 0 : _f.discount_product_id) ?? (product == null ? void 0 : product.product_id) ?? 0,
166
+ product_id: ((_g = item == null ? void 0 : item.discount) == null ? void 0 : _g.discount_product_id) ?? (product == null ? void 0 : product.product_id) ?? 0,
157
167
  relation_type: "",
158
- par_value: String(((_g = item == null ? void 0 : item.discount) == null ? void 0 : _g.original_amount) ?? (item == null ? void 0 : item.amount) ?? "0"),
168
+ par_value: String(((_h = item == null ? void 0 : item.discount) == null ? void 0 : _h.original_amount) ?? (item == null ? void 0 : item.amount) ?? "0"),
159
169
  used_par_value: String((item == null ? void 0 : item.amount) ?? "0"),
160
170
  limit_status: "enable",
161
171
  limited_relation_product_data: {
@@ -185,8 +195,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
185
195
  discount: {
186
196
  ...(item == null ? void 0 : item.discount) || {},
187
197
  resource_id: key,
188
- discount_product_id: ((_h = item == null ? void 0 : item.discount) == null ? void 0 : _h.discount_product_id) ?? (product == null ? void 0 : product.product_id) ?? 0,
189
- discount_calculation_mode: ((_i = item == null ? void 0 : item.discount) == null ? void 0 : _i.discount_calculation_mode) ?? "item_level"
198
+ discount_product_id: ((_i = item == null ? void 0 : item.discount) == null ? void 0 : _i.discount_product_id) ?? (product == null ? void 0 : product.product_id) ?? 0,
199
+ discount_calculation_mode: ((_j = item == null ? void 0 : item.discount) == null ? void 0 : _j.discount_calculation_mode) ?? "item_level"
190
200
  },
191
201
  applicableProductDetails: [detail],
192
202
  appliedProductDetails: [detail]
@@ -301,12 +311,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
301
311
  if (!this.store.summary) {
302
312
  this.store.summary = (0, import_utils.createEmptySummary)();
303
313
  }
314
+ if (!Array.isArray(this.store.availableWalletIds)) {
315
+ this.store.availableWalletIds = [];
316
+ }
304
317
  this.request = this.core.getPlugin("request");
305
- const appPlugin = this.core.getPlugin("app");
306
- if (!appPlugin) {
318
+ this.appPlugin = this.core.getPlugin("app");
319
+ if (!this.appPlugin) {
307
320
  throw new Error("Order 模块需要 app 插件支持");
308
321
  }
309
- const app = appPlugin.getApp();
322
+ const app = this.appPlugin.getApp();
310
323
  this.logger = app.logger;
311
324
  this.window = this.core.getPlugin("window");
312
325
  const otherParams = options.otherParams || {};
@@ -428,19 +441,30 @@ var OrderModule = class extends import_BaseModule.BaseModule {
428
441
  async loadDiscountConfig(params) {
429
442
  var _a, _b, _c, _d, _e, _f, _g;
430
443
  const orderId = params.orderId || ((_a = this.store.tempOrder) == null ? void 0 : _a.order_id) || void 0;
431
- const discountList = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
444
+ const prepareConfigResult = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
432
445
  customer_id: params.customerId,
433
446
  action: params.action || (orderId ? "edit" : "create"),
434
447
  with_good_pass: 1,
435
448
  with_discount_card: 1,
436
449
  with_wallet_pass_holder: 1,
450
+ with_available_wallet_flag: 1,
451
+ with_available_wallet_pass_flag: 1,
437
452
  request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
438
453
  ...orderId ? { order_id: orderId } : {}
439
454
  }));
455
+ const discountList = prepareConfigResult == null ? void 0 : prepareConfigResult.discountList;
456
+ this.store.availableWalletIds = (prepareConfigResult == null ? void 0 : prepareConfigResult.availableWalletIds) || [];
440
457
  if (discountList) {
441
- const currentEditDiscounts = (((_c = this.store.discount) == null ? void 0 : _c.getDiscountList()) || []).filter((discount) => discount == null ? void 0 : discount.isEditMode);
458
+ const currentDiscountList = ((_c = this.store.discount) == null ? void 0 : _c.getDiscountList()) || [];
459
+ const currentEditDiscounts = currentDiscountList.filter((discount) => discount == null ? void 0 : discount.isEditMode);
460
+ const currentScanDiscounts = currentDiscountList.filter((discount) => discount == null ? void 0 : discount.isScan);
461
+ const currentScanDiscountIds = new Set(
462
+ currentScanDiscounts.map((discount) => discount == null ? void 0 : discount.id)
463
+ );
442
464
  const runtimeDiscountIds = /* @__PURE__ */ new Set();
443
465
  const runtimeDiscounts = discountList.filter((discount) => {
466
+ if (currentScanDiscountIds.has(discount == null ? void 0 : discount.id))
467
+ return false;
444
468
  if (runtimeDiscountIds.has(discount == null ? void 0 : discount.id))
445
469
  return false;
446
470
  runtimeDiscountIds.add(discount == null ? void 0 : discount.id);
@@ -448,6 +472,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
448
472
  });
449
473
  const mergedDiscountList = [
450
474
  ...currentEditDiscounts,
475
+ ...currentScanDiscounts,
451
476
  ...runtimeDiscounts
452
477
  ];
453
478
  await ((_d = this.store.discount) == null ? void 0 : _d.setOriginalDiscountList(mergedDiscountList));
@@ -462,6 +487,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
462
487
  var _a;
463
488
  return ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList()) || [];
464
489
  }
490
+ getAvailableWalletIds() {
491
+ return Array.isArray(this.store.availableWalletIds) ? [...this.store.availableWalletIds] : [];
492
+ }
493
+ async syncScannedDiscountsToOriginalDiscountList(discountList) {
494
+ var _a, _b, _c, _d;
495
+ const scanDiscounts = (discountList || []).filter((discount) => discount == null ? void 0 : discount.isScan);
496
+ if (!scanDiscounts.length)
497
+ return;
498
+ const scanDiscountIds = new Set(scanDiscounts.map((discount) => discount == null ? void 0 : discount.id));
499
+ const originalDiscounts = ((_b = (_a = this.store.discount) == null ? void 0 : _a.getOriginalDiscountList) == null ? void 0 : _b.call(_a)) || [];
500
+ const nextOriginalDiscounts = [
501
+ ...scanDiscounts,
502
+ ...originalDiscounts.filter((discount) => !scanDiscountIds.has(discount == null ? void 0 : discount.id))
503
+ ];
504
+ await ((_d = (_c = this.store.discount) == null ? void 0 : _c.setOriginalDiscountList) == null ? void 0 : _d.call(_c, nextOriginalDiscounts));
505
+ }
465
506
  async ensureEditDiscountConfigForProductChange(tempOrder) {
466
507
  var _a, _b, _c, _d, _e, _f;
467
508
  const orderId = tempOrder.order_id;
@@ -510,6 +551,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
510
551
  }));
511
552
  const currentSelected = this.getDiscountList().filter((n) => n.isSelected);
512
553
  if (currentSelected.length && currentSelected.some((n) => withScanList.some((m) => m.id === n.id))) {
554
+ await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
513
555
  return {
514
556
  type: "clientCalc",
515
557
  isAvailable: true,
@@ -530,6 +572,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
530
572
  if (isAvailable && newDiscountList) {
531
573
  (_d = this.store.discount) == null ? void 0 : _d.setDiscountList(newDiscountList);
532
574
  this.applyDiscount();
575
+ await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
533
576
  }
534
577
  return {
535
578
  type: "clientCalc",
@@ -539,8 +582,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
539
582
  unavailableReason
540
583
  };
541
584
  }
542
- applyDiscount() {
543
- var _a, _b, _c, _d;
585
+ applyDiscount(options) {
586
+ var _a, _b, _c;
544
587
  const tempOrder = this.store.tempOrder;
545
588
  if (!tempOrder)
546
589
  return;
@@ -553,13 +596,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
553
596
  const rulesModule = this.store.rules;
554
597
  if (!rulesModule)
555
598
  return;
556
- const holders = ((_b = tempOrder.holder) == null ? void 0 : _b.form_record) || [];
557
599
  const result = rulesModule.calcDiscount({
558
600
  productList: tempOrder.products,
559
601
  discountList,
560
- holders,
602
+ holders: [],
561
603
  isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
562
- orderTotalAmount: Number(((_c = this.store.summary) == null ? void 0 : _c.total_amount) || 0)
604
+ orderTotalAmount: Number(((_b = this.store.summary) == null ? void 0 : _b.total_amount) || 0)
605
+ }, {
606
+ reapplyBookingDiscountProductUids: options == null ? void 0 : options.reapplyBookingDiscountProductUids
563
607
  });
564
608
  if (result == null ? void 0 : result.productList) {
565
609
  const previousProductsByUid = (0, import_utils.indexOrderProductsByUid)(tempOrder.products);
@@ -588,7 +632,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
588
632
  result.productList || tempOrder.products,
589
633
  result.discountList
590
634
  );
591
- (_d = this.store.discount) == null ? void 0 : _d.setDiscountList(result.discountList);
635
+ (_c = this.store.discount) == null ? void 0 : _c.setDiscountList(result.discountList);
592
636
  }
593
637
  this.hasActiveCustomerBoundDiscount = (tempOrder.products || []).some(
594
638
  (product) => this.productHasCustomerBoundDiscount(product)
@@ -871,6 +915,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
871
915
  return sum.plus(this.calculatePaymentEffectiveAmount(payment));
872
916
  }, new import_decimal.default(0));
873
917
  }
918
+ calculateOrderPaidPaymentTotal(payments) {
919
+ return (0, import_utils.mapPaymentItemsToOrderPayments)(payments, {
920
+ includeVoided: false
921
+ }).reduce((sum, payment) => {
922
+ if (!isPaidPaymentRecord(payment))
923
+ return sum;
924
+ return sum.plus(this.calculatePaymentGapAmount(payment));
925
+ }, new import_decimal.default(0));
926
+ }
874
927
  getDepositAmount(tempOrder, summary) {
875
928
  return new import_decimal.default(summary.deposit_amount || tempOrder.deposit_amount || "0.00");
876
929
  }
@@ -961,7 +1014,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
961
1014
  const paymentList = payments || tempOrder.payments || [];
962
1015
  const refundAmount = this.getSummaryRefundAmount(summary);
963
1016
  const netPaidAmount = import_decimal.default.max(
964
- this.calculatePaymentTotal(paymentList).minus(refundAmount),
1017
+ this.calculateOrderPaidPaymentTotal(paymentList).minus(refundAmount),
965
1018
  0
966
1019
  );
967
1020
  const depositAmount = this.getDepositAmount(tempOrder, summary);
@@ -990,11 +1043,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
990
1043
  const isDepositPayment = paymentRecord.type === "deposit" || paymentRecord.order_payment_type === "deposit";
991
1044
  if (!isDepositPayment)
992
1045
  return sum;
993
- if (paymentRecord.origin_amount !== void 0 && paymentRecord.origin_amount !== null && paymentRecord.origin_amount !== "") {
994
- return sum.plus(this.calculatePaymentGapAmount(paymentRecord));
995
- }
996
- const rounding = new import_decimal.default(paymentRecord.rounding_amount || 0);
997
- return sum.plus(new import_decimal.default(paymentRecord.amount || 0).minus(rounding));
1046
+ return sum.plus(this.calculatePaymentGapAmount(paymentRecord));
998
1047
  }, new import_decimal.default(0));
999
1048
  }
1000
1049
  resolveNextOrderPaymentType(tempOrder) {
@@ -1006,17 +1055,40 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1006
1055
  const depositPaidAmount = this.calculateDepositPaidAmount(tempOrder.payments || []);
1007
1056
  return depositPaidAmount.lt(depositAmount) ? "deposit" : "normal";
1008
1057
  }
1058
+ getPaymentNumberAppData(key) {
1059
+ var _a, _b, _c, _d, _e;
1060
+ const appPlugin = this.appPlugin;
1061
+ if (!appPlugin)
1062
+ return void 0;
1063
+ const getData = (_a = appPlugin.getData) == null ? void 0 : _a.call(appPlugin);
1064
+ if (typeof getData === "function")
1065
+ return getData(key);
1066
+ const app = appPlugin.getApp();
1067
+ const coreData = (_e = (_c = (_b = app == null ? void 0 : app.models) == null ? void 0 : _b.getStore) == null ? void 0 : (_d = _c.call(_b)).getDataByModel) == null ? void 0 : _e.call(_d, "core", "core");
1068
+ return coreData == null ? void 0 : coreData[key];
1069
+ }
1070
+ getPaymentNumberDevicePrefixSync() {
1071
+ return (0, import_payment_number.resolvePaymentNumberDevicePrefixFromDeviceId)(
1072
+ (key) => this.getPaymentNumberAppData(key)
1073
+ );
1074
+ }
1075
+ getPaymentNumberDevicePrefixAsync() {
1076
+ return (0, import_payment_number.resolvePaymentNumberDevicePrefix)(
1077
+ (key) => this.getPaymentNumberAppData(key)
1078
+ );
1079
+ }
1009
1080
  normalizePaymentSource(payment, options) {
1010
1081
  const paymentRecord = payment;
1011
1082
  const metadata = paymentRecord.metadata && typeof paymentRecord.metadata === "object" ? { ...paymentRecord.metadata } : {};
1012
- if (!metadata.unique_payment_number) {
1013
- metadata.unique_payment_number = (0, import_utils.createUuidV4)();
1014
- }
1015
- const normalized = {
1016
- ...paymentRecord,
1017
- metadata,
1018
- origin_amount: paymentRecord.origin_amount ?? paymentRecord.amount ?? "0.00"
1019
- };
1083
+ const normalized = (0, import_payment_utils.ensureOrderPaymentNumber)(
1084
+ {
1085
+ ...paymentRecord,
1086
+ metadata,
1087
+ origin_amount: paymentRecord.origin_amount ?? paymentRecord.amount ?? "0.00"
1088
+ },
1089
+ (options == null ? void 0 : options.devicePrefix) || this.getPaymentNumberDevicePrefixSync(),
1090
+ import_utils.createUuidV4
1091
+ );
1020
1092
  if (paymentRecord.status !== void 0) {
1021
1093
  normalized.status = paymentRecord.status;
1022
1094
  } else if ((options == null ? void 0 : options.defaultPaid) !== false) {
@@ -1027,8 +1099,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1027
1099
  updateTempOrderPaymentStatus(tempOrder, options) {
1028
1100
  const summary = (options == null ? void 0 : options.summary) || this.store.summary || (0, import_utils.createEmptySummary)();
1029
1101
  const paymentTotal = this.calculatePaymentTotal(tempOrder.payments || []);
1102
+ const orderPaymentTotal = this.calculateOrderPaidPaymentTotal(tempOrder.payments || []);
1030
1103
  const refundAmount = this.getSummaryRefundAmount(summary);
1031
- const netPaymentTotal = import_decimal.default.max(paymentTotal.minus(refundAmount), 0);
1104
+ const netPaymentTotal = import_decimal.default.max(orderPaymentTotal.minus(refundAmount), 0);
1032
1105
  const targetAmount = this.calculatePaymentTargetAmount(
1033
1106
  tempOrder,
1034
1107
  summary,
@@ -1097,7 +1170,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1097
1170
  }
1098
1171
  capVoucherPaymentsByRemainingAmount(params) {
1099
1172
  const targetAmount = this.getPaymentTargetAmount();
1100
- const nonVoucherTotal = this.calculatePaymentTotal(params.nonVoucherPayments);
1173
+ const nonVoucherTotal = this.calculateOrderPaidPaymentTotal(params.nonVoucherPayments);
1101
1174
  if (targetAmount.lte(0))
1102
1175
  return [];
1103
1176
  let remainingAmount = import_decimal.default.max(
@@ -1140,7 +1213,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1140
1213
  return summary;
1141
1214
  return {
1142
1215
  customerPaidAmount: summary.customerPaidAmount.plus(paymentRecord.amount || 0),
1143
- orderPaidAmount: summary.orderPaidAmount.plus(paymentRecord.origin_amount || 0),
1216
+ orderPaidAmount: summary.orderPaidAmount.plus(this.calculatePaymentOrderAmount(paymentRecord)),
1144
1217
  gapPaidAmount: summary.gapPaidAmount.plus(this.calculatePaymentGapAmount(paymentRecord)),
1145
1218
  payServiceChargeAmount: summary.payServiceChargeAmount.plus(this.calculatePaymentServiceFee(paymentRecord)),
1146
1219
  roundingAmount: summary.roundingAmount.plus(this.calculatePaymentRoundingAmount(paymentRecord))
@@ -1165,11 +1238,30 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1165
1238
  return new import_decimal.default(payment.amount || 0).times(percentage).plus(fixedAmount);
1166
1239
  }
1167
1240
  calculatePaymentGapAmount(payment) {
1168
- if (payment.origin_amount === void 0 || payment.origin_amount === null || payment.origin_amount === "") {
1169
- return new import_decimal.default(0);
1241
+ if (payment.origin_amount !== void 0 && payment.origin_amount !== null && payment.origin_amount !== "") {
1242
+ const rounding2 = new import_decimal.default(payment.rounding_amount || 0);
1243
+ return new import_decimal.default(payment.origin_amount || 0).minus(rounding2);
1170
1244
  }
1171
1245
  const rounding = new import_decimal.default(payment.rounding_amount || 0);
1172
- return new import_decimal.default(payment.origin_amount || 0).minus(rounding);
1246
+ const amount = new import_decimal.default(payment.amount || 0);
1247
+ const serviceFee = this.calculatePaymentServiceFee(payment);
1248
+ if (serviceFee.lte(0))
1249
+ return amount.minus(rounding);
1250
+ if (!hasSyncedOrderPaymentRecord(payment))
1251
+ return new import_decimal.default(0);
1252
+ return import_decimal.default.max(amount.minus(serviceFee), 0).minus(rounding);
1253
+ }
1254
+ calculatePaymentOrderAmount(payment) {
1255
+ if (payment.origin_amount !== void 0 && payment.origin_amount !== null && payment.origin_amount !== "") {
1256
+ return new import_decimal.default(payment.origin_amount || 0);
1257
+ }
1258
+ const amount = new import_decimal.default(payment.amount || 0);
1259
+ const serviceFee = this.calculatePaymentServiceFee(payment);
1260
+ if (serviceFee.lte(0))
1261
+ return amount;
1262
+ if (!hasSyncedOrderPaymentRecord(payment))
1263
+ return new import_decimal.default(0);
1264
+ return import_decimal.default.max(amount.minus(serviceFee), 0);
1173
1265
  }
1174
1266
  calculatePaymentRoundingAmount(payment) {
1175
1267
  if (payment.rounding_amount === void 0 || payment.rounding_amount === null || payment.rounding_amount === "") {
@@ -1480,6 +1572,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1480
1572
  }
1481
1573
  restoreOriginalSnapshotIfProductsUnchanged(tempOrder, snapshot) {
1482
1574
  const currentFingerprint = this.buildOrderProductsFingerprint(tempOrder.products);
1575
+ const manualDepositOverride = this.getManualDepositOverride(tempOrder);
1483
1576
  if (currentFingerprint !== snapshot.productFingerprint) {
1484
1577
  const currentStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(tempOrder.products);
1485
1578
  const snapshotStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(
@@ -1488,11 +1581,24 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1488
1581
  if (currentStructuralFingerprint !== snapshotStructuralFingerprint)
1489
1582
  return null;
1490
1583
  }
1491
- const summary = {
1584
+ let summary = {
1492
1585
  ...(0, import_utils.createEmptySummary)(),
1493
1586
  ...(0, import_lodash_es.cloneDeep)(snapshot.summary || {})
1494
1587
  };
1495
- if (!this.isSnapshotPayableAmountUnchanged(tempOrder, snapshot, summary))
1588
+ const shouldUseManualDepositOverride = Boolean(
1589
+ manualDepositOverride && manualDepositOverride.productStructuralFingerprint === this.buildOrderProductsStructuralFingerprint(tempOrder.products)
1590
+ );
1591
+ if (shouldUseManualDepositOverride) {
1592
+ summary = this.applyDepositAmountToSummary(
1593
+ tempOrder,
1594
+ summary,
1595
+ manualDepositOverride.amount
1596
+ );
1597
+ } else if (manualDepositOverride) {
1598
+ this.clearManualDepositOverride(tempOrder);
1599
+ }
1600
+ const isPayableAmountUnchanged = this.isSnapshotPayableAmountUnchanged(tempOrder, snapshot, summary);
1601
+ if (!isPayableAmountUnchanged)
1496
1602
  return null;
1497
1603
  if (Array.isArray(snapshot.products)) {
1498
1604
  tempOrder.products = (0, import_lodash_es.cloneDeep)(snapshot.products);
@@ -1503,7 +1609,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1503
1609
  tempOrder.surcharge_fee = summary.surcharge_fee || tempOrder.surcharge_fee;
1504
1610
  tempOrder.deposit_amount = summary.deposit_amount || "0.00";
1505
1611
  tempOrder.is_deposit = summary.deposit_amount !== "0.00" ? 1 : 0;
1612
+ const previousSummary = this.store.summary;
1506
1613
  this.store.summary = summary;
1614
+ this.updateTempOrderPaymentStatus(tempOrder, {
1615
+ previousSummary,
1616
+ summary
1617
+ });
1507
1618
  return summary;
1508
1619
  }
1509
1620
  clearPersistedAmountFieldsForFullRecalc(products) {
@@ -2192,6 +2303,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2192
2303
  const type = (discount == null ? void 0 : discount.type) ?? (discount == null ? void 0 : discount.tag);
2193
2304
  return type === "good_pass" || type === "discount_card" || type === "product_discount_card";
2194
2305
  }
2306
+ shouldKeepCustomerBoundDiscountAfterCustomerChange(discount) {
2307
+ return Boolean((discount == null ? void 0 : discount.isScan) || (discount == null ? void 0 : discount.isEditMode));
2308
+ }
2195
2309
  productHasCustomerBoundDiscount(product) {
2196
2310
  if (((product == null ? void 0 : product.discount_list) || []).some((discount) => this.isCustomerBoundDiscount(discount))) {
2197
2311
  return true;
@@ -2247,12 +2361,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2247
2361
  const currentDiscounts = ((_a = discountModule.getDiscountList) == null ? void 0 : _a.call(discountModule)) || [];
2248
2362
  const currentOriginalDiscounts = ((_b = discountModule.getOriginalDiscountList) == null ? void 0 : _b.call(discountModule)) || [];
2249
2363
  const nextDiscounts = currentDiscounts.filter((discount) => {
2250
- if (discount == null ? void 0 : discount.isEditMode)
2364
+ if (this.shouldKeepCustomerBoundDiscountAfterCustomerChange(discount))
2251
2365
  return true;
2252
2366
  return !this.isCustomerBoundDiscount(discount);
2253
2367
  });
2254
2368
  const nextOriginalDiscounts = currentOriginalDiscounts.filter((discount) => {
2255
- if (discount == null ? void 0 : discount.isEditMode)
2369
+ if (this.shouldKeepCustomerBoundDiscountAfterCustomerChange(discount))
2256
2370
  return true;
2257
2371
  return !this.isCustomerBoundDiscount(discount);
2258
2372
  });
@@ -2323,6 +2437,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2323
2437
  }
2324
2438
  const nextCustomerId = tempOrder.customer_id ?? null;
2325
2439
  if (String(previousCustomerId ?? "") !== String(nextCustomerId ?? "")) {
2440
+ this.store.availableWalletIds = [];
2326
2441
  (0, import_utils.clearTempOrderHolderAssignments)(tempOrder);
2327
2442
  this.clearCustomerBoundDiscounts(tempOrder);
2328
2443
  this.applyDiscount();
@@ -2362,6 +2477,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2362
2477
  tempOrder.customer = null;
2363
2478
  if (tempOrder._extend)
2364
2479
  delete tempOrder._extend.customerSnapshot;
2480
+ this.store.availableWalletIds = [];
2365
2481
  this.clearCustomerBoundDiscounts(tempOrder);
2366
2482
  this.persistTempOrder();
2367
2483
  this.saveDraftInBackground();
@@ -2393,17 +2509,36 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2393
2509
  * 用一组支付来源覆盖当前订单支付项。
2394
2510
  *
2395
2511
  * 入参允许来自 PaymentModule 的 PaymentItem,内部统一映射为 Sales 协议:
2396
- * uuid -> metadata.unique_payment_number,id -> custom_payment_id,
2512
+ * 新支付来源的 uuid 会作为 payment_number 的唯一号段,id -> custom_payment_id,
2397
2513
  * isSynced 等运行态字段不会进入 tempOrder.payments。
2398
2514
  */
2399
2515
  setOrderPayments(payments) {
2400
2516
  const tempOrder = this.ensureTempOrder();
2401
- tempOrder.payments = (0, import_utils.mapPaymentItemsToOrderPayments)(payments);
2517
+ tempOrder.payments = (0, import_utils.mapPaymentItemsToOrderPayments)(
2518
+ (payments || []).map((payment) => this.normalizePaymentSource(payment, { defaultPaid: false }))
2519
+ );
2402
2520
  this.persistTempOrder();
2403
2521
  return tempOrder.payments;
2404
2522
  }
2405
- /** 追加单个支付项,并立即持久化当前 tempOrder。 */
2523
+ /** 同步兼容入口:按调用当下的 device_id 或 LOCAL 生成支付编号。 */
2406
2524
  addOrderPayment(payment) {
2525
+ const hasPaymentNumber = String(
2526
+ payment.payment_number || ""
2527
+ ).trim() !== "";
2528
+ return this.addOrderPaymentWithDevicePrefix(
2529
+ payment,
2530
+ hasPaymentNumber ? "LOCAL" : this.getPaymentNumberDevicePrefixSync()
2531
+ );
2532
+ }
2533
+ /** 异步入口:创建支付项时读取最新 IoT 设备短号。 */
2534
+ async addOrderPaymentAsync(payment) {
2535
+ const hasPaymentNumber = String(
2536
+ payment.payment_number || ""
2537
+ ).trim() !== "";
2538
+ const devicePrefix = hasPaymentNumber ? "LOCAL" : await this.getPaymentNumberDevicePrefixAsync();
2539
+ return this.addOrderPaymentWithDevicePrefix(payment, devicePrefix);
2540
+ }
2541
+ addOrderPaymentWithDevicePrefix(payment, devicePrefix) {
2407
2542
  this.logInfo("addOrderPayment", {
2408
2543
  payment
2409
2544
  });
@@ -2416,7 +2551,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2416
2551
  type: orderPaymentType,
2417
2552
  order_payment_type: orderPaymentType
2418
2553
  },
2419
- { defaultPaid: true }
2554
+ { defaultPaid: true, devicePrefix }
2420
2555
  )
2421
2556
  ]);
2422
2557
  tempOrder.payments = [...tempOrder.payments || [], ...mapped];
@@ -2429,57 +2564,55 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2429
2564
  return tempOrder.payments;
2430
2565
  }
2431
2566
  /**
2432
- * 按支付唯一号、后端支付 ID、自定义支付方式 ID 或旧 uuid 更新支付项。
2433
- *
2434
- * 该方法服务 PaymentModal 的 void / 编辑场景;更新 metadata 时会做浅合并,
2435
- * 避免覆盖 unique_payment_number、现金实付/找零等已有元数据。
2567
+ * 默认按支付唯一号精确更新;仅显式指定 legacy 时兼容历史支付标识。
2568
+ * metadata 与 transactions 会分别合并,避免覆盖支付会话号和已有交易记录。
2436
2569
  */
2437
- updateOrderPayment(paymentIdentity, updates) {
2570
+ async updateOrderPayment(paymentIdentity, updates, options = {}) {
2438
2571
  const tempOrder = this.ensureTempOrder();
2439
2572
  const identity = String(paymentIdentity);
2440
- tempOrder.payments = (tempOrder.payments || []).map((payment) => {
2441
- var _a;
2442
- const uniquePaymentNumber = (_a = payment == null ? void 0 : payment.metadata) == null ? void 0 : _a.unique_payment_number;
2443
- const orderPaymentId = payment == null ? void 0 : payment.order_payment_id;
2444
- const customPaymentId = payment == null ? void 0 : payment.custom_payment_id;
2445
- const uuid = payment == null ? void 0 : payment.uuid;
2446
- const matched = [
2447
- uniquePaymentNumber,
2448
- orderPaymentId,
2449
- customPaymentId,
2450
- uuid
2451
- ].some((value) => value !== void 0 && String(value) === identity);
2452
- if (!matched)
2573
+ const matchMode = options.matchBy === "compat" || options.matchBy === "legacy" ? "compat" : "payment_number";
2574
+ const matchedPayment = (0, import_payment_utils.resolveOrderPaymentIdentity)(
2575
+ tempOrder.payments || [],
2576
+ identity,
2577
+ matchMode
2578
+ );
2579
+ if (!matchedPayment) {
2580
+ throw new Error(`未找到支付项: ${identity}`);
2581
+ }
2582
+ let updatedPayment = null;
2583
+ tempOrder.payments = (tempOrder.payments || []).map((payment, index) => {
2584
+ if (index !== matchedPayment.index)
2453
2585
  return payment;
2454
- return {
2455
- ...payment,
2586
+ const nextPayment = (0, import_payment_utils.mergeOrderPaymentRecord)(payment, {
2456
2587
  ...updates,
2457
- metadata: {
2458
- ...payment.metadata || {},
2459
- ...updates.metadata || {}
2460
- }
2461
- };
2588
+ updated_at: updates.updated_at || (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
2589
+ });
2590
+ updatedPayment = nextPayment;
2591
+ return nextPayment;
2462
2592
  });
2463
2593
  this.persistTempOrder();
2464
- return tempOrder.payments;
2594
+ const summary = await this.recalculateSummary({ createIfMissing: true });
2595
+ this.persistTempOrder();
2596
+ const payments = tempOrder.payments;
2597
+ return {
2598
+ updated: true,
2599
+ payment: payments[matchedPayment.index] || updatedPayment,
2600
+ payments,
2601
+ summary
2602
+ };
2465
2603
  }
2466
2604
  /** 从当前订单支付项中移除指定支付项。 */
2467
2605
  deleteOrderPayment(paymentIdentity) {
2468
2606
  const tempOrder = this.ensureTempOrder();
2469
2607
  const identity = String(paymentIdentity);
2470
- tempOrder.payments = (tempOrder.payments || []).filter((payment) => {
2471
- var _a;
2472
- const uniquePaymentNumber = (_a = payment == null ? void 0 : payment.metadata) == null ? void 0 : _a.unique_payment_number;
2473
- const orderPaymentId = payment == null ? void 0 : payment.order_payment_id;
2474
- const customPaymentId = payment == null ? void 0 : payment.custom_payment_id;
2475
- const uuid = payment == null ? void 0 : payment.uuid;
2476
- return ![
2477
- uniquePaymentNumber,
2478
- orderPaymentId,
2479
- customPaymentId,
2480
- uuid
2481
- ].some((value) => value !== void 0 && String(value) === identity);
2482
- });
2608
+ const matchedPayment = (0, import_payment_utils.resolveOrderPaymentIdentity)(
2609
+ tempOrder.payments || [],
2610
+ identity,
2611
+ "compat"
2612
+ );
2613
+ if (!matchedPayment)
2614
+ return tempOrder.payments;
2615
+ tempOrder.payments = (tempOrder.payments || []).filter((_, index) => index !== matchedPayment.index);
2483
2616
  this.persistTempOrder();
2484
2617
  return tempOrder.payments;
2485
2618
  }
@@ -2588,7 +2721,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2588
2721
  payments.map(
2589
2722
  (payment) => this.normalizePaymentSource(
2590
2723
  normalizeVoucherPaymentStatus(withVoucherPaymentType(payment)),
2591
- { defaultPaid: false }
2724
+ {
2725
+ defaultPaid: false,
2726
+ devicePrefix: options == null ? void 0 : options.devicePrefix
2727
+ }
2592
2728
  )
2593
2729
  )
2594
2730
  ).filter((payment) => {
@@ -2639,6 +2775,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2639
2775
  });
2640
2776
  return tempOrder.payments;
2641
2777
  }
2778
+ async updateVoucherOrderPaymentsAsync(payments, options) {
2779
+ const needsPaymentNumber = (payments || []).some((payment) => String(payment.payment_number || "").trim() === "");
2780
+ const devicePrefix = needsPaymentNumber ? await this.getPaymentNumberDevicePrefixAsync() : "LOCAL";
2781
+ return this.updateVoucherOrderPayments(payments, {
2782
+ ...options,
2783
+ devicePrefix
2784
+ });
2785
+ }
2642
2786
  async shouldMergeProductToOrder(params) {
2643
2787
  var _a;
2644
2788
  const onBeforeMergeProductToOrder = (_a = this.orderHooks) == null ? void 0 : _a.onBeforeMergeProductToOrder;
@@ -2728,12 +2872,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2728
2872
  const hasIncomingBookingUid = this.hasLinkedBookingUid(productToAdd) || this.hasLinkedBookingUid(normalizedIncoming);
2729
2873
  const shouldForceNewLine = !!booking || hasIncomingProductNote || hasIncomingBookingUid;
2730
2874
  const matchedIndex = hasIncomingGoodPass || shouldForceNewLine ? -1 : tempOrder.products.findIndex((item) => {
2875
+ var _a2;
2731
2876
  if (this.hasGoodPassDiscount(item))
2732
2877
  return false;
2733
2878
  if (this.hasOrderProductLineNote(item))
2734
2879
  return false;
2735
2880
  if (item.order_detail_id !== void 0 && item.order_detail_id !== null)
2736
2881
  return false;
2882
+ if ((_a2 = item.metadata) == null ? void 0 : _a2.is_edit_for_runtime)
2883
+ return false;
2737
2884
  if (item.product_id !== productToAdd.product_id)
2738
2885
  return false;
2739
2886
  if (item.product_variant_id !== productToAdd.product_variant_id)
@@ -2964,6 +3111,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2964
3111
  return bundle;
2965
3112
  return {
2966
3113
  ...bundle,
3114
+ ...(bundle.cover === void 0 || bundle.cover === null || bundle.cover === "") && previous.cover !== void 0 && previous.cover !== null && previous.cover !== "" ? { cover: previous.cover } : {},
2967
3115
  price: previous.price,
2968
3116
  custom_price: previous.custom_price,
2969
3117
  bundle_payment_price: previous.bundle_payment_price,
@@ -2974,7 +3122,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2974
3122
  });
2975
3123
  }
2976
3124
  applyOrderProductUpdateToTempOrder(tempOrder, params) {
2977
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
3125
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
2978
3126
  const {
2979
3127
  product_id,
2980
3128
  product_variant_id,
@@ -3038,9 +3186,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3038
3186
  nextProduct.num = (0, import_utils3.getSafeProductNum)(nextProduct.num);
3039
3187
  const callerUpdatesTopPrice = Object.prototype.hasOwnProperty.call(updates || {}, "selling_price") || Object.prototype.hasOwnProperty.call(updates || {}, "original_price");
3040
3188
  const callerUpdatesMainMeta = ((_c = updates == null ? void 0 : updates.metadata) == null ? void 0 : _c.main_product_selling_price) !== void 0 || ((_d = updates == null ? void 0 : updates.metadata) == null ? void 0 : _d.main_product_original_price) !== void 0 || ((_e = updates == null ? void 0 : updates.metadata) == null ? void 0 : _e.source_product_price) !== void 0;
3189
+ const callerUpdatesSourcePrice = ((_f = updates == null ? void 0 : updates.metadata) == null ? void 0 : _f.source_product_price) !== void 0;
3190
+ const callerUpdatesMainSellingPrice = ((_g = updates == null ? void 0 : updates.metadata) == null ? void 0 : _g.main_product_selling_price) !== void 0;
3191
+ const callerUpdatesMainOriginalPrice = ((_h = updates == null ? void 0 : updates.metadata) == null ? void 0 : _h.main_product_original_price) !== void 0;
3192
+ const previousLineFingerprint = (0, import_utils3.buildProductLineFingerprint)(
3193
+ (0, import_utils.getProductSkuOptions)(targetProduct),
3194
+ targetProduct.product_bundle
3195
+ );
3196
+ const nextLineFingerprint = (0, import_utils3.buildProductLineFingerprint)(
3197
+ (0, import_utils.getProductSkuOptions)(nextProduct),
3198
+ nextProduct.product_bundle
3199
+ );
3200
+ const callerChangesVariant = Number(product_variant_id || 0) !== Number(targetProduct.product_variant_id || 0);
3201
+ const callerChangesLineConfiguration = callerChangesVariant || previousLineFingerprint !== nextLineFingerprint;
3041
3202
  const isPersistedOrderLine = targetProduct.order_detail_id !== void 0 && targetProduct.order_detail_id !== null;
3042
3203
  const callerChangesDiscountList = Array.isArray(updates == null ? void 0 : updates.discount_list) && updates.discount_list.length > 0 && !isSameDiscountList(updates.discount_list, targetProduct.discount_list);
3043
- const callerUpdatesManualPrice = ((_f = updates == null ? void 0 : updates.metadata) == null ? void 0 : _f.price_override) !== void 0 || ((_g = updates == null ? void 0 : updates.metadata) == null ? void 0 : _g.is_manual_discount) !== void 0 || ((_h = updates == null ? void 0 : updates.metadata) == null ? void 0 : _h.product_discount_reason) !== void 0 || callerChangesDiscountList;
3204
+ const callerUpdatesManualPrice = ((_i = updates == null ? void 0 : updates.metadata) == null ? void 0 : _i.price_override) !== void 0 || ((_j = updates == null ? void 0 : updates.metadata) == null ? void 0 : _j.is_manual_discount) !== void 0 || ((_k = updates == null ? void 0 : updates.metadata) == null ? void 0 : _k.product_discount_reason) !== void 0 || callerChangesDiscountList;
3044
3205
  const callerAllowsBookingReprice = (() => {
3045
3206
  if (params.allow_booking_reprice !== true || !booking || !callerUpdatesTopPrice || !callerUpdatesMainMeta) {
3046
3207
  return false;
@@ -3055,21 +3216,69 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3055
3216
  };
3056
3217
  return hasChangedPrice(updates.selling_price, targetProduct.selling_price) || hasChangedPrice(updates.original_price, targetProduct.original_price);
3057
3218
  })();
3058
- if (isPersistedOrderLine && !callerUpdatesManualPrice && !callerAllowsBookingReprice) {
3219
+ if (isPersistedOrderLine && !callerChangesLineConfiguration && !callerUpdatesManualPrice && !callerAllowsBookingReprice) {
3059
3220
  nextProduct.selling_price = targetProduct.selling_price;
3060
3221
  nextProduct.original_price = targetProduct.original_price;
3061
3222
  nextProduct.payment_price = targetProduct.payment_price;
3062
3223
  nextProduct.metadata = {
3063
3224
  ...nextProduct.metadata || {},
3064
- source_product_price: (_i = targetProduct.metadata) == null ? void 0 : _i.source_product_price,
3065
- main_product_selling_price: (_j = targetProduct.metadata) == null ? void 0 : _j.main_product_selling_price,
3066
- main_product_original_price: (_k = targetProduct.metadata) == null ? void 0 : _k.main_product_original_price,
3067
- price_schema_version: ((_l = targetProduct.metadata) == null ? void 0 : _l.price_schema_version) ?? 2
3225
+ source_product_price: (_l = targetProduct.metadata) == null ? void 0 : _l.source_product_price,
3226
+ main_product_selling_price: (_m = targetProduct.metadata) == null ? void 0 : _m.main_product_selling_price,
3227
+ main_product_original_price: (_n = targetProduct.metadata) == null ? void 0 : _n.main_product_original_price,
3228
+ price_schema_version: ((_o = targetProduct.metadata) == null ? void 0 : _o.price_schema_version) ?? 2
3068
3229
  };
3069
3230
  nextProduct.product_bundle = this.preservePersistedBundlePriceFields(
3070
3231
  targetProduct.product_bundle,
3071
3232
  nextProduct.product_bundle
3072
3233
  );
3234
+ } else if (callerChangesLineConfiguration && callerUpdatesSourcePrice && (!callerUpdatesMainSellingPrice || !callerUpdatesMainOriginalPrice)) {
3235
+ const previousMainOriginal = new import_decimal.default(
3236
+ Number((_p = targetProduct.metadata) == null ? void 0 : _p.main_product_original_price) || 0
3237
+ );
3238
+ const previousMainSelling = new import_decimal.default(
3239
+ Number((_q = targetProduct.metadata) == null ? void 0 : _q.main_product_selling_price) || previousMainOriginal.toNumber()
3240
+ );
3241
+ const preservedDiscount = previousMainOriginal.minus(previousMainSelling);
3242
+ const nextMainOriginal = new import_decimal.default(
3243
+ Number(updates.metadata.source_product_price) || 0
3244
+ ).plus((0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(nextProduct)));
3245
+ nextProduct.metadata = {
3246
+ ...nextProduct.metadata || {},
3247
+ source_product_price: String(updates.metadata.source_product_price),
3248
+ main_product_original_price: callerUpdatesMainOriginalPrice ? String(updates.metadata.main_product_original_price) : nextMainOriginal.toDecimalPlaces(2).toFixed(2),
3249
+ main_product_selling_price: callerUpdatesMainSellingPrice ? String(updates.metadata.main_product_selling_price) : nextMainOriginal.minus(preservedDiscount).toDecimalPlaces(2).toFixed(2),
3250
+ price_schema_version: 2
3251
+ };
3252
+ } else if (callerChangesVariant && !callerUpdatesTopPrice && !callerUpdatesMainMeta) {
3253
+ const existedMeta = nextProduct.metadata || {};
3254
+ nextProduct.metadata = { ...existedMeta };
3255
+ delete nextProduct.metadata.source_product_price;
3256
+ delete nextProduct.metadata.main_product_selling_price;
3257
+ delete nextProduct.metadata.main_product_original_price;
3258
+ delete nextProduct.metadata.price_schema_version;
3259
+ } else if (callerChangesLineConfiguration && !callerUpdatesTopPrice && !callerUpdatesMainMeta) {
3260
+ const previousOptionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(targetProduct));
3261
+ const nextOptionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(nextProduct));
3262
+ const previousMainOriginal = new import_decimal.default(
3263
+ Number(
3264
+ ((_r = targetProduct.metadata) == null ? void 0 : _r.main_product_original_price) ?? targetProduct.original_price ?? 0
3265
+ ) || 0
3266
+ );
3267
+ const previousMainSelling = new import_decimal.default(
3268
+ Number(
3269
+ ((_s = targetProduct.metadata) == null ? void 0 : _s.main_product_selling_price) ?? targetProduct.selling_price ?? previousMainOriginal.toNumber()
3270
+ ) || 0
3271
+ );
3272
+ const preservedDiscount = previousMainOriginal.minus(previousMainSelling);
3273
+ const previousSource = ((_t = targetProduct.metadata) == null ? void 0 : _t.source_product_price) != null ? new import_decimal.default(Number(targetProduct.metadata.source_product_price) || 0) : previousMainOriginal.minus(previousOptionSum);
3274
+ const nextMainOriginal = previousSource.plus(nextOptionSum);
3275
+ nextProduct.metadata = {
3276
+ ...nextProduct.metadata || {},
3277
+ source_product_price: previousSource.toDecimalPlaces(2).toFixed(2),
3278
+ main_product_original_price: nextMainOriginal.toDecimalPlaces(2).toFixed(2),
3279
+ main_product_selling_price: nextMainOriginal.minus(preservedDiscount).toDecimalPlaces(2).toFixed(2),
3280
+ price_schema_version: 2
3281
+ };
3073
3282
  } else if (callerUpdatesTopPrice && !callerUpdatesMainMeta) {
3074
3283
  const existedMeta = nextProduct.metadata || {};
3075
3284
  nextProduct.metadata = { ...existedMeta };
@@ -3085,7 +3294,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3085
3294
  normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
3086
3295
  normalizedProduct.discount_list
3087
3296
  );
3088
- const preservedBookingUid = nextProduct.booking_uid || ((_m = nextProduct.metadata) == null ? void 0 : _m.booking_uid) || targetProduct.booking_uid || ((_n = targetProduct.metadata) == null ? void 0 : _n.booking_uid);
3297
+ const preservedBookingUid = nextProduct.booking_uid || ((_u = nextProduct.metadata) == null ? void 0 : _u.booking_uid) || targetProduct.booking_uid || ((_v = targetProduct.metadata) == null ? void 0 : _v.booking_uid);
3089
3298
  if (!booking && preservedBookingUid) {
3090
3299
  normalizedProduct.booking_uid = preservedBookingUid;
3091
3300
  normalizedProduct.metadata = {
@@ -3095,7 +3304,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3095
3304
  }
3096
3305
  if (booking) {
3097
3306
  const productUid = String(
3098
- ((_o = normalizedProduct.metadata) == null ? void 0 : _o.unique_identification_number) || ((_p = targetProduct.metadata) == null ? void 0 : _p.unique_identification_number) || unique_identification_number || (0, import_utils.createUuidV4)()
3307
+ ((_w = normalizedProduct.metadata) == null ? void 0 : _w.unique_identification_number) || ((_x = targetProduct.metadata) == null ? void 0 : _x.unique_identification_number) || unique_identification_number || (0, import_utils.createUuidV4)()
3099
3308
  );
3100
3309
  normalizedProduct.metadata = {
3101
3310
  ...normalizedProduct.metadata || {},
@@ -3126,14 +3335,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3126
3335
  tempOrder,
3127
3336
  updates,
3128
3337
  tempOrder.products[productIndex],
3129
- (_q = tempOrder.products[productIndex].metadata) == null ? void 0 : _q.unique_identification_number
3338
+ (_y = tempOrder.products[productIndex].metadata) == null ? void 0 : _y.unique_identification_number
3130
3339
  );
3340
+ return (_z = tempOrder.products[productIndex].metadata) == null ? void 0 : _z.unique_identification_number;
3131
3341
  }
3132
3342
  async updateOrderProduct(params) {
3133
3343
  const tempOrder = this.ensureTempOrder();
3134
- this.applyOrderProductUpdateToTempOrder(tempOrder, params);
3344
+ const updatedProductUid = this.applyOrderProductUpdateToTempOrder(tempOrder, params);
3135
3345
  await this.applyPromotion();
3136
- this.applyDiscount();
3346
+ this.applyDiscount({
3347
+ reapplyBookingDiscountProductUids: params.allow_booking_discount_reapply && updatedProductUid ? [String(updatedProductUid)] : void 0
3348
+ });
3137
3349
  this.sanitizeTempOrderProducts(tempOrder);
3138
3350
  await this.recalculateSummary({ createIfMissing: true });
3139
3351
  this.persistTempOrder();
@@ -3147,10 +3359,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3147
3359
  if (!paramsList.length) {
3148
3360
  return tempOrder.products;
3149
3361
  }
3150
- paramsList.forEach((params) => {
3151
- this.applyOrderProductUpdateToTempOrder(tempOrder, params);
3362
+ const reapplyBookingDiscountProductUids = paramsList.reduce((acc, params) => {
3363
+ const updatedProductUid = this.applyOrderProductUpdateToTempOrder(tempOrder, params);
3364
+ if (params.allow_booking_discount_reapply && updatedProductUid) {
3365
+ acc.push(String(updatedProductUid));
3366
+ }
3367
+ return acc;
3368
+ }, []);
3369
+ await this.finalizeAfterProductsMutation(tempOrder, {
3370
+ reapplyBookingDiscountProductUids: reapplyBookingDiscountProductUids.length ? reapplyBookingDiscountProductUids : void 0
3152
3371
  });
3153
- await this.finalizeAfterProductsMutation(tempOrder);
3154
3372
  this.logInfo("updateOrderProduct success", {
3155
3373
  paramsList
3156
3374
  });
@@ -3259,10 +3477,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3259
3477
  * @example
3260
3478
  * await this.finalizeAfterProductsMutation(tempOrder);
3261
3479
  */
3262
- async finalizeAfterProductsMutation(tempOrder) {
3480
+ async finalizeAfterProductsMutation(tempOrder, options) {
3263
3481
  this.syncTempOrderHolderFromBookings(tempOrder);
3264
3482
  await this.applyPromotion();
3265
- this.applyDiscount();
3483
+ this.applyDiscount({
3484
+ reapplyBookingDiscountProductUids: options == null ? void 0 : options.reapplyBookingDiscountProductUids
3485
+ });
3266
3486
  this.sanitizeTempOrderProducts(tempOrder);
3267
3487
  await this.recalculateSummary({ createIfMissing: true });
3268
3488
  this.persistTempOrder();
@@ -3393,6 +3613,38 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3393
3613
  await this.saveDraft();
3394
3614
  return tempOrder;
3395
3615
  }
3616
+ async saveTempOrderAsDraft(params) {
3617
+ var _a, _b, _c, _d, _e;
3618
+ const tempOrder = this.ensureTempOrder();
3619
+ this.ensureExternalSaleNumber(tempOrder);
3620
+ this.persistTempOrder();
3621
+ const latestSummary = await this.recalculateSummary({ createIfMissing: true }) || this.store.summary || (0, import_utils.createEmptySummary)();
3622
+ const payload = (0, import_utils.buildSubmitPayload)({
3623
+ tempOrder,
3624
+ cacheId: (params == null ? void 0 : params.cacheId) ?? this.cacheId,
3625
+ platform: (params == null ? void 0 : params.platform) || ((_a = this.otherParams) == null ? void 0 : _a.platform),
3626
+ businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
3627
+ channel: params == null ? void 0 : params.channel,
3628
+ type: (params == null ? void 0 : params.type) ?? ((_d = this.otherParams) == null ? void 0 : _d.type),
3629
+ summary: latestSummary,
3630
+ enhance: params == null ? void 0 : params.enhancePayload
3631
+ });
3632
+ if (!payload.created_at) {
3633
+ payload.created_at = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
3634
+ }
3635
+ payload.need_sync = 0;
3636
+ payload.is_draft_order = 1;
3637
+ this.logInfo("saveTempOrderAsDraft calling sales draft", {
3638
+ orderId: payload.order_id,
3639
+ externalSaleNumber: payload.external_sale_number,
3640
+ productsCount: ((_e = payload.products) == null ? void 0 : _e.length) || 0
3641
+ });
3642
+ return this.request.post("/order/sales/draft", payload, {
3643
+ osServer: true,
3644
+ customToast: () => {
3645
+ }
3646
+ });
3647
+ }
3396
3648
  /**
3397
3649
  * 提交当前 Sales tempOrder。
3398
3650
  *
@@ -3593,14 +3845,19 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3593
3845
  }
3594
3846
  async syncPaymentsToOrder(params) {
3595
3847
  const tempOrder = this.ensureTempOrder();
3848
+ const needsPaymentNumber = (params.payments || []).some((payment) => String(payment.payment_number || "").trim() === "");
3849
+ const devicePrefix = needsPaymentNumber ? await this.getPaymentNumberDevicePrefixAsync() : "LOCAL";
3596
3850
  const mappedPayments = (0, import_utils.mapPaymentItemsToOrderPayments)(
3597
- params.payments || []
3851
+ (params.payments || []).map((payment) => this.normalizePaymentSource(payment, {
3852
+ defaultPaid: false,
3853
+ devicePrefix
3854
+ }))
3598
3855
  );
3599
3856
  const shouldConfirmPendingVoucherPayments = params.confirmPendingVoucherPayments ?? params.submitWhenPaid === true;
3600
3857
  const effectivePayments = shouldConfirmPendingVoucherPayments ? this.confirmPendingVoucherPaymentsInList(mappedPayments) : params.confirmPendingVoucherPayments === false ? this.discardPendingVoucherPaymentsFromList(mappedPayments) : mappedPayments;
3601
3858
  const completion = this.getPaymentCompletion(effectivePayments);
3602
- const paidPaymentTotal = this.calculatePaymentTotal(effectivePayments);
3603
- const paymentStatus = completion.isOrderFullyPaid ? params.paymentStatus || "paid" : paidPaymentTotal.gt(0) ? "partially_paid" : "payment_processing";
3859
+ const orderPaidPaymentTotal = this.calculateOrderPaidPaymentTotal(effectivePayments);
3860
+ const paymentStatus = completion.isOrderFullyPaid ? params.paymentStatus || "paid" : orderPaidPaymentTotal.gt(0) ? "partially_paid" : "payment_processing";
3604
3861
  tempOrder.payments = effectivePayments;
3605
3862
  tempOrder.payment_status = paymentStatus;
3606
3863
  this.persistTempOrder();
@@ -3940,8 +4197,42 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3940
4197
  */
3941
4198
  async hydrateTempOrderFromRecord(record, options) {
3942
4199
  var _a, _b, _c;
3943
- const raw = record && typeof record === "object" && record.data && record.order_id == null ? record.data : record || {};
3944
- const nextTempOrder = this.normalizeTempOrderForRuntime(raw);
4200
+ const sourceRaw = record && typeof record === "object" && record.data && record.order_id == null ? record.data : record || {};
4201
+ const identityReadySource = this.seedAnonymousBookingUidsFromProducts(
4202
+ sourceRaw
4203
+ );
4204
+ const normalizedCollections = (0, import_orderCollectionIdentity.normalizeOrderCollections)(identityReadySource);
4205
+ const raw = normalizedCollections.order;
4206
+ const hasIdentityChanges = Object.values(normalizedCollections.stats).some(
4207
+ (stats) => stats.backfilledUidCount > 0 || stats.collapsedDuplicateCount > 0 || stats.uidConflictCount > 0 || stats.anonymousRowCount > 0
4208
+ );
4209
+ if (hasIdentityChanges) {
4210
+ const identityLogMetadata = {
4211
+ collections: normalizedCollections.stats,
4212
+ uidRemapCount: normalizedCollections.uidRemaps.length
4213
+ };
4214
+ const hasIdentityWarnings = Object.values(normalizedCollections.stats).some(
4215
+ (stats) => stats.uidConflictCount > 0 || stats.anonymousRowCount > 0
4216
+ );
4217
+ if (hasIdentityWarnings) {
4218
+ this.logWarning(
4219
+ "Normalized hydrated order collection identities",
4220
+ identityLogMetadata
4221
+ );
4222
+ } else {
4223
+ this.logInfo(
4224
+ "Normalized hydrated order collection identities",
4225
+ identityLogMetadata
4226
+ );
4227
+ }
4228
+ }
4229
+ const nextTempOrder = this.normalizeTempOrderForRuntime(raw, { makeEditMark: true });
4230
+ const sourceLastOrderInfo = raw.lastOrderInfo || raw;
4231
+ const isDraftOrder = Number(nextTempOrder.is_draft_order || 0) === 1;
4232
+ const syntheticIdentityOptions = {
4233
+ isDraftOrder,
4234
+ externalSaleNumber: nextTempOrder.external_sale_number
4235
+ };
3945
4236
  const rawSummary = raw.summary && typeof raw.summary === "object" ? raw.summary : {};
3946
4237
  const summarySurcharges = Array.isArray(rawSummary.surcharges) ? rawSummary.surcharges.map((s) => ({ ...s || {} })) : (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []);
3947
4238
  this.store.tempOrder = nextTempOrder;
@@ -3955,23 +4246,42 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3955
4246
  originalSalesSnapshot: {
3956
4247
  summary: (0, import_lodash_es.cloneDeep)(this.store.summary),
3957
4248
  products: (0, import_lodash_es.cloneDeep)(nextTempOrder.products || []),
4249
+ bookings: (0, import_lodash_es.cloneDeep)(nextTempOrder.bookings || []),
3958
4250
  payments: (0, import_lodash_es.cloneDeep)(nextTempOrder.payments || []),
3959
4251
  surcharges: (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []),
3960
4252
  shop_discount: nextTempOrder.shop_discount || "0.00",
3961
4253
  productFingerprint: this.buildOrderProductsFingerprint(nextTempOrder.products || [])
3962
4254
  }
3963
4255
  };
3964
- this.store.lastOrderInfo = raw.lastOrderInfo || raw;
4256
+ this.store.lastOrderInfo = this.withoutSyntheticDraftOrderIdForRuntime(
4257
+ sourceLastOrderInfo,
4258
+ syntheticIdentityOptions
4259
+ );
4260
+ const hadSyntheticDraftOrderId = this.isSyntheticDraftOrderIdForRuntime(raw, syntheticIdentityOptions) || this.isSyntheticDraftOrderIdForRuntime(sourceLastOrderInfo, syntheticIdentityOptions);
4261
+ if (hadSyntheticDraftOrderId && this.store.syncState !== "submitting") {
4262
+ this.store.syncState = "local";
4263
+ }
3965
4264
  const hydratedEditDiscounts = this.collectHydratedEditDiscounts(nextTempOrder.products);
3966
4265
  const currentDiscounts = typeof ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList) === "function" ? this.store.discount.getDiscountList() || [] : [];
3967
- const shouldSkipEmptyDiscountSync = hydratedEditDiscounts.length === 0 && currentDiscounts.length === 0;
4266
+ const currentScanDiscounts = currentDiscounts.filter((discount) => discount == null ? void 0 : discount.isScan);
4267
+ const hydratedDiscountIds = new Set(
4268
+ hydratedEditDiscounts.map((discount) => discount == null ? void 0 : discount.id)
4269
+ );
4270
+ const retainedScanDiscounts = currentScanDiscounts.filter(
4271
+ (discount) => !hydratedDiscountIds.has(discount == null ? void 0 : discount.id)
4272
+ );
4273
+ const nextDiscounts = [
4274
+ ...hydratedEditDiscounts,
4275
+ ...retainedScanDiscounts
4276
+ ];
4277
+ const shouldSkipEmptyDiscountSync = nextDiscounts.length === 0 && currentDiscounts.length === 0;
3968
4278
  if (!shouldSkipEmptyDiscountSync) {
3969
4279
  OrderModule.populateSavedAmounts(
3970
4280
  nextTempOrder.products,
3971
- hydratedEditDiscounts
4281
+ nextDiscounts
3972
4282
  );
3973
- await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(hydratedEditDiscounts));
3974
- await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(hydratedEditDiscounts));
4283
+ await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(nextDiscounts));
4284
+ await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(nextDiscounts));
3975
4285
  }
3976
4286
  if (options == null ? void 0 : options.recalcOnHydrate) {
3977
4287
  await this.recalculateSummary({ createIfMissing: false });
@@ -4003,14 +4313,73 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4003
4313
  }
4004
4314
  return next;
4005
4315
  }
4316
+ /**
4317
+ * 匿名 booking 没有服务端行 ID 时,商品侧已有的 booking_uid 就是唯一可用的强引用。
4318
+ * 在统一规范化生成 UUID 前先复用它;已落库 booking 仍按 schedule_event_id 派生稳定 UID。
4319
+ */
4320
+ seedAnonymousBookingUidsFromProducts(raw) {
4321
+ var _a, _b;
4322
+ if (!raw || typeof raw !== "object")
4323
+ return {};
4324
+ if (!Array.isArray(raw.bookings) || !Array.isArray(raw.products))
4325
+ return raw;
4326
+ const bookingUidsByProductUid = /* @__PURE__ */ new Map();
4327
+ for (const product of raw.products) {
4328
+ const productUid = (0, import_orderCollectionIdentity.getOrderCollectionUid)("product", product);
4329
+ const bookingUid = (product == null ? void 0 : product.booking_uid) || ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.booking_uid);
4330
+ if (!productUid || bookingUid === void 0 || bookingUid === null || bookingUid === "") {
4331
+ continue;
4332
+ }
4333
+ const candidates = bookingUidsByProductUid.get(productUid) || /* @__PURE__ */ new Set();
4334
+ candidates.add(String(bookingUid));
4335
+ bookingUidsByProductUid.set(productUid, candidates);
4336
+ }
4337
+ if (bookingUidsByProductUid.size === 0)
4338
+ return raw;
4339
+ const anonymousBookingCountByProductUid = /* @__PURE__ */ new Map();
4340
+ for (const booking of raw.bookings) {
4341
+ if ((0, import_orderCollectionIdentity.getOrderCollectionPersistentId)("booking", booking) || (0, import_orderCollectionIdentity.getOrderCollectionUid)("booking", booking)) {
4342
+ continue;
4343
+ }
4344
+ const productUid = (booking == null ? void 0 : booking.product_uid) || ((_b = booking == null ? void 0 : booking.metadata) == null ? void 0 : _b.product_uid);
4345
+ if (productUid === void 0 || productUid === null || productUid === "")
4346
+ continue;
4347
+ const key = String(productUid);
4348
+ anonymousBookingCountByProductUid.set(
4349
+ key,
4350
+ (anonymousBookingCountByProductUid.get(key) || 0) + 1
4351
+ );
4352
+ }
4353
+ return {
4354
+ ...raw,
4355
+ bookings: raw.bookings.map((booking) => {
4356
+ var _a2;
4357
+ if ((0, import_orderCollectionIdentity.getOrderCollectionPersistentId)("booking", booking) || (0, import_orderCollectionIdentity.getOrderCollectionUid)("booking", booking)) {
4358
+ return booking;
4359
+ }
4360
+ const productUid = (booking == null ? void 0 : booking.product_uid) || ((_a2 = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a2.product_uid);
4361
+ if (productUid === void 0 || productUid === null || productUid === "") {
4362
+ return booking;
4363
+ }
4364
+ const productUidKey = String(productUid);
4365
+ if (anonymousBookingCountByProductUid.get(productUidKey) !== 1) {
4366
+ return booking;
4367
+ }
4368
+ const bookingUidCandidates = bookingUidsByProductUid.get(productUidKey);
4369
+ const bookingUid = (bookingUidCandidates == null ? void 0 : bookingUidCandidates.size) === 1 ? [...bookingUidCandidates][0] : null;
4370
+ return bookingUid ? (0, import_orderCollectionIdentity.setOrderCollectionUid)("booking", booking, bookingUid) : booking;
4371
+ })
4372
+ };
4373
+ }
4006
4374
  normalizeTempOrderForRuntime(raw, options) {
4007
4375
  var _a, _b;
4376
+ const runtimeRaw = this.withoutSyntheticDraftOrderIdForRuntime(raw);
4008
4377
  const nextTempOrder = {
4009
4378
  ...this.createDefaultTempOrderInstance(),
4010
- ...raw || {}
4379
+ ...runtimeRaw || {}
4011
4380
  };
4012
- if ((nextTempOrder.order_id === void 0 || nextTempOrder.order_id === null) && (raw == null ? void 0 : raw.id) !== void 0 && (raw == null ? void 0 : raw.id) !== null) {
4013
- nextTempOrder.order_id = raw.id;
4381
+ if ((nextTempOrder.order_id === void 0 || nextTempOrder.order_id === null) && (runtimeRaw == null ? void 0 : runtimeRaw.id) !== void 0 && (runtimeRaw == null ? void 0 : runtimeRaw.id) !== null) {
4382
+ nextTempOrder.order_id = runtimeRaw.id;
4014
4383
  }
4015
4384
  delete nextTempOrder.summary;
4016
4385
  delete nextTempOrder.lastOrderInfo;
@@ -4028,7 +4397,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4028
4397
  nextTempOrder.metadata = raw.metadata && typeof raw.metadata === "object" ? { ...raw.metadata } : {};
4029
4398
  nextTempOrder.holder = raw.holder && typeof raw.holder === "object" ? { ...raw.holder } : null;
4030
4399
  const rawProducts = Array.isArray(raw.products) ? raw.products : [];
4031
- nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map((p) => this.normalizeHydratedOrderProduct(p)) : [];
4400
+ nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map((p) => this.normalizeHydratedOrderProduct(p, { makeEditMark: options == null ? void 0 : options.makeEditMark })) : [];
4032
4401
  nextTempOrder.bookings = Array.isArray(raw.bookings) ? raw.bookings.map((b) => {
4033
4402
  const booking = this.normalizeHydratedBookingHolder(b || {});
4034
4403
  return {
@@ -4078,6 +4447,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4078
4447
  nextTempOrder.vouchers = raw.vouchers || [];
4079
4448
  return nextTempOrder;
4080
4449
  }
4450
+ isSyntheticDraftOrderIdForRuntime(record, options) {
4451
+ const isDraftOrder = (options == null ? void 0 : options.isDraftOrder) ?? Number((record == null ? void 0 : record.is_draft_order) || 0) === 1;
4452
+ const externalSaleNumber = (record == null ? void 0 : record.external_sale_number) ?? (options == null ? void 0 : options.externalSaleNumber);
4453
+ const orderId = record == null ? void 0 : record.order_id;
4454
+ return Boolean(
4455
+ isDraftOrder && orderId !== void 0 && orderId !== null && orderId !== "" && externalSaleNumber !== void 0 && externalSaleNumber !== null && externalSaleNumber !== "" && String(orderId) === String(externalSaleNumber)
4456
+ );
4457
+ }
4458
+ withoutSyntheticDraftOrderIdForRuntime(record, options) {
4459
+ if (!this.isSyntheticDraftOrderIdForRuntime(record, options))
4460
+ return record;
4461
+ return {
4462
+ ...record,
4463
+ order_id: null
4464
+ };
4465
+ }
4081
4466
  hydrateLinkedBookingIdentity(tempOrder) {
4082
4467
  const bookingUidByProductUid = /* @__PURE__ */ new Map();
4083
4468
  const productByUid = /* @__PURE__ */ new Map();
@@ -4117,9 +4502,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4117
4502
  if (!product.metadata || typeof product.metadata !== "object") {
4118
4503
  product.metadata = {};
4119
4504
  }
4120
- const linkedBookingUid = String(
4121
- product.booking_uid || product.metadata.booking_uid || bookingUid
4122
- );
4505
+ const linkedBookingUid = String(bookingUid);
4123
4506
  product.booking_uid = linkedBookingUid;
4124
4507
  product.metadata.booking_uid = linkedBookingUid;
4125
4508
  });
@@ -4174,7 +4557,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4174
4557
  normalized.id = optionItem.id;
4175
4558
  return normalized;
4176
4559
  }
4177
- normalizeHydratedOrderProduct(product) {
4560
+ normalizeHydratedOrderProduct(product, options) {
4178
4561
  let row = { ...product || {} };
4179
4562
  if (row.num === void 0 && row.product_quantity !== void 0) {
4180
4563
  row.num = row.product_quantity;
@@ -4201,6 +4584,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4201
4584
  if (!existingIdentity) {
4202
4585
  row.metadata.unique_identification_number = (0, import_utils.createUuidV4)();
4203
4586
  }
4587
+ if (options == null ? void 0 : options.makeEditMark) {
4588
+ row.metadata.is_edit_for_runtime = true;
4589
+ }
4204
4590
  const normalized = (0, import_utils3.normalizeOrderProduct)(row);
4205
4591
  normalized.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
4206
4592
  normalized.discount_list