@pisell/pisellos 2.1.172 → 2.1.174

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 (238) hide show
  1. package/dist/apis/picoding.d.ts +0 -0
  2. package/dist/apis/picoding.js +1 -0
  3. package/dist/index.d.ts +0 -1
  4. package/dist/index.js +0 -1
  5. package/dist/model/strategy/adapter/promotion/evaluator.js +26 -99
  6. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  7. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +2 -2
  8. package/dist/model/strategy/adapter/walletPass/evaluator.js +12 -63
  9. package/dist/model/strategy/adapter/walletPass/locales.js +3 -12
  10. package/dist/model/strategy/engine.d.ts +5 -18
  11. package/dist/model/strategy/engine.js +45 -145
  12. package/dist/model/strategy/type.d.ts +0 -17
  13. package/dist/model/strategy/type.js +0 -4
  14. package/dist/modules/Cart/types.d.ts +0 -2
  15. package/dist/modules/Cart/utils/cartProduct.js +25 -56
  16. package/dist/modules/Cart/utils/changePrice.js +16 -9
  17. package/dist/modules/Discount/availability.d.ts +7 -0
  18. package/dist/modules/Discount/availability.js +52 -0
  19. package/dist/modules/Discount/entitlementPass.d.ts +34 -0
  20. package/dist/modules/Discount/entitlementPass.js +147 -0
  21. package/dist/modules/Discount/entitlementState.d.ts +8 -0
  22. package/dist/modules/Discount/entitlementState.js +205 -0
  23. package/dist/modules/Discount/index.d.ts +12 -3
  24. package/dist/modules/Discount/index.js +211 -17
  25. package/dist/modules/Discount/types.d.ts +42 -22
  26. package/dist/modules/Holder/index.d.ts +48 -0
  27. package/dist/modules/Holder/index.js +640 -0
  28. package/dist/modules/Holder/types.d.ts +123 -0
  29. package/dist/modules/Holder/types.js +1 -0
  30. package/dist/modules/Holder/utils.d.ts +13 -0
  31. package/dist/modules/Holder/utils.js +34 -0
  32. package/dist/modules/OpenData/index.d.ts +24 -0
  33. package/dist/modules/OpenData/index.js +173 -0
  34. package/dist/modules/OpenData/types.d.ts +73 -0
  35. package/dist/modules/OpenData/types.js +1 -0
  36. package/dist/modules/OpenData/utils.d.ts +2 -0
  37. package/dist/modules/OpenData/utils.js +75 -0
  38. package/dist/modules/Order/index.d.ts +67 -1
  39. package/dist/modules/Order/index.js +923 -30
  40. package/dist/modules/Order/types.d.ts +176 -12
  41. package/dist/modules/Order/types.js +2 -0
  42. package/dist/modules/Order/utils.d.ts +128 -0
  43. package/dist/modules/Order/utils.js +621 -5
  44. package/dist/modules/Payment/index.d.ts +1 -2
  45. package/dist/modules/Payment/index.js +7 -10
  46. package/dist/modules/Payment/utils.js +0 -3
  47. package/dist/modules/Payment/walletpass.d.ts +0 -23
  48. package/dist/modules/Payment/walletpass.js +95 -191
  49. package/dist/modules/Product/types.d.ts +7 -0
  50. package/dist/modules/Product/utils.js +2 -2
  51. package/dist/modules/ProductList/index.d.ts +1 -1
  52. package/dist/modules/ProductList/index.js +4 -3
  53. package/dist/modules/Quotation/index.d.ts +48 -0
  54. package/dist/modules/Quotation/index.js +248 -0
  55. package/dist/modules/Quotation/types.d.ts +42 -0
  56. package/dist/modules/Quotation/types.js +1 -0
  57. package/dist/modules/Rules/entitlementLines.d.ts +8 -0
  58. package/dist/modules/Rules/entitlementLines.js +157 -0
  59. package/dist/modules/Rules/index.d.ts +17 -11
  60. package/dist/modules/Rules/index.js +495 -726
  61. package/dist/modules/Rules/types.d.ts +2 -4
  62. package/dist/modules/SalesSummary/index.d.ts +63 -0
  63. package/dist/modules/SalesSummary/index.js +174 -0
  64. package/dist/modules/SalesSummary/types.d.ts +60 -0
  65. package/dist/modules/SalesSummary/types.js +1 -0
  66. package/dist/modules/SalesSummary/utils.d.ts +30 -0
  67. package/dist/modules/SalesSummary/utils.js +480 -0
  68. package/dist/modules/ScanOrderLogger/index.d.ts +23 -0
  69. package/dist/modules/ScanOrderLogger/index.js +174 -0
  70. package/dist/modules/ScanOrderLogger/providers/feishu.d.ts +2 -0
  71. package/dist/modules/ScanOrderLogger/providers/feishu.js +221 -0
  72. package/dist/modules/ScanOrderLogger/providers/grafana.d.ts +2 -0
  73. package/dist/modules/ScanOrderLogger/providers/grafana.js +50 -0
  74. package/dist/modules/ScanOrderLogger/types.d.ts +53 -0
  75. package/dist/modules/ScanOrderLogger/types.js +1 -0
  76. package/dist/modules/Schedule/getDateIsInSchedule.js +11 -18
  77. package/dist/modules/Schedule/utils.d.ts +1 -1
  78. package/dist/modules/Summary/types.d.ts +0 -2
  79. package/dist/modules/Summary/utils.d.ts +3 -9
  80. package/dist/modules/Summary/utils.js +67 -57
  81. package/dist/modules/index.d.ts +5 -0
  82. package/dist/modules/index.js +6 -1
  83. package/dist/plugins/window.d.ts +3 -2
  84. package/dist/solution/BookingByStep/index.d.ts +17 -3
  85. package/dist/solution/BookingByStep/index.js +322 -247
  86. package/dist/solution/BookingByStep/types.d.ts +4 -1
  87. package/dist/solution/BookingByStep/types.js +7 -1
  88. package/dist/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  89. package/dist/solution/BookingByStep/utils/timeslots.js +19 -12
  90. package/dist/solution/Checkout/index.js +0 -2
  91. package/dist/solution/ScanOrder/index.d.ts +158 -0
  92. package/dist/solution/ScanOrder/index.js +3474 -0
  93. package/dist/solution/ScanOrder/types.d.ts +307 -0
  94. package/dist/solution/ScanOrder/types.js +35 -0
  95. package/dist/solution/ScanOrder/utils.d.ts +172 -0
  96. package/dist/solution/ScanOrder/utils.js +796 -0
  97. package/dist/solution/ShopDiscount/index.d.ts +6 -2
  98. package/dist/solution/ShopDiscount/index.js +194 -110
  99. package/dist/solution/ShopDiscount/types.d.ts +1 -1
  100. package/dist/solution/ShopDiscount/types.js +1 -2
  101. package/dist/solution/ShopDiscount/utils.d.ts +1 -0
  102. package/dist/solution/ShopDiscount/utils.js +52 -27
  103. package/dist/solution/VenueBooking/index.d.ts +225 -0
  104. package/dist/solution/VenueBooking/index.js +3749 -0
  105. package/dist/solution/VenueBooking/sales-section-4-annotated.json +343 -0
  106. package/dist/solution/VenueBooking/types.d.ts +156 -0
  107. package/dist/solution/VenueBooking/types.js +21 -0
  108. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +11 -0
  109. package/dist/solution/VenueBooking/utils/dateSummary.js +104 -0
  110. package/dist/solution/VenueBooking/utils/resource.d.ts +14 -0
  111. package/dist/solution/VenueBooking/utils/resource.js +131 -0
  112. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +38 -0
  113. package/dist/solution/VenueBooking/utils/slotMerge.js +239 -0
  114. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +32 -0
  115. package/dist/solution/VenueBooking/utils/timeSlot.js +453 -0
  116. package/dist/solution/VenueBooking/utils.d.ts +1 -0
  117. package/dist/solution/VenueBooking/utils.js +1 -0
  118. package/dist/solution/index.d.ts +2 -0
  119. package/dist/solution/index.js +3 -1
  120. package/dist/types/index.d.ts +1 -0
  121. package/lib/apis/picoding.d.ts +0 -0
  122. package/lib/apis/picoding.js +0 -0
  123. package/lib/index.d.ts +0 -1
  124. package/lib/index.js +1 -3
  125. package/lib/model/strategy/adapter/promotion/evaluator.js +8 -57
  126. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  127. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +2 -2
  128. package/lib/model/strategy/adapter/walletPass/evaluator.js +7 -36
  129. package/lib/model/strategy/adapter/walletPass/locales.js +3 -12
  130. package/lib/model/strategy/engine.d.ts +5 -18
  131. package/lib/model/strategy/engine.js +21 -85
  132. package/lib/model/strategy/type.d.ts +0 -17
  133. package/lib/modules/Cart/types.d.ts +0 -2
  134. package/lib/modules/Cart/utils/cartProduct.js +12 -39
  135. package/lib/modules/Cart/utils/changePrice.js +13 -9
  136. package/lib/modules/Discount/availability.d.ts +7 -0
  137. package/lib/modules/Discount/availability.js +91 -0
  138. package/lib/modules/Discount/entitlementPass.d.ts +34 -0
  139. package/lib/modules/Discount/entitlementPass.js +184 -0
  140. package/lib/modules/Discount/entitlementState.d.ts +8 -0
  141. package/lib/modules/Discount/entitlementState.js +206 -0
  142. package/lib/modules/Discount/index.d.ts +12 -3
  143. package/lib/modules/Discount/index.js +123 -12
  144. package/lib/modules/Discount/types.d.ts +42 -22
  145. package/lib/modules/Holder/index.d.ts +48 -0
  146. package/lib/modules/Holder/index.js +402 -0
  147. package/lib/modules/Holder/types.d.ts +123 -0
  148. package/lib/modules/Holder/types.js +17 -0
  149. package/lib/modules/Holder/utils.d.ts +13 -0
  150. package/lib/modules/Holder/utils.js +71 -0
  151. package/lib/modules/OpenData/index.d.ts +24 -0
  152. package/lib/modules/OpenData/index.js +119 -0
  153. package/lib/modules/OpenData/types.d.ts +73 -0
  154. package/lib/modules/OpenData/types.js +17 -0
  155. package/lib/modules/OpenData/utils.d.ts +2 -0
  156. package/lib/modules/OpenData/utils.js +111 -0
  157. package/lib/modules/Order/index.d.ts +67 -1
  158. package/lib/modules/Order/index.js +529 -1
  159. package/lib/modules/Order/types.d.ts +176 -12
  160. package/lib/modules/Order/utils.d.ts +128 -0
  161. package/lib/modules/Order/utils.js +514 -2
  162. package/lib/modules/Payment/index.d.ts +1 -2
  163. package/lib/modules/Payment/index.js +0 -1
  164. package/lib/modules/Payment/utils.js +0 -3
  165. package/lib/modules/Payment/walletpass.d.ts +0 -23
  166. package/lib/modules/Payment/walletpass.js +17 -94
  167. package/lib/modules/Product/types.d.ts +7 -0
  168. package/lib/modules/Product/utils.js +2 -2
  169. package/lib/modules/ProductList/index.d.ts +1 -1
  170. package/lib/modules/ProductList/index.js +5 -4
  171. package/lib/modules/Quotation/index.d.ts +48 -0
  172. package/lib/modules/Quotation/index.js +152 -0
  173. package/lib/modules/Quotation/types.d.ts +42 -0
  174. package/lib/modules/Quotation/types.js +17 -0
  175. package/lib/modules/Rules/entitlementLines.d.ts +8 -0
  176. package/lib/modules/Rules/entitlementLines.js +158 -0
  177. package/lib/modules/Rules/index.d.ts +17 -11
  178. package/lib/modules/Rules/index.js +548 -798
  179. package/lib/modules/Rules/types.d.ts +2 -4
  180. package/lib/modules/SalesSummary/index.d.ts +63 -0
  181. package/lib/modules/SalesSummary/index.js +105 -0
  182. package/lib/modules/SalesSummary/types.d.ts +60 -0
  183. package/lib/modules/SalesSummary/types.js +17 -0
  184. package/lib/modules/SalesSummary/utils.d.ts +30 -0
  185. package/lib/modules/SalesSummary/utils.js +420 -0
  186. package/lib/modules/ScanOrderLogger/index.d.ts +23 -0
  187. package/lib/modules/ScanOrderLogger/index.js +147 -0
  188. package/lib/modules/ScanOrderLogger/providers/feishu.d.ts +2 -0
  189. package/lib/modules/ScanOrderLogger/providers/feishu.js +157 -0
  190. package/lib/modules/ScanOrderLogger/providers/grafana.d.ts +2 -0
  191. package/lib/modules/ScanOrderLogger/providers/grafana.js +52 -0
  192. package/lib/modules/ScanOrderLogger/types.d.ts +53 -0
  193. package/lib/modules/ScanOrderLogger/types.js +17 -0
  194. package/lib/modules/Schedule/getDateIsInSchedule.js +9 -11
  195. package/lib/modules/Schedule/utils.d.ts +1 -1
  196. package/lib/modules/Summary/types.d.ts +0 -2
  197. package/lib/modules/Summary/utils.d.ts +3 -9
  198. package/lib/modules/Summary/utils.js +45 -34
  199. package/lib/modules/index.d.ts +5 -0
  200. package/lib/modules/index.js +11 -1
  201. package/lib/plugins/window.d.ts +3 -2
  202. package/lib/solution/BookingByStep/index.d.ts +17 -3
  203. package/lib/solution/BookingByStep/index.js +45 -4
  204. package/lib/solution/BookingByStep/types.d.ts +4 -1
  205. package/lib/solution/BookingByStep/types.js +15 -0
  206. package/lib/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  207. package/lib/solution/BookingByStep/utils/timeslots.js +19 -11
  208. package/lib/solution/Checkout/index.js +0 -2
  209. package/lib/solution/ScanOrder/index.d.ts +158 -0
  210. package/lib/solution/ScanOrder/index.js +2135 -0
  211. package/lib/solution/ScanOrder/types.d.ts +307 -0
  212. package/lib/solution/ScanOrder/types.js +36 -0
  213. package/lib/solution/ScanOrder/utils.d.ts +172 -0
  214. package/lib/solution/ScanOrder/utils.js +658 -0
  215. package/lib/solution/ShopDiscount/index.d.ts +6 -2
  216. package/lib/solution/ShopDiscount/index.js +94 -50
  217. package/lib/solution/ShopDiscount/types.d.ts +1 -1
  218. package/lib/solution/ShopDiscount/utils.d.ts +1 -0
  219. package/lib/solution/ShopDiscount/utils.js +48 -11
  220. package/lib/solution/VenueBooking/index.d.ts +225 -0
  221. package/lib/solution/VenueBooking/index.js +2073 -0
  222. package/lib/solution/VenueBooking/sales-section-4-annotated.json +343 -0
  223. package/lib/solution/VenueBooking/types.d.ts +156 -0
  224. package/lib/solution/VenueBooking/types.js +44 -0
  225. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +11 -0
  226. package/lib/solution/VenueBooking/utils/dateSummary.js +110 -0
  227. package/lib/solution/VenueBooking/utils/resource.d.ts +14 -0
  228. package/lib/solution/VenueBooking/utils/resource.js +92 -0
  229. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +38 -0
  230. package/lib/solution/VenueBooking/utils/slotMerge.js +237 -0
  231. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +32 -0
  232. package/lib/solution/VenueBooking/utils/timeSlot.js +339 -0
  233. package/lib/solution/VenueBooking/utils.d.ts +1 -0
  234. package/lib/solution/VenueBooking/utils.js +69 -0
  235. package/lib/solution/index.d.ts +2 -0
  236. package/lib/solution/index.js +5 -1
  237. package/lib/types/index.d.ts +1 -0
  238. package/package.json +1 -1
