@pisell/pisellos 2.1.113 → 2.1.114

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 (98) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +1 -0
  3. package/dist/model/index.d.ts +1 -0
  4. package/dist/model/index.js +1 -0
  5. package/dist/model/strategy/adapter/index.d.ts +3 -0
  6. package/dist/model/strategy/adapter/index.js +4 -0
  7. package/dist/model/strategy/adapter/type.d.ts +28 -0
  8. package/dist/model/strategy/adapter/type.js +1 -0
  9. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +84 -0
  10. package/dist/model/strategy/adapter/walletPass/evaluator.js +499 -0
  11. package/dist/model/strategy/adapter/walletPass/example.d.ts +4 -0
  12. package/dist/model/strategy/adapter/walletPass/example.js +258 -0
  13. package/dist/model/strategy/adapter/walletPass/index.d.ts +32 -0
  14. package/dist/model/strategy/adapter/walletPass/index.js +182 -0
  15. package/dist/model/strategy/adapter/walletPass/locales.d.ts +1 -0
  16. package/dist/model/strategy/adapter/walletPass/locales.js +26 -0
  17. package/dist/model/strategy/adapter/walletPass/type.d.ts +187 -0
  18. package/dist/model/strategy/adapter/walletPass/type.js +1 -0
  19. package/dist/model/strategy/adapter/walletPass/utils.d.ts +50 -0
  20. package/dist/model/strategy/adapter/walletPass/utils.js +1104 -0
  21. package/dist/model/strategy/index.d.ts +94 -0
  22. package/dist/model/strategy/index.js +551 -0
  23. package/dist/model/strategy/strategy-example.d.ts +5 -0
  24. package/dist/model/strategy/strategy-example.js +331 -0
  25. package/dist/model/strategy/type.d.ts +228 -0
  26. package/dist/model/strategy/type.js +94 -0
  27. package/dist/modules/Cart/types.d.ts +2 -0
  28. package/dist/modules/Cart/utils/cartProduct.js +56 -24
  29. package/dist/modules/Discount/types.d.ts +18 -0
  30. package/dist/modules/Payment/index.d.ts +2 -1
  31. package/dist/modules/Payment/index.js +10 -7
  32. package/dist/modules/Payment/utils.js +3 -0
  33. package/dist/modules/Payment/walletpass.d.ts +23 -0
  34. package/dist/modules/Payment/walletpass.js +191 -95
  35. package/dist/modules/Product/index.d.ts +1 -1
  36. package/dist/modules/Rules/index.d.ts +9 -5
  37. package/dist/modules/Rules/index.js +664 -152
  38. package/dist/modules/Rules/types.d.ts +2 -0
  39. package/dist/modules/Summary/types.d.ts +2 -0
  40. package/dist/modules/Summary/utils.d.ts +6 -0
  41. package/dist/modules/Summary/utils.js +21 -0
  42. package/dist/plugins/window.d.ts +2 -0
  43. package/dist/solution/BookingByStep/index.d.ts +1 -0
  44. package/dist/solution/Checkout/index.js +2 -0
  45. package/dist/solution/ShopDiscount/index.d.ts +1 -0
  46. package/dist/solution/ShopDiscount/index.js +23 -7
  47. package/dist/solution/ShopDiscount/types.d.ts +1 -0
  48. package/dist/solution/ShopDiscount/types.js +2 -1
  49. package/dist/solution/ShopDiscount/utils.js +26 -12
  50. package/lib/index.d.ts +1 -0
  51. package/lib/index.js +3 -1
  52. package/lib/model/index.d.ts +1 -0
  53. package/lib/model/index.js +23 -0
  54. package/lib/model/strategy/adapter/index.d.ts +3 -0
  55. package/lib/model/strategy/adapter/index.js +45 -0
  56. package/lib/model/strategy/adapter/type.d.ts +28 -0
  57. package/lib/model/strategy/adapter/type.js +17 -0
  58. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +84 -0
  59. package/lib/model/strategy/adapter/walletPass/evaluator.js +423 -0
  60. package/lib/model/strategy/adapter/walletPass/example.d.ts +4 -0
  61. package/lib/model/strategy/adapter/walletPass/example.js +207 -0
  62. package/lib/model/strategy/adapter/walletPass/index.d.ts +32 -0
  63. package/lib/model/strategy/adapter/walletPass/index.js +142 -0
  64. package/lib/model/strategy/adapter/walletPass/locales.d.ts +1 -0
  65. package/lib/model/strategy/adapter/walletPass/locales.js +54 -0
  66. package/lib/model/strategy/adapter/walletPass/type.d.ts +187 -0
  67. package/lib/model/strategy/adapter/walletPass/type.js +17 -0
  68. package/lib/model/strategy/adapter/walletPass/utils.d.ts +50 -0
  69. package/lib/model/strategy/adapter/walletPass/utils.js +791 -0
  70. package/lib/model/strategy/index.d.ts +94 -0
  71. package/lib/model/strategy/index.js +413 -0
  72. package/lib/model/strategy/strategy-example.d.ts +5 -0
  73. package/lib/model/strategy/strategy-example.js +318 -0
  74. package/lib/model/strategy/type.d.ts +228 -0
  75. package/lib/model/strategy/type.js +44 -0
  76. package/lib/modules/Cart/types.d.ts +2 -0
  77. package/lib/modules/Cart/utils/cartProduct.js +39 -11
  78. package/lib/modules/Discount/types.d.ts +18 -0
  79. package/lib/modules/Payment/index.d.ts +2 -1
  80. package/lib/modules/Payment/index.js +1 -0
  81. package/lib/modules/Payment/utils.js +3 -0
  82. package/lib/modules/Payment/walletpass.d.ts +23 -0
  83. package/lib/modules/Payment/walletpass.js +94 -17
  84. package/lib/modules/Product/index.d.ts +1 -1
  85. package/lib/modules/Rules/index.d.ts +9 -5
  86. package/lib/modules/Rules/index.js +779 -284
  87. package/lib/modules/Rules/types.d.ts +2 -0
  88. package/lib/modules/Summary/types.d.ts +2 -0
  89. package/lib/modules/Summary/utils.d.ts +6 -0
  90. package/lib/modules/Summary/utils.js +15 -0
  91. package/lib/plugins/window.d.ts +2 -0
  92. package/lib/solution/BookingByStep/index.d.ts +1 -0
  93. package/lib/solution/Checkout/index.js +2 -0
  94. package/lib/solution/ShopDiscount/index.d.ts +1 -0
  95. package/lib/solution/ShopDiscount/index.js +22 -8
  96. package/lib/solution/ShopDiscount/types.d.ts +1 -0
  97. package/lib/solution/ShopDiscount/utils.js +10 -6
  98. package/package.json +1 -1
@@ -50,6 +50,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
50
50
  this.core = core;
51
51
  this.hooks = options == null ? void 0 : options.hooks;
52
52
  this.store = options == null ? void 0 : options.store;
53
+ this.window = core.getPlugin("window");
53
54
  }
