@pisell/pisellos 2.1.64 → 2.1.66

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 (104) hide show
  1. package/dist/index.d.ts +0 -1
  2. package/dist/index.js +0 -1
  3. package/dist/modules/Cart/types.d.ts +0 -2
  4. package/dist/modules/Cart/utils/cartProduct.js +21 -15
  5. package/dist/modules/Discount/index.js +2 -2
  6. package/dist/modules/Discount/types.d.ts +9 -15
  7. package/dist/modules/Payment/index.d.ts +1 -2
  8. package/dist/modules/Payment/index.js +7 -10
  9. package/dist/modules/Payment/utils.js +0 -3
  10. package/dist/modules/Payment/walletpass.d.ts +0 -23
  11. package/dist/modules/Payment/walletpass.js +95 -191
  12. package/dist/modules/Product/index.d.ts +1 -1
  13. package/dist/modules/Rules/index.d.ts +3 -8
  14. package/dist/modules/Rules/index.js +408 -240
  15. package/dist/modules/Rules/types.d.ts +0 -1
  16. package/dist/modules/Summary/types.d.ts +0 -2
  17. package/dist/modules/Summary/utils.d.ts +5 -6
  18. package/dist/modules/Summary/utils.js +34 -20
  19. package/dist/plugins/window.d.ts +0 -2
  20. package/dist/solution/BookingByStep/index.d.ts +1 -2
  21. package/dist/solution/BookingByStep/index.js +2 -1
  22. package/dist/solution/Checkout/index.js +0 -2
  23. package/dist/solution/ShopDiscount/index.d.ts +0 -1
  24. package/dist/solution/ShopDiscount/index.js +5 -14
  25. package/dist/solution/ShopDiscount/types.d.ts +0 -1
  26. package/dist/solution/ShopDiscount/utils.d.ts +24 -0
  27. package/dist/solution/ShopDiscount/utils.js +145 -26
  28. package/lib/index.d.ts +0 -1
  29. package/lib/index.js +1 -3
  30. package/lib/modules/Cart/types.d.ts +0 -2
  31. package/lib/modules/Cart/utils/cartProduct.js +22 -15
  32. package/lib/modules/Discount/index.js +2 -2
  33. package/lib/modules/Discount/types.d.ts +9 -15
  34. package/lib/modules/Payment/index.d.ts +1 -2
  35. package/lib/modules/Payment/index.js +0 -1
  36. package/lib/modules/Payment/utils.js +0 -3
  37. package/lib/modules/Payment/walletpass.d.ts +0 -23
  38. package/lib/modules/Payment/walletpass.js +17 -94
  39. package/lib/modules/Product/index.d.ts +1 -1
  40. package/lib/modules/Rules/index.d.ts +3 -8
  41. package/lib/modules/Rules/index.js +441 -399
  42. package/lib/modules/Rules/types.d.ts +0 -1
  43. package/lib/modules/Summary/types.d.ts +0 -2
  44. package/lib/modules/Summary/utils.d.ts +5 -6
  45. package/lib/modules/Summary/utils.js +27 -18
  46. package/lib/plugins/window.d.ts +0 -2
  47. package/lib/solution/BookingByStep/index.d.ts +1 -2
  48. package/lib/solution/BookingByStep/index.js +1 -1
  49. package/lib/solution/BookingTicket/index.js +6 -0
  50. package/lib/solution/Checkout/index.js +0 -2
  51. package/lib/solution/ShopDiscount/index.d.ts +0 -1
  52. package/lib/solution/ShopDiscount/index.js +6 -12
  53. package/lib/solution/ShopDiscount/types.d.ts +0 -1
  54. package/lib/solution/ShopDiscount/utils.d.ts +24 -0
  55. package/lib/solution/ShopDiscount/utils.js +93 -10
  56. package/package.json +1 -1
  57. package/dist/model/index.d.ts +0 -1
  58. package/dist/model/index.js +0 -1
  59. package/dist/model/strategy/adapter/index.d.ts +0 -3
  60. package/dist/model/strategy/adapter/index.js +0 -4
  61. package/dist/model/strategy/adapter/type.d.ts +0 -28
  62. package/dist/model/strategy/adapter/type.js +0 -1
  63. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +0 -84
  64. package/dist/model/strategy/adapter/walletPass/evaluator.js +0 -497
  65. package/dist/model/strategy/adapter/walletPass/example.d.ts +0 -4
  66. package/dist/model/strategy/adapter/walletPass/example.js +0 -258
  67. package/dist/model/strategy/adapter/walletPass/index.d.ts +0 -32
  68. package/dist/model/strategy/adapter/walletPass/index.js +0 -182
  69. package/dist/model/strategy/adapter/walletPass/locales.d.ts +0 -1
  70. package/dist/model/strategy/adapter/walletPass/locales.js +0 -23
  71. package/dist/model/strategy/adapter/walletPass/type.d.ts +0 -163
  72. package/dist/model/strategy/adapter/walletPass/type.js +0 -1
  73. package/dist/model/strategy/adapter/walletPass/utils.d.ts +0 -50
  74. package/dist/model/strategy/adapter/walletPass/utils.js +0 -965
  75. package/dist/model/strategy/index.d.ts +0 -94
  76. package/dist/model/strategy/index.js +0 -551
  77. package/dist/model/strategy/strategy-example.d.ts +0 -5
  78. package/dist/model/strategy/strategy-example.js +0 -331
  79. package/dist/model/strategy/type.d.ts +0 -228
  80. package/dist/model/strategy/type.js +0 -94
  81. package/lib/model/index.d.ts +0 -1
  82. package/lib/model/index.js +0 -23
  83. package/lib/model/strategy/adapter/index.d.ts +0 -3
  84. package/lib/model/strategy/adapter/index.js +0 -45
  85. package/lib/model/strategy/adapter/type.d.ts +0 -28
  86. package/lib/model/strategy/adapter/type.js +0 -17
  87. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +0 -84
  88. package/lib/model/strategy/adapter/walletPass/evaluator.js +0 -421
  89. package/lib/model/strategy/adapter/walletPass/example.d.ts +0 -4
  90. package/lib/model/strategy/adapter/walletPass/example.js +0 -207
  91. package/lib/model/strategy/adapter/walletPass/index.d.ts +0 -32
  92. package/lib/model/strategy/adapter/walletPass/index.js +0 -142
  93. package/lib/model/strategy/adapter/walletPass/locales.d.ts +0 -1
  94. package/lib/model/strategy/adapter/walletPass/locales.js +0 -51
  95. package/lib/model/strategy/adapter/walletPass/type.d.ts +0 -163
  96. package/lib/model/strategy/adapter/walletPass/type.js +0 -17
  97. package/lib/model/strategy/adapter/walletPass/utils.d.ts +0 -50
  98. package/lib/model/strategy/adapter/walletPass/utils.js +0 -660
  99. package/lib/model/strategy/index.d.ts +0 -94
  100. package/lib/model/strategy/index.js +0 -413
  101. package/lib/model/strategy/strategy-example.d.ts +0 -5
  102. package/lib/model/strategy/strategy-example.js +0 -318
  103. package/lib/model/strategy/type.d.ts +0 -228
  104. package/lib/model/strategy/type.js +0 -44
@@ -49,7 +49,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
49
49
  this.core = core;
50
50
  this.hooks = options == null ? void 0 : options.hooks;
51
51
  this.store = options == null ? void 0 : options.store;
52
- this.window = core.getPlugin("window");
53
52
  }