@@ -39,18 +39,32 @@ var import_utils2 = require("../Cart/utils");
39
39
  var import_decimal = __toESM(require("decimal.js"));
40
40
  var import_lodash_es = require("lodash-es");
41
41
  var import_dayjs = __toESM(require("dayjs"));
42
+ var import_evaluator = require("../../model/strategy/adapter/walletPass/evaluator");
43
+ var import_entitlementPass = require("../Discount/entitlementPass");
44
+ var import_availability = require("../Discount/availability");
45
+ var import_entitlementState = require("../Discount/entitlementState");
46
+ var import_utils3 = require("../../solution/ShopDiscount/utils");
47
+ var import_lodash_es2 = require("lodash-es");
48
+ var import_entitlementLines = require("./entitlementLines");
42
49
  var RulesModule = class extends import_BaseModule.BaseModule {
43
50
  constructor(name, version) {
44
51
  super(name, version);
45
52
  this.defaultName = "rules";
46
53
  this.defaultVersion = "1.0.0";
54
+ this.entitlementPassEnabled = false;
47
55
  this.hooks = {};
48
56
  }
57
+ setEntitlementPassEnabled(enabled) {
58
+ this.entitlementPassEnabled = enabled;
59
+ }
60
+ getWalletPassEvaluator() {
61
+ var _a, _b, _c;
62
+ return ((_c = (_b = (_a = this.core) == null ? void 0 : _a.getPlugin("window")) == null ? void 0 : _b.getWalletPassEvaluator) == null ? void 0 : _c.call(_b)) || (this.defaultWalletPassEvaluator ?? (this.defaultWalletPassEvaluator = new import_evaluator.WalletPassEvaluator()));
63
+ }
49
64
  async initialize(core, options) {
50
65
  this.core = core;
51
66
  this.hooks = options == null ? void 0 : options.hooks;
52
67
  this.store = options == null ? void 0 : options.store;
53
- this.window = core.getPlugin("window");
54
68
  }
55
69
  async setRulesList(rulesList) {
56
70
  this.store.rulesList = rulesList;
@@ -59,29 +73,64 @@ var RulesModule = class extends import_BaseModule.BaseModule {
59
73
  getRulesList() {
60
74
  return this.store.rulesList;
61
75
  }
62
- // 商品不需要holder,则不需要判断,直接返回true,商品需要holder但是还没填写,那么暂时不使用带有holder的券,直到填写才去匹配
63
- checkHolderMatch(discount, product, holders) {
64
- var _a;
76
+ normalizeHolderRecordIds(value) {
77
+ const records = Array.isArray(value) ? value : [value];
78
+ return Array.from(
79
+ new Set(
80
+ records.map((record) => {
81
+ if (record && typeof record === "object") {
82
+ return record.form_record_id;
83
+ }
84
+ return record;
85
+ }).filter(
86
+ (record) => record !== void 0 && record !== null && record !== "" && record !== 0 && record !== "0"
87
+ ).map(String)
88
+ )
89
+ );
90
+ }
91
+ /**
92
+ * 商品未开启 Holder 选择时跳过匹配;已开启时,特定 form Holder 卡
93
+ * 只适用于同一 Holder Record,是否必填不影响匹配规则。
94
+ */
95
+ checkHolderMatch(discount, product, holderSource, holders) {
96
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
65
97
  if (((_a = discount.holder) == null ? void 0 : _a.holder_type) !== "form")
66
98
  return true;
67
- const orderHolderId = Array.isArray(holders) && holders.length > 0 ? holders[0].form_record_id : void 0;
68
- const productHolderId = Array.isArray(product.holder_id) ? product.holder_id[0] : product.holder_id;
69
- if (!product.isNeedHolder)
99
+ if (!(0, import_entitlementPass.isEntitlementPass)(discount)) {
100
+ if (!product.isNeedHolder)
101
+ return true;
102
+ const holder = holders == null ? void 0 : holders[0];
103
+ const orderHolderId = holder && typeof holder === "object" ? holder.form_record_id : holder;
104
+ const productHolderId = Array.isArray(product.holder_id) ? product.holder_id[0] : product.holder_id;
105
+ if (!orderHolderId && !productHolderId)
106
+ return false;
107
+ return (productHolderId || orderHolderId) === discount.holder.holder_id;
108
+ }
109
+ const holderConfig = (holderSource == null ? void 0 : holderSource.holder_config) ?? ((_b = holderSource == null ? void 0 : holderSource.metadata) == null ? void 0 : _b.holder_config) ?? ((_c = holderSource == null ? void 0 : holderSource.origin) == null ? void 0 : _c.holder_config) ?? ((_e = (_d = holderSource == null ? void 0 : holderSource.metadata) == null ? void 0 : _d.origin) == null ? void 0 : _e.holder_config) ?? ((_f = holderSource == null ? void 0 : holderSource._origin) == null ? void 0 : _f.holder_config) ?? ((_h = (_g = holderSource == null ? void 0 : holderSource._origin) == null ? void 0 : _g.product) == null ? void 0 : _h.holder_config) ?? ((_j = (_i = holderSource == null ? void 0 : holderSource._originData) == null ? void 0 : _i.product) == null ? void 0 : _j.holder_config) ?? ((_k = holderSource == null ? void 0 : holderSource._productInit) == null ? void 0 : _k.holder_config) ?? ((_l = holderSource == null ? void 0 : holderSource._productOrigin) == null ? void 0 : _l.holder_config) ?? ((_m = holderSource == null ? void 0 : holderSource._extend) == null ? void 0 : _m.holder_config) ?? ((_o = (_n = holderSource == null ? void 0 : holderSource._extend) == null ? void 0 : _n.product) == null ? void 0 : _o.holder_config) ?? ((_r = (_q = (_p = holderSource == null ? void 0 : holderSource._extend) == null ? void 0 : _p.product) == null ? void 0 : _q.metadata) == null ? void 0 : _r.holder_config);
110
+ const holderStatus = holderConfig == null ? void 0 : holderConfig.status;
111
+ const holderEnabled = holderStatus == null || holderStatus === "" || holderStatus === true || ["enable", "1"].includes(String(holderStatus).trim().toLowerCase());
112
+ if (!holderEnabled || !(holderConfig == null ? void 0 : holderConfig.resource_id)) {
70
113
  return true;
71
- if (!orderHolderId && !productHolderId)
114
+ }
115
+ const discountHolderIds = this.normalizeHolderRecordIds(
116
+ discount.holder.holder_id
117
+ );
118
+ if (!discountHolderIds.length)
72
119
  return false;
73
- return (productHolderId || orderHolderId) === discount.holder.holder_id;
74
- }
75
- getWalletPassEvaluator() {
76
- var _a, _b;
77
- return (_b = (_a = this.window).getWalletPassEvaluator) == null ? void 0 : _b.call(_a);
120
+ const productHolderIds = this.normalizeHolderRecordIds(product.holder_id);
121
+ const candidateHolderIds = productHolderIds.length || Array.isArray(product.holder_id) ? productHolderIds : this.normalizeHolderRecordIds(holders);
122
+ if (!candidateHolderIds.length)
123
+ return false;
124
+ const discountHolderIdSet = new Set(discountHolderIds);
125
+ return candidateHolderIds.every(
126
+ (holderId) => discountHolderIdSet.has(holderId)
127
+ );
78
128
  }
79
129
  // 判断discountList 是否可以对当前productList生效
80
130
  isDiscountListAvailable({
81
131
  oldDiscountList,
82
132
  newDiscountList,
83
133
  productList,
84
- orderTotalAmount,
85
134
  holders,
86
135
  isFormSubject
87
136
  }) {
@@ -92,7 +141,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
92
141
  productList
93
142
  };
94
143
  }
95
- if (productList.every((item) => {
144
+ if (!newDiscountList.some(import_entitlementPass.isEntitlementPass) && productList.length > 0 && productList.every((item) => {
96
145
  var _a;
97
146
  const product = this.hooks.getProduct(item);
98
147
  return product.booking_id && (((_a = product.discount_list) == null ? void 0 : _a.length) || product.total == 0);
@@ -108,22 +157,25 @@ var RulesModule = class extends import_BaseModule.BaseModule {
108
157
  (discount) => !discount.isEditMode && (discount.tag !== "good_pass" || discount.isScan)
109
158
  );
110
159
  const mergedDiscountList = (0, import_utils.uniqueById)([
160
+ ...newDiscountList.filter(import_entitlementPass.isEntitlementPass),
111
161
  ...filteredOldDiscountList,
112
162
  ...newDiscountList
113
163
  ]);
114
164
  const result = this.calcDiscount({
115
165
  discountList: mergedDiscountList,
116
- productList: [...productList],
117
- orderTotalAmount,
166
+ productList: this.entitlementPassEnabled ? (0, import_lodash_es2.cloneDeep)(productList) : [...productList],
118
167
  holders,
119
168
  isFormSubject
120
169
  }, {
121
170
  scan: true
122
171
  });
123
172
  let hasApplicableDiscount = false;
124
- const newDiscountIds = newDiscountList.map((discount) => discount.id);
173
+ const newDiscountIds = new Set(newDiscountList.map((discount) => String(discount.id)));
125
174
  result.productList.forEach((product) => {
126
- const { discount_list, bundle } = this.hooks.getProduct(product);
175
+ const mappedProduct = this.hooks.getProduct(product);
176
+ if ((0, import_entitlementState.isPersistedEntitlementLine)(product, mappedProduct))
177
+ return;
178
+ const { discount_list, bundle } = mappedProduct;
127
179
  const allDiscountList = [...discount_list || []];
128
180
  (bundle || []).forEach((item) => {
129
181
  allDiscountList.push(...(item == null ? void 0 : item.discount_list) || []);
@@ -132,7 +184,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
132
184
  const usedNewDiscount = allDiscountList.some(
133
185
  (discount) => {
134
186
  var _a;
135
- return newDiscountIds.includes((_a = discount == null ? void 0 : discount.discount) == null ? void 0 : _a.resource_id);
187
+ return newDiscountIds.has(String((_a = discount == null ? void 0 : discount.discount) == null ? void 0 : _a.resource_id));
136
188
  }
137
189
  );
138
190
  if (usedNewDiscount) {
@@ -146,6 +198,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
146
198
  }
147
199
  return {
148
200
  isAvailable: hasApplicableDiscount,
201
+ evaluatedDiscountList: result.discountList,
149
202
  discountList: hasApplicableDiscount ? result.discountList : oldDiscountList,
150
203
  productList: hasApplicableDiscount ? result.productList : productList,
151
204
  unavailableReason
@@ -160,7 +213,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
160
213
  for (const discount of discountList) {
161
214
  for (const item of productList) {
162
215
  const product = this.hooks.getProduct(item);
163
- const bookingTime = ((product == null ? void 0 : product.startDate) || (0, import_dayjs.default)()).format("YYYY-MM-DD HH:mm:ss");
216
+ const bookingTime = (0, import_dayjs.default)((product == null ? void 0 : product.startDate) || void 0).format("YYYY-MM-DD HH:mm:ss");
164
217
  const filteredList = (0, import_utils.filterDiscountListByBookingTime)([discount], bookingTime);
165
218
  if (filteredList.length === 0) {
166
219
  return import_types.UnavailableReason.TimeLimit;
@@ -169,6 +222,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
169
222
  }
170
223
  for (const discount of discountList) {
171
224
  const limitedData = discount.limited_relation_product_data;
225
+ if (!limitedData)
226
+ return import_types.UnavailableReason.ProductNotApplicable;
172
227
  let hasApplicableProduct = false;
173
228
  for (const item of productList) {
174
229
  const product = this.hooks.getProduct(item);
@@ -190,16 +245,45 @@ var RulesModule = class extends import_BaseModule.BaseModule {
190
245
  discountList,
191
246
  productList,
192
247
  holders,
193
- isFormSubject,
194
- orderTotalAmount
248
+ isFormSubject
195
249
  }, options) {
250
+ discountList = this.entitlementPassEnabled ? (0, import_entitlementState.withCommittedEntitlementDetails)(discountList, productList, this.hooks.getProduct) : discountList.filter((item) => !(0, import_entitlementPass.isEntitlementPass)(item));
251
+ const usableEntitlements = discountList.filter(
252
+ (discount) => (0, import_entitlementPass.isEntitlementPass)(discount) && !discount.isEditMode && !discount.isManualSelect && !(0, import_availability.getDiscountUsageBlockReason)(discount)
253
+ );
254
+ const canUseEntitlement = (originProduct) => {
255
+ const product = this.hooks.getProduct(originProduct);
256
+ const holderProducts = Array.isArray(product.holder_id) && product.holder_id.length > 1 ? product.holder_id.map((holder_id) => ({ ...product, holder_id })) : [product];
257
+ const items = [
258
+ { type: "main", id: product.id, price: product.original_price ?? product.price },
259
+ ...(product.bundle || []).map((bundleItem) => ({
260
+ type: "bundle",
261
+ id: bundleItem._bundle_product_id ?? bundleItem.bundle_product_id ?? bundleItem.product_id,
262
+ price: bundleItem.original_price ?? bundleItem.price,
263
+ bundleItem
264
+ }))
265
+ ];
266
+ return usableEntitlements.some((discount) => {
267
+ const scope = discount.limited_relation_product_data;
268
+ if (!scope || !holderProducts.some((item) => this.checkHolderMatch(discount, item, originProduct, holders)) || !(0, import_utils.filterDiscountListByBookingTime)([discount], (0, import_dayjs.default)(product.startDate || void 0).format("YYYY-MM-DD HH:mm:ss")).length)
269
+ return false;
270
+ return items.some(
271
+ (item) => {
272
+ var _a, _b;
273
+ return Number(item.price) > 0 && (scope.type === "product_all" ? !(scope.filter === 1 && ((_a = scope.exclude_product_ids) == null ? void 0 : _a.some((id) => String(id) === String(item.id)))) : !!((_b = scope.product_ids) == null ? void 0 : _b.includes(item.id))) && this.checkPackageSubItemUsageRules(discount, { ...item, originProduct, parentProduct: product });
274
+ }
275
+ );
276
+ });
277
+ };
278
+ if (this.entitlementPassEnabled)
279
+ productList = (0, import_entitlementLines.prepareEntitlementLines)(productList, this.hooks, canUseEntitlement);
196
280
  const editModeDiscount = [];
197
281
  const addModeDiscount = [];
198
282
  discountList.forEach((discount) => {
199
283
  if (discount.isEditMode) {
200
284
  editModeDiscount.push(discount);
201
285
  } else {
202
- addModeDiscount.push(discount);
286
+ addModeDiscount.push((0, import_entitlementPass.isEntitlementPass)(discount) ? { ...discount, config: void 0, reason: void 0, reasonCode: void 0 } : discount);
203
287
  }
204
288
  });
205
289
  const editModeOrderLevelProductIds = /* @__PURE__ */ new Set();
@@ -245,8 +329,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
245
329
  bundleIndex,
246
330
  // 虚拟商品属性
247
331
  price: Number(bundleItem.price || 0),
248
- id: bundleItem._bundle_product_id,
249
- // 🔥 使用 _bundle_product_id
332
+ id: bundleItem._bundle_product_id ?? bundleItem.bundle_product_id ?? bundleItem.product_id,
250
333
  _id: `${product._id}_bundle_${bundleIndex}`,
251
334
  parentId: product._id,
252
335
  num: bundleItem.num || 1,
@@ -328,6 +411,9 @@ var RulesModule = class extends import_BaseModule.BaseModule {
328
411
  }
329
412
  return 0;
330
413
  }
414
+ if ((0, import_entitlementPass.isEntitlementPass)(a) || (0, import_entitlementPass.isEntitlementPass)(b)) {
415
+ return (0, import_entitlementPass.isEntitlementPass)(a) && (0, import_entitlementPass.isEntitlementPass)(b) ? (0, import_entitlementPass.compareEntitlementPassPriority)(a, b) : (0, import_entitlementPass.isEntitlementPass)(a) ? -1 : 1;
416
+ }
331
417
  const priorityA = getPriority(a);
332
418
  const priorityB = getPriority(b);
333
419
  if (priorityA !== priorityB) {
@@ -370,63 +456,85 @@ var RulesModule = class extends import_BaseModule.BaseModule {
370
456
  }
371
457
  return priceB.minus(priceA).toNumber();
372
458
  });
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
- }
459
+ const isProductIncludedByLimitedData = (limitedData, productId) => {
460
+ const excludedIds = (limitedData == null ? void 0 : limitedData.exclude_product_ids) || [];
461
+ const isExcluded = (limitedData == null ? void 0 : limitedData.filter) === 1 && excludedIds.some((id) => String(id) === String(productId));
462
+ return !isExcluded;
463
+ };
419
464
  const usedDiscounts = /* @__PURE__ */ new Map();
465
+ const entitlementUsageCounts = /* @__PURE__ */ new Map();
420
466
  const usedProductIdCounts = /* @__PURE__ */ new Map();
421
- const usedDiscountCardLimitCounts = /* @__PURE__ */ new Map();
422
- editModeDiscount.forEach((discount) => {
467
+ const markDiscountUsed = (discount) => {
468
+ if ((0, import_entitlementPass.isEntitlementPass)(discount)) {
469
+ entitlementUsageCounts.set(discount.id, (entitlementUsageCounts.get(discount.id) || 0) + 1);
470
+ } else {
471
+ usedDiscounts.set(discount.id, true);
472
+ }
473
+ usedProductIdCounts.set(discount.product_id, (usedProductIdCounts.get(discount.product_id) || 0) + 1);
474
+ };
475
+ const getFullCoveragePasses = (discounts, quantity) => {
423
476
  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));
477
+ const allocated = [];
478
+ const productCounts = new Map(usedProductIdCounts);
479
+ for (const discount of discounts) {
480
+ if (!(0, import_entitlementPass.isFullCoveragePass)(discount) || allocated.length >= quantity)
481
+ continue;
482
+ let count = (0, import_entitlementPass.isEntitlementPass)(discount) ? (0, import_entitlementPass.getRemainingEntitlementUses)(discount, entitlementUsageCounts.get(discount.id) || 0, quantity - allocated.length) : usedDiscounts.get(discount.id) ? 0 : 1;
483
+ const limit = Number(((_a = discount.config) == null ? void 0 : _a.maxUsagePerOrder) || 0);
484
+ if ((0, import_entitlementPass.isEntitlementPass)(discount) && limit > 0) {
485
+ count = Math.min(count, Math.max(0, Math.floor(limit) - (productCounts.get(discount.product_id) || 0)));
486
+ }
487
+ for (let i = 0; i < count; i++)
488
+ allocated.push(discount);
489
+ productCounts.set(discount.product_id, (productCounts.get(discount.product_id) || 0) + count);
490
+ }
491
+ return allocated;
492
+ };
493
+ let evaluator;
494
+ addModeDiscount.filter(import_entitlementPass.isEntitlementPass).forEach((discount) => {
495
+ var _a, _b;
496
+ discount.usageLimitFailKey = (0, import_availability.getDiscountUsageLimitFailKey)(discount);
497
+ discount.reasonCode = (0, import_availability.getDiscountUsageBlockReason)(discount);
498
+ const quota = (0, import_entitlementPass.resolveEntitlementQuota)(discount);
499
+ if (discount.reasonCode || !quota) {
500
+ discount.config = { isAvailable: false };
501
+ return;
502
+ }
503
+ evaluator ?? (evaluator = this.getWalletPassEvaluator());
504
+ const result = evaluator.checkVoucherAvailability({
505
+ orderTotalAmount: productList.reduce((sum, item) => {
506
+ const product = this.hooks.getProduct(item);
507
+ return sum.plus(new import_decimal.default(product.origin_total || 0).times(product.quantity || product.num || 1));
508
+ }, new import_decimal.default(0)).toNumber(),
509
+ // 策略按统一商品结构读主价与数量,套餐次数还需乘父商品份数。
510
+ products: sortedFlattenedList.map((item) => {
511
+ var _a2, _b2, _c;
512
+ return {
513
+ product_id: item.id,
514
+ price: item.price || 0,
515
+ main_product_selling_price: item.price || 0,
516
+ quantity: (item.quantity || item.num || 1) * (item.type === "bundle" ? ((_a2 = item.parentProduct) == null ? void 0 : _a2.quantity) || ((_b2 = item.parentProduct) == null ? void 0 : _b2.num) || 1 : 1),
517
+ product_options: item.type === "main" ? (_c = item.product) == null ? void 0 : _c.options : void 0
518
+ };
519
+ }),
520
+ vouchers: [{
521
+ ...discount,
522
+ amount: Number(discount.par_value || 0),
523
+ balance: quota.type === "unlimited" ? Number.MAX_SAFE_INTEGER : quota.balance,
524
+ type: "entitlement_pass",
525
+ unified_available_status: discount.unified_available_status ?? 1,
526
+ available_product_type: (_a = discount.limited_relation_product_data) == null ? void 0 : _a.type,
527
+ available_product_ids: (_b = discount.limited_relation_product_data) == null ? void 0 : _b.product_ids
528
+ }]
529
+ });
530
+ discount.config = { ...result.config, isAvailable: result.isAvailable };
531
+ if (!result.isAvailable) {
532
+ discount.reason = result.reason;
533
+ discount.reasonCode = result.reasonCode || "not_meet_the_required_conditions";
428
534
  }
429
535
  });
536
+ const entitlementTimeReasons = /* @__PURE__ */ new Map();
537
+ const entitlementHolderMismatch = /* @__PURE__ */ new Set();
430
538
  const discountApplicability = /* @__PURE__ */ new Map();
431
539
  const discountApplicableProducts = /* @__PURE__ */ new Map();
432
540
  addModeDiscount.forEach((discount) => {
@@ -453,7 +561,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
453
561
  startDate: (_a = flatItem.parentProduct) == null ? void 0 : _a.startDate
454
562
  };
455
563
  }
456
- const isAvailableProduct = flatItem.type === "main" ? !((product == null ? void 0 : product.booking_id) && ((_b = product == null ? void 0 : product.discount_list) == null ? void 0 : _b.length) && ((_c = product == null ? void 0 : product.discount_list) == null ? void 0 : _c.every((d) => d.id && ["good_pass", "discount_card", "product_discount_card"].includes(d.tag || d.type)))) : !((flatItem == null ? void 0 : flatItem.booking_id) && !!((_e = (_d = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _d.discount_list) == null ? void 0 : _e.length) && ((_g = (_f = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _f.discount_list) == null ? void 0 : _g.every((d) => d.id)));
564
+ const isAvailableProduct = flatItem.type === "main" ? !((product == null ? void 0 : product.booking_id) && ((_b = product == null ? void 0 : product.discount_list) == null ? void 0 : _b.length) && ((_c = product == null ? void 0 : product.discount_list) == null ? void 0 : _c.every((d) => d.id && ["entitlement_pass", "good_pass", "discount_card", "product_discount_card"].includes(d.tag || d.type)))) : !((flatItem == null ? void 0 : flatItem.booking_id) && !!((_e = (_d = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _d.discount_list) == null ? void 0 : _e.length) && ((_g = (_f = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _f.discount_list) == null ? void 0 : _g.every((d) => d.id)));
457
565
  if (!isAvailableProduct) {
458
566
  return false;
459
567
  }
@@ -464,7 +572,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
464
572
  return false;
465
573
  }
466
574
  const limitedData = discount.limited_relation_product_data;
467
- const timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], ((product == null ? void 0 : product.startDate) || (0, import_dayjs.default)()).format("YYYY-MM-DD HH:mm:ss")).length;
575
+ const timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], (0, import_dayjs.default)((product == null ? void 0 : product.startDate) || void 0).format("YYYY-MM-DD HH:mm:ss")).length;
468
576
  if (!timeLimit) {
469
577
  return false;
470
578
  }
@@ -566,7 +674,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
566
674
  originProduct = flatItem.originProduct;
567
675
  } else {
568
676
  product = {
569
- startDate: (_a = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _a.startDate,
570
677
  _id: flatItem._id,
571
678
  id: flatItem.id,
572
679
  price: flatItem.price,
@@ -575,13 +682,16 @@ var RulesModule = class extends import_BaseModule.BaseModule {
575
682
  total: flatItem.total,
576
683
  origin_total: flatItem.origin_total,
577
684
  booking_id: flatItem.booking_id,
578
- discount_list: flatItem.discount_list || []
685
+ discount_list: flatItem.discount_list || [],
686
+ startDate: (_a = flatItem.parentProduct) == null ? void 0 : _a.startDate
579
687
  };
580
688
  originProduct = flatItem.originProduct;
581
689
  }
582
690
  addModeDiscount.forEach((discount) => {
583
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
691
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
584
692
  const limitedData = discount == null ? void 0 : discount.limited_relation_product_data;
693
+ if (!limitedData || (0, import_entitlementPass.isEntitlementPass)(discount) && ((_a2 = discount.config) == null ? void 0 : _a2.isAvailable) === false)
694
+ return;
585
695
  const _tempVar = (flatItem == null ? void 0 : flatItem.type) === "bundle" ? flatItem == null ? void 0 : flatItem.parentProduct : flatItem == null ? void 0 : flatItem.product;
586
696
  const isHolderMatch = this.checkHolderMatch(
587
697
  discount,
@@ -589,39 +699,49 @@ var RulesModule = class extends import_BaseModule.BaseModule {
589
699
  isNeedHolder: isFormSubject && !(_tempVar == null ? void 0 : _tempVar.isNormalProduct),
590
700
  holder_id: (_tempVar == null ? void 0 : _tempVar.holder_id) || product.holder_id
591
701
  },
702
+ flatItem.originProduct,
592
703
  holders
593
704
  );
594
705
  let timeLimit = true;
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;
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;
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(
706
+ const useTime = (0, import_dayjs.default)((product == null ? void 0 : product.startDate) || void 0).format("YYYY-MM-DD HH:mm:ss");
707
+ timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], useTime).length;
708
+ if ((0, import_entitlementPass.isEntitlementPass)(discount)) {
709
+ const reason = (0, import_utils3.getDiscountTimeUnavailableReason)(discount, useTime);
710
+ const reasons = entitlementTimeReasons.get(discount.id) || [];
711
+ reasons.push(reason);
712
+ entitlementTimeReasons.set(discount.id, reasons);
713
+ if (!isHolderMatch)
714
+ entitlementHolderMismatch.add(discount.id);
715
+ }
716
+ const isLimitedProduct = (limitedData.type === "product_all" && !(limitedData.filter === 1 && ((_b = limitedData.exclude_product_ids) == null ? void 0 : _b.includes(product.id))) || limitedData.product_ids && limitedData.product_ids.includes(product.id)) && isHolderMatch;
717
+ const isAvailableProduct = flatItem.type === "main" ? !((product == null ? void 0 : product.booking_id) && ((_c = product == null ? void 0 : product.discount_list) == null ? void 0 : _c.length) && ((_d = product == null ? void 0 : product.discount_list) == null ? void 0 : _d.every(
598
718
  (discount2) => discount2.id && [
719
+ "entitlement_pass",
599
720
  "good_pass",
600
721
  "discount_card",
601
722
  "product_discount_card"
602
723
  ].includes(discount2.tag || discount2.type)
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)));
724
+ ))) : !((flatItem == null ? void 0 : flatItem.booking_id) && !!((_f = (_e = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _e.discount_list) == null ? void 0 : _f.length) && ((_h = (_g = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _g.discount_list) == null ? void 0 : _h.every((discount2) => discount2.id)));
604
725
  const isBundleAvailable = this.checkPackageSubItemUsageRules(discount, flatItem);
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);
726
+ if (isAvailableProduct && !(0, import_entitlementState.isPersistedEntitlementLine)(originProduct, flatItem.type === "main" ? flatItem.product : flatItem.parentProduct) && isLimitedProduct && isBundleAvailable && timeLimit) {
727
+ (_i = discountApplicability.get(discount.id)) == null ? void 0 : _i.push(product.id);
607
728
  const applicableProducts = discountApplicableProducts.get(discount.id) || [];
608
729
  const discountType = discount.tag || discount.type;
609
- const isGoodPass = discountType === "good_pass";
730
+ const isGoodPass = (0, import_entitlementPass.isFullCoveragePass)(discount);
610
731
  const num = isGoodPass || (flatItem == null ? void 0 : flatItem.type) === "main" ? 1 : product.num;
611
732
  const productData = {
612
733
  amount: product.price * num,
613
734
  type: discountType,
614
735
  tag: discountType,
615
736
  discount: {
616
- discount_card_type: (_i = discount == null ? void 0 : discount.metadata) == null ? void 0 : _i.discount_card_type,
737
+ discount_card_type: (_j = discount == null ? void 0 : discount.metadata) == null ? void 0 : _j.discount_card_type,
617
738
  fixed_amount: product.price,
618
- discount_calculation_mode: (_j = discount == null ? void 0 : discount.metadata) == null ? void 0 : _j.discount_calculation_mode,
739
+ discount_calculation_mode: (_k = discount == null ? void 0 : discount.metadata) == null ? void 0 : _k.discount_calculation_mode,
619
740
  resource_id: discount.id,
620
741
  title: discount.format_title,
621
742
  original_amount: product.price || product.origin_total,
622
743
  pre_value: discount.par_value,
623
- product_id: originProduct.id,
624
- discount_product_id: discount.product_id
744
+ product_id: product.id
625
745
  },
626
746
  metadata: {
627
747
  num,
@@ -634,129 +754,56 @@ var RulesModule = class extends import_BaseModule.BaseModule {
634
754
  });
635
755
  });
636
756
  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
- };
681
757
  sortedFlattenedList.forEach((flatItem, index) => {
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;
758
+ 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;
683
759
  let product, originProduct;
684
760
  if (flatItem.type === "main") {
685
761
  product = flatItem.product;
686
762
  originProduct = flatItem.originProduct;
687
763
  } else {
688
764
  product = {
689
- startDate: (_a = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _a.startDate,
690
765
  _id: flatItem._id,
691
766
  id: flatItem.id,
692
767
  price: flatItem.price,
693
768
  quantity: flatItem.quantity,
694
769
  num: flatItem.num,
695
770
  total: flatItem.total,
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,
771
+ original_price: (_a = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _a.original_price,
772
+ origin_total: (_b = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _b.original_price,
698
773
  booking_id: flatItem.booking_id,
699
- discount_list: ((_d = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _d.discount_list) || []
774
+ discount_list: ((_c = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _c.discount_list) || [],
775
+ startDate: (_d = flatItem.parentProduct) == null ? void 0 : _d.startDate
700
776
  };
701
777
  originProduct = flatItem.originProduct;
702
778
  }
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
- ))) {
779
+ if ((0, import_entitlementState.isPersistedEntitlementLine)(originProduct, flatItem.type === "main" ? flatItem.product : flatItem.parentProduct) || (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 && ["entitlement_pass", "good_pass", "discount_card", "product_discount_card"].includes(discount.tag || discount.type)))) {
708
780
  if (flatItem.type === "main") {
709
781
  processedProductsMap.set(product._id, [originProduct]);
710
782
  } else {
711
- processedFlatItemsMap.set(flatItem._id, [
712
- {
713
- ...flatItem,
714
- processed: true
715
- }
716
- ]);
783
+ processedFlatItemsMap.set(flatItem._id, [{
784
+ ...flatItem,
785
+ processed: true
786
+ }]);
717
787
  }
718
788
  return;
719
789
  }
720
790
  const applicableDiscounts = sortedDiscountList.filter((discount) => {
721
791
  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")
792
+ if ((0, import_entitlementPass.isEntitlementPass)(discount) && (((_a2 = discount.config) == null ? void 0 : _a2.isAvailable) === false || (0, import_entitlementPass.getRemainingEntitlementUses)(discount, entitlementUsageCounts.get(discount.id) || 0, 1) <= 0 || Number((_b2 = discount.config) == null ? void 0 : _b2.maxUsagePerOrder) > 0 && (usedProductIdCounts.get(discount.product_id) || 0) >= Number((_c2 = discount.config) == null ? void 0 : _c2.maxUsagePerOrder)))
731
793
  return false;
732
- if ((Number(product.total) <= 0 || !product.total) && !((_c2 = product.discount_list) == null ? void 0 : _c2.find((n) => {
794
+ if ((Number(product.price) <= 0 || !product.price) && !((_d2 = product.discount_list) == null ? void 0 : _d2.length) && (0, import_entitlementPass.isFullCoveragePass)(discount))
795
+ return false;
796
+ if ((Number(product.price) <= 0 || !product.price) && !((_e2 = product.discount_list) == null ? void 0 : _e2.find((n) => {
733
797
  var _a3;
734
798
  return ((_a3 = n.discount) == null ? void 0 : _a3.resource_id) === discount.id;
735
- })) && (discount.tag || discount.type) !== "good_pass")
799
+ })) && !(0, import_entitlementPass.isFullCoveragePass)(discount))
736
800
  return false;
737
801
  const targetUsedDiscounts = usedDiscounts.get(discount.id);
738
802
  if (targetUsedDiscounts && (discount.tag || discount.type) === "good_pass")
739
803
  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
- }
759
804
  const limitedData = discount.limited_relation_product_data;
805
+ if (!limitedData)
806
+ return false;
760
807
  const _tempVar = (flatItem == null ? void 0 : flatItem.type) === "bundle" ? flatItem == null ? void 0 : flatItem.parentProduct : flatItem == null ? void 0 : flatItem.product;
761
808
  const isHolderMatch = this.checkHolderMatch(
762
809
  discount,
@@ -764,17 +811,18 @@ var RulesModule = class extends import_BaseModule.BaseModule {
764
811
  isNeedHolder: isFormSubject && !(_tempVar == null ? void 0 : _tempVar.isNormalProduct),
765
812
  holder_id: (_tempVar == null ? void 0 : _tempVar.holder_id) || product.holder_id
766
813
  },
814
+ flatItem.originProduct,
767
815
  holders
768
816
  );
769
817
  if (!isHolderMatch)
770
818
  return false;
771
819
  let timeLimit = true;
772
- timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], (product.startDate || (0, import_dayjs.default)()).format("YYYY-MM-DD HH:mm:ss")).length;
820
+ timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], (0, import_dayjs.default)(product.startDate || void 0).format("YYYY-MM-DD HH:mm:ss")).length;
773
821
  if (!timeLimit) {
774
822
  return false;
775
823
  }
776
824
  if (limitedData.type === "product_all") {
777
- if (limitedData.filter === 1 && limitedData.exclude_product_ids.includes(product.id)) {
825
+ if (!isProductIncludedByLimitedData(limitedData, product.id)) {
778
826
  return false;
779
827
  }
780
828
  if (!this.checkPackageSubItemUsageRules(discount, flatItem)) {
@@ -789,36 +837,22 @@ var RulesModule = class extends import_BaseModule.BaseModule {
789
837
  }
790
838
  return false;
791
839
  });
792
- const selectedDiscountCard = applicableDiscounts.find(
793
- (n) => n.isScan && n.isSelected && (n.tag || n.type) !== "good_pass"
794
- );
795
- const selectedDiscount = selectedDiscountCard || applicableDiscounts[0];
840
+ const selectedDiscountCard = applicableDiscounts.find((n) => n.isScan && n.isSelected && !(0, import_entitlementPass.isFullCoveragePass)(n));
841
+ const explicitlySelected = (options == null ? void 0 : options.isSelected) === true ? applicableDiscounts.find((item) => (0, import_entitlementPass.isEntitlementPass)(item) && String(item.id) === String(options.discountId)) : void 0;
842
+ const selectedDiscount = explicitlySelected || selectedDiscountCard || applicableDiscounts[0];
796
843
  let isManualDiscount = false;
797
844
  if (flatItem.type === "main") {
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
- }
845
+ isManualDiscount = typeof product.isManualDiscount === "boolean" ? product.isManualDiscount : product.total != product.origin_total && (product.bundle || []).every((item) => {
846
+ var _a2;
847
+ return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
848
+ }) && (!((_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")));
810
849
  } else {
811
850
  const parentProduct = flatItem.parentProduct;
812
851
  if (parentProduct) {
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
- )));
852
+ isManualDiscount = typeof parentProduct.isManualDiscount === "boolean" ? parentProduct.isManualDiscount : parentProduct.total != parentProduct.origin_total && (parentProduct.bundle || []).every((item) => {
853
+ var _a2;
854
+ return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
855
+ }) && (!((_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")));
822
856
  }
823
857
  }
824
858
  if (options == null ? void 0 : options.discountId) {
@@ -870,17 +904,17 @@ var RulesModule = class extends import_BaseModule.BaseModule {
870
904
  }
871
905
  if (applicableDiscounts.length === 0 || isManualDiscount || (0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
872
906
  if (flatItem.type === "main") {
873
- const restoredOptions = restoreOptionPrices(product.options);
874
907
  if (product.isClient) {
875
- processedProductsMap.set(product._id, [
876
- this.hooks.setProduct(originProduct, {
908
+ processedProductsMap.set(
909
+ product._id,
910
+ [this.hooks.setProduct(originProduct, {
877
911
  ...isManualDiscount ? {} : {
878
912
  origin_total: (0, import_utils2.getProductOriginTotalPrice)({
879
913
  product: {
880
914
  original_price: product.original_price
881
915
  },
882
916
  bundle: product.bundle,
883
- options: restoredOptions
917
+ options: product.options
884
918
  }),
885
919
  variant: originProduct._productInit.variant,
886
920
  original_price: originProduct._productInit.original_price,
@@ -889,14 +923,14 @@ var RulesModule = class extends import_BaseModule.BaseModule {
889
923
  price: product.price
890
924
  },
891
925
  bundle: product.bundle,
892
- options: restoredOptions
926
+ options: product.options
893
927
  }),
894
928
  price: product.price,
895
- options: restoredOptions
929
+ options: product.options
896
930
  },
897
931
  discount_list: this.filterDiscountListByType(product.discount_list, "promotion")
898
- })
899
- ]);
932
+ })]
933
+ );
900
934
  } else {
901
935
  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;
902
936
  let main_product_selling_price = product.price ?? product.main_product_selling_price;
@@ -906,20 +940,19 @@ var RulesModule = class extends import_BaseModule.BaseModule {
906
940
  }
907
941
  processedProductsMap.set(
908
942
  product._id,
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
- ]
943
+ [this.hooks.setProduct(originProduct, {
944
+ ...isManualDiscount ? {
945
+ price: product.price
946
+ } : {
947
+ _id: product._id.split("___")[0] + "___" + index,
948
+ origin_total: product.origin_total,
949
+ total,
950
+ original_price: product.original_price,
951
+ price: product.price,
952
+ main_product_selling_price
953
+ },
954
+ discount_list: this.filterDiscountListByType(product.discount_list, "promotion")
955
+ })]
923
956
  );
924
957
  }
925
958
  } else {
@@ -935,166 +968,105 @@ var RulesModule = class extends import_BaseModule.BaseModule {
935
968
  if (applicableDiscounts.length && product.booking_id && typeof selectedDiscount.isManualSelect === "undefined" && !(options == null ? void 0 : options.scan) && !isEditModeAddNewProduct) {
936
969
  return;
937
970
  }
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;
971
+ const isNeedSplit = (0, import_entitlementPass.isFullCoveragePass)(selectedDiscount);
943
972
  const totalQuantity = product.quantity || product.num || 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;
973
+ const prioritizedDiscounts = [selectedDiscount, ...applicableDiscounts.filter((item) => item !== selectedDiscount)];
974
+ const allocatedPasses = isNeedSplit ? applicableDiscounts.some(import_entitlementPass.isEntitlementPass) ? getFullCoveragePasses(prioritizedDiscounts, totalQuantity) : applicableDiscounts.slice(0, Math.min(totalQuantity, applicableDiscounts.filter((item) => (item.tag || item.type) === "good_pass").length)) : [selectedDiscount];
975
+ const splitCount = allocatedPasses.length;
963
976
  const arr = [];
964
977
  if (flatItem.type === "main") {
965
978
  if (splitCount < totalQuantity && isNeedSplit) {
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
- );
979
+ arr.push(this.hooks.setProduct(originProduct, {
980
+ discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
981
+ quantity: totalQuantity - splitCount,
982
+ _id: product._id.split("___")[0]
983
+ }));
978
984
  }
979
985
  for (let i = 0; i < splitCount; i++) {
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) || [];
986
+ const selectedDiscount2 = allocatedPasses[i];
987
+ markDiscountUsed(selectedDiscount2);
988
+ const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
992
989
  let productOriginTotal = product.origin_total || product.total || 0;
993
990
  if (this.filterDiscountListByType(product.discount_list, "promotion").length && product.origin_total) {
994
991
  productOriginTotal = product.origin_total;
995
992
  }
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) {
993
+ 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) {
997
994
  productOriginTotal = product.total;
998
995
  }
999
- const isOrderLevel = (0, import_utils.isOrderLevelFixedAmountDiscount)(selectedDiscount);
1000
- const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
996
+ const isOrderLevel = (0, import_utils.isOrderLevelFixedAmountDiscount)(selectedDiscount2);
997
+ const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount2.id) : null;
1001
998
  const productAllocation = orderLevelAllocation == null ? void 0 : orderLevelAllocation.get(flatItem._id);
1002
- const isDeductOptionPrice = !!((_y = selectedDiscount.config) == null ? void 0 : _y.deductOptionPrice);
1003
- let mainProductSellingPrice;
999
+ let targetProductTotal;
1004
1000
  let amount;
1005
1001
  let productDiscountDifference;
1006
- let discountedOptions = product.options;
1007
- let optionDiscountAmount = 0;
1008
1002
  if (isOrderLevel && productAllocation) {
1009
1003
  amount = productAllocation.discountAmount;
1010
1004
  productDiscountDifference = productAllocation.difference;
1011
- mainProductSellingPrice = Math.max(new import_decimal.default(product.price).minus(amount).toNumber(), 0);
1005
+ targetProductTotal = Math.max(new import_decimal.default(product.price).minus(amount).toNumber(), 0);
1012
1006
  } else {
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();
1007
+ targetProductTotal = (0, import_utils.getDiscountAmount)(selectedDiscount2, product.price, product.price);
1008
+ amount = new import_decimal.default(product.price).minus(new import_decimal.default(targetProductTotal)).toNumber();
1019
1009
  }
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";
1010
+ const discountType = selectedDiscount2.tag || selectedDiscount2.type;
1011
+ const isGoodPass = (0, import_entitlementPass.isFullCoveragePass)(selectedDiscount2);
1036
1012
  const discountDetail = {
1037
- amount: lineDiscountAmount,
1038
- type: selectedDiscount.tag === "product_discount_card" ? "discount_card" : discountType2,
1013
+ amount,
1014
+ type: selectedDiscount2.tag === "product_discount_card" ? "discount_card" : discountType,
1039
1015
  discount: {
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,
1016
+ discount_card_type: (_x = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _x.discount_card_type,
1017
+ fixed_amount: amount,
1018
+ discount_calculation_mode: (_y = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _y.discount_calculation_mode,
1019
+ resource_id: selectedDiscount2.id,
1020
+ title: selectedDiscount2.format_title,
1045
1021
  original_amount: product.price,
1046
- product_id: originProduct.id,
1047
- percent: currentSelectedDiscount.par_value,
1048
- discount_product_id: currentSelectedDiscount.product_id
1022
+ product_id: product.id,
1023
+ percent: selectedDiscount2.par_value
1049
1024
  },
1050
- // 前端使用的num数量,为了计算优惠金额(拆分时为1)
1051
- _num: isNeedSplit ? 1 : product.num,
1052
- config: currentSelectedDiscount == null ? void 0 : currentSelectedDiscount.config,
1025
+ // 前端使用的num数量,为了计算优惠金额
1026
+ _num: isGoodPass ? 1 : product.num,
1053
1027
  metadata: {
1054
1028
  num: 1,
1055
- discount_rule_uncheck_flag: selectedDiscount == null ? void 0 : selectedDiscount.discount_rule_uncheck_flag,
1029
+ discount_rule_uncheck_flag: selectedDiscount2 == null ? void 0 : selectedDiscount2.discount_rule_uncheck_flag,
1056
1030
  // 🔥 order_level 分摊差值
1057
- ...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference },
1058
- /** 仅主商品上的优惠金额(不含 option) */
1059
- mainProductDiscountAmount,
1060
- optionDiscountAmount
1031
+ ...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference }
1061
1032
  }
1062
1033
  };
1063
1034
  appliedProducts.push(discountDetail);
1064
- appliedDiscountProducts.set(currentSelectedDiscount.id, appliedProducts);
1035
+ appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
1036
+ let total = targetProductTotal;
1037
+ if (product.options) {
1038
+ total = product.options.reduce((accumulator, currentValue) => {
1039
+ const currentPrice = new import_decimal.default(currentValue.price || 0);
1040
+ const currentNum = new import_decimal.default(currentValue.num || 0);
1041
+ return accumulator.add(currentPrice.mul(currentNum));
1042
+ }, new import_decimal.default(total)).toNumber();
1043
+ }
1065
1044
  if (product.isClient) {
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
- );
1045
+ arr.push(this.hooks.setProduct(originProduct, {
1046
+ discount_list: [discountDetail],
1047
+ price: isGoodPass ? 0 : product.price,
1048
+ quantity: isNeedSplit ? 1 : product.quantity,
1049
+ origin_total: (0, import_utils2.getProductOriginTotalPrice)({
1050
+ product: {
1051
+ original_price: product.original_price
1052
+ },
1053
+ bundle: product.bundle,
1054
+ options: product.options
1055
+ }),
1056
+ variant: originProduct._productInit.variant,
1057
+ original_price: new import_decimal.default(product.price || 0).toNumber(),
1058
+ total
1059
+ }));
1085
1060
  } else {
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
- );
1061
+ arr.push(this.hooks.setProduct(originProduct, {
1062
+ discount_list: this.filterDiscountListByType(product.discount_list, "promotion").concat([discountDetail]),
1063
+ _id: product._id.split("___")[0] + "___" + selectedDiscount2.id + index + ((0, import_entitlementPass.isEntitlementPass)(selectedDiscount2) ? `_${i}` : ""),
1064
+ price: isGoodPass ? 0 : product.price,
1065
+ quantity: isNeedSplit ? 1 : product.quantity,
1066
+ total,
1067
+ origin_total: productOriginTotal,
1068
+ main_product_selling_price: targetProductTotal
1069
+ }));
1098
1070
  }
1099
1071
  }
1100
1072
  processedProductsMap.set(product._id, arr);
@@ -1104,295 +1076,58 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1104
1076
  const discountNum = splitCount;
1105
1077
  const normalNum = totalQuantity - discountNum;
1106
1078
  for (let i = 0; i < discountNum; i++) {
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
- }
1079
+ const selectedDiscount2 = allocatedPasses[i];
1080
+ markDiscountUsed(selectedDiscount2);
1118
1081
  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;
1126
1082
  const discountDetail = {
1127
- amount: bundleDiscountAmount,
1128
- type: bundleDiscountType,
1083
+ amount: product.origin_total || product.price || 0,
1084
+ type: selectedDiscount2.tag || selectedDiscount2.type,
1129
1085
  discount: {
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,
1086
+ fixed_amount: product.origin_total || product.price || 0,
1087
+ discount_calculation_mode: (_z = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _z.discount_calculation_mode,
1088
+ resource_id: selectedDiscount2.id,
1089
+ title: selectedDiscount2.format_title,
1135
1090
  original_amount: product.origin_total,
1136
- product_id: product.id,
1137
- percent: currentBundleDiscount.par_value,
1138
- discount_product_id: currentBundleDiscount.product_id
1091
+ product_id: product.id
1139
1092
  },
1140
1093
  metadata: {
1141
1094
  // 🔥 使用拆分后的唯一 _id
1142
1095
  custom_product_bundle_map_id: uniqueId,
1143
- discount_rule_uncheck_flag: selectedDiscount == null ? void 0 : selectedDiscount.discount_rule_uncheck_flag,
1096
+ discount_rule_uncheck_flag: selectedDiscount2 == null ? void 0 : selectedDiscount2.discount_rule_uncheck_flag,
1144
1097
  num: 1
1145
1098
  },
1146
- _num: 1,
1147
- config: currentBundleDiscount == null ? void 0 : currentBundleDiscount.config
1099
+ _num: 1
1148
1100
  };
1149
- const appliedProducts = appliedDiscountProducts.get(currentBundleDiscount.id) || [];
1101
+ const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
1150
1102
  appliedProducts.push(discountDetail);
1151
- appliedDiscountProducts.set(currentBundleDiscount.id, appliedProducts);
1103
+ appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
1152
1104
  processedItems.push({
1153
1105
  ...flatItem,
1154
1106
  // 🔥 使用唯一的 _id
1155
1107
  _id: uniqueId,
1156
1108
  num: 1,
1157
1109
  quantity: 1,
1158
- price: discountedPrice,
1159
- // 折扣后的价格
1160
- total: discountedPrice,
1110
+ price: 0,
1111
+ // 商品券价格为0
1112
+ total: 0,
1161
1113
  discount_list: this.filterDiscountListByType(flatItem.discount_list, "promotion").concat([discountDetail]),
1162
1114
  processed: true,
1163
- _discountId: currentBundleDiscount.id
1115
+ _discountId: selectedDiscount2.id
1164
1116
  });
1165
1117
  }
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;
1118
+ if (normalNum > 0) {
1119
+ processedItems.push({
1120
+ ...flatItem,
1121
+ // 🔥 为剩余商品生成唯一的 _id
1122
+ _id: `${flatItem._id}_split_rest`,
1123
+ num: normalNum,
1124
+ quantity: normalNum,
1125
+ discount_list: this.filterDiscountListByType(flatItem.discount_list, "promotion"),
1126
+ processed: true
1220
1127
  });
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;
1382
1128
  }
1383
1129
  } else {
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
- }
1130
+ usedDiscounts.set(selectedDiscount.id, true);
1396
1131
  const productOriginTotal = product.original_price || product.price || 0;
1397
1132
  const isOrderLevel = (0, import_utils.isOrderLevelFixedAmountDiscount)(selectedDiscount);
1398
1133
  const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
@@ -1406,27 +1141,25 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1406
1141
  targetProductTotal = Math.max(new import_decimal.default(productOriginTotal).minus(fixedAmountPerItem).toNumber(), 0);
1407
1142
  } else {
1408
1143
  targetProductTotal = (0, import_utils.getDiscountAmount)(
1409
- currentBundleDiscount,
1144
+ selectedDiscount,
1410
1145
  productOriginTotal,
1411
1146
  productOriginTotal
1412
1147
  );
1413
1148
  fixedAmountPerItem = new import_decimal.default(productOriginTotal).minus(targetProductTotal).toNumber();
1414
1149
  }
1415
- const bundleActualDiscountAmount = new import_decimal.default(productOriginTotal).minus(targetProductTotal).toNumber();
1416
1150
  const uniqueId = flatItem._id;
1417
1151
  const discountDetail = {
1418
- amount: bundleActualDiscountAmount * (product.num || 1),
1419
- type: currentBundleDiscount.tag === "product_discount_card" ? "discount_card" : currentBundleDiscount.tag,
1152
+ amount: fixedAmountPerItem * (product.num || 1),
1153
+ type: selectedDiscount.tag === "product_discount_card" ? "discount_card" : selectedDiscount.tag,
1420
1154
  discount: {
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,
1155
+ discount_card_type: (_A = selectedDiscount == null ? void 0 : selectedDiscount.metadata) == null ? void 0 : _A.discount_card_type,
1156
+ fixed_amount: fixedAmountPerItem,
1157
+ discount_calculation_mode: (_B = selectedDiscount == null ? void 0 : selectedDiscount.metadata) == null ? void 0 : _B.discount_calculation_mode,
1158
+ resource_id: selectedDiscount.id,
1159
+ title: selectedDiscount.format_title,
1426
1160
  original_amount: product.original_price,
1427
1161
  product_id: product.id,
1428
- percent: currentBundleDiscount.par_value,
1429
- discount_product_id: currentBundleDiscount.product_id
1162
+ percent: selectedDiscount.par_value
1430
1163
  },
1431
1164
  metadata: {
1432
1165
  // 🔥 使用唯一的 _id
@@ -1436,12 +1169,11 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1436
1169
  // 🔥 order_level 分摊差值
1437
1170
  ...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference }
1438
1171
  },
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)
1172
+ _num: (product.num || 1) * (((_C = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _C.num) || 1)
1441
1173
  };
1442
- const appliedProducts = appliedDiscountProducts.get(currentBundleDiscount.id) || [];
1174
+ const appliedProducts = appliedDiscountProducts.get(selectedDiscount.id) || [];
1443
1175
  appliedProducts.push(discountDetail);
1444
- appliedDiscountProducts.set(currentBundleDiscount.id, appliedProducts);
1176
+ appliedDiscountProducts.set(selectedDiscount.id, appliedProducts);
1445
1177
  processedItems.push({
1446
1178
  ...flatItem,
1447
1179
  total: targetProductTotal,
@@ -1457,10 +1189,33 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1457
1189
  const result = [];
1458
1190
  originalProductList.forEach((originProduct) => {
1459
1191
  const product = this.hooks.getProduct(originProduct);
1192
+ if ((0, import_entitlementState.isPersistedEntitlementLine)(originProduct, product)) {
1193
+ result.push(originProduct);
1194
+ return;
1195
+ }
1460
1196
  const mainProductArr = processedProductsMap2.get(product._id);
1197
+ if ((0, import_entitlementLines.isEntitlementRuntimeLine)(originProduct, product) && !product.isManualDiscount && (mainProductArr == null ? void 0 : mainProductArr.length)) {
1198
+ const bundle = (product.bundle || []).flatMap((item, index) => {
1199
+ const processed = processedFlatItemsMap2.get(`${product._id}_bundle_${index}`);
1200
+ if (!(processed == null ? void 0 : processed.length))
1201
+ return [item];
1202
+ return processed.map((child) => ({
1203
+ ...item,
1204
+ _id: child._id,
1205
+ price: child.price,
1206
+ bundle_selling_price: child.price,
1207
+ num: child.num,
1208
+ discount_list: (child.discount_list || []).map((detail) => ({
1209
+ ...detail,
1210
+ metadata: { ...detail.metadata, num: child.num, custom_product_bundle_map_id: child._id }
1211
+ }))
1212
+ }));
1213
+ });
1214
+ result.push(...mainProductArr.map((item) => (0, import_entitlementLines.rebuildEntitlementLine)(item, bundle, this.hooks)));
1215
+ return;
1216
+ }
1461
1217
  if (!mainProductArr || mainProductArr.length === 0) {
1462
1218
  const getDefaultProduct = () => {
1463
- const restoredOptions = restoreOptionPrices(product.options);
1464
1219
  if (product.isClient) {
1465
1220
  return this.hooks.setProduct(originProduct, {
1466
1221
  discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
@@ -1470,7 +1225,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1470
1225
  original_price: product.original_price
1471
1226
  },
1472
1227
  bundle: product.bundle,
1473
- options: restoredOptions
1228
+ options: product.options
1474
1229
  }),
1475
1230
  variant: originProduct._productInit.variant,
1476
1231
  original_price: originProduct._productInit.original_price,
@@ -1479,17 +1234,15 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1479
1234
  price: product.price
1480
1235
  },
1481
1236
  bundle: product.bundle,
1482
- options: restoredOptions
1483
- }),
1484
- options: restoredOptions
1237
+ options: product.options
1238
+ })
1485
1239
  });
1486
1240
  } else {
1487
1241
  return this.hooks.setProduct(originProduct, {
1488
1242
  discount_list: this.filterDiscountListByType(product.discount_list, "promotion"),
1489
1243
  total: product.total,
1490
1244
  origin_total: product.origin_total,
1491
- price: product.price,
1492
- options: restoreOptionPrices(product.options)
1245
+ price: product.price
1493
1246
  });
1494
1247
  }
1495
1248
  };
@@ -1514,7 +1267,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1514
1267
  (item) => {
1515
1268
  var _a;
1516
1269
  return (_a = item.discount_list) == null ? void 0 : _a.some(
1517
- (discount) => discount.type === "good_pass" || discount.tag === "good_pass"
1270
+ (discount) => (0, import_entitlementPass.isFullCoveragePass)(discount)
1518
1271
  );
1519
1272
  }
1520
1273
  );
@@ -1529,92 +1282,80 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1529
1282
  const mainProduct = mainProductArr[0];
1530
1283
  const mainProductData = this.hooks.getProduct(mainProduct);
1531
1284
  const newBundleWithDiscount = [];
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
- });
1285
+ (product.bundle || []).forEach((bundleItem, bundleIndex) => {
1286
+ const processedItems = bundleProcessingInfo.get(bundleIndex) || [bundleItem];
1287
+ if (processedItems.length > 1) {
1288
+ processedItems.forEach((item) => {
1289
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1290
+ var _a;
1291
+ return {
1292
+ ...discount,
1293
+ metadata: {
1294
+ ...discount.metadata,
1295
+ num: item.num,
1296
+ custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
1297
+ }
1298
+ // num: item.num, // 使用拆分后的 num
1299
+ };
1300
+ });
1301
+ newBundleWithDiscount.push({
1302
+ ...bundleItem,
1303
+ _id: item._id,
1304
+ product_id: bundleItem.product_id,
1305
+ price: item.price,
1306
+ num: item.num,
1307
+ discount_list: updatedDiscountList2
1308
+ });
1309
+ });
1310
+ } else {
1311
+ const item = processedItems[0];
1312
+ if (item.processed) {
1313
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1314
+ var _a;
1315
+ return {
1316
+ ...discount,
1317
+ metadata: {
1318
+ ...discount.metadata,
1319
+ num: item.num,
1320
+ custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
1321
+ }
1322
+ // num: item.num, // 使用当前的 num
1323
+ };
1324
+ });
1325
+ newBundleWithDiscount.push({
1326
+ ...bundleItem,
1327
+ _id: item._id,
1328
+ product_id: bundleItem.product_id,
1329
+ price: item.price,
1330
+ num: item.num,
1331
+ discount_list: updatedDiscountList2
1560
1332
  });
1561
1333
  } else {
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
- }
1334
+ newBundleWithDiscount.push(item);
1588
1335
  }
1589
1336
  }
1590
- );
1337
+ });
1591
1338
  let newTotalWithDiscount = Number(mainProductData.price || 0);
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;
1600
- }
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);
1339
+ let newOriginTotalWithDiscount = Number(mainProductData.original_price || mainProductData.price || 0);
1340
+ const updatedMainDiscountList = mainProductData.discount_list.map((discount) => {
1341
+ var _a, _b;
1342
+ if ((_a = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a.custom_product_bundle_map_id) {
1343
+ return discount;
1616
1344
  }
1617
- );
1345
+ return {
1346
+ ...discount,
1347
+ // num: 1,
1348
+ metadata: {
1349
+ ...discount.metadata,
1350
+ custom_product_bundle_map_id: (_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.custom_product_bundle_map_id,
1351
+ num: 1
1352
+ }
1353
+ };
1354
+ });
1355
+ const mainDiscountList = updatedMainDiscountList.filter((item) => {
1356
+ var _a;
1357
+ return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
1358
+ });
1618
1359
  if (mainDiscountList && mainDiscountList.length > 0) {
1619
1360
  const allDiscountAmount = (0, import_utils.getDiscountListAmountTotal)(mainDiscountList);
1620
1361
  newTotalWithDiscount = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotalWithDiscount;
@@ -1644,24 +1385,20 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1644
1385
  quantity: 1,
1645
1386
  discount_list: updatedMainDiscountList,
1646
1387
  bundle: newBundleWithDiscount,
1647
- total: newTotalWithDiscount,
1648
- origin_total: newOriginTotalWithDiscount
1388
+ total: new import_decimal.default(newTotalWithDiscount).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber(),
1389
+ origin_total: new import_decimal.default(newOriginTotalWithDiscount).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber()
1649
1390
  })
