@pisell/pisellos 2.2.264 → 2.2.266

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 (126) 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/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +16 -10
  14. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  15. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  16. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +32 -1
  17. package/dist/modules/Discount/index.d.ts +5 -2
  18. package/dist/modules/Discount/index.js +30 -7
  19. package/dist/modules/Discount/types.d.ts +4 -0
  20. package/dist/modules/Order/index.d.ts +41 -10
  21. package/dist/modules/Order/index.js +1379 -810
  22. package/dist/modules/Order/payment-utils.d.ts +26 -0
  23. package/dist/modules/Order/payment-utils.js +225 -0
  24. package/dist/modules/Order/types.d.ts +49 -1
  25. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  26. package/dist/modules/Order/utils/orderCollectionIdentity.js +410 -0
  27. package/dist/modules/Order/utils.d.ts +4 -3
  28. package/dist/modules/Order/utils.js +61 -64
  29. package/dist/modules/Payment/index.d.ts +2 -0
  30. package/dist/modules/Payment/index.js +78 -49
  31. package/dist/modules/Payment/types.d.ts +26 -24
  32. package/dist/modules/Payment/types.js +2 -0
  33. package/dist/modules/Product/types.d.ts +22 -0
  34. package/dist/modules/ProductList/index.d.ts +1 -1
  35. package/dist/modules/ProductList/index.js +4 -2
  36. package/dist/modules/ProductList/types.d.ts +2 -0
  37. package/dist/modules/Rules/index.d.ts +2 -8
  38. package/dist/modules/Rules/index.js +55 -9
  39. package/dist/modules/Rules/types.d.ts +10 -1
  40. package/dist/server/index.d.ts +71 -0
  41. package/dist/server/index.js +2504 -1187
  42. package/dist/server/modules/order/index.d.ts +56 -5
  43. package/dist/server/modules/order/index.js +1718 -834
  44. package/dist/server/modules/order/types.d.ts +15 -3
  45. package/dist/server/modules/order/types.js +1 -1
  46. package/dist/server/modules/products/index.d.ts +31 -8
  47. package/dist/server/modules/products/index.js +549 -390
  48. package/dist/server/modules/products/types.d.ts +18 -0
  49. package/dist/solution/BaseSales/index.d.ts +67 -4
  50. package/dist/solution/BaseSales/index.js +1476 -792
  51. package/dist/solution/BaseSales/types.d.ts +6 -1
  52. package/dist/solution/BaseSales/types.js +1 -1
  53. package/dist/solution/BaseSales/utils/cartPromotion.js +19 -7
  54. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +9 -4
  55. package/dist/solution/BaseSales/utils/parseSalesResponse.js +6 -8
  56. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -1
  57. package/dist/solution/BookingByStep/index.d.ts +1 -1
  58. package/dist/solution/BookingTicket/index.js +94 -54
  59. package/dist/solution/BookingTicket/types.d.ts +2 -0
  60. package/dist/solution/Sales/index.d.ts +1 -0
  61. package/dist/solution/Sales/index.js +10 -2
  62. package/dist/solution/ShopDiscount/index.js +15 -14
  63. package/dist/utils/payment-number.d.ts +9 -0
  64. package/dist/utils/payment-number.js +69 -0
  65. package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +50 -0
  66. package/lib/model/strategy/adapter/dataVariant/adapter.js +149 -0
  67. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +89 -0
  68. package/lib/model/strategy/adapter/dataVariant/evaluator.js +583 -0
  69. package/lib/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
  70. package/lib/model/strategy/adapter/dataVariant/examples.js +293 -0
  71. package/lib/model/strategy/adapter/dataVariant/index.d.ts +4 -0
  72. package/lib/model/strategy/adapter/dataVariant/index.js +38 -0
  73. package/lib/model/strategy/adapter/dataVariant/type.d.ts +148 -0
  74. package/lib/model/strategy/adapter/dataVariant/type.js +31 -0
  75. package/lib/model/strategy/adapter/index.d.ts +4 -0
  76. package/lib/model/strategy/adapter/index.js +13 -2
  77. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +5 -0
  78. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +1 -0
  79. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  80. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +23 -2
  81. package/lib/modules/Discount/index.d.ts +5 -2
  82. package/lib/modules/Discount/index.js +23 -3
  83. package/lib/modules/Discount/types.d.ts +4 -0
  84. package/lib/modules/Order/index.d.ts +41 -10
  85. package/lib/modules/Order/index.js +514 -122
  86. package/lib/modules/Order/payment-utils.d.ts +26 -0
  87. package/lib/modules/Order/payment-utils.js +224 -0
  88. package/lib/modules/Order/types.d.ts +49 -1
  89. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  90. package/lib/modules/Order/utils/orderCollectionIdentity.js +418 -0
  91. package/lib/modules/Order/utils.d.ts +4 -3
  92. package/lib/modules/Order/utils.js +26 -20
  93. package/lib/modules/Payment/index.d.ts +2 -0
  94. package/lib/modules/Payment/index.js +33 -12
  95. package/lib/modules/Payment/types.d.ts +26 -24
  96. package/lib/modules/Product/types.d.ts +22 -0
  97. package/lib/modules/ProductList/index.d.ts +1 -1
  98. package/lib/modules/ProductList/index.js +4 -2
  99. package/lib/modules/ProductList/types.d.ts +2 -0
  100. package/lib/modules/Rules/index.d.ts +2 -8
  101. package/lib/modules/Rules/index.js +57 -6
  102. package/lib/modules/Rules/types.d.ts +10 -1
  103. package/lib/server/index.d.ts +71 -0
  104. package/lib/server/index.js +1002 -52
  105. package/lib/server/modules/order/index.d.ts +56 -5
  106. package/lib/server/modules/order/index.js +798 -148
  107. package/lib/server/modules/order/types.d.ts +15 -3
  108. package/lib/server/modules/products/index.d.ts +31 -8
  109. package/lib/server/modules/products/index.js +134 -35
  110. package/lib/server/modules/products/types.d.ts +18 -0
  111. package/lib/solution/BaseSales/index.d.ts +67 -4
  112. package/lib/solution/BaseSales/index.js +496 -50
  113. package/lib/solution/BaseSales/types.d.ts +6 -1
  114. package/lib/solution/BaseSales/utils/cartPromotion.js +13 -1
  115. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +9 -4
  116. package/lib/solution/BaseSales/utils/parseSalesResponse.js +4 -5
  117. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +8 -0
  118. package/lib/solution/BookingByStep/index.d.ts +1 -1
  119. package/lib/solution/BookingTicket/index.js +39 -11
  120. package/lib/solution/BookingTicket/types.d.ts +2 -0
  121. package/lib/solution/Sales/index.d.ts +1 -0
  122. package/lib/solution/Sales/index.js +5 -3
  123. package/lib/solution/ShopDiscount/index.js +2 -1
  124. package/lib/utils/payment-number.d.ts +9 -0
  125. package/lib/utils/payment-number.js +64 -0
  126. 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");