54
53
  async setRulesList(rulesList) {
55
54
  this.store.rulesList = rulesList;
@@ -58,10 +57,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
58
57
  getRulesList() {
59
58
  return this.store.rulesList;
60
59
  }
61
- getWalletPassEvaluator() {
62
- var _a, _b;
63
- return (_b = (_a = this.window).getWalletPassEvaluator) == null ? void 0 : _b.call(_a);
64
- }
65
60
  // 商品不需要holder,则不需要判断,直接返回true,商品需要holder但是还没填写,那么暂时不使用带有holder的券,直到填写才去匹配
66
61
  checkHolderMatch(discount, product, holders) {
67
62
  var _a;
@@ -81,7 +76,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
81
76
  newDiscountList,
82
77
  productList,
83
78
  holders,
84
- orderTotalAmount,
85
79
  isFormSubject
86
80
  }) {
87
81
  if (!newDiscountList || newDiscountList.length === 0) {
@@ -102,18 +96,15 @@ var RulesModule = class extends import_BaseModule.BaseModule {
102
96
  productList
103
97
  };
104
98
  }
105
- const filteredOldDiscountList = oldDiscountList.filter(
106
- (discount) => !discount.isEditMode && discount.tag !== "good_pass"
107
- );
108
- const mergedDiscountList = (0, import_utils.uniqueById)(
109
- (0, import_utils.uniqueById)([...filteredOldDiscountList, ...newDiscountList]),
110
- "product_id"
111
- );
99
+ const filteredOldDiscountList = oldDiscountList.filter((discount) => !discount.isEditMode && discount.tag !== "good_pass");
100
+ const mergedDiscountList = (0, import_utils.uniqueById)((0, import_utils.uniqueById)([
101
+ ...filteredOldDiscountList,
102
+ ...newDiscountList
103
+ ]), "product_id");
112
104
  const result = this.calcDiscount({
113
105
  discountList: mergedDiscountList,
114
106
  productList: [...productList],
115
107
  holders,
116
- orderTotalAmount,
117
108
  isFormSubject
118
109
  }, {
119
110
  scan: true
@@ -148,7 +139,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
148
139
  discountList,
149
140
  productList,
150
141
  holders,
151
- orderTotalAmount,
152
142
  isFormSubject
153
143
  }, options) {
154
144
  const isEditModeAddNewProduct = productList.find((n) => n.booking_id) && productList.find((n) => !n.booking_id);
@@ -161,6 +151,20 @@ var RulesModule = class extends import_BaseModule.BaseModule {
161
151
  addModeDiscount.push(discount);
162
152
  }
163
153
  });
154
+ const editModeOrderLevelProductIds = /* @__PURE__ */ new Set();
155
+ editModeDiscount.forEach((discount) => {
156
+ var _a, _b;
157
+ if (((_a = discount.discount) == null ? void 0 : _a.discount_calculation_mode) === "order_level") {
158
+ editModeOrderLevelProductIds.add((_b = discount == null ? void 0 : discount.discount) == null ? void 0 : _b.discount_product_id);
159
+ }
160
+ });
161
+ if (editModeOrderLevelProductIds.size > 0) {
162
+ addModeDiscount.forEach((discount) => {
163
+ if (editModeOrderLevelProductIds.has(discount.product_id)) {
164
+ discount.isDisabled = true;
165
+ }
166
+ });
167
+ }
164
168
  const filteredDiscountList = addModeDiscount.filter((discount) => {
165
169
  return !discount.isManualSelect;
166
170
  });
@@ -208,45 +212,85 @@ var RulesModule = class extends import_BaseModule.BaseModule {
208
212
  return flattened;
209
213
  };