1650
1391
  );
1651
1392
  if (mainProductQuantity > 1) {
1652
1393
  const newBundleOriginal = [];
1653
- (product.bundle || []).forEach(
1654
- (bundleItem, bundleIndex) => {
1655
- newBundleOriginal.push({
1656
- ...bundleItem,
1657
- discount_list: []
1658
- });
1659
- }
1660
- );
1394
+ (product.bundle || []).forEach((bundleItem, bundleIndex) => {
1395
+ newBundleOriginal.push({
1396
+ ...bundleItem,
1397
+ discount_list: []
1398
+ });
1399
+ });
1661
1400
  let newTotalOriginal = Number(mainProductData.price || 0);
1662
- let newOriginTotalOriginal = Number(
1663
- mainProductData.original_price || mainProductData.price || 0
1664
- );
1401
+ let newOriginTotalOriginal = Number(mainProductData.original_price || mainProductData.price || 0);
1665
1402
  const updatedMainDiscountListOriginal = mainProductData.discount_list.map((discount) => {
1666
1403
  var _a, _b;
1667
1404
  if ((_a = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a.custom_product_bundle_map_id) {
@@ -1677,16 +1414,12 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1677
1414
  // num: mainProductQuantity - 1,
1678
1415
  };
1679
1416
  });
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
- );
1417
+ const mainDiscountListOriginal = updatedMainDiscountListOriginal.filter((item) => {
1418
+ var _a;
1419
+ return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
1420
+ });
1686
1421
  if (mainDiscountListOriginal && mainDiscountListOriginal.length > 0) {
1687
- const allDiscountAmount = (0, import_utils.getDiscountListAmount)(
1688
- mainDiscountListOriginal
1689
- );
1422
+ const allDiscountAmount = (0, import_utils.getDiscountListAmount)(mainDiscountListOriginal);
1690
1423
  newTotalOriginal = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotalOriginal;
1691
1424
  newOriginTotalOriginal = mainProductData.origin_total ?? newOriginTotalOriginal;
1692
1425
  }
@@ -1723,59 +1456,48 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1723
1456
  const mainProductData = this.hooks.getProduct(mainProduct);
1724
1457
  const newBundle = [];
1725
1458
  if (product.bundle && Array.isArray(product.bundle)) {
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
- });
1459
+ product.bundle.forEach((bundleItem, bundleIndex) => {
1460
+ const bundleItemId = `${product._id}_bundle_${bundleIndex}`;
1461
+ const processedBundleItems = processedFlatItemsMap2.get(bundleItemId);
1462
+ if (!processedBundleItems || processedBundleItems.length === 0) {
1463
+ newBundle.push(bundleItem);
1464
+ } else {
1465
+ processedBundleItems.forEach((item) => {
1466
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1467
+ var _a2;
1468
+ return {
1469
+ ...discount,
1470
+ metadata: {
1471
+ ...discount.metadata,
1472
+ num: item.num,
1473
+ custom_product_bundle_map_id: (_a2 = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id
1474
+ }
1475
+ // num: item.num, // 使用拆分后的 num
1476
+ };
1756
1477
  });
1757
- }
1478
+ newBundle.push({
1479
+ ...bundleItem,
1480
+ _id: item._id,
1481
+ product_id: bundleItem.product_id,
1482
+ price: item.price,
1483
+ num: item.num,
1484
+ discount_list: updatedDiscountList2
1485
+ });
1486
+ });
1758
1487
  }
1759
- );
1488
+ });
1760
1489
  }
1761
1490
  let newTotal = Number(mainProductData.price || 0);
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
- )));
1491
+ let newOriginTotal = Number(mainProductData.original_price || mainProductData.price || 0);
1492
+ 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")));
1769
1493
  if (isManualDiscount) {
1770
1494
  newTotal = mainProductData.total ?? newTotal;
1771
1495
  newOriginTotal = mainProductData.origin_total ?? newOriginTotal;
1772
1496
  } else {
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
- );
1497
+ const mainDiscountList = mainProductData.discount_list.filter((item) => {
1498
+ var _a2;
1499
+ return !((_a2 = item == null ? void 0 : item.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id);
1500
+ });
1779
1501
  if (mainDiscountList && mainDiscountList.length > 0) {
1780
1502
  const allDiscountAmount = (0, import_utils.getDiscountListAmount)(mainDiscountList);
1781
1503
  newTotal = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotal;
@@ -1783,8 +1505,10 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1783
1505
  }
1784
1506
  if (newBundle.length > 0) {
1785
1507
  newBundle.forEach((item) => {
1786
- var _a2, _b2, _c2;
1787
1508
  newTotal += Number(item.price) * Number(item.num);
1509
+ });
1510
+ newBundle.forEach((item) => {
1511
+ var _a2, _b2, _c2;
1788
1512
  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;
1789
1513
  newOriginTotal += Number(originalPrice) * Number(item.num);
1790
1514
  });
@@ -1797,6 +1521,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1797
1521
  return accumulator.add(currentPrice.mul(currentNum));
1798
1522
  }, new import_decimal.default(newTotal)).toNumber();
1799
1523
  }
1524
+ newTotal = new import_decimal.default(newTotal).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
1525
+ newOriginTotal = new import_decimal.default(newOriginTotal).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
1800
1526
  result.push(
1801
1527
  this.hooks.setProduct(mainProduct, {
1802
1528
  ...mainProductData,
@@ -1820,6 +1546,30 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1820
1546
  const applicableProducts = discountApplicability.get(discount.id) || [];
1821
1547
  const applicableProductDetails = discountApplicableProducts.get(discount.id) || [];
1822
1548
  const appliedProductDetails = appliedDiscountProducts.get(discount.id) || [];
1549
+ if ((0, import_entitlementPass.isEntitlementPass)(discount)) {
1550
+ const committed = discount.committedAppliedProductDetails || [];
1551
+ const details = [...committed, ...appliedProductDetails];
1552
+ const isAvailable2 = applicableProducts.length > 0;
1553
+ const timeReasons = entitlementTimeReasons.get(discount.id) || [];
1554
+ const timeReason = timeReasons.length ? timeReasons.every(Boolean) ? timeReasons[0] : void 0 : (0, import_utils3.getDiscountTimeUnavailableReason)(discount, (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss"));
1555
+ const reasonCode = isAvailable2 ? void 0 : discount.reasonCode || timeReason || (entitlementHolderMismatch.has(discount.id) ? "holder_not_matched" : "product_not_applicable");
1556
+ return {
1557
+ ...discount,
1558
+ isAvailable: isAvailable2 || committed.length > 0,
1559
+ isSelected: details.length > 0,
1560
+ isUsed: details.length > 0,
1561
+ reasonCode,
1562
+ reason: reasonCode === discount.reasonCode ? discount.reason : void 0,
1563
+ isManualSelect: (options == null ? void 0 : options.scan) ? false : discount.isManualSelect,
1564
+ applicableProductIds: applicableProducts,
1565
+ applicableProductDetails,
1566
+ appliedProductDetails: details,
1567
+ savedAmount: details.reduce((sum, detail) => {
1568
+ var _a;
1569
+ return new import_decimal.default(sum).plus(new import_decimal.default(((_a = detail.discount) == null ? void 0 : _a.fixed_amount) || 0).mul(detail._num || 1)).toNumber();
1570
+ }, 0)
1571
+ };
1572
+ }
1823
1573
  const isAvailable = applicableProducts.length > 0;
1824
1574
  if (typeof discount.isSelected === "boolean" && discount.isSelected === false && discount.isManualSelect) {
1825
1575
  return {
@@ -1872,7 +1622,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1872
1622
  });
1873
1623
  console.log(processedProductList, "processedProductList");
1874
1624
  return {
1875
- productList: processedProductList,
1625
+ productList: this.entitlementPassEnabled ? (0, import_entitlementLines.finalizeEntitlementLines)(processedProductList, this.hooks) : processedProductList,
1876
1626
  discountList: [...editModeDiscount, ...updatedDiscountList]
1877
1627
  };
1878
1628
  }
@@ -1892,7 +1642,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1892
1642
  }
1893
1643
  const ruleType = usageRules.type;
1894
1644
  const packageScope = usageRules == null ? void 0 : usageRules.package_scope;
1895
- const { type: scopeType, exclude_bundle_product_ids = [], include_bundle_product_ids = [], filter = 0 } = packageScope || {};
1645
+ const { type: scopeType = "product_all", exclude_bundle_product_ids = [], include_bundle_product_ids = [], filter = 0 } = packageScope || {};
1896
1646
  const isMainProduct = flatItem.type === "main";
1897
1647
  const isBundleItem = flatItem.type === "bundle";
1898
1648
  if (isMainProduct) {