@pisell/pisellos 2.2.256 → 2.2.258

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 (52) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  2. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +17 -13
  3. package/dist/modules/Order/index.d.ts +29 -1
  4. package/dist/modules/Order/index.js +508 -241
  5. package/dist/modules/Order/types.d.ts +20 -2
  6. package/dist/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  7. package/dist/modules/Order/utils/bundleDiscountHydration.js +144 -0
  8. package/dist/modules/Order/utils.d.ts +4 -0
  9. package/dist/modules/Order/utils.js +114 -28
  10. package/dist/modules/Product/index.d.ts +1 -1
  11. package/dist/modules/Product/types.d.ts +6 -0
  12. package/dist/modules/Rules/index.d.ts +3 -3
  13. package/dist/modules/Rules/index.js +8 -3
  14. package/dist/modules/Rules/types.d.ts +2 -1
  15. package/dist/server/index.d.ts +12 -2
  16. package/dist/server/index.js +1227 -923
  17. package/dist/server/modules/order/index.d.ts +22 -3
  18. package/dist/server/modules/order/index.js +397 -314
  19. package/dist/solution/BaseSales/index.d.ts +16 -2
  20. package/dist/solution/BaseSales/index.js +484 -314
  21. package/dist/solution/BaseSales/types.d.ts +1 -0
  22. package/dist/solution/BaseSales/types.js +2 -1
  23. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +4 -2
  24. package/dist/solution/BookingByStep/index.d.ts +1 -1
  25. package/dist/solution/BookingTicket/index.d.ts +9 -1
  26. package/dist/solution/BookingTicket/index.js +162 -6
  27. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +11 -1
  28. package/lib/modules/Order/index.d.ts +29 -1
  29. package/lib/modules/Order/index.js +340 -57
  30. package/lib/modules/Order/types.d.ts +20 -2
  31. package/lib/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  32. package/lib/modules/Order/utils/bundleDiscountHydration.js +139 -0
  33. package/lib/modules/Order/utils.d.ts +4 -0
  34. package/lib/modules/Order/utils.js +84 -2
  35. package/lib/modules/Product/index.d.ts +1 -1
  36. package/lib/modules/Product/types.d.ts +6 -0
  37. package/lib/modules/Rules/index.d.ts +3 -3
  38. package/lib/modules/Rules/index.js +4 -3
  39. package/lib/modules/Rules/types.d.ts +2 -1
  40. package/lib/server/index.d.ts +12 -2
  41. package/lib/server/index.js +218 -12
  42. package/lib/server/modules/order/index.d.ts +22 -3
  43. package/lib/server/modules/order/index.js +102 -51
  44. package/lib/solution/BaseSales/index.d.ts +16 -2
  45. package/lib/solution/BaseSales/index.js +143 -31
  46. package/lib/solution/BaseSales/types.d.ts +1 -0
  47. package/lib/solution/BaseSales/types.js +2 -1
  48. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +4 -5
  49. package/lib/solution/BookingByStep/index.d.ts +1 -1
  50. package/lib/solution/BookingTicket/index.d.ts +9 -1
  51. package/lib/solution/BookingTicket/index.js +112 -0
  52. package/package.json +1 -1
@@ -40,6 +40,7 @@ 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");
43
44
  var import_Discount = require("../Discount");
44
45
  var import_Rules = require("../Rules");
45
46
  var import_types2 = require("../Rules/types");
@@ -64,6 +65,23 @@ function isManualProductDiscountProduct(product) {
64
65
  var _a, _b;
65
66
  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
67
  }
