@pisell/pisellos 2.2.260 → 2.2.262

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 (107) hide show
  1. package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +1 -0
  2. package/dist/model/strategy/adapter/dataVariant/adapter.js +15 -0
  3. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +2 -0
  4. package/dist/model/strategy/adapter/dataVariant/evaluator.js +25 -0
  5. package/dist/model/strategy/adapter/dataVariant/examples.js +1 -6
  6. package/dist/model/strategy/adapter/dataVariant/type.d.ts +2 -0
  7. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  8. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +23 -13
  9. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  10. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  11. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +32 -1
  12. package/dist/modules/Discount/index.d.ts +5 -2
  13. package/dist/modules/Discount/index.js +30 -7
  14. package/dist/modules/Discount/types.d.ts +4 -0
  15. package/dist/modules/Order/index.d.ts +45 -2
  16. package/dist/modules/Order/index.js +1552 -926
  17. package/dist/modules/Order/types.d.ts +36 -2
  18. package/dist/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  19. package/dist/modules/Order/utils/bundleDiscountHydration.js +144 -0
  20. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  21. package/dist/modules/Order/utils/orderCollectionIdentity.js +405 -0
  22. package/dist/modules/Order/utils.d.ts +8 -3
  23. package/dist/modules/Order/utils.js +136 -56
  24. package/dist/modules/Rules/index.d.ts +4 -10
  25. package/dist/modules/Rules/index.js +63 -12
  26. package/dist/modules/Rules/types.d.ts +12 -2
  27. package/dist/modules/SalesSummary/index.d.ts +7 -3
  28. package/dist/modules/SalesSummary/index.js +67 -39
  29. package/dist/modules/SalesSummary/types.d.ts +1 -0
  30. package/dist/modules/SalesSummary/utils.js +2 -1
  31. package/dist/modules/SurchargeList/index.d.ts +6 -4
  32. package/dist/modules/SurchargeList/index.js +62 -39
  33. package/dist/modules/SurchargeList/types.d.ts +6 -2
  34. package/dist/server/index.d.ts +8 -0
  35. package/dist/server/index.js +1365 -911
  36. package/dist/server/modules/order/index.d.ts +32 -7
  37. package/dist/server/modules/order/index.js +551 -464
  38. package/dist/server/modules/order/types.d.ts +4 -0
  39. package/dist/server/modules/products/index.d.ts +5 -1
  40. package/dist/server/modules/products/index.js +384 -315
  41. package/dist/server/modules/products/types.d.ts +4 -0
  42. package/dist/solution/BaseSales/index.d.ts +42 -2
  43. package/dist/solution/BaseSales/index.js +1416 -775
  44. package/dist/solution/BaseSales/types.d.ts +7 -1
  45. package/dist/solution/BaseSales/types.js +3 -2
  46. package/dist/solution/BaseSales/utils/cartPromotion.js +19 -7
  47. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -3
  48. package/dist/solution/BaseSales/utils/parseSalesResponse.js +6 -8
  49. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +20 -4
  50. package/dist/solution/BookingByStep/index.d.ts +1 -1
  51. package/dist/solution/BookingTicket/index.d.ts +8 -0
  52. package/dist/solution/BookingTicket/index.js +212 -31
  53. package/dist/solution/ShopDiscount/index.js +15 -14
  54. package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +1 -0
  55. package/lib/model/strategy/adapter/dataVariant/adapter.js +10 -0
  56. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +2 -0
  57. package/lib/model/strategy/adapter/dataVariant/evaluator.js +20 -1
  58. package/lib/model/strategy/adapter/dataVariant/examples.js +0 -2
  59. package/lib/model/strategy/adapter/dataVariant/type.d.ts +2 -0
  60. package/lib/model/strategy/adapter/promotion/index.js +0 -49
  61. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +16 -1
  62. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +1 -0
  63. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  64. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +23 -2
  65. package/lib/modules/Discount/index.d.ts +5 -2
  66. package/lib/modules/Discount/index.js +23 -3
  67. package/lib/modules/Discount/types.d.ts +4 -0
  68. package/lib/modules/Order/index.d.ts +45 -2
  69. package/lib/modules/Order/index.js +720 -116
  70. package/lib/modules/Order/types.d.ts +36 -2
  71. package/lib/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  72. package/lib/modules/Order/utils/bundleDiscountHydration.js +139 -0
  73. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  74. package/lib/modules/Order/utils/orderCollectionIdentity.js +415 -0
  75. package/lib/modules/Order/utils.d.ts +8 -3
  76. package/lib/modules/Order/utils.js +104 -18
  77. package/lib/modules/Rules/index.d.ts +4 -10
  78. package/lib/modules/Rules/index.js +61 -9
  79. package/lib/modules/Rules/types.d.ts +12 -2
  80. package/lib/modules/SalesSummary/index.d.ts +7 -3
  81. package/lib/modules/SalesSummary/index.js +28 -11
  82. package/lib/modules/SalesSummary/types.d.ts +1 -0
  83. package/lib/modules/SalesSummary/utils.js +2 -0
  84. package/lib/modules/SurchargeList/index.d.ts +6 -4
  85. package/lib/modules/SurchargeList/index.js +41 -21
  86. package/lib/modules/SurchargeList/types.d.ts +6 -2
  87. package/lib/server/index.d.ts +8 -0
  88. package/lib/server/index.js +336 -11
  89. package/lib/server/modules/order/index.d.ts +32 -7
  90. package/lib/server/modules/order/index.js +298 -189
  91. package/lib/server/modules/order/types.d.ts +4 -0
  92. package/lib/server/modules/products/index.d.ts +5 -1
  93. package/lib/server/modules/products/index.js +21 -0
  94. package/lib/server/modules/products/types.d.ts +4 -0
  95. package/lib/solution/BaseSales/index.d.ts +42 -2
  96. package/lib/solution/BaseSales/index.js +535 -108
  97. package/lib/solution/BaseSales/types.d.ts +7 -1
  98. package/lib/solution/BaseSales/types.js +2 -1
  99. package/lib/solution/BaseSales/utils/cartPromotion.js +13 -1
  100. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -3
  101. package/lib/solution/BaseSales/utils/parseSalesResponse.js +4 -5
  102. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -6
  103. package/lib/solution/BookingByStep/index.d.ts +1 -1
  104. package/lib/solution/BookingTicket/index.d.ts +8 -0
  105. package/lib/solution/BookingTicket/index.js +134 -8
  106. package/lib/solution/ShopDiscount/index.js +2 -1
  107. package/package.json +1 -1
@@ -40,6 +40,8 @@ var import_dayjs = __toESM(require("dayjs"));
40
40
  var import_cartPromotion = require("../../solution/BaseSales/utils/cartPromotion");
41
41
  var import_utils3 = require("../../solution/ScanOrder/utils");
42
42
  var import_manualProductDiscount = require("./utils/manualProductDiscount");
43
+ var import_bundleDiscountHydration = require("./utils/bundleDiscountHydration");
44
+ var import_orderCollectionIdentity = require("./utils/orderCollectionIdentity");
43
45
  var import_Discount = require("../Discount");
44
46
  var import_Rules = require("../Rules");
45
47
  var import_types2 = require("../Rules/types");
@@ -64,6 +66,23 @@ function isManualProductDiscountProduct(product) {
64
66
  var _a, _b;
65
67
  return ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.is_manual_discount) === true || ((_b = product == null ? void 0 : product.metadata) == null ? void 0 : _b.is_manual_discount) === 1 || ((product == null ? void 0 : product.discount_list) || []).some((item) => (item == null ? void 0 : item.type) === "product");
66
68
  }
69
+ var ORDER_PAYMENT_STATUS_PAID = "paid";
70
+ var ORDER_PAYMENT_STATUS_PENDING = "payment_pending";
71
+ function isVoucherPaymentRecord(payment) {
72
+ return (payment == null ? void 0 : payment.voucher_id) !== void 0 && Number(payment.voucher_id) !== 0;
73
+ }
74
+ function hasSyncedOrderPaymentRecord(payment) {
75
+ return (payment == null ? void 0 : payment.order_payment_id) !== void 0 && payment.order_payment_id !== null;
76
+ }
77
+ function isPendingVoucherPaymentRecord(payment) {
78
+ return isVoucherPaymentRecord(payment) && (payment == null ? void 0 : payment.status) === ORDER_PAYMENT_STATUS_PENDING;
79
+ }
80
+ function isPaidPaymentRecord(payment) {
81
+ return (payment == null ? void 0 : payment.status) === ORDER_PAYMENT_STATUS_PAID;
82
+ }
83
+ function isCommittedVoucherPaymentRecord(payment) {
84
+ return isVoucherPaymentRecord(payment) && (payment == null ? void 0 : payment.status) !== "voided" && (hasSyncedOrderPaymentRecord(payment) || isPaidPaymentRecord(payment));
85
+ }
67
86
  var OrderModule = class extends import_BaseModule.BaseModule {
68
87
  constructor(name, version) {
69
88
  super(name || "order", version);
@@ -89,9 +108,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
89
108
  this.draftPersistEnabled = true;
90
109
  }
91
110
  collectHydratedEditDiscounts(products) {
92
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
111
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
93
112
  const discountMap = /* @__PURE__ */ new Map();
94
- for (const product of products || []) {
113
+ for (const product of (0, import_bundleDiscountHydration.expandHydratedProductsForDiscountCollection)(products)) {
95
114
  for (const item of (product == null ? void 0 : product.discount_list) || []) {
96
115
  const type = (item == null ? void 0 : item.type) ?? (item == null ? void 0 : item.tag);
97
116
  if (!type || type === "product")
@@ -114,15 +133,37 @@ var OrderModule = class extends import_BaseModule.BaseModule {
114
133
  discount: item == null ? void 0 : item.discount,
115
134
  _num: Number(((_e = item == null ? void 0 : item.metadata) == null ? void 0 : _e.num) ?? (product == null ? void 0 : product.num) ?? (product == null ? void 0 : product.product_quantity) ?? 1) || 1
116
135
  };
136
+ const existed = discountMap.get(key);
137
+ if (existed) {
138
+ existed.amount = Number(existed.amount || 0) + amount;
139
+ existed.used_par_value = String(Number(existed.used_par_value || 0) + amount);
140
+ existed.balance = String(Number(existed.balance || 0) + amount);
141
+ const productIds = Array.isArray((_f = existed.limited_relation_product_data) == null ? void 0 : _f.product_ids) ? existed.limited_relation_product_data.product_ids : [];
142
+ if ((product == null ? void 0 : product.product_id) !== void 0 && (product == null ? void 0 : product.product_id) !== null && !productIds.includes(product.product_id)) {
143
+ existed.limited_relation_product_data = {
144
+ ...existed.limited_relation_product_data || {},
145
+ product_ids: [...productIds, product.product_id]
146
+ };
147
+ }
148
+ existed.applicableProductDetails = [
149
+ ...existed.applicableProductDetails || [],
150
+ detail
151
+ ];
152
+ existed.appliedProductDetails = [
153
+ ...existed.appliedProductDetails || [],
154
+ detail
155
+ ];
156
+ continue;
157
+ }
117
158
  discountMap.set(key, {
118
159
  id: key,
119
160
  product_name: "",
120
161
  encoded: "",
121
162
  code: "",
122
163
  tag: type,
123
- product_id: ((_f = item == null ? void 0 : item.discount) == null ? void 0 : _f.discount_product_id) ?? (product == null ? void 0 : product.product_id) ?? 0,
164
+ product_id: ((_g = item == null ? void 0 : item.discount) == null ? void 0 : _g.discount_product_id) ?? (product == null ? void 0 : product.product_id) ?? 0,
124
165
  relation_type: "",
125
- par_value: String(((_g = item == null ? void 0 : item.discount) == null ? void 0 : _g.original_amount) ?? (item == null ? void 0 : item.amount) ?? "0"),
166
+ par_value: String(((_h = item == null ? void 0 : item.discount) == null ? void 0 : _h.original_amount) ?? (item == null ? void 0 : item.amount) ?? "0"),
126
167
  used_par_value: String((item == null ? void 0 : item.amount) ?? "0"),
127
168
  limit_status: "enable",
128
169
  limited_relation_product_data: {
@@ -152,8 +193,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
152
193
  discount: {
153
194
  ...(item == null ? void 0 : item.discount) || {},
154
195
  resource_id: key,
155
- 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,
156
- discount_calculation_mode: ((_i = item == null ? void 0 : item.discount) == null ? void 0 : _i.discount_calculation_mode) ?? "item_level"
196
+ 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,
197
+ discount_calculation_mode: ((_j = item == null ? void 0 : item.discount) == null ? void 0 : _j.discount_calculation_mode) ?? "item_level"
157
198
  },
158
199
  applicableProductDetails: [detail],
159
200
  appliedProductDetails: [detail]
@@ -236,6 +277,21 @@ var OrderModule = class extends import_BaseModule.BaseModule {
236
277
  product.metadata.main_product_selling_price = newMainSellingPrice;
237
278
  product.metadata.price_schema_version = 2;
238
279
  }
280
+ if (Array.isArray(product.product_bundle)) {
281
+ product.product_bundle = product.product_bundle.map((bundle) => {
282
+ const hasBundleDiscount = Array.isArray(bundle == null ? void 0 : bundle.discount_list) && bundle.discount_list.length > 0;
283
+ if (hasBundleDiscount)
284
+ return bundle;
285
+ const restoredPrice = (bundle == null ? void 0 : bundle.original_price) ?? (bundle == null ? void 0 : bundle.product_price) ?? (bundle == null ? void 0 : bundle.price);
286
+ if (restoredPrice === void 0 || restoredPrice === null || restoredPrice === "")
287
+ return bundle;
288
+ return {
289
+ ...bundle,
290
+ price: restoredPrice,
291
+ bundle_selling_price: restoredPrice
292
+ };
293
+ });
294
+ }
239
295
  product.selling_price = (0, import_utils.composeLinePrice)({
240
296
  mainPrice: newMainSellingPrice,
241
297
  bundle: product.product_bundle
@@ -253,6 +309,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
253
309
  if (!this.store.summary) {
254
310
  this.store.summary = (0, import_utils.createEmptySummary)();
255
311
  }
312
+ if (!Array.isArray(this.store.availableWalletIds)) {
313
+ this.store.availableWalletIds = [];
314
+ }
256
315
  this.request = this.core.getPlugin("request");
257
316
  const appPlugin = this.core.getPlugin("app");
258
317
  if (!appPlugin) {
@@ -380,19 +439,30 @@ var OrderModule = class extends import_BaseModule.BaseModule {
380
439
  async loadDiscountConfig(params) {
381
440
  var _a, _b, _c, _d, _e, _f, _g;
382
441
  const orderId = params.orderId || ((_a = this.store.tempOrder) == null ? void 0 : _a.order_id) || void 0;
383
- const discountList = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
442
+ const prepareConfigResult = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
384
443
  customer_id: params.customerId,
385
444
  action: params.action || (orderId ? "edit" : "create"),
386
445
  with_good_pass: 1,
387
446
  with_discount_card: 1,
388
447
  with_wallet_pass_holder: 1,
448
+ with_available_wallet_flag: 1,
449
+ with_available_wallet_pass_flag: 1,
389
450
  request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
390
451
  ...orderId ? { order_id: orderId } : {}
391
452
  }));
453
+ const discountList = prepareConfigResult == null ? void 0 : prepareConfigResult.discountList;
454
+ this.store.availableWalletIds = (prepareConfigResult == null ? void 0 : prepareConfigResult.availableWalletIds) || [];
392
455
  if (discountList) {
393
- const currentEditDiscounts = (((_c = this.store.discount) == null ? void 0 : _c.getDiscountList()) || []).filter((discount) => discount == null ? void 0 : discount.isEditMode);
456
+ const currentDiscountList = ((_c = this.store.discount) == null ? void 0 : _c.getDiscountList()) || [];
457
+ const currentEditDiscounts = currentDiscountList.filter((discount) => discount == null ? void 0 : discount.isEditMode);
458
+ const currentScanDiscounts = currentDiscountList.filter((discount) => discount == null ? void 0 : discount.isScan);
459
+ const currentScanDiscountIds = new Set(
460
+ currentScanDiscounts.map((discount) => discount == null ? void 0 : discount.id)
461
+ );
394
462
  const runtimeDiscountIds = /* @__PURE__ */ new Set();
395
463
  const runtimeDiscounts = discountList.filter((discount) => {
464
+ if (currentScanDiscountIds.has(discount == null ? void 0 : discount.id))
465
+ return false;
396
466
  if (runtimeDiscountIds.has(discount == null ? void 0 : discount.id))
397
467
  return false;
398
468
  runtimeDiscountIds.add(discount == null ? void 0 : discount.id);
@@ -400,6 +470,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
400
470
  });
401
471
  const mergedDiscountList = [
402
472
  ...currentEditDiscounts,
473
+ ...currentScanDiscounts,
403
474
  ...runtimeDiscounts
404
475
  ];
405
476
  await ((_d = this.store.discount) == null ? void 0 : _d.setOriginalDiscountList(mergedDiscountList));
@@ -414,6 +485,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
414
485
  var _a;
415
486
  return ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList()) || [];
416
487
  }
488
+ getAvailableWalletIds() {
489
+ return Array.isArray(this.store.availableWalletIds) ? [...this.store.availableWalletIds] : [];
490
+ }
491
+ async syncScannedDiscountsToOriginalDiscountList(discountList) {
492
+ var _a, _b, _c, _d;
493
+ const scanDiscounts = (discountList || []).filter((discount) => discount == null ? void 0 : discount.isScan);
494
+ if (!scanDiscounts.length)
495
+ return;
496
+ const scanDiscountIds = new Set(scanDiscounts.map((discount) => discount == null ? void 0 : discount.id));
497
+ const originalDiscounts = ((_b = (_a = this.store.discount) == null ? void 0 : _a.getOriginalDiscountList) == null ? void 0 : _b.call(_a)) || [];
498
+ const nextOriginalDiscounts = [
499
+ ...scanDiscounts,
500
+ ...originalDiscounts.filter((discount) => !scanDiscountIds.has(discount == null ? void 0 : discount.id))
501
+ ];
502
+ await ((_d = (_c = this.store.discount) == null ? void 0 : _c.setOriginalDiscountList) == null ? void 0 : _d.call(_c, nextOriginalDiscounts));
503
+ }
417
504
  async ensureEditDiscountConfigForProductChange(tempOrder) {
418
505
  var _a, _b, _c, _d, _e, _f;
419
506
  const orderId = tempOrder.order_id;
@@ -434,7 +521,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
434
521
  });
435
522
  }
436
523
  async scanCode(code, customerId) {
437
- var _a, _b, _c, _d, _e;
524
+ var _a, _b, _c, _d;
438
525
  const resultDiscountWithReason = await ((_a = this.store.discount) == null ? void 0 : _a.batchSearch(code, { customerId })) || { discountList: [], unavailableReasonKey: null };
439
526
  const { discountList: resultDiscountList, unavailableReasonKey } = resultDiscountWithReason;
440
527
  const rulesModule = this.store.rules;
@@ -462,6 +549,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
462
549
  }));
463
550
  const currentSelected = this.getDiscountList().filter((n) => n.isSelected);
464
551
  if (currentSelected.length && currentSelected.some((n) => withScanList.some((m) => m.id === n.id))) {
552
+ await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
465
553
  return {
466
554
  type: "clientCalc",
467
555
  isAvailable: true,
@@ -470,18 +558,19 @@ var OrderModule = class extends import_BaseModule.BaseModule {
470
558
  };
471
559
  }
472
560
  const tempOrder = this.store.tempOrder;
473
- const holders = ((_b = tempOrder == null ? void 0 : tempOrder.holder) == null ? void 0 : _b.form_record_id) ? [{ form_record_id: tempOrder.holder.form_record_id }] : [];
561
+ const holders = ((_b = tempOrder == null ? void 0 : tempOrder.holder) == null ? void 0 : _b.form_record) || [];
474
562
  const { isAvailable, discountList: newDiscountList, unavailableReason } = rulesModule.isDiscountListAvailable({
475
563
  productList: (tempOrder == null ? void 0 : tempOrder.products) || [],
476
564
  oldDiscountList: this.getDiscountList(),
477
565
  newDiscountList: withScanList,
478
566
  orderTotalAmount: Number(((_c = this.store.summary) == null ? void 0 : _c.total_amount) || 0),
479
567
  holders,
480
- isFormSubject: !!((_d = tempOrder == null ? void 0 : tempOrder.holder) == null ? void 0 : _d.type) && tempOrder.holder.type === "form"
568
+ isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product)
481
569
  }) || { isAvailable: false, discountList: this.getDiscountList() };
482
570
  if (isAvailable && newDiscountList) {
483
- (_e = this.store.discount) == null ? void 0 : _e.setDiscountList(newDiscountList);
571
+ (_d = this.store.discount) == null ? void 0 : _d.setDiscountList(newDiscountList);
484
572
  this.applyDiscount();
573
+ await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
485
574
  }
486
575
  return {
487
576
  type: "clientCalc",
@@ -491,25 +580,28 @@ var OrderModule = class extends import_BaseModule.BaseModule {
491
580
  unavailableReason
492
581
  };
493
582
  }
494
- applyDiscount() {
495
- var _a, _b, _c, _d, _e;
583
+ applyDiscount(options) {
584
+ var _a, _b, _c;
496
585
  const tempOrder = this.store.tempOrder;
497
586
  if (!tempOrder)
498
587
  return;
588
+ this.syncLinkedBookingHoldersToProducts(tempOrder);
499
589
  delete tempOrder.discount_list;
500
- if (this.shouldSkipDiscountCalculation(tempOrder))
590
+ const discountList = ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList()) || [];
591
+ const shouldSkipDiscountCalculation = this.shouldSkipDiscountCalculation(tempOrder);
592
+ if (shouldSkipDiscountCalculation)
501
593
  return;
502
594
  const rulesModule = this.store.rules;
503
595
  if (!rulesModule)
504
596
  return;
505
- const discountList = ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList()) || [];
506
- const holders = ((_b = tempOrder.holder) == null ? void 0 : _b.form_record_id) ? [{ form_record_id: tempOrder.holder.form_record_id }] : [];
507
597
  const result = rulesModule.calcDiscount({
508
598
  productList: tempOrder.products,
509
599
  discountList,
510
- holders,
511
- isFormSubject: !!((_c = tempOrder.holder) == null ? void 0 : _c.type) && tempOrder.holder.type === "form",
512
- orderTotalAmount: Number(((_d = this.store.summary) == null ? void 0 : _d.total_amount) || 0)
600
+ holders: [],
601
+ isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
602
+ orderTotalAmount: Number(((_b = this.store.summary) == null ? void 0 : _b.total_amount) || 0)
603
+ }, {
604
+ reapplyBookingDiscountProductUids: options == null ? void 0 : options.reapplyBookingDiscountProductUids
513
605
  });
514
606
  if (result == null ? void 0 : result.productList) {
515
607
  const previousProductsByUid = (0, import_utils.indexOrderProductsByUid)(tempOrder.products);
@@ -538,7 +630,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
538
630
  result.productList || tempOrder.products,
539
631
  result.discountList
540
632
  );
541
- (_e = this.store.discount) == null ? void 0 : _e.setDiscountList(result.discountList);
633
+ (_c = this.store.discount) == null ? void 0 : _c.setDiscountList(result.discountList);
542
634
  }
543
635
  this.hasActiveCustomerBoundDiscount = (tempOrder.products || []).some(
544
636
  (product) => this.productHasCustomerBoundDiscount(product)
@@ -816,15 +908,53 @@ var OrderModule = class extends import_BaseModule.BaseModule {
816
908
  return (0, import_utils.mapPaymentItemsToOrderPayments)(payments, {
817
909
  includeVoided: false
818
910
  }).reduce((sum, payment) => {
911
+ if (!isPaidPaymentRecord(payment))
912
+ return sum;
819
913
  return sum.plus(this.calculatePaymentEffectiveAmount(payment));
820
914
  }, new import_decimal.default(0));
821
915
  }
916
+ calculateOrderPaidPaymentTotal(payments) {
917
+ return (0, import_utils.mapPaymentItemsToOrderPayments)(payments, {
918
+ includeVoided: false
919
+ }).reduce((sum, payment) => {
920
+ if (!isPaidPaymentRecord(payment))
921
+ return sum;
922
+ return sum.plus(this.calculatePaymentGapAmount(payment));
923
+ }, new import_decimal.default(0));
924
+ }
822
925
  getDepositAmount(tempOrder, summary) {
823
926
  return new import_decimal.default(summary.deposit_amount || tempOrder.deposit_amount || "0.00");
824
927
  }
825
928
  normalizeDepositAmount(amount) {
826
929
  return import_decimal.default.max(new import_decimal.default(Number(amount) || 0), 0).toDecimalPlaces(2).toFixed(2);
827
930
  }
931
+ getLastOrderDepositSnapshot() {
932
+ var _a;
933
+ const lastOrderInfo = this.store.lastOrderInfo;
934
+ if (!lastOrderInfo || typeof lastOrderInfo !== "object")
935
+ return null;
936
+ const rawDepositAmount = lastOrderInfo.deposit_amount ?? ((_a = lastOrderInfo.summary) == null ? void 0 : _a.deposit_amount);
937
+ const depositAmount = this.normalizeDepositAmount(rawDepositAmount ?? 0);
938
+ const hasDepositAmount = new import_decimal.default(depositAmount).gt(0);
939
+ const isDeposit = Number(lastOrderInfo.is_deposit) === 1 || hasDepositAmount;
940
+ if (!isDeposit || !hasDepositAmount)
941
+ return null;
942
+ return {
943
+ isDeposit: 1,
944
+ depositAmount
945
+ };
946
+ }
947
+ getLastOrderSubmitSnapshot() {
948
+ const lastOrderInfo = this.store.lastOrderInfo;
949
+ if (!lastOrderInfo || typeof lastOrderInfo !== "object")
950
+ return {};
951
+ const businessCode = lastOrderInfo.business_code;
952
+ const type = lastOrderInfo.type;
953
+ return {
954
+ ...typeof businessCode === "string" && businessCode ? { businessCode } : {},
955
+ ...typeof type === "string" && type ? { type } : {}
956
+ };
957
+ }
828
958
  applyDepositAmountToSummary(tempOrder, summary, amount) {
829
959
  const depositAmount = this.normalizeDepositAmount(amount);
830
960
  const hasDepositAmount = new import_decimal.default(depositAmount).gt(0);
@@ -843,8 +973,27 @@ var OrderModule = class extends import_BaseModule.BaseModule {
843
973
  tempOrder.is_deposit = hasDepositAmount ? 1 : 0;
844
974
  return nextSummary;
845
975
  }
976
+ applyLastOrderDepositSnapshot(tempOrder, summary) {
977
+ const snapshot = this.getLastOrderDepositSnapshot();
978
+ if (!snapshot)
979
+ return summary;
980
+ const existedDeposit = summary.deposit && typeof summary.deposit === "object" ? summary.deposit : void 0;
981
+ const nextSummary = {
982
+ ...summary,
983
+ deposit_amount: snapshot.depositAmount,
984
+ deposit: {
985
+ ...existedDeposit || {},
986
+ total: snapshot.depositAmount,
987
+ deposit_policy_ids: (existedDeposit == null ? void 0 : existedDeposit.deposit_policy_ids) || [],
988
+ hasDeposit: true
989
+ }
990
+ };
991
+ tempOrder.deposit_amount = snapshot.depositAmount;
992
+ tempOrder.is_deposit = tempOrder.is_deposit === 0 && new import_decimal.default(tempOrder.deposit_amount || 0).gt(0) ? 0 : snapshot.isDeposit;
993
+ return nextSummary;
994
+ }
846
995
  isDepositOrder(tempOrder, depositAmount) {
847
- return tempOrder.is_deposit === 1 || depositAmount.gt(0);
996
+ return tempOrder.is_deposit === 1 && depositAmount.gt(0);
848
997
  }
849
998
  getOrderExpectedAmount(summary) {
850
999
  return new import_decimal.default(summary.expect_amount || summary.total_amount || 0);
@@ -857,19 +1006,42 @@ var OrderModule = class extends import_BaseModule.BaseModule {
857
1006
  return false;
858
1007
  return params.paidAmount.gte(depositAmount);
859
1008
  }
1009
+ getPaymentCompletion(payments) {
1010
+ const tempOrder = this.ensureTempOrder();
1011
+ const summary = this.store.summary || (0, import_utils.createEmptySummary)();
1012
+ const paymentList = payments || tempOrder.payments || [];
1013
+ const refundAmount = this.getSummaryRefundAmount(summary);
1014
+ const netPaidAmount = import_decimal.default.max(
1015
+ this.calculateOrderPaidPaymentTotal(paymentList).minus(refundAmount),
1016
+ 0
1017
+ );
1018
+ const depositAmount = this.getDepositAmount(tempOrder, summary);
1019
+ const orderExpectedAmount = this.getOrderExpectedAmount(summary);
1020
+ const isDepositFullyPaid = this.isDepositCovered({
1021
+ tempOrder,
1022
+ summary,
1023
+ paidAmount: netPaidAmount
1024
+ });
1025
+ const isOrderFullyPaid = orderExpectedAmount.lte(0) ? true : netPaidAmount.gte(orderExpectedAmount);
1026
+ const paymentStage = this.isDepositOrder(tempOrder, depositAmount) && !isDepositFullyPaid ? "deposit" : "normal";
1027
+ return {
1028
+ isFullyPaid: isOrderFullyPaid,
1029
+ isOrderFullyPaid,
1030
+ isDepositFullyPaid,
1031
+ paymentStage,
1032
+ depositAmount: depositAmount.toFixed(2),
1033
+ orderExpectedAmount: orderExpectedAmount.toFixed(2)
1034
+ };
1035
+ }
860
1036
  calculateDepositPaidAmount(payments) {
861
1037
  return (payments || []).reduce((sum, payment) => {
862
1038
  const paymentRecord = payment;
863
- if ((paymentRecord == null ? void 0 : paymentRecord.status) !== "paid")
1039
+ if (!isPaidPaymentRecord(paymentRecord))
864
1040
  return sum;
865
1041
  const isDepositPayment = paymentRecord.type === "deposit" || paymentRecord.order_payment_type === "deposit";
866
1042
  if (!isDepositPayment)
867
1043
  return sum;
868
- if (paymentRecord.origin_amount !== void 0 && paymentRecord.origin_amount !== null && paymentRecord.origin_amount !== "") {
869
- return sum.plus(this.calculatePaymentGapAmount(paymentRecord));
870
- }
871
- const rounding = new import_decimal.default(paymentRecord.rounding_amount || 0);
872
- return sum.plus(new import_decimal.default(paymentRecord.amount || 0).minus(rounding));
1044
+ return sum.plus(this.calculatePaymentGapAmount(paymentRecord));
873
1045
  }, new import_decimal.default(0));
874
1046
  }
875
1047
  resolveNextOrderPaymentType(tempOrder) {
@@ -902,8 +1074,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
902
1074
  updateTempOrderPaymentStatus(tempOrder, options) {
903
1075
  const summary = (options == null ? void 0 : options.summary) || this.store.summary || (0, import_utils.createEmptySummary)();
904
1076
  const paymentTotal = this.calculatePaymentTotal(tempOrder.payments || []);
1077
+ const orderPaymentTotal = this.calculateOrderPaidPaymentTotal(tempOrder.payments || []);
905
1078
  const refundAmount = this.getSummaryRefundAmount(summary);
906
- const netPaymentTotal = import_decimal.default.max(paymentTotal.minus(refundAmount), 0);
1079
+ const netPaymentTotal = import_decimal.default.max(orderPaymentTotal.minus(refundAmount), 0);
907
1080
  const targetAmount = this.calculatePaymentTargetAmount(
908
1081
  tempOrder,
909
1082
  summary,
@@ -972,7 +1145,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
972
1145
  }
973
1146
  capVoucherPaymentsByRemainingAmount(params) {
974
1147
  const targetAmount = this.getPaymentTargetAmount();
975
- const nonVoucherTotal = this.calculatePaymentTotal(params.nonVoucherPayments);
1148
+ const nonVoucherTotal = this.calculateOrderPaidPaymentTotal(params.nonVoucherPayments);
976
1149
  if (targetAmount.lte(0))
977
1150
  return [];
978
1151
  let remainingAmount = import_decimal.default.max(
@@ -1011,11 +1184,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1011
1184
  return (payments || []).reduce(
1012
1185
  (summary, payment) => {
1013
1186
  const paymentRecord = payment;
1014
- if ((paymentRecord == null ? void 0 : paymentRecord.status) !== "paid")
1187
+ if (!isPaidPaymentRecord(paymentRecord))
1015
1188
  return summary;
1016
1189
  return {
1017
1190
  customerPaidAmount: summary.customerPaidAmount.plus(paymentRecord.amount || 0),
1018
- orderPaidAmount: summary.orderPaidAmount.plus(paymentRecord.origin_amount || 0),
1191
+ orderPaidAmount: summary.orderPaidAmount.plus(this.calculatePaymentOrderAmount(paymentRecord)),
1019
1192
  gapPaidAmount: summary.gapPaidAmount.plus(this.calculatePaymentGapAmount(paymentRecord)),
1020
1193
  payServiceChargeAmount: summary.payServiceChargeAmount.plus(this.calculatePaymentServiceFee(paymentRecord)),
1021
1194
  roundingAmount: summary.roundingAmount.plus(this.calculatePaymentRoundingAmount(paymentRecord))
@@ -1040,11 +1213,30 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1040
1213
  return new import_decimal.default(payment.amount || 0).times(percentage).plus(fixedAmount);
1041
1214
  }
1042
1215
  calculatePaymentGapAmount(payment) {
1043
- if (payment.origin_amount === void 0 || payment.origin_amount === null || payment.origin_amount === "") {
1044
- return new import_decimal.default(0);
1216
+ if (payment.origin_amount !== void 0 && payment.origin_amount !== null && payment.origin_amount !== "") {
1217
+ const rounding2 = new import_decimal.default(payment.rounding_amount || 0);
1218
+ return new import_decimal.default(payment.origin_amount || 0).minus(rounding2);
1045
1219
  }
1046
1220
  const rounding = new import_decimal.default(payment.rounding_amount || 0);
1047
- return new import_decimal.default(payment.origin_amount || 0).minus(rounding);
1221
+ const amount = new import_decimal.default(payment.amount || 0);
1222
+ const serviceFee = this.calculatePaymentServiceFee(payment);
1223
+ if (serviceFee.lte(0))
1224
+ return amount.minus(rounding);
1225
+ if (!hasSyncedOrderPaymentRecord(payment))
1226
+ return new import_decimal.default(0);
1227
+ return import_decimal.default.max(amount.minus(serviceFee), 0).minus(rounding);
1228
+ }
1229
+ calculatePaymentOrderAmount(payment) {
1230
+ if (payment.origin_amount !== void 0 && payment.origin_amount !== null && payment.origin_amount !== "") {
1231
+ return new import_decimal.default(payment.origin_amount || 0);
1232
+ }
1233
+ const amount = new import_decimal.default(payment.amount || 0);
1234
+ const serviceFee = this.calculatePaymentServiceFee(payment);
1235
+ if (serviceFee.lte(0))
1236
+ return amount;
1237
+ if (!hasSyncedOrderPaymentRecord(payment))
1238
+ return new import_decimal.default(0);
1239
+ return import_decimal.default.max(amount.minus(serviceFee), 0);
1048
1240
  }
1049
1241
  calculatePaymentRoundingAmount(payment) {
1050
1242
  if (payment.rounding_amount === void 0 || payment.rounding_amount === null || payment.rounding_amount === "") {
@@ -1345,11 +1537,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1345
1537
  });
1346
1538
  return currentAmountGap === snapshotAmountGap;
1347
1539
  }
1348
- restoreOriginalSnapshotIfProductsUnchanged(tempOrder) {
1349
- const snapshot = this.getOriginalSalesSnapshot(tempOrder);
1350
- if (!snapshot)
1351
- return null;
1540
+ hasShopDiscountChangedFromSnapshot(tempOrder, snapshot) {
1541
+ const snapshotSummary = snapshot.summary && typeof snapshot.summary === "object" ? snapshot.summary : {};
1542
+ const snapshotShopDiscount = snapshot.shop_discount ?? snapshotSummary.shop_discount;
1543
+ if (snapshotShopDiscount === void 0 || snapshotShopDiscount === null || snapshotShopDiscount === "") {
1544
+ return !new import_decimal.default(tempOrder.shop_discount || 0).equals(0);
1545
+ }
1546
+ return !new import_decimal.default(tempOrder.shop_discount || 0).equals(snapshotShopDiscount || 0);
1547
+ }
1548
+ restoreOriginalSnapshotIfProductsUnchanged(tempOrder, snapshot) {
1352
1549
  const currentFingerprint = this.buildOrderProductsFingerprint(tempOrder.products);
1550
+ const manualDepositOverride = this.getManualDepositOverride(tempOrder);
1353
1551
  if (currentFingerprint !== snapshot.productFingerprint) {
1354
1552
  const currentStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(tempOrder.products);
1355
1553
  const snapshotStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(
@@ -1358,11 +1556,24 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1358
1556
  if (currentStructuralFingerprint !== snapshotStructuralFingerprint)
1359
1557
  return null;
1360
1558
  }
1361
- const summary = {
1559
+ let summary = {
1362
1560
  ...(0, import_utils.createEmptySummary)(),
1363
1561
  ...(0, import_lodash_es.cloneDeep)(snapshot.summary || {})
1364
1562
  };
1365
- if (!this.isSnapshotPayableAmountUnchanged(tempOrder, snapshot, summary))
1563
+ const shouldUseManualDepositOverride = Boolean(
1564
+ manualDepositOverride && manualDepositOverride.productStructuralFingerprint === this.buildOrderProductsStructuralFingerprint(tempOrder.products)
1565
+ );
1566
+ if (shouldUseManualDepositOverride) {
1567
+ summary = this.applyDepositAmountToSummary(
1568
+ tempOrder,
1569
+ summary,
1570
+ manualDepositOverride.amount
1571
+ );
1572
+ } else if (manualDepositOverride) {
1573
+ this.clearManualDepositOverride(tempOrder);
1574
+ }
1575
+ const isPayableAmountUnchanged = this.isSnapshotPayableAmountUnchanged(tempOrder, snapshot, summary);
1576
+ if (!isPayableAmountUnchanged)
1366
1577
  return null;
1367
1578
  if (Array.isArray(snapshot.products)) {
1368
1579
  tempOrder.products = (0, import_lodash_es.cloneDeep)(snapshot.products);
@@ -1373,7 +1584,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1373
1584
  tempOrder.surcharge_fee = summary.surcharge_fee || tempOrder.surcharge_fee;
1374
1585
  tempOrder.deposit_amount = summary.deposit_amount || "0.00";
1375
1586
  tempOrder.is_deposit = summary.deposit_amount !== "0.00" ? 1 : 0;
1587
+ const previousSummary = this.store.summary;
1376
1588
  this.store.summary = summary;
1589
+ this.updateTempOrderPaymentStatus(tempOrder, {
1590
+ previousSummary,
1591
+ summary
1592
+ });
1377
1593
  return summary;
1378
1594
  }
1379
1595
  clearPersistedAmountFieldsForFullRecalc(products) {
@@ -1437,6 +1653,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1437
1653
  }
1438
1654
  restoreOrder() {
1439
1655
  var _a, _b;
1656
+ this.logInfo("restoreOrder start", {});
1440
1657
  const freshTempOrder = this.createDefaultTempOrderInstance();
1441
1658
  this.ensureExternalSaleNumber(freshTempOrder);
1442
1659
  this.store.tempOrder = freshTempOrder;
@@ -1515,7 +1732,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1515
1732
  orderPaidAmount: paidPaymentSummary.gapPaidAmount
1516
1733
  });
1517
1734
  return {
1518
- isDeposit: tempOrder.is_deposit === 1 || depositAmount !== "0.00",
1735
+ isDeposit: tempOrder.is_deposit === 1,
1519
1736
  depositAmount,
1520
1737
  expectAmount: summary.expect_amount || "0.00",
1521
1738
  totalAmount: summary.total_amount || "0.00",
@@ -1662,6 +1879,47 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1662
1879
  const records = Array.isArray(source) ? source : [source];
1663
1880
  return records.filter((record) => record !== void 0 && record !== null && record !== "");
1664
1881
  }
1882
+ setProductHolderFromBooking(product, booking) {
1883
+ if (!product || !booking)
1884
+ return;
1885
+ const holderRecords = this.collectBookingHolderRecords(booking);
1886
+ if (!product.metadata || typeof product.metadata !== "object") {
1887
+ product.metadata = {};
1888
+ }
1889
+ product.metadata.holder_id = holderRecords.length > 0 ? holderRecords : null;
1890
+ }
1891
+ syncLinkedBookingHoldersToProducts(tempOrder) {
1892
+ const bookings = tempOrder.bookings || [];
1893
+ const products = tempOrder.products || [];
1894
+ if (!bookings.length || !products.length)
1895
+ return;
1896
+ const bookingByProductUid = /* @__PURE__ */ new Map();
1897
+ const bookingByBookingUid = /* @__PURE__ */ new Map();
1898
+ bookings.forEach((booking) => {
1899
+ var _a, _b;
1900
+ if (!booking || typeof booking !== "object")
1901
+ return;
1902
+ const productUid = booking.product_uid || ((_a = booking.metadata) == null ? void 0 : _a.product_uid);
1903
+ if (productUid !== void 0 && productUid !== null && String(productUid) !== "") {
1904
+ bookingByProductUid.set(String(productUid), booking);
1905
+ }
1906
+ const bookingUid = ((_b = booking.metadata) == null ? void 0 : _b.unique_identification_number) || booking.booking_uid;
1907
+ if (bookingUid !== void 0 && bookingUid !== null && String(bookingUid) !== "") {
1908
+ bookingByBookingUid.set(String(bookingUid), booking);
1909
+ }
1910
+ });
1911
+ products.forEach((product) => {
1912
+ var _a, _b;
1913
+ if (!product || typeof product !== "object")
1914
+ return;
1915
+ const productUid = ((_a = product.metadata) == null ? void 0 : _a.unique_identification_number) || product.unique_identification_number;
1916
+ const bookingUid = product.booking_uid || ((_b = product.metadata) == null ? void 0 : _b.booking_uid);
1917
+ const linkedBooking = (productUid !== void 0 && productUid !== null && String(productUid) !== "" ? bookingByProductUid.get(String(productUid)) : void 0) || (bookingUid !== void 0 && bookingUid !== null && String(bookingUid) !== "" ? bookingByBookingUid.get(String(bookingUid)) : void 0);
1918
+ if (linkedBooking) {
1919
+ this.setProductHolderFromBooking(product, linkedBooking);
1920
+ }
1921
+ });
1922
+ }
1665
1923
  /**
1666
1924
  * 按 form_record 顺序读取 booking holder 的主字段名称。
1667
1925
  *
@@ -1741,6 +1999,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1741
1999
  if (nextHolder || hasHolderSource || bookings.length === 0) {
1742
2000
  tempOrder.holder = nextHolder;
1743
2001
  }
2002
+ this.syncLinkedBookingHoldersToProducts(tempOrder);
1744
2003
  }
1745
2004
  getBookingUniqueIdentificationNumber(booking) {
1746
2005
  var _a;
@@ -1800,19 +2059,24 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1800
2059
  hasDeposit: true
1801
2060
  } : void 0
1802
2061
  };
2062
+ const isExistingDepositDisabled = tempOrder.is_deposit === 0 && new import_decimal.default(tempOrder.deposit_amount || 0).gt(0);
1803
2063
  tempOrder.deposit_amount = depositAmount;
1804
- tempOrder.is_deposit = hasDepositAmount ? 1 : 0;
1805
- return nextSummary;
2064
+ tempOrder.is_deposit = hasDepositAmount && !isExistingDepositDisabled ? 1 : 0;
2065
+ return this.applyLastOrderDepositSnapshot(tempOrder, nextSummary);
1806
2066
  }
1807
2067
  async recalculateSummary(options) {
2068
+ var _a;
1808
2069
  const tempOrder = (options == null ? void 0 : options.createIfMissing) ? this.ensureTempOrder() : this.store.tempOrder;
1809
2070
  if (!tempOrder)
1810
2071
  return null;
1811
2072
  this.sanitizeTempOrderProducts(tempOrder);
1812
- const snapshotSummary = this.restoreOriginalSnapshotIfProductsUnchanged(tempOrder);
2073
+ const originalSnapshot = this.getOriginalSalesSnapshot(tempOrder);
2074
+ const hasShopDiscountChanged = originalSnapshot ? this.hasShopDiscountChangedFromSnapshot(tempOrder, originalSnapshot) : false;
2075
+ const shouldReuseOriginalSnapshot = originalSnapshot && !hasShopDiscountChanged;
2076
+ const snapshotSummary = shouldReuseOriginalSnapshot ? this.restoreOriginalSnapshotIfProductsUnchanged(tempOrder, originalSnapshot) : null;
1813
2077
  if (snapshotSummary)
1814
2078
  return snapshotSummary;
1815
- const shouldFullRecalculateFromSnapshot = Boolean(this.getOriginalSalesSnapshot(tempOrder));
2079
+ const shouldFullRecalculateFromSnapshot = Boolean(originalSnapshot);
1816
2080
  const summaryProducts = shouldFullRecalculateFromSnapshot ? (0, import_lodash_es.cloneDeep)(tempOrder.products || []) : tempOrder.products;
1817
2081
  if (shouldFullRecalculateFromSnapshot) {
1818
2082
  this.clearPersistedAmountFieldsForFullRecalc(summaryProducts || []);
@@ -1859,7 +2123,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1859
2123
  const salesSummaryResult = await salesSummary.getSummary({
1860
2124
  products: summaryProducts,
1861
2125
  isPriceIncludeTax: tempOrder.is_price_include_tax,
1862
- shopDiscount: tempOrder.shop_discount
2126
+ shopDiscount: tempOrder.shop_discount,
2127
+ ...((_a = this.otherParams) == null ? void 0 : _a.channel) ? { channel: this.otherParams.channel } : {}
1863
2128
  });
1864
2129
  if (shouldFullRecalculateFromSnapshot) {
1865
2130
  tempOrder.products = summaryProducts;
@@ -2013,6 +2278,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2013
2278
  const type = (discount == null ? void 0 : discount.type) ?? (discount == null ? void 0 : discount.tag);
2014
2279
  return type === "good_pass" || type === "discount_card" || type === "product_discount_card";
2015
2280
  }
2281
+ shouldKeepCustomerBoundDiscountAfterCustomerChange(discount) {
2282
+ return Boolean((discount == null ? void 0 : discount.isScan) || (discount == null ? void 0 : discount.isEditMode));
2283
+ }
2016
2284
  productHasCustomerBoundDiscount(product) {
2017
2285
  if (((product == null ? void 0 : product.discount_list) || []).some((discount) => this.isCustomerBoundDiscount(discount))) {
2018
2286
  return true;
@@ -2068,12 +2336,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2068
2336
  const currentDiscounts = ((_a = discountModule.getDiscountList) == null ? void 0 : _a.call(discountModule)) || [];
2069
2337
  const currentOriginalDiscounts = ((_b = discountModule.getOriginalDiscountList) == null ? void 0 : _b.call(discountModule)) || [];
2070
2338
  const nextDiscounts = currentDiscounts.filter((discount) => {
2071
- if (discount == null ? void 0 : discount.isEditMode)
2339
+ if (this.shouldKeepCustomerBoundDiscountAfterCustomerChange(discount))
2072
2340
  return true;
2073
2341
  return !this.isCustomerBoundDiscount(discount);
2074
2342
  });
2075
2343
  const nextOriginalDiscounts = currentOriginalDiscounts.filter((discount) => {
2076
- if (discount == null ? void 0 : discount.isEditMode)
2344
+ if (this.shouldKeepCustomerBoundDiscountAfterCustomerChange(discount))
2077
2345
  return true;
2078
2346
  return !this.isCustomerBoundDiscount(discount);
2079
2347
  });
@@ -2144,8 +2412,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2144
2412
  }
2145
2413
  const nextCustomerId = tempOrder.customer_id ?? null;
2146
2414
  if (String(previousCustomerId ?? "") !== String(nextCustomerId ?? "")) {
2415
+ this.store.availableWalletIds = [];
2147
2416
  (0, import_utils.clearTempOrderHolderAssignments)(tempOrder);
2148
2417
  this.clearCustomerBoundDiscounts(tempOrder);
2418
+ this.applyDiscount();
2149
2419
  }
2150
2420
  this.persistTempOrder();
2151
2421
  this.saveDraftInBackground();
@@ -2182,6 +2452,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2182
2452
  tempOrder.customer = null;
2183
2453
  if (tempOrder._extend)
2184
2454
  delete tempOrder._extend.customerSnapshot;
2455
+ this.store.availableWalletIds = [];
2185
2456
  this.clearCustomerBoundDiscounts(tempOrder);
2186
2457
  this.persistTempOrder();
2187
2458
  this.saveDraftInBackground();
@@ -2303,49 +2574,153 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2303
2574
  this.persistTempOrder();
2304
2575
  return tempOrder.payments;
2305
2576
  }
2577
+ confirmPendingVoucherPaymentsInList(payments) {
2578
+ return (payments || []).map((payment) => {
2579
+ if (!isPendingVoucherPaymentRecord(payment))
2580
+ return payment;
2581
+ return {
2582
+ ...payment,
2583
+ status: ORDER_PAYMENT_STATUS_PAID
2584
+ };
2585
+ });
2586
+ }
2587
+ discardPendingVoucherPaymentsFromList(payments) {
2588
+ return (payments || []).filter((payment) => !isPendingVoucherPaymentRecord(payment));
2589
+ }
2590
+ prepareVoucherPaymentsForSubmit(payments, confirmPendingVoucherPayments = true) {
2591
+ const mappedPayments = (0, import_utils.mapPaymentItemsToOrderPayments)(payments || []);
2592
+ return confirmPendingVoucherPayments ? this.confirmPendingVoucherPaymentsInList(mappedPayments) : this.discardPendingVoucherPaymentsFromList(mappedPayments);
2593
+ }
2594
+ applyPaymentLifecycleChange(tempOrder, options) {
2595
+ this.updateTempOrderPaymentStatus(tempOrder);
2596
+ if ((options == null ? void 0 : options.persist) !== false) {
2597
+ this.persistTempOrder();
2598
+ }
2599
+ if ((options == null ? void 0 : options.recalculateSummary) === false)
2600
+ return;
2601
+ const logContext = (options == null ? void 0 : options.logContext) || "payment lifecycle change";
2602
+ void this.recalculateSummary({ createIfMissing: true }).catch((error) => {
2603
+ this.logError(`recalculate summary after ${logContext} failed`, {
2604
+ error: error instanceof Error ? error.message : String(error)
2605
+ });
2606
+ });
2607
+ }
2608
+ confirmPendingVoucherPayments(options) {
2609
+ const tempOrder = this.ensureTempOrder();
2610
+ const payments = tempOrder.payments || [];
2611
+ const hasPendingVoucher = payments.some((payment) => isPendingVoucherPaymentRecord(payment));
2612
+ if (!hasPendingVoucher)
2613
+ return payments;
2614
+ tempOrder.payments = this.confirmPendingVoucherPaymentsInList(payments);
2615
+ this.applyPaymentLifecycleChange(tempOrder, {
2616
+ ...options,
2617
+ logContext: "confirmPendingVoucherPayments"
2618
+ });
2619
+ return tempOrder.payments;
2620
+ }
2621
+ discardPendingVoucherPayments(options) {
2622
+ const tempOrder = this.ensureTempOrder();
2623
+ const payments = tempOrder.payments || [];
2624
+ const nextPayments = this.discardPendingVoucherPaymentsFromList(payments);
2625
+ if (nextPayments.length === payments.length)
2626
+ return payments;
2627
+ tempOrder.payments = nextPayments;
2628
+ this.applyPaymentLifecycleChange(tempOrder, {
2629
+ ...options,
2630
+ logContext: "discardPendingVoucherPayments"
2631
+ });
2632
+ return tempOrder.payments;
2633
+ }
2306
2634
  /**
2307
2635
  * 覆盖当前订单中的 wallet pass 支付项。
2308
2636
  *
2309
2637
  * 判断口径与 PaymentModal 保持一致:voucher_id 存在且不为 0 的支付项
2310
2638
  * 视为 wallet pass;其它支付项保持不变。
2311
2639
  */
2312
- updateVoucherOrderPayments(payments) {
2640
+ updateVoucherOrderPayments(payments, options) {
2313
2641
  const tempOrder = this.ensureTempOrder();
2314
- const isVoucherPayment = (payment) => {
2315
- return payment.voucher_id !== void 0 && Number(payment.voucher_id) !== 0;
2642
+ const isOrderPaymentType = (value) => {
2643
+ return value === "normal" || value === "deposit";
2644
+ };
2645
+ const voucherOrderPaymentType = this.resolveNextOrderPaymentType(tempOrder);
2646
+ const withVoucherPaymentType = (payment) => {
2647
+ const paymentRecord = payment;
2648
+ if (!isVoucherPaymentRecord(paymentRecord))
2649
+ return payment;
2650
+ const explicitPaymentType = isOrderPaymentType(paymentRecord.order_payment_type) ? paymentRecord.order_payment_type : isOrderPaymentType(paymentRecord.type) ? paymentRecord.type : void 0;
2651
+ const nextPaymentType = explicitPaymentType || voucherOrderPaymentType;
2652
+ const shouldPreserveCustomPaymentType = paymentRecord.custom_payment_type === void 0 && paymentRecord.type !== void 0 && !isOrderPaymentType(paymentRecord.type);
2653
+ return {
2654
+ ...paymentRecord,
2655
+ ...shouldPreserveCustomPaymentType ? { custom_payment_type: paymentRecord.type } : {},
2656
+ type: nextPaymentType,
2657
+ order_payment_type: nextPaymentType
2658
+ };
2316
2659
  };
2317
- const hasSyncedOrderPayment = (payment) => {
2318
- return payment.order_payment_id !== void 0 && payment.order_payment_id !== null;
2660
+ const normalizeVoucherPaymentStatus = (payment) => {
2661
+ const paymentRecord = payment;
2662
+ if (!isVoucherPaymentRecord(paymentRecord))
2663
+ return payment;
2664
+ if (hasSyncedOrderPaymentRecord(paymentRecord) && (paymentRecord.status === void 0 || paymentRecord.status === "active")) {
2665
+ return {
2666
+ ...paymentRecord,
2667
+ status: ORDER_PAYMENT_STATUS_PAID
2668
+ };
2669
+ }
2670
+ if (paymentRecord.status !== void 0 && paymentRecord.status !== "active") {
2671
+ return payment;
2672
+ }
2673
+ return {
2674
+ ...paymentRecord,
2675
+ status: (options == null ? void 0 : options.status) || ORDER_PAYMENT_STATUS_PENDING
2676
+ };
2319
2677
  };
2320
2678
  const mappedVouchers = (0, import_utils.mapPaymentItemsToOrderPayments)(
2321
2679
  payments.map(
2322
- (payment) => this.normalizePaymentSource(payment, { defaultPaid: true })
2680
+ (payment) => this.normalizePaymentSource(
2681
+ normalizeVoucherPaymentStatus(withVoucherPaymentType(payment)),
2682
+ { defaultPaid: false }
2683
+ )
2323
2684
  )
2324
2685
  ).filter((payment) => {
2325
- return isVoucherPayment(payment);
2686
+ return isVoucherPaymentRecord(payment);
2326
2687
  });
2327
2688
  const nonVoucherPayments = (tempOrder.payments || []).filter((payment) => {
2328
- return !isVoucherPayment(payment);
2329
- });
2330
- const syncedVoucherPayments = (tempOrder.payments || []).filter((payment) => {
2331
- return isVoucherPayment(payment) && hasSyncedOrderPayment(payment);
2689
+ return !isVoucherPaymentRecord(payment);
2332
2690
  });
2333
- const syncedVoucherPaymentIds = new Set(
2334
- syncedVoucherPayments.map((payment) => String(payment.order_payment_id))
2691
+ const normalizeCommittedVoucherPayment = (payment) => {
2692
+ if (hasSyncedOrderPaymentRecord(payment) && (payment.status === void 0 || payment.status === "active")) {
2693
+ return {
2694
+ ...payment,
2695
+ status: ORDER_PAYMENT_STATUS_PAID
2696
+ };
2697
+ }
2698
+ return payment;
2699
+ };
2700
+ const committedVoucherPayments = (tempOrder.payments || []).filter((payment) => isCommittedVoucherPaymentRecord(payment)).map((payment) => normalizeCommittedVoucherPayment(payment));
2701
+ const committedVoucherPaymentIds = new Set(
2702
+ committedVoucherPayments.filter((payment) => hasSyncedOrderPaymentRecord(payment)).map((payment) => String(payment.order_payment_id))
2703
+ );
2704
+ const committedVoucherIds = new Set(
2705
+ committedVoucherPayments.map((payment) => String(payment.voucher_id))
2335
2706
  );
2336
2707
  const replaceableVouchers = mappedVouchers.filter((payment) => {
2337
- if (!hasSyncedOrderPayment(payment))
2338
- return true;
2339
- return !syncedVoucherPaymentIds.has(String(payment.order_payment_id));
2708
+ if (hasSyncedOrderPaymentRecord(payment) && committedVoucherPaymentIds.has(String(payment.order_payment_id))) {
2709
+ return false;
2710
+ }
2711
+ if (payment.voucher_id !== void 0 && committedVoucherIds.has(String(payment.voucher_id))) {
2712
+ return false;
2713
+ }
2714
+ return true;
2340
2715
  });
2341
2716
  const cappedVouchers = this.capVoucherPaymentsByRemainingAmount({
2342
2717
  vouchers: replaceableVouchers,
2343
2718
  nonVoucherPayments: [
2344
2719
  ...nonVoucherPayments,
2345
- ...syncedVoucherPayments
2720
+ ...committedVoucherPayments
2346
2721
  ]
2347
2722
  });
2348
- tempOrder.payments = [...nonVoucherPayments, ...syncedVoucherPayments, ...cappedVouchers];
2723
+ tempOrder.payments = [...nonVoucherPayments, ...committedVoucherPayments, ...cappedVouchers];
2349
2724
  this.updateTempOrderPaymentStatus(tempOrder);
2350
2725
  this.persistTempOrder();
2351
2726
  void this.recalculateSummary({ createIfMissing: true }).catch((error) => {
@@ -2444,12 +2819,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2444
2819
  const hasIncomingBookingUid = this.hasLinkedBookingUid(productToAdd) || this.hasLinkedBookingUid(normalizedIncoming);
2445
2820
  const shouldForceNewLine = !!booking || hasIncomingProductNote || hasIncomingBookingUid;
2446
2821
  const matchedIndex = hasIncomingGoodPass || shouldForceNewLine ? -1 : tempOrder.products.findIndex((item) => {
2822
+ var _a2;
2447
2823
  if (this.hasGoodPassDiscount(item))
2448
2824
  return false;
2449
2825
  if (this.hasOrderProductLineNote(item))
2450
2826
  return false;
2451
2827
  if (item.order_detail_id !== void 0 && item.order_detail_id !== null)
2452
2828
  return false;
2829
+ if ((_a2 = item.metadata) == null ? void 0 : _a2.is_edit_for_runtime)
2830
+ return false;
2453
2831
  if (item.product_id !== productToAdd.product_id)
2454
2832
  return false;
2455
2833
  if (item.product_variant_id !== productToAdd.product_variant_id)
@@ -2561,7 +2939,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2561
2939
  */
2562
2940
  async addProductToOrder(product, booking) {
2563
2941
  const tempOrder = this.ensureTempOrder();
2564
- debugger;
2565
2942
  if (booking) {
2566
2943
  const productRecord = product;
2567
2944
  const splitCount = (0, import_utils3.getSafeProductNum)(
@@ -2584,6 +2961,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2584
2961
  }
2585
2962
  await this.appendProductLineToTempOrder(tempOrder, product, booking);
2586
2963
  await this.finalizeProductOrderMutation(tempOrder);
2964
+ this.logInfo("addProductToOrder success", {
2965
+ product_id: product.product_id,
2966
+ with_booking: !!booking
2967
+ });
2587
2968
  return tempOrder.products;
2588
2969
  }
2589
2970
  /**
@@ -2625,6 +3006,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2625
3006
  await this.appendProductLineToTempOrder(tempOrder, product, booking);
2626
3007
  }
2627
3008
  await this.finalizeProductOrderMutation(tempOrder, options);
3009
+ this.logInfo("addProductsToOrder success", {
3010
+ itemsCount: items.length
3011
+ });
2628
3012
  return tempOrder.products;
2629
3013
  }
2630
3014
  hasGoodPassDiscount(product) {
@@ -2674,6 +3058,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2674
3058
  return bundle;
2675
3059
  return {
2676
3060
  ...bundle,
3061
+ ...(bundle.cover === void 0 || bundle.cover === null || bundle.cover === "") && previous.cover !== void 0 && previous.cover !== null && previous.cover !== "" ? { cover: previous.cover } : {},
2677
3062
  price: previous.price,
2678
3063
  custom_price: previous.custom_price,
2679
3064
  bundle_payment_price: previous.bundle_payment_price,
@@ -2684,7 +3069,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2684
3069
  });
2685
3070
  }
2686
3071
  applyOrderProductUpdateToTempOrder(tempOrder, params) {
2687
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
3072
+ 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;
2688
3073
  const {
2689
3074
  product_id,
2690
3075
  product_variant_id,
@@ -2748,9 +3133,22 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2748
3133
  nextProduct.num = (0, import_utils3.getSafeProductNum)(nextProduct.num);
2749
3134
  const callerUpdatesTopPrice = Object.prototype.hasOwnProperty.call(updates || {}, "selling_price") || Object.prototype.hasOwnProperty.call(updates || {}, "original_price");
2750
3135
  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;
3136
+ const callerUpdatesSourcePrice = ((_f = updates == null ? void 0 : updates.metadata) == null ? void 0 : _f.source_product_price) !== void 0;
3137
+ const callerUpdatesMainSellingPrice = ((_g = updates == null ? void 0 : updates.metadata) == null ? void 0 : _g.main_product_selling_price) !== void 0;
3138
+ const callerUpdatesMainOriginalPrice = ((_h = updates == null ? void 0 : updates.metadata) == null ? void 0 : _h.main_product_original_price) !== void 0;
3139
+ const previousLineFingerprint = (0, import_utils3.buildProductLineFingerprint)(
3140
+ (0, import_utils.getProductSkuOptions)(targetProduct),
3141
+ targetProduct.product_bundle
3142
+ );
3143
+ const nextLineFingerprint = (0, import_utils3.buildProductLineFingerprint)(
3144
+ (0, import_utils.getProductSkuOptions)(nextProduct),
3145
+ nextProduct.product_bundle
3146
+ );
3147
+ const callerChangesVariant = Number(product_variant_id || 0) !== Number(targetProduct.product_variant_id || 0);
3148
+ const callerChangesLineConfiguration = callerChangesVariant || previousLineFingerprint !== nextLineFingerprint;
2751
3149
  const isPersistedOrderLine = targetProduct.order_detail_id !== void 0 && targetProduct.order_detail_id !== null;
2752
3150
  const callerChangesDiscountList = Array.isArray(updates == null ? void 0 : updates.discount_list) && updates.discount_list.length > 0 && !isSameDiscountList(updates.discount_list, targetProduct.discount_list);
2753
- 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;
3151
+ 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;
2754
3152
  const callerAllowsBookingReprice = (() => {
2755
3153
  if (params.allow_booking_reprice !== true || !booking || !callerUpdatesTopPrice || !callerUpdatesMainMeta) {
2756
3154
  return false;
@@ -2765,21 +3163,69 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2765
3163
  };
2766
3164
  return hasChangedPrice(updates.selling_price, targetProduct.selling_price) || hasChangedPrice(updates.original_price, targetProduct.original_price);
2767
3165
  })();
2768
- if (isPersistedOrderLine && !callerUpdatesManualPrice && !callerAllowsBookingReprice) {
3166
+ if (isPersistedOrderLine && !callerChangesLineConfiguration && !callerUpdatesManualPrice && !callerAllowsBookingReprice) {
2769
3167
  nextProduct.selling_price = targetProduct.selling_price;
2770
3168
  nextProduct.original_price = targetProduct.original_price;
2771
3169
  nextProduct.payment_price = targetProduct.payment_price;
2772
3170
  nextProduct.metadata = {
2773
3171
  ...nextProduct.metadata || {},
2774
- source_product_price: (_i = targetProduct.metadata) == null ? void 0 : _i.source_product_price,
2775
- main_product_selling_price: (_j = targetProduct.metadata) == null ? void 0 : _j.main_product_selling_price,
2776
- main_product_original_price: (_k = targetProduct.metadata) == null ? void 0 : _k.main_product_original_price,
2777
- price_schema_version: ((_l = targetProduct.metadata) == null ? void 0 : _l.price_schema_version) ?? 2
3172
+ source_product_price: (_l = targetProduct.metadata) == null ? void 0 : _l.source_product_price,
3173
+ main_product_selling_price: (_m = targetProduct.metadata) == null ? void 0 : _m.main_product_selling_price,
3174
+ main_product_original_price: (_n = targetProduct.metadata) == null ? void 0 : _n.main_product_original_price,
3175
+ price_schema_version: ((_o = targetProduct.metadata) == null ? void 0 : _o.price_schema_version) ?? 2
2778
3176
  };
2779
3177
  nextProduct.product_bundle = this.preservePersistedBundlePriceFields(
2780
3178
  targetProduct.product_bundle,
2781
3179
  nextProduct.product_bundle
2782
3180
  );
3181
+ } else if (callerChangesLineConfiguration && callerUpdatesSourcePrice && (!callerUpdatesMainSellingPrice || !callerUpdatesMainOriginalPrice)) {
3182
+ const previousMainOriginal = new import_decimal.default(
3183
+ Number((_p = targetProduct.metadata) == null ? void 0 : _p.main_product_original_price) || 0
3184
+ );
3185
+ const previousMainSelling = new import_decimal.default(
3186
+ Number((_q = targetProduct.metadata) == null ? void 0 : _q.main_product_selling_price) || previousMainOriginal.toNumber()
3187
+ );
3188
+ const preservedDiscount = previousMainOriginal.minus(previousMainSelling);
3189
+ const nextMainOriginal = new import_decimal.default(
3190
+ Number(updates.metadata.source_product_price) || 0
3191
+ ).plus((0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(nextProduct)));
3192
+ nextProduct.metadata = {
3193
+ ...nextProduct.metadata || {},
3194
+ source_product_price: String(updates.metadata.source_product_price),
3195
+ main_product_original_price: callerUpdatesMainOriginalPrice ? String(updates.metadata.main_product_original_price) : nextMainOriginal.toDecimalPlaces(2).toFixed(2),
3196
+ main_product_selling_price: callerUpdatesMainSellingPrice ? String(updates.metadata.main_product_selling_price) : nextMainOriginal.minus(preservedDiscount).toDecimalPlaces(2).toFixed(2),
3197
+ price_schema_version: 2
3198
+ };
3199
+ } else if (callerChangesVariant && !callerUpdatesTopPrice && !callerUpdatesMainMeta) {
3200
+ const existedMeta = nextProduct.metadata || {};
3201
+ nextProduct.metadata = { ...existedMeta };
3202
+ delete nextProduct.metadata.source_product_price;
3203
+ delete nextProduct.metadata.main_product_selling_price;
3204
+ delete nextProduct.metadata.main_product_original_price;
3205
+ delete nextProduct.metadata.price_schema_version;
3206
+ } else if (callerChangesLineConfiguration && !callerUpdatesTopPrice && !callerUpdatesMainMeta) {
3207
+ const previousOptionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(targetProduct));
3208
+ const nextOptionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(nextProduct));
3209
+ const previousMainOriginal = new import_decimal.default(
3210
+ Number(
3211
+ ((_r = targetProduct.metadata) == null ? void 0 : _r.main_product_original_price) ?? targetProduct.original_price ?? 0
3212
+ ) || 0
3213
+ );
3214
+ const previousMainSelling = new import_decimal.default(
3215
+ Number(
3216
+ ((_s = targetProduct.metadata) == null ? void 0 : _s.main_product_selling_price) ?? targetProduct.selling_price ?? previousMainOriginal.toNumber()
3217
+ ) || 0
3218
+ );
3219
+ const preservedDiscount = previousMainOriginal.minus(previousMainSelling);
3220
+ 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);
3221
+ const nextMainOriginal = previousSource.plus(nextOptionSum);
3222
+ nextProduct.metadata = {
3223
+ ...nextProduct.metadata || {},
3224
+ source_product_price: previousSource.toDecimalPlaces(2).toFixed(2),
3225
+ main_product_original_price: nextMainOriginal.toDecimalPlaces(2).toFixed(2),
3226
+ main_product_selling_price: nextMainOriginal.minus(preservedDiscount).toDecimalPlaces(2).toFixed(2),
3227
+ price_schema_version: 2
3228
+ };
2783
3229
  } else if (callerUpdatesTopPrice && !callerUpdatesMainMeta) {
2784
3230
  const existedMeta = nextProduct.metadata || {};
2785
3231
  nextProduct.metadata = { ...existedMeta };
@@ -2795,7 +3241,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2795
3241
  normalizedProduct.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
2796
3242
  normalizedProduct.discount_list
2797
3243
  );
2798
- 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);
3244
+ 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);
2799
3245
  if (!booking && preservedBookingUid) {
2800
3246
  normalizedProduct.booking_uid = preservedBookingUid;
2801
3247
  normalizedProduct.metadata = {
@@ -2805,7 +3251,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2805
3251
  }
2806
3252
  if (booking) {
2807
3253
  const productUid = String(
2808
- ((_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)()
3254
+ ((_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)()
2809
3255
  );
2810
3256
  normalizedProduct.metadata = {
2811
3257
  ...normalizedProduct.metadata || {},
@@ -2836,17 +3282,23 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2836
3282
  tempOrder,
2837
3283
  updates,
2838
3284
  tempOrder.products[productIndex],
2839
- (_q = tempOrder.products[productIndex].metadata) == null ? void 0 : _q.unique_identification_number
3285
+ (_y = tempOrder.products[productIndex].metadata) == null ? void 0 : _y.unique_identification_number
2840
3286
  );
3287
+ return (_z = tempOrder.products[productIndex].metadata) == null ? void 0 : _z.unique_identification_number;
2841
3288
  }
2842
3289
  async updateOrderProduct(params) {
2843
3290
  const tempOrder = this.ensureTempOrder();
2844
- this.applyOrderProductUpdateToTempOrder(tempOrder, params);
3291
+ const updatedProductUid = this.applyOrderProductUpdateToTempOrder(tempOrder, params);
2845
3292
  await this.applyPromotion();
2846
- this.applyDiscount();
3293
+ this.applyDiscount({
3294
+ reapplyBookingDiscountProductUids: params.allow_booking_discount_reapply && updatedProductUid ? [String(updatedProductUid)] : void 0
3295
+ });
2847
3296
  this.sanitizeTempOrderProducts(tempOrder);
2848
3297
  await this.recalculateSummary({ createIfMissing: true });
2849
3298
  this.persistTempOrder();
3299
+ this.logInfo("updateOrderProduct success", {
3300
+ params
3301
+ });
2850
3302
  return tempOrder.products;
2851
3303
  }
2852
3304
  async updateOrderProducts(paramsList) {
@@ -2854,10 +3306,19 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2854
3306
  if (!paramsList.length) {
2855
3307
  return tempOrder.products;
2856
3308
  }
2857
- paramsList.forEach((params) => {
2858
- this.applyOrderProductUpdateToTempOrder(tempOrder, params);
3309
+ const reapplyBookingDiscountProductUids = paramsList.reduce((acc, params) => {
3310
+ const updatedProductUid = this.applyOrderProductUpdateToTempOrder(tempOrder, params);
3311
+ if (params.allow_booking_discount_reapply && updatedProductUid) {
3312
+ acc.push(String(updatedProductUid));
3313
+ }
3314
+ return acc;
3315
+ }, []);
3316
+ await this.finalizeAfterProductsMutation(tempOrder, {
3317
+ reapplyBookingDiscountProductUids: reapplyBookingDiscountProductUids.length ? reapplyBookingDiscountProductUids : void 0
3318
+ });
3319
+ this.logInfo("updateOrderProduct success", {
3320
+ paramsList
2859
3321
  });
2860
- await this.finalizeAfterProductsMutation(tempOrder);
2861
3322
  return tempOrder.products;
2862
3323
  }
2863
3324
  async updateOrderProductQuantity(params) {
@@ -2922,6 +3383,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2922
3383
  this.sanitizeTempOrderProducts(tempOrder);
2923
3384
  await this.recalculateSummary({ createIfMissing: true });
2924
3385
  this.persistTempOrder();
3386
+ this.logInfo("updateOrderProductQuantity success", {
3387
+ params
3388
+ });
2925
3389
  return tempOrder.products;
2926
3390
  }
2927
3391
  updateOrderBooking(params) {
@@ -2960,10 +3424,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2960
3424
  * @example
2961
3425
  * await this.finalizeAfterProductsMutation(tempOrder);
2962
3426
  */
2963
- async finalizeAfterProductsMutation(tempOrder) {
3427
+ async finalizeAfterProductsMutation(tempOrder, options) {
2964
3428
  this.syncTempOrderHolderFromBookings(tempOrder);
2965
3429
  await this.applyPromotion();
2966
- this.applyDiscount();
3430
+ this.applyDiscount({
3431
+ reapplyBookingDiscountProductUids: options == null ? void 0 : options.reapplyBookingDiscountProductUids
3432
+ });
2967
3433
  this.sanitizeTempOrderProducts(tempOrder);
2968
3434
  await this.recalculateSummary({ createIfMissing: true });
2969
3435
  this.persistTempOrder();
@@ -3023,6 +3489,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3023
3489
  });
3024
3490
  }
3025
3491
  await this.finalizeAfterProductsMutation(tempOrder);
3492
+ this.logInfo("removeProductsFromOrder success", {
3493
+ identities
3494
+ });
3026
3495
  return tempOrder.products;
3027
3496
  }
3028
3497
  async removeProductFromOrder(identity) {
@@ -3048,6 +3517,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3048
3517
  this.sanitizeTempOrderProducts(tempOrder);
3049
3518
  await this.recalculateSummary({ createIfMissing: true });
3050
3519
  this.persistTempOrder();
3520
+ this.logInfo("clearOrderCartLines success", {});
3051
3521
  return tempOrder;
3052
3522
  }
3053
3523
  // ─── TempOrder: 提交 ───
@@ -3108,37 +3578,55 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3108
3578
  async runSubmitTempOrder(params) {
3109
3579
  var _a, _b, _c, _d, _e;
3110
3580
  const tempOrder = this.ensureTempOrder();
3581
+ const shouldConfirmPendingVoucherPayments = (params == null ? void 0 : params.confirmPendingVoucherPayments) !== false;
3582
+ const hasPaymentOverride = (params == null ? void 0 : params.payments) !== void 0;
3583
+ const preparedPaymentOverride = hasPaymentOverride ? this.prepareVoucherPaymentsForSubmit(
3584
+ (params == null ? void 0 : params.payments) || [],
3585
+ shouldConfirmPendingVoucherPayments
3586
+ ) : void 0;
3587
+ if (!hasPaymentOverride) {
3588
+ if (shouldConfirmPendingVoucherPayments) {
3589
+ this.confirmPendingVoucherPayments({
3590
+ persist: false,
3591
+ recalculateSummary: false
3592
+ });
3593
+ } else {
3594
+ this.discardPendingVoucherPayments({
3595
+ persist: false,
3596
+ recalculateSummary: false
3597
+ });
3598
+ }
3599
+ }
3111
3600
  this.persistTempOrder();
3112
3601
  const latestSummary = await this.recalculateSummary({ createIfMissing: true }) || this.store.summary || (0, import_utils.createEmptySummary)();
3113
3602
  const effectiveCacheId = (params == null ? void 0 : params.cacheId) ?? this.cacheId;
3114
- const hasPaymentOverride = (params == null ? void 0 : params.payments) !== void 0;
3115
3603
  const hasPaymentStatusOverride = (params == null ? void 0 : params.paymentStatus) !== void 0;
3116
3604
  const hasSmallTicketDataFlagOverride = (params == null ? void 0 : params.smallTicketDataFlag) !== void 0;
3117
3605
  const enhancePayload = hasPaymentOverride || hasPaymentStatusOverride || hasSmallTicketDataFlagOverride || (params == null ? void 0 : params.enhancePayload) ? (payload2, ctx) => {
3118
3606
  const nextPayload = {
3119
3607
  ...payload2,
3120
3608
  ...hasPaymentOverride ? {
3121
- payments: (0, import_utils.mapPaymentItemsToOrderPayments)(
3122
- (params == null ? void 0 : params.payments) || []
3123
- )
3609
+ payments: preparedPaymentOverride || []
3124
3610
  } : {},
3125
- ...hasPaymentStatusOverride ? { payment_status: params == null ? void 0 : params.paymentStatus } : {},
3611
+ ...hasPaymentStatusOverride && !shouldConfirmPendingVoucherPayments ? { payment_status: params == null ? void 0 : params.paymentStatus } : {},
3126
3612
  ...hasSmallTicketDataFlagOverride ? { small_ticket_data_flag: params == null ? void 0 : params.smallTicketDataFlag } : {}
3127
3613
  };
3128
3614
  const enhancedPayload = (params == null ? void 0 : params.enhancePayload) ? params.enhancePayload(nextPayload, ctx) : nextPayload;
3129
3615
  return enhancedPayload;
3130
3616
  } : void 0;
3617
+ const submitSnapshot = this.getLastOrderSubmitSnapshot();
3131
3618
  const payload = (0, import_utils.buildSubmitPayload)({
3132
3619
  tempOrder,
3133
3620
  cacheId: effectiveCacheId,
3134
3621
  platform: (params == null ? void 0 : params.platform) || ((_a = this.otherParams) == null ? void 0 : _a.platform),
3135
- businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
3622
+ businessCode: submitSnapshot.businessCode ?? (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
3136
3623
  channel: params == null ? void 0 : params.channel,
3137
- type: params == null ? void 0 : params.type,
3624
+ type: submitSnapshot.type ?? (params == null ? void 0 : params.type),
3138
3625
  summary: latestSummary,
3139
3626
  request_unique_idempotency_token: params == null ? void 0 : params.request_unique_idempotency_token,
3140
3627
  enhance: enhancePayload
3141
3628
  });
3629
+ console.log("[Order.runSubmitTempOrder.payload]", payload);
3142
3630
  if (params == null ? void 0 : params.syncMode) {
3143
3631
  payload.sync_mode = true;
3144
3632
  }
@@ -3186,7 +3674,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3186
3674
  this.logInfo("runSubmitTempOrder: 提交成功", {
3187
3675
  submittedOrderId,
3188
3676
  result,
3189
- tempOrder
3677
+ tempOrder: {
3678
+ ...tempOrder,
3679
+ _extend: void 0
3680
+ }
3190
3681
  });
3191
3682
  if (submittedOrderId !== null && submittedOrderId !== void 0) {
3192
3683
  tempOrder.order_id = submittedOrderId;
@@ -3272,31 +3763,33 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3272
3763
  const mappedPayments = (0, import_utils.mapPaymentItemsToOrderPayments)(
3273
3764
  params.payments || []
3274
3765
  );
3275
- const paymentTotal = this.calculatePaymentTotal(mappedPayments);
3276
- const targetAmount = this.getPaymentTargetAmount();
3277
- const isFullyPaid = targetAmount.lte(0) ? true : paymentTotal.gte(targetAmount);
3278
- const paymentStatus = isFullyPaid ? params.paymentStatus || "paid" : "partially_paid";
3279
- tempOrder.payments = mappedPayments;
3766
+ const shouldConfirmPendingVoucherPayments = params.confirmPendingVoucherPayments ?? params.submitWhenPaid === true;
3767
+ const effectivePayments = shouldConfirmPendingVoucherPayments ? this.confirmPendingVoucherPaymentsInList(mappedPayments) : params.confirmPendingVoucherPayments === false ? this.discardPendingVoucherPaymentsFromList(mappedPayments) : mappedPayments;
3768
+ const completion = this.getPaymentCompletion(effectivePayments);
3769
+ const orderPaidPaymentTotal = this.calculateOrderPaidPaymentTotal(effectivePayments);
3770
+ const paymentStatus = completion.isOrderFullyPaid ? params.paymentStatus || "paid" : orderPaidPaymentTotal.gt(0) ? "partially_paid" : "payment_processing";
3771
+ tempOrder.payments = effectivePayments;
3280
3772
  tempOrder.payment_status = paymentStatus;
3281
3773
  this.persistTempOrder();
3282
3774
  await this.saveDraft();
3283
3775
  if (!params.submitWhenPaid) {
3284
- return { isFullyPaid };
3776
+ return completion;
3285
3777
  }
3286
3778
  if (this.store.syncState === "submitting") {
3287
- return { isFullyPaid };
3779
+ return completion;
3288
3780
  }
3289
3781
  this.store.syncState = "submitting";
3290
3782
  const paymentSyncIdempotencyToken = this.buildPaymentSyncIdempotencyToken(
3291
3783
  tempOrder,
3292
- mappedPayments
3784
+ effectivePayments
3293
3785
  );
3294
3786
  const submitResult = await this.submitTempOrder({
3295
- payments: mappedPayments,
3787
+ payments: effectivePayments,
3296
3788
  paymentStatus,
3297
3789
  smallTicketDataFlag: params.smallTicketDataFlag,
3298
3790
  businessCode: params.businessCode,
3299
3791
  channel: params.channel,
3792
+ confirmPendingVoucherPayments: true,
3300
3793
  enhancePayload: (payload) => {
3301
3794
  const nextPayload = {
3302
3795
  ...payload,
@@ -3305,7 +3798,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3305
3798
  return nextPayload;
3306
3799
  }
3307
3800
  });
3308
- return { isFullyPaid, submitResult };
3801
+ return { ...completion, submitResult };
3309
3802
  }
3310
3803
  createOrder(params) {
3311
3804
  var _a;
@@ -3614,8 +4107,36 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3614
4107
  */
3615
4108
  async hydrateTempOrderFromRecord(record, options) {
3616
4109
  var _a, _b, _c;
3617
- const raw = record && typeof record === "object" && record.data && record.order_id == null ? record.data : record || {};
3618
- const nextTempOrder = this.normalizeTempOrderForRuntime(raw);
4110
+ const sourceRaw = record && typeof record === "object" && record.data && record.order_id == null ? record.data : record || {};
4111
+ const identityReadySource = this.seedAnonymousBookingUidsFromProducts(
4112
+ sourceRaw
4113
+ );
4114
+ const normalizedCollections = (0, import_orderCollectionIdentity.normalizeOrderCollections)(identityReadySource);
4115
+ const raw = normalizedCollections.order;
4116
+ const hasIdentityChanges = Object.values(normalizedCollections.stats).some(
4117
+ (stats) => stats.backfilledUidCount > 0 || stats.collapsedDuplicateCount > 0 || stats.uidConflictCount > 0 || stats.anonymousRowCount > 0
4118
+ );
4119
+ if (hasIdentityChanges) {
4120
+ const identityLogMetadata = {
4121
+ collections: normalizedCollections.stats,
4122
+ uidRemapCount: normalizedCollections.uidRemaps.length
4123
+ };
4124
+ const hasIdentityWarnings = Object.values(normalizedCollections.stats).some(
4125
+ (stats) => stats.uidConflictCount > 0 || stats.anonymousRowCount > 0
4126
+ );
4127
+ if (hasIdentityWarnings) {
4128
+ this.logWarning(
4129
+ "Normalized hydrated order collection identities",
4130
+ identityLogMetadata
4131
+ );
4132
+ } else {
4133
+ this.logInfo(
4134
+ "Normalized hydrated order collection identities",
4135
+ identityLogMetadata
4136
+ );
4137
+ }
4138
+ }
4139
+ const nextTempOrder = this.normalizeTempOrderForRuntime(raw, { makeEditMark: true });
3619
4140
  const rawSummary = raw.summary && typeof raw.summary === "object" ? raw.summary : {};
3620
4141
  const summarySurcharges = Array.isArray(rawSummary.surcharges) ? rawSummary.surcharges.map((s) => ({ ...s || {} })) : (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []);
3621
4142
  this.store.tempOrder = nextTempOrder;
@@ -3629,18 +4150,35 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3629
4150
  originalSalesSnapshot: {
3630
4151
  summary: (0, import_lodash_es.cloneDeep)(this.store.summary),
3631
4152
  products: (0, import_lodash_es.cloneDeep)(nextTempOrder.products || []),
4153
+ bookings: (0, import_lodash_es.cloneDeep)(nextTempOrder.bookings || []),
3632
4154
  payments: (0, import_lodash_es.cloneDeep)(nextTempOrder.payments || []),
3633
4155
  surcharges: (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []),
4156
+ shop_discount: nextTempOrder.shop_discount || "0.00",
3634
4157
  productFingerprint: this.buildOrderProductsFingerprint(nextTempOrder.products || [])
3635
4158
  }
3636
4159
  };
3637
- this.store.lastOrderInfo = raw.lastOrderInfo || raw;
4160
+ this.store.lastOrderInfo = sourceRaw.lastOrderInfo || sourceRaw;
3638
4161
  const hydratedEditDiscounts = this.collectHydratedEditDiscounts(nextTempOrder.products);
3639
4162
  const currentDiscounts = typeof ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList) === "function" ? this.store.discount.getDiscountList() || [] : [];
3640
- const shouldSkipEmptyDiscountSync = hydratedEditDiscounts.length === 0 && currentDiscounts.length === 0;
4163
+ const currentScanDiscounts = currentDiscounts.filter((discount) => discount == null ? void 0 : discount.isScan);
4164
+ const hydratedDiscountIds = new Set(
4165
+ hydratedEditDiscounts.map((discount) => discount == null ? void 0 : discount.id)
4166
+ );
4167
+ const retainedScanDiscounts = currentScanDiscounts.filter(
4168
+ (discount) => !hydratedDiscountIds.has(discount == null ? void 0 : discount.id)
4169
+ );
4170
+ const nextDiscounts = [
4171
+ ...hydratedEditDiscounts,
4172
+ ...retainedScanDiscounts
4173
+ ];
4174
+ const shouldSkipEmptyDiscountSync = nextDiscounts.length === 0 && currentDiscounts.length === 0;
3641
4175
  if (!shouldSkipEmptyDiscountSync) {
3642
- await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(hydratedEditDiscounts));
3643
- await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(hydratedEditDiscounts));
4176
+ OrderModule.populateSavedAmounts(
4177
+ nextTempOrder.products,
4178
+ nextDiscounts
4179
+ );
4180
+ await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(nextDiscounts));
4181
+ await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(nextDiscounts));
3644
4182
  }
3645
4183
  if (options == null ? void 0 : options.recalcOnHydrate) {
3646
4184
  await this.recalculateSummary({ createIfMissing: false });
@@ -3672,6 +4210,64 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3672
4210
  }
3673
4211
  return next;
3674
4212
  }
4213
+ /**
4214
+ * 匿名 booking 没有服务端行 ID 时,商品侧已有的 booking_uid 就是唯一可用的强引用。
4215
+ * 在统一规范化生成 UUID 前先复用它;已落库 booking 仍按 schedule_event_id 派生稳定 UID。
4216
+ */
4217
+ seedAnonymousBookingUidsFromProducts(raw) {
4218
+ var _a, _b;
4219
+ if (!raw || typeof raw !== "object")
4220
+ return {};
4221
+ if (!Array.isArray(raw.bookings) || !Array.isArray(raw.products))
4222
+ return raw;
4223
+ const bookingUidsByProductUid = /* @__PURE__ */ new Map();
4224
+ for (const product of raw.products) {
4225
+ const productUid = (0, import_orderCollectionIdentity.getOrderCollectionUid)("product", product);
4226
+ const bookingUid = (product == null ? void 0 : product.booking_uid) || ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.booking_uid);
4227
+ if (!productUid || bookingUid === void 0 || bookingUid === null || bookingUid === "") {
4228
+ continue;
4229
+ }
4230
+ const candidates = bookingUidsByProductUid.get(productUid) || /* @__PURE__ */ new Set();
4231
+ candidates.add(String(bookingUid));
4232
+ bookingUidsByProductUid.set(productUid, candidates);
4233
+ }
4234
+ if (bookingUidsByProductUid.size === 0)
4235
+ return raw;
4236
+ const anonymousBookingCountByProductUid = /* @__PURE__ */ new Map();
4237
+ for (const booking of raw.bookings) {
4238
+ if ((0, import_orderCollectionIdentity.getOrderCollectionPersistentId)("booking", booking) || (0, import_orderCollectionIdentity.getOrderCollectionUid)("booking", booking)) {
4239
+ continue;
4240
+ }
4241
+ const productUid = (booking == null ? void 0 : booking.product_uid) || ((_b = booking == null ? void 0 : booking.metadata) == null ? void 0 : _b.product_uid);
4242
+ if (productUid === void 0 || productUid === null || productUid === "")
4243
+ continue;
4244
+ const key = String(productUid);
4245
+ anonymousBookingCountByProductUid.set(
4246
+ key,
4247
+ (anonymousBookingCountByProductUid.get(key) || 0) + 1
4248
+ );
4249
+ }
4250
+ return {
4251
+ ...raw,
4252
+ bookings: raw.bookings.map((booking) => {
4253
+ var _a2;
4254
+ if ((0, import_orderCollectionIdentity.getOrderCollectionPersistentId)("booking", booking) || (0, import_orderCollectionIdentity.getOrderCollectionUid)("booking", booking)) {
4255
+ return booking;
4256
+ }
4257
+ const productUid = (booking == null ? void 0 : booking.product_uid) || ((_a2 = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a2.product_uid);
4258
+ if (productUid === void 0 || productUid === null || productUid === "") {
4259
+ return booking;
4260
+ }
4261
+ const productUidKey = String(productUid);
4262
+ if (anonymousBookingCountByProductUid.get(productUidKey) !== 1) {
4263
+ return booking;
4264
+ }
4265
+ const bookingUidCandidates = bookingUidsByProductUid.get(productUidKey);
4266
+ const bookingUid = (bookingUidCandidates == null ? void 0 : bookingUidCandidates.size) === 1 ? [...bookingUidCandidates][0] : null;
4267
+ return bookingUid ? (0, import_orderCollectionIdentity.setOrderCollectionUid)("booking", booking, bookingUid) : booking;
4268
+ })
4269
+ };
4270
+ }
3675
4271
  normalizeTempOrderForRuntime(raw, options) {
3676
4272
  var _a, _b;
3677
4273
  const nextTempOrder = {
@@ -3697,7 +4293,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3697
4293
  nextTempOrder.metadata = raw.metadata && typeof raw.metadata === "object" ? { ...raw.metadata } : {};
3698
4294
  nextTempOrder.holder = raw.holder && typeof raw.holder === "object" ? { ...raw.holder } : null;
3699
4295
  const rawProducts = Array.isArray(raw.products) ? raw.products : [];
3700
- nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map((p) => this.normalizeHydratedOrderProduct(p)) : [];
4296
+ nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map((p) => this.normalizeHydratedOrderProduct(p, { makeEditMark: options == null ? void 0 : options.makeEditMark })) : [];
3701
4297
  nextTempOrder.bookings = Array.isArray(raw.bookings) ? raw.bookings.map((b) => {
3702
4298
  const booking = this.normalizeHydratedBookingHolder(b || {});
3703
4299
  return {
@@ -3786,12 +4382,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3786
4382
  if (!product.metadata || typeof product.metadata !== "object") {
3787
4383
  product.metadata = {};
3788
4384
  }
3789
- const linkedBookingUid = String(
3790
- product.booking_uid || product.metadata.booking_uid || bookingUid
3791
- );
4385
+ const linkedBookingUid = String(bookingUid);
3792
4386
  product.booking_uid = linkedBookingUid;
3793
4387
  product.metadata.booking_uid = linkedBookingUid;
3794
4388
  });
4389
+ this.syncLinkedBookingHoldersToProducts(tempOrder);
3795
4390
  }
3796
4391
  pickHydratedDisplayText(value) {
3797
4392
  if (value === void 0 || value === null)
@@ -3842,8 +4437,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3842
4437
  normalized.id = optionItem.id;
3843
4438
  return normalized;
3844
4439
  }
3845
- normalizeHydratedOrderProduct(product) {
3846
- const row = { ...product || {} };
4440
+ normalizeHydratedOrderProduct(product, options) {
4441
+ let row = { ...product || {} };
3847
4442
  if (row.num === void 0 && row.product_quantity !== void 0) {
3848
4443
  row.num = row.product_quantity;
3849
4444
  }
@@ -3864,10 +4459,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3864
4459
  if (row.booking_uid && !row.metadata.booking_uid) {
3865
4460
  row.metadata.booking_uid = row.booking_uid;
3866
4461
  }
4462
+ row = (0, import_bundleDiscountHydration.restoreHydratedBundleDiscounts)(row, import_utils.normalizeOrderProductDiscountList);
3867
4463
  const existingIdentity = row.metadata.unique_identification_number || row.unique_identification_number;
3868
4464
  if (!existingIdentity) {
3869
4465
  row.metadata.unique_identification_number = (0, import_utils.createUuidV4)();
3870
4466
  }
4467
+ if (options == null ? void 0 : options.makeEditMark) {
4468
+ row.metadata.is_edit_for_runtime = true;
4469
+ }
3871
4470
  const normalized = (0, import_utils3.normalizeOrderProduct)(row);
3872
4471
  normalized.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
3873
4472
  normalized.discount_list
@@ -3883,7 +4482,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3883
4482
  };
3884
4483
  if (result.metadata)
3885
4484
  delete result.metadata.price_schema_version;
3886
- return this.sanitizeOrderProductForTempOrder(result);
4485
+ const restored = (0, import_bundleDiscountHydration.restoreHydratedBundleDiscounts)(result, import_utils.normalizeOrderProductDiscountList);
4486
+ return this.sanitizeOrderProductForTempOrder(restored);
3887
4487
  }
3888
4488
  getLastOrderInfo() {
3889
4489
  var _a;
@@ -3897,6 +4497,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3897
4497
  });
3898
4498
  return res;
3899
4499
  }
4500
+ getVouchers() {
4501
+ var _a;
4502
+ return ((_a = this.store.tempOrder) == null ? void 0 : _a.vouchers) || [];
4503
+ }
3900
4504
  };
3901
4505
  // Annotate the CommonJS export names for ESM import in node:
3902
4506
  0 && (module.exports = {