210
214
  const sortedDiscountList = [...filteredDiscountList].sort((a, b) => {
211
- var _a, _b;
212
- if (a.tag === "good_pass" && b.tag !== "good_pass")
213
- return -1;
214
- if (b.tag === "good_pass" && a.tag !== "good_pass")
215
- return 1;
216
- if (a.tag === "good_pass" && b.tag === "good_pass") {
217
- return compareByExpireTime(a, b);
218
- } else if (a.tag === "product_discount_card" && b.tag === "product_discount_card") {
219
- const typeA = ((_a = a.metadata) == null ? void 0 : _a.discount_card_type) || "percent";
220
- const typeB = ((_b = b.metadata) == null ? void 0 : _b.discount_card_type) || "percent";
215
+ const isHolderDiscount = (discount) => {
216
+ var _a, _b;
217
+ return ((_b = (_a = discount.metadata) == null ? void 0 : _a.holder) == null ? void 0 : _b.type) === "custom";
218
+ };
219
+ const isGoodPass = (discount) => discount.tag === "good_pass";
220
+ const isOrderLevelDiscount = (discount) => {
221
+ var _a;
222
+ return discount.tag === "product_discount_card" && ((_a = discount.metadata) == null ? void 0 : _a.discount_calculation_mode) === "order_level";
223
+ };
224
+ const isItemLevelDiscount = (discount) => {
225
+ var _a;
226
+ return discount.tag === "product_discount_card" && ((_a = discount.metadata) == null ? void 0 : _a.discount_calculation_mode) !== "order_level";
227
+ };
228
+ const getPriority = (discount) => {
229
+ const isHolder = isHolderDiscount(discount);
230
+ if (isHolder) {
231
+ if (isGoodPass(discount))
232
+ return 1;
233
+ if (isItemLevelDiscount(discount))
234
+ return 2;
235
+ if (isOrderLevelDiscount(discount))
236
+ return 3;
237
+ } else {
238
+ if (isGoodPass(discount))
239
+ return 4;
240
+ if (isItemLevelDiscount(discount))
241
+ return 5;
242
+ if (isOrderLevelDiscount(discount))
243
+ return 6;
244
+ }
245
+ return 7;
246
+ };
247
+ function compareByExpireTime(itemA, itemB) {
248
+ if (itemA.expire_time && itemB.expire_time) {
249
+ const timeA = new Date(itemA.expire_time).getTime();
250
+ const timeB = new Date(itemB.expire_time).getTime();
251
+ return timeA - timeB;
252
+ }
253
+ return itemA.expire_time ? -1 : itemB.expire_time ? 1 : 0;
254
+ }
255
+ function compareDiscountCardValue(itemA, itemB) {
256
+ var _a, _b;
257
+ const typeA = ((_a = itemA.metadata) == null ? void 0 : _a.discount_card_type) || "percent";
258
+ const typeB = ((_b = itemB.metadata) == null ? void 0 : _b.discount_card_type) || "percent";
221
259
  if (typeA === "fixed_amount" && typeB === "percent")
222
260
  return -1;
223
261
  if (typeA === "percent" && typeB === "fixed_amount")
224
262
  return 1;
225
263
  if (typeA === "fixed_amount" && typeB === "fixed_amount") {
226
- if (a.par_value !== b.par_value) {
227
- const valueA = new import_decimal.default(a.par_value || 0);
228
- const valueB = new import_decimal.default(b.par_value || 0);
264
+ if (itemA.par_value !== itemB.par_value) {
265
+ const valueA = new import_decimal.default(itemA.par_value || 0);
266
+ const valueB = new import_decimal.default(itemB.par_value || 0);
229
267
  return valueB.minus(valueA).toNumber();
230
268
  }
231
269
  }
232
270
  if (typeA === "percent" && typeB === "percent") {
233
- if (a.par_value !== b.par_value) {
234
- const valueA = new import_decimal.default(100).minus(a.par_value || 0);
235
- const valueB = new import_decimal.default(100).minus(b.par_value || 0);
271
+ if (itemA.par_value !== itemB.par_value) {
272
+ const valueA = new import_decimal.default(100).minus(itemA.par_value || 0);
273
+ const valueB = new import_decimal.default(100).minus(itemB.par_value || 0);
236
274
  return valueA.minus(valueB).toNumber();
237
275
  }
238
276
  }
277
+ return 0;
278
+ }
279
+ const priorityA = getPriority(a);
280
+ const priorityB = getPriority(b);
281
+ if (priorityA !== priorityB) {
282
+ return priorityA - priorityB;
283
+ }
284
+ if (isGoodPass(a) && isGoodPass(b)) {
239
285
  return compareByExpireTime(a, b);
240
286
  }
241
- return compareByExpireTime(a, b);
242
- function compareByExpireTime(itemA, itemB) {
243
- if (itemA.expire_time && itemB.expire_time) {
244
- const timeA = new Date(itemA.expire_time).getTime();
245
- const timeB = new Date(itemB.expire_time).getTime();
246
- return timeA - timeB;
247
- }
248
- return itemA.expire_time ? -1 : itemB.expire_time ? 1 : 0;
287
+ if (a.tag === "product_discount_card" && b.tag === "product_discount_card") {
288
+ const valueCompare = compareDiscountCardValue(a, b);
289
+ if (valueCompare !== 0)
290
+ return valueCompare;
291
+ return compareByExpireTime(a, b);
249
292
  }
293
+ return compareByExpireTime(a, b);
250
294
  });
251
295
  const flattenedList = flattenProductsWithBundle(productList);
252
296
  const sortedFlattenedList = flattenedList.sort((a, b) => {
@@ -273,56 +317,135 @@ var RulesModule = class extends import_BaseModule.BaseModule {
273
317
  }
274
318
  return priceB.minus(priceA).toNumber();
275
319
  });
276
- const evaluator = this.getWalletPassEvaluator();
277
- if (evaluator) {
278
- addModeDiscount.forEach((discount) => {
279
- var _a, _b;
280
- const discountType = discount.tag || discount.type;
281
- if (["good_pass", "discount_card", "product_discount_card"].includes(
282
- discountType
283
- )) {
284
- const voucher = {
285
- id: discount.id,
286
- amount: Number(discount.par_value || 0),
287
- balance: Number(discount.balance || 0),
288
- type: discountType,
289
- product_id: discount.product_id,
290
- unified_available_status: 1,
291
- available_product_type: (_a = discount.limited_relation_product_data) == null ? void 0 : _a.type,
292
- available_product_ids: (_b = discount.limited_relation_product_data) == null ? void 0 : _b.product_ids
293
- };
294
- const productsForEvaluate = sortedFlattenedList.map((item) => ({
295
- product_id: item.id,
296
- price: item.price || 0,
297
- quantity: item.quantity || item.num || 1,
298
- selling_price: item.price || 0
299
- }));
300
- const result = evaluator.checkVoucherAvailability({
301
- orderTotalAmount,
302
- products: productsForEvaluate,
303
- vouchers: [voucher]
304
- });
305
- if (result.isAvailable) {
306
- discount.config = {
307
- ...result.config,
308
- isAvailable: true
309
- };
310
- } else {
311
- discount.config = {
312
- isAvailable: false
313
- };
314
- }
315
- }
316
- });
317
- }
318
320
  const usedDiscounts = /* @__PURE__ */ new Map();
319
- const usedProductIdCounts = /* @__PURE__ */ new Map();
320
321
  const discountApplicability = /* @__PURE__ */ new Map();
321
322
  const discountApplicableProducts = /* @__PURE__ */ new Map();
322
323
  addModeDiscount.forEach((discount) => {
323
324
  discountApplicability.set(discount.id, []);
324
325
  discountApplicableProducts.set(discount.id, []);
325
326
  });
327
+ const orderLevelDiscountAllocations = /* @__PURE__ */ new Map();
328
+ const orderLevelDiscountApplicableItems = /* @__PURE__ */ new Map();
329
+ const itemApplicableDiscounts = /* @__PURE__ */ new Map();
330
+ const checkItemApplicableForDiscount = (flatItem, discount) => {
331
+ var _a, _b, _c, _d, _e, _f, _g, _h;
332
+ let product;
333
+ if (flatItem.type === "main") {
334
+ product = flatItem.product;
335
+ } else {
336
+ product = {
337
+ _id: flatItem._id,
338
+ id: flatItem.id,
339
+ price: flatItem.price,
340
+ quantity: flatItem.quantity,
341
+ num: flatItem.num,
342
+ booking_id: flatItem.booking_id,
343
+ discount_list: flatItem.discount_list || [],
344
+ startDate: (_a = flatItem.parentProduct) == null ? void 0 : _a.startDate
345
+ };
346
+ }
347
+ 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)));
348
+ if (!isAvailableProduct) {
349
+ return false;
350
+ }
351
+ if ((0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
352
+ return false;
353
+ }
354
+ if (Number(product.price) <= 0 || !product.price) {
355
+ return false;
356
+ }
357
+ const limitedData = discount.limited_relation_product_data;
358
+ 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;
359
+ if (!timeLimit) {
360
+ return false;
361
+ }
362
+ let isLimitedProduct = false;
363
+ if (limitedData.type === "product_all") {
364
+ if (limitedData.filter === 1 && ((_h = limitedData.exclude_product_ids) == null ? void 0 : _h.includes(product.id))) {
365
+ isLimitedProduct = false;
366
+ } else {
367
+ isLimitedProduct = true;
368
+ }
369
+ } else if (limitedData.product_ids && limitedData.product_ids.includes(product.id)) {
370
+ isLimitedProduct = true;
371
+ }
372
+ const isBundleAvailable = this.checkPackageSubItemUsageRules(discount, flatItem);
373
+ return isLimitedProduct && isBundleAvailable;
374
+ };
375
+ const selectedOrderLevelDiscounts = sortedDiscountList.filter((discount) => {
376
+ return (0, import_utils.isOrderLevelFixedAmountDiscount)(discount) && discount.isSelected !== false;
377
+ });
378
+ selectedOrderLevelDiscounts.forEach((discount) => {
379
+ const applicableItemIds = /* @__PURE__ */ new Set();
380
+ sortedFlattenedList.forEach((flatItem) => {
381
+ if (checkItemApplicableForDiscount(flatItem, discount)) {
382
+ applicableItemIds.add(flatItem._id);
383
+ if (!itemApplicableDiscounts.has(flatItem._id)) {
384
+ itemApplicableDiscounts.set(flatItem._id, /* @__PURE__ */ new Set());
385
+ }
386
+ itemApplicableDiscounts.get(flatItem._id).add(discount.id);
387
+ }
388
+ });
389
+ orderLevelDiscountApplicableItems.set(discount.id, applicableItemIds);
390
+ });
391
+ const occupiedItems = /* @__PURE__ */ new Map();
392
+ selectedOrderLevelDiscounts.forEach((discount) => {
393
+ const limitedData = discount.limited_relation_product_data;
394
+ const isExclusiveDiscount = limitedData.type !== "product_all";
395
+ if (isExclusiveDiscount) {
396
+ const applicableItems = orderLevelDiscountApplicableItems.get(discount.id);
397
+ if (applicableItems) {
398
+ applicableItems.forEach((itemId) => {
399
+ if (!occupiedItems.has(itemId)) {
400
+ occupiedItems.set(itemId, discount.id);
401
+ }
402
+ });
403
+ }
404
+ }
405
+ });
406
+ console.log("occupiedItems", occupiedItems, "orderLevelDiscountApplicableItems", orderLevelDiscountApplicableItems);
407
+ sortedDiscountList.forEach((discount) => {
408
+ if (!(0, import_utils.isOrderLevelFixedAmountDiscount)(discount)) {
409
+ return;
410
+ }
411
+ const applicableProducts = [];
412
+ sortedFlattenedList.forEach((flatItem) => {
413
+ var _a, _b;
414
+ const occupyingDiscountId = occupiedItems.get(flatItem._id);
415
+ if (occupyingDiscountId !== void 0 && occupyingDiscountId !== discount.id) {
416
+ return;
417
+ }
418
+ if (!checkItemApplicableForDiscount(flatItem, discount)) {
419
+ return;
420
+ }
421
+ let product;
422
+ if (flatItem.type === "main") {
423
+ product = flatItem.product;
424
+ } else {
425
+ product = {
426
+ _id: flatItem._id,
427
+ id: flatItem.id,
428
+ price: flatItem.price,
429
+ quantity: flatItem.quantity,
430
+ num: flatItem.num
431
+ };
432
+ }
433
+ const quantity = flatItem.type === "main" ? product.quantity || 1 : (product.num || 1) * (((_a = flatItem.parentProduct) == null ? void 0 : _a.quantity) || 1);
434
+ const productData = {
435
+ productId: flatItem._id,
436
+ amount: Number(product.price || 0),
437
+ quantity
438
+ };
439
+ if (flatItem.type === "bundle") {
440
+ productData.parentQuantity = ((_b = flatItem.parentProduct) == null ? void 0 : _b.quantity) || 1;
441
+ }
442
+ applicableProducts.push(productData);
443
+ });
444
+ if (applicableProducts.length > 0) {
445
+ const allocation = (0, import_utils.calculateOrderLevelDiscountAllocation)(discount, applicableProducts);
446
+ orderLevelDiscountAllocations.set(discount.id, allocation);
447
+ }
448
+ });
326
449
  const processedProductsMap = /* @__PURE__ */ new Map();
327
450
  const appliedDiscountProducts = /* @__PURE__ */ new Map();
328
451
  sortedFlattenedList.forEach((flatItem) => {
@@ -347,7 +470,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
347
470
  originProduct = flatItem.originProduct;
348
471
  }
349
472
  addModeDiscount.forEach((discount) => {
350
- var _a2, _b, _c, _d, _e, _f, _g;
473
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
351
474
  const limitedData = discount == null ? void 0 : discount.limited_relation_product_data;
352
475
  const _tempVar = (flatItem == null ? void 0 : flatItem.type) === "bundle" ? flatItem == null ? void 0 : flatItem.parentProduct : flatItem == null ? void 0 : flatItem.product;
353
476
  const isHolderMatch = this.checkHolderMatch(
@@ -360,17 +483,17 @@ var RulesModule = class extends import_BaseModule.BaseModule {
360
483
  );
361
484
  let timeLimit = true;
362
485
  timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], ((product == null ? void 0 : product.startDate) || (0, import_dayjs.default)()).format("YYYY-MM-DD HH:mm:ss")).length;
363
- 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;
486
+ const isLimitedProduct = (limitedData.type === "product_all" || limitedData.product_ids && limitedData.product_ids.includes(product.id)) && isHolderMatch;
364
487
  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(
365
488
  (discount2) => discount2.id && [
366
489
  "good_pass",
367
490
  "discount_card",
368
491
  "product_discount_card"
369
492
  ].includes(discount2.tag || discount2.type)
370
- ))) : !((flatItem == null ? void 0 : flatItem.booking_id) && ((_d = (_c = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _c.metadata) == null ? void 0 : _d.custom_product_bundle_map_id));
493
+ ))) : !((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)));
371
494
  const isBundleAvailable = this.checkPackageSubItemUsageRules(discount, flatItem);