@@ -82,6 +85,11 @@ function isPaidPaymentRecord(payment) {
82
85
  function isCommittedVoucherPaymentRecord(payment) {
83
86
  return isVoucherPaymentRecord(payment) && (payment == null ? void 0 : payment.status) !== "voided" && (hasSyncedOrderPaymentRecord(payment) || isPaidPaymentRecord(payment));
84
87
  }
88
+ function getVoucherPaymentLifecycleKey(payment) {
89
+ if (!isVoucherPaymentRecord(payment))
90
+ return null;
91
+ return `${String(payment.voucher_id)}::${String(payment.status || "")}`;
92
+ }
85
93
  var OrderModule = class extends import_BaseModule.BaseModule {
86
94
  constructor(name, version) {
87
95
  super(name || "order", version);
@@ -107,7 +115,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
107
115
  this.draftPersistEnabled = true;
108
116
  }
109
117
  collectHydratedEditDiscounts(products) {
110
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
118
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
111
119
  const discountMap = /* @__PURE__ */ new Map();
112
120
  for (const product of (0, import_bundleDiscountHydration.expandHydratedProductsForDiscountCollection)(products)) {
113
121
  for (const item of (product == null ? void 0 : product.discount_list) || []) {
@@ -137,6 +145,13 @@ var OrderModule = class extends import_BaseModule.BaseModule {
137
145
  existed.amount = Number(existed.amount || 0) + amount;
138
146
  existed.used_par_value = String(Number(existed.used_par_value || 0) + amount);
139
147
  existed.balance = String(Number(existed.balance || 0) + amount);
148
+ const productIds = Array.isArray((_f = existed.limited_relation_product_data) == null ? void 0 : _f.product_ids) ? existed.limited_relation_product_data.product_ids : [];
149
+ if ((product == null ? void 0 : product.product_id) !== void 0 && (product == null ? void 0 : product.product_id) !== null && !productIds.includes(product.product_id)) {
150
+ existed.limited_relation_product_data = {
151
+ ...existed.limited_relation_product_data || {},
152
+ product_ids: [...productIds, product.product_id]
153
+ };
154
+ }
140
155
  existed.applicableProductDetails = [
141
156
  ...existed.applicableProductDetails || [],
142
157
  detail
@@ -153,9 +168,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
153
168
  encoded: "",
154
169
  code: "",
155
170
  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,
171
+ 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
172
  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"),
173
+ par_value: String(((_h = item == null ? void 0 : item.discount) == null ? void 0 : _h.original_amount) ?? (item == null ? void 0 : item.amount) ?? "0"),
159
174
  used_par_value: String((item == null ? void 0 : item.amount) ?? "0"),
160
175
  limit_status: "enable",
161
176
  limited_relation_product_data: {
@@ -185,8 +200,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
185
200
  discount: {
186
201
  ...(item == null ? void 0 : item.discount) || {},
187
202
  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"
203
+ 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,
204
+ discount_calculation_mode: ((_j = item == null ? void 0 : item.discount) == null ? void 0 : _j.discount_calculation_mode) ?? "item_level"
190
205
  },
191
206
  applicableProductDetails: [detail],
192
207
  appliedProductDetails: [detail]
@@ -301,12 +316,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
301
316
  if (!this.store.summary) {
302
317
  this.store.summary = (0, import_utils.createEmptySummary)();
303
318
  }
319
+ if (!Array.isArray(this.store.availableWalletIds)) {
320
+ this.store.availableWalletIds = [];
321
+ }
304
322
  this.request = this.core.getPlugin("request");
305
- const appPlugin = this.core.getPlugin("app");
306
- if (!appPlugin) {
323
+ this.appPlugin = this.core.getPlugin("app");
324
+ if (!this.appPlugin) {
307
325
  throw new Error("Order 模块需要 app 插件支持");
308
326
  }
309
- const app = appPlugin.getApp();
327
+ const app = this.appPlugin.getApp();
310
328
  this.logger = app.logger;
311
329
  this.window = this.core.getPlugin("window");
312
330
  const otherParams = options.otherParams || {};
@@ -428,19 +446,30 @@ var OrderModule = class extends import_BaseModule.BaseModule {
428
446
  async loadDiscountConfig(params) {
429
447
  var _a, _b, _c, _d, _e, _f, _g;
430
448
  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({
449
+ const prepareConfigResult = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
432
450
  customer_id: params.customerId,
433
451
  action: params.action || (orderId ? "edit" : "create"),
434
452
  with_good_pass: 1,
435
453
  with_discount_card: 1,
436
454
  with_wallet_pass_holder: 1,
455
+ with_available_wallet_flag: 1,
456
+ with_available_wallet_pass_flag: 1,
437
457
  request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
438
458
  ...orderId ? { order_id: orderId } : {}
439
459
  }));
460
+ const discountList = prepareConfigResult == null ? void 0 : prepareConfigResult.discountList;
461
+ this.store.availableWalletIds = (prepareConfigResult == null ? void 0 : prepareConfigResult.availableWalletIds) || [];
440
462
  if (discountList) {
441
- const currentEditDiscounts = (((_c = this.store.discount) == null ? void 0 : _c.getDiscountList()) || []).filter((discount) => discount == null ? void 0 : discount.isEditMode);
463
+ const currentDiscountList = ((_c = this.store.discount) == null ? void 0 : _c.getDiscountList()) || [];
464
+ const currentEditDiscounts = currentDiscountList.filter((discount) => discount == null ? void 0 : discount.isEditMode);
465
+ const currentScanDiscounts = currentDiscountList.filter((discount) => discount == null ? void 0 : discount.isScan);
466
+ const currentScanDiscountIds = new Set(
467
+ currentScanDiscounts.map((discount) => discount == null ? void 0 : discount.id)
468
+ );
442
469
  const runtimeDiscountIds = /* @__PURE__ */ new Set();
443
470
  const runtimeDiscounts = discountList.filter((discount) => {
471
+ if (currentScanDiscountIds.has(discount == null ? void 0 : discount.id))
472
+ return false;
444
473
  if (runtimeDiscountIds.has(discount == null ? void 0 : discount.id))
445
474
  return false;
446
475
  runtimeDiscountIds.add(discount == null ? void 0 : discount.id);
@@ -448,6 +477,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
448
477
  });
449
478
  const mergedDiscountList = [
450
479
  ...currentEditDiscounts,
480
+ ...currentScanDiscounts,
451
481
  ...runtimeDiscounts
452
482
  ];
453
483
  await ((_d = this.store.discount) == null ? void 0 : _d.setOriginalDiscountList(mergedDiscountList));
@@ -462,6 +492,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
462
492
  var _a;
463
493
  return ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList()) || [];
464
494
  }
495
+ getAvailableWalletIds() {
496
+ return Array.isArray(this.store.availableWalletIds) ? [...this.store.availableWalletIds] : [];
497
+ }
498
+ async syncScannedDiscountsToOriginalDiscountList(discountList) {
499
+ var _a, _b, _c, _d;
500
+ const scanDiscounts = (discountList || []).filter((discount) => discount == null ? void 0 : discount.isScan);
501
+ if (!scanDiscounts.length)
502
+ return;
503
+ const scanDiscountIds = new Set(scanDiscounts.map((discount) => discount == null ? void 0 : discount.id));
504
+ const originalDiscounts = ((_b = (_a = this.store.discount) == null ? void 0 : _a.getOriginalDiscountList) == null ? void 0 : _b.call(_a)) || [];
505
+ const nextOriginalDiscounts = [
506
+ ...scanDiscounts,
507
+ ...originalDiscounts.filter((discount) => !scanDiscountIds.has(discount == null ? void 0 : discount.id))
508
+ ];
509
+ await ((_d = (_c = this.store.discount) == null ? void 0 : _c.setOriginalDiscountList) == null ? void 0 : _d.call(_c, nextOriginalDiscounts));
510
+ }
465
511
  async ensureEditDiscountConfigForProductChange(tempOrder) {
466
512
  var _a, _b, _c, _d, _e, _f;
467
513
  const orderId = tempOrder.order_id;
@@ -510,6 +556,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
510
556
  }));
511
557
  const currentSelected = this.getDiscountList().filter((n) => n.isSelected);
512
558
  if (currentSelected.length && currentSelected.some((n) => withScanList.some((m) => m.id === n.id))) {
559
+ await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
513
560
  return {
514
561
  type: "clientCalc",
515
562
  isAvailable: true,
@@ -530,6 +577,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
530
577
  if (isAvailable && newDiscountList) {
531
578
  (_d = this.store.discount) == null ? void 0 : _d.setDiscountList(newDiscountList);
532
579
  this.applyDiscount();
580
+ await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
533
581
  }
534
582
  return {
535
583
  type: "clientCalc",
@@ -539,8 +587,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
539
587
  unavailableReason
540
588
  };
541
589
  }
542
- applyDiscount() {
543
- var _a, _b, _c, _d;
590
+ applyDiscount(options) {
591
+ var _a, _b, _c;
544
592
  const tempOrder = this.store.tempOrder;
545
593
  if (!tempOrder)
546
594
  return;
@@ -553,13 +601,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
553
601
  const rulesModule = this.store.rules;
554
602
  if (!rulesModule)
555
603
  return;
556
- const holders = ((_b = tempOrder.holder) == null ? void 0 : _b.form_record) || [];
557
604
  const result = rulesModule.calcDiscount({
558
605
  productList: tempOrder.products,
559
606
  discountList,
560
- holders,
607
+ holders: [],
561
608
  isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
562
- orderTotalAmount: Number(((_c = this.store.summary) == null ? void 0 : _c.total_amount) || 0)
609
+ orderTotalAmount: Number(((_b = this.store.summary) == null ? void 0 : _b.total_amount) || 0)
610
+ }, {
611
+ reapplyBookingDiscountProductUids: options == null ? void 0 : options.reapplyBookingDiscountProductUids
563
612
  });
564
613
  if (result == null ? void 0 : result.productList) {
565
614
  const previousProductsByUid = (0, import_utils.indexOrderProductsByUid)(tempOrder.products);
@@ -588,7 +637,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
588
637
  result.productList || tempOrder.products,
589
638
  result.discountList
590
639
  );
591
- (_d = this.store.discount) == null ? void 0 : _d.setDiscountList(result.discountList);
640
+ (_c = this.store.discount) == null ? void 0 : _c.setDiscountList(result.discountList);
592
641
  }
593
642
  this.hasActiveCustomerBoundDiscount = (tempOrder.products || []).some(
594
643
  (product) => this.productHasCustomerBoundDiscount(product)
@@ -871,6 +920,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
871
920
  return sum.plus(this.calculatePaymentEffectiveAmount(payment));
872
921
  }, new import_decimal.default(0));
873
922
  }
923
+ calculateOrderPaidPaymentTotal(payments) {
924
+ return (0, import_utils.mapPaymentItemsToOrderPayments)(payments, {
925
+ includeVoided: false
926
+ }).reduce((sum, payment) => {
927
+ if (!isPaidPaymentRecord(payment))
928
+ return sum;
929
+ return sum.plus(this.calculatePaymentGapAmount(payment));
930
+ }, new import_decimal.default(0));
931
+ }
874
932
  getDepositAmount(tempOrder, summary) {
875
933
  return new import_decimal.default(summary.deposit_amount || tempOrder.deposit_amount || "0.00");
876
934
  }
@@ -961,7 +1019,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
961
1019
  const paymentList = payments || tempOrder.payments || [];
962
1020
  const refundAmount = this.getSummaryRefundAmount(summary);
963
1021
  const netPaidAmount = import_decimal.default.max(
964
- this.calculatePaymentTotal(paymentList).minus(refundAmount),
1022
+ this.calculateOrderPaidPaymentTotal(paymentList).minus(refundAmount),
965
1023
  0
966
1024
  );
967
1025
  const depositAmount = this.getDepositAmount(tempOrder, summary);
@@ -990,11 +1048,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
990
1048
  const isDepositPayment = paymentRecord.type === "deposit" || paymentRecord.order_payment_type === "deposit";
991
1049
  if (!isDepositPayment)
992
1050
  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));
1051
+ return sum.plus(this.calculatePaymentGapAmount(paymentRecord));
998
1052
  }, new import_decimal.default(0));
999
1053
  }
1000
1054
  resolveNextOrderPaymentType(tempOrder) {
@@ -1006,17 +1060,40 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1006
1060
  const depositPaidAmount = this.calculateDepositPaidAmount(tempOrder.payments || []);
1007
1061
  return depositPaidAmount.lt(depositAmount) ? "deposit" : "normal";
1008
1062
  }
1063
+ getPaymentNumberAppData(key) {
1064
+ var _a, _b, _c, _d, _e;
1065
+ const appPlugin = this.appPlugin;
1066
+ if (!appPlugin)
1067
+ return void 0;
1068
+ const getData = (_a = appPlugin.getData) == null ? void 0 : _a.call(appPlugin);
1069
+ if (typeof getData === "function")
1070
+ return getData(key);
1071
+ const app = appPlugin.getApp();
1072
+ 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");
1073
+ return coreData == null ? void 0 : coreData[key];
1074
+ }
1075
+ getPaymentNumberDevicePrefixSync() {
1076
+ return (0, import_payment_number.resolvePaymentNumberDevicePrefixFromDeviceId)(
1077
+ (key) => this.getPaymentNumberAppData(key)
1078
+ );
1079
+ }
1080
+ getPaymentNumberDevicePrefixAsync() {
1081
+ return (0, import_payment_number.resolvePaymentNumberDevicePrefix)(
1082
+ (key) => this.getPaymentNumberAppData(key)
1083
+ );
1084
+ }
1009
1085
  normalizePaymentSource(payment, options) {
1010
1086
  const paymentRecord = payment;
1011
1087
  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
- };
1088
+ const normalized = (0, import_payment_utils.ensureOrderPaymentNumber)(
1089
+ {
1090
+ ...paymentRecord,
1091
+ metadata,
1092
+ origin_amount: paymentRecord.origin_amount ?? paymentRecord.amount ?? "0.00"
1093
+ },
1094
+ (options == null ? void 0 : options.devicePrefix) || this.getPaymentNumberDevicePrefixSync(),
1095
+ import_utils.createUuidV4
1096
+ );
1020
1097
  if (paymentRecord.status !== void 0) {
1021
1098
  normalized.status = paymentRecord.status;
1022
1099
  } else if ((options == null ? void 0 : options.defaultPaid) !== false) {
@@ -1027,8 +1104,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1027
1104
  updateTempOrderPaymentStatus(tempOrder, options) {
1028
1105
  const summary = (options == null ? void 0 : options.summary) || this.store.summary || (0, import_utils.createEmptySummary)();
1029
1106
  const paymentTotal = this.calculatePaymentTotal(tempOrder.payments || []);
1107
+ const orderPaymentTotal = this.calculateOrderPaidPaymentTotal(tempOrder.payments || []);
1030
1108
  const refundAmount = this.getSummaryRefundAmount(summary);
1031
- const netPaymentTotal = import_decimal.default.max(paymentTotal.minus(refundAmount), 0);
1109
+ const netPaymentTotal = import_decimal.default.max(orderPaymentTotal.minus(refundAmount), 0);
1032
1110
  const targetAmount = this.calculatePaymentTargetAmount(
1033
1111
  tempOrder,
1034
1112
  summary,
@@ -1097,7 +1175,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1097
1175
  }
1098
1176
  capVoucherPaymentsByRemainingAmount(params) {
1099
1177
  const targetAmount = this.getPaymentTargetAmount();
1100
- const nonVoucherTotal = this.calculatePaymentTotal(params.nonVoucherPayments);
1178
+ const nonVoucherTotal = this.calculateOrderPaidPaymentTotal(params.nonVoucherPayments);
1101
1179
  if (targetAmount.lte(0))
1102
1180
  return [];
1103
1181
  let remainingAmount = import_decimal.default.max(
@@ -1140,7 +1218,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1140
1218
  return summary;
1141
1219
  return {
1142
1220
  customerPaidAmount: summary.customerPaidAmount.plus(paymentRecord.amount || 0),
1143
- orderPaidAmount: summary.orderPaidAmount.plus(paymentRecord.origin_amount || 0),
1221
+ orderPaidAmount: summary.orderPaidAmount.plus(this.calculatePaymentOrderAmount(paymentRecord)),
1144
1222
  gapPaidAmount: summary.gapPaidAmount.plus(this.calculatePaymentGapAmount(paymentRecord)),
1145
1223
  payServiceChargeAmount: summary.payServiceChargeAmount.plus(this.calculatePaymentServiceFee(paymentRecord)),
1146
1224
  roundingAmount: summary.roundingAmount.plus(this.calculatePaymentRoundingAmount(paymentRecord))
@@ -1165,11 +1243,30 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1165
1243
  return new import_decimal.default(payment.amount || 0).times(percentage).plus(fixedAmount);
1166
1244
  }
1167
1245
  calculatePaymentGapAmount(payment) {
1168
- if (payment.origin_amount === void 0 || payment.origin_amount === null || payment.origin_amount === "") {
1169
- return new import_decimal.default(0);
1246
+ if (payment.origin_amount !== void 0 && payment.origin_amount !== null && payment.origin_amount !== "") {
1247
+ const rounding2 = new import_decimal.default(payment.rounding_amount || 0);
1248
+ return new import_decimal.default(payment.origin_amount || 0).minus(rounding2);
1170
1249
  }
1171
1250
  const rounding = new import_decimal.default(payment.rounding_amount || 0);
1172
- return new import_decimal.default(payment.origin_amount || 0).minus(rounding);
1251
+ const amount = new import_decimal.default(payment.amount || 0);
1252
+ const serviceFee = this.calculatePaymentServiceFee(payment);
1253
+ if (serviceFee.lte(0))
1254
+ return amount.minus(rounding);
1255
+ if (!hasSyncedOrderPaymentRecord(payment))
1256
+ return new import_decimal.default(0);
1257
+ return import_decimal.default.max(amount.minus(serviceFee), 0).minus(rounding);
1258
+ }
1259
+ calculatePaymentOrderAmount(payment) {
1260
+ if (payment.origin_amount !== void 0 && payment.origin_amount !== null && payment.origin_amount !== "") {
1261
+ return new import_decimal.default(payment.origin_amount || 0);
1262
+ }
1263
+ const amount = new import_decimal.default(payment.amount || 0);
1264
+ const serviceFee = this.calculatePaymentServiceFee(payment);
1265
+ if (serviceFee.lte(0))
1266
+ return amount;
1267
+ if (!hasSyncedOrderPaymentRecord(payment))
1268
+ return new import_decimal.default(0);
1269
+ return import_decimal.default.max(amount.minus(serviceFee), 0);
1173
1270
  }
1174
1271
  calculatePaymentRoundingAmount(payment) {
1175
1272
  if (payment.rounding_amount === void 0 || payment.rounding_amount === null || payment.rounding_amount === "") {
@@ -1480,6 +1577,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1480
1577
  }
1481
1578
  restoreOriginalSnapshotIfProductsUnchanged(tempOrder, snapshot) {
1482
1579
  const currentFingerprint = this.buildOrderProductsFingerprint(tempOrder.products);
1580
+ const manualDepositOverride = this.getManualDepositOverride(tempOrder);
1483
1581
  if (currentFingerprint !== snapshot.productFingerprint) {
1484
1582
  const currentStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(tempOrder.products);
1485
1583
  const snapshotStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(
@@ -1488,11 +1586,24 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1488
1586
  if (currentStructuralFingerprint !== snapshotStructuralFingerprint)
1489
1587
  return null;
1490
1588
  }
1491
- const summary = {
1589
+ let summary = {
1492
1590
  ...(0, import_utils.createEmptySummary)(),
1493
1591
  ...(0, import_lodash_es.cloneDeep)(snapshot.summary || {})
1494
1592
  };
1495
- if (!this.isSnapshotPayableAmountUnchanged(tempOrder, snapshot, summary))
1593
+ const shouldUseManualDepositOverride = Boolean(
1594
+ manualDepositOverride && manualDepositOverride.productStructuralFingerprint === this.buildOrderProductsStructuralFingerprint(tempOrder.products)
1595
+ );
1596
+ if (shouldUseManualDepositOverride) {
1597
+ summary = this.applyDepositAmountToSummary(
1598
+ tempOrder,
1599
+ summary,
1600
+ manualDepositOverride.amount
1601
+ );
1602
+ } else if (manualDepositOverride) {
1603
+ this.clearManualDepositOverride(tempOrder);
1604
+ }
1605
+ const isPayableAmountUnchanged = this.isSnapshotPayableAmountUnchanged(tempOrder, snapshot, summary);
1606
+ if (!isPayableAmountUnchanged)
1496
1607
  return null;
1497
1608
  if (Array.isArray(snapshot.products)) {
1498
1609
  tempOrder.products = (0, import_lodash_es.cloneDeep)(snapshot.products);
@@ -1503,7 +1614,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1503
1614
  tempOrder.surcharge_fee = summary.surcharge_fee || tempOrder.surcharge_fee;
1504
1615
  tempOrder.deposit_amount = summary.deposit_amount || "0.00";
1505
1616
  tempOrder.is_deposit = summary.deposit_amount !== "0.00" ? 1 : 0;
1617
+ const previousSummary = this.store.summary;
1506
1618
  this.store.summary = summary;
1619
+ this.updateTempOrderPaymentStatus(tempOrder, {
1620
+ previousSummary,
1621
+ summary
1622
+ });
1507
1623
  return summary;
1508
1624
  }
1509
1625
  clearPersistedAmountFieldsForFullRecalc(products) {
@@ -2192,6 +2308,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2192
2308
  const type = (discount == null ? void 0 : discount.type) ?? (discount == null ? void 0 : discount.tag);
2193
2309
  return type === "good_pass" || type === "discount_card" || type === "product_discount_card";
2194
2310
  }
2311
+ shouldKeepCustomerBoundDiscountAfterCustomerChange(discount) {
2312
+ return Boolean((discount == null ? void 0 : discount.isScan) || (discount == null ? void 0 : discount.isEditMode));
2313
+ }
2195
2314
  productHasCustomerBoundDiscount(product) {
2196
2315
  if (((product == null ? void 0 : product.discount_list) || []).some((discount) => this.isCustomerBoundDiscount(discount))) {
2197
2316
  return true;
@@ -2247,12 +2366,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2247
2366
  const currentDiscounts = ((_a = discountModule.getDiscountList) == null ? void 0 : _a.call(discountModule)) || [];
2248
2367
  const currentOriginalDiscounts = ((_b = discountModule.getOriginalDiscountList) == null ? void 0 : _b.call(discountModule)) || [];
2249
2368
  const nextDiscounts = currentDiscounts.filter((discount) => {
2250
- if (discount == null ? void 0 : discount.isEditMode)
2369
+ if (this.shouldKeepCustomerBoundDiscountAfterCustomerChange(discount))
2251
2370
  return true;
2252
2371
  return !this.isCustomerBoundDiscount(discount);
2253
2372
  });
2254
2373
  const nextOriginalDiscounts = currentOriginalDiscounts.filter((discount) => {
2255
- if (discount == null ? void 0 : discount.isEditMode)
2374
+ if (this.shouldKeepCustomerBoundDiscountAfterCustomerChange(discount))
2256
2375
  return true;
2257
2376
  return !this.isCustomerBoundDiscount(discount);
2258
2377
  });
@@ -2323,6 +2442,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2323
2442
  }
2324
2443
  const nextCustomerId = tempOrder.customer_id ?? null;
2325
2444
  if (String(previousCustomerId ?? "") !== String(nextCustomerId ?? "")) {
2445
+ this.store.availableWalletIds = [];
2326
2446
  (0, import_utils.clearTempOrderHolderAssignments)(tempOrder);
2327
2447
  this.clearCustomerBoundDiscounts(tempOrder);
2328
2448
  this.applyDiscount();
@@ -2362,6 +2482,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2362
2482
  tempOrder.customer = null;
2363
2483
  if (tempOrder._extend)
2364
2484
  delete tempOrder._extend.customerSnapshot;
2485
+ this.store.availableWalletIds = [];
2365
2486
  this.clearCustomerBoundDiscounts(tempOrder);
2366
2487
  this.persistTempOrder();
2367
2488
  this.saveDraftInBackground();
@@ -2393,17 +2514,36 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2393
2514
  * 用一组支付来源覆盖当前订单支付项。
2394
2515
  *
2395
2516
  * 入参允许来自 PaymentModule 的 PaymentItem,内部统一映射为 Sales 协议:
2396
- * uuid -> metadata.unique_payment_number,id -> custom_payment_id,
2517
+ * 新支付来源的 uuid 会作为 payment_number 的唯一号段,id -> custom_payment_id,
2397
2518
  * isSynced 等运行态字段不会进入 tempOrder.payments。
2398
2519
  */
2399
2520
  setOrderPayments(payments) {
2400
2521
  const tempOrder = this.ensureTempOrder();
2401
- tempOrder.payments = (0, import_utils.mapPaymentItemsToOrderPayments)(payments);
2522
+ tempOrder.payments = (0, import_utils.mapPaymentItemsToOrderPayments)(
2523
+ (payments || []).map((payment) => this.normalizePaymentSource(payment, { defaultPaid: false }))
2524
+ );
2402
2525
  this.persistTempOrder();
2403
2526
  return tempOrder.payments;
2404
2527
  }
2405
- /** 追加单个支付项,并立即持久化当前 tempOrder。 */
2528
+ /** 同步兼容入口:按调用当下的 device_id 或 LOCAL 生成支付编号。 */
2406
2529
  addOrderPayment(payment) {
2530
+ const hasPaymentNumber = String(
2531
+ payment.payment_number || ""
2532
+ ).trim() !== "";
2533
+ return this.addOrderPaymentWithDevicePrefix(
2534
+ payment,
2535
+ hasPaymentNumber ? "LOCAL" : this.getPaymentNumberDevicePrefixSync()
2536
+ );
2537
+ }
2538
+ /** 异步入口:创建支付项时读取最新 IoT 设备短号。 */
2539
+ async addOrderPaymentAsync(payment) {
2540
+ const hasPaymentNumber = String(
2541
+ payment.payment_number || ""
2542
+ ).trim() !== "";
2543
+ const devicePrefix = hasPaymentNumber ? "LOCAL" : await this.getPaymentNumberDevicePrefixAsync();
2544
+ return this.addOrderPaymentWithDevicePrefix(payment, devicePrefix);
2545
+ }
2546
+ addOrderPaymentWithDevicePrefix(payment, devicePrefix) {
2407
2547
  this.logInfo("addOrderPayment", {
2408
2548
  payment
2409
2549
  });
@@ -2416,7 +2556,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2416
2556
  type: orderPaymentType,
2417
2557
  order_payment_type: orderPaymentType
2418
2558
  },
2419
- { defaultPaid: true }
2559
+ { defaultPaid: true, devicePrefix }
2420
2560
  )
2421
2561
  ]);
2422
2562
  tempOrder.payments = [...tempOrder.payments || [], ...mapped];
@@ -2429,57 +2569,55 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2429
2569
  return tempOrder.payments;
2430
2570
  }
2431
2571
  /**
2432
- * 按支付唯一号、后端支付 ID、自定义支付方式 ID 或旧 uuid 更新支付项。
2433
- *
2434
- * 该方法服务 PaymentModal 的 void / 编辑场景;更新 metadata 时会做浅合并,
2435
- * 避免覆盖 unique_payment_number、现金实付/找零等已有元数据。
2572
+ * 默认按支付唯一号精确更新;仅显式指定 legacy 时兼容历史支付标识。
2573
+ * metadata 与 transactions 会分别合并,避免覆盖支付会话号和已有交易记录。
2436
2574
  */
2437
- updateOrderPayment(paymentIdentity, updates) {
2575
+ async updateOrderPayment(paymentIdentity, updates, options = {}) {
2438
2576
  const tempOrder = this.ensureTempOrder();
2439
2577
  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)
2578
+ const matchMode = options.matchBy === "compat" || options.matchBy === "legacy" ? "compat" : "payment_number";
2579
+ const matchedPayment = (0, import_payment_utils.resolveOrderPaymentIdentity)(
2580
+ tempOrder.payments || [],
2581
+ identity,
2582
+ matchMode
2583
+ );
2584
+ if (!matchedPayment) {
2585
+ throw new Error(`未找到支付项: ${identity}`);
2586
+ }
2587
+ let updatedPayment = null;
2588
+ tempOrder.payments = (tempOrder.payments || []).map((payment, index) => {
2589
+ if (index !== matchedPayment.index)
2453
2590
  return payment;
2454
- return {
2455
- ...payment,
2591
+ const nextPayment = (0, import_payment_utils.mergeOrderPaymentRecord)(payment, {
2456
2592
  ...updates,
2457
- metadata: {
2458
- ...payment.metadata || {},
2459
- ...updates.metadata || {}
2460
- }
2461
- };
2593
+ updated_at: updates.updated_at || (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
2594
+ });
2595
+ updatedPayment = nextPayment;
2596
+ return nextPayment;
2462
2597
  });
2463
2598
  this.persistTempOrder();
2464
- return tempOrder.payments;
2599
+ const summary = await this.recalculateSummary({ createIfMissing: true });
2600
+ this.persistTempOrder();
2601
+ const payments = tempOrder.payments;
2602
+ return {
2603
+ updated: true,
2604
+ payment: payments[matchedPayment.index] || updatedPayment,
2605
+ payments,
2606
+ summary
2607
+ };
2465
2608
  }
2466
2609
  /** 从当前订单支付项中移除指定支付项。 */
2467
2610
  deleteOrderPayment(paymentIdentity) {
2468
2611
  const tempOrder = this.ensureTempOrder();
2469
2612
  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
- });
2613
+ const matchedPayment = (0, import_payment_utils.resolveOrderPaymentIdentity)(
2614
+ tempOrder.payments || [],
2615
+ identity,
2616
+ "compat"
2617
+ );
2618
+ if (!matchedPayment)
2619
+ return tempOrder.payments;
2620
+ tempOrder.payments = (tempOrder.payments || []).filter((_, index) => index !== matchedPayment.index);
2483
2621
  this.persistTempOrder();
2484
2622
  return tempOrder.payments;
2485
2623
  }
@@ -2588,7 +2726,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2588
2726
  payments.map(
2589
2727
  (payment) => this.normalizePaymentSource(
2590
2728
  normalizeVoucherPaymentStatus(withVoucherPaymentType(payment)),
2591
- { defaultPaid: false }
2729
+ {
2730
+ defaultPaid: false,
2731
+ devicePrefix: options == null ? void 0 : options.devicePrefix
2732
+ }
2592
2733
  )
2593
2734
  )
2594
2735
  ).filter((payment) => {
@@ -2610,14 +2751,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2610
2751
  const committedVoucherPaymentIds = new Set(
2611
2752
  committedVoucherPayments.filter((payment) => hasSyncedOrderPaymentRecord(payment)).map((payment) => String(payment.order_payment_id))
2612
2753
  );
2613
- const committedVoucherIds = new Set(
2614
- committedVoucherPayments.map((payment) => String(payment.voucher_id))
2754
+ const committedVoucherLifecycleKeys = new Set(
2755
+ committedVoucherPayments.map((payment) => getVoucherPaymentLifecycleKey(payment)).filter((key) => key !== null)
2615
2756
  );
2616
2757
  const replaceableVouchers = mappedVouchers.filter((payment) => {
2617
2758
  if (hasSyncedOrderPaymentRecord(payment) && committedVoucherPaymentIds.has(String(payment.order_payment_id))) {
2618
2759
  return false;
2619
2760
  }
2620
- if (payment.voucher_id !== void 0 && committedVoucherIds.has(String(payment.voucher_id))) {
2761
+ const lifecycleKey = getVoucherPaymentLifecycleKey(payment);
2762
+ if (lifecycleKey && committedVoucherLifecycleKeys.has(lifecycleKey)) {
2621
2763
  return false;
2622
2764
  }
2623
2765
  return true;
@@ -2639,6 +2781,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2639
2781
  });
2640
2782
  return tempOrder.payments;
2641
2783
  }
2784
+ async updateVoucherOrderPaymentsAsync(payments, options) {
2785
+ const needsPaymentNumber = (payments || []).some((payment) => String(payment.payment_number || "").trim() === "");
2786
+ const devicePrefix = needsPaymentNumber ? await this.getPaymentNumberDevicePrefixAsync() : "LOCAL";
2787
+ return this.updateVoucherOrderPayments(payments, {
2788
+ ...options,
2789
+ devicePrefix
2790
+ });
2791
+ }
2642
2792
  async shouldMergeProductToOrder(params) {
2643
2793
  var _a;
2644
2794
  const onBeforeMergeProductToOrder = (_a = this.orderHooks) == null ? void 0 : _a.onBeforeMergeProductToOrder;
@@ -2728,12 +2878,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2728
2878
  const hasIncomingBookingUid = this.hasLinkedBookingUid(productToAdd) || this.hasLinkedBookingUid(normalizedIncoming);
2729
2879
  const shouldForceNewLine = !!booking || hasIncomingProductNote || hasIncomingBookingUid;
2730
2880
  const matchedIndex = hasIncomingGoodPass || shouldForceNewLine ? -1 : tempOrder.products.findIndex((item) => {
2881
+ var _a2;
2731
2882
  if (this.hasGoodPassDiscount(item))
2732
2883
  return false;
2733
2884
  if (this.hasOrderProductLineNote(item))
2734
2885
  return false;
2735
2886
  if (item.order_detail_id !== void 0 && item.order_detail_id !== null)
2736
2887
  return false;
2888
+ if ((_a2 = item.metadata) == null ? void 0 : _a2.is_edit_for_runtime)
2889
+ return false;
2737
2890
  if (item.product_id !== productToAdd.product_id)
2738
2891
  return false;
2739
2892
  if (item.product_variant_id !== productToAdd.product_variant_id)
@@ -2964,6 +3117,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2964
3117
  return bundle;
2965
3118
  return {
2966
3119
  ...bundle,
3120
+ ...(bundle.cover === void 0 || bundle.cover === null || bundle.cover === "") && previous.cover !== void 0 && previous.cover !== null && previous.cover !== "" ? { cover: previous.cover } : {},
2967
3121
  price: previous.price,
2968
3122
  custom_price: previous.custom_price,
2969
3123
  bundle_payment_price: previous.bundle_payment_price,
@@ -2974,7 +3128,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2974
3128
  });
2975
3129
  }
2976
3130
  applyOrderProductUpdateToTempOrder(tempOrder, params) {
2977
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
3131
+ 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
3132
  const {
2979
3133
  product_id,
2980
3134
  product_variant_id,
@@ -3038,9 +3192,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3038
3192
  nextProduct.num = (0, import_utils3.getSafeProductNum)(nextProduct.num);
3039
3193
  const callerUpdatesTopPrice = Object.prototype.hasOwnProperty.call(updates || {}, "selling_price") || Object.prototype.hasOwnProperty.call(updates || {}, "original_price");
3040
3194
  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;
3195
+ const callerUpdatesSourcePrice = ((_f = updates == null ? void 0 : updates.metadata) == null ? void 0 : _f.source_product_price) !== void 0;
3196
+ const callerUpdatesMainSellingPrice = ((_g = updates == null ? void 0 : updates.metadata) == null ? void 0 : _g.main_product_selling_price) !== void 0;
3197
+ const callerUpdatesMainOriginalPrice = ((_h = updates == null ? void 0 : updates.metadata) == null ? void 0 : _h.main_product_original_price) !== void 0;
3198
+ const previousLineFingerprint = (0, import_utils3.buildProductLineFingerprint)(
3199
+ (0, import_utils.getProductSkuOptions)(targetProduct),
3200
+ targetProduct.product_bundle
3201
+ );
3202
+ const nextLineFingerprint = (0, import_utils3.buildProductLineFingerprint)(
3203
+ (0, import_utils.getProductSkuOptions)(nextProduct),
3204
+ nextProduct.product_bundle
3205
+ );
3206
+ const callerChangesVariant = Number(product_variant_id || 0) !== Number(targetProduct.product_variant_id || 0);
3207
+ const callerChangesLineConfiguration = callerChangesVariant || previousLineFingerprint !== nextLineFingerprint;
3041
3208
  const isPersistedOrderLine = targetProduct.order_detail_id !== void 0 && targetProduct.order_detail_id !== null;
3042
3209
  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;
3210
+ 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
3211
  const callerAllowsBookingReprice = (() => {
3045
3212
  if (params.allow_booking_reprice !== true || !booking || !callerUpdatesTopPrice || !callerUpdatesMainMeta) {
3046
3213
  return false;
@@ -3055,21 +3222,69 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3055
3222
  };
3056
3223
  return hasChangedPrice(updates.selling_price, targetProduct.selling_price) || hasChangedPrice(updates.original_price, targetProduct.original_price);
3057
3224
  })();
3058
- if (isPersistedOrderLine && !callerUpdatesManualPrice && !callerAllowsBookingReprice) {
3225
+ if (isPersistedOrderLine && !callerChangesLineConfiguration && !callerUpdatesManualPrice && !callerAllowsBookingReprice) {
3059
3226
  nextProduct.selling_price = targetProduct.selling_price;
3060
3227
  nextProduct.original_price = targetProduct.original_price;
3061
3228
  nextProduct.payment_price = targetProduct.payment_price;
3062
3229
  nextProduct.metadata = {
3063
3230
  ...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
3231
+ source_product_price: (_l = targetProduct.metadata) == null ? void 0 : _l.source_product_price,
3232
+ main_product_selling_price: (_m = targetProduct.metadata) == null ? void 0 : _m.main_product_selling_price,
3233
+ main_product_original_price: (_n = targetProduct.metadata) == null ? void 0 : _n.main_product_original_price,
3234
+ price_schema_version: ((_o = targetProduct.metadata) == null ? void 0 : _o.price_schema_version) ?? 2
3068
3235
  };
3069
3236
  nextProduct.product_bundle = this.preservePersistedBundlePriceFields(
3070
3237
  targetProduct.product_bundle,
3071
3238
  nextProduct.product_bundle
3072
3239
  );
3240
+ } else if (callerChangesLineConfiguration && callerUpdatesSourcePrice && (!callerUpdatesMainSellingPrice || !callerUpdatesMainOriginalPrice)) {
3241
+ const previousMainOriginal = new import_decimal.default(
3242
+ Number((_p = targetProduct.metadata) == null ? void 0 : _p.main_product_original_price) || 0
3243
+ );
3244
+ const previousMainSelling = new import_decimal.default(
3245
+ Number((_q = targetProduct.metadata) == null ? void 0 : _q.main_product_selling_price) || previousMainOriginal.toNumber()
3246
+ );
3247
+ const preservedDiscount = previousMainOriginal.minus(previousMainSelling);
3248
+ const nextMainOriginal = new import_decimal.default(
3249
+ Number(updates.metadata.source_product_price) || 0
3250
+ ).plus((0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(nextProduct)));
3251
+ nextProduct.metadata = {
3252
+ ...nextProduct.metadata || {},
3253
+ source_product_price: String(updates.metadata.source_product_price),
3254
+ main_product_original_price: callerUpdatesMainOriginalPrice ? String(updates.metadata.main_product_original_price) : nextMainOriginal.toDecimalPlaces(2).toFixed(2),
3255
+ main_product_selling_price: callerUpdatesMainSellingPrice ? String(updates.metadata.main_product_selling_price) : nextMainOriginal.minus(preservedDiscount).toDecimalPlaces(2).toFixed(2),
3256
+ price_schema_version: 2
3257
+ };
3258
+ } else if (callerChangesVariant && !callerUpdatesTopPrice && !callerUpdatesMainMeta) {
3259
+ const existedMeta = nextProduct.metadata || {};
3260
+ nextProduct.metadata = { ...existedMeta };
3261
+ delete nextProduct.metadata.source_product_price;
3262
+ delete nextProduct.metadata.main_product_selling_price;
3263
+ delete nextProduct.metadata.main_product_original_price;
3264
+ delete nextProduct.metadata.price_schema_version;
3265
+ } else if (callerChangesLineConfiguration && !callerUpdatesTopPrice && !callerUpdatesMainMeta) {
3266
+ const previousOptionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(targetProduct));
3267
+ const nextOptionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(nextProduct));
3268
+ const previousMainOriginal = new import_decimal.default(
3269
+ Number(
3270
+ ((_r = targetProduct.metadata) == null ? void 0 : _r.main_product_original_price) ?? targetProduct.original_price ?? 0
3271
+ ) || 0
3272
+ );
3273
+ const previousMainSelling = new import_decimal.default(
3274
+ Number(
3275
+ ((_s = targetProduct.metadata) == null ? void 0 : _s.main_product_selling_price) ?? targetProduct.selling_price ?? previousMainOriginal.toNumber()
3276
+ ) || 0
3277
+ );
3278
+ const preservedDiscount = previousMainOriginal.minus(previousMainSelling);
3279
+ 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);
3280
+ const nextMainOriginal = previousSource.plus(nextOptionSum);
3281
+ nextProduct.metadata = {
3282
+ ...nextProduct.metadata || {},
3283
+ source_product_price: previousSource.toDecimalPlaces(2).toFixed(2),
3284
+ main_product_original_price: nextMainOriginal.toDecimalPlaces(2).toFixed(2),
3285
+ main_product_selling_price: nextMainOriginal.minus(preservedDiscount).toDecimalPlaces(2).toFixed(2),
3286
+ price_schema_version: 2
3287
+ };
3073
3288
  } else if (callerUpdatesTopPrice && !callerUpdatesMainMeta) {
3074
3289
  const existedMeta = nextProduct.metadata || {};
3075
3290
  nextProduct.metadata = { ...existedMeta };
@@ -3085,7 +3300,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3085
3300
  normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
3086
3301
  normalizedProduct.discount_list
3087
3302
  );
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);
3303
+ 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
3304
  if (!booking && preservedBookingUid) {
3090
3305
  normalizedProduct.booking_uid = preservedBookingUid;
3091
3306
  normalizedProduct.metadata = {
@@ -3095,7 +3310,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3095
3310
  }
3096
3311
  if (booking) {
3097
3312
  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)()
3313
+ ((_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
3314
  );
3100
3315
  normalizedProduct.metadata = {
3101
3316
  ...normalizedProduct.metadata || {},
@@ -3126,14 +3341,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3126
3341
  tempOrder,
3127
3342
  updates,
3128
3343
  tempOrder.products[productIndex],
3129
- (_q = tempOrder.products[productIndex].metadata) == null ? void 0 : _q.unique_identification_number
3344
+ (_y = tempOrder.products[productIndex].metadata) == null ? void 0 : _y.unique_identification_number
3130
3345
  );
3346
+ return (_z = tempOrder.products[productIndex].metadata) == null ? void 0 : _z.unique_identification_number;
3131
3347
  }
3132
3348
  async updateOrderProduct(params) {
3133
3349
  const tempOrder = this.ensureTempOrder();
3134
- this.applyOrderProductUpdateToTempOrder(tempOrder, params);
3350
+ const updatedProductUid = this.applyOrderProductUpdateToTempOrder(tempOrder, params);
3135
3351
  await this.applyPromotion();
3136
- this.applyDiscount();
3352
+ this.applyDiscount({
3353
+ reapplyBookingDiscountProductUids: params.allow_booking_discount_reapply && updatedProductUid ? [String(updatedProductUid)] : void 0
3354
+ });
3137
3355
  this.sanitizeTempOrderProducts(tempOrder);
3138
3356
  await this.recalculateSummary({ createIfMissing: true });
3139
3357
  this.persistTempOrder();
@@ -3147,10 +3365,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3147
3365
  if (!paramsList.length) {
3148
3366
  return tempOrder.products;
3149
3367
  }
3150
- paramsList.forEach((params) => {
3151
- this.applyOrderProductUpdateToTempOrder(tempOrder, params);
3368
+ const reapplyBookingDiscountProductUids = paramsList.reduce((acc, params) => {
3369
+ const updatedProductUid = this.applyOrderProductUpdateToTempOrder(tempOrder, params);
3370
+ if (params.allow_booking_discount_reapply && updatedProductUid) {
3371
+ acc.push(String(updatedProductUid));
3372
+ }
3373
+ return acc;
3374
+ }, []);
3375
+ await this.finalizeAfterProductsMutation(tempOrder, {
3376
+ reapplyBookingDiscountProductUids: reapplyBookingDiscountProductUids.length ? reapplyBookingDiscountProductUids : void 0
3152
3377
  });
3153
- await this.finalizeAfterProductsMutation(tempOrder);
3154
3378
  this.logInfo("updateOrderProduct success", {
3155
3379
  paramsList
3156
3380
  });
@@ -3259,10 +3483,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3259
3483
  * @example
3260
3484
  * await this.finalizeAfterProductsMutation(tempOrder);
3261
3485
  */
3262
- async finalizeAfterProductsMutation(tempOrder) {
3486
+ async finalizeAfterProductsMutation(tempOrder, options) {
3263
3487
  this.syncTempOrderHolderFromBookings(tempOrder);
3264
3488
  await this.applyPromotion();
3265
- this.applyDiscount();
3489
+ this.applyDiscount({
3490
+ reapplyBookingDiscountProductUids: options == null ? void 0 : options.reapplyBookingDiscountProductUids
3491
+ });
3266
3492
  this.sanitizeTempOrderProducts(tempOrder);
3267
3493
  await this.recalculateSummary({ createIfMissing: true });
3268
3494
  this.persistTempOrder();
@@ -3393,6 +3619,38 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3393
3619
  await this.saveDraft();
3394
3620
  return tempOrder;
3395
3621
  }
3622
+ async saveTempOrderAsDraft(params) {
3623
+ var _a, _b, _c, _d, _e;
3624
+ const tempOrder = this.ensureTempOrder();
3625
+ this.ensureExternalSaleNumber(tempOrder);
3626
+ this.persistTempOrder();
3627
+ const latestSummary = await this.recalculateSummary({ createIfMissing: true }) || this.store.summary || (0, import_utils.createEmptySummary)();
3628
+ const payload = (0, import_utils.buildSubmitPayload)({
3629
+ tempOrder,
3630
+ cacheId: (params == null ? void 0 : params.cacheId) ?? this.cacheId,
3631
+ platform: (params == null ? void 0 : params.platform) || ((_a = this.otherParams) == null ? void 0 : _a.platform),
3632
+ businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
3633
+ channel: params == null ? void 0 : params.channel,
3634
+ type: (params == null ? void 0 : params.type) ?? ((_d = this.otherParams) == null ? void 0 : _d.type),
3635
+ summary: latestSummary,
3636
+ enhance: params == null ? void 0 : params.enhancePayload
3637
+ });
3638
+ if (!payload.created_at) {
3639
+ payload.created_at = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
3640
+ }
3641
+ payload.need_sync = 0;
3642
+ payload.is_draft_order = 1;
3643
+ this.logInfo("saveTempOrderAsDraft calling sales draft", {
3644
+ orderId: payload.order_id,
3645
+ externalSaleNumber: payload.external_sale_number,
3646
+ productsCount: ((_e = payload.products) == null ? void 0 : _e.length) || 0
3647
+ });
3648
+ return this.request.post("/order/sales/draft", payload, {
3649
+ osServer: true,
3650
+ customToast: () => {
3651
+ }
3652
+ });
3653
+ }
3396
3654
  /**
3397
3655
  * 提交当前 Sales tempOrder。
3398
3656
  *
@@ -3593,14 +3851,19 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3593
3851
  }
3594
3852
  async syncPaymentsToOrder(params) {
3595
3853
  const tempOrder = this.ensureTempOrder();
3854
+ const needsPaymentNumber = (params.payments || []).some((payment) => String(payment.payment_number || "").trim() === "");
3855
+ const devicePrefix = needsPaymentNumber ? await this.getPaymentNumberDevicePrefixAsync() : "LOCAL";
3596
3856
  const mappedPayments = (0, import_utils.mapPaymentItemsToOrderPayments)(
3597
- params.payments || []
3857
+ (params.payments || []).map((payment) => this.normalizePaymentSource(payment, {
3858
+ defaultPaid: false,
3859
+ devicePrefix
3860
+ }))
3598
3861
  );
3599
3862
  const shouldConfirmPendingVoucherPayments = params.confirmPendingVoucherPayments ?? params.submitWhenPaid === true;
3600
3863
  const effectivePayments = shouldConfirmPendingVoucherPayments ? this.confirmPendingVoucherPaymentsInList(mappedPayments) : params.confirmPendingVoucherPayments === false ? this.discardPendingVoucherPaymentsFromList(mappedPayments) : mappedPayments;
3601
3864
  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";
3865
+ const orderPaidPaymentTotal = this.calculateOrderPaidPaymentTotal(effectivePayments);
3866
+ const paymentStatus = completion.isOrderFullyPaid ? params.paymentStatus || "paid" : orderPaidPaymentTotal.gt(0) ? "partially_paid" : "payment_processing";
3604
3867
  tempOrder.payments = effectivePayments;
3605
3868
  tempOrder.payment_status = paymentStatus;
3606
3869
  this.persistTempOrder();
@@ -3940,8 +4203,42 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3940
4203
  */
3941
4204
  async hydrateTempOrderFromRecord(record, options) {
3942
4205
  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);
4206
+ const sourceRaw = record && typeof record === "object" && record.data && record.order_id == null ? record.data : record || {};
4207
+ const identityReadySource = this.seedAnonymousBookingUidsFromProducts(
4208
+ sourceRaw
4209
+ );
4210
+ const normalizedCollections = (0, import_orderCollectionIdentity.normalizeOrderCollections)(identityReadySource);
4211
+ const raw = normalizedCollections.order;
4212
+ const hasIdentityChanges = Object.values(normalizedCollections.stats).some(
4213
+ (stats) => stats.backfilledUidCount > 0 || stats.collapsedDuplicateCount > 0 || stats.uidConflictCount > 0 || stats.anonymousRowCount > 0
4214
+ );
4215
+ if (hasIdentityChanges) {
4216
+ const identityLogMetadata = {
4217
+ collections: normalizedCollections.stats,
4218
+ uidRemapCount: normalizedCollections.uidRemaps.length
4219
+ };
4220
+ const hasIdentityWarnings = Object.values(normalizedCollections.stats).some(
4221
+ (stats) => stats.uidConflictCount > 0 || stats.anonymousRowCount > 0
4222
+ );
4223
+ if (hasIdentityWarnings) {
4224
+ this.logWarning(
4225
+ "Normalized hydrated order collection identities",
4226
+ identityLogMetadata
4227
+ );
4228
+ } else {
4229
+ this.logInfo(
4230
+ "Normalized hydrated order collection identities",
4231
+ identityLogMetadata
4232
+ );
4233
+ }
4234
+ }
4235
+ const nextTempOrder = this.normalizeTempOrderForRuntime(raw, { makeEditMark: true });
4236
+ const sourceLastOrderInfo = raw.lastOrderInfo || raw;
4237
+ const isDraftOrder = Number(nextTempOrder.is_draft_order || 0) === 1;
4238
+ const syntheticIdentityOptions = {
4239
+ isDraftOrder,
4240
+ externalSaleNumber: nextTempOrder.external_sale_number
4241
+ };
3945
4242
  const rawSummary = raw.summary && typeof raw.summary === "object" ? raw.summary : {};
3946
4243
  const summarySurcharges = Array.isArray(rawSummary.surcharges) ? rawSummary.surcharges.map((s) => ({ ...s || {} })) : (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []);
3947
4244
  this.store.tempOrder = nextTempOrder;
@@ -3955,23 +4252,42 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3955
4252
  originalSalesSnapshot: {
3956
4253
  summary: (0, import_lodash_es.cloneDeep)(this.store.summary),
3957
4254
  products: (0, import_lodash_es.cloneDeep)(nextTempOrder.products || []),
4255
+ bookings: (0, import_lodash_es.cloneDeep)(nextTempOrder.bookings || []),
3958
4256
  payments: (0, import_lodash_es.cloneDeep)(nextTempOrder.payments || []),
3959
4257
  surcharges: (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []),
3960
4258
  shop_discount: nextTempOrder.shop_discount || "0.00",
3961
4259
  productFingerprint: this.buildOrderProductsFingerprint(nextTempOrder.products || [])
3962
4260
  }
3963
4261
  };
3964
- this.store.lastOrderInfo = raw.lastOrderInfo || raw;
4262
+ this.store.lastOrderInfo = this.withoutSyntheticDraftOrderIdForRuntime(
4263
+ sourceLastOrderInfo,
4264
+ syntheticIdentityOptions
4265
+ );
4266
+ const hadSyntheticDraftOrderId = this.isSyntheticDraftOrderIdForRuntime(raw, syntheticIdentityOptions) || this.isSyntheticDraftOrderIdForRuntime(sourceLastOrderInfo, syntheticIdentityOptions);
4267
+ if (hadSyntheticDraftOrderId && this.store.syncState !== "submitting") {
4268
+ this.store.syncState = "local";
4269
+ }
3965
4270
  const hydratedEditDiscounts = this.collectHydratedEditDiscounts(nextTempOrder.products);
3966
4271
  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;
4272
+ const currentScanDiscounts = currentDiscounts.filter((discount) => discount == null ? void 0 : discount.isScan);
4273
+ const hydratedDiscountIds = new Set(
4274
+ hydratedEditDiscounts.map((discount) => discount == null ? void 0 : discount.id)
4275
+ );
4276
+ const retainedScanDiscounts = currentScanDiscounts.filter(
4277
+ (discount) => !hydratedDiscountIds.has(discount == null ? void 0 : discount.id)
4278
+ );
4279
+ const nextDiscounts = [
4280
+ ...hydratedEditDiscounts,
4281
+ ...retainedScanDiscounts
4282
+ ];
4283
+ const shouldSkipEmptyDiscountSync = nextDiscounts.length === 0 && currentDiscounts.length === 0;
3968
4284
  if (!shouldSkipEmptyDiscountSync) {
3969
4285
  OrderModule.populateSavedAmounts(
3970
4286
  nextTempOrder.products,
3971
- hydratedEditDiscounts
4287
+ nextDiscounts
3972
4288
  );
3973
- await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(hydratedEditDiscounts));
3974
- await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(hydratedEditDiscounts));
4289
+ await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(nextDiscounts));
4290
+ await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(nextDiscounts));
3975
4291
  }
3976
4292
  if (options == null ? void 0 : options.recalcOnHydrate) {
3977
4293
  await this.recalculateSummary({ createIfMissing: false });
@@ -4003,14 +4319,73 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4003
4319
  }
4004
4320
  return next;
4005
4321
  }
4322
+ /**
4323
+ * 匿名 booking 没有服务端行 ID 时,商品侧已有的 booking_uid 就是唯一可用的强引用。
4324
+ * 在统一规范化生成 UUID 前先复用它;已落库 booking 仍按 schedule_event_id 派生稳定 UID。
4325
+ */
4326
+ seedAnonymousBookingUidsFromProducts(raw) {
4327
+ var _a, _b;
4328
+ if (!raw || typeof raw !== "object")
4329
+ return {};
4330
+ if (!Array.isArray(raw.bookings) || !Array.isArray(raw.products))
4331
+ return raw;
4332
+ const bookingUidsByProductUid = /* @__PURE__ */ new Map();
4333
+ for (const product of raw.products) {
4334
+ const productUid = (0, import_orderCollectionIdentity.getOrderCollectionUid)("product", product);
4335
+ const bookingUid = (product == null ? void 0 : product.booking_uid) || ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.booking_uid);
4336
+ if (!productUid || bookingUid === void 0 || bookingUid === null || bookingUid === "") {
4337
+ continue;
4338
+ }
4339
+ const candidates = bookingUidsByProductUid.get(productUid) || /* @__PURE__ */ new Set();
4340
+ candidates.add(String(bookingUid));
4341
+ bookingUidsByProductUid.set(productUid, candidates);
4342
+ }
4343
+ if (bookingUidsByProductUid.size === 0)
4344
+ return raw;
4345
+ const anonymousBookingCountByProductUid = /* @__PURE__ */ new Map();
4346
+ for (const booking of raw.bookings) {
4347
+ if ((0, import_orderCollectionIdentity.getOrderCollectionPersistentId)("booking", booking) || (0, import_orderCollectionIdentity.getOrderCollectionUid)("booking", booking)) {
4348
+ continue;
4349
+ }
4350
+ const productUid = (booking == null ? void 0 : booking.product_uid) || ((_b = booking == null ? void 0 : booking.metadata) == null ? void 0 : _b.product_uid);
4351
+ if (productUid === void 0 || productUid === null || productUid === "")
4352
+ continue;
4353
+ const key = String(productUid);
4354
+ anonymousBookingCountByProductUid.set(
4355
+ key,
4356
+ (anonymousBookingCountByProductUid.get(key) || 0) + 1
4357
+ );
4358
+ }
4359
+ return {
4360
+ ...raw,
4361
+ bookings: raw.bookings.map((booking) => {
4362
+ var _a2;
4363
+ if ((0, import_orderCollectionIdentity.getOrderCollectionPersistentId)("booking", booking) || (0, import_orderCollectionIdentity.getOrderCollectionUid)("booking", booking)) {
4364
+ return booking;
4365
+ }
4366
+ const productUid = (booking == null ? void 0 : booking.product_uid) || ((_a2 = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a2.product_uid);
4367
+ if (productUid === void 0 || productUid === null || productUid === "") {
4368
+ return booking;
4369
+ }
4370
+ const productUidKey = String(productUid);
4371
+ if (anonymousBookingCountByProductUid.get(productUidKey) !== 1) {
4372
+ return booking;
4373
+ }
4374
+ const bookingUidCandidates = bookingUidsByProductUid.get(productUidKey);
4375
+ const bookingUid = (bookingUidCandidates == null ? void 0 : bookingUidCandidates.size) === 1 ? [...bookingUidCandidates][0] : null;
4376
+ return bookingUid ? (0, import_orderCollectionIdentity.setOrderCollectionUid)("booking", booking, bookingUid) : booking;
4377
+ })
4378
+ };
4379
+ }
4006
4380
  normalizeTempOrderForRuntime(raw, options) {
4007
4381
  var _a, _b;
4382
+ const runtimeRaw = this.withoutSyntheticDraftOrderIdForRuntime(raw);
4008
4383
  const nextTempOrder = {
4009
4384
  ...this.createDefaultTempOrderInstance(),
4010
- ...raw || {}
4385
+ ...runtimeRaw || {}
4011
4386
  };
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;
4387
+ 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) {
4388
+ nextTempOrder.order_id = runtimeRaw.id;
4014
4389
  }
4015
4390
  delete nextTempOrder.summary;
4016
4391
  delete nextTempOrder.lastOrderInfo;
@@ -4028,7 +4403,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4028
4403
  nextTempOrder.metadata = raw.metadata && typeof raw.metadata === "object" ? { ...raw.metadata } : {};
4029
4404
  nextTempOrder.holder = raw.holder && typeof raw.holder === "object" ? { ...raw.holder } : null;
4030
4405
  const rawProducts = Array.isArray(raw.products) ? raw.products : [];
4031
- nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map((p) => this.normalizeHydratedOrderProduct(p)) : [];
4406
+ nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map((p) => this.normalizeHydratedOrderProduct(p, { makeEditMark: options == null ? void 0 : options.makeEditMark })) : [];
4032
4407
  nextTempOrder.bookings = Array.isArray(raw.bookings) ? raw.bookings.map((b) => {
4033
4408
  const booking = this.normalizeHydratedBookingHolder(b || {});
4034
4409
  return {
@@ -4078,6 +4453,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4078
4453
  nextTempOrder.vouchers = raw.vouchers || [];
4079
4454
  return nextTempOrder;
4080
4455
  }
4456
+ isSyntheticDraftOrderIdForRuntime(record, options) {
4457
+ const isDraftOrder = (options == null ? void 0 : options.isDraftOrder) ?? Number((record == null ? void 0 : record.is_draft_order) || 0) === 1;
4458
+ const externalSaleNumber = (record == null ? void 0 : record.external_sale_number) ?? (options == null ? void 0 : options.externalSaleNumber);
4459
+ const orderId = record == null ? void 0 : record.order_id;
4460
+ return Boolean(
4461
+ isDraftOrder && orderId !== void 0 && orderId !== null && orderId !== "" && externalSaleNumber !== void 0 && externalSaleNumber !== null && externalSaleNumber !== "" && String(orderId) === String(externalSaleNumber)
4462
+ );
4463
+ }
4464
+ withoutSyntheticDraftOrderIdForRuntime(record, options) {
4465
+ if (!this.isSyntheticDraftOrderIdForRuntime(record, options))
4466
+ return record;
4467
+ return {
4468
+ ...record,
4469
+ order_id: null
4470
+ };
4471
+ }
4081
4472
  hydrateLinkedBookingIdentity(tempOrder) {
4082
4473
  const bookingUidByProductUid = /* @__PURE__ */ new Map();
4083
4474
  const productByUid = /* @__PURE__ */ new Map();
@@ -4117,9 +4508,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4117
4508
  if (!product.metadata || typeof product.metadata !== "object") {
4118
4509
  product.metadata = {};
4119
4510
  }
4120
- const linkedBookingUid = String(
4121
- product.booking_uid || product.metadata.booking_uid || bookingUid
4122
- );
4511
+ const linkedBookingUid = String(bookingUid);
4123
4512
  product.booking_uid = linkedBookingUid;
4124
4513
  product.metadata.booking_uid = linkedBookingUid;
4125
4514
  });
@@ -4174,7 +4563,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4174
4563
  normalized.id = optionItem.id;
4175
4564
  return normalized;
4176
4565
  }
4177
- normalizeHydratedOrderProduct(product) {
4566
+ normalizeHydratedOrderProduct(product, options) {
4178
4567
  let row = { ...product || {} };
4179
4568
  if (row.num === void 0 && row.product_quantity !== void 0) {
4180
4569
  row.num = row.product_quantity;
@@ -4201,6 +4590,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4201
4590
  if (!existingIdentity) {
4202
4591
  row.metadata.unique_identification_number = (0, import_utils.createUuidV4)();
4203
4592
  }
4593
+ if (options == null ? void 0 : options.makeEditMark) {
4594
+ row.metadata.is_edit_for_runtime = true;
4595
+ }
4204
4596
  const normalized = (0, import_utils3.normalizeOrderProduct)(row);
4205
4597
  normalized.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
4206
4598
  normalized.discount_list