68
+ var ORDER_PAYMENT_STATUS_PAID = "paid";
69
+ var ORDER_PAYMENT_STATUS_PENDING = "payment_pending";
70
+ function isVoucherPaymentRecord(payment) {
71
+ return (payment == null ? void 0 : payment.voucher_id) !== void 0 && Number(payment.voucher_id) !== 0;
72
+ }
73
+ function hasSyncedOrderPaymentRecord(payment) {
74
+ return (payment == null ? void 0 : payment.order_payment_id) !== void 0 && payment.order_payment_id !== null;
75
+ }
76
+ function isPendingVoucherPaymentRecord(payment) {
77
+ return isVoucherPaymentRecord(payment) && (payment == null ? void 0 : payment.status) === ORDER_PAYMENT_STATUS_PENDING;
78
+ }
79
+ function isPaidPaymentRecord(payment) {
80
+ return (payment == null ? void 0 : payment.status) === ORDER_PAYMENT_STATUS_PAID;
81
+ }
82
+ function isCommittedVoucherPaymentRecord(payment) {
83
+ return isVoucherPaymentRecord(payment) && (payment == null ? void 0 : payment.status) !== "voided" && (hasSyncedOrderPaymentRecord(payment) || isPaidPaymentRecord(payment));
84
+ }
67
85
  var OrderModule = class extends import_BaseModule.BaseModule {
68
86
  constructor(name, version) {
69
87
  super(name || "order", version);
@@ -91,7 +109,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
91
109
  collectHydratedEditDiscounts(products) {
92
110
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
93
111
  const discountMap = /* @__PURE__ */ new Map();
94
- for (const product of products || []) {
112
+ for (const product of (0, import_bundleDiscountHydration.expandHydratedProductsForDiscountCollection)(products)) {
95
113
  for (const item of (product == null ? void 0 : product.discount_list) || []) {
96
114
  const type = (item == null ? void 0 : item.type) ?? (item == null ? void 0 : item.tag);
97
115
  if (!type || type === "product")
@@ -114,6 +132,21 @@ var OrderModule = class extends import_BaseModule.BaseModule {
114
132
  discount: item == null ? void 0 : item.discount,
115
133
  _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
134
  };
135
+ const existed = discountMap.get(key);
136
+ if (existed) {
137
+ existed.amount = Number(existed.amount || 0) + amount;
138
+ existed.used_par_value = String(Number(existed.used_par_value || 0) + amount);
139
+ existed.balance = String(Number(existed.balance || 0) + amount);
140
+ existed.applicableProductDetails = [
141
+ ...existed.applicableProductDetails || [],
142
+ detail
143
+ ];
144
+ existed.appliedProductDetails = [
145
+ ...existed.appliedProductDetails || [],
146
+ detail
147
+ ];
148
+ continue;
149
+ }
117
150
  discountMap.set(key, {
118
151
  id: key,
119
152
  product_name: "",
@@ -236,6 +269,21 @@ var OrderModule = class extends import_BaseModule.BaseModule {
236
269
  product.metadata.main_product_selling_price = newMainSellingPrice;
237
270
  product.metadata.price_schema_version = 2;
238
271
  }
272
+ if (Array.isArray(product.product_bundle)) {
273
+ product.product_bundle = product.product_bundle.map((bundle) => {
274
+ const hasBundleDiscount = Array.isArray(bundle == null ? void 0 : bundle.discount_list) && bundle.discount_list.length > 0;
275
+ if (hasBundleDiscount)
276
+ return bundle;
277
+ const restoredPrice = (bundle == null ? void 0 : bundle.original_price) ?? (bundle == null ? void 0 : bundle.product_price) ?? (bundle == null ? void 0 : bundle.price);
278
+ if (restoredPrice === void 0 || restoredPrice === null || restoredPrice === "")
279
+ return bundle;
280
+ return {
281
+ ...bundle,
282
+ price: restoredPrice,
283
+ bundle_selling_price: restoredPrice
284
+ };
285
+ });
286
+ }
239
287
  product.selling_price = (0, import_utils.composeLinePrice)({
240
288
  mainPrice: newMainSellingPrice,
241
289
  bundle: product.product_bundle
@@ -434,7 +482,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
434
482
  });
435
483
  }
436
484
  async scanCode(code, customerId) {
437
- var _a, _b, _c, _d, _e;
485
+ var _a, _b, _c, _d;
438
486
  const resultDiscountWithReason = await ((_a = this.store.discount) == null ? void 0 : _a.batchSearch(code, { customerId })) || { discountList: [], unavailableReasonKey: null };
439
487
  const { discountList: resultDiscountList, unavailableReasonKey } = resultDiscountWithReason;
440
488
  const rulesModule = this.store.rules;
@@ -470,17 +518,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
470
518
  };
471
519
  }
472
520
  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 }] : [];
521
+ const holders = ((_b = tempOrder == null ? void 0 : tempOrder.holder) == null ? void 0 : _b.form_record) || [];
474
522
  const { isAvailable, discountList: newDiscountList, unavailableReason } = rulesModule.isDiscountListAvailable({
475
523
  productList: (tempOrder == null ? void 0 : tempOrder.products) || [],
476
524
  oldDiscountList: this.getDiscountList(),
477
525
  newDiscountList: withScanList,
478
526
  orderTotalAmount: Number(((_c = this.store.summary) == null ? void 0 : _c.total_amount) || 0),
479
527
  holders,
480
- isFormSubject: !!((_d = tempOrder == null ? void 0 : tempOrder.holder) == null ? void 0 : _d.type) && tempOrder.holder.type === "form"
528
+ isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product)
481
529
  }) || { isAvailable: false, discountList: this.getDiscountList() };
482
530
  if (isAvailable && newDiscountList) {
483
- (_e = this.store.discount) == null ? void 0 : _e.setDiscountList(newDiscountList);
531
+ (_d = this.store.discount) == null ? void 0 : _d.setDiscountList(newDiscountList);
484
532
  this.applyDiscount();
485
533
  }
486
534
  return {
@@ -492,24 +540,25 @@ var OrderModule = class extends import_BaseModule.BaseModule {
492
540
  };
493
541
  }
494
542
  applyDiscount() {
495
- var _a, _b, _c, _d, _e;
543
+ var _a, _b, _c, _d;
496
544
  const tempOrder = this.store.tempOrder;
497
545
  if (!tempOrder)
498
546
  return;
499
547
  delete tempOrder.discount_list;
500
- if (this.shouldSkipDiscountCalculation(tempOrder))
548
+ const discountList = ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList()) || [];
549
+ const shouldSkipDiscountCalculation = this.shouldSkipDiscountCalculation(tempOrder);
550
+ if (shouldSkipDiscountCalculation)
501
551
  return;
502
552
  const rulesModule = this.store.rules;
503
553
  if (!rulesModule)
504
554
  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 }] : [];
555
+ const holders = ((_b = tempOrder.holder) == null ? void 0 : _b.form_record) || [];
507
556
  const result = rulesModule.calcDiscount({
508
557
  productList: tempOrder.products,
509
558
  discountList,
510
559
  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)
560
+ isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
561
+ orderTotalAmount: Number(((_c = this.store.summary) == null ? void 0 : _c.total_amount) || 0)
513
562
  });
514
563
  if (result == null ? void 0 : result.productList) {
515
564
  const previousProductsByUid = (0, import_utils.indexOrderProductsByUid)(tempOrder.products);
@@ -538,7 +587,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
538
587
  result.productList || tempOrder.products,
539
588
  result.discountList
540
589
  );
541
- (_e = this.store.discount) == null ? void 0 : _e.setDiscountList(result.discountList);
590
+ (_d = this.store.discount) == null ? void 0 : _d.setDiscountList(result.discountList);
542
591
  }
543
592
  this.hasActiveCustomerBoundDiscount = (tempOrder.products || []).some(
544
593
  (product) => this.productHasCustomerBoundDiscount(product)
@@ -816,6 +865,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
816
865
  return (0, import_utils.mapPaymentItemsToOrderPayments)(payments, {
817
866
  includeVoided: false
818
867
  }).reduce((sum, payment) => {
868
+ if (!isPaidPaymentRecord(payment))
869
+ return sum;
819
870
  return sum.plus(this.calculatePaymentEffectiveAmount(payment));
820
871
  }, new import_decimal.default(0));
821
872
  }
@@ -825,6 +876,33 @@ var OrderModule = class extends import_BaseModule.BaseModule {
825
876
  normalizeDepositAmount(amount) {
826
877
  return import_decimal.default.max(new import_decimal.default(Number(amount) || 0), 0).toDecimalPlaces(2).toFixed(2);
827
878
  }
879
+ getLastOrderDepositSnapshot() {
880
+ var _a;
881
+ const lastOrderInfo = this.store.lastOrderInfo;
882
+ if (!lastOrderInfo || typeof lastOrderInfo !== "object")
883
+ return null;
884
+ const rawDepositAmount = lastOrderInfo.deposit_amount ?? ((_a = lastOrderInfo.summary) == null ? void 0 : _a.deposit_amount);
885
+ const depositAmount = this.normalizeDepositAmount(rawDepositAmount ?? 0);
886
+ const hasDepositAmount = new import_decimal.default(depositAmount).gt(0);
887
+ const isDeposit = Number(lastOrderInfo.is_deposit) === 1 || hasDepositAmount;
888
+ if (!isDeposit || !hasDepositAmount)
889
+ return null;
890
+ return {
891
+ isDeposit: 1,
892
+ depositAmount
893
+ };
894
+ }
895
+ getLastOrderSubmitSnapshot() {
896
+ const lastOrderInfo = this.store.lastOrderInfo;
897
+ if (!lastOrderInfo || typeof lastOrderInfo !== "object")
898
+ return {};
899
+ const businessCode = lastOrderInfo.business_code;
900
+ const type = lastOrderInfo.type;
901
+ return {
902
+ ...typeof businessCode === "string" && businessCode ? { businessCode } : {},
903
+ ...typeof type === "string" && type ? { type } : {}
904
+ };
905
+ }
828
906
  applyDepositAmountToSummary(tempOrder, summary, amount) {
829
907
  const depositAmount = this.normalizeDepositAmount(amount);
830
908
  const hasDepositAmount = new import_decimal.default(depositAmount).gt(0);
@@ -843,8 +921,27 @@ var OrderModule = class extends import_BaseModule.BaseModule {
843
921
  tempOrder.is_deposit = hasDepositAmount ? 1 : 0;
844
922
  return nextSummary;
845
923
  }
924
+ applyLastOrderDepositSnapshot(tempOrder, summary) {
925
+ const snapshot = this.getLastOrderDepositSnapshot();
926
+ if (!snapshot)
927
+ return summary;
928
+ const existedDeposit = summary.deposit && typeof summary.deposit === "object" ? summary.deposit : void 0;
929
+ const nextSummary = {
930
+ ...summary,
931
+ deposit_amount: snapshot.depositAmount,
932
+ deposit: {
933
+ ...existedDeposit || {},
934
+ total: snapshot.depositAmount,
935
+ deposit_policy_ids: (existedDeposit == null ? void 0 : existedDeposit.deposit_policy_ids) || [],
936
+ hasDeposit: true
937
+ }
938
+ };
939
+ tempOrder.deposit_amount = snapshot.depositAmount;
940
+ tempOrder.is_deposit = tempOrder.is_deposit === 0 && new import_decimal.default(tempOrder.deposit_amount || 0).gt(0) ? 0 : snapshot.isDeposit;
941
+ return nextSummary;
942
+ }
846
943
  isDepositOrder(tempOrder, depositAmount) {
847
- return tempOrder.is_deposit === 1 || depositAmount.gt(0);
944
+ return tempOrder.is_deposit === 1 && depositAmount.gt(0);
848
945
  }
849
946
  getOrderExpectedAmount(summary) {
850
947
  return new import_decimal.default(summary.expect_amount || summary.total_amount || 0);
@@ -857,10 +954,37 @@ var OrderModule = class extends import_BaseModule.BaseModule {
857
954
  return false;
858
955
  return params.paidAmount.gte(depositAmount);
859
956
  }
957
+ getPaymentCompletion(payments) {
958
+ const tempOrder = this.ensureTempOrder();
959
+ const summary = this.store.summary || (0, import_utils.createEmptySummary)();
960
+ const paymentList = payments || tempOrder.payments || [];
961
+ const refundAmount = this.getSummaryRefundAmount(summary);
962
+ const netPaidAmount = import_decimal.default.max(
963
+ this.calculatePaymentTotal(paymentList).minus(refundAmount),
964
+ 0
965
+ );
966
+ const depositAmount = this.getDepositAmount(tempOrder, summary);
967
+ const orderExpectedAmount = this.getOrderExpectedAmount(summary);
968
+ const isDepositFullyPaid = this.isDepositCovered({
969
+ tempOrder,
970
+ summary,
971
+ paidAmount: netPaidAmount
972
+ });
973
+ const isOrderFullyPaid = orderExpectedAmount.lte(0) ? true : netPaidAmount.gte(orderExpectedAmount);
974
+ const paymentStage = this.isDepositOrder(tempOrder, depositAmount) && !isDepositFullyPaid ? "deposit" : "normal";
975
+ return {
976
+ isFullyPaid: isOrderFullyPaid,
977
+ isOrderFullyPaid,
978
+ isDepositFullyPaid,
979
+ paymentStage,
980
+ depositAmount: depositAmount.toFixed(2),
981
+ orderExpectedAmount: orderExpectedAmount.toFixed(2)
982
+ };
983
+ }
860
984
  calculateDepositPaidAmount(payments) {
861
985
  return (payments || []).reduce((sum, payment) => {
862
986
  const paymentRecord = payment;
863
- if ((paymentRecord == null ? void 0 : paymentRecord.status) !== "paid")
987
+ if (!isPaidPaymentRecord(paymentRecord))
864
988
  return sum;
865
989
  const isDepositPayment = paymentRecord.type === "deposit" || paymentRecord.order_payment_type === "deposit";
866
990
  if (!isDepositPayment)
@@ -1011,7 +1135,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1011
1135
  return (payments || []).reduce(
1012
1136
  (summary, payment) => {
1013
1137
  const paymentRecord = payment;
1014
- if ((paymentRecord == null ? void 0 : paymentRecord.status) !== "paid")
1138
+ if (!isPaidPaymentRecord(paymentRecord))
1015
1139
  return summary;
1016
1140
  return {
1017
1141
  customerPaidAmount: summary.customerPaidAmount.plus(paymentRecord.amount || 0),
@@ -1437,6 +1561,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1437
1561
  }
1438
1562
  restoreOrder() {
1439
1563
  var _a, _b;
1564
+ this.logInfo("restoreOrder start", {});
1440
1565
  const freshTempOrder = this.createDefaultTempOrderInstance();
1441
1566
  this.ensureExternalSaleNumber(freshTempOrder);
1442
1567
  this.store.tempOrder = freshTempOrder;
@@ -1515,7 +1640,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1515
1640
  orderPaidAmount: paidPaymentSummary.gapPaidAmount
1516
1641
  });
1517
1642
  return {
1518
- isDeposit: tempOrder.is_deposit === 1 || depositAmount !== "0.00",
1643
+ isDeposit: tempOrder.is_deposit === 1,
1519
1644
  depositAmount,
1520
1645
  expectAmount: summary.expect_amount || "0.00",
1521
1646
  totalAmount: summary.total_amount || "0.00",
@@ -1800,9 +1925,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1800
1925
  hasDeposit: true
1801
1926
  } : void 0
1802
1927
  };
1928
+ const isExistingDepositDisabled = tempOrder.is_deposit === 0 && new import_decimal.default(tempOrder.deposit_amount || 0).gt(0);
1803
1929
  tempOrder.deposit_amount = depositAmount;
1804
- tempOrder.is_deposit = hasDepositAmount ? 1 : 0;
1805
- return nextSummary;
1930
+ tempOrder.is_deposit = hasDepositAmount && !isExistingDepositDisabled ? 1 : 0;
1931
+ return this.applyLastOrderDepositSnapshot(tempOrder, nextSummary);
1806
1932
  }
1807
1933
  async recalculateSummary(options) {
1808
1934
  const tempOrder = (options == null ? void 0 : options.createIfMissing) ? this.ensureTempOrder() : this.store.tempOrder;
@@ -2146,6 +2272,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2146
2272
  if (String(previousCustomerId ?? "") !== String(nextCustomerId ?? "")) {
2147
2273
  (0, import_utils.clearTempOrderHolderAssignments)(tempOrder);
2148
2274
  this.clearCustomerBoundDiscounts(tempOrder);
2275
+ this.applyDiscount();
2149
2276
  }
2150
2277
  this.persistTempOrder();
2151
2278
  this.saveDraftInBackground();
@@ -2303,49 +2430,153 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2303
2430
  this.persistTempOrder();
2304
2431
  return tempOrder.payments;
2305
2432
  }
2433
+ confirmPendingVoucherPaymentsInList(payments) {
2434
+ return (payments || []).map((payment) => {
2435
+ if (!isPendingVoucherPaymentRecord(payment))
2436
+ return payment;
2437
+ return {
2438
+ ...payment,
2439
+ status: ORDER_PAYMENT_STATUS_PAID
2440
+ };
2441
+ });
2442
+ }
2443
+ discardPendingVoucherPaymentsFromList(payments) {
2444
+ return (payments || []).filter((payment) => !isPendingVoucherPaymentRecord(payment));
2445
+ }
2446
+ prepareVoucherPaymentsForSubmit(payments, confirmPendingVoucherPayments = true) {
2447
+ const mappedPayments = (0, import_utils.mapPaymentItemsToOrderPayments)(payments || []);
2448
+ return confirmPendingVoucherPayments ? this.confirmPendingVoucherPaymentsInList(mappedPayments) : this.discardPendingVoucherPaymentsFromList(mappedPayments);
2449
+ }
2450
+ applyPaymentLifecycleChange(tempOrder, options) {
2451
+ this.updateTempOrderPaymentStatus(tempOrder);
2452
+ if ((options == null ? void 0 : options.persist) !== false) {
2453
+ this.persistTempOrder();
2454
+ }
2455
+ if ((options == null ? void 0 : options.recalculateSummary) === false)
2456
+ return;
2457
+ const logContext = (options == null ? void 0 : options.logContext) || "payment lifecycle change";
2458
+ void this.recalculateSummary({ createIfMissing: true }).catch((error) => {
2459
+ this.logError(`recalculate summary after ${logContext} failed`, {
2460
+ error: error instanceof Error ? error.message : String(error)
2461
+ });
2462
+ });
2463
+ }
2464
+ confirmPendingVoucherPayments(options) {
2465
+ const tempOrder = this.ensureTempOrder();
2466
+ const payments = tempOrder.payments || [];
2467
+ const hasPendingVoucher = payments.some((payment) => isPendingVoucherPaymentRecord(payment));
2468
+ if (!hasPendingVoucher)
2469
+ return payments;
2470
+ tempOrder.payments = this.confirmPendingVoucherPaymentsInList(payments);
2471
+ this.applyPaymentLifecycleChange(tempOrder, {
2472
+ ...options,
2473
+ logContext: "confirmPendingVoucherPayments"
2474
+ });
2475
+ return tempOrder.payments;
2476
+ }
2477
+ discardPendingVoucherPayments(options) {
2478
+ const tempOrder = this.ensureTempOrder();
2479
+ const payments = tempOrder.payments || [];
2480
+ const nextPayments = this.discardPendingVoucherPaymentsFromList(payments);
2481
+ if (nextPayments.length === payments.length)
2482
+ return payments;
2483
+ tempOrder.payments = nextPayments;
2484
+ this.applyPaymentLifecycleChange(tempOrder, {
2485
+ ...options,
2486
+ logContext: "discardPendingVoucherPayments"
2487
+ });
2488
+ return tempOrder.payments;
2489
+ }
2306
2490
  /**
2307
2491
  * 覆盖当前订单中的 wallet pass 支付项。
2308
2492
  *
2309
2493
  * 判断口径与 PaymentModal 保持一致:voucher_id 存在且不为 0 的支付项
2310
2494
  * 视为 wallet pass;其它支付项保持不变。
2311
2495
  */
2312
- updateVoucherOrderPayments(payments) {
2496
+ updateVoucherOrderPayments(payments, options) {
2313
2497
  const tempOrder = this.ensureTempOrder();
2314
- const isVoucherPayment = (payment) => {
2315
- return payment.voucher_id !== void 0 && Number(payment.voucher_id) !== 0;
2498
+ const isOrderPaymentType = (value) => {
2499
+ return value === "normal" || value === "deposit";
2316
2500
  };
2317
- const hasSyncedOrderPayment = (payment) => {
2318
- return payment.order_payment_id !== void 0 && payment.order_payment_id !== null;
2501
+ const voucherOrderPaymentType = this.resolveNextOrderPaymentType(tempOrder);
2502
+ const withVoucherPaymentType = (payment) => {
2503
+ const paymentRecord = payment;
2504
+ if (!isVoucherPaymentRecord(paymentRecord))
2505
+ return payment;
2506
+ const explicitPaymentType = isOrderPaymentType(paymentRecord.order_payment_type) ? paymentRecord.order_payment_type : isOrderPaymentType(paymentRecord.type) ? paymentRecord.type : void 0;
2507
+ const nextPaymentType = explicitPaymentType || voucherOrderPaymentType;
2508
+ const shouldPreserveCustomPaymentType = paymentRecord.custom_payment_type === void 0 && paymentRecord.type !== void 0 && !isOrderPaymentType(paymentRecord.type);
2509
+ return {
2510
+ ...paymentRecord,
2511
+ ...shouldPreserveCustomPaymentType ? { custom_payment_type: paymentRecord.type } : {},
2512
+ type: nextPaymentType,
2513
+ order_payment_type: nextPaymentType
2514
+ };
2515
+ };
2516
+ const normalizeVoucherPaymentStatus = (payment) => {
2517
+ const paymentRecord = payment;
2518
+ if (!isVoucherPaymentRecord(paymentRecord))
2519
+ return payment;
2520
+ if (hasSyncedOrderPaymentRecord(paymentRecord) && (paymentRecord.status === void 0 || paymentRecord.status === "active")) {
2521
+ return {
2522
+ ...paymentRecord,
2523
+ status: ORDER_PAYMENT_STATUS_PAID
2524
+ };
2525
+ }
2526
+ if (paymentRecord.status !== void 0 && paymentRecord.status !== "active") {
2527
+ return payment;
2528
+ }
2529
+ return {
2530
+ ...paymentRecord,
2531
+ status: (options == null ? void 0 : options.status) || ORDER_PAYMENT_STATUS_PENDING
2532
+ };
2319
2533
  };
2320
2534
  const mappedVouchers = (0, import_utils.mapPaymentItemsToOrderPayments)(
2321
2535
  payments.map(
2322
- (payment) => this.normalizePaymentSource(payment, { defaultPaid: true })
2536
+ (payment) => this.normalizePaymentSource(
2537
+ normalizeVoucherPaymentStatus(withVoucherPaymentType(payment)),
2538
+ { defaultPaid: false }
2539
+ )
2323
2540
  )
2324
2541
  ).filter((payment) => {
2325
- return isVoucherPayment(payment);
2542
+ return isVoucherPaymentRecord(payment);
2326
2543
  });
2327
2544
  const nonVoucherPayments = (tempOrder.payments || []).filter((payment) => {
2328
- return !isVoucherPayment(payment);
2329
- });
2330
- const syncedVoucherPayments = (tempOrder.payments || []).filter((payment) => {
2331
- return isVoucherPayment(payment) && hasSyncedOrderPayment(payment);
2545
+ return !isVoucherPaymentRecord(payment);
2332
2546
  });
2333
- const syncedVoucherPaymentIds = new Set(
2334
- syncedVoucherPayments.map((payment) => String(payment.order_payment_id))
2547
+ const normalizeCommittedVoucherPayment = (payment) => {
2548
+ if (hasSyncedOrderPaymentRecord(payment) && (payment.status === void 0 || payment.status === "active")) {
2549
+ return {
2550
+ ...payment,
2551
+ status: ORDER_PAYMENT_STATUS_PAID
2552
+ };
2553
+ }
2554
+ return payment;
2555
+ };
2556
+ const committedVoucherPayments = (tempOrder.payments || []).filter((payment) => isCommittedVoucherPaymentRecord(payment)).map((payment) => normalizeCommittedVoucherPayment(payment));
2557
+ const committedVoucherPaymentIds = new Set(
2558
+ committedVoucherPayments.filter((payment) => hasSyncedOrderPaymentRecord(payment)).map((payment) => String(payment.order_payment_id))
2559
+ );
2560
+ const committedVoucherIds = new Set(
2561
+ committedVoucherPayments.map((payment) => String(payment.voucher_id))
2335
2562
  );
2336
2563
  const replaceableVouchers = mappedVouchers.filter((payment) => {
2337
- if (!hasSyncedOrderPayment(payment))
2338
- return true;
2339
- return !syncedVoucherPaymentIds.has(String(payment.order_payment_id));
2564
+ if (hasSyncedOrderPaymentRecord(payment) && committedVoucherPaymentIds.has(String(payment.order_payment_id))) {
2565
+ return false;
2566
+ }
2567
+ if (payment.voucher_id !== void 0 && committedVoucherIds.has(String(payment.voucher_id))) {
2568
+ return false;
2569
+ }
2570
+ return true;
2340
2571
  });
2341
2572
  const cappedVouchers = this.capVoucherPaymentsByRemainingAmount({
2342
2573
  vouchers: replaceableVouchers,
2343
2574
  nonVoucherPayments: [
2344
2575
  ...nonVoucherPayments,
2345
- ...syncedVoucherPayments
2576
+ ...committedVoucherPayments
2346
2577
  ]
2347
2578
  });
2348
- tempOrder.payments = [...nonVoucherPayments, ...syncedVoucherPayments, ...cappedVouchers];
2579
+ tempOrder.payments = [...nonVoucherPayments, ...committedVoucherPayments, ...cappedVouchers];
2349
2580
  this.updateTempOrderPaymentStatus(tempOrder);
2350
2581
  this.persistTempOrder();
2351
2582
  void this.recalculateSummary({ createIfMissing: true }).catch((error) => {
@@ -2561,7 +2792,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2561
2792
  */
2562
2793
  async addProductToOrder(product, booking) {
2563
2794
  const tempOrder = this.ensureTempOrder();
2564
- debugger;
2565
2795
  if (booking) {
2566
2796
  const productRecord = product;
2567
2797
  const splitCount = (0, import_utils3.getSafeProductNum)(
@@ -2584,6 +2814,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2584
2814
  }
2585
2815
  await this.appendProductLineToTempOrder(tempOrder, product, booking);
2586
2816
  await this.finalizeProductOrderMutation(tempOrder);
2817
+ this.logInfo("addProductToOrder success", {
2818
+ product_id: product.product_id,
2819
+ with_booking: !!booking
2820
+ });
2587
2821
  return tempOrder.products;
2588
2822
  }
2589
2823
  /**
@@ -2625,6 +2859,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2625
2859
  await this.appendProductLineToTempOrder(tempOrder, product, booking);
2626
2860
  }
2627
2861
  await this.finalizeProductOrderMutation(tempOrder, options);
2862
+ this.logInfo("addProductsToOrder success", {
2863
+ itemsCount: items.length
2864
+ });
2628
2865
  return tempOrder.products;
2629
2866
  }
2630
2867
  hasGoodPassDiscount(product) {
@@ -2847,6 +3084,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2847
3084
  this.sanitizeTempOrderProducts(tempOrder);
2848
3085
  await this.recalculateSummary({ createIfMissing: true });
2849
3086
  this.persistTempOrder();
3087
+ this.logInfo("updateOrderProduct success", {
3088
+ params
3089
+ });
2850
3090
  return tempOrder.products;
2851
3091
  }
2852
3092
  async updateOrderProducts(paramsList) {
@@ -2858,6 +3098,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2858
3098
  this.applyOrderProductUpdateToTempOrder(tempOrder, params);
2859
3099
  });
2860
3100
  await this.finalizeAfterProductsMutation(tempOrder);
3101
+ this.logInfo("updateOrderProduct success", {
3102
+ paramsList
3103
+ });
2861
3104
  return tempOrder.products;
2862
3105
  }
2863
3106
  async updateOrderProductQuantity(params) {
@@ -2922,6 +3165,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2922
3165
  this.sanitizeTempOrderProducts(tempOrder);
2923
3166
  await this.recalculateSummary({ createIfMissing: true });
2924
3167
  this.persistTempOrder();
3168
+ this.logInfo("updateOrderProductQuantity success", {
3169
+ params
3170
+ });
2925
3171
  return tempOrder.products;
2926
3172
  }
2927
3173
  updateOrderBooking(params) {
@@ -3023,6 +3269,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3023
3269
  });
3024
3270
  }
3025
3271
  await this.finalizeAfterProductsMutation(tempOrder);
3272
+ this.logInfo("removeProductsFromOrder success", {
3273
+ identities
3274
+ });
3026
3275
  return tempOrder.products;
3027
3276
  }
3028
3277
  async removeProductFromOrder(identity) {
@@ -3048,6 +3297,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3048
3297
  this.sanitizeTempOrderProducts(tempOrder);
3049
3298
  await this.recalculateSummary({ createIfMissing: true });
3050
3299
  this.persistTempOrder();
3300
+ this.logInfo("clearOrderCartLines success", {});
3051
3301
  return tempOrder;
3052
3302
  }
3053
3303
  // ─── TempOrder: 提交 ───
@@ -3108,37 +3358,55 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3108
3358
  async runSubmitTempOrder(params) {
3109
3359
  var _a, _b, _c, _d, _e;
3110
3360
  const tempOrder = this.ensureTempOrder();
3361
+ const shouldConfirmPendingVoucherPayments = (params == null ? void 0 : params.confirmPendingVoucherPayments) !== false;
3362
+ const hasPaymentOverride = (params == null ? void 0 : params.payments) !== void 0;
3363
+ const preparedPaymentOverride = hasPaymentOverride ? this.prepareVoucherPaymentsForSubmit(
3364
+ (params == null ? void 0 : params.payments) || [],
3365
+ shouldConfirmPendingVoucherPayments
3366
+ ) : void 0;
3367
+ if (!hasPaymentOverride) {
3368
+ if (shouldConfirmPendingVoucherPayments) {
3369
+ this.confirmPendingVoucherPayments({
3370
+ persist: false,
3371
+ recalculateSummary: false
3372
+ });
3373
+ } else {
3374
+ this.discardPendingVoucherPayments({
3375
+ persist: false,
3376
+ recalculateSummary: false
3377
+ });
3378
+ }
3379
+ }
3111
3380
  this.persistTempOrder();
3112
3381
  const latestSummary = await this.recalculateSummary({ createIfMissing: true }) || this.store.summary || (0, import_utils.createEmptySummary)();
3113
3382
  const effectiveCacheId = (params == null ? void 0 : params.cacheId) ?? this.cacheId;
3114
- const hasPaymentOverride = (params == null ? void 0 : params.payments) !== void 0;
3115
3383
  const hasPaymentStatusOverride = (params == null ? void 0 : params.paymentStatus) !== void 0;
3116
3384
  const hasSmallTicketDataFlagOverride = (params == null ? void 0 : params.smallTicketDataFlag) !== void 0;
3117
3385
  const enhancePayload = hasPaymentOverride || hasPaymentStatusOverride || hasSmallTicketDataFlagOverride || (params == null ? void 0 : params.enhancePayload) ? (payload2, ctx) => {
3118
3386
  const nextPayload = {
3119
3387
  ...payload2,
3120
3388
  ...hasPaymentOverride ? {
3121
- payments: (0, import_utils.mapPaymentItemsToOrderPayments)(
3122
- (params == null ? void 0 : params.payments) || []
3123
- )
3389
+ payments: preparedPaymentOverride || []
3124
3390
  } : {},
3125
- ...hasPaymentStatusOverride ? { payment_status: params == null ? void 0 : params.paymentStatus } : {},
3391
+ ...hasPaymentStatusOverride && !shouldConfirmPendingVoucherPayments ? { payment_status: params == null ? void 0 : params.paymentStatus } : {},
3126
3392
  ...hasSmallTicketDataFlagOverride ? { small_ticket_data_flag: params == null ? void 0 : params.smallTicketDataFlag } : {}
3127
3393
  };
3128
3394
  const enhancedPayload = (params == null ? void 0 : params.enhancePayload) ? params.enhancePayload(nextPayload, ctx) : nextPayload;
3129
3395
  return enhancedPayload;
3130
3396
  } : void 0;
3397
+ const submitSnapshot = this.getLastOrderSubmitSnapshot();
3131
3398
  const payload = (0, import_utils.buildSubmitPayload)({
3132
3399
  tempOrder,
3133
3400
  cacheId: effectiveCacheId,
3134
3401
  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),
3402
+ 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
3403
  channel: params == null ? void 0 : params.channel,
3137
- type: params == null ? void 0 : params.type,
3404
+ type: submitSnapshot.type ?? (params == null ? void 0 : params.type),
3138
3405
  summary: latestSummary,
3139
3406
  request_unique_idempotency_token: params == null ? void 0 : params.request_unique_idempotency_token,
3140
3407
  enhance: enhancePayload
3141
3408
  });
3409
+ console.log("[Order.runSubmitTempOrder.payload]", payload);
3142
3410
  if (params == null ? void 0 : params.syncMode) {
3143
3411
  payload.sync_mode = true;
3144
3412
  }
@@ -3186,7 +3454,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3186
3454
  this.logInfo("runSubmitTempOrder: 提交成功", {
3187
3455
  submittedOrderId,
3188
3456
  result,
3189
- tempOrder
3457
+ tempOrder: {
3458
+ ...tempOrder,
3459
+ _extend: void 0
3460
+ }
3190
3461
  });
3191
3462
  if (submittedOrderId !== null && submittedOrderId !== void 0) {
3192
3463
  tempOrder.order_id = submittedOrderId;
@@ -3272,31 +3543,33 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3272
3543
  const mappedPayments = (0, import_utils.mapPaymentItemsToOrderPayments)(
3273
3544
  params.payments || []
3274
3545
  );
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;
3546
+ const shouldConfirmPendingVoucherPayments = params.confirmPendingVoucherPayments ?? params.submitWhenPaid === true;
3547
+ const effectivePayments = shouldConfirmPendingVoucherPayments ? this.confirmPendingVoucherPaymentsInList(mappedPayments) : params.confirmPendingVoucherPayments === false ? this.discardPendingVoucherPaymentsFromList(mappedPayments) : mappedPayments;
3548
+ const completion = this.getPaymentCompletion(effectivePayments);
3549
+ const paidPaymentTotal = this.calculatePaymentTotal(effectivePayments);
3550
+ const paymentStatus = completion.isOrderFullyPaid ? params.paymentStatus || "paid" : paidPaymentTotal.gt(0) ? "partially_paid" : "payment_processing";
3551
+ tempOrder.payments = effectivePayments;
3280
3552
  tempOrder.payment_status = paymentStatus;
3281
3553
  this.persistTempOrder();
3282
3554
  await this.saveDraft();
3283
3555
  if (!params.submitWhenPaid) {
3284
- return { isFullyPaid };
3556
+ return completion;
3285
3557
  }
3286
3558
  if (this.store.syncState === "submitting") {
3287
- return { isFullyPaid };
3559
+ return completion;
3288
3560
  }
3289
3561
  this.store.syncState = "submitting";
3290
3562
  const paymentSyncIdempotencyToken = this.buildPaymentSyncIdempotencyToken(
3291
3563
  tempOrder,
3292
- mappedPayments
3564
+ effectivePayments
3293
3565
  );
3294
3566
  const submitResult = await this.submitTempOrder({
3295
- payments: mappedPayments,
3567
+ payments: effectivePayments,
3296
3568
  paymentStatus,
3297
3569
  smallTicketDataFlag: params.smallTicketDataFlag,
3298
3570
  businessCode: params.businessCode,
3299
3571
  channel: params.channel,
3572
+ confirmPendingVoucherPayments: true,
3300
3573
  enhancePayload: (payload) => {
3301
3574
  const nextPayload = {
3302
3575
  ...payload,
@@ -3305,7 +3578,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3305
3578
  return nextPayload;
3306
3579
  }
3307
3580
  });
3308
- return { isFullyPaid, submitResult };
3581
+ return { ...completion, submitResult };
3309
3582
  }
3310
3583
  createOrder(params) {
3311
3584
  var _a;
@@ -3639,6 +3912,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3639
3912
  const currentDiscounts = typeof ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList) === "function" ? this.store.discount.getDiscountList() || [] : [];
3640
3913
  const shouldSkipEmptyDiscountSync = hydratedEditDiscounts.length === 0 && currentDiscounts.length === 0;
3641
3914
  if (!shouldSkipEmptyDiscountSync) {
3915
+ OrderModule.populateSavedAmounts(
3916
+ nextTempOrder.products,
3917
+ hydratedEditDiscounts
3918
+ );
3642
3919
  await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(hydratedEditDiscounts));
3643
3920
  await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(hydratedEditDiscounts));
3644
3921
  }
@@ -3843,7 +4120,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3843
4120
  return normalized;
3844
4121
  }
3845
4122
  normalizeHydratedOrderProduct(product) {
3846
- const row = { ...product || {} };
4123
+ let row = { ...product || {} };
3847
4124
  if (row.num === void 0 && row.product_quantity !== void 0) {
3848
4125
  row.num = row.product_quantity;
3849
4126
  }
@@ -3864,6 +4141,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3864
4141
  if (row.booking_uid && !row.metadata.booking_uid) {
3865
4142
  row.metadata.booking_uid = row.booking_uid;
3866
4143
  }
4144
+ row = (0, import_bundleDiscountHydration.restoreHydratedBundleDiscounts)(row, import_utils.normalizeOrderProductDiscountList);
3867
4145
  const existingIdentity = row.metadata.unique_identification_number || row.unique_identification_number;
3868
4146
  if (!existingIdentity) {
3869
4147
  row.metadata.unique_identification_number = (0, import_utils.createUuidV4)();
@@ -3883,7 +4161,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3883
4161
  };
3884
4162
  if (result.metadata)
3885
4163
  delete result.metadata.price_schema_version;
3886
- return this.sanitizeOrderProductForTempOrder(result);
4164
+ const restored = (0, import_bundleDiscountHydration.restoreHydratedBundleDiscounts)(result, import_utils.normalizeOrderProductDiscountList);
4165
+ return this.sanitizeOrderProductForTempOrder(restored);
3887
4166
  }
3888
4167
  getLastOrderInfo() {
3889
4168
  var _a;
@@ -3897,6 +4176,10 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3897
4176
  });
3898
4177
  return res;
3899
4178
  }
4179
+ getVouchers() {
4180
+ var _a;
4181
+ return ((_a = this.store.tempOrder) == null ? void 0 : _a.vouchers) || [];
4182
+ }
3900
4183
  };
3901
4184
  // Annotate the CommonJS export names for ESM import in node:
3902
4185
  0 && (module.exports = {