54
55
  async setRulesList(rulesList) {
55
56
  this.store.rulesList = rulesList;
@@ -71,11 +72,16 @@ var RulesModule = class extends import_BaseModule.BaseModule {
71
72
  return false;
72
73
  return (productHolderId || orderHolderId) === discount.holder.holder_id;
73
74
  }
75
+ getWalletPassEvaluator() {
76
+ var _a, _b;
77
+ return (_b = (_a = this.window).getWalletPassEvaluator) == null ? void 0 : _b.call(_a);
78
+ }
74
79
  // 判断discountList 是否可以对当前productList生效
75
80
  isDiscountListAvailable({
76
81
  oldDiscountList,
77
82
  newDiscountList,
78
83
  productList,
84
+ orderTotalAmount,
79
85
  holders,
80
86
  isFormSubject
81
87
  }) {
@@ -108,6 +114,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
108
114
  const result = this.calcDiscount({
109
115
  discountList: mergedDiscountList,
110
116
  productList: [...productList],
117
+ orderTotalAmount,
111
118
  holders,
112
119
  isFormSubject
113
120
  }, {
@@ -183,7 +190,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
183
190
  discountList,
184
191
  productList,
185
192
  holders,
186
- isFormSubject
193
+ isFormSubject,
194
+ orderTotalAmount
187
195
  }, options) {
188
196
  const editModeDiscount = [];
189
197
  const addModeDiscount = [];
@@ -362,7 +370,63 @@ var RulesModule = class extends import_BaseModule.BaseModule {
362
370
  }
363
371
  return priceB.minus(priceA).toNumber();
364
372
  });
373
+ const evaluator = this.getWalletPassEvaluator();
374
+ if (evaluator) {
375
+ addModeDiscount.forEach((discount) => {
376
+ var _a, _b;
377
+ const discountType = discount.tag || discount.type;
378
+ if (["good_pass", "discount_card", "product_discount_card"].includes(
379
+ discountType
380
+ )) {
381
+ const voucher = {
382
+ id: discount.id,
383
+ amount: Number(discount.par_value || 0),
384
+ balance: Number(discount.balance || 0),
385
+ type: discountType,
386
+ product_id: discount.product_id,
387
+ unified_available_status: 1,
388
+ available_product_type: (_a = discount.limited_relation_product_data) == null ? void 0 : _a.type,
389
+ available_product_ids: (_b = discount.limited_relation_product_data) == null ? void 0 : _b.product_ids
390
+ };
391
+ const productsForEvaluate = sortedFlattenedList.map((item) => {
392
+ var _a2;
393
+ return {
394
+ product_id: item.id,
395
+ price: item.price || 0,
396
+ quantity: item.quantity || item.num || 1,
397
+ selling_price: item.price || 0,
398
+ product_options: item.type === "main" ? (_a2 = item.product) == null ? void 0 : _a2.options : void 0
399
+ };
400
+ });
401
+ const result = evaluator.checkVoucherAvailability({
402
+ orderTotalAmount,
403
+ products: productsForEvaluate,
404
+ vouchers: [voucher]
405
+ });
406
+ if (result.isAvailable) {
407
+ discount.config = {
408
+ ...result.config,
409
+ isAvailable: true
410
+ };
411
+ } else {
412
+ discount.config = {
413
+ isAvailable: false
414
+ };
415
+ }
416
+ }
417
+ });
418
+ }
365
419
  const usedDiscounts = /* @__PURE__ */ new Map();
420
+ const usedProductIdCounts = /* @__PURE__ */ new Map();
421
+ const usedDiscountCardLimitCounts = /* @__PURE__ */ new Map();
422
+ editModeDiscount.forEach((discount) => {
423
+ var _a;
424
+ const discountType = discount.tag || discount.type;
425
+ if (["discount_card", "product_discount_card"].includes(discountType)) {
426
+ const currentCount = usedDiscountCardLimitCounts.get(discount.id) || 0;
427
+ usedDiscountCardLimitCounts.set(discount.id, currentCount + (((_a = discount.metadata) == null ? void 0 : _a.num) || 1));
428
+ }
429
+ });
366
430
  const discountApplicability = /* @__PURE__ */ new Map();
367
431
  const discountApplicableProducts = /* @__PURE__ */ new Map();
368
432
  addModeDiscount.forEach((discount) => {
@@ -502,6 +566,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
502
566
  originProduct = flatItem.originProduct;
503
567
  } else {
504
568
  product = {
569
+ startDate: (_a = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _a.startDate,
505
570
  _id: flatItem._id,
506
571
  id: flatItem.id,
507
572
  price: flatItem.price,
@@ -510,13 +575,12 @@ var RulesModule = class extends import_BaseModule.BaseModule {
510
575
  total: flatItem.total,
511
576
  origin_total: flatItem.origin_total,
512
577
  booking_id: flatItem.booking_id,
513
- discount_list: flatItem.discount_list || [],
514
- startDate: (_a = flatItem.parentProduct) == null ? void 0 : _a.startDate
578
+ discount_list: flatItem.discount_list || []
515
579
  };
516
580
  originProduct = flatItem.originProduct;
517
581
  }
518
582
  addModeDiscount.forEach((discount) => {
519
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
583
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
520
584
  const limitedData = discount == null ? void 0 : discount.limited_relation_product_data;
521
585
  const _tempVar = (flatItem == null ? void 0 : flatItem.type) === "bundle" ? flatItem == null ? void 0 : flatItem.parentProduct : flatItem == null ? void 0 : flatItem.product;
522
586
  const isHolderMatch = this.checkHolderMatch(
@@ -529,7 +593,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
529
593
  );
530
594
  let timeLimit = true;
531
595
  timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], ((product == null ? void 0 : product.startDate) || (0, import_dayjs.default)()).format("YYYY-MM-DD HH:mm:ss")).length;
532
- const isLimitedProduct = (limitedData.type === "product_all" || limitedData.product_ids && limitedData.product_ids.includes(product.id)) && isHolderMatch;
596
+ const isLimitedProduct = (limitedData.type === "product_all" && limitedData.filter !== 1 || limitedData.type === "product_all" && limitedData.filter === 1 && !limitedData.exclude_product_ids.includes(product.id) || limitedData.product_ids && limitedData.product_ids.includes(product.id)) && isHolderMatch;
533
597
  const isAvailableProduct = flatItem.type === "main" ? !((product == null ? void 0 : product.booking_id) && ((_a2 = product == null ? void 0 : product.discount_list) == null ? void 0 : _a2.length) && ((_b = product == null ? void 0 : product.discount_list) == null ? void 0 : _b.every(
534
598
  (discount2) => discount2.id && [
535
599
  "good_pass",
@@ -538,8 +602,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
538
602
  ].includes(discount2.tag || discount2.type)
539
603
  ))) : !((flatItem == null ? void 0 : flatItem.booking_id) && !!((_d = (_c = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _c.discount_list) == null ? void 0 : _d.length) && ((_f = (_e = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _e.discount_list) == null ? void 0 : _f.every((discount2) => discount2.id)));
540
604
  const isBundleAvailable = this.checkPackageSubItemUsageRules(discount, flatItem);
541
- if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable) {
542
- (_g = discountApplicability.get(discount.id)) == null ? void 0 : _g.push(product.id);
605
+ if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable && ((_g = discount.config) == null ? void 0 : _g.isAvailable)) {
606
+ (_h = discountApplicability.get(discount.id)) == null ? void 0 : _h.push(product.id);
543
607
  const applicableProducts = discountApplicableProducts.get(discount.id) || [];
544
608
  const discountType = discount.tag || discount.type;
545
609
  const isGoodPass = discountType === "good_pass";
@@ -549,14 +613,15 @@ var RulesModule = class extends import_BaseModule.BaseModule {
549
613
  type: discountType,
550
614
  tag: discountType,
551
615
  discount: {
552
- discount_card_type: (_h = discount == null ? void 0 : discount.metadata) == null ? void 0 : _h.discount_card_type,
616
+ discount_card_type: (_i = discount == null ? void 0 : discount.metadata) == null ? void 0 : _i.discount_card_type,
553
617
  fixed_amount: product.price,
554
- discount_calculation_mode: (_i = discount == null ? void 0 : discount.metadata) == null ? void 0 : _i.discount_calculation_mode,
618
+ discount_calculation_mode: (_j = discount == null ? void 0 : discount.metadata) == null ? void 0 : _j.discount_calculation_mode,
555
619
  resource_id: discount.id,
556
620
  title: discount.format_title,
557
621
  original_amount: product.price || product.origin_total,
558
622
  pre_value: discount.par_value,
559
- product_id: originProduct.id
623
+ product_id: originProduct.id,
624
+ discount_product_id: discount.product_id
560
625
  },
561
626
  metadata: {
562
627
  num,
@@ -569,44 +634,102 @@ var RulesModule = class extends import_BaseModule.BaseModule {
569
634
  });
570
635
  });
571
636
  const processedFlatItemsMap = /* @__PURE__ */ new Map();
637
+ const applyDiscountToOptions = (options2, discount) => {
638
+ if (!(options2 == null ? void 0 : options2.length))
639
+ return { discountedOptions: options2, optionDiscountAmount: 0 };
640
+ let optionDiscountAmount = 0;
641
+ const discountedOptions = options2.map((option) => {
642
+ const rawUnit = option._original_price ?? option._original_add_price ?? option.price ?? option.add_price;
643
+ const baseUnitNum = Number(rawUnit ?? 0);
644
+ if (baseUnitNum <= 0)
645
+ return option;
646
+ const discountedPrice = (0, import_utils.getDiscountAmount)(discount, baseUnitNum, baseUnitNum);
647
+ const optQty = Number(option.num ?? option.quantity ?? 1);
648
+ optionDiscountAmount = new import_decimal.default(optionDiscountAmount).plus(new import_decimal.default(baseUnitNum).minus(discountedPrice).mul(optQty)).toNumber();
649
+ const { _original_add_price, ...rest } = option;
650
+ const tmpl = rest.price ?? rest.add_price;
651
+ const nextPrice = typeof tmpl === "string" ? String(discountedPrice) : discountedPrice;
652
+ return {
653
+ ...rest,
654
+ _original_price: option._original_price ?? (_original_add_price !== void 0 ? _original_add_price : rawUnit),
655
+ price: nextPrice
656
+ };
657
+ });
658
+ return { discountedOptions, optionDiscountAmount };
659
+ };
660
+ const restoreOptionPrices = (options2) => {
661
+ if (!(options2 == null ? void 0 : options2.length))
662
+ return options2;
663
+ return options2.map((option) => {
664
+ const orig = option._original_price !== void 0 ? option._original_price : option._original_add_price;
665
+ if (orig !== void 0) {
666
+ const { _original_price, _original_add_price, ...rest } = option;
667
+ return { ...rest, price: orig };
668
+ }
669
+ return option;
670
+ });
671
+ };
672
+ const getOptionTotal = (options2) => {
673
+ if (!(options2 == null ? void 0 : options2.length))
674
+ return 0;
675
+ return options2.reduce((sum, opt) => {
676
+ const unit = Number(opt.price ?? opt.add_price ?? 0);
677
+ const n = Number(opt.num ?? opt.quantity ?? 1);
678
+ return new import_decimal.default(sum).plus(new import_decimal.default(unit).mul(n)).toNumber();
679
+ }, 0);
680
+ };
572
681
  sortedFlattenedList.forEach((flatItem, index) => {
573
- 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, _A, _B, _C;
682
+ 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, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M;
574
683
  let product, originProduct;
575
684
  if (flatItem.type === "main") {
576
685
  product = flatItem.product;
577
686
  originProduct = flatItem.originProduct;
578
687
  } else {
579
688
  product = {
689
+ startDate: (_a = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _a.startDate,
580
690
  _id: flatItem._id,
581
691
  id: flatItem.id,
582
692
  price: flatItem.price,
583
693
  quantity: flatItem.quantity,
584
694
  num: flatItem.num,
585
695
  total: flatItem.total,
586
- original_price: (_a = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _a.original_price,
587
- origin_total: (_b = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _b.original_price,
696
+ original_price: (_b = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _b.original_price,
697
+ origin_total: (_c = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _c.original_price,
588
698
  booking_id: flatItem.booking_id,
589
- discount_list: ((_c = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _c.discount_list) || [],
590
- startDate: (_d = flatItem.parentProduct) == null ? void 0 : _d.startDate
699
+ discount_list: ((_d = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _d.discount_list) || []
591
700
  };
592
701
  originProduct = flatItem.originProduct;
593
702
  }
594
- if ((product == null ? void 0 : product.booking_id) && ((_e = product.discount_list) == null ? void 0 : _e.length) && ((_f = product == null ? void 0 : product.discount_list) == null ? void 0 : _f.every((discount) => discount.id && ["good_pass", "discount_card", "product_discount_card"].includes(discount.tag || discount.type)))) {
703
+ if ((product == null ? void 0 : product.booking_id) && ((_e = product.discount_list) == null ? void 0 : _e.length) && ((_f = product == null ? void 0 : product.discount_list) == null ? void 0 : _f.every(
704
+ (discount) => discount.id && ["good_pass", "discount_card", "product_discount_card"].includes(
705
+ discount.tag || discount.type
706
+ )
707
+ ))) {
595
708
  if (flatItem.type === "main") {
596
709
  processedProductsMap.set(product._id, [originProduct]);
597
710
  } else {
598
- processedFlatItemsMap.set(flatItem._id, [{
599
- ...flatItem,
600
- processed: true
601
- }]);
711
+ processedFlatItemsMap.set(flatItem._id, [
712
+ {
713
+ ...flatItem,
714
+ processed: true
715
+ }
716
+ ]);
602
717
  }
603
718
  return;
604
719
  }
605
720
  const applicableDiscounts = sortedDiscountList.filter((discount) => {
606
- var _a2, _b2;
607
- if ((Number(product.price) <= 0 || !product.price) && !((_a2 = product.discount_list) == null ? void 0 : _a2.length) && (discount.tag || discount.type) === "good_pass")
721
+ var _a2, _b2, _c2, _d2, _e2;
722
+ const discountType2 = discount.tag || discount.type;
723
+ if (["good_pass", "discount_card", "product_discount_card"].includes(
724
+ discountType2
725
+ )) {
726
+ if (discount.config === void 0 || !((_a2 = discount == null ? void 0 : discount.config) == null ? void 0 : _a2.isAvailable)) {
727
+ return false;
728
+ }
729
+ }
730
+ if ((Number(product.price) <= 0 || !product.price) && !((_b2 = product.discount_list) == null ? void 0 : _b2.length) && (discount.tag || discount.type) === "good_pass")
608
731
  return false;
609
- if ((Number(product.price) <= 0 || !product.price) && !((_b2 = product.discount_list) == null ? void 0 : _b2.find((n) => {
732
+ if ((Number(product.total) <= 0 || !product.total) && !((_c2 = product.discount_list) == null ? void 0 : _c2.find((n) => {
610
733
  var _a3;
611
734
  return ((_a3 = n.discount) == null ? void 0 : _a3.resource_id) === discount.id;
612
735
  })) && (discount.tag || discount.type) !== "good_pass")
@@ -614,6 +737,25 @@ var RulesModule = class extends import_BaseModule.BaseModule {
614
737
  const targetUsedDiscounts = usedDiscounts.get(discount.id);
615
738
  if (targetUsedDiscounts && (discount.tag || discount.type) === "good_pass")
616
739
  return false;
740
+ if ((discount.tag || discount.type) === "good_pass") {
741
+ const maxUsagePerOrder = (_d2 = discount.config) == null ? void 0 : _d2.maxUsagePerOrder;
742
+ if (maxUsagePerOrder && maxUsagePerOrder > 0) {
743
+ const currentUsedCount = usedProductIdCounts.get(discount.product_id) || 0;
744
+ if (currentUsedCount >= maxUsagePerOrder) {
745
+ return false;
746
+ }
747
+ }
748
+ }
749
+ const discountTypeForLimit = discount.tag || discount.type;
750
+ if (["discount_card", "product_discount_card"].includes(discountTypeForLimit)) {
751
+ const applicableProductLimitConfig = ((_e2 = discount.config) == null ? void 0 : _e2.applicableProductLimit) || 0;
752
+ if (applicableProductLimitConfig > 0) {
753
+ const currentUsedLimitCount = usedDiscountCardLimitCounts.get(discount.id) || 0;
754
+ if (currentUsedLimitCount >= applicableProductLimitConfig) {
755
+ return false;
756
+ }
757
+ }
758
+ }
617
759
  const limitedData = discount.limited_relation_product_data;
618
760
  const _tempVar = (flatItem == null ? void 0 : flatItem.type) === "bundle" ? flatItem == null ? void 0 : flatItem.parentProduct : flatItem == null ? void 0 : flatItem.product;
619
761
  const isHolderMatch = this.checkHolderMatch(
@@ -632,6 +774,9 @@ var RulesModule = class extends import_BaseModule.BaseModule {
632
774
  return false;
633
775
  }
634
776
  if (limitedData.type === "product_all") {
777
+ if (limitedData.filter === 1 && limitedData.exclude_product_ids.includes(product.id)) {
778
+ return false;
779
+ }
635
780
  if (!this.checkPackageSubItemUsageRules(discount, flatItem)) {
636
781
  return false;
637
782
  }
@@ -644,21 +789,36 @@ var RulesModule = class extends import_BaseModule.BaseModule {
644
789
  }
645
790
  return false;
646
791
  });
647
- const selectedDiscountCard = applicableDiscounts.find((n) => n.isScan && n.isSelected && (n.tag || n.type) !== "good_pass");
792
+ const selectedDiscountCard = applicableDiscounts.find(
793
+ (n) => n.isScan && n.isSelected && (n.tag || n.type) !== "good_pass"
794
+ );
648
795
  const selectedDiscount = selectedDiscountCard || applicableDiscounts[0];
649
796
  let isManualDiscount = false;
650
797
  if (flatItem.type === "main") {
651
- isManualDiscount = typeof product.isManualDiscount === "boolean" ? product.isManualDiscount : product.total != product.origin_total && (product.bundle || []).every((item) => {
652
- var _a2;
653
- return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
654
- }) && (!((_g = product.discount_list) == null ? void 0 : _g.length) || ((_i = (_h = product == null ? void 0 : product.discount_list) == null ? void 0 : _h.every) == null ? void 0 : _i.call(_h, (item) => item.type === "product")));
798
+ isManualDiscount = typeof product.isManualDiscount === "boolean" ? product.isManualDiscount : product.total != product.origin_total && (product.bundle || []).every(
799
+ (item) => {
800
+ var _a2;
801
+ return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
802
+ }
803
+ ) && (!((_g = product.discount_list) == null ? void 0 : _g.length) || ((_i = (_h = product == null ? void 0 : product.discount_list) == null ? void 0 : _h.every) == null ? void 0 : _i.call(
804
+ _h,
805
+ (item) => item.type === "product"
806
+ )));
807
+ if (product.inPromotion) {
808
+ isManualDiscount = false;
809
+ }
655
810
  } else {
656
811
  const parentProduct = flatItem.parentProduct;
657
812
  if (parentProduct) {
658
- isManualDiscount = typeof parentProduct.isManualDiscount === "boolean" ? parentProduct.isManualDiscount : parentProduct.total != parentProduct.origin_total && (parentProduct.bundle || []).every((item) => {
659
- var _a2;
660
- return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
661
- }) && (!((_j = parentProduct.discount_list) == null ? void 0 : _j.length) || ((_l = (_k = parentProduct == null ? void 0 : parentProduct.discount_list) == null ? void 0 : _k.every) == null ? void 0 : _l.call(_k, (item) => item.type === "product")));
813
+ isManualDiscount = typeof parentProduct.isManualDiscount === "boolean" ? parentProduct.isManualDiscount : parentProduct.total != parentProduct.origin_total && (parentProduct.bundle || []).every(
814
+ (item) => {
815
+ var _a2;
816
+ return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
817
+ }
818
+ ) && (!((_j = parentProduct.discount_list) == null ? void 0 : _j.length) || ((_l = (_k = parentProduct == null ? void 0 : parentProduct.discount_list) == null ? void 0 : _k.every) == null ? void 0 : _l.call(
819
+ _k,
820
+ (item) => item.type === "product"
821
+ )));
662
822
  }
663
823
  }
664
824
  if (options == null ? void 0 : options.discountId) {
@@ -710,17 +870,17 @@ var RulesModule = class extends import_BaseModule.BaseModule {
710
870
  }
711
871
  if (applicableDiscounts.length === 0 || isManualDiscount || (0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
712
872
  if (flatItem.type === "main") {
873
+ const restoredOptions = restoreOptionPrices(product.options);
713
874
  if (product.isClient) {
714
- processedProductsMap.set(
715
- product._id,
716
- [this.hooks.setProduct(originProduct, {
875
+ processedProductsMap.set(product._id, [
876
+ this.hooks.setProduct(originProduct, {
717
877
  ...isManualDiscount ? {} : {
718
878
  origin_total: (0, import_utils2.getProductOriginTotalPrice)({
719
879
  product: {
720
880
  original_price: product.original_price
721
881
  },
722
882
  bundle: product.bundle,
723
- options: product.options
883
+ options: restoredOptions
724
884
  }),
725
885
  variant: originProduct._productInit.variant,
726
886
  original_price: originProduct._productInit.original_price,
@@ -729,13 +889,14 @@ var RulesModule = class extends import_BaseModule.BaseModule {
729
889
  price: product.price
730
890
  },
731
891
  bundle: product.bundle,
732
- options: product.options
892
+ options: restoredOptions
733
893
  }),
734
- price: product.price
894
+ price: product.price,
895
+ options: restoredOptions
735
896
  },
736
897
  discount_list: this.filterDiscountListByType(product.discount_list, "promotion")
737
- })]
738
- );
898
+ })
899
+ ]);
739
900
  } else {
740
901
  let total = product.inPromotion ? ((_u = product == null ? void 0 : product._promotion) == null ? void 0 : _u.finalPrice) ?? product.origin_total ?? product.total : product.origin_total ?? product.total;
741
902
  let main_product_selling_price = product.price ?? product.main_product_selling_price;
@@ -745,17 +906,20 @@ var RulesModule = class extends import_BaseModule.BaseModule {
745
906
  }
746
907
  processedProductsMap.set(
747
908
  product._id,
748
- [this.hooks.setProduct(originProduct, {
749
- ...isManualDiscount ? {
750
- price: product.price
751
- } : {
752
- _id: product._id.split("___")[0] + "___" + index,
753
- total,
754
- price: product.price,
755
- main_product_selling_price
756
- },
757
- discount_list: this.filterDiscountListByType(product.discount_list, "promotion")
758
- })]
909
+ [
910
+ this.hooks.setProduct(originProduct, {
911
+ ...isManualDiscount ? {
912
+ price: product.price
913
+ } : {
914
+ _id: product._id.split("___")[0] + "___" + index,
915
+ total,
916
+ price: product.price,
917
+ main_product_selling_price,
918
+ options: restoredOptions
919
+ },
920
+ discount_list: this.filterDiscountListByType(product.discount_list, "promotion")
921
+ })
922
+ ]
759
923
  );
760
924
  }
761
925
  } else {
@@ -771,104 +935,166 @@ var RulesModule = class extends import_BaseModule.BaseModule {
771
935
  if (applicableDiscounts.length && product.booking_id && typeof selectedDiscount.isManualSelect === "undefined" && !(options == null ? void 0 : options.scan) && !isEditModeAddNewProduct) {
772
936
  return;
773
937
  }
774
- const isNeedSplit = (selectedDiscount.tag || selectedDiscount.type) === "good_pass";
938
+ const discountType = selectedDiscount.tag || selectedDiscount.type;
939
+ const isGoodPass = discountType === "good_pass";
940
+ const isDiscountCard = ["discount_card", "product_discount_card"].includes(discountType);
941
+ const applicableProductLimit = ((_w = selectedDiscount.config) == null ? void 0 : _w.applicableProductLimit) || 0;
942
+ const isNeedSplit = isGoodPass || isDiscountCard && applicableProductLimit > 0;
775
943
  const totalQuantity = product.quantity || product.num || 1;
776
- const availableGoodPassCount = applicableDiscounts.filter((item) => (item.tag || item.type) === "good_pass").length;
777
- const splitCount = isNeedSplit ? Math.min(totalQuantity, availableGoodPassCount) : 1;
944
+ const availableGoodPassCount = applicableDiscounts.filter(
945
+ (item) => (item.tag || item.type) === "good_pass"
946
+ ).length;
947
+ let maxUsageLimit;
948
+ if (isGoodPass) {
949
+ maxUsageLimit = availableGoodPassCount;
950
+ if (selectedDiscount.config && selectedDiscount.config.maxUsagePerOrder) {
951
+ maxUsageLimit = Math.min(
952
+ availableGoodPassCount,
953
+ selectedDiscount.config.maxUsagePerOrder
954
+ );
955
+ }
956
+ } else if (isDiscountCard && applicableProductLimit > 0) {
957
+ const usedLimitCount = usedDiscountCardLimitCounts.get(selectedDiscount.id) || 0;
958
+ maxUsageLimit = Math.max(0, applicableProductLimit - usedLimitCount);
959
+ } else {
960
+ maxUsageLimit = 1;
961
+ }
962
+ const splitCount = isNeedSplit ? Math.min(product.quantity || product.num || 1, maxUsageLimit) : 1;
778
963
  const arr = [];
779
964
  if (flatItem.type === "main") {
780
965
  if (splitCount < totalQuantity && isNeedSplit) {
781
- arr.push(this.hooks.setProduct(originProduct, {
782
- discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
783
- quantity: totalQuantity - splitCount,
784
- _id: product._id.split("___")[0]
785
- }));
966
+ let total = product.origin_total ?? product.total;
967
+ if ((product.discount_list || []).some((item) => item.type === "promotion")) {
968
+ total = product.total ?? product.origin_total;
969
+ }
970
+ arr.push(
971
+ this.hooks.setProduct(originProduct, {
972
+ discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
973
+ quantity: totalQuantity - splitCount,
974
+ _id: product._id.split("___")[0],
975
+ total
976
+ })
977
+ );
786
978
  }
787
979
  for (let i = 0; i < splitCount; i++) {
788
- const selectedDiscount2 = selectedDiscountCard || applicableDiscounts[i];
789
- usedDiscounts.set(selectedDiscount2.id, true);
790
- const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
980
+ const currentSelectedDiscount = isGoodPass ? selectedDiscountCard || applicableDiscounts[i] : selectedDiscountCard || applicableDiscounts[0];
981
+ usedDiscounts.set(currentSelectedDiscount.id, true);
982
+ if ((currentSelectedDiscount.tag || currentSelectedDiscount.type) === "good_pass") {
983
+ const currentCount = usedProductIdCounts.get(currentSelectedDiscount.product_id) || 0;
984
+ usedProductIdCounts.set(currentSelectedDiscount.product_id, currentCount + 1);
985
+ }
986
+ const currentDiscountTypeForCount = currentSelectedDiscount.tag || currentSelectedDiscount.type;
987
+ if (["discount_card", "product_discount_card"].includes(currentDiscountTypeForCount)) {
988
+ const currentLimitCount = usedDiscountCardLimitCounts.get(currentSelectedDiscount.id) || 0;
989
+ usedDiscountCardLimitCounts.set(currentSelectedDiscount.id, currentLimitCount + 1);
990
+ }
991
+ const appliedProducts = appliedDiscountProducts.get(currentSelectedDiscount.id) || [];
791
992
  let productOriginTotal = product.origin_total || product.total || 0;
792
993
  if (this.filterDiscountListByType(product.discount_list, "promotion").length && product.origin_total) {
793
994
  productOriginTotal = product.origin_total;
794
995
  }
795
- if (Number(((_w = originProduct == null ? void 0 : originProduct._productInit) == null ? void 0 : _w.original_price) || 0) > 0 && product.origin_total && product.total && product.origin_total !== product.total) {
996
+ if (Number(((_x = originProduct == null ? void 0 : originProduct._productInit) == null ? void 0 : _x.original_price) || 0) > 0 && product.origin_total && product.total && product.origin_total !== product.total) {
796
997
  productOriginTotal = product.total;
797
998
  }
798
- const isOrderLevel = (0, import_utils.isOrderLevelFixedAmountDiscount)(selectedDiscount2);
799
- const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount2.id) : null;
999
+ const isOrderLevel = (0, import_utils.isOrderLevelFixedAmountDiscount)(selectedDiscount);
1000
+ const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
800
1001
  const productAllocation = orderLevelAllocation == null ? void 0 : orderLevelAllocation.get(flatItem._id);
801
- let targetProductTotal;
1002
+ const isDeductOptionPrice = !!((_y = selectedDiscount.config) == null ? void 0 : _y.deductOptionPrice);
1003
+ let mainProductSellingPrice;
802
1004
  let amount;
803
1005
  let productDiscountDifference;
1006
+ let discountedOptions = product.options;
1007
+ let optionDiscountAmount = 0;
804
1008
  if (isOrderLevel && productAllocation) {
805
1009
  amount = productAllocation.discountAmount;
806
1010
  productDiscountDifference = productAllocation.difference;
807
- targetProductTotal = Math.max(new import_decimal.default(product.price).minus(amount).toNumber(), 0);
1011
+ mainProductSellingPrice = Math.max(new import_decimal.default(product.price).minus(amount).toNumber(), 0);
808
1012
  } else {
809
- targetProductTotal = (0, import_utils.getDiscountAmount)(selectedDiscount2, product.price, product.price);
810
- amount = new import_decimal.default(product.price).minus(new import_decimal.default(targetProductTotal)).toNumber();
1013
+ mainProductSellingPrice = (0, import_utils.getDiscountAmount)(
1014
+ currentSelectedDiscount,
1015
+ product.price,
1016
+ product.price
1017
+ );
1018
+ amount = new import_decimal.default(product.price).minus(new import_decimal.default(mainProductSellingPrice)).toNumber();
811
1019
  }
812
- const discountType = selectedDiscount2.tag || selectedDiscount2.type;
813
- const isGoodPass = discountType === "good_pass";
1020
+ if (isDeductOptionPrice && ((_z = product.options) == null ? void 0 : _z.length)) {
1021
+ const optionResult = applyDiscountToOptions(
1022
+ product.options,
1023
+ currentSelectedDiscount
1024
+ );
1025
+ discountedOptions = optionResult.discountedOptions;
1026
+ optionDiscountAmount = optionResult.optionDiscountAmount;
1027
+ }
1028
+ const optionsForLineTotal = isDeductOptionPrice && ((_A = product.options) == null ? void 0 : _A.length) ? discountedOptions : product.options;
1029
+ const optionsLineTotal = getOptionTotal(optionsForLineTotal || []);
1030
+ const total = new import_decimal.default(mainProductSellingPrice).plus(optionsLineTotal).toNumber();
1031
+ const mainProductDiscountAmount = amount;
1032
+ const lineDiscountAmount = new import_decimal.default(mainProductDiscountAmount).plus(optionDiscountAmount).toNumber();
1033
+ const currentDiscountType = currentSelectedDiscount.tag === "product_discount_card" ? "discount_card" : currentSelectedDiscount.tag;
1034
+ const discountType2 = selectedDiscount.tag || selectedDiscount.type;
1035
+ const currentIsGoodPass = currentDiscountType === "good_pass";
814
1036
  const discountDetail = {
815
- amount,
816
- type: selectedDiscount2.tag === "product_discount_card" ? "discount_card" : discountType,
1037
+ amount: lineDiscountAmount,
1038
+ type: selectedDiscount.tag === "product_discount_card" ? "discount_card" : discountType2,
817
1039
  discount: {
818
- discount_card_type: (_x = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _x.discount_card_type,
819
- fixed_amount: amount,
820
- discount_calculation_mode: (_y = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _y.discount_calculation_mode,
821
- resource_id: selectedDiscount2.id,
822
- title: selectedDiscount2.format_title,
1040
+ discount_card_type: (_B = selectedDiscount == null ? void 0 : selectedDiscount.metadata) == null ? void 0 : _B.discount_card_type,
1041
+ fixed_amount: lineDiscountAmount,
1042
+ discount_calculation_mode: (_C = selectedDiscount == null ? void 0 : selectedDiscount.metadata) == null ? void 0 : _C.discount_calculation_mode,
1043
+ resource_id: selectedDiscount.id,
1044
+ title: selectedDiscount.format_title,
823
1045
  original_amount: product.price,
824
1046
  product_id: originProduct.id,
825
- percent: selectedDiscount2.par_value
1047
+ percent: currentSelectedDiscount.par_value,
1048
+ discount_product_id: currentSelectedDiscount.product_id
826
1049
  },
827
- // 前端使用的num数量,为了计算优惠金额
828
- _num: isGoodPass ? 1 : product.num,
1050
+ // 前端使用的num数量,为了计算优惠金额(拆分时为1)
1051
+ _num: isNeedSplit ? 1 : product.num,
1052
+ config: currentSelectedDiscount == null ? void 0 : currentSelectedDiscount.config,
829
1053
  metadata: {
830
1054
  num: 1,
831
- discount_rule_uncheck_flag: selectedDiscount2 == null ? void 0 : selectedDiscount2.discount_rule_uncheck_flag,
1055
+ discount_rule_uncheck_flag: selectedDiscount == null ? void 0 : selectedDiscount.discount_rule_uncheck_flag,
832
1056
  // 🔥 order_level 分摊差值
833
- ...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference }
1057
+ ...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference },
1058
+ /** 仅主商品上的优惠金额(不含 option) */
1059
+ mainProductDiscountAmount,
1060
+ optionDiscountAmount
834
1061
  }
835
1062
  };
836
1063
  appliedProducts.push(discountDetail);
837
- appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
838
- let total = targetProductTotal;
839
- if (product.options) {
840
- total = product.options.reduce((accumulator, currentValue) => {
841
- const currentPrice = new import_decimal.default(currentValue.price || 0);
842
- const currentNum = new import_decimal.default(currentValue.num || 0);
843
- return accumulator.add(currentPrice.mul(currentNum));
844
- }, new import_decimal.default(total)).toNumber();
845
- }
1064
+ appliedDiscountProducts.set(currentSelectedDiscount.id, appliedProducts);
846
1065
  if (product.isClient) {
847
- arr.push(this.hooks.setProduct(originProduct, {
848
- discount_list: [discountDetail],
849
- price: selectedDiscount2.tag === "good_pass" ? 0 : product.price,
850
- quantity: isNeedSplit ? 1 : product.quantity,
851
- origin_total: (0, import_utils2.getProductOriginTotalPrice)({
852
- product: {
853
- original_price: product.original_price
854
- },
855
- bundle: product.bundle,
856
- options: product.options
857
- }),
858
- variant: originProduct._productInit.variant,
859
- original_price: new import_decimal.default(product.price || 0).toNumber(),
860
- total
861
- }));
1066
+ arr.push(
1067
+ this.hooks.setProduct(originProduct, {
1068
+ discount_list: [discountDetail],
1069
+ // good_pass:主商品价以折后价为准;勿用 product.price - amount(amount 含 option 优惠时会算错)
1070
+ price: currentIsGoodPass ? mainProductSellingPrice : product.price,
1071
+ quantity: isNeedSplit ? 1 : product.quantity,
1072
+ origin_total: (0, import_utils2.getProductOriginTotalPrice)({
1073
+ product: {
1074
+ original_price: product.original_price
1075
+ },
1076
+ bundle: product.bundle,
1077
+ options: restoreOptionPrices(product.options)
1078
+ }),
1079
+ variant: originProduct._productInit.variant,
1080
+ original_price: new import_decimal.default(product.price || 0).toNumber(),
1081
+ total,
1082
+ options: discountedOptions
1083
+ })
1084
+ );
862
1085
  } else {
863
- arr.push(this.hooks.setProduct(originProduct, {
864
- discount_list: this.filterDiscountListByType(product.discount_list, "promotion").concat([discountDetail]),
865
- _id: product._id.split("___")[0] + "___" + selectedDiscount2.id + index,
866
- price: selectedDiscount2.tag === "good_pass" ? 0 : product.price,
867
- quantity: isNeedSplit ? 1 : product.quantity,
868
- total,
869
- origin_total: productOriginTotal,
870
- main_product_selling_price: targetProductTotal
871
- }));
1086
+ arr.push(
1087
+ this.hooks.setProduct(originProduct, {
1088
+ discount_list: this.filterDiscountListByType(product.discount_list, "promotion").concat([discountDetail]),
1089
+ _id: product._id.split("___")[0] + "___" + currentSelectedDiscount.id + "_" + i + "_" + index,
1090
+ price: currentIsGoodPass ? 0 : product.price,
1091
+ quantity: isNeedSplit ? 1 : product.quantity,
1092
+ total,
1093
+ origin_total: productOriginTotal,
1094
+ main_product_selling_price: mainProductSellingPrice,
1095
+ options: discountedOptions
1096
+ })
1097
+ );
872
1098
  }
873
1099
  }
874
1100
  processedProductsMap.set(product._id, arr);
@@ -878,62 +1104,298 @@ var RulesModule = class extends import_BaseModule.BaseModule {
878
1104
  const discountNum = splitCount;
879
1105
  const normalNum = totalQuantity - discountNum;
880
1106
  for (let i = 0; i < discountNum; i++) {
881
- const selectedDiscount2 = applicableDiscounts[i];
882
- usedDiscounts.set(selectedDiscount2.id, true);
1107
+ const currentBundleDiscount = isGoodPass ? selectedDiscountCard || applicableDiscounts[i] : selectedDiscountCard || applicableDiscounts[0];
1108
+ usedDiscounts.set(currentBundleDiscount.id, true);
1109
+ if ((currentBundleDiscount.tag || currentBundleDiscount.type) === "good_pass") {
1110
+ const currentCount = usedProductIdCounts.get(currentBundleDiscount.product_id) || 0;
1111
+ usedProductIdCounts.set(currentBundleDiscount.product_id, currentCount + 1);
1112
+ }
1113
+ const bundleDiscountTypeForCount = currentBundleDiscount.tag || currentBundleDiscount.type;
1114
+ if (["discount_card", "product_discount_card"].includes(bundleDiscountTypeForCount)) {
1115
+ const currentBundleLimitCount = usedDiscountCardLimitCounts.get(currentBundleDiscount.id) || 0;
1116
+ usedDiscountCardLimitCounts.set(currentBundleDiscount.id, currentBundleLimitCount + 1);
1117
+ }
883
1118
  const uniqueId = `${flatItem._id}_split_${i}`;
1119
+ const discountedPrice = (0, import_utils.getDiscountAmount)(
1120
+ currentBundleDiscount,
1121
+ product.origin_total,
1122
+ product.origin_total
1123
+ );
1124
+ const bundleDiscountAmount = new import_decimal.default(product.origin_total || 0).minus(discountedPrice).toNumber();
1125
+ const bundleDiscountType = currentBundleDiscount.tag === "product_discount_card" ? "discount_card" : currentBundleDiscount.tag;
884
1126
  const discountDetail = {
885
- amount: product.origin_total,
886
- type: "good_pass",
1127
+ amount: bundleDiscountAmount,
1128
+ type: bundleDiscountType,
887
1129
  discount: {
888
- fixed_amount: product.origin_total,
889
- discount_calculation_mode: (_z = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _z.discount_calculation_mode,
890
- resource_id: selectedDiscount2.id,
891
- title: selectedDiscount2.format_title,
1130
+ discount_card_type: (_D = currentBundleDiscount == null ? void 0 : currentBundleDiscount.metadata) == null ? void 0 : _D.discount_card_type,
1131
+ discount_calculation_mode: (_E = currentBundleDiscount == null ? void 0 : currentBundleDiscount.metadata) == null ? void 0 : _E.discount_calculation_mode,
1132
+ fixed_amount: bundleDiscountAmount,
1133
+ resource_id: currentBundleDiscount.id,
1134
+ title: currentBundleDiscount.format_title,
892
1135
  original_amount: product.origin_total,
893
- product_id: product.id
1136
+ product_id: product.id,
1137
+ percent: currentBundleDiscount.par_value,
1138
+ discount_product_id: currentBundleDiscount.product_id
894
1139
  },
895
1140
  metadata: {
896
1141
  // 🔥 使用拆分后的唯一 _id
897
1142
  custom_product_bundle_map_id: uniqueId,
898
- discount_rule_uncheck_flag: selectedDiscount2 == null ? void 0 : selectedDiscount2.discount_rule_uncheck_flag,
1143
+ discount_rule_uncheck_flag: selectedDiscount == null ? void 0 : selectedDiscount.discount_rule_uncheck_flag,
899
1144
  num: 1
900
1145
  },
901
- _num: 1
1146
+ _num: 1,
1147
+ config: currentBundleDiscount == null ? void 0 : currentBundleDiscount.config
902
1148
  };
903
- const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
1149
+ const appliedProducts = appliedDiscountProducts.get(currentBundleDiscount.id) || [];
904
1150
  appliedProducts.push(discountDetail);
905
- appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
1151
+ appliedDiscountProducts.set(currentBundleDiscount.id, appliedProducts);
906
1152
  processedItems.push({
907
1153
  ...flatItem,
908
1154
  // 🔥 使用唯一的 _id
909
1155
  _id: uniqueId,
910
1156
  num: 1,
911
1157
  quantity: 1,
912
- price: 0,
913
- // 商品券价格为0
914
- total: 0,
1158
+ price: discountedPrice,
1159
+ // 折扣后的价格
1160
+ total: discountedPrice,
915
1161
  discount_list: this.filterDiscountListByType(flatItem.discount_list, "promotion").concat([discountDetail]),
916
1162
  processed: true,
917
- _discountId: selectedDiscount2.id
1163
+ _discountId: currentBundleDiscount.id
918
1164
  });
919
1165
  }
920
- if (normalNum > 0) {
921
- processedItems.push({
922
- ...flatItem,
923
- // 🔥 为剩余商品生成唯一的 _id
924
- _id: `${flatItem._id}_split_rest`,
925
- num: normalNum,
926
- quantity: normalNum,
927
- discount_list: this.filterDiscountListByType(flatItem.discount_list, "promotion"),
928
- processed: true
1166
+ let remainingNum = normalNum;
1167
+ let continueSplitIndex = discountNum;
1168
+ while (remainingNum > 0) {
1169
+ const nextApplicableDiscounts = sortedDiscountList.filter((nextDiscount) => {
1170
+ var _a2, _b2, _c2, _d2;
1171
+ const nextDiscountType = nextDiscount.tag || nextDiscount.type;
1172
+ if (["good_pass", "discount_card", "product_discount_card"].includes(nextDiscountType)) {
1173
+ if (nextDiscount.config === void 0 || !((_a2 = nextDiscount == null ? void 0 : nextDiscount.config) == null ? void 0 : _a2.isAvailable)) {
1174
+ return false;
1175
+ }
1176
+ }
1177
+ if ((Number(product.total) <= 0 || !product.total) && !((_b2 = product.discount_list) == null ? void 0 : _b2.find(
1178
+ (n) => {
1179
+ var _a3;
1180
+ return ((_a3 = n.discount) == null ? void 0 : _a3.resource_id) === nextDiscount.id;
1181
+ }
1182
+ )) && nextDiscountType !== "good_pass")
1183
+ return false;
1184
+ if (usedDiscounts.get(nextDiscount.id) && nextDiscountType === "good_pass")
1185
+ return false;
1186
+ if (nextDiscountType === "good_pass") {
1187
+ const maxUsagePerOrder = (_c2 = nextDiscount.config) == null ? void 0 : _c2.maxUsagePerOrder;
1188
+ if (maxUsagePerOrder && maxUsagePerOrder > 0) {
1189
+ const currentUsedCount = usedProductIdCounts.get(nextDiscount.product_id) || 0;
1190
+ if (currentUsedCount >= maxUsagePerOrder) {
1191
+ return false;
1192
+ }
1193
+ }
1194
+ }
1195
+ if (["discount_card", "product_discount_card"].includes(nextDiscountType)) {
1196
+ const limitConfig = ((_d2 = nextDiscount.config) == null ? void 0 : _d2.applicableProductLimit) || 0;
1197
+ if (limitConfig > 0) {
1198
+ const currentUsedLimitCount = usedDiscountCardLimitCounts.get(nextDiscount.id) || 0;
1199
+ if (currentUsedLimitCount >= limitConfig) {
1200
+ return false;
1201
+ }
1202
+ }
1203
+ }
1204
+ const limitedData = nextDiscount.limited_relation_product_data;
1205
+ if (limitedData.type === "product_all") {
1206
+ if (limitedData.filter === 1 && limitedData.exclude_product_ids.includes(product.id)) {
1207
+ return false;
1208
+ }
1209
+ if (!this.checkPackageSubItemUsageRules(nextDiscount, flatItem)) {
1210
+ return false;
1211
+ }
1212
+ return true;
1213
+ } else if (limitedData.product_ids && limitedData.product_ids.includes(product.id)) {
1214
+ if (!this.checkPackageSubItemUsageRules(nextDiscount, flatItem)) {
1215
+ return false;
1216
+ }
1217
+ return true;
1218
+ }
1219
+ return false;
929
1220
  });
1221
+ if (nextApplicableDiscounts.length === 0) {
1222
+ processedItems.push({
1223
+ ...flatItem,
1224
+ _id: `${flatItem._id}_split_rest`,
1225
+ num: remainingNum,
1226
+ quantity: remainingNum,
1227
+ discount_list: [],
1228
+ processed: true
1229
+ });
1230
+ break;
1231
+ }
1232
+ const nextSelectedDiscountCard = nextApplicableDiscounts.find(
1233
+ (n) => n.isScan && n.isSelected && (n.tag || n.type) !== "good_pass"
1234
+ );
1235
+ const nextSelectedDiscount = nextSelectedDiscountCard || nextApplicableDiscounts[0];
1236
+ const nextDiscType = nextSelectedDiscount.tag || nextSelectedDiscount.type;
1237
+ const nextIsGoodPass = nextDiscType === "good_pass";
1238
+ const nextIsDiscountCard = ["discount_card", "product_discount_card"].includes(nextDiscType);
1239
+ const nextApplicableProductLimit = ((_F = nextSelectedDiscount.config) == null ? void 0 : _F.applicableProductLimit) || 0;
1240
+ const nextIsNeedSplit = nextIsGoodPass || nextIsDiscountCard && nextApplicableProductLimit > 0;
1241
+ if (!nextIsNeedSplit) {
1242
+ const nextBundleDiscount = nextSelectedDiscountCard || nextApplicableDiscounts[0];
1243
+ usedDiscounts.set(nextBundleDiscount.id, true);
1244
+ if ((nextBundleDiscount.tag || nextBundleDiscount.type) === "good_pass") {
1245
+ const curCount = usedProductIdCounts.get(nextBundleDiscount.product_id) || 0;
1246
+ usedProductIdCounts.set(nextBundleDiscount.product_id, curCount + 1);
1247
+ }
1248
+ const nextNoSplitType = nextBundleDiscount.tag || nextBundleDiscount.type;
1249
+ if (["discount_card", "product_discount_card"].includes(nextNoSplitType)) {
1250
+ const curCount = usedDiscountCardLimitCounts.get(nextBundleDiscount.id) || 0;
1251
+ usedDiscountCardLimitCounts.set(nextBundleDiscount.id, curCount + remainingNum);
1252
+ }
1253
+ const nextOriginTotal = product.original_price || product.price || 0;
1254
+ const nextTargetTotal = (0, import_utils.getDiscountAmount)(nextBundleDiscount, nextOriginTotal, nextOriginTotal);
1255
+ const nextDiscountAmount = new import_decimal.default(nextOriginTotal).minus(nextTargetTotal).toNumber();
1256
+ const nextUniqueId = `${flatItem._id}_split_${continueSplitIndex}`;
1257
+ const nextBundleDiscType = nextBundleDiscount.tag === "product_discount_card" ? "discount_card" : nextBundleDiscount.tag;
1258
+ const nextDiscountDetail = {
1259
+ amount: nextDiscountAmount * remainingNum,
1260
+ type: nextBundleDiscType,
1261
+ discount: {
1262
+ discount_card_type: (_G = nextBundleDiscount == null ? void 0 : nextBundleDiscount.metadata) == null ? void 0 : _G.discount_card_type,
1263
+ fixed_amount: nextDiscountAmount,
1264
+ resource_id: nextBundleDiscount.id,
1265
+ title: nextBundleDiscount.format_title,
1266
+ original_amount: product.original_price,
1267
+ product_id: product.id,
1268
+ percent: nextBundleDiscount.par_value,
1269
+ discount_product_id: nextBundleDiscount.product_id
1270
+ },
1271
+ metadata: {
1272
+ custom_product_bundle_map_id: nextUniqueId,
1273
+ num: remainingNum
1274
+ },
1275
+ config: nextBundleDiscount == null ? void 0 : nextBundleDiscount.config,
1276
+ _num: remainingNum * (((_H = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _H.num) || 1)
1277
+ };
1278
+ const nextAppliedProducts = appliedDiscountProducts.get(nextBundleDiscount.id) || [];
1279
+ nextAppliedProducts.push(nextDiscountDetail);
1280
+ appliedDiscountProducts.set(nextBundleDiscount.id, nextAppliedProducts);
1281
+ processedItems.push({
1282
+ ...flatItem,
1283
+ _id: nextUniqueId,
1284
+ num: remainingNum,
1285
+ quantity: remainingNum,
1286
+ total: nextTargetTotal,
1287
+ price: new import_decimal.default(nextOriginTotal || 0).minus(nextDiscountDetail.discount.fixed_amount).toNumber(),
1288
+ discount_list: [nextDiscountDetail],
1289
+ processed: true
1290
+ });
1291
+ remainingNum = 0;
1292
+ break;
1293
+ }
1294
+ let nextMaxUsageLimit;
1295
+ if (nextIsGoodPass) {
1296
+ const nextGoodPassCount = nextApplicableDiscounts.filter(
1297
+ (item) => (item.tag || item.type) === "good_pass"
1298
+ ).length;
1299
+ nextMaxUsageLimit = nextGoodPassCount;
1300
+ if ((_I = nextSelectedDiscount.config) == null ? void 0 : _I.maxUsagePerOrder) {
1301
+ const usedCount = usedProductIdCounts.get(nextSelectedDiscount.product_id) || 0;
1302
+ nextMaxUsageLimit = Math.min(
1303
+ nextGoodPassCount,
1304
+ Math.max(0, nextSelectedDiscount.config.maxUsagePerOrder - usedCount)
1305
+ );
1306
+ }
1307
+ } else if (nextIsDiscountCard && nextApplicableProductLimit > 0) {
1308
+ const usedLimitCount = usedDiscountCardLimitCounts.get(nextSelectedDiscount.id) || 0;
1309
+ nextMaxUsageLimit = Math.max(0, nextApplicableProductLimit - usedLimitCount);
1310
+ } else {
1311
+ nextMaxUsageLimit = 1;
1312
+ }
1313
+ const nextSplitCount = Math.min(remainingNum, nextMaxUsageLimit);
1314
+ if (nextSplitCount === 0) {
1315
+ processedItems.push({
1316
+ ...flatItem,
1317
+ _id: `${flatItem._id}_split_rest`,
1318
+ num: remainingNum,
1319
+ quantity: remainingNum,
1320
+ discount_list: this.filterDiscountListByType(flatItem.discount_list, "promotion"),
1321
+ processed: true
1322
+ });
1323
+ break;
1324
+ }
1325
+ for (let j = 0; j < nextSplitCount; j++) {
1326
+ const nextBundleDiscount = nextIsGoodPass ? nextSelectedDiscountCard || nextApplicableDiscounts[j] : nextSelectedDiscountCard || nextApplicableDiscounts[0];
1327
+ usedDiscounts.set(nextBundleDiscount.id, true);
1328
+ if ((nextBundleDiscount.tag || nextBundleDiscount.type) === "good_pass") {
1329
+ const curCount = usedProductIdCounts.get(nextBundleDiscount.product_id) || 0;
1330
+ usedProductIdCounts.set(nextBundleDiscount.product_id, curCount + 1);
1331
+ }
1332
+ const nextBundleDiscTypeForCount = nextBundleDiscount.tag || nextBundleDiscount.type;
1333
+ if (["discount_card", "product_discount_card"].includes(nextBundleDiscTypeForCount)) {
1334
+ const curLimitCount = usedDiscountCardLimitCounts.get(nextBundleDiscount.id) || 0;
1335
+ usedDiscountCardLimitCounts.set(nextBundleDiscount.id, curLimitCount + 1);
1336
+ }
1337
+ const nextUniqueId = `${flatItem._id}_split_${continueSplitIndex}`;
1338
+ const nextDiscountedPrice = (0, import_utils.getDiscountAmount)(
1339
+ nextBundleDiscount,
1340
+ product.origin_total,
1341
+ product.origin_total
1342
+ );
1343
+ const nextBundleDiscAmount = new import_decimal.default(product.origin_total || 0).minus(nextDiscountedPrice).toNumber();
1344
+ const nextBundleDiscTypeStr = nextBundleDiscount.tag === "product_discount_card" ? "discount_card" : nextBundleDiscount.tag;
1345
+ const nextDiscountDetail = {
1346
+ amount: nextBundleDiscAmount,
1347
+ type: nextBundleDiscTypeStr,
1348
+ discount: {
1349
+ discount_card_type: (_J = nextBundleDiscount == null ? void 0 : nextBundleDiscount.metadata) == null ? void 0 : _J.discount_card_type,
1350
+ fixed_amount: nextBundleDiscAmount,
1351
+ resource_id: nextBundleDiscount.id,
1352
+ title: nextBundleDiscount.format_title,
1353
+ original_amount: product.origin_total,
1354
+ product_id: product.id,
1355
+ percent: nextBundleDiscount.par_value,
1356
+ discount_product_id: nextBundleDiscount.product_id
1357
+ },
1358
+ metadata: {
1359
+ custom_product_bundle_map_id: nextUniqueId,
1360
+ num: 1
1361
+ },
1362
+ _num: 1,
1363
+ config: nextBundleDiscount == null ? void 0 : nextBundleDiscount.config
1364
+ };
1365
+ const nextAppliedProducts = appliedDiscountProducts.get(nextBundleDiscount.id) || [];
1366
+ nextAppliedProducts.push(nextDiscountDetail);
1367
+ appliedDiscountProducts.set(nextBundleDiscount.id, nextAppliedProducts);
1368
+ processedItems.push({
1369
+ ...flatItem,
1370
+ _id: nextUniqueId,
1371
+ num: 1,
1372
+ quantity: 1,
1373
+ price: nextDiscountedPrice,
1374
+ total: nextDiscountedPrice,
1375
+ discount_list: [nextDiscountDetail],
1376
+ processed: true,
1377
+ _discountId: nextBundleDiscount.id
1378
+ });
1379
+ continueSplitIndex++;
1380
+ }
1381
+ remainingNum -= nextSplitCount;
930
1382
  }
931
1383
  } else {
932
- const selectedDiscount2 = selectedDiscountCard || applicableDiscounts[0];
933
- usedDiscounts.set(selectedDiscount2.id, true);
1384
+ const currentBundleDiscount = selectedDiscountCard || applicableDiscounts[0];
1385
+ usedDiscounts.set(currentBundleDiscount.id, true);
1386
+ if ((currentBundleDiscount.tag || currentBundleDiscount.type) === "good_pass") {
1387
+ const currentCount = usedProductIdCounts.get(currentBundleDiscount.product_id) || 0;
1388
+ usedProductIdCounts.set(currentBundleDiscount.product_id, currentCount + 1);
1389
+ }
1390
+ const noSplitDiscountType = currentBundleDiscount.tag || currentBundleDiscount.type;
1391
+ if (["discount_card", "product_discount_card"].includes(noSplitDiscountType)) {
1392
+ const bundleQuantity = product.num || 1;
1393
+ const currentNoSplitCount = usedDiscountCardLimitCounts.get(currentBundleDiscount.id) || 0;
1394
+ usedDiscountCardLimitCounts.set(currentBundleDiscount.id, currentNoSplitCount + bundleQuantity);
1395
+ }
934
1396
  const productOriginTotal = product.original_price || product.price || 0;
935
- const isOrderLevel = (0, import_utils.isOrderLevelFixedAmountDiscount)(selectedDiscount2);
936
- const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount2.id) : null;
1397
+ const isOrderLevel = (0, import_utils.isOrderLevelFixedAmountDiscount)(selectedDiscount);
1398
+ const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
937
1399
  const productAllocation = orderLevelAllocation == null ? void 0 : orderLevelAllocation.get(flatItem._id);
938
1400
  let targetProductTotal;
939
1401
  let fixedAmountPerItem;
@@ -944,39 +1406,42 @@ var RulesModule = class extends import_BaseModule.BaseModule {
944
1406
  targetProductTotal = Math.max(new import_decimal.default(productOriginTotal).minus(fixedAmountPerItem).toNumber(), 0);
945
1407
  } else {
946
1408
  targetProductTotal = (0, import_utils.getDiscountAmount)(
947
- selectedDiscount2,
1409
+ currentBundleDiscount,
948
1410
  productOriginTotal,
949
1411
  productOriginTotal
950
1412
  );
951
1413
  fixedAmountPerItem = new import_decimal.default(productOriginTotal).minus(targetProductTotal).toNumber();
952
1414
  }
1415
+ const bundleActualDiscountAmount = new import_decimal.default(productOriginTotal).minus(targetProductTotal).toNumber();
953
1416
  const uniqueId = flatItem._id;
954
1417
  const discountDetail = {
955
- amount: fixedAmountPerItem * (product.num || 1),
956
- type: selectedDiscount2.tag === "product_discount_card" ? "discount_card" : selectedDiscount2.tag,
1418
+ amount: bundleActualDiscountAmount * (product.num || 1),
1419
+ type: currentBundleDiscount.tag === "product_discount_card" ? "discount_card" : currentBundleDiscount.tag,
957
1420
  discount: {
958
- discount_card_type: (_A = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _A.discount_card_type,
959
- fixed_amount: fixedAmountPerItem,
960
- discount_calculation_mode: (_B = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _B.discount_calculation_mode,
961
- resource_id: selectedDiscount2.id,
962
- title: selectedDiscount2.format_title,
1421
+ discount_card_type: (_K = currentBundleDiscount == null ? void 0 : currentBundleDiscount.metadata) == null ? void 0 : _K.discount_card_type,
1422
+ fixed_amount: bundleActualDiscountAmount,
1423
+ discount_calculation_mode: (_L = currentBundleDiscount == null ? void 0 : currentBundleDiscount.metadata) == null ? void 0 : _L.discount_calculation_mode,
1424
+ resource_id: currentBundleDiscount.id,
1425
+ title: currentBundleDiscount.format_title,
963
1426
  original_amount: product.original_price,
964
1427
  product_id: product.id,
965
- percent: selectedDiscount2.par_value
1428
+ percent: currentBundleDiscount.par_value,
1429
+ discount_product_id: currentBundleDiscount.product_id
966
1430
  },
967
1431
  metadata: {
968
1432
  // 🔥 使用唯一的 _id
969
1433
  custom_product_bundle_map_id: uniqueId,
970
- discount_rule_uncheck_flag: selectedDiscount2 == null ? void 0 : selectedDiscount2.discount_rule_uncheck_flag,
1434
+ discount_rule_uncheck_flag: selectedDiscount == null ? void 0 : selectedDiscount.discount_rule_uncheck_flag,
971
1435
  num: product.num || 1,
972
1436
  // 🔥 order_level 分摊差值
973
1437
  ...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference }
974
1438
  },
975
- _num: (product.num || 1) * (((_C = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _C.num) || 1)
1439
+ config: currentBundleDiscount == null ? void 0 : currentBundleDiscount.config,
1440
+ _num: (product.num || 1) * (((_M = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _M.num) || 1)
976
1441
  };
977
- const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
1442
+ const appliedProducts = appliedDiscountProducts.get(currentBundleDiscount.id) || [];
978
1443
  appliedProducts.push(discountDetail);
979
- appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
1444
+ appliedDiscountProducts.set(currentBundleDiscount.id, appliedProducts);
980
1445
  processedItems.push({
981
1446
  ...flatItem,
982
1447
  total: targetProductTotal,
@@ -995,6 +1460,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
995
1460
  const mainProductArr = processedProductsMap2.get(product._id);
996
1461
  if (!mainProductArr || mainProductArr.length === 0) {
997
1462
  const getDefaultProduct = () => {
1463
+ const restoredOptions = restoreOptionPrices(product.options);
998
1464
  if (product.isClient) {
999
1465
  return this.hooks.setProduct(originProduct, {
1000
1466
  discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
@@ -1004,7 +1470,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1004
1470
  original_price: product.original_price
1005
1471
  },
1006
1472
  bundle: product.bundle,
1007
- options: product.options
1473
+ options: restoredOptions
1008
1474
  }),
1009
1475
  variant: originProduct._productInit.variant,
1010
1476
  original_price: originProduct._productInit.original_price,
@@ -1013,15 +1479,17 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1013
1479
  price: product.price
1014
1480
  },
1015
1481
  bundle: product.bundle,
1016
- options: product.options
1017
- })
1482
+ options: restoredOptions
1483
+ }),
1484
+ options: restoredOptions
1018
1485
  });
1019
1486
  } else {
1020
1487
  return this.hooks.setProduct(originProduct, {
1021
1488
  discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
1022
1489
  total: product.total,
1023
1490
  origin_total: product.origin_total,
1024
- price: product.price
1491
+ price: product.price,
1492
+ options: restoreOptionPrices(product.options)
1025
1493
  });
1026
1494
  }
1027
1495
  };
@@ -1061,80 +1529,92 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1061
1529
  const mainProduct = mainProductArr[0];
1062
1530
  const mainProductData = this.hooks.getProduct(mainProduct);
1063
1531
  const newBundleWithDiscount = [];
1064
- (product.bundle || []).forEach((bundleItem, bundleIndex) => {
1065
- const processedItems = bundleProcessingInfo.get(bundleIndex) || [bundleItem];
1066
- if (processedItems.length > 1) {
1067
- processedItems.forEach((item) => {
1068
- const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1069
- var _a;
1070
- return {
1071
- ...discount,
1072
- metadata: {
1073
- ...discount.metadata,
1074
- num: item.num,
1075
- custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
1076
- }
1077
- // num: item.num, // 使用拆分后的 num
1078
- };
1079
- });
1080
- newBundleWithDiscount.push({
1081
- ...bundleItem,
1082
- _id: item._id,
1083
- product_id: bundleItem.product_id,
1084
- price: item.price,
1085
- num: item.num,
1086
- discount_list: updatedDiscountList2
1087
- });
1088
- });
1089
- } else {
1090
- const item = processedItems[0];
1091
- if (item.processed) {
1092
- const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1093
- var _a;
1094
- return {
1095
- ...discount,
1096
- metadata: {
1097
- ...discount.metadata,
1098
- num: item.num,
1099
- custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
1100
- }
1101
- // num: item.num, // 使用当前的 num
1102
- };
1103
- });
1104
- newBundleWithDiscount.push({
1105
- ...bundleItem,
1106
- _id: item._id,
1107
- product_id: bundleItem.product_id,
1108
- price: item.price,
1109
- num: item.num,
1110
- discount_list: updatedDiscountList2
1532
+ (product.bundle || []).forEach(
1533
+ (bundleItem, bundleIndex) => {
1534
+ const processedItems = bundleProcessingInfo.get(
1535
+ bundleIndex
1536
+ ) || [bundleItem];
1537
+ if (processedItems.length > 1) {
1538
+ processedItems.forEach((item) => {
1539
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1540
+ var _a;
1541
+ return {
1542
+ ...discount,
1543
+ metadata: {
1544
+ ...discount.metadata,
1545
+ num: item.num,
1546
+ custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
1547
+ }
1548
+ // num: item.num, // 使用拆分后的 num
1549
+ };
1550
+ });
1551
+ newBundleWithDiscount.push({
1552
+ ...bundleItem,
1553
+ _id: item._id,
1554
+ product_id: bundleItem.product_id,
1555
+ price: item.price,
1556
+ num: item.num,
1557
+ quantity: item.num,
1558
+ discount_list: updatedDiscountList2
1559
+ });
1111
1560
  });
1112
1561
  } else {
1113
- newBundleWithDiscount.push(item);
1562
+ const item = processedItems[0];
1563
+ if (item.processed) {
1564
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1565
+ var _a;
1566
+ return {
1567
+ ...discount,
1568
+ metadata: {
1569
+ ...discount.metadata,
1570
+ num: item.num,
1571
+ custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
1572
+ }
1573
+ // num: item.num, // 使用当前的 num
1574
+ };
1575
+ });
1576
+ newBundleWithDiscount.push({
1577
+ ...bundleItem,
1578
+ _id: item._id,
1579
+ product_id: bundleItem.product_id,
1580
+ price: item.price,
1581
+ num: item.num,
1582
+ quantity: item.num,
1583
+ discount_list: updatedDiscountList2
1584
+ });
1585
+ } else {
1586
+ newBundleWithDiscount.push(item);
1587
+ }
1114
1588
  }
1115
1589
  }
1116
- });
1590
+ );
1117
1591
  let newTotalWithDiscount = Number(mainProductData.price || 0);
1118
- let newOriginTotalWithDiscount = Number(mainProductData.original_price || mainProductData.price || 0);
1119
- const updatedMainDiscountList = mainProductData.discount_list.map((discount) => {
1120
- var _a, _b;
1121
- if ((_a = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a.custom_product_bundle_map_id) {
1122
- return discount;
1123
- }
1124
- return {
1125
- ...discount,
1126
- // num: 1,
1127
- metadata: {
1128
- ...discount.metadata,
1129
- custom_product_bundle_map_id: (_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.custom_product_bundle_map_id,
1130
- num: 1
1592
+ let newOriginTotalWithDiscount = Number(
1593
+ mainProductData.original_price || mainProductData.price || 0
1594
+ );
1595
+ const updatedMainDiscountList = mainProductData.discount_list.map(
1596
+ (discount) => {
1597
+ var _a, _b;
1598
+ if ((_a = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a.custom_product_bundle_map_id) {
1599
+ return discount;
1131
1600
  }
1132
- };
1133
- });
1134
- const mainDiscountList = updatedMainDiscountList.filter((item) => {
1135
- var _a;
1136
- return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
1137
- });
1601
+ return {
1602
+ ...discount,
1603
+ // num: 1,
1604
+ metadata: {
1605
+ ...discount.metadata,
1606
+ custom_product_bundle_map_id: (_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.custom_product_bundle_map_id,
1607
+ num: 1
1608
+ }
1609
+ };
1610
+ }
1611
+ );
1612
+ const mainDiscountList = updatedMainDiscountList.filter(
1613
+ (item) => {
1614
+ var _a;
1615
+ return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
1616
+ }
1617
+ );
1138
1618
  if (mainDiscountList && mainDiscountList.length > 0) {
1139
1619
  const allDiscountAmount = (0, import_utils.getDiscountListAmountTotal)(mainDiscountList);
1140
1620
  newTotalWithDiscount = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotalWithDiscount;
@@ -1164,20 +1644,24 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1164
1644
  quantity: 1,
1165
1645
  discount_list: updatedMainDiscountList,
1166
1646
  bundle: newBundleWithDiscount,
1167
- total: new import_decimal.default(newTotalWithDiscount).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber(),
1168
- origin_total: new import_decimal.default(newOriginTotalWithDiscount).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber()
1647
+ total: newTotalWithDiscount,
1648
+ origin_total: newOriginTotalWithDiscount
1169
1649
  })
1170
1650
  );
1171
1651
  if (mainProductQuantity > 1) {
1172
1652
  const newBundleOriginal = [];
1173
- (product.bundle || []).forEach((bundleItem, bundleIndex) => {
1174
- newBundleOriginal.push({
1175
- ...bundleItem,
1176
- discount_list: []
1177
- });
1178
- });
1653
+ (product.bundle || []).forEach(
1654
+ (bundleItem, bundleIndex) => {
1655
+ newBundleOriginal.push({
1656
+ ...bundleItem,
1657
+ discount_list: []
1658
+ });
1659
+ }
1660
+ );
1179
1661
  let newTotalOriginal = Number(mainProductData.price || 0);
1180
- let newOriginTotalOriginal = Number(mainProductData.original_price || mainProductData.price || 0);
1662
+ let newOriginTotalOriginal = Number(
1663
+ mainProductData.original_price || mainProductData.price || 0
1664
+ );
1181
1665
  const updatedMainDiscountListOriginal = mainProductData.discount_list.map((discount) => {
1182
1666
  var _a, _b;
1183
1667
  if ((_a = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a.custom_product_bundle_map_id) {
@@ -1193,12 +1677,16 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1193
1677
  // num: mainProductQuantity - 1,
1194
1678
  };
1195
1679
  });
1196
- const mainDiscountListOriginal = updatedMainDiscountListOriginal.filter((item) => {
1197
- var _a;
1198
- return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
1199
- });
1680
+ const mainDiscountListOriginal = updatedMainDiscountListOriginal.filter(
1681
+ (item) => {
1682
+ var _a;
1683
+ return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
1684
+ }
1685
+ );
1200
1686
  if (mainDiscountListOriginal && mainDiscountListOriginal.length > 0) {
1201
- const allDiscountAmount = (0, import_utils.getDiscountListAmount)(mainDiscountListOriginal);
1687
+ const allDiscountAmount = (0, import_utils.getDiscountListAmount)(
1688
+ mainDiscountListOriginal
1689
+ );
1202
1690
  newTotalOriginal = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotalOriginal;
1203
1691
  newOriginTotalOriginal = mainProductData.origin_total ?? newOriginTotalOriginal;
1204
1692
  }
@@ -1235,59 +1723,68 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1235
1723
  const mainProductData = this.hooks.getProduct(mainProduct);
1236
1724
  const newBundle = [];
1237
1725
  if (product.bundle && Array.isArray(product.bundle)) {
1238
- product.bundle.forEach((bundleItem, bundleIndex) => {
1239
- const bundleItemId = `${product._id}_bundle_${bundleIndex}`;
1240
- const processedBundleItems = processedFlatItemsMap2.get(bundleItemId);
1241
- if (!processedBundleItems || processedBundleItems.length === 0) {
1242
- newBundle.push(bundleItem);
1243
- } else {
1244
- processedBundleItems.forEach((item) => {
1245
- const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1246
- var _a2;
1247
- return {
1248
- ...discount,
1249
- metadata: {
1250
- ...discount.metadata,
1251
- num: item.num,
1252
- custom_product_bundle_map_id: (_a2 = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id
1253
- }
1254
- // num: item.num, // 使用拆分后的 num
1255
- };
1726
+ product.bundle.forEach(
1727
+ (bundleItem, bundleIndex) => {
1728
+ const bundleItemId = `${product._id}_bundle_${bundleIndex}`;
1729
+ const processedBundleItems = processedFlatItemsMap2.get(bundleItemId);
1730
+ if (!processedBundleItems || processedBundleItems.length === 0) {
1731
+ newBundle.push(bundleItem);
1732
+ } else {
1733
+ processedBundleItems.forEach((item) => {
1734
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1735
+ var _a2;
1736
+ return {
1737
+ ...discount,
1738
+ metadata: {
1739
+ ...discount.metadata,
1740
+ num: item.num,
1741
+ custom_product_bundle_map_id: (_a2 = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id
1742
+ }
1743
+ // num: item.num, // 使用拆分后的 num
1744
+ };
1745
+ });
1746
+ newBundle.push({
1747
+ ...bundleItem,
1748
+ _id: item._id,
1749
+ product_id: bundleItem.product_id,
1750
+ price: item.price,
1751
+ num: item.num,
1752
+ quantity: item.num,
1753
+ discount_list: updatedDiscountList2,
1754
+ bundle_selling_price: bundleItem.bundle_selling_price !== void 0 ? item.price : void 0
1755
+ });
1256
1756
  });
1257
- newBundle.push({
1258
- ...bundleItem,
1259
- _id: item._id,
1260
- product_id: bundleItem.product_id,
1261
- price: item.price,
1262
- num: item.num,
1263
- discount_list: updatedDiscountList2
1264
- });
1265
- });
1757
+ }
1266
1758
  }
1267
- });
1759
+ );
1268
1760
  }
1269
1761
  let newTotal = Number(mainProductData.price || 0);
1270
- let newOriginTotal = Number(mainProductData.original_price || mainProductData.price || 0);
1271
- const isManualDiscount = typeof mainProductData.isManualDiscount === "boolean" ? mainProductData.isManualDiscount : mainProductData.total != mainProductData.origin_total && (!((_a = mainProductData.discount_list) == null ? void 0 : _a.length) || ((_c = (_b = mainProductData == null ? void 0 : mainProductData.discount_list) == null ? void 0 : _b.every) == null ? void 0 : _c.call(_b, (item) => item.type === "product")));
1762
+ let newOriginTotal = Number(
1763
+ mainProductData.original_price || mainProductData.price || 0
1764
+ );
1765
+ const isManualDiscount = typeof mainProductData.isManualDiscount === "boolean" ? mainProductData.isManualDiscount : mainProductData.total != mainProductData.origin_total && (!((_a = mainProductData.discount_list) == null ? void 0 : _a.length) || ((_c = (_b = mainProductData == null ? void 0 : mainProductData.discount_list) == null ? void 0 : _b.every) == null ? void 0 : _c.call(
1766
+ _b,
1767
+ (item) => item.type === "product"
1768
+ )));
1272
1769
  if (isManualDiscount) {
1273
1770
  newTotal = mainProductData.total ?? newTotal;
1274
1771
  newOriginTotal = mainProductData.origin_total ?? newOriginTotal;
1275
1772
  } else {
1276
- const mainDiscountList = mainProductData.discount_list.filter((item) => {
1277
- var _a2;
1278
- return !((_a2 = item == null ? void 0 : item.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id);
1279
- });
1773
+ const mainDiscountList = mainProductData.discount_list.filter(
1774
+ (item) => {
1775
+ var _a2;
1776
+ return !((_a2 = item == null ? void 0 : item.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id);
1777
+ }
1778
+ );
1280
1779
  if (mainDiscountList && mainDiscountList.length > 0) {
1281
1780
  const allDiscountAmount = (0, import_utils.getDiscountListAmount)(mainDiscountList);
1282
1781
  newTotal = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotal;
1283
1782
  newOriginTotal = mainProductData.origin_total ?? newOriginTotal;
1284
1783
  }
1285
1784
  if (newBundle.length > 0) {
1286
- newBundle.forEach((item) => {
1287
- newTotal += Number(item.price) * Number(item.num);
1288
- });
1289
1785
  newBundle.forEach((item) => {
1290
1786
  var _a2, _b2, _c2;
1787
+ newTotal += Number(item.price) * Number(item.num);
1291
1788
  const originalPrice = ((_c2 = (_b2 = (_a2 = item.discount_list) == null ? void 0 : _a2[0]) == null ? void 0 : _b2.discount) == null ? void 0 : _c2.original_amount) || item.price;
1292
1789
  newOriginTotal += Number(originalPrice) * Number(item.num);
1293
1790
  });
@@ -1300,8 +1797,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1300
1797
  return accumulator.add(currentPrice.mul(currentNum));
1301
1798
  }, new import_decimal.default(newTotal)).toNumber();
1302
1799
  }
1303
- newTotal = new import_decimal.default(newTotal).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
1304
- newOriginTotal = new import_decimal.default(newOriginTotal).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
1305
1800
  result.push(
1306
1801
  this.hooks.setProduct(mainProduct, {
1307
1802
  ...mainProductData,