372
- if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable && ((_e = discount.config) == null ? void 0 : _e.isAvailable)) {
373
- (_f = discountApplicability.get(discount.id)) == null ? void 0 : _f.push(product.id);
495
+ if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable) {
496
+ (_g = discountApplicability.get(discount.id)) == null ? void 0 : _g.push(product.id);
374
497
  const applicableProducts = discountApplicableProducts.get(discount.id) || [];
375
498
  const discountType = discount.tag || discount.type;
376
499
  const isGoodPass = discountType === "good_pass";
@@ -380,14 +503,14 @@ var RulesModule = class extends import_BaseModule.BaseModule {
380
503
  type: discountType,
381
504
  tag: discountType,
382
505
  discount: {
383
- discount_card_type: (_g = discount == null ? void 0 : discount.metadata) == null ? void 0 : _g.discount_card_type,
506
+ discount_card_type: (_h = discount == null ? void 0 : discount.metadata) == null ? void 0 : _h.discount_card_type,
384
507
  fixed_amount: product.price,
508
+ discount_calculation_mode: (_i = discount == null ? void 0 : discount.metadata) == null ? void 0 : _i.discount_calculation_mode,
385
509
  resource_id: discount.id,
386
510
  title: discount.format_title,
387
511
  original_amount: product.price || product.origin_total,
388
512
  pre_value: discount.par_value,
389
- product_id: originProduct.id,
390
- discount_product_id: discount.product_id
513
+ product_id: originProduct.id
391
514
  },
392
515
  metadata: {
393
516
  num
@@ -400,7 +523,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
400
523
  });
401
524
  const processedFlatItemsMap = /* @__PURE__ */ new Map();
402
525
  sortedFlattenedList.forEach((flatItem, index) => {
403
- 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;
526
+ 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;
404
527
  let product, originProduct;
405
528
  if (flatItem.type === "main") {
406
529
  product = flatItem.product;
@@ -421,36 +544,22 @@ var RulesModule = class extends import_BaseModule.BaseModule {
421
544
  };
422
545
  originProduct = flatItem.originProduct;
423
546
  }
424
- 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(
425
- (discount) => discount.id && ["good_pass", "discount_card", "product_discount_card"].includes(
426
- discount.tag || discount.type
427
- )
428
- ))) {
547
+ if ((product == null ? void 0 : product.booking_id) && ((_e = product.discount_list) == null ? void 0 : _e.length) && ((_f = product == null ? void 0 : product.discount_list) == null ? void 0 : _f.every((discount) => discount.id && ["good_pass", "discount_card", "product_discount_card"].includes(discount.tag || discount.type)))) {
429
548
  if (flatItem.type === "main") {
430
549
  processedProductsMap.set(product._id, [originProduct]);
431
550
  } else {
432
- processedFlatItemsMap.set(flatItem._id, [
433
- {
434
- ...flatItem,
435
- processed: true
436
- }
437
- ]);
551
+ processedFlatItemsMap.set(flatItem._id, [{
552
+ ...flatItem,
553
+ processed: true
554
+ }]);
438
555
  }
439
556
  return;
440
557
  }
441
558
  const applicableDiscounts = sortedDiscountList.filter((discount) => {
442
- var _a2, _b2, _c2, _d2;
443
- const discountType = discount.tag || discount.type;
444
- if (["good_pass", "discount_card", "product_discount_card"].includes(
445
- discountType
446
- )) {
447
- if (discount.config === void 0 || !((_a2 = discount == null ? void 0 : discount.config) == null ? void 0 : _a2.isAvailable)) {
448
- return false;
449
- }
450
- }
451
- if ((Number(product.price) <= 0 || !product.price) && !((_b2 = product.discount_list) == null ? void 0 : _b2.length) && (discount.tag || discount.type) === "good_pass")
559
+ var _a2, _b2;
560
+ if ((Number(product.price) <= 0 || !product.price) && !((_a2 = product.discount_list) == null ? void 0 : _a2.length) && (discount.tag || discount.type) === "good_pass")
452
561
  return false;
453
- if ((Number(product.price) <= 0 || !product.price) && !((_c2 = product.discount_list) == null ? void 0 : _c2.find((n) => {
562
+ if ((Number(product.price) <= 0 || !product.price) && !((_b2 = product.discount_list) == null ? void 0 : _b2.find((n) => {
454
563
  var _a3;
455
564
  return ((_a3 = n.discount) == null ? void 0 : _a3.resource_id) === discount.id;
456
565
  })) && (discount.tag || discount.type) !== "good_pass")
@@ -458,15 +567,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
458
567
  const targetUsedDiscounts = usedDiscounts.get(discount.id);
459
568
  if (targetUsedDiscounts && (discount.tag || discount.type) === "good_pass")
460
569
  return false;
461
- if ((discount.tag || discount.type) === "good_pass") {
462
- const maxUsagePerOrder = (_d2 = discount.config) == null ? void 0 : _d2.maxUsagePerOrder;
463
- if (maxUsagePerOrder && maxUsagePerOrder > 0) {
464
- const currentUsedCount = usedProductIdCounts.get(discount.product_id) || 0;
465
- if (currentUsedCount >= maxUsagePerOrder) {
466
- return false;
467
- }
468
- }
469
- }
470
570
  const limitedData = discount.limited_relation_product_data;
471
571
  const _tempVar = (flatItem == null ? void 0 : flatItem.type) === "bundle" ? flatItem == null ? void 0 : flatItem.parentProduct : flatItem == null ? void 0 : flatItem.product;
472
572
  const isHolderMatch = this.checkHolderMatch(
@@ -485,9 +585,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
485
585
  return false;
486
586
  }
487
587
  if (limitedData.type === "product_all") {
488
- if (limitedData.filter === 1 && limitedData.exclude_product_ids.includes(product.id)) {
489
- return false;
490
- }
491
588
  if (!this.checkPackageSubItemUsageRules(discount, flatItem)) {
492
589
  return false;
493
590
  }
@@ -500,96 +597,66 @@ var RulesModule = class extends import_BaseModule.BaseModule {
500
597
  }
501
598
  return false;
502
599
  });
503
- const selectedDiscountCard = applicableDiscounts.find(
504
- (n) => n.isScan && n.isSelected && (n.tag || n.type) !== "good_pass"
505
- );
600
+ const selectedDiscountCard = applicableDiscounts.find((n) => n.isScan && n.isSelected && (n.tag || n.type) !== "good_pass");
506
601
  const selectedDiscount = selectedDiscountCard || applicableDiscounts[0];
507
602
  let isManualDiscount = false;
508
603
  if (flatItem.type === "main") {
509
- isManualDiscount = typeof product.isManualDiscount === "boolean" ? product.isManualDiscount : product.total != product.origin_total && (product.bundle || []).every(
510
- (item) => {
511
- var _a2;
512
- return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
513
- }
514
- ) && (!((_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(
515
- _h,
516
- (item) => item.type === "product"
517
- )));
604
+ isManualDiscount = typeof product.isManualDiscount === "boolean" ? product.isManualDiscount : product.total != product.origin_total && (product.bundle || []).every((item) => {
605
+ var _a2;
606
+ return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
607
+ }) && (!((_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")));
518
608
  } else {
519
609
  const parentProduct = flatItem.parentProduct;
520
610
  if (parentProduct) {
521
- isManualDiscount = typeof parentProduct.isManualDiscount === "boolean" ? parentProduct.isManualDiscount : parentProduct.total != parentProduct.origin_total && (parentProduct.bundle || []).every(
522
- (item) => {
523
- var _a2;
524
- return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
525
- }
526
- ) && (!((_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(
527
- _k,
528
- (item) => item.type === "product"
529
- )));
611
+ isManualDiscount = typeof parentProduct.isManualDiscount === "boolean" ? parentProduct.isManualDiscount : parentProduct.total != parentProduct.origin_total && (parentProduct.bundle || []).every((item) => {
612
+ var _a2;
613
+ return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
614
+ }) && (!((_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")));
530
615
  }
531
616
  }
532
617
  if (options == null ? void 0 : options.discountId) {
533
- if (flatItem.type === "main" && ((_m = product.discount_list) == null ? void 0 : _m.some(
534
- (item) => {
535
- var _a2;
536
- return ((_a2 = item.discount) == null ? void 0 : _a2.resource_id) === options.discountId;
537
- }
538
- ))) {
618
+ if (flatItem.type === "main" && ((_m = product.discount_list) == null ? void 0 : _m.some((item) => {
619
+ var _a2;
620
+ return ((_a2 = item.discount) == null ? void 0 : _a2.resource_id) === options.discountId;
621
+ }))) {
539
622
  isManualDiscount = false;
540
623
  }
541
624
  if (flatItem.type === "bundle") {
542
- if (((_n = product.discount_list) == null ? void 0 : _n.some(
543
- (item) => {
544
- var _a2;
545
- return ((_a2 = item.discount) == null ? void 0 : _a2.resource_id) === options.discountId;
546
- }
547
- )) || ((_p = (_o = flatItem.parentProduct) == null ? void 0 : _o.discount_list) == null ? void 0 : _p.some(
548
- (item) => {
549
- var _a2;
550
- return ((_a2 = item.discount) == null ? void 0 : _a2.resource_id) === options.discountId;
551
- }
552
- ))) {
625
+ if (((_n = product.discount_list) == null ? void 0 : _n.some((item) => {
626
+ var _a2;
627
+ return ((_a2 = item.discount) == null ? void 0 : _a2.resource_id) === options.discountId;
628
+ })) || ((_p = (_o = flatItem.parentProduct) == null ? void 0 : _o.discount_list) == null ? void 0 : _p.some((item) => {
629
+ var _a2;
630
+ return ((_a2 = item.discount) == null ? void 0 : _a2.resource_id) === options.discountId;
631
+ }))) {
553
632
  isManualDiscount = false;
554
633
  }
555
634
  }
556
635
  }
557
636
  if (options == null ? void 0 : options.selectedList) {
558
- if (flatItem.type === "main" && ((_q = product.discount_list) == null ? void 0 : _q.some(
559
- (item) => {
560
- var _a2;
561
- return (_a2 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a2.some(
562
- (n) => {
563
- var _a3;
564
- return n.discountId === ((_a3 = item.discount) == null ? void 0 : _a3.resource_id);
565
- }
566
- );
567
- }
568
- ))) {
637
+ if (flatItem.type === "main" && ((_q = product.discount_list) == null ? void 0 : _q.some((item) => {
638
+ var _a2;
639
+ return (_a2 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a2.some((n) => {
640
+ var _a3;
641
+ return n.discountId === ((_a3 = item.discount) == null ? void 0 : _a3.resource_id);
642
+ });
643
+ }))) {
569
644
  isManualDiscount = false;
570
645
  }
571
646
  if (flatItem.type === "bundle") {
572
- if (((_r = product.discount_list) == null ? void 0 : _r.some(
573
- (item) => {
574
- var _a2;
575
- return (_a2 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a2.some(
576
- (n) => {
577
- var _a3;
578
- return n.discountId === ((_a3 = item.discount) == null ? void 0 : _a3.resource_id);
579
- }
580
- );
581
- }
582
- )) || ((_t = (_s = flatItem.parentProduct) == null ? void 0 : _s.discount_list) == null ? void 0 : _t.some(
583
- (item) => {
584
- var _a2;
585
- return (_a2 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a2.some(
586
- (n) => {
587
- var _a3;
588
- return n.discountId === ((_a3 = item.discount) == null ? void 0 : _a3.resource_id);
589
- }
590
- );
591
- }
592
- ))) {
647
+ if (((_r = product.discount_list) == null ? void 0 : _r.some((item) => {
648
+ var _a2;
649
+ return (_a2 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a2.some((n) => {
650
+ var _a3;
651
+ return n.discountId === ((_a3 = item.discount) == null ? void 0 : _a3.resource_id);
652
+ });
653
+ })) || ((_t = (_s = flatItem.parentProduct) == null ? void 0 : _s.discount_list) == null ? void 0 : _t.some((item) => {
654
+ var _a2;
655
+ return (_a2 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a2.some((n) => {
656
+ var _a3;
657
+ return n.discountId === ((_a3 = item.discount) == null ? void 0 : _a3.resource_id);
658
+ });
659
+ }))) {
593
660
  isManualDiscount = false;
594
661
  }
595
662
  }
@@ -597,8 +664,9 @@ var RulesModule = class extends import_BaseModule.BaseModule {
597
664
  if (applicableDiscounts.length === 0 || isManualDiscount || (0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
598
665
  if (flatItem.type === "main") {
599
666
  if (product.isClient) {
600
- processedProductsMap.set(product._id, [
601
- this.hooks.setProduct(originProduct, {
667
+ processedProductsMap.set(
668
+ product._id,
669
+ [this.hooks.setProduct(originProduct, {
602
670
  ...isManualDiscount ? {} : {
603
671
  origin_total: (0, import_utils2.getProductOriginTotalPrice)({
604
672
  product: {
@@ -619,11 +687,12 @@ var RulesModule = class extends import_BaseModule.BaseModule {
619
687
  price: product.price
620
688
  },
621
689
  discount_list: []
622
- })
623
- ]);
690
+ })]
691
+ );
624
692
  } else {
625
- processedProductsMap.set(product._id, [
626
- this.hooks.setProduct(originProduct, {
693
+ processedProductsMap.set(
694
+ product._id,
695
+ [this.hooks.setProduct(originProduct, {
627
696
  ...isManualDiscount ? {
628
697
  price: product.price,
629
698
  main_product_selling_price: product.price
@@ -634,8 +703,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
634
703
  main_product_selling_price: product.price
635
704
  },
636
705
  discount_list: []
637
- })
638
- ]);
706
+ })]
707
+ );
639
708
  }
640
709
  } else {
641
710
  processedFlatItemsMap.set(flatItem._id, [{
@@ -652,36 +721,20 @@ var RulesModule = class extends import_BaseModule.BaseModule {
652
721
  }
653
722
  const isNeedSplit = (selectedDiscount.tag || selectedDiscount.type) === "good_pass";
654
723
  const totalQuantity = product.quantity || product.num || 1;
655
- const availableGoodPassCount = applicableDiscounts.filter(
656
- (item) => (item.tag || item.type) === "good_pass"
657
- ).length;
658
- let maxUsageLimit = availableGoodPassCount;
659
- if (selectedDiscount.config && selectedDiscount.config.maxUsagePerOrder) {
660
- maxUsageLimit = Math.min(
661
- availableGoodPassCount,
662
- selectedDiscount.config.maxUsagePerOrder
663
- );
664
- }
665
- const splitCount = isNeedSplit ? Math.min(product.quantity || product.num || 1, maxUsageLimit) : 1;
724
+ const availableGoodPassCount = applicableDiscounts.filter((item) => (item.tag || item.type) === "good_pass").length;
725
+ const splitCount = isNeedSplit ? Math.min(totalQuantity, availableGoodPassCount) : 1;
666
726
  const arr = [];
667
727
  if (flatItem.type === "main") {
668
728
  if (splitCount < totalQuantity && isNeedSplit) {
669
- arr.push(
670
- this.hooks.setProduct(originProduct, {
671
- discount_list: [],
672
- quantity: totalQuantity - splitCount,
673
- _id: product._id.split("___")[0],
674
- total: product.origin_total || product.total
675
- })
676
- );
729
+ arr.push(this.hooks.setProduct(originProduct, {
730
+ discount_list: [],
731
+ quantity: totalQuantity - splitCount,
732
+ _id: product._id.split("___")[0]
733
+ }));
677
734
  }
678
735
  for (let i = 0; i < splitCount; i++) {
679
736
  const selectedDiscount2 = selectedDiscountCard || applicableDiscounts[i];
680
737
  usedDiscounts.set(selectedDiscount2.id, true);
681
- if ((selectedDiscount2.tag || selectedDiscount2.type) === "good_pass") {
682
- const currentCount = usedProductIdCounts.get(selectedDiscount2.product_id) || 0;
683
- usedProductIdCounts.set(selectedDiscount2.product_id, currentCount + 1);
684
- }
685
738
  const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
686
739
  let productOriginTotal = product.origin_total || product.total || 0;
687
740
  if (((_u = product.discount_list) == null ? void 0 : _u.length) && product.origin_total) {
@@ -690,32 +743,41 @@ var RulesModule = class extends import_BaseModule.BaseModule {
690
743
  if (Number(((_v = originProduct == null ? void 0 : originProduct._productInit) == null ? void 0 : _v.original_price) || 0) > 0 && product.origin_total && product.total && product.origin_total !== product.total) {
691
744
  productOriginTotal = product.total;
692
745
  }
693
- const targetProductTotal = (0, import_utils.getDiscountAmount)(
694
- selectedDiscount2,
695
- product.price,
696
- product.price
697
- );
698
- const discountType = selectedDiscount2.tag === "product_discount_card" ? "discount_card" : selectedDiscount2.tag;
699
- const actualDiscountAmount = new import_decimal.default(product.price).minus(new import_decimal.default(targetProductTotal)).toNumber();
746
+ const isOrderLevel = (0, import_utils.isOrderLevelFixedAmountDiscount)(selectedDiscount2);
747
+ const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount2.id) : null;
748
+ const productAllocation = orderLevelAllocation == null ? void 0 : orderLevelAllocation.get(flatItem._id);
749
+ let targetProductTotal;
750
+ let amount;
751
+ let productDiscountDifference;
752
+ if (isOrderLevel && productAllocation) {
753
+ amount = productAllocation.discountAmount;
754
+ productDiscountDifference = productAllocation.difference;
755
+ targetProductTotal = Math.max(new import_decimal.default(product.price).minus(amount).toNumber(), 0);
756
+ } else {
757
+ targetProductTotal = (0, import_utils.getDiscountAmount)(selectedDiscount2, product.price, product.price);
758
+ amount = new import_decimal.default(product.price).minus(new import_decimal.default(targetProductTotal)).toNumber();
759
+ }
760
+ const discountType = selectedDiscount2.tag || selectedDiscount2.type;
700
761
  const isGoodPass = discountType === "good_pass";
701
762
  const discountDetail = {
702
- amount: actualDiscountAmount,
703
- type: discountType,
763
+ amount,
764
+ type: selectedDiscount2.tag === "product_discount_card" ? "discount_card" : discountType,
704
765
  discount: {
705
766
  discount_card_type: (_w = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _w.discount_card_type,
706
- fixed_amount: actualDiscountAmount,
767
+ fixed_amount: amount,
768
+ discount_calculation_mode: (_x = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _x.discount_calculation_mode,
707
769
  resource_id: selectedDiscount2.id,
708
770
  title: selectedDiscount2.format_title,
709
771
  original_amount: product.price,
710
772
  product_id: originProduct.id,
711
- percent: selectedDiscount2.par_value,
712
- discount_product_id: selectedDiscount2.product_id
773
+ percent: selectedDiscount2.par_value
713
774
  },
714
775
  // 前端使用的num数量,为了计算优惠金额
715
776
  _num: isGoodPass ? 1 : product.num,
716
- config: selectedDiscount2 == null ? void 0 : selectedDiscount2.config,
717
777
  metadata: {
718
- num: 1
778
+ num: 1,
779
+ // 🔥 order_level 分摊差值
780
+ ...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference }
719
781
  }
720
782
  };
721
783
  appliedProducts.push(discountDetail);
@@ -729,6 +791,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
729
791
  }, new import_decimal.default(total)).toNumber();
730
792
  }
731
793
  if (product.isClient) {
794
+ debugger;
732
795
  arr.push(this.hooks.setProduct(originProduct, {
733
796
  discount_list: [discountDetail],
734
797
  price: selectedDiscount2.tag === "good_pass" ? 0 : product.price,
@@ -765,35 +828,24 @@ var RulesModule = class extends import_BaseModule.BaseModule {
765
828
  for (let i = 0; i < discountNum; i++) {
766
829
  const selectedDiscount2 = applicableDiscounts[i];
767
830
  usedDiscounts.set(selectedDiscount2.id, true);
768
- if ((selectedDiscount2.tag || selectedDiscount2.type) === "good_pass") {
769
- const currentCount = usedProductIdCounts.get(selectedDiscount2.product_id) || 0;
770
- usedProductIdCounts.set(selectedDiscount2.product_id, currentCount + 1);
771
- }
772
831
  const uniqueId = `${flatItem._id}_split_${i}`;
773
- const discountedPrice = (0, import_utils.getDiscountAmount)(
774
- selectedDiscount2,
775
- product.origin_total,
776
- product.origin_total
777
- );
778
- const bundleDiscountAmount = new import_decimal.default(product.origin_total || 0).minus(discountedPrice).toNumber();
779
832
  const discountDetail = {
780
- amount: bundleDiscountAmount,
833
+ amount: product.origin_total,
781
834
  type: "good_pass",
782
835
  discount: {
783
836
  fixed_amount: product.origin_total,
837
+ discount_calculation_mode: (_y = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _y.discount_calculation_mode,
784
838
  resource_id: selectedDiscount2.id,
785
839
  title: selectedDiscount2.format_title,
786
840
  original_amount: product.origin_total,
787
- product_id: product.id,
788
- discount_product_id: selectedDiscount2.product_id
841
+ product_id: product.id
789
842
  },
790
843
  metadata: {
791
844
  // 🔥 使用拆分后的唯一 _id
792
845
  custom_product_bundle_map_id: uniqueId,
793
846
  num: 1
794
847
  },
795
- _num: 1,
796
- config: selectedDiscount2 == null ? void 0 : selectedDiscount2.config
848
+ _num: 1
797
849
  };
798
850
  const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
799
851
  appliedProducts.push(discountDetail);
@@ -804,9 +856,9 @@ var RulesModule = class extends import_BaseModule.BaseModule {
804
856
  _id: uniqueId,
805
857
  num: 1,
806
858
  quantity: 1,
807
- price: discountedPrice,
808
- // 折扣后的价格
809
- total: discountedPrice,
859
+ price: 0,
860
+ // 商品券价格为0
861
+ total: 0,
810
862
  discount_list: [discountDetail],
811
863
  processed: true,
812
864
  _discountId: selectedDiscount2.id
@@ -826,38 +878,48 @@ var RulesModule = class extends import_BaseModule.BaseModule {
826
878
  } else {
827
879
  const selectedDiscount2 = selectedDiscountCard || applicableDiscounts[0];
828
880
  usedDiscounts.set(selectedDiscount2.id, true);
829
- if ((selectedDiscount2.tag || selectedDiscount2.type) === "good_pass") {
830
- const currentCount = usedProductIdCounts.get(selectedDiscount2.product_id) || 0;
831
- usedProductIdCounts.set(selectedDiscount2.product_id, currentCount + 1);
832
- }
833
881
  const productOriginTotal = product.original_price || product.price || 0;
834
- const targetProductTotal = (0, import_utils.getDiscountAmount)(
835
- selectedDiscount2,
836
- productOriginTotal,
837
- productOriginTotal
838
- );
839
- const bundleActualDiscountAmount = new import_decimal.default(productOriginTotal).minus(targetProductTotal).toNumber();
882
+ const isOrderLevel = (0, import_utils.isOrderLevelFixedAmountDiscount)(selectedDiscount2);
883
+ const orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount2.id) : null;
884
+ const productAllocation = orderLevelAllocation == null ? void 0 : orderLevelAllocation.get(flatItem._id);
885
+ let targetProductTotal;
886
+ let fixedAmountPerItem;
887
+ let productDiscountDifference;
888
+ if (isOrderLevel && productAllocation) {
889
+ fixedAmountPerItem = productAllocation.discountAmount;
890
+ productDiscountDifference = productAllocation.difference;
891
+ targetProductTotal = Math.max(new import_decimal.default(productOriginTotal).minus(fixedAmountPerItem).toNumber(), 0);
892
+ } else {
893
+ targetProductTotal = (0, import_utils.getDiscountAmount)(
894
+ selectedDiscount2,
895
+ productOriginTotal,
896
+ productOriginTotal
897
+ );
898
+ fixedAmountPerItem = new import_decimal.default(productOriginTotal).minus(targetProductTotal).toNumber();
899
+ }
900
+ debugger;
840
901
  const uniqueId = flatItem._id;
841
902
  const discountDetail = {
842
- amount: bundleActualDiscountAmount * (product.num || 1),
903
+ amount: fixedAmountPerItem * (product.num || 1),
843
904
  type: selectedDiscount2.tag === "product_discount_card" ? "discount_card" : selectedDiscount2.tag,
844
905
  discount: {
845
- discount_card_type: (_x = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _x.discount_card_type,
846
- fixed_amount: bundleActualDiscountAmount,
906
+ discount_card_type: (_z = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _z.discount_card_type,
907
+ fixed_amount: fixedAmountPerItem,
908
+ discount_calculation_mode: (_A = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _A.discount_calculation_mode,
847
909
  resource_id: selectedDiscount2.id,
848
910
  title: selectedDiscount2.format_title,
849
911
  original_amount: product.original_price,
850
912
  product_id: product.id,
851
- percent: selectedDiscount2.par_value,
852
- discount_product_id: selectedDiscount2.product_id
913
+ percent: selectedDiscount2.par_value
853
914
  },
854
915
  metadata: {
855
916
  // 🔥 使用唯一的 _id
856
917
  custom_product_bundle_map_id: uniqueId,
857
- num: product.num || 1
918
+ num: product.num || 1,
919
+ // 🔥 order_level 分摊差值
920
+ ...productDiscountDifference !== void 0 && { product_discount_difference: productDiscountDifference }
858
921
  },
859
- config: selectedDiscount2 == null ? void 0 : selectedDiscount2.config,
860
- _num: (product.num || 1) * (((_y = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _y.num) || 1)
922
+ _num: (product.num || 1) * (((_B = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _B.num) || 1)
861
923
  };
862
924
  const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
863
925
  appliedProducts.push(discountDetail);
@@ -865,7 +927,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
865
927
  processedItems.push({
866
928
  ...flatItem,
867
929
  total: targetProductTotal,
868
- price: new import_decimal.default(productOriginTotal || 0).minus(discountDetail.discount.fixed_amount).toNumber(),
930
+ price: new import_decimal.default(productOriginTotal || 0).minus(fixedAmountPerItem).toNumber(),
869
931
  discount_list: [discountDetail],
870
932
  processed: true
871
933
  });
@@ -946,65 +1008,61 @@ var RulesModule = class extends import_BaseModule.BaseModule {
946
1008
  const mainProduct = mainProductArr[0];
947
1009
  const mainProductData = this.hooks.getProduct(mainProduct);
948
1010
  const newBundleWithDiscount = [];
949
- (product.bundle || []).forEach(
950
- (bundleItem, bundleIndex) => {
951
- const processedItems = bundleProcessingInfo.get(
952
- bundleIndex
953
- ) || [bundleItem];
954
- if (processedItems.length > 1) {
955
- processedItems.forEach((item) => {
956
- const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
957
- var _a;
958
- return {
959
- ...discount,
960
- metadata: {
961
- num: item.num,
962
- custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
963
- }
964
- // num: item.num, // 使用拆分后的 num
965
- };
966
- });
967
- newBundleWithDiscount.push({
968
- ...bundleItem,
969
- _id: item._id,
970
- product_id: bundleItem.product_id,
971
- price: item.price,
972
- num: item.num,
973
- discount_list: updatedDiscountList2
974
- });
1011
+ (product.bundle || []).forEach((bundleItem, bundleIndex) => {
1012
+ const processedItems = bundleProcessingInfo.get(bundleIndex) || [bundleItem];
1013
+ if (processedItems.length > 1) {
1014
+ processedItems.forEach((item) => {
1015
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1016
+ var _a;
1017
+ return {
1018
+ ...discount,
1019
+ metadata: {
1020
+ ...discount.metadata,
1021
+ num: item.num,
1022
+ custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
1023
+ }
1024
+ // num: item.num, // 使用拆分后的 num
1025
+ };
1026
+ });
1027
+ newBundleWithDiscount.push({
1028
+ ...bundleItem,
1029
+ _id: item._id,
1030
+ product_id: bundleItem.product_id,
1031
+ price: item.price,
1032
+ num: item.num,
1033
+ discount_list: updatedDiscountList2
1034
+ });
1035
+ });
1036
+ } else {
1037
+ const item = processedItems[0];
1038
+ if (item.processed) {
1039
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1040
+ var _a;
1041
+ return {
1042
+ ...discount,
1043
+ metadata: {
1044
+ ...discount.metadata,
1045
+ num: item.num,
1046
+ custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
1047
+ }
1048
+ // num: item.num, // 使用当前的 num
1049
+ };
1050
+ });
1051
+ newBundleWithDiscount.push({
1052
+ ...bundleItem,
1053
+ _id: item._id,
1054
+ product_id: bundleItem.product_id,
1055
+ price: item.price,
1056
+ num: item.num,
1057
+ discount_list: updatedDiscountList2
975
1058
  });
976
1059
  } else {
977
- const item = processedItems[0];
978
- if (item.processed) {
979
- const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
980
- var _a;
981
- return {
982
- ...discount,
983
- metadata: {
984
- num: item.num,
985
- custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
986
- }
987
- // num: item.num, // 使用当前的 num
988
- };
989
- });
990
- newBundleWithDiscount.push({
991
- ...bundleItem,
992
- _id: item._id,
993
- product_id: bundleItem.product_id,
994
- price: item.price,
995
- num: item.num,
996
- discount_list: updatedDiscountList2
997
- });
998
- } else {
999
- newBundleWithDiscount.push(item);
1000
- }
1060
+ newBundleWithDiscount.push(item);
1001
1061
  }
1002
1062
  }
1003
- );
1063
+ });
1004
1064
  let newTotalWithDiscount = Number(mainProductData.price || 0);
1005
- let newOriginTotalWithDiscount = Number(
1006
- mainProductData.original_price || mainProductData.price || 0
1007
- );
1065
+ let newOriginTotalWithDiscount = Number(mainProductData.original_price || mainProductData.price || 0);
1008
1066
  const updatedMainDiscountList = mainProductData.discount_list.map((discount) => {
1009
1067
  var _a, _b;
1010
1068
  if ((_a = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a.custom_product_bundle_map_id) {
@@ -1014,17 +1072,16 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1014
1072
  ...discount,
1015
1073
  // num: 1,
1016
1074
  metadata: {
1075
+ ...discount.metadata,
1017
1076
  custom_product_bundle_map_id: (_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.custom_product_bundle_map_id,
1018
1077
  num: 1
1019
1078
  }
1020
1079
  };
1021
1080
  });
1022
- const mainDiscountList = updatedMainDiscountList.filter(
1023
- (item) => {
1024
- var _a;
1025
- return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
1026
- }
1027
- );
1081
+ const mainDiscountList = updatedMainDiscountList.filter((item) => {
1082
+ var _a;
1083
+ return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
1084
+ });
1028
1085
  if (mainDiscountList && mainDiscountList.length > 0) {
1029
1086
  const allDiscountAmount = (0, import_utils.getDiscountListAmountTotal)(mainDiscountList);
1030
1087
  newTotalWithDiscount = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotalWithDiscount;
@@ -1060,18 +1117,14 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1060
1117
  );
1061
1118
  if (mainProductQuantity > 1) {
1062
1119
  const newBundleOriginal = [];
1063
- (product.bundle || []).forEach(
1064
- (bundleItem, bundleIndex) => {
1065
- newBundleOriginal.push({
1066
- ...bundleItem,
1067
- discount_list: []
1068
- });
1069
- }
1070
- );
1120
+ (product.bundle || []).forEach((bundleItem, bundleIndex) => {
1121
+ newBundleOriginal.push({
1122
+ ...bundleItem,
1123
+ discount_list: []
1124
+ });
1125
+ });
1071
1126
  let newTotalOriginal = Number(mainProductData.price || 0);
1072
- let newOriginTotalOriginal = Number(
1073
- mainProductData.original_price || mainProductData.price || 0
1074
- );
1127
+ let newOriginTotalOriginal = Number(mainProductData.original_price || mainProductData.price || 0);
1075
1128
  const updatedMainDiscountListOriginal = mainProductData.discount_list.map((discount) => {
1076
1129
  var _a, _b;
1077
1130
  if ((_a = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a.custom_product_bundle_map_id) {
@@ -1080,22 +1133,19 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1080
1133
  return {
1081
1134
  ...discount,
1082
1135
  metadata: {
1136
+ ...discount.metadata,
1083
1137
  num: mainProductQuantity - 1,
1084
1138
  custom_product_bundle_map_id: (_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.custom_product_bundle_map_id
1085
1139
  }
1086
1140
  // num: mainProductQuantity - 1,
1087
1141
  };
1088
1142
  });
1089
- const mainDiscountListOriginal = updatedMainDiscountListOriginal.filter(
1090
- (item) => {
1091
- var _a;
1092
- return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
1093
- }
1094
- );
1143
+ const mainDiscountListOriginal = updatedMainDiscountListOriginal.filter((item) => {
1144
+ var _a;
1145
+ return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
1146
+ });
1095
1147
  if (mainDiscountListOriginal && mainDiscountListOriginal.length > 0) {
1096
- const allDiscountAmount = (0, import_utils.getDiscountListAmount)(
1097
- mainDiscountListOriginal
1098
- );
1148
+ const allDiscountAmount = (0, import_utils.getDiscountListAmount)(mainDiscountListOriginal);
1099
1149
  newTotalOriginal = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotalOriginal;
1100
1150
  newOriginTotalOriginal = mainProductData.origin_total ?? newOriginTotalOriginal;
1101
1151
  }
@@ -1130,56 +1180,48 @@ var RulesModule = class extends import_BaseModule.BaseModule {
1130
1180
  const mainProductData = this.hooks.getProduct(mainProduct);
1131
1181
  const newBundle = [];
1132
1182
  if (product.bundle && Array.isArray(product.bundle)) {
1133
- product.bundle.forEach(
1134
- (bundleItem, bundleIndex) => {
1135
- const bundleItemId = `${product._id}_bundle_${bundleIndex}`;
1136
- const processedBundleItems = processedFlatItemsMap2.get(bundleItemId);
1137
- if (!processedBundleItems || processedBundleItems.length === 0) {
1138
- newBundle.push(bundleItem);
1139
- } else {
1140
- processedBundleItems.forEach((item) => {
1141
- const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1142
- var _a2;
1143
- return {
1144
- ...discount,
1145
- metadata: {
1146
- num: item.num,
1147
- custom_product_bundle_map_id: (_a2 = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id
1148
- }
1149
- // num: item.num, // 使用拆分后的 num
1150
- };
1151
- });
1152
- newBundle.push({
1153
- ...bundleItem,
1154
- _id: item._id,
1155
- product_id: bundleItem.product_id,
1156
- price: item.price,
1157
- num: item.num,
1158
- discount_list: updatedDiscountList2
1159
- });
1183
+ product.bundle.forEach((bundleItem, bundleIndex) => {
1184
+ const bundleItemId = `${product._id}_bundle_${bundleIndex}`;
1185
+ const processedBundleItems = processedFlatItemsMap2.get(bundleItemId);
1186
+ if (!processedBundleItems || processedBundleItems.length === 0) {
1187
+ newBundle.push(bundleItem);
1188
+ } else {
1189
+ processedBundleItems.forEach((item) => {
1190
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
1191
+ var _a2;
1192
+ return {
1193
+ ...discount,
1194
+ metadata: {
1195
+ ...discount.metadata,
1196
+ num: item.num,
1197
+ custom_product_bundle_map_id: (_a2 = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id
1198
+ }
1199
+ // num: item.num, // 使用拆分后的 num
1200
+ };
1160
1201
  });
1161
- }
1202
+ newBundle.push({
1203
+ ...bundleItem,
1204
+ _id: item._id,
1205
+ product_id: bundleItem.product_id,
1206
+ price: item.price,
1207
+ num: item.num,
1208
+ discount_list: updatedDiscountList2
1209
+ });
1210
+ });
1162
1211
  }
1163
- );
1212
+ });
1164
1213
  }
1165
1214
  let newTotal = Number(mainProductData.price || 0);
1166
- let newOriginTotal = Number(
1167
- mainProductData.original_price || mainProductData.price || 0
1168
- );
1169
- 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(
1170
- _b,
1171
- (item) => item.type === "product"
1172
- )));
1215
+ let newOriginTotal = Number(mainProductData.original_price || mainProductData.price || 0);
1216
+ 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")));
1173
1217
  if (isManualDiscount) {
1174
1218
  newTotal = mainProductData.total ?? newTotal;
1175
1219
  newOriginTotal = mainProductData.origin_total ?? newOriginTotal;
1176
1220
  } else {
1177
- const mainDiscountList = mainProductData.discount_list.filter(
1178
- (item) => {
1179
- var _a2;
1180
- return !((_a2 = item == null ? void 0 : item.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id);
1181
- }
1182
- );
1221
+ const mainDiscountList = mainProductData.discount_list.filter((item) => {
1222
+ var _a2;
1223
+ return !((_a2 = item == null ? void 0 : item.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id);
1224
+ });
1183
1225
  if (mainDiscountList && mainDiscountList.length > 0) {
1184
1226
  const allDiscountAmount = (0, import_utils.getDiscountListAmount)(mainDiscountList);
1185
1227
  newTotal = